@koda-sl/baker-cli 0.387.0 → 0.389.0-dev.8065ad8f0
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 +1090 -211
- package/canvas/tiktok-captions-composition/index.html +5 -6
- package/canvas/tiktok-captions-composition/meta.json +5 -0
- package/dist/account-CLOKMTTC.js +49 -0
- package/dist/account-CLOKMTTC.js.map +1 -0
- package/dist/account-V5Y2QHAK.js +79 -0
- package/dist/account-V5Y2QHAK.js.map +1 -0
- package/dist/account-XFK6VX2R.js +80 -0
- package/dist/account-XFK6VX2R.js.map +1 -0
- package/dist/account-reads-S5VXX2QU.js +218 -0
- package/dist/account-reads-S5VXX2QU.js.map +1 -0
- package/dist/account-writes-Y7EQXDXF.js +66 -0
- package/dist/account-writes-Y7EQXDXF.js.map +1 -0
- package/dist/accounts-7YD457YN.js +114 -0
- package/dist/accounts-7YD457YN.js.map +1 -0
- package/dist/accounts-BJ3X5JQT.js +115 -0
- package/dist/accounts-BJ3X5JQT.js.map +1 -0
- package/dist/accounts-LOJ4WLIX.js +77 -0
- package/dist/accounts-LOJ4WLIX.js.map +1 -0
- package/dist/accounts-RYBDLQ6H.js +75 -0
- package/dist/accounts-RYBDLQ6H.js.map +1 -0
- package/dist/accounts-UO4XBWM2.js +611 -0
- package/dist/accounts-UO4XBWM2.js.map +1 -0
- package/dist/actions-3AW3R63U.js +55 -0
- package/dist/actions-3AW3R63U.js.map +1 -0
- package/dist/active-entities-R6GZIO6Z.js +103 -0
- package/dist/active-entities-R6GZIO6Z.js.map +1 -0
- package/dist/activities-ESBF3GFS.js +74 -0
- package/dist/activities-ESBF3GFS.js.map +1 -0
- package/dist/ad-group-writes-I225OYDZ.js +170 -0
- package/dist/ad-group-writes-I225OYDZ.js.map +1 -0
- package/dist/ad-groups-O35MWNF6.js +68 -0
- package/dist/ad-groups-O35MWNF6.js.map +1 -0
- package/dist/ad-writes-SS5YZO5W.js +174 -0
- package/dist/ad-writes-SS5YZO5W.js.map +1 -0
- package/dist/add-43DUOVNR.js +104 -0
- package/dist/add-43DUOVNR.js.map +1 -0
- package/dist/add-IE5WDELB.js +302 -0
- package/dist/add-IE5WDELB.js.map +1 -0
- package/dist/add-QZHAWUBA.js +97 -0
- package/dist/add-QZHAWUBA.js.map +1 -0
- package/dist/add-TGQIVVXH.js +105 -0
- package/dist/add-TGQIVVXH.js.map +1 -0
- package/dist/add-accounts-6QYPOPR2.js +91 -0
- package/dist/add-accounts-6QYPOPR2.js.map +1 -0
- package/dist/ads-AUSRB4GU.js +128 -0
- package/dist/ads-AUSRB4GU.js.map +1 -0
- package/dist/ads-COYOTEKE.js +77 -0
- package/dist/ads-COYOTEKE.js.map +1 -0
- package/dist/ads-MALHYD2D.js +40 -0
- package/dist/ads-MALHYD2D.js.map +1 -0
- package/dist/ads-XZCMSPM5.js +113 -0
- package/dist/ads-XZCMSPM5.js.map +1 -0
- package/dist/adsets-AKR75THA.js +176 -0
- package/dist/adsets-AKR75THA.js.map +1 -0
- package/dist/advertisers-52FMMBTQ.js +120 -0
- package/dist/advertisers-52FMMBTQ.js.map +1 -0
- package/dist/advertisers-BCGKUMEH.js +125 -0
- package/dist/advertisers-BCGKUMEH.js.map +1 -0
- package/dist/analytics-JPDBKETM.js +1980 -0
- package/dist/analytics-JPDBKETM.js.map +1 -0
- package/dist/analytics-YVQ6H4BG.js +433 -0
- package/dist/analytics-YVQ6H4BG.js.map +1 -0
- package/dist/animate-JXIT77Y5.js +480 -0
- package/dist/animate-JXIT77Y5.js.map +1 -0
- package/dist/assign-66NTWTR2.js +77 -0
- package/dist/assign-66NTWTR2.js.map +1 -0
- package/dist/audience-size-LVQJWQAS.js +94 -0
- package/dist/audience-size-LVQJWQAS.js.map +1 -0
- package/dist/audiences-DC3IOG34.js +85 -0
- package/dist/audiences-DC3IOG34.js.map +1 -0
- package/dist/audiences-NEW3LLQR.js +268 -0
- package/dist/audiences-NEW3LLQR.js.map +1 -0
- package/dist/audiences-NYGMBGQ3.js +79 -0
- package/dist/audiences-NYGMBGQ3.js.map +1 -0
- package/dist/audit-UIPMTI5C.js +88 -0
- package/dist/audit-UIPMTI5C.js.map +1 -0
- package/dist/audit-XGN2OFLN.js +151 -0
- package/dist/audit-XGN2OFLN.js.map +1 -0
- package/dist/autocomplete-LVPDV3JE.js +111 -0
- package/dist/autocomplete-LVPDV3JE.js.map +1 -0
- package/dist/avatars-S6NSLMJK.js +38 -0
- package/dist/avatars-S6NSLMJK.js.map +1 -0
- package/dist/bid-pricing-2LYULXU2.js +99 -0
- package/dist/bid-pricing-2LYULXU2.js.map +1 -0
- package/dist/brand-WWHUZ72R.js +22 -0
- package/dist/brand-WWHUZ72R.js.map +1 -0
- package/dist/brief-XY3TFWBC.js +492 -0
- package/dist/brief-XY3TFWBC.js.map +1 -0
- package/dist/businesses-J7OP7MSK.js +53 -0
- package/dist/businesses-J7OP7MSK.js.map +1 -0
- package/dist/campaign-groups-N4TZ2F3L.js +95 -0
- package/dist/campaign-groups-N4TZ2F3L.js.map +1 -0
- package/dist/campaign-writes-5XA727KI.js +170 -0
- package/dist/campaign-writes-5XA727KI.js.map +1 -0
- package/dist/campaign-writes-7YFRQIQT.js +165 -0
- package/dist/campaign-writes-7YFRQIQT.js.map +1 -0
- package/dist/campaigns-JPYNVFQI.js +76 -0
- package/dist/campaigns-JPYNVFQI.js.map +1 -0
- package/dist/campaigns-L43ZUKAI.js +107 -0
- package/dist/campaigns-L43ZUKAI.js.map +1 -0
- package/dist/campaigns-OD7Z332M.js +109 -0
- package/dist/campaigns-OD7Z332M.js.map +1 -0
- package/dist/campaigns-R4DXIR2Q.js +110 -0
- package/dist/campaigns-R4DXIR2Q.js.map +1 -0
- package/dist/canvas-J7SLIVL7.js +46 -0
- package/dist/canvas-J7SLIVL7.js.map +1 -0
- package/dist/capabilities-FVTZAFPV.js +144 -0
- package/dist/capabilities-FVTZAFPV.js.map +1 -0
- package/dist/cards-7H32TNMO.js +85 -0
- package/dist/cards-7H32TNMO.js.map +1 -0
- package/dist/catalog-OTICZPJA.js +64 -0
- package/dist/catalog-OTICZPJA.js.map +1 -0
- package/dist/catalogs-ABCQLCDU.js +128 -0
- package/dist/catalogs-ABCQLCDU.js.map +1 -0
- package/dist/changes-7ZIGNUW6.js +135 -0
- package/dist/changes-7ZIGNUW6.js.map +1 -0
- package/dist/chatgpt-B3NHRJUE.js +47 -0
- package/dist/chatgpt-B3NHRJUE.js.map +1 -0
- package/dist/chats-E7DBRHBF.js +262 -0
- package/dist/chats-E7DBRHBF.js.map +1 -0
- package/dist/chunk-2CV7LX23.js +474 -0
- package/dist/chunk-2CV7LX23.js.map +1 -0
- package/dist/chunk-2HCI5BXB.js +479 -0
- package/dist/chunk-2HCI5BXB.js.map +1 -0
- package/dist/chunk-2SQJL7ZN.js +56 -0
- package/dist/chunk-2SQJL7ZN.js.map +1 -0
- package/dist/chunk-2Y5V23PU.js +29 -0
- package/dist/chunk-2Y5V23PU.js.map +1 -0
- package/dist/chunk-32CPGJPL.js +149 -0
- package/dist/chunk-32CPGJPL.js.map +1 -0
- package/dist/chunk-3ACMDRSE.js +39 -0
- package/dist/chunk-3ACMDRSE.js.map +1 -0
- package/dist/chunk-3CIXGQJS.js +150 -0
- package/dist/chunk-3CIXGQJS.js.map +1 -0
- package/dist/chunk-3U7TDBIB.js +275 -0
- package/dist/chunk-3U7TDBIB.js.map +1 -0
- package/dist/chunk-3UDSYYND.js +42 -0
- package/dist/chunk-3UDSYYND.js.map +1 -0
- package/dist/chunk-3ZWWXAQZ.js +150 -0
- package/dist/chunk-3ZWWXAQZ.js.map +1 -0
- package/dist/chunk-4MH6LONO.js +274 -0
- package/dist/chunk-4MH6LONO.js.map +1 -0
- package/dist/chunk-4NZ47VXO.js +137 -0
- package/dist/chunk-4NZ47VXO.js.map +1 -0
- package/dist/chunk-564AEU2Q.js +541 -0
- package/dist/chunk-564AEU2Q.js.map +1 -0
- package/dist/chunk-5HYSKH77.js +315 -0
- package/dist/chunk-5HYSKH77.js.map +1 -0
- package/dist/chunk-5MBPIONY.js +29 -0
- package/dist/chunk-5MBPIONY.js.map +1 -0
- package/dist/chunk-5OVOLYY3.js +74 -0
- package/dist/chunk-5OVOLYY3.js.map +1 -0
- package/dist/chunk-66USKCVY.js +4410 -0
- package/dist/chunk-66USKCVY.js.map +1 -0
- package/dist/chunk-6I7SYEYN.js +166 -0
- package/dist/chunk-6I7SYEYN.js.map +1 -0
- package/dist/chunk-6O7ISBC7.js +65 -0
- package/dist/chunk-6O7ISBC7.js.map +1 -0
- package/dist/chunk-752S7JF6.js +35 -0
- package/dist/chunk-752S7JF6.js.map +1 -0
- package/dist/chunk-77DN7R35.js +228 -0
- package/dist/chunk-77DN7R35.js.map +1 -0
- package/dist/chunk-7F7MFMLI.js +175 -0
- package/dist/chunk-7F7MFMLI.js.map +1 -0
- package/dist/chunk-7THBBTJJ.js +183 -0
- package/dist/chunk-7THBBTJJ.js.map +1 -0
- package/dist/chunk-7XU3HKMX.js +1599 -0
- package/dist/chunk-7XU3HKMX.js.map +1 -0
- package/dist/chunk-A2CBZLQ6.js +111 -0
- package/dist/chunk-A2CBZLQ6.js.map +1 -0
- package/dist/chunk-AFJGYJ7Z.js +45 -0
- package/dist/chunk-AFJGYJ7Z.js.map +1 -0
- package/dist/chunk-AR7PU7BB.js +76 -0
- package/dist/chunk-AR7PU7BB.js.map +1 -0
- package/dist/chunk-ASL7JFBD.js +96 -0
- package/dist/chunk-ASL7JFBD.js.map +1 -0
- package/dist/chunk-AUSKKFVH.js +84 -0
- package/dist/chunk-AUSKKFVH.js.map +1 -0
- package/dist/chunk-B52DCYL2.js +159 -0
- package/dist/chunk-B52DCYL2.js.map +1 -0
- package/dist/{chunk-XHC4LMK4.js → chunk-BVM5IRZW.js} +16 -8
- package/dist/chunk-BVM5IRZW.js.map +1 -0
- package/dist/chunk-CAMX6OHF.js +3182 -0
- package/dist/chunk-CAMX6OHF.js.map +1 -0
- package/dist/chunk-CYBLKMXQ.js +310 -0
- package/dist/chunk-CYBLKMXQ.js.map +1 -0
- package/dist/chunk-CZENWCBS.js +333 -0
- package/dist/chunk-CZENWCBS.js.map +1 -0
- package/dist/chunk-D5FY4FAK.js +24 -0
- package/dist/chunk-D5FY4FAK.js.map +1 -0
- package/dist/chunk-DGCUPJZD.js +39 -0
- package/dist/chunk-DGCUPJZD.js.map +1 -0
- package/dist/chunk-DNCLWSHO.js +41 -0
- package/dist/chunk-DNCLWSHO.js.map +1 -0
- package/dist/chunk-DX4GIDO7.js +296 -0
- package/dist/chunk-DX4GIDO7.js.map +1 -0
- package/dist/chunk-EDLZGTGN.js +216 -0
- package/dist/chunk-EDLZGTGN.js.map +1 -0
- package/dist/chunk-EDNKALM6.js +304 -0
- package/dist/chunk-EDNKALM6.js.map +1 -0
- package/dist/chunk-EDNX3AOS.js +76 -0
- package/dist/chunk-EDNX3AOS.js.map +1 -0
- package/dist/chunk-EF5DP6EB.js +52 -0
- package/dist/chunk-EF5DP6EB.js.map +1 -0
- package/dist/chunk-ERSX3MKH.js +34 -0
- package/dist/chunk-ERSX3MKH.js.map +1 -0
- package/dist/chunk-F3IJSR7O.js +346 -0
- package/dist/chunk-F3IJSR7O.js.map +1 -0
- package/dist/chunk-FKOECEVC.js +126 -0
- package/dist/chunk-FKOECEVC.js.map +1 -0
- package/dist/chunk-FWT55B3O.js +509 -0
- package/dist/chunk-FWT55B3O.js.map +1 -0
- package/dist/chunk-FYWWTMXP.js +2902 -0
- package/dist/chunk-FYWWTMXP.js.map +1 -0
- package/dist/chunk-FZGCAW46.js +64 -0
- package/dist/chunk-FZGCAW46.js.map +1 -0
- package/dist/chunk-G7AFVTUS.js +106 -0
- package/dist/chunk-G7AFVTUS.js.map +1 -0
- package/dist/chunk-GIW7ABMM.js +74 -0
- package/dist/chunk-GIW7ABMM.js.map +1 -0
- package/dist/chunk-GIWHHCD6.js +145 -0
- package/dist/chunk-GIWHHCD6.js.map +1 -0
- package/dist/chunk-GRQ2AXDX.js +9 -0
- package/dist/chunk-GRQ2AXDX.js.map +1 -0
- package/dist/chunk-GXDLWBOY.js +73 -0
- package/dist/chunk-GXDLWBOY.js.map +1 -0
- package/dist/chunk-GYABNLWW.js +629 -0
- package/dist/chunk-GYABNLWW.js.map +1 -0
- package/dist/chunk-H7MLHG2I.js +94 -0
- package/dist/chunk-H7MLHG2I.js.map +1 -0
- package/dist/chunk-H7XVKLIY.js +206 -0
- package/dist/chunk-H7XVKLIY.js.map +1 -0
- package/dist/chunk-HAE4WWFQ.js +455 -0
- package/dist/chunk-HAE4WWFQ.js.map +1 -0
- package/dist/chunk-HDHWIEJJ.js +136 -0
- package/dist/chunk-HDHWIEJJ.js.map +1 -0
- package/dist/chunk-HJTIBTF7.js +98 -0
- package/dist/chunk-HJTIBTF7.js.map +1 -0
- package/dist/{chunk-VZEDAFAR.js → chunk-HLXWKMTK.js} +47 -8
- package/dist/chunk-HLXWKMTK.js.map +1 -0
- package/dist/{chunk-MF7YA62W.js → chunk-HREWXNTO.js} +10 -5
- package/dist/chunk-HREWXNTO.js.map +1 -0
- package/dist/chunk-HYXKRNRV.js +176 -0
- package/dist/chunk-HYXKRNRV.js.map +1 -0
- package/dist/chunk-I3DIZWN5.js +97 -0
- package/dist/chunk-I3DIZWN5.js.map +1 -0
- package/dist/chunk-IJMWEO4P.js +57 -0
- package/dist/chunk-IJMWEO4P.js.map +1 -0
- package/dist/chunk-IOCSDFF2.js +23992 -0
- package/dist/chunk-IOCSDFF2.js.map +1 -0
- package/dist/chunk-IVIJJXXT.js +62 -0
- package/dist/chunk-IVIJJXXT.js.map +1 -0
- package/dist/chunk-J57GWTPK.js +106 -0
- package/dist/chunk-J57GWTPK.js.map +1 -0
- package/dist/chunk-JPK34QPS.js +134 -0
- package/dist/chunk-JPK34QPS.js.map +1 -0
- package/dist/chunk-JRCFCIE3.js +188 -0
- package/dist/chunk-JRCFCIE3.js.map +1 -0
- package/dist/chunk-JUAIGJ2A.js +76 -0
- package/dist/chunk-JUAIGJ2A.js.map +1 -0
- package/dist/chunk-K5OQES4V.js +58 -0
- package/dist/chunk-K5OQES4V.js.map +1 -0
- package/dist/chunk-KBS5GH4T.js +1626 -0
- package/dist/chunk-KBS5GH4T.js.map +1 -0
- package/dist/chunk-KIGGMKAE.js +66 -0
- package/dist/chunk-KIGGMKAE.js.map +1 -0
- package/dist/chunk-KKJ4KJCW.js +29 -0
- package/dist/chunk-KKJ4KJCW.js.map +1 -0
- package/dist/chunk-KLK6KQLQ.js +55 -0
- package/dist/chunk-KLK6KQLQ.js.map +1 -0
- package/dist/chunk-KXGG6EQM.js +382 -0
- package/dist/chunk-KXGG6EQM.js.map +1 -0
- package/dist/chunk-KXRKPZZY.js +169 -0
- package/dist/chunk-KXRKPZZY.js.map +1 -0
- package/dist/chunk-KZUHRZ2C.js +5187 -0
- package/dist/chunk-KZUHRZ2C.js.map +1 -0
- package/dist/chunk-L45A3IYV.js +1079 -0
- package/dist/chunk-L45A3IYV.js.map +1 -0
- package/dist/chunk-LA6PPSNA.js +65 -0
- package/dist/chunk-LA6PPSNA.js.map +1 -0
- package/dist/chunk-LEIQAHWF.js +25 -0
- package/dist/chunk-LEIQAHWF.js.map +1 -0
- package/dist/chunk-LERWCRY5.js +297 -0
- package/dist/chunk-LERWCRY5.js.map +1 -0
- package/dist/chunk-LLPFY3NI.js +207 -0
- package/dist/chunk-LLPFY3NI.js.map +1 -0
- package/dist/chunk-M6UNISGO.js +66 -0
- package/dist/chunk-M6UNISGO.js.map +1 -0
- package/dist/chunk-MDATIJPM.js +92 -0
- package/dist/chunk-MDATIJPM.js.map +1 -0
- package/dist/chunk-MGKHFGLV.js +75 -0
- package/dist/chunk-MGKHFGLV.js.map +1 -0
- package/dist/chunk-MZWC6HHA.js +455 -0
- package/dist/chunk-MZWC6HHA.js.map +1 -0
- package/dist/chunk-N3XJ434P.js +197 -0
- package/dist/chunk-N3XJ434P.js.map +1 -0
- package/dist/chunk-NFSLRRIE.js +77 -0
- package/dist/chunk-NFSLRRIE.js.map +1 -0
- package/dist/chunk-NHU33T2S.js +60 -0
- package/dist/chunk-NHU33T2S.js.map +1 -0
- package/dist/chunk-NJEZM4OB.js +51 -0
- package/dist/chunk-NJEZM4OB.js.map +1 -0
- package/dist/chunk-O6QKCJE4.js +455 -0
- package/dist/chunk-O6QKCJE4.js.map +1 -0
- package/dist/chunk-OFFAMC5H.js +225 -0
- package/dist/chunk-OFFAMC5H.js.map +1 -0
- package/dist/chunk-OHGTCFFE.js +57 -0
- package/dist/chunk-OHGTCFFE.js.map +1 -0
- package/dist/chunk-P4NSJS54.js +20 -0
- package/dist/chunk-P4NSJS54.js.map +1 -0
- package/dist/chunk-P5T7OZKV.js +26 -0
- package/dist/chunk-P5T7OZKV.js.map +1 -0
- package/dist/chunk-PFBQERWX.js +10 -0
- package/dist/chunk-PFBQERWX.js.map +1 -0
- package/dist/chunk-PUPEGICD.js +103 -0
- package/dist/chunk-PUPEGICD.js.map +1 -0
- package/dist/chunk-Q6ULQMWG.js +41 -0
- package/dist/chunk-Q6ULQMWG.js.map +1 -0
- package/dist/chunk-QO23YHLK.js +84 -0
- package/dist/chunk-QO23YHLK.js.map +1 -0
- package/dist/chunk-QSGIWV4P.js +337 -0
- package/dist/chunk-QSGIWV4P.js.map +1 -0
- package/dist/chunk-R4Y5P3PB.js +19 -0
- package/dist/chunk-R4Y5P3PB.js.map +1 -0
- package/dist/chunk-R5OQM7FF.js +179 -0
- package/dist/chunk-R5OQM7FF.js.map +1 -0
- package/dist/chunk-RODLBWIR.js +592 -0
- package/dist/chunk-RODLBWIR.js.map +1 -0
- package/dist/chunk-RY7TYEIX.js +504 -0
- package/dist/chunk-RY7TYEIX.js.map +1 -0
- package/dist/chunk-S4LZ7KTG.js +160 -0
- package/dist/chunk-S4LZ7KTG.js.map +1 -0
- package/dist/chunk-SHTESUB6.js +1442 -0
- package/dist/chunk-SHTESUB6.js.map +1 -0
- package/dist/chunk-SJH4EOZH.js +23 -0
- package/dist/chunk-SJH4EOZH.js.map +1 -0
- package/dist/chunk-SMIENBNX.js +6212 -0
- package/dist/chunk-SMIENBNX.js.map +1 -0
- package/dist/chunk-T7GT22KA.js +494 -0
- package/dist/chunk-T7GT22KA.js.map +1 -0
- package/dist/chunk-T7M4WFNV.js +172 -0
- package/dist/chunk-T7M4WFNV.js.map +1 -0
- package/dist/chunk-TIFVHGQL.js +6683 -0
- package/dist/chunk-TIFVHGQL.js.map +1 -0
- package/dist/chunk-TMIDUSOR.js +665 -0
- package/dist/chunk-TMIDUSOR.js.map +1 -0
- package/dist/{chunk-WLDM2TRF.js → chunk-TPXI2GCW.js} +4 -4
- package/dist/chunk-U6VRBDNQ.js +1830 -0
- package/dist/chunk-U6VRBDNQ.js.map +1 -0
- package/dist/chunk-U7BBXM67.js +1743 -0
- package/dist/chunk-U7BBXM67.js.map +1 -0
- package/dist/chunk-UI6BKYQD.js +225 -0
- package/dist/chunk-UI6BKYQD.js.map +1 -0
- package/dist/chunk-UOI5S62H.js +846 -0
- package/dist/chunk-UOI5S62H.js.map +1 -0
- package/dist/chunk-USL5ARRE.js +26 -0
- package/dist/chunk-USL5ARRE.js.map +1 -0
- package/dist/chunk-UYC45JNS.js +139 -0
- package/dist/chunk-UYC45JNS.js.map +1 -0
- package/dist/chunk-VNKVBY54.js +363 -0
- package/dist/chunk-VNKVBY54.js.map +1 -0
- package/dist/chunk-VS4C7VAR.js +533 -0
- package/dist/chunk-VS4C7VAR.js.map +1 -0
- package/dist/chunk-VZMDYVNS.js +3151 -0
- package/dist/chunk-VZMDYVNS.js.map +1 -0
- package/dist/chunk-W4W4ZRBP.js +191 -0
- package/dist/chunk-W4W4ZRBP.js.map +1 -0
- package/dist/chunk-WN4KX7GE.js +25 -0
- package/dist/chunk-WN4KX7GE.js.map +1 -0
- package/dist/chunk-WNFTXSGR.js +111 -0
- package/dist/chunk-WNFTXSGR.js.map +1 -0
- package/dist/chunk-WOTDHRNF.js +2109 -0
- package/dist/chunk-WOTDHRNF.js.map +1 -0
- package/dist/chunk-XGWKTYXQ.js +67 -0
- package/dist/chunk-XGWKTYXQ.js.map +1 -0
- package/dist/chunk-XIGIJJSF.js +66 -0
- package/dist/chunk-XIGIJJSF.js.map +1 -0
- package/dist/chunk-XNUXB63I.js +817 -0
- package/dist/chunk-XNUXB63I.js.map +1 -0
- package/dist/chunk-XQ3CCNJD.js +610 -0
- package/dist/chunk-XQ3CCNJD.js.map +1 -0
- package/dist/chunk-XX6ZMCY5.js +4227 -0
- package/dist/chunk-XX6ZMCY5.js.map +1 -0
- package/dist/chunk-Y362QH54.js +98 -0
- package/dist/chunk-Y362QH54.js.map +1 -0
- package/dist/chunk-Y4T6ATDQ.js +74 -0
- package/dist/chunk-Y4T6ATDQ.js.map +1 -0
- package/dist/chunk-YQSBHWOI.js +41 -0
- package/dist/chunk-YU26SDNT.js +46 -0
- package/dist/chunk-YU26SDNT.js.map +1 -0
- package/dist/chunk-YULENNA7.js +501 -0
- package/dist/chunk-YULENNA7.js.map +1 -0
- package/dist/chunk-Z3ENMCFE.js +94 -0
- package/dist/chunk-Z3ENMCFE.js.map +1 -0
- package/dist/chunk-ZH7ZM3ZM.js +125 -0
- package/dist/chunk-ZH7ZM3ZM.js.map +1 -0
- package/dist/chunk-ZIXHS6AM.js +42 -0
- package/dist/chunk-ZIXHS6AM.js.map +1 -0
- package/dist/chunk-ZLLJKSNS.js +96 -0
- package/dist/chunk-ZLLJKSNS.js.map +1 -0
- package/dist/claim-LF6VQ7OR.js +197 -0
- package/dist/claim-LF6VQ7OR.js.map +1 -0
- package/dist/cli.js +104 -70041
- package/dist/cli.js.map +1 -1
- package/dist/client-26SAJ46D.js +19 -0
- package/dist/code-MOWYJMDH.js +76 -0
- package/dist/code-MOWYJMDH.js.map +1 -0
- package/dist/companies-6HSK5BLK.js +195 -0
- package/dist/companies-6HSK5BLK.js.map +1 -0
- package/dist/complete-2PUAFQEC.js +81 -0
- package/dist/complete-2PUAFQEC.js.map +1 -0
- package/dist/config-X6GKOVQ6.js +88 -0
- package/dist/config-X6GKOVQ6.js.map +1 -0
- package/dist/connect-RXPMAJQI.js +42 -0
- package/dist/content-UYZC4AKN.js +85 -0
- package/dist/content-UYZC4AKN.js.map +1 -0
- package/dist/conversation-Y3NB2VDI.js +93 -0
- package/dist/conversation-Y3NB2VDI.js.map +1 -0
- package/dist/conversion-report-R4GJWWTK.js +125 -0
- package/dist/conversion-report-R4GJWWTK.js.map +1 -0
- package/dist/conversion-upload-command-YP4DGTPP.js +438 -0
- package/dist/conversion-upload-command-YP4DGTPP.js.map +1 -0
- package/dist/conversion-writes-WHFFUWWL.js +120 -0
- package/dist/conversion-writes-WHFFUWWL.js.map +1 -0
- package/dist/conversions-K7C32DPW.js +135 -0
- package/dist/conversions-K7C32DPW.js.map +1 -0
- package/dist/conversions-OXJAX5GB.js +76 -0
- package/dist/conversions-OXJAX5GB.js.map +1 -0
- package/dist/countries-PBXNB3BR.js +82 -0
- package/dist/countries-PBXNB3BR.js.map +1 -0
- package/dist/create-AJ4KPSJ4.js +59 -0
- package/dist/create-AJ4KPSJ4.js.map +1 -0
- package/dist/create-ALKOAD5J.js +138 -0
- package/dist/create-ALKOAD5J.js.map +1 -0
- package/dist/create-HTKZMXKB.js +207 -0
- package/dist/create-HTKZMXKB.js.map +1 -0
- package/dist/create-TZMAOFBR.js +236 -0
- package/dist/create-TZMAOFBR.js.map +1 -0
- package/dist/creatives-MBTZTIAA.js +51 -0
- package/dist/creatives-MBTZTIAA.js.map +1 -0
- package/dist/creatives-OZHVU4WB.js +182 -0
- package/dist/creatives-OZHVU4WB.js.map +1 -0
- package/dist/creatives-VMGY5SU4.js +87 -0
- package/dist/creatives-VMGY5SU4.js.map +1 -0
- package/dist/credentials-FY4UH6TF.js +287 -0
- package/dist/credentials-FY4UH6TF.js.map +1 -0
- package/dist/critique-2UTP4DR3.js +216 -0
- package/dist/critique-2UTP4DR3.js.map +1 -0
- package/dist/critique-B3H7QFM2.js +1449 -0
- package/dist/critique-B3H7QFM2.js.map +1 -0
- package/dist/crm-2IBLUHDB.js +318 -0
- package/dist/crm-2IBLUHDB.js.map +1 -0
- package/dist/crm-YMYO4U53.js +224 -0
- package/dist/crm-YMYO4U53.js.map +1 -0
- package/dist/crop-U3AD4DDR.js +113 -0
- package/dist/crop-U3AD4DDR.js.map +1 -0
- package/dist/currency-S6KWZSZ6.js +88 -0
- package/dist/currency-S6KWZSZ6.js.map +1 -0
- package/dist/custom-conversions-FABS6YVT.js +125 -0
- package/dist/custom-conversions-FABS6YVT.js.map +1 -0
- package/dist/customers-P6LLLJHK.js +56 -0
- package/dist/decide-YTHCBKM6.js +199 -0
- package/dist/decide-YTHCBKM6.js.map +1 -0
- package/dist/delete-B2TDEW7H.js +63 -0
- package/dist/delete-B2TDEW7H.js.map +1 -0
- package/dist/delete-DZUDLYPC.js +69 -0
- package/dist/delete-DZUDLYPC.js.map +1 -0
- package/dist/delete-NZGZP4YP.js +71 -0
- package/dist/delete-NZGZP4YP.js.map +1 -0
- package/dist/delete-SDOZNDWQ.js +54 -0
- package/dist/delete-SDOZNDWQ.js.map +1 -0
- package/dist/delete-VQMU56OH.js +71 -0
- package/dist/delete-VQMU56OH.js.map +1 -0
- package/dist/delete-WKQPMVAM.js +66 -0
- package/dist/delete-WKQPMVAM.js.map +1 -0
- package/dist/demographics-Q3DCXULY.js +138 -0
- package/dist/demographics-Q3DCXULY.js.map +1 -0
- package/dist/describe-JNTCQZNL.js +97 -0
- package/dist/describe-JNTCQZNL.js.map +1 -0
- package/dist/describe-MT4334NG.js +97 -0
- package/dist/describe-MT4334NG.js.map +1 -0
- package/dist/dimensions-FEZUJRAG.js +101 -0
- package/dist/dimensions-FEZUJRAG.js.map +1 -0
- package/dist/discard-NEZM5CHF.js +66 -0
- package/dist/discard-NEZM5CHF.js.map +1 -0
- package/dist/discover-4GD7QSF5.js +93 -0
- package/dist/discover-4GD7QSF5.js.map +1 -0
- package/dist/discover-6K3IOYXR.js +172 -0
- package/dist/discover-6K3IOYXR.js.map +1 -0
- package/dist/domain-7Y256IDR.js +98 -0
- package/dist/domain-7Y256IDR.js.map +1 -0
- package/dist/download-L27HWEOE.js +299 -0
- package/dist/download-L27HWEOE.js.map +1 -0
- package/dist/draft-25G2P2TE.js +281 -0
- package/dist/draft-25G2P2TE.js.map +1 -0
- package/dist/draft-F6TUGXAY.js +307 -0
- package/dist/draft-F6TUGXAY.js.map +1 -0
- package/dist/draft-KLULNBWP.js +233 -0
- package/dist/draft-KLULNBWP.js.map +1 -0
- package/dist/draft-LY5ZPF73.js +217 -0
- package/dist/draft-LY5ZPF73.js.map +1 -0
- package/dist/draft-M4ZHDQ46.js +306 -0
- package/dist/draft-M4ZHDQ46.js.map +1 -0
- package/dist/draft-MI7RWY2K.js +100 -0
- package/dist/draft-MI7RWY2K.js.map +1 -0
- package/dist/draft-P4IVYTY3.js +103 -0
- package/dist/draft-P4IVYTY3.js.map +1 -0
- package/dist/draft-QQMCVDDS.js +328 -0
- package/dist/draft-QQMCVDDS.js.map +1 -0
- package/dist/engine/index.d.ts +213 -127
- package/dist/engine/index.js +18 -4
- package/dist/{env-4P5HOGNA.js → env-FBTHZKGN.js} +12 -2
- package/dist/env-FBTHZKGN.js.map +1 -0
- package/dist/experiment-HDYTJPUY.js +1397 -0
- package/dist/experiment-HDYTJPUY.js.map +1 -0
- package/dist/export-TS5GYEMA.js +168 -0
- package/dist/export-TS5GYEMA.js.map +1 -0
- package/dist/extract-QVQFUOIK.js +113 -0
- package/dist/extract-QVQFUOIK.js.map +1 -0
- package/dist/facets-7MBSM7BP.js +114 -0
- package/dist/facets-7MBSM7BP.js.map +1 -0
- package/dist/favorites-7QP7BY5K.js +178 -0
- package/dist/favorites-7QP7BY5K.js.map +1 -0
- package/dist/feed-EETRO2FG.js +177 -0
- package/dist/feed-EETRO2FG.js.map +1 -0
- package/dist/feedback-PLMFRAQW.js +66 -0
- package/dist/feedback-PLMFRAQW.js.map +1 -0
- package/dist/feedback-record-QEHHGVYC.js +177 -0
- package/dist/feedback-record-QEHHGVYC.js.map +1 -0
- package/dist/fetch-QE3EB756.js +176 -0
- package/dist/fetch-QE3EB756.js.map +1 -0
- package/dist/fetch-Z7O3ZL4D.js +139 -0
- package/dist/fetch-Z7O3ZL4D.js.map +1 -0
- package/dist/find-KAQ6JDMO.js +134 -0
- package/dist/find-KAQ6JDMO.js.map +1 -0
- package/dist/fit-MY5GVZZZ.js +45 -0
- package/dist/fit-MY5GVZZZ.js.map +1 -0
- package/dist/flows-C67KEMDU.js +247 -0
- package/dist/flows-C67KEMDU.js.map +1 -0
- package/dist/follow-IX4XVK5Y.js +94 -0
- package/dist/follow-IX4XVK5Y.js.map +1 -0
- package/dist/follow-competitors-UZBUOYTH.js +112 -0
- package/dist/follow-competitors-UZBUOYTH.js.map +1 -0
- package/dist/following-VGOIUCIZ.js +113 -0
- package/dist/following-VGOIUCIZ.js.map +1 -0
- package/dist/fonts-UR7XZ5XZ.js +34 -0
- package/dist/fonts-UR7XZ5XZ.js.map +1 -0
- package/dist/forecast-3F4SZNAK.js +104 -0
- package/dist/forecast-3F4SZNAK.js.map +1 -0
- package/dist/forecast-K5E7CTKX.js +168 -0
- package/dist/forecast-K5E7CTKX.js.map +1 -0
- package/dist/funding-H5YO37OW.js +85 -0
- package/dist/funding-H5YO37OW.js.map +1 -0
- package/dist/funnel-2PPEPAMY.js +394 -0
- package/dist/funnel-2PPEPAMY.js.map +1 -0
- package/dist/ga4-YHJ2XMLC.js +55 -0
- package/dist/ga4-YHJ2XMLC.js.map +1 -0
- package/dist/generate-M2ZX5DMI.js +262 -0
- package/dist/generate-M2ZX5DMI.js.map +1 -0
- package/dist/get-4EYKCZ6F.js +59 -0
- package/dist/get-4EYKCZ6F.js.map +1 -0
- package/dist/get-637GALM2.js +63 -0
- package/dist/get-637GALM2.js.map +1 -0
- package/dist/get-AZARFR6O.js +61 -0
- package/dist/get-AZARFR6O.js.map +1 -0
- package/dist/get-BPMEHRUG.js +56 -0
- package/dist/get-BPMEHRUG.js.map +1 -0
- package/dist/get-MQ6MMIZ7.js +78 -0
- package/dist/get-MQ6MMIZ7.js.map +1 -0
- package/dist/get-N4BPOQCB.js +63 -0
- package/dist/get-N4BPOQCB.js.map +1 -0
- package/dist/get-RPZHLQ56.js +92 -0
- package/dist/get-RPZHLQ56.js.map +1 -0
- package/dist/gif-6PRTB2VR.js +94 -0
- package/dist/gif-6PRTB2VR.js.map +1 -0
- package/dist/google-52JRH7X3.js +136 -0
- package/dist/google-52JRH7X3.js.map +1 -0
- package/dist/google-X2AQR3RB.js +3190 -0
- package/dist/google-X2AQR3RB.js.map +1 -0
- package/dist/google-ads-PWX7OF5Z.js +195 -0
- package/dist/google-ads-PWX7OF5Z.js.map +1 -0
- package/dist/group-AAZ5QKC3.js +43 -0
- package/dist/group-AAZ5QKC3.js.map +1 -0
- package/dist/group-GSYCZORC.js +43 -0
- package/dist/group-GSYCZORC.js.map +1 -0
- package/dist/gsc-TS5T7ML2.js +30 -0
- package/dist/gsc-TS5T7ML2.js.map +1 -0
- package/dist/history-EW6LFFCX.js +67 -0
- package/dist/history-EW6LFFCX.js.map +1 -0
- package/dist/history-XI5ABCFO.js +133 -0
- package/dist/history-XI5ABCFO.js.map +1 -0
- package/dist/hubspot-AVUOILRE.js +779 -0
- package/dist/hubspot-AVUOILRE.js.map +1 -0
- package/dist/icon-K75KI6BV.js +137 -0
- package/dist/icon-K75KI6BV.js.map +1 -0
- package/dist/ideas-L3SZSIZP.js +35 -0
- package/dist/ideas-L3SZSIZP.js.map +1 -0
- package/dist/images-CD53I2W5.js +90 -0
- package/dist/images-CD53I2W5.js.map +1 -0
- package/dist/improve-L3BW4EQG.js +86 -0
- package/dist/improve-L3BW4EQG.js.map +1 -0
- package/dist/ingest-KRJOYTCQ.js +107 -0
- package/dist/ingest-KRJOYTCQ.js.map +1 -0
- package/dist/ingest-WE3SPPND.js +23 -0
- package/dist/ingest-WE3SPPND.js.map +1 -0
- package/dist/insights-PELVD4RY.js +122 -0
- package/dist/insights-PELVD4RY.js.map +1 -0
- package/dist/insights-XCA4BUJW.js +423 -0
- package/dist/insights-XCA4BUJW.js.map +1 -0
- package/dist/inspect-QKETG5UJ.js +189 -0
- package/dist/inspect-QKETG5UJ.js.map +1 -0
- package/dist/inspiration-Y2J2PUPC.js +53 -0
- package/dist/inspiration-Y2J2PUPC.js.map +1 -0
- package/dist/intent-YJOJGNVJ.js +95 -0
- package/dist/intent-YJOJGNVJ.js.map +1 -0
- package/dist/job-E2U4FS5P.js +202 -0
- package/dist/job-E2U4FS5P.js.map +1 -0
- package/dist/job-create-DFYCHVQ7.js +109 -0
- package/dist/job-create-DFYCHVQ7.js.map +1 -0
- package/dist/job-status-FFPMTSHB.js +74 -0
- package/dist/job-status-FFPMTSHB.js.map +1 -0
- package/dist/keep-GYZS2UTL.js +78 -0
- package/dist/keep-GYZS2UTL.js.map +1 -0
- package/dist/keyword-gap-QU7O7UKC.js +130 -0
- package/dist/keyword-gap-QU7O7UKC.js.map +1 -0
- package/dist/keyword-metrics-HLCM3QU7.js +197 -0
- package/dist/keyword-metrics-HLCM3QU7.js.map +1 -0
- package/dist/keywords-for-site-BDKPQKWB.js +128 -0
- package/dist/keywords-for-site-BDKPQKWB.js.map +1 -0
- package/dist/landing-4K6XYNFM.js +28 -0
- package/dist/landing-4K6XYNFM.js.map +1 -0
- package/dist/landings-F7LOAEJE.js +151 -0
- package/dist/landings-F7LOAEJE.js.map +1 -0
- package/dist/languages-P3ZM6R2A.js +40 -0
- package/dist/languages-P3ZM6R2A.js.map +1 -0
- package/dist/languages-XEJKTIFP.js +55 -0
- package/dist/languages-XEJKTIFP.js.map +1 -0
- package/dist/launches-TCFAYUA5.js +19 -0
- package/dist/launches-TCFAYUA5.js.map +1 -0
- package/dist/layerize-ZSKFIPZA.js +190 -0
- package/dist/layerize-ZSKFIPZA.js.map +1 -0
- package/dist/leads-GDF4S2AM.js +90 -0
- package/dist/leads-GDF4S2AM.js.map +1 -0
- package/dist/leads-TPB5OFSQ.js +293 -0
- package/dist/leads-TPB5OFSQ.js.map +1 -0
- package/dist/learn-NMFEA5H5.js +203 -0
- package/dist/learn-NMFEA5H5.js.map +1 -0
- package/dist/library-IP2UKNRU.js +109 -0
- package/dist/library-IP2UKNRU.js.map +1 -0
- package/dist/lighthouse-57XBJRCO.js +75 -0
- package/dist/lighthouse-57XBJRCO.js.map +1 -0
- package/dist/line-item-writes-O6SSS5NQ.js +208 -0
- package/dist/line-item-writes-O6SSS5NQ.js.map +1 -0
- package/dist/line-items-ZZAKH3YZ.js +103 -0
- package/dist/line-items-ZZAKH3YZ.js.map +1 -0
- package/dist/link-CRY57R3E.js +64 -0
- package/dist/link-CRY57R3E.js.map +1 -0
- package/dist/linkedin-WC7LGYPP.js +1008 -0
- package/dist/linkedin-WC7LGYPP.js.map +1 -0
- package/dist/list-6IKPWQGG.js +57 -0
- package/dist/list-6IKPWQGG.js.map +1 -0
- package/dist/list-CAUH3BMG.js +65 -0
- package/dist/list-CAUH3BMG.js.map +1 -0
- package/dist/list-CWAKX5TH.js +63 -0
- package/dist/list-CWAKX5TH.js.map +1 -0
- package/dist/list-FJ5FSVL6.js +151 -0
- package/dist/list-FJ5FSVL6.js.map +1 -0
- package/dist/list-GTOSN7DP.js +50 -0
- package/dist/list-GTOSN7DP.js.map +1 -0
- package/dist/list-HLJP4NVE.js +51 -0
- package/dist/list-HLJP4NVE.js.map +1 -0
- package/dist/list-LCUPF7EF.js +76 -0
- package/dist/list-LCUPF7EF.js.map +1 -0
- package/dist/list-NH4ZRZTL.js +303 -0
- package/dist/list-NH4ZRZTL.js.map +1 -0
- package/dist/locations-2BYWKIYA.js +67 -0
- package/dist/locations-2BYWKIYA.js.map +1 -0
- package/dist/locations-LVVDOSXO.js +40 -0
- package/dist/locations-LVVDOSXO.js.map +1 -0
- package/dist/log-6JOWOY5G.js +92 -0
- package/dist/log-6JOWOY5G.js.map +1 -0
- package/dist/logo-AJK2TDQU.js +18 -0
- package/dist/logo-AJK2TDQU.js.map +1 -0
- package/dist/lookup-H5GEM77H.js +22 -0
- package/dist/lookup-H5GEM77H.js.map +1 -0
- package/dist/make-N3WZ6OSS.js +640 -0
- package/dist/make-N3WZ6OSS.js.map +1 -0
- package/dist/map-4KOYFHAN.js +404 -0
- package/dist/map-4KOYFHAN.js.map +1 -0
- package/dist/mcp-LSS2DHYL.js +463 -0
- package/dist/mcp-LSS2DHYL.js.map +1 -0
- package/dist/media-JBCN6V4X.js +15 -0
- package/dist/media-JBCN6V4X.js.map +1 -0
- package/dist/media-RAGEJTZX.js +89 -0
- package/dist/media-RAGEJTZX.js.map +1 -0
- package/dist/media-sources-GSPAV7HT.js +32 -0
- package/dist/media-sources-GSPAV7HT.js.map +1 -0
- package/dist/members-GUUVEK2Y.js +44 -0
- package/dist/members-GUUVEK2Y.js.map +1 -0
- package/dist/meta-Z37ZR3PJ.js +69 -0
- package/dist/meta-Z37ZR3PJ.js.map +1 -0
- package/dist/metrics-KW6SDULI.js +152 -0
- package/dist/metrics-KW6SDULI.js.map +1 -0
- package/dist/models-5J4WFUD3.js +155 -0
- package/dist/models-5J4WFUD3.js.map +1 -0
- package/dist/normalize-DSFVTRXN.js +806 -0
- package/dist/normalize-DSFVTRXN.js.map +1 -0
- package/dist/normalize-EUDI5HEM.js +141 -0
- package/dist/normalize-EUDI5HEM.js.map +1 -0
- package/dist/options-P4PPJQH4.js +121 -0
- package/dist/options-P4PPJQH4.js.map +1 -0
- package/dist/output-DTCLVPUF.js +24 -0
- package/dist/output-DTCLVPUF.js.map +1 -0
- package/dist/page-N2ZO3O7F.js +105 -0
- package/dist/page-N2ZO3O7F.js.map +1 -0
- package/dist/pages-FQ4CBAJ2.js +66 -0
- package/dist/pages-FQ4CBAJ2.js.map +1 -0
- package/dist/performance-A66LYIZX.js +24 -0
- package/dist/performance-A66LYIZX.js.map +1 -0
- package/dist/pinterest-NV5XTNJE.js +96 -0
- package/dist/pinterest-NV5XTNJE.js.map +1 -0
- package/dist/pixels-CTJ43FZ4.js +108 -0
- package/dist/pixels-CTJ43FZ4.js.map +1 -0
- package/dist/pixels-HKINGZCH.js +60 -0
- package/dist/pixels-HKINGZCH.js.map +1 -0
- package/dist/plan-ZYTWLGWK.js +207 -0
- package/dist/plan-ZYTWLGWK.js.map +1 -0
- package/dist/preview-5ROBOQG7.js +169 -0
- package/dist/preview-5ROBOQG7.js.map +1 -0
- package/dist/profile-Q3PHR6FU.js +159 -0
- package/dist/profile-Q3PHR6FU.js.map +1 -0
- package/dist/promoted-tweet-writes-AEOUK2LK.js +180 -0
- package/dist/promoted-tweet-writes-AEOUK2LK.js.map +1 -0
- package/dist/promoted-tweets-L2CEC2BJ.js +119 -0
- package/dist/promoted-tweets-L2CEC2BJ.js.map +1 -0
- package/dist/properties-WLL6M2P6.js +101 -0
- package/dist/properties-WLL6M2P6.js.map +1 -0
- package/dist/publish-KHNR5ARF.js +322 -0
- package/dist/publish-KHNR5ARF.js.map +1 -0
- package/dist/query-A34J7BGX.js +61 -0
- package/dist/query-A34J7BGX.js.map +1 -0
- package/dist/query-IYZN5KHO.js +236 -0
- package/dist/query-IYZN5KHO.js.map +1 -0
- package/dist/query-UN2P6DBA.js +247 -0
- package/dist/query-UN2P6DBA.js.map +1 -0
- package/dist/questionnaire-Z2ZIKNBV.js +93 -0
- package/dist/questionnaire-Z2ZIKNBV.js.map +1 -0
- package/dist/read-GM7PQYJA.js +141 -0
- package/dist/read-GM7PQYJA.js.map +1 -0
- package/dist/reddit-5NPFULGD.js +26 -0
- package/dist/reddit-5NPFULGD.js.map +1 -0
- package/dist/refresh-FGXW4Y4X.js +94 -0
- package/dist/refresh-FGXW4Y4X.js.map +1 -0
- package/dist/release-OKZMC73N.js +60 -0
- package/dist/release-OKZMC73N.js.map +1 -0
- package/dist/relevant-pages-J76ZKNKF.js +99 -0
- package/dist/relevant-pages-J76ZKNKF.js.map +1 -0
- package/dist/remove-CA2J6ACH.js +50 -0
- package/dist/remove-CA2J6ACH.js.map +1 -0
- package/dist/remove-GOYW2G4R.js +48 -0
- package/dist/remove-GOYW2G4R.js.map +1 -0
- package/dist/reopen-XPKSOE6O.js +63 -0
- package/dist/reopen-XPKSOE6O.js.map +1 -0
- package/dist/rerun-QA6ISKVO.js +86 -0
- package/dist/rerun-QA6ISKVO.js.map +1 -0
- package/dist/research-FZ63UZTE.js +62 -0
- package/dist/research-FZ63UZTE.js.map +1 -0
- package/dist/research-YGQQ6CNG.js +262 -0
- package/dist/research-YGQQ6CNG.js.map +1 -0
- package/dist/reset-BGPZ4HMA.js +54 -0
- package/dist/reset-BGPZ4HMA.js.map +1 -0
- package/dist/reset-HTD6LCIT.js +54 -0
- package/dist/reset-HTD6LCIT.js.map +1 -0
- package/dist/resolve-NRDZ6N2B.js +121 -0
- package/dist/resolve-NRDZ6N2B.js.map +1 -0
- package/dist/retry-PF4BGKJV.js +60 -0
- package/dist/retry-PF4BGKJV.js.map +1 -0
- package/dist/retry-XL26JDAV.js +62 -0
- package/dist/retry-XL26JDAV.js.map +1 -0
- package/dist/retry-failed-BEFWRV4Z.js +45 -0
- package/dist/retry-failed-BEFWRV4Z.js.map +1 -0
- package/dist/run-3ZDGCCTH.js +61 -0
- package/dist/run-3ZDGCCTH.js.map +1 -0
- package/dist/run-EMJLI7LR.js +65 -0
- package/dist/run-EMJLI7LR.js.map +1 -0
- package/dist/scaffold-ad-QW75LLYR.js +1550 -0
- package/dist/scaffold-ad-QW75LLYR.js.map +1 -0
- package/dist/scaffold-static-ad-S3UOKLJ3.js +973 -0
- package/dist/scaffold-static-ad-S3UOKLJ3.js.map +1 -0
- package/dist/scaffold-video-3BJQOUAA.js +874 -0
- package/dist/scaffold-video-3BJQOUAA.js.map +1 -0
- package/dist/schedule-KQ7UIR3N.js +66 -0
- package/dist/schedule-KQ7UIR3N.js.map +1 -0
- package/dist/schedule-PKPNSISL.js +61 -0
- package/dist/schedule-PKPNSISL.js.map +1 -0
- package/dist/scheduled-agents-LP5LITA3.js +49 -0
- package/dist/scheduled-agents-LP5LITA3.js.map +1 -0
- package/dist/schema-B6J6VPTO.js +132 -0
- package/dist/schema-B6J6VPTO.js.map +1 -0
- package/dist/schema-QXTDLZVC.js +63 -0
- package/dist/schema-QXTDLZVC.js.map +1 -0
- package/dist/scrape-7YKJWFZE.js +2241 -0
- package/dist/scrape-7YKJWFZE.js.map +1 -0
- package/dist/screenshot-ZHBSG3SI.js +102 -0
- package/dist/screenshot-ZHBSG3SI.js.map +1 -0
- package/dist/search-332KFYZ6.js +224 -0
- package/dist/search-332KFYZ6.js.map +1 -0
- package/dist/search-4PBMXXUY.js +91 -0
- package/dist/search-4PBMXXUY.js.map +1 -0
- package/dist/search-6WNUKCMP.js +174 -0
- package/dist/search-6WNUKCMP.js.map +1 -0
- package/dist/search-AVNUU6TJ.js +26 -0
- package/dist/search-AVNUU6TJ.js.map +1 -0
- package/dist/search-F5INRFFK.js +92 -0
- package/dist/search-F5INRFFK.js.map +1 -0
- package/dist/search-copy-DZVBYG2B.js +168 -0
- package/dist/search-copy-DZVBYG2B.js.map +1 -0
- package/dist/seeds-5JTQN5WI.js +101 -0
- package/dist/seeds-5JTQN5WI.js.map +1 -0
- package/dist/select-2V6CHATD.js +96 -0
- package/dist/select-2V6CHATD.js.map +1 -0
- package/dist/sends-3L6QBS46.js +309 -0
- package/dist/sends-3L6QBS46.js.map +1 -0
- package/dist/sequences-YKFV7BDH.js +146 -0
- package/dist/sequences-YKFV7BDH.js.map +1 -0
- package/dist/set-prompt-XGZXW63I.js +188 -0
- package/dist/set-prompt-XGZXW63I.js.map +1 -0
- package/dist/setup-links-6H5ONDCQ.js +141 -0
- package/dist/setup-links-6H5ONDCQ.js.map +1 -0
- package/dist/{shared-6762QE6R.js → shared-QAMP7FZV.js} +8 -6
- package/dist/shared-QAMP7FZV.js.map +1 -0
- package/dist/shopify-D3GNV5O6.js +3715 -0
- package/dist/shopify-D3GNV5O6.js.map +1 -0
- package/dist/site-TBPERLY3.js +177 -0
- package/dist/site-TBPERLY3.js.map +1 -0
- package/dist/sitemaps-XPGLW24S.js +87 -0
- package/dist/sitemaps-XPGLW24S.js.map +1 -0
- package/dist/sites-WMBY2HJV.js +101 -0
- package/dist/sites-WMBY2HJV.js.map +1 -0
- package/dist/skills-3HEILQCU.js +47 -0
- package/dist/skills-3HEILQCU.js.map +1 -0
- package/dist/sources-JFQKTK2L.js +421 -0
- package/dist/sources-JFQKTK2L.js.map +1 -0
- package/dist/sources-Q3I6DDV7.js +30 -0
- package/dist/sources-Q3I6DDV7.js.map +1 -0
- package/dist/stale-4SERZW2D.js +66 -0
- package/dist/stale-4SERZW2D.js.map +1 -0
- package/dist/stats-GNILHSKK.js +34 -0
- package/dist/stats-GNILHSKK.js.map +1 -0
- package/dist/status-LIZWJYS4.js +62 -0
- package/dist/status-LIZWJYS4.js.map +1 -0
- package/dist/sticker-KCV3VZHY.js +94 -0
- package/dist/sticker-KCV3VZHY.js.map +1 -0
- package/dist/stock-VTORKR4C.js +179 -0
- package/dist/stock-VTORKR4C.js.map +1 -0
- package/dist/studio-QCRA6BY5.js +49 -0
- package/dist/studio-QCRA6BY5.js.map +1 -0
- package/dist/sync-455DB46Y.js +54 -0
- package/dist/sync-455DB46Y.js.map +1 -0
- package/dist/sync-A4KKQ3B6.js +265 -0
- package/dist/sync-A4KKQ3B6.js.map +1 -0
- package/dist/sync-ULKWDFXM.js +54 -0
- package/dist/sync-ULKWDFXM.js.map +1 -0
- package/dist/sync-definition-YTBLMLX2.js +55 -0
- package/dist/sync-definition-YTBLMLX2.js.map +1 -0
- package/dist/tag-manager-E7QTXBWQ.js +43 -0
- package/dist/tag-manager-E7QTXBWQ.js.map +1 -0
- package/dist/tags-4Q4I5GQJ.js +20 -0
- package/dist/tags-4Q4I5GQJ.js.map +1 -0
- package/dist/tags-AMEVAQZ4.js +26 -0
- package/dist/tags-AMEVAQZ4.js.map +1 -0
- package/dist/tags-DPLOLH3E.js +20 -0
- package/dist/tags-DPLOLH3E.js.map +1 -0
- package/dist/tags-LDHXONR3.js +224 -0
- package/dist/tags-LDHXONR3.js.map +1 -0
- package/dist/tags-UW3WJTAQ.js +20 -0
- package/dist/tags-UW3WJTAQ.js.map +1 -0
- package/dist/targeting-constants-D64YO3E7.js +118 -0
- package/dist/targeting-constants-D64YO3E7.js.map +1 -0
- package/dist/targeting-criteria-BP6VJA7X.js +113 -0
- package/dist/targeting-criteria-BP6VJA7X.js.map +1 -0
- package/dist/targets-CQWO2UXD.js +102 -0
- package/dist/targets-CQWO2UXD.js.map +1 -0
- package/dist/templates-WZSTNRNZ.js +178 -0
- package/dist/templates-WZSTNRNZ.js.map +1 -0
- package/dist/testimonials-ETHSNWUH.js +32 -0
- package/dist/testimonials-ETHSNWUH.js.map +1 -0
- package/dist/themes-YU663LQH.js +94 -0
- package/dist/themes-YU663LQH.js.map +1 -0
- package/dist/top-companies-KTXHS472.js +108 -0
- package/dist/top-companies-KTXHS472.js.map +1 -0
- package/dist/translate-6QAJ5ZUU.js +600 -0
- package/dist/translate-6QAJ5ZUU.js.map +1 -0
- package/dist/triggers-4EDFLNGH.js +141 -0
- package/dist/triggers-4EDFLNGH.js.map +1 -0
- package/dist/tweets-ZUKQAAUQ.js +123 -0
- package/dist/tweets-ZUKQAAUQ.js.map +1 -0
- package/dist/unfollow-A4JVCJBF.js +46 -0
- package/dist/unfollow-A4JVCJBF.js.map +1 -0
- package/dist/unlink-KY2OEKMD.js +67 -0
- package/dist/unlink-KY2OEKMD.js.map +1 -0
- package/dist/unstage-FHUG67RI.js +84 -0
- package/dist/unstage-FHUG67RI.js.map +1 -0
- package/dist/unstage-ZRLLCSQF.js +95 -0
- package/dist/unstage-ZRLLCSQF.js.map +1 -0
- package/dist/update-27LGM65V.js +63 -0
- package/dist/update-27LGM65V.js.map +1 -0
- package/dist/update-AIY46I2Q.js +155 -0
- package/dist/update-AIY46I2Q.js.map +1 -0
- package/dist/update-QYD2XZFM.js +142 -0
- package/dist/update-QYD2XZFM.js.map +1 -0
- package/dist/update-W2OSRNFO.js +98 -0
- package/dist/update-W2OSRNFO.js.map +1 -0
- package/dist/upload-JGBTSKGH.js +126 -0
- package/dist/upload-JGBTSKGH.js.map +1 -0
- package/dist/upload-XEHWYMJG.js +150 -0
- package/dist/upload-XEHWYMJG.js.map +1 -0
- package/dist/upscale-I5P2OHTN.js +109 -0
- package/dist/upscale-I5P2OHTN.js.map +1 -0
- package/dist/url-options-QHGA42RP.js +130 -0
- package/dist/url-options-QHGA42RP.js.map +1 -0
- package/dist/url-params-NWSUHWRE.js +98 -0
- package/dist/url-params-NWSUHWRE.js.map +1 -0
- package/dist/use-U4HG2NF3.js +95 -0
- package/dist/use-U4HG2NF3.js.map +1 -0
- package/dist/validate-DOQ6AI62.js +91 -0
- package/dist/validate-DOQ6AI62.js.map +1 -0
- package/dist/variant-FOVE6URJ.js +338 -0
- package/dist/variant-FOVE6URJ.js.map +1 -0
- package/dist/videos-DP3VCSYG.js +39 -0
- package/dist/videos-DP3VCSYG.js.map +1 -0
- package/dist/view-HRI3FHCH.js +121 -0
- package/dist/view-HRI3FHCH.js.map +1 -0
- package/dist/viewer-check-JYUE24M6.js +68 -0
- package/dist/viewer-check-JYUE24M6.js.map +1 -0
- package/dist/web-AFUIWPFU.js +140 -0
- package/dist/web-AFUIWPFU.js.map +1 -0
- package/dist/winners-SMMDN6LW.js +113 -0
- package/dist/winners-SMMDN6LW.js.map +1 -0
- package/dist/winning-ads-PCIJUYVA.js +84 -0
- package/dist/winning-ads-PCIJUYVA.js.map +1 -0
- package/dist/write-commands-7Z34WG2J.js +206 -0
- package/dist/write-commands-7Z34WG2J.js.map +1 -0
- package/dist/write-commands-BLT2SEC4.js +713 -0
- package/dist/write-commands-BLT2SEC4.js.map +1 -0
- package/dist/write-commands-N4FSGRVQ.js +743 -0
- package/dist/write-commands-N4FSGRVQ.js.map +1 -0
- package/dist/write-commands-Q4MQ3BGM.js +1015 -0
- package/dist/write-commands-Q4MQ3BGM.js.map +1 -0
- package/dist/x-AUOZJNWE.js +47 -0
- package/dist/x-AUOZJNWE.js.map +1 -0
- package/package.json +9 -2
- package/dist/chunk-FGHMWBUD.js +0 -9989
- package/dist/chunk-FGHMWBUD.js.map +0 -1
- package/dist/chunk-HJEMOSPH.js +0 -1292
- package/dist/chunk-HJEMOSPH.js.map +0 -1
- package/dist/chunk-MF7YA62W.js.map +0 -1
- package/dist/chunk-VZEDAFAR.js.map +0 -1
- package/dist/chunk-XHC4LMK4.js.map +0 -1
- package/dist/client-GR6YL3YX.js +0 -17
- package/dist/output-NMQXZF3Z.js +0 -18
- /package/dist/{chunk-WLDM2TRF.js.map → chunk-TPXI2GCW.js.map} +0 -0
- /package/dist/{client-GR6YL3YX.js.map → chunk-YQSBHWOI.js.map} +0 -0
- /package/dist/{env-4P5HOGNA.js.map → client-26SAJ46D.js.map} +0 -0
- /package/dist/{output-NMQXZF3Z.js.map → connect-RXPMAJQI.js.map} +0 -0
- /package/dist/{shared-6762QE6R.js.map → customers-P6LLLJHK.js.map} +0 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DIRECT_ROUTE,
|
|
3
|
+
captureProxyCredentials,
|
|
4
|
+
childEnvWith,
|
|
5
|
+
plannedRoutes,
|
|
6
|
+
shouldEscalate
|
|
7
|
+
} from "./chunk-O6QKCJE4.js";
|
|
8
|
+
|
|
9
|
+
// src/lib/vimeoCookie.ts
|
|
10
|
+
import { writeFile } from "fs/promises";
|
|
11
|
+
import path from "path";
|
|
12
|
+
var COOKIE_NAME = "vimeo";
|
|
13
|
+
async function writeVimeoCookieFile(cookie, workDir) {
|
|
14
|
+
const value = cookie?.trim();
|
|
15
|
+
if (!value) return void 0;
|
|
16
|
+
const expires = Math.floor(Date.now() / 1e3) + 365 * 24 * 60 * 60;
|
|
17
|
+
const jar = [
|
|
18
|
+
"# Netscape HTTP Cookie File",
|
|
19
|
+
[".vimeo.com", "TRUE", "/", "TRUE", String(expires), COOKIE_NAME, value].join(" "),
|
|
20
|
+
""
|
|
21
|
+
].join("\n");
|
|
22
|
+
const filePath = path.join(workDir, "vimeo-cookies.txt");
|
|
23
|
+
await writeFile(filePath, jar, { mode: 384 });
|
|
24
|
+
return filePath;
|
|
25
|
+
}
|
|
26
|
+
var VIMEO_AUTH_SIGNATURES = ["oauth token", "only works when logged-in", "unable to fetch new oauth tokens"];
|
|
27
|
+
function isVimeoAuthFailure(detail) {
|
|
28
|
+
const haystack = detail.toLowerCase();
|
|
29
|
+
if (!haystack.includes("[vimeo]")) return false;
|
|
30
|
+
return VIMEO_AUTH_SIGNATURES.some((signature) => haystack.includes(signature));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/lib/ytDlpSignal.ts
|
|
34
|
+
var HTTP_ERROR = /HTTP Error (\d{3})/i;
|
|
35
|
+
var CHALLENGE_PHRASES = [
|
|
36
|
+
"sign in to confirm you're not a bot",
|
|
37
|
+
"sign in to confirm you\u2019re not a bot",
|
|
38
|
+
"confirm you are not a bot",
|
|
39
|
+
"unusual traffic",
|
|
40
|
+
"captcha"
|
|
41
|
+
];
|
|
42
|
+
var NOT_A_BLOCK_PHRASES = ["private video", "video unavailable", "members-only", "this video is available to"];
|
|
43
|
+
var PROXY_TUNNEL_FAILURE = /tunnel connection failed: 407|proxy authentication required|http error 407/i;
|
|
44
|
+
function ytDlpBlockSignal(stderr) {
|
|
45
|
+
const text = stderr.toLowerCase();
|
|
46
|
+
if (PROXY_TUNNEL_FAILURE.test(stderr)) return { status: 407 };
|
|
47
|
+
if (NOT_A_BLOCK_PHRASES.some((phrase) => text.includes(phrase))) return {};
|
|
48
|
+
const status = HTTP_ERROR.exec(stderr);
|
|
49
|
+
if (status) return { status: Number(status[1]) };
|
|
50
|
+
if (CHALLENGE_PHRASES.some((phrase) => text.includes(phrase))) return { challenge: true };
|
|
51
|
+
return {};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/lib/ytDlp.ts
|
|
55
|
+
import { spawn } from "child_process";
|
|
56
|
+
import { readdir, readFile } from "fs/promises";
|
|
57
|
+
import path2 from "path";
|
|
58
|
+
|
|
59
|
+
// src/lib/ytDlpFormat.ts
|
|
60
|
+
function videoFormatArgs(maxResolution) {
|
|
61
|
+
const sort = maxResolution ? ["-S", `res:${maxResolution}`] : [];
|
|
62
|
+
return ["--format", "bv*+ba/b", ...sort, "--merge-output-format", "mp4"];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/lib/ytDlpPlayerClient.ts
|
|
66
|
+
var YOUTUBE_FALLBACK_CLIENT_ARGS = ["--extractor-args", "youtube:player_client=android"];
|
|
67
|
+
var MEDIA_FETCH_REFUSED = "unable to download video data";
|
|
68
|
+
var YOUTUBE_HOSTS = ["youtube.com", "youtu.be"];
|
|
69
|
+
function isYouTube(url) {
|
|
70
|
+
let host;
|
|
71
|
+
try {
|
|
72
|
+
host = new URL(url).hostname.toLowerCase();
|
|
73
|
+
} catch {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
return YOUTUBE_HOSTS.some((known) => host === known || host.endsWith(`.${known}`));
|
|
77
|
+
}
|
|
78
|
+
function needsPlayerClientRetry(url, stderr) {
|
|
79
|
+
return isYouTube(url) && stderr.toLowerCase().includes(MEDIA_FETCH_REFUSED);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/lib/ytDlp.ts
|
|
83
|
+
var YT_DLP_BIN = "yt-dlp";
|
|
84
|
+
var YT_DLP_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
85
|
+
var YT_DLP_PROBE_TIMEOUT_MS = 60 * 1e3;
|
|
86
|
+
var TRUST_SYSTEM_CERTS = ["--compat-options", "no-certifi"];
|
|
87
|
+
var YtDlpError = class extends Error {
|
|
88
|
+
constructor(message, stderrTail) {
|
|
89
|
+
super(message);
|
|
90
|
+
this.stderrTail = stderrTail;
|
|
91
|
+
this.name = "YtDlpError";
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
function tail(text, maxLines) {
|
|
95
|
+
return text.split("\n").slice(-maxLines).join("\n");
|
|
96
|
+
}
|
|
97
|
+
async function runYtDlp(args) {
|
|
98
|
+
const outTemplate = path2.join(args.workDir, "out.%(ext)s");
|
|
99
|
+
const infoPath = path2.join(args.workDir, "out.info.json");
|
|
100
|
+
const argv = [
|
|
101
|
+
args.url,
|
|
102
|
+
"--no-playlist",
|
|
103
|
+
"--no-progress",
|
|
104
|
+
"--no-warnings",
|
|
105
|
+
"--quiet",
|
|
106
|
+
"--write-info-json",
|
|
107
|
+
...TRUST_SYSTEM_CERTS,
|
|
108
|
+
"-o",
|
|
109
|
+
outTemplate
|
|
110
|
+
];
|
|
111
|
+
if (args.audioOnly) {
|
|
112
|
+
argv.push("-x", "--audio-format", "m4a");
|
|
113
|
+
} else {
|
|
114
|
+
argv.push(...videoFormatArgs(args.maxHeight));
|
|
115
|
+
}
|
|
116
|
+
const cookieFile = await writeVimeoCookieFile(args.vimeoCookie, args.workDir);
|
|
117
|
+
if (cookieFile) argv.push("--cookies", cookieFile);
|
|
118
|
+
args.onLog?.(`yt-dlp: downloading ${args.audioOnly ? "audio" : "video"}`);
|
|
119
|
+
const timeoutMs = args.timeoutMs ?? YT_DLP_TIMEOUT_MS;
|
|
120
|
+
const { code, stderr, tier, reducedQuality } = await downloadWithClientFallback({
|
|
121
|
+
url: args.url,
|
|
122
|
+
argv,
|
|
123
|
+
onLog: args.onLog,
|
|
124
|
+
ladder: (attemptArgv) => runViaLadder({ url: args.url, argv: attemptArgv, timeoutMs, onLog: args.onLog, country: args.country }),
|
|
125
|
+
repeat: (attemptArgv, route) => spawnAndWait(YT_DLP_BIN, attemptArgv, timeoutMs, { extraEnv: proxyEnvFor(route) })
|
|
126
|
+
});
|
|
127
|
+
if (code !== 0) {
|
|
128
|
+
throw new YtDlpError(`yt-dlp exited ${code}`, tail(stderr, 40));
|
|
129
|
+
}
|
|
130
|
+
const files = await readdir(args.workDir);
|
|
131
|
+
const wanted = args.audioOnly ? ".m4a" : ".mp4";
|
|
132
|
+
const downloaded = files.find((f) => f.startsWith("out.") && f.endsWith(wanted));
|
|
133
|
+
if (!downloaded) {
|
|
134
|
+
throw new YtDlpError(`yt-dlp finished but produced no ${wanted} file (saw: ${files.join(", ")})`, "");
|
|
135
|
+
}
|
|
136
|
+
let info = {};
|
|
137
|
+
try {
|
|
138
|
+
info = JSON.parse(await readFile(infoPath, "utf-8"));
|
|
139
|
+
} catch {
|
|
140
|
+
}
|
|
141
|
+
return { filePath: path2.join(args.workDir, downloaded), info, tier, reducedQuality };
|
|
142
|
+
}
|
|
143
|
+
async function probeYtDlp(args) {
|
|
144
|
+
const argv = [
|
|
145
|
+
args.url,
|
|
146
|
+
"--no-playlist",
|
|
147
|
+
"--no-warnings",
|
|
148
|
+
"--dump-single-json",
|
|
149
|
+
"--skip-download",
|
|
150
|
+
// Without this the probe fails wherever the *download* would fail, which
|
|
151
|
+
// defeats the point of probing: yt-dlp still runs format selection for
|
|
152
|
+
// `--dump-single-json`, so a binary too old to read a site's format list
|
|
153
|
+
// exits "Requested format is not available" and we learn nothing — measured
|
|
154
|
+
// against a stale build, which returned full metadata the moment this flag
|
|
155
|
+
// was added. Duration and id come from the page, not from a format.
|
|
156
|
+
"--ignore-no-formats-error",
|
|
157
|
+
...TRUST_SYSTEM_CERTS
|
|
158
|
+
];
|
|
159
|
+
if (args.cookieDir) {
|
|
160
|
+
const cookieFile = await writeVimeoCookieFile(args.vimeoCookie, args.cookieDir);
|
|
161
|
+
if (cookieFile) argv.push("--cookies", cookieFile);
|
|
162
|
+
}
|
|
163
|
+
let stdout = "";
|
|
164
|
+
const { code, stderr, tier } = await walkYtDlpLadder({
|
|
165
|
+
url: args.url,
|
|
166
|
+
credentials: captureProxyCredentials(),
|
|
167
|
+
attempt: async (route) => {
|
|
168
|
+
const result = await spawnAndWait(YT_DLP_BIN, argv, args.timeoutMs ?? YT_DLP_PROBE_TIMEOUT_MS, {
|
|
169
|
+
extraEnv: proxyEnvFor(route),
|
|
170
|
+
captureStdout: true
|
|
171
|
+
});
|
|
172
|
+
stdout = result.stdout ?? "";
|
|
173
|
+
return result;
|
|
174
|
+
},
|
|
175
|
+
onLog: args.onLog,
|
|
176
|
+
country: args.country
|
|
177
|
+
});
|
|
178
|
+
if (code !== 0) {
|
|
179
|
+
throw new YtDlpError(`yt-dlp exited ${code}`, tail(stderr, 40));
|
|
180
|
+
}
|
|
181
|
+
let parsed;
|
|
182
|
+
try {
|
|
183
|
+
parsed = JSON.parse(stdout);
|
|
184
|
+
} catch {
|
|
185
|
+
throw new YtDlpError("yt-dlp returned metadata that could not be read", tail(stdout, 5));
|
|
186
|
+
}
|
|
187
|
+
if (parsed === null || typeof parsed !== "object") {
|
|
188
|
+
throw new YtDlpError("yt-dlp returned no metadata for that link", tail(stderr, 40));
|
|
189
|
+
}
|
|
190
|
+
return { info: parsed, tier };
|
|
191
|
+
}
|
|
192
|
+
function isAudioOnly(info) {
|
|
193
|
+
return info.vcodec === "none";
|
|
194
|
+
}
|
|
195
|
+
function durationSeconds(info) {
|
|
196
|
+
const raw = info.duration;
|
|
197
|
+
return typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : void 0;
|
|
198
|
+
}
|
|
199
|
+
function canonicalUrl(info) {
|
|
200
|
+
const raw = info.webpage_url;
|
|
201
|
+
return typeof raw === "string" && raw.length > 0 ? raw : void 0;
|
|
202
|
+
}
|
|
203
|
+
async function walkYtDlpLadder(args) {
|
|
204
|
+
const routes = plannedRoutes(args.url, args.credentials, args.country ? { country: args.country } : void 0);
|
|
205
|
+
let last = { code: -1, stderr: "", tier: "direct", route: DIRECT_ROUTE };
|
|
206
|
+
for (const route of routes) {
|
|
207
|
+
const tier = route.kind === "proxy" ? route.tier : "direct";
|
|
208
|
+
if (route.kind === "proxy") args.onLog?.(`yt-dlp: retrying via ${tier}`);
|
|
209
|
+
last = { ...await args.attempt(route), tier, route };
|
|
210
|
+
if (last.code === 0) return last;
|
|
211
|
+
if (!shouldEscalate(ytDlpBlockSignal(last.stderr))) return last;
|
|
212
|
+
}
|
|
213
|
+
return last;
|
|
214
|
+
}
|
|
215
|
+
async function downloadWithClientFallback(args) {
|
|
216
|
+
const first = await args.ladder(args.argv);
|
|
217
|
+
if (first.code === 0 || !needsPlayerClientRetry(args.url, first.stderr)) {
|
|
218
|
+
return { ...first, reducedQuality: false };
|
|
219
|
+
}
|
|
220
|
+
args.onLog?.("yt-dlp: retrying with the fallback player client");
|
|
221
|
+
const again = await args.repeat([...args.argv, ...YOUTUBE_FALLBACK_CLIENT_ARGS], first.route);
|
|
222
|
+
return { ...again, tier: first.tier, route: first.route, reducedQuality: again.code === 0 };
|
|
223
|
+
}
|
|
224
|
+
function runViaLadder(args) {
|
|
225
|
+
return walkYtDlpLadder({
|
|
226
|
+
url: args.url,
|
|
227
|
+
credentials: captureProxyCredentials(),
|
|
228
|
+
attempt: (route) => spawnAndWait(YT_DLP_BIN, args.argv, args.timeoutMs, { extraEnv: proxyEnvFor(route) }),
|
|
229
|
+
onLog: args.onLog,
|
|
230
|
+
country: args.country
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
function proxyEnvFor(route) {
|
|
234
|
+
if (route.kind !== "proxy") return void 0;
|
|
235
|
+
const uri = new URL(route.server);
|
|
236
|
+
uri.username = encodeURIComponent(route.username);
|
|
237
|
+
uri.password = encodeURIComponent(route.password);
|
|
238
|
+
return {
|
|
239
|
+
HTTP_PROXY: uri.toString(),
|
|
240
|
+
HTTPS_PROXY: uri.toString(),
|
|
241
|
+
http_proxy: uri.toString(),
|
|
242
|
+
https_proxy: uri.toString()
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function spawnAndWait(bin, argv, timeoutMs, options = {}) {
|
|
246
|
+
return new Promise((resolve, reject) => {
|
|
247
|
+
const child = spawn(bin, argv, {
|
|
248
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
249
|
+
// `childEnvWith` because `spawn`'s `env` REPLACES the environment rather
|
|
250
|
+
// than extending it — passing only the additions would strip PATH.
|
|
251
|
+
...options.extraEnv ? { env: childEnvWith(options.extraEnv) } : {}
|
|
252
|
+
});
|
|
253
|
+
const stderrChunks = [];
|
|
254
|
+
const stdoutChunks = [];
|
|
255
|
+
let stderrLen = 0;
|
|
256
|
+
const MAX_STDERR = 256 * 1024;
|
|
257
|
+
child.stdout.on("data", (chunk) => {
|
|
258
|
+
if (options.captureStdout) stdoutChunks.push(chunk);
|
|
259
|
+
});
|
|
260
|
+
child.stderr.on("data", (chunk) => {
|
|
261
|
+
if (stderrLen < MAX_STDERR) {
|
|
262
|
+
stderrChunks.push(chunk);
|
|
263
|
+
stderrLen += chunk.length;
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
const timer = setTimeout(() => {
|
|
267
|
+
child.kill("SIGKILL");
|
|
268
|
+
reject(new Error(`${bin} timed out after ${timeoutMs}ms`));
|
|
269
|
+
}, timeoutMs);
|
|
270
|
+
child.on("error", (err) => {
|
|
271
|
+
clearTimeout(timer);
|
|
272
|
+
reject(new Error(`failed to spawn "${bin}" \u2014 ${err.message}`));
|
|
273
|
+
});
|
|
274
|
+
child.on("close", (code) => {
|
|
275
|
+
clearTimeout(timer);
|
|
276
|
+
resolve({
|
|
277
|
+
code: code ?? -1,
|
|
278
|
+
stderr: Buffer.concat(stderrChunks).toString("utf-8"),
|
|
279
|
+
...options.captureStdout ? { stdout: Buffer.concat(stdoutChunks).toString("utf-8") } : {}
|
|
280
|
+
});
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export {
|
|
286
|
+
isVimeoAuthFailure,
|
|
287
|
+
ytDlpBlockSignal,
|
|
288
|
+
YT_DLP_BIN,
|
|
289
|
+
YtDlpError,
|
|
290
|
+
runYtDlp,
|
|
291
|
+
probeYtDlp,
|
|
292
|
+
isAudioOnly,
|
|
293
|
+
durationSeconds,
|
|
294
|
+
canonicalUrl
|
|
295
|
+
};
|
|
296
|
+
//# sourceMappingURL=chunk-DX4GIDO7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/vimeoCookie.ts","../src/lib/ytDlpSignal.ts","../src/lib/ytDlp.ts","../src/lib/ytDlpFormat.ts","../src/lib/ytDlpPlayerClient.ts"],"sourcesContent":["import { writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\n\n/**\n * Vimeo's session cookie, as a file yt-dlp can read.\n *\n * Vimeo is the only platform with no anonymous route left: every yt-dlp client\n * either cannot mint a token any more or refuses without a login, and the\n * failure is identical through direct, datacenter and residential exits, so it\n * is neither our IP nor our TLS fingerprint. A logged-in cookie is the whole\n * fix — measured, `vimeo` alone is sufficient and `vuid`/`auth_xsrft` without it\n * are worthless.\n *\n * The cookie arrives as a value, never as a path: the backend owns the secret\n * and the sandbox owns its filesystem, so nothing outside writes into the\n * Runtime. `--cookies <path>` then puts only the path in argv, keeping the\n * credential out of `ps` — the same rule that governs proxy passwords.\n */\n\n/** The single cookie yt-dlp's `_is_logged_in` actually checks. */\nconst COOKIE_NAME = \"vimeo\";\n\n/**\n * Write the cookie jar, returning its path — or undefined when unconfigured.\n *\n * Undefined rather than an empty file, because an empty jar is not the same as\n * no jar: yt-dlp would read it, find no session, and fail with the anonymous\n * error while looking as though credentials had been supplied.\n */\nexport async function writeVimeoCookieFile(cookie: string | undefined, workDir: string): Promise<string | undefined> {\n const value = cookie?.trim();\n if (!value) return undefined;\n\n // A year out. The jar's own expiry is a formality — Vimeo expires the session\n // server-side on its own schedule, and `isVimeoAuthFailure` is what notices.\n const expires = Math.floor(Date.now() / 1000) + 365 * 24 * 60 * 60;\n const jar = [\n \"# Netscape HTTP Cookie File\",\n [\".vimeo.com\", \"TRUE\", \"/\", \"TRUE\", String(expires), COOKIE_NAME, value].join(\"\\t\"),\n \"\",\n ].join(\"\\n\");\n\n const filePath = path.join(workDir, \"vimeo-cookies.txt\");\n // 0o600 at creation, not chmod-after: the sandbox runs the agent's own shell,\n // and a world-readable window between write and chmod is a window.\n await writeFile(filePath, jar, { mode: 0o600 });\n return filePath;\n}\n\n/**\n * Whether a Vimeo failure is about authentication rather than the video.\n *\n * Every one of these phrasings means the same thing to whoever pasted the link —\n * Vimeo would not talk to us — but Vimeo's own wording (\"Failed to fetch macos\n * OAuth token\") names an internal detail that sends the reader nowhere. The\n * distinction earns its place because this credential *expires*: without it, the\n * day the cookie lapses looks like a brand-new mystery instead of a five-minute\n * re-export.\n *\n * Scoped to `[vimeo]` so another platform's 401 cannot inherit advice about a\n * cookie that has nothing to do with it.\n */\nconst VIMEO_AUTH_SIGNATURES = [\"oauth token\", \"only works when logged-in\", \"unable to fetch new oauth tokens\"] as const;\n\nexport function isVimeoAuthFailure(detail: string): boolean {\n const haystack = detail.toLowerCase();\n if (!haystack.includes(\"[vimeo]\")) return false;\n return VIMEO_AUTH_SIGNATURES.some((signature) => haystack.includes(signature));\n}\n","import type { BlockSignal } from \"@baker/proxy\";\n\n/**\n * yt-dlp's stderr, read as the same signal every other surface produces.\n *\n * Deliberately only extraction — `shouldEscalate` still makes the decision, so\n * yt-dlp cannot drift into its own private idea of what a block is. The two\n * halves have to stay separate: a downloader that decided for itself would be\n * the one surface where a 404 could cost money.\n *\n * The parsing exists because yt-dlp gives us prose and an exit code, not a\n * response. There is no status line to read, so the status has to be recovered\n * from the sentence it was printed into.\n */\n\n/** `HTTP Error 403: Forbidden`, in any of the shapes yt-dlp writes it. */\nconst HTTP_ERROR = /HTTP Error (\\d{3})/i;\n\n/**\n * Refusals that arrive as prose with no status at all.\n *\n * YouTube's bot check is the one that matters: it is the single most common\n * reason a datacenter IP fails a download that a residential one completes, and\n * it looks like an ordinary successful page to everything except a human\n * reading the text.\n */\nconst CHALLENGE_PHRASES = [\n \"sign in to confirm you're not a bot\",\n \"sign in to confirm you’re not a bot\",\n \"confirm you are not a bot\",\n \"unusual traffic\",\n \"captcha\",\n];\n\n/**\n * Prose that must never escalate, checked *before* the phrases above.\n *\n * \"Private video. Sign in if you've been granted access\" contains a sign-in\n * demand and is not a block — no exit IP on earth opens it, and treating it as\n * one would spend the expensive rung on every private link an agent is handed.\n */\nconst NOT_A_BLOCK_PHRASES = [\"private video\", \"video unavailable\", \"members-only\", \"this video is available to\"];\n\n/**\n * Our own proxy refusing us, which yt-dlp writes without an `HTTP Error` prefix.\n *\n * Checked before everything else. A 407 cannot come from an origin server, so\n * recovering it is what lets `isProxyFailure` separate \"the platform's egress\n * credentials are wrong\" from \"this site blocked us\" — opposite remediations,\n * and the first is otherwise invisible: a rotated password reads downstream as\n * every site having simultaneously started refusing us.\n */\nconst PROXY_TUNNEL_FAILURE = /tunnel connection failed: 407|proxy authentication required|http error 407/i;\n\nexport function ytDlpBlockSignal(stderr: string): BlockSignal {\n const text = stderr.toLowerCase();\n\n if (PROXY_TUNNEL_FAILURE.test(stderr)) return { status: 407 };\n\n if (NOT_A_BLOCK_PHRASES.some((phrase) => text.includes(phrase))) return {};\n\n // First, not last. yt-dlp prints a line per retry, so the final line is\n // usually \"giving up after 3 retries\" — the verdict that started the sequence\n // is the one that says why.\n const status = HTTP_ERROR.exec(stderr);\n if (status) return { status: Number(status[1]) };\n\n if (CHALLENGE_PHRASES.some((phrase) => text.includes(phrase))) return { challenge: true };\n return {};\n}\n","import { spawn } from \"node:child_process\";\nimport { readdir, readFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ProxyCredentials, ProxyRoute, ProxyTier } from \"@baker/proxy\";\nimport { DIRECT_ROUTE, plannedRoutes, shouldEscalate } from \"@baker/proxy\";\nimport { captureProxyCredentials, childEnvWith } from \"../env.ts\";\nimport { writeVimeoCookieFile } from \"./vimeoCookie.ts\";\nimport { videoFormatArgs } from \"./ytDlpFormat.ts\";\nimport { needsPlayerClientRetry, YOUTUBE_FALLBACK_CLIENT_ARGS } from \"./ytDlpPlayerClient.ts\";\nimport { ytDlpBlockSignal } from \"./ytDlpSignal.ts\";\n\n/**\n * yt-dlp, run through the egress ladder, shared by the canvas `ingest` node and\n * `baker videos ingest`.\n *\n * Both download the same kinds of URL from the same sandbox and must agree about\n * what \"blocked\" means and how a credential is written down — and the second of\n * those is a decision that silently means two different passwords if it is made\n * twice (see `proxyEnvFor`). One copy is the point.\n *\n * Callers own how a failure is reported: the node wraps `YtDlpError` in a\n * `NodeExecutionError`, the command turns it into a `{ ok: false }` envelope.\n */\n\nexport const YT_DLP_BIN = \"yt-dlp\";\nexport const YT_DLP_TIMEOUT_MS = 10 * 60 * 1000;\n/** A probe fetches no media, so it gets a much shorter leash than a download. */\nexport const YT_DLP_PROBE_TIMEOUT_MS = 60 * 1000;\n\nexport type YtDlpInfo = Record<string, unknown>;\n\n/**\n * Verify TLS against the system bundle, never certifi's.\n *\n * The Runtime reads HTTPS through the credential broker, and the broker's CA is\n * installed in the system bundle (`SSL_CERT_FILE`) and nowhere else. yt-dlp is\n * installed with certifi and, left alone, verifies against certifi's own copy —\n * so once the broker shipped, every direct download in a Runtime failed with\n * `CERTIFICATE_VERIFY_FAILED` while `curl` to the same host answered. The agent\n * that hit it on our own CDN worked around it by pointing a committed canvas at\n * its gitignored local cache, which broke the next Session's publish. The\n * impersonating (curl_cffi) path reads `CURL_CA_BUNDLE`, which the broker also\n * sets, so it needs nothing here.\n */\nconst TRUST_SYSTEM_CERTS = [\"--compat-options\", \"no-certifi\"] as const;\n\nexport class YtDlpError extends Error {\n constructor(\n message: string,\n readonly stderrTail: string,\n ) {\n super(message);\n this.name = \"YtDlpError\";\n }\n}\n\nexport function tail(text: string, maxLines: number): string {\n return text.split(\"\\n\").slice(-maxLines).join(\"\\n\");\n}\n\n/**\n * Download `url` into `workDir`, climbing to a paid exit only if the host\n * refused the cheaper one. Returns the media file and yt-dlp's info.json\n * (best-effort — yt-dlp omits it for some direct file URLs).\n *\n * By default the best the site will release: `bv*+ba/b`. There used to be an\n * optional height cap here, on the reasoning that a 4K master is bytes we\n * re-encode anyway — but both callers now want the master, because capping\n * discards source pixels before the systems that make renditions from them ever\n * see them, and that loss is permanent while the saving is one download.\n * The one exception is opt-in: a bulk import may pass `maxHeight`.\n */\nexport async function runYtDlp(args: {\n url: string;\n audioOnly: boolean;\n workDir: string;\n timeoutMs?: number;\n onLog?: (message: string) => void;\n country?: string;\n /** Vimeo session cookie value; written to a jar in `workDir` when present. */\n vimeoCookie?: string;\n /** Opt-in resolution cap (shorter side) for bulk imports — see `videoFormatArgs`. */\n maxHeight?: number;\n}): Promise<{ filePath: string; info: YtDlpInfo; tier: EgressTier; reducedQuality: boolean }> {\n const outTemplate = path.join(args.workDir, \"out.%(ext)s\");\n const infoPath = path.join(args.workDir, \"out.info.json\");\n\n const argv: string[] = [\n args.url,\n \"--no-playlist\",\n \"--no-progress\",\n \"--no-warnings\",\n \"--quiet\",\n \"--write-info-json\",\n ...TRUST_SYSTEM_CERTS,\n \"-o\",\n outTemplate,\n ];\n\n if (args.audioOnly) {\n argv.push(\"-x\", \"--audio-format\", \"m4a\");\n } else {\n argv.push(...videoFormatArgs(args.maxHeight));\n }\n\n const cookieFile = await writeVimeoCookieFile(args.vimeoCookie, args.workDir);\n if (cookieFile) argv.push(\"--cookies\", cookieFile);\n\n args.onLog?.(`yt-dlp: downloading ${args.audioOnly ? \"audio\" : \"video\"}`);\n const timeoutMs = args.timeoutMs ?? YT_DLP_TIMEOUT_MS;\n const { code, stderr, tier, reducedQuality } = await downloadWithClientFallback({\n url: args.url,\n argv,\n onLog: args.onLog,\n ladder: (attemptArgv) =>\n runViaLadder({ url: args.url, argv: attemptArgv, timeoutMs, onLog: args.onLog, country: args.country }),\n repeat: (attemptArgv, route) => spawnAndWait(YT_DLP_BIN, attemptArgv, timeoutMs, { extraEnv: proxyEnvFor(route) }),\n });\n\n if (code !== 0) {\n throw new YtDlpError(`yt-dlp exited ${code}`, tail(stderr, 40));\n }\n\n const files = await readdir(args.workDir);\n const wanted = args.audioOnly ? \".m4a\" : \".mp4\";\n const downloaded = files.find((f) => f.startsWith(\"out.\") && f.endsWith(wanted));\n if (!downloaded) {\n throw new YtDlpError(`yt-dlp finished but produced no ${wanted} file (saw: ${files.join(\", \")})`, \"\");\n }\n\n let info: YtDlpInfo = {};\n try {\n info = JSON.parse(await readFile(infoPath, \"utf-8\")) as YtDlpInfo;\n } catch {\n // info.json is best-effort — yt-dlp sometimes omits it for direct file URLs.\n }\n\n return { filePath: path.join(args.workDir, downloaded), info, tier, reducedQuality };\n}\n\n/**\n * Read a URL's metadata without fetching any media.\n *\n * Worth its own round trip because it settles the one thing that has to be known\n * before the expensive part starts: how long the video is. Measured, a ten-hour\n * link is now refused in ~3s, where the byte ceiling it replaced could only\n * refuse it after the download it was meant to avoid. It also carries the\n * provider id, which used to be readable only from the download's own info.json.\n *\n * Climbs the same egress ladder as the download, so a host that answers only a\n * paid exit is probed through one too.\n */\nexport async function probeYtDlp(args: {\n url: string;\n timeoutMs?: number;\n onLog?: (message: string) => void;\n country?: string;\n /** Vimeo session cookie value. `cookieDir` must be set for it to be used. */\n vimeoCookie?: string;\n cookieDir?: string;\n}): Promise<{ info: YtDlpInfo; tier: EgressTier }> {\n const argv = [\n args.url,\n \"--no-playlist\",\n \"--no-warnings\",\n \"--dump-single-json\",\n \"--skip-download\",\n // Without this the probe fails wherever the *download* would fail, which\n // defeats the point of probing: yt-dlp still runs format selection for\n // `--dump-single-json`, so a binary too old to read a site's format list\n // exits \"Requested format is not available\" and we learn nothing — measured\n // against a stale build, which returned full metadata the moment this flag\n // was added. Duration and id come from the page, not from a format.\n \"--ignore-no-formats-error\",\n ...TRUST_SYSTEM_CERTS,\n ];\n\n // The probe needs the same credential as the download: Vimeo refuses metadata\n // to an anonymous caller too, so probing without it fails before the duration\n // gate ever runs.\n if (args.cookieDir) {\n const cookieFile = await writeVimeoCookieFile(args.vimeoCookie, args.cookieDir);\n if (cookieFile) argv.push(\"--cookies\", cookieFile);\n }\n\n let stdout = \"\";\n const { code, stderr, tier } = await walkYtDlpLadder({\n url: args.url,\n credentials: captureProxyCredentials(),\n attempt: async (route) => {\n const result = await spawnAndWait(YT_DLP_BIN, argv, args.timeoutMs ?? YT_DLP_PROBE_TIMEOUT_MS, {\n extraEnv: proxyEnvFor(route),\n captureStdout: true,\n });\n stdout = result.stdout ?? \"\";\n return result;\n },\n onLog: args.onLog,\n country: args.country,\n });\n\n if (code !== 0) {\n throw new YtDlpError(`yt-dlp exited ${code}`, tail(stderr, 40));\n }\n\n // Parsed, not trusted: yt-dlp prints a bare `null` for a page it recognised\n // but could not extract, and on at least one site it pairs that with a\n // non-zero exit — so the exit code alone is not enough to promise an object.\n let parsed: unknown;\n try {\n parsed = JSON.parse(stdout);\n } catch {\n throw new YtDlpError(\"yt-dlp returned metadata that could not be read\", tail(stdout, 5));\n }\n if (parsed === null || typeof parsed !== \"object\") {\n throw new YtDlpError(\"yt-dlp returned no metadata for that link\", tail(stderr, 40));\n }\n return { info: parsed as YtDlpInfo, tier };\n}\n\n/**\n * True only when the source explicitly says it carries no video.\n *\n * `vcodec: \"none\"` is the assertion; a *missing* vcodec is not, and that\n * distinction is the whole function. Measured: SoundCloud reports `\"none\"`,\n * while Streamable reports `null` and is perfectly good video. The obvious\n * version of this check — \"no format has a video codec\" — matches both and\n * would refuse Streamable, which ingests fine today.\n *\n * Caught at probe time because the alternative is what it replaces: the\n * download succeeds, produces an `.m4a`, and the caller fails looking for an\n * `.mp4` — surfaced as \"yt-dlp finished but produced no .mp4 file\", which names\n * an internal expectation rather than the fact that someone linked to audio.\n */\nexport function isAudioOnly(info: YtDlpInfo): boolean {\n return info.vcodec === \"none\";\n}\n\n/** The probed duration in seconds, when the site reported one that can be read. */\nexport function durationSeconds(info: YtDlpInfo): number | undefined {\n const raw = info.duration;\n return typeof raw === \"number\" && Number.isFinite(raw) && raw > 0 ? raw : undefined;\n}\n\n/**\n * The canonical page URL for what was probed, when the extractor resolved one.\n *\n * Worth preferring over the URL a person pasted, because yt-dlp has already done\n * the normalising: measured, it turns `youtu.be/<id>?si=…&t=42`,\n * `/shorts/<id>` and `m.youtube.com/watch?v=<id>&feature=share` all into the one\n * `www.youtube.com/watch?v=<id>`. Storing the raw paste instead files the same\n * video under a different `externalUrl` depending on where the link was copied\n * from, which is exactly the provenance question this field exists to answer.\n */\nexport function canonicalUrl(info: YtDlpInfo): string | undefined {\n const raw = info.webpage_url;\n return typeof raw === \"string\" && raw.length > 0 ? raw : undefined;\n}\n\n/**\n * Walk the ladder: direct first, then each configured tier, stopping the moment\n * the failure is one a different exit IP cannot fix.\n *\n * The escalation decision is `shouldEscalate`'s, not ours — the same closed\n * allow-list every other egress surface uses. A downloader that decided for\n * itself would be the one surface where a 404 could cost money.\n */\nexport type EgressTier = \"direct\" | ProxyTier;\n\n/**\n * Which rung produced this result — so a paid exit is never spent invisibly.\n *\n * The `route` is here, and not just the tier's name, because one caller needs to\n * *repeat* the rung rather than merely report it: the player-client fallback\n * re-runs on whichever exit already got far enough to be refused at the media\n * stage. A name cannot be handed back to `proxyEnvFor`; the route can.\n */\nexport type LadderResult = SpawnResult & { tier: EgressTier; route: ProxyRoute };\n\nexport async function walkYtDlpLadder(args: {\n url: string;\n credentials: ProxyCredentials;\n attempt: (route: ProxyRoute) => Promise<SpawnResult>;\n onLog?: (message: string) => void;\n /**\n * ISO-3166 alpha-2 exit country for the paid rungs. Omit for \"wherever\".\n *\n * Not inferred and never automatic: a country is only right when someone\n * knows *which* one opens the video, and guessing would multiply the cost of\n * every failure by the length of the guess list. `@baker/proxy` owns the\n * per-product syntax — datacenter and residential spell geo differently and\n * each rejects the other's token.\n */\n country?: string;\n}): Promise<LadderResult> {\n const routes = plannedRoutes(args.url, args.credentials, args.country ? { country: args.country } : undefined);\n let last: LadderResult = { code: -1, stderr: \"\", tier: \"direct\", route: DIRECT_ROUTE };\n\n for (const route of routes) {\n const tier: EgressTier = route.kind === \"proxy\" ? route.tier : \"direct\";\n if (route.kind === \"proxy\") args.onLog?.(`yt-dlp: retrying via ${tier}`);\n last = { ...(await args.attempt(route)), tier, route };\n if (last.code === 0) return last;\n if (!shouldEscalate(ytDlpBlockSignal(last.stderr))) return last;\n }\n return last;\n}\n\n/**\n * The download, plus the one retry that changes the player instead of the exit.\n *\n * Split out from `runYtDlp` with its two runners injected because the decision\n * this makes is the expensive one to get wrong and the hardest to observe: it\n * spends egress. A test can drive both branches here; it cannot drive them\n * through a function that spawns a binary.\n *\n * **The retry repeats one rung and opens no new one.** It re-runs on\n * `first.route` — whichever exit already got far enough to be refused at the\n * media stage — rather than walking the ladder again. Walking it again was the\n * first version of this and it was wrong in exactly the way this whole change\n * exists to stop: the trigger is a 403, `shouldEscalate` treats a 403 as\n * escalatable, so a fallback client that was also refused would climb through\n * datacenter and residential a second time, paying twice more for a verdict\n * that has already been shown not to depend on the address. Re-using the rung\n * is also what makes the retry correct when the *only* rung that reached the\n * media stage was a paid one — a direct-only retry would land back on the bot\n * wall that made us leave direct in the first place.\n */\nexport async function downloadWithClientFallback(args: {\n url: string;\n argv: readonly string[];\n ladder: (argv: readonly string[]) => Promise<LadderResult>;\n repeat: (argv: readonly string[], route: ProxyRoute) => Promise<SpawnResult>;\n onLog?: (message: string) => void;\n}): Promise<LadderResult & { reducedQuality: boolean }> {\n const first = await args.ladder(args.argv);\n if (first.code === 0 || !needsPlayerClientRetry(args.url, first.stderr)) {\n return { ...first, reducedQuality: false };\n }\n\n args.onLog?.(\"yt-dlp: retrying with the fallback player client\");\n const again = await args.repeat([...args.argv, ...YOUTUBE_FALLBACK_CLIENT_ARGS], first.route);\n\n // `tier` and `route` stay the first attempt's: the retry deliberately did not\n // move, so reporting a different rung would misstate what was spent.\n return { ...again, tier: first.tier, route: first.route, reducedQuality: again.code === 0 };\n}\n\nfunction runViaLadder(args: {\n url: string;\n argv: readonly string[];\n timeoutMs: number;\n onLog?: (message: string) => void;\n country?: string;\n}): Promise<LadderResult> {\n return walkYtDlpLadder({\n url: args.url,\n credentials: captureProxyCredentials(),\n attempt: (route) => spawnAndWait(YT_DLP_BIN, args.argv, args.timeoutMs, { extraEnv: proxyEnvFor(route) }),\n onLog: args.onLog,\n country: args.country,\n });\n}\n\n/**\n * A route as the environment a child process reads it from.\n *\n * Env, never `--proxy`: the flag would put the password in `argv`, readable by\n * any `ps` sharing the sandbox and printed by yt-dlp into the very stderr this\n * module reads back and attaches to an error. Both spellings, because \"which\n * case does this tool read\" is not worth being wrong about once — and `NO_PROXY`\n * is deliberately unset, since `plannedRoutes` has already refused to build a\n * proxy route for a private address.\n *\n * The percent-encoding is correct here and is deliberately **not** the same\n * decision as `browserProxyUrl` in `@baker/proxy`. Measured against both readers\n * with a proxy that logs what it receives: given `ab%3Dcd`, yt-dlp (Python)\n * authenticates as `ab=cd` — it decodes — while Chromium authenticates as the\n * literal `ab%3Dcd`. The same URL means two different passwords depending on who\n * reads it, so each side is written for its own reader. Do not harmonise them.\n */\nexport function proxyEnvFor(route: ProxyRoute): Record<string, string> | undefined {\n if (route.kind !== \"proxy\") return undefined;\n const uri = new URL(route.server);\n uri.username = encodeURIComponent(route.username);\n uri.password = encodeURIComponent(route.password);\n return {\n HTTP_PROXY: uri.toString(),\n HTTPS_PROXY: uri.toString(),\n http_proxy: uri.toString(),\n https_proxy: uri.toString(),\n };\n}\n\nexport type SpawnResult = { code: number; stderr: string; stdout?: string };\n\n/**\n * Spawn helper local to yt-dlp: the engine's `cli-runner` rejects URL arguments\n * by policy, which is directly at odds with yt-dlp's job.\n *\n * stdout is discarded unless asked for, because on a download it is the media\n * progress firehose; the probe is the one caller that actually wants it.\n */\nexport function spawnAndWait(\n bin: string,\n argv: readonly string[],\n timeoutMs: number,\n options: { extraEnv?: Record<string, string>; captureStdout?: boolean } = {},\n): Promise<SpawnResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(bin, argv, {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n // `childEnvWith` because `spawn`'s `env` REPLACES the environment rather\n // than extending it — passing only the additions would strip PATH.\n ...(options.extraEnv ? { env: childEnvWith(options.extraEnv) } : {}),\n });\n const stderrChunks: Buffer[] = [];\n const stdoutChunks: Buffer[] = [];\n let stderrLen = 0;\n const MAX_STDERR = 256 * 1024;\n\n child.stdout.on(\"data\", (chunk: Buffer) => {\n if (options.captureStdout) stdoutChunks.push(chunk);\n });\n child.stderr.on(\"data\", (chunk: Buffer) => {\n if (stderrLen < MAX_STDERR) {\n stderrChunks.push(chunk);\n stderrLen += chunk.length;\n }\n });\n\n const timer = setTimeout(() => {\n child.kill(\"SIGKILL\");\n reject(new Error(`${bin} timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n\n child.on(\"error\", (err) => {\n clearTimeout(timer);\n reject(new Error(`failed to spawn \"${bin}\" — ${err.message}`));\n });\n\n child.on(\"close\", (code) => {\n clearTimeout(timer);\n resolve({\n code: code ?? -1,\n stderr: Buffer.concat(stderrChunks).toString(\"utf-8\"),\n ...(options.captureStdout ? { stdout: Buffer.concat(stdoutChunks).toString(\"utf-8\") } : {}),\n });\n });\n });\n}\n","/**\n * Which video yt-dlp keeps. By default the best the site releases — see\n * `runYtDlp` for why the master matters. A caller importing in bulk may cap\n * the resolution instead: a whole channel of 4K masters is five times the bytes\n * of 1080p, and those bytes are what overruns a download's time budget.\n *\n * The cap is on the shorter side (yt-dlp's `res` sort field), not the height: a\n * vertical Short's 1080p is 1080×1920, and a height cap would keep its 608×1080\n * rendition instead. A sort rather than a filter, so when nothing fits the cap\n * the closest there is still beats no video.\n */\nexport function videoFormatArgs(maxResolution?: number): string[] {\n const sort = maxResolution ? [\"-S\", `res:${maxResolution}`] : [];\n return [\"--format\", \"bv*+ba/b\", ...sort, \"--merge-output-format\", \"mp4\"];\n}\n","/**\n * The second thing to try when YouTube hands us a video and then refuses it.\n *\n * Distinct from the egress ladder, and the distinction is the whole point. The\n * ladder answers \"would a different IP help\"; this answers \"would a different\n * *client* help\" — and measured inside a Runtime, the second question is the one\n * that was failing. yt-dlp's default client selection lands on `android_vr`,\n * whose media URLs YouTube now signs and then rejects, so extraction succeeds,\n * a format is chosen, and the byte fetch comes back\n * `unable to download video data: HTTP Error 403: Forbidden`. That failure is\n * identical from every exit: direct, datacenter and residential all produced it,\n * so climbing the ladder spent both paid rungs to reproduce it.\n *\n * The `android` client resolves a progressive format whose URL is honoured from\n * the same address — verified on two unrelated videos from the Runtime's own IP\n * after the default clients had 403'd. It is a *fallback*, not the default: it\n * currently offers only 360p, so it is worth reaching for once the good formats\n * have already been refused and worth nothing before that.\n */\n\n/** yt-dlp's argv for the fallback client. Appended, never substituted. */\nexport const YOUTUBE_FALLBACK_CLIENT_ARGS = [\"--extractor-args\", \"youtube:player_client=android\"] as const;\n\n/**\n * The refusal that happens *after* a format was chosen.\n *\n * Deliberately this exact phrase rather than a bare 403: a 403 raised while\n * fetching the page is a block on us, which the egress ladder already owns and\n * can actually fix. This one is raised on the media URL yt-dlp was just given,\n * which no exit IP changes.\n */\nconst MEDIA_FETCH_REFUSED = \"unable to download video data\";\n\nconst YOUTUBE_HOSTS = [\"youtube.com\", \"youtu.be\"];\n\nfunction isYouTube(url: string): boolean {\n let host: string;\n try {\n host = new URL(url).hostname.toLowerCase();\n } catch {\n return false;\n }\n return YOUTUBE_HOSTS.some((known) => host === known || host.endsWith(`.${known}`));\n}\n\n/** True when re-running with the fallback client is worth one more attempt. */\nexport function needsPlayerClientRetry(url: string, stderr: string): boolean {\n return isYouTube(url) && stderr.toLowerCase().includes(MEDIA_FETCH_REFUSED);\n}\n"],"mappings":"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","names":["path","path"]}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
// ../api/src/identity/digest.ts
|
|
2
|
+
var SHA256_HEX = /^[0-9a-fA-F]{64}$/;
|
|
3
|
+
function isSha256Hex(value) {
|
|
4
|
+
return SHA256_HEX.test(value);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// ../api/src/identity/email.ts
|
|
8
|
+
function normalizeEmailV1(raw) {
|
|
9
|
+
const trimmed = raw.trim().toLowerCase();
|
|
10
|
+
return trimmed === "" ? null : trimmed;
|
|
11
|
+
}
|
|
12
|
+
var EMAIL = /^[^\s@]+@[^\s@.]+(?:\.[^\s@.]+)+$/;
|
|
13
|
+
function normalizeEmailV2(raw) {
|
|
14
|
+
const trimmed = raw.trim().toLowerCase();
|
|
15
|
+
return EMAIL.test(trimmed) ? trimmed : null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// ../api/src/identity/phone.ts
|
|
19
|
+
function normalizePhoneV1(raw) {
|
|
20
|
+
const digits = raw.trim().toLowerCase().replace(/[^0-9]/g, "");
|
|
21
|
+
return digits === "" ? null : `+${digits}`;
|
|
22
|
+
}
|
|
23
|
+
var PHONE_PUNCTUATION = /[\s()./-]/g;
|
|
24
|
+
var E164 = /^\+[1-9]\d{7,14}$/;
|
|
25
|
+
function normalizePhoneV2(raw) {
|
|
26
|
+
const compact = raw.replace(PHONE_PUNCTUATION, "");
|
|
27
|
+
const e164 = compact.startsWith("00") ? `+${compact.slice(2)}` : compact;
|
|
28
|
+
return E164.test(e164) ? e164 : null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// ../api/src/identity/index.ts
|
|
32
|
+
function normalizeIdentity(raw, version) {
|
|
33
|
+
const value = raw.kind === "email" ? version === 1 ? normalizeEmailV1(raw.value) : normalizeEmailV2(raw.value) : version === 1 ? normalizePhoneV1(raw.value) : normalizePhoneV2(raw.value);
|
|
34
|
+
return value === null ? null : { kind: raw.kind, value, normalizationVersion: version };
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// ../api/src/event-ingest/matching.ts
|
|
38
|
+
var MATCH_FIELDS = [
|
|
39
|
+
"first_name",
|
|
40
|
+
"last_name",
|
|
41
|
+
"date_of_birth",
|
|
42
|
+
"gender",
|
|
43
|
+
"city",
|
|
44
|
+
"region",
|
|
45
|
+
"postal_code",
|
|
46
|
+
"country"
|
|
47
|
+
];
|
|
48
|
+
var MATCH_COOKIES = ["fbp", "fbc"];
|
|
49
|
+
function tightened(value) {
|
|
50
|
+
const stripped = value.toLowerCase().replace(/[^\p{L}\p{N}]/gu, "");
|
|
51
|
+
return stripped === "" ? null : stripped;
|
|
52
|
+
}
|
|
53
|
+
function loosened(value) {
|
|
54
|
+
const collapsed = value.trim().toLowerCase().replace(/\s+/g, " ");
|
|
55
|
+
return collapsed === "" ? null : collapsed;
|
|
56
|
+
}
|
|
57
|
+
function birthDate(value) {
|
|
58
|
+
const digits = value.replace(/\D/g, "");
|
|
59
|
+
if (!/^\d{8}$/.test(digits)) return null;
|
|
60
|
+
const month = Number(digits.slice(4, 6));
|
|
61
|
+
const day = Number(digits.slice(6, 8));
|
|
62
|
+
if (month < 1 || month > 12 || day < 1 || day > 31) return null;
|
|
63
|
+
return digits;
|
|
64
|
+
}
|
|
65
|
+
function genderLetter(value) {
|
|
66
|
+
const first = value.trim().toLowerCase().charAt(0);
|
|
67
|
+
return first === "f" || first === "m" ? first : null;
|
|
68
|
+
}
|
|
69
|
+
function countryCode(value) {
|
|
70
|
+
const code = value.trim().toLowerCase();
|
|
71
|
+
return /^[a-z]{2}$/.test(code) ? code : null;
|
|
72
|
+
}
|
|
73
|
+
var MATCH_SPECS = {
|
|
74
|
+
first_name: { keep: "hashed", normalize: tightened, meta: "fn", google: "hashed_first_name" },
|
|
75
|
+
last_name: { keep: "hashed", normalize: tightened, meta: "ln", google: "hashed_last_name" },
|
|
76
|
+
// Meta only. Google's enhanced conversions have no date of birth, so there is
|
|
77
|
+
// no destination wanting it in the clear and every reason not to keep one.
|
|
78
|
+
date_of_birth: { keep: "hashed", normalize: birthDate, meta: "db", google: null },
|
|
79
|
+
gender: { keep: "plain", normalize: genderLetter, meta: "ge", google: null },
|
|
80
|
+
city: { keep: "plain", normalize: loosened, meta: "ct", google: "city" },
|
|
81
|
+
region: { keep: "plain", normalize: loosened, meta: "st", google: "state" },
|
|
82
|
+
postal_code: { keep: "plain", normalize: loosened, meta: "zp", google: "postal_code" },
|
|
83
|
+
country: { keep: "plain", normalize: countryCode, meta: "country", google: "country_code" }
|
|
84
|
+
};
|
|
85
|
+
var MATCH_FIELD_FORWARDING = [
|
|
86
|
+
{ field: "email", meta: "em", google: "hashed_email", hashed: true },
|
|
87
|
+
{ field: "phone", meta: "ph", google: "hashed_phone_number", hashed: true },
|
|
88
|
+
// Kept in the clear — see `resolveOwnId`. The digest is still computed and
|
|
89
|
+
// still stored beside it, so a Meta forward has one; what changed is that the
|
|
90
|
+
// sender's own key is now readable, which is the entire reason they sent it.
|
|
91
|
+
{ field: "external_id", meta: "external_id", google: null, hashed: false },
|
|
92
|
+
...MATCH_FIELDS.map((field) => ({
|
|
93
|
+
field,
|
|
94
|
+
meta: MATCH_SPECS[field].meta,
|
|
95
|
+
google: MATCH_SPECS[field].google,
|
|
96
|
+
hashed: MATCH_SPECS[field].keep === "hashed"
|
|
97
|
+
})),
|
|
98
|
+
{ field: "fbp", meta: "fbp", google: null, hashed: false },
|
|
99
|
+
{ field: "fbc", meta: "fbc", google: null, hashed: false }
|
|
100
|
+
];
|
|
101
|
+
|
|
102
|
+
// ../api/src/event-ingest/vocabulary.ts
|
|
103
|
+
var INGEST_CLICK_ID_PARAMS = [
|
|
104
|
+
"gclid",
|
|
105
|
+
"wbraid",
|
|
106
|
+
"gbraid",
|
|
107
|
+
"dclid",
|
|
108
|
+
"fbclid",
|
|
109
|
+
"ttclid",
|
|
110
|
+
"twclid",
|
|
111
|
+
"li_fat_id",
|
|
112
|
+
"msclkid",
|
|
113
|
+
"rdt_cid",
|
|
114
|
+
"epik",
|
|
115
|
+
"sccid",
|
|
116
|
+
"oppref"
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
// ../api/src/event-sources/fields.ts
|
|
120
|
+
var MATCH_LABELS = {
|
|
121
|
+
first_name: "First name",
|
|
122
|
+
last_name: "Last name",
|
|
123
|
+
date_of_birth: "Date of birth",
|
|
124
|
+
gender: "Gender",
|
|
125
|
+
city: "City",
|
|
126
|
+
region: "Region",
|
|
127
|
+
postal_code: "Postcode",
|
|
128
|
+
country: "Country"
|
|
129
|
+
};
|
|
130
|
+
var CLICK_LABELS = {
|
|
131
|
+
gclid: "Google click id",
|
|
132
|
+
wbraid: "Google click id (iOS, web to app)",
|
|
133
|
+
gbraid: "Google click id (iOS, app)",
|
|
134
|
+
dclid: "Google click id (Display & Video)",
|
|
135
|
+
fbclid: "Meta click id",
|
|
136
|
+
ttclid: "TikTok click id",
|
|
137
|
+
twclid: "X click id",
|
|
138
|
+
li_fat_id: "LinkedIn click id",
|
|
139
|
+
msclkid: "Microsoft click id",
|
|
140
|
+
rdt_cid: "Reddit click id",
|
|
141
|
+
epik: "Pinterest click id",
|
|
142
|
+
sccid: "Snapchat click id",
|
|
143
|
+
oppref: "ChatGPT Ads click id"
|
|
144
|
+
};
|
|
145
|
+
var SOURCE_FIELDS = [
|
|
146
|
+
{ field: "event_name", label: "What happened", group: "event" },
|
|
147
|
+
{ field: "event_time", label: "When it happened", group: "event" },
|
|
148
|
+
{ field: "event_id", label: "Its id", group: "event" },
|
|
149
|
+
{ field: "email", label: "Email", group: "person" },
|
|
150
|
+
{ field: "phone", label: "Phone", group: "person" },
|
|
151
|
+
{ field: "external_id", label: "Your own id for the person", group: "person" },
|
|
152
|
+
...MATCH_FIELDS.map((field) => ({ field, label: MATCH_LABELS[field], group: "person" })),
|
|
153
|
+
{ field: "value", label: "Amount", group: "money" },
|
|
154
|
+
{ field: "currency", label: "Currency", group: "money" },
|
|
155
|
+
...INGEST_CLICK_ID_PARAMS.map((field) => ({ field, label: CLICK_LABELS[field], group: "click" }))
|
|
156
|
+
];
|
|
157
|
+
var SOURCE_FIELD_NAMES = SOURCE_FIELDS.map((spec) => spec.field);
|
|
158
|
+
var FIELD_SET = new Set(SOURCE_FIELD_NAMES);
|
|
159
|
+
function isSourceField(value) {
|
|
160
|
+
return FIELD_SET.has(value);
|
|
161
|
+
}
|
|
162
|
+
var PROPERTY_ROW_PREFIX = "properties.";
|
|
163
|
+
var PROPERTY_KEY_MAX = 64;
|
|
164
|
+
var PROPERTY_KEY = /^[A-Za-z0-9_][A-Za-z0-9_.-]*$/;
|
|
165
|
+
var RESERVED_PROPERTY_KEYS = ["baker_source", "hubspot_property", "hubspot_value"];
|
|
166
|
+
function isPropertyRow(row) {
|
|
167
|
+
return row.startsWith(PROPERTY_ROW_PREFIX);
|
|
168
|
+
}
|
|
169
|
+
function propertyKeyOf(row) {
|
|
170
|
+
return isPropertyRow(row) ? row.slice(PROPERTY_ROW_PREFIX.length) : null;
|
|
171
|
+
}
|
|
172
|
+
function propertyKeyProblem(key) {
|
|
173
|
+
const trimmed = key.trim();
|
|
174
|
+
if (trimmed === "") return "A property needs a name.";
|
|
175
|
+
if (trimmed.length > PROPERTY_KEY_MAX) return `A property name is at most ${PROPERTY_KEY_MAX} characters.`;
|
|
176
|
+
if (!PROPERTY_KEY.test(trimmed)) {
|
|
177
|
+
return `"${trimmed}" is not a property name: letters, digits, underscore, dash and dot only, starting with a letter or digit.`;
|
|
178
|
+
}
|
|
179
|
+
if (RESERVED_PROPERTY_KEYS.includes(trimmed)) return `"${trimmed}" is written by Baker itself; pick another name.`;
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
function mappingRowProblem(row) {
|
|
183
|
+
if (isSourceField(row)) return null;
|
|
184
|
+
const key = propertyKeyOf(row);
|
|
185
|
+
if (key === null) {
|
|
186
|
+
return `"${row}" is not a field an event can carry. A field is one of ${SOURCE_FIELD_NAMES.join(", ")}; an extra property is spelled properties.<name>.`;
|
|
187
|
+
}
|
|
188
|
+
return propertyKeyProblem(key);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// ../api/src/event-sources/template.ts
|
|
192
|
+
var MENTION = /\{\{\s*([^{}]+?)\s*\}\}/g;
|
|
193
|
+
function mentionOf(path) {
|
|
194
|
+
return `{{${path}}}`;
|
|
195
|
+
}
|
|
196
|
+
function templateMentions(template) {
|
|
197
|
+
const seen = [];
|
|
198
|
+
for (const match of template.matchAll(MENTION)) {
|
|
199
|
+
const path = (match[1] ?? "").trim();
|
|
200
|
+
if (path !== "" && !seen.includes(path)) seen.push(path);
|
|
201
|
+
}
|
|
202
|
+
return seen;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export {
|
|
206
|
+
isSha256Hex,
|
|
207
|
+
normalizeIdentity,
|
|
208
|
+
MATCH_COOKIES,
|
|
209
|
+
MATCH_FIELD_FORWARDING,
|
|
210
|
+
INGEST_CLICK_ID_PARAMS,
|
|
211
|
+
SOURCE_FIELD_NAMES,
|
|
212
|
+
mappingRowProblem,
|
|
213
|
+
mentionOf,
|
|
214
|
+
templateMentions
|
|
215
|
+
};
|
|
216
|
+
//# sourceMappingURL=chunk-EDLZGTGN.js.map
|