mcp-scraper 0.90.7 → 0.90.8
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/CHANGELOG.md +32 -1
- package/README.md +2 -2
- package/dist/{analytics-repository-FXS45ZTM.js → analytics-repository-IHOFBSUV.js} +1 -1
- package/dist/bin/api-server.js +1 -1
- package/dist/bin/mcp-scraper-cli.js +1 -1
- package/dist/bin/mcp-scraper-core.js +1 -1
- package/dist/bin/mcp-scraper-install.js +1 -1
- package/dist/bin/mcp-stdio-server.js +1 -1
- package/dist/bin/paa-harvest.js +1 -1
- package/dist/{chunk-5NQY2N7J.js → chunk-2F35B4U5.js} +2 -2
- package/dist/{chunk-BDLR4CCL.js → chunk-2SP57VCG.js} +6 -6
- package/dist/{chunk-ZKQRA6NQ.js → chunk-53IEEOKA.js} +167 -167
- package/dist/chunk-6DTXIZY2.js +1 -0
- package/dist/{chunk-YTEAWZEN.js → chunk-6FMIMP5Z.js} +1 -1
- package/dist/chunk-7SHEBDEB.js +1 -0
- package/dist/{chunk-LPEIHMYH.js → chunk-DKXZIIA5.js} +1 -1
- package/dist/{chunk-TBTA7VVZ.js → chunk-IK5BG7MO.js} +1 -1
- package/dist/{chunk-QUFR3KG2.js → chunk-J374DIKA.js} +1 -1
- package/dist/{chunk-I7IS7NTC.js → chunk-KZV2FLGG.js} +1 -1
- package/dist/{chunk-UKFNSXP3.js → chunk-LI7WHOII.js} +1 -1
- package/dist/{chunk-B2C7JU4O.js → chunk-LSFDB5XE.js} +1 -1
- package/dist/{chunk-DSK6RKBS.js → chunk-OIMPG6M6.js} +1 -1
- package/dist/{chunk-OT2HUS2G.js → chunk-OMYTA34L.js} +1 -1
- package/dist/chunk-ORB4RHCK.js +63 -0
- package/dist/chunk-OVTHAIDS.js +1 -0
- package/dist/{chunk-IGJKAECE.js → chunk-QTDLZTQ7.js} +1 -1
- package/dist/chunk-RK2VCTZI.js +1 -0
- package/dist/{chunk-TOJBPATJ.js → chunk-WJ4XFLS4.js} +159 -115
- package/dist/{chunk-74HHYSAZ.js → chunk-X7GZJU5P.js} +1 -1
- package/dist/{chunk-R7LCD65B.js → chunk-ZMNUI5LB.js} +7 -7
- package/dist/db-B5XJTOGN.js +1 -0
- package/dist/{extract-bundle-INT6JMJP.js → extract-bundle-II3RPATK.js} +10 -10
- package/dist/gmail-service-E5KORS6C.js +1 -0
- package/dist/index.cjs +18 -18
- package/dist/index.js +1 -1
- package/dist/{lead-list-enrichment-repository-B6Q4O4DG.js → lead-list-enrichment-repository-AWZZMY2H.js} +1 -1
- package/dist/{location-data-repository-CBI5K7MR.js → location-data-repository-6XAVI65Z.js} +1 -1
- package/dist/operation-metering-DB5F7SXN.js +1 -0
- package/dist/server-MI6XN25Z.js +4961 -0
- package/dist/{site-extract-repository-VPYOC3CP.js → site-extract-repository-JHSVJJ62.js} +1 -1
- package/dist/stripe-event-worker-7KNF3VH5.js +1 -0
- package/dist/worker-3VTFFYHH.js +1 -0
- package/package.json +1 -1
- package/dist/chunk-KDDU6BW3.js +0 -48
- package/dist/chunk-WEPU72WA.js +0 -1
- package/dist/db-SVSD2AWJ.js +0 -1
- package/dist/gmail-service-YCPMGW3E.js +0 -1
- package/dist/server-LYWW6XYE.js +0 -4956
- package/dist/stripe-event-worker-AQVRF24K.js +0 -1
- package/dist/worker-U43KLOLN.js +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
"use strict";var Ao=Object.create;var Un=Object.defineProperty;var Lo=Object.getOwnPropertyDescriptor;var xo=Object.getOwnPropertyNames;var Oo=Object.getPrototypeOf,Ro=Object.prototype.hasOwnProperty;var Wo=(e,t)=>{for(var n in t)Un(e,n,{get:t[n],enumerable:!0})},li=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of xo(t))!Ro.call(e,i)&&i!==n&&Un(e,i,{get:()=>t[i],enumerable:!(a=Lo(t,i))||a.enumerable});return e};var un=(e,t,n)=>(n=e!=null?Ao(Oo(e)):{},li(t||!e||!e.__esModule?Un(n,"default",{value:e,enumerable:!0}):n,e)),Ho=e=>li(Un({},"__esModule",{value:!0}),e);var Ql={};Wo(Ql,{VideoGenerator:()=>zn,buildClipPrompts:()=>Kn,harvest:()=>Co});module.exports=Ho(Ql);var p=require("zod");var Qn="none",Do="none",Zn=p.z.object({query:p.z.string().min(1),location:p.z.string().optional(),gl:p.z.string().length(2).default("us"),hl:p.z.string().length(2).default("en"),device:p.z.enum(["desktop","mobile"]).default("desktop"),proxyMode:p.z.enum(["location","configured","none"]).default(Qn),proxyZip:p.z.string().regex(/^\d{5}$/).optional(),keepDefaultProxy:p.z.boolean().optional(),requireUsEgress:p.z.boolean().optional(),maxAttempts:p.z.number().int().min(1).max(12).optional(),debug:p.z.boolean().default(!1),depth:p.z.number().int().min(1).max(30).default(3),maxQuestions:p.z.number().int().min(1).max(100).default(100),headless:p.z.boolean().default(!1),profileDir:p.z.string().optional(),proxy:p.z.string().url().optional(),\u006b\u0065\u0072\u006e\u0065\u006cApiKey:p.z.string().optional(),\u006b\u0065\u0072\u006e\u0065\u006cProxyId:p.z.string().optional(),\u006b\u0065\u0072\u006e\u0065\u006cProfileName:p.z.string().optional(),\u006b\u0065\u0072\u006e\u0065\u006cProfileSaveChanges:p.z.boolean().optional(),\u006b\u0065\u0072\u006e\u0065\u006cStealth:p.z.boolean().optional(),serpIdentity:p.z.string().regex(/^[a-z0-9][a-z0-9_-]{0,63}$/).optional(),\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution:p.z.unknown().optional(),outputDir:p.z.string().default("./paa-output"),format:p.z.enum(["json","csv","both"]).default("both"),serpOnly:p.z.boolean().default(!1),questionsOnly:p.z.boolean().default(!1),questionGrowthRecoveryRounds:p.z.number().int().min(0).max(4).default(2),pages:p.z.number().int().min(1).max(2).default(1),includeAllSerpFeatures:p.z.boolean().default(!1),includeLocalPack:p.z.boolean().default(!1),includeForums:p.z.boolean().default(!1),includeVideos:p.z.boolean().default(!1),includeAiOverview:p.z.boolean().default(!1),includeWhatPeopleSaying:p.z.boolean().default(!1),includeShortVideos:p.z.boolean().default(!1),recency:p.z.enum(["day","week","month","year"]).optional(),softDeadlineMs:p.z.number().optional()});function He(e){switch(e){case"day":return"qdr:d";case"week":return"qdr:w";case"month":return"qdr:m";case"year":return"qdr:y";default:return}}var aS=p.z.object({businessName:p.z.string().min(1),location:p.z.string().min(1),gl:p.z.string().length(2).default("us"),hl:p.z.string().length(2).default("en"),includeReviews:p.z.boolean().default(!1),maxReviews:p.z.number().int().min(1).max(500).default(50),includeServices:p.z.boolean().default(!1),includeImages:p.z.boolean().default(!1),imageScope:p.z.enum(["owner","all"]).default("all"),maxImages:p.z.number().int().min(1).max(250).default(100),maxInlineImages:p.z.number().int().min(0).max(5).default(3),\u006b\u0065\u0072\u006e\u0065\u006cApiKey:p.z.string().optional(),\u006b\u0065\u0072\u006e\u0065\u006cProxyId:p.z.string().optional(),headless:p.z.boolean().default(!0)}),iS=p.z.object({query:p.z.string().min(1),location:p.z.string().optional(),gl:p.z.string().length(2).default("us"),hl:p.z.string().length(2).default("en"),maxResults:p.z.number().int().min(1).max(50).default(10),includeServices:p.z.boolean().default(!1),proxyMode:p.z.enum(["location","configured","none"]).default(Do),proxyZip:p.z.string().regex(/^\d{5}$/).optional(),serpRedirect:p.z.boolean().optional(),forceDirectEgress:p.z.boolean().optional(),debug:p.z.boolean().default(!1),\u006b\u0065\u0072\u006e\u0065\u006cApiKey:p.z.string().optional(),\u006b\u0065\u0072\u006e\u0065\u006cProxyId:p.z.string().optional(),\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution:p.z.unknown().optional(),headless:p.z.boolean().default(!0)}),Si=p.z.object({questionId:p.z.string().min(1),googleLinkId:p.z.string().nullable(),googleEvidenceId:p.z.string().nullable(),question:p.z.string().min(1),answer:p.z.string().optional(),sourceTitle:p.z.string().optional(),sourceSite:p.z.string().optional(),sourceCite:p.z.string().optional(),sources:p.z.array(p.z.object({title:p.z.string().nullable(),site:p.z.string().nullable(),url:p.z.string().min(1),rawUrl:p.z.string().min(1),resolvedUrl:p.z.string().nullable(),linkType:p.z.enum(["plain","google_url_redirect","google_goto_redirect"]),resolutionStatus:p.z.enum(["not_needed","resolved","unresolved","rejected"])})).default([])}),sS=p.z.object({name:p.z.string().nullable(),rating:p.z.string().nullable(),reviewCount:p.z.string().nullable(),category:p.z.string().nullable(),address:p.z.string().nullable(),hoursSummary:p.z.string().nullable(),phone:p.z.string().nullable(),phoneDisplay:p.z.string().nullable(),website:p.z.string().nullable(),plusCode:p.z.string().nullable(),bookingUrl:p.z.string().nullable()}),oS=p.z.object({day:p.z.string(),hours:p.z.string()}),rS=p.z.object({reviewHistogram:p.z.array(p.z.object({stars:p.z.number(),count:p.z.string()})),reviewTopics:p.z.array(p.z.object({label:p.z.string(),count:p.z.string()}))}),dS=p.z.object({reviewId:p.z.string(),author:p.z.string().nullable(),stars:p.z.string().nullable(),date:p.z.string().nullable(),text:p.z.string().nullable(),ownerResponse:p.z.string().nullable()}),lS=p.z.object({section:p.z.string(),attribute:p.z.string()});function Ui(){return(process.env.BROWSER_SERVICE_API_KEY??process.env.\u004b\u0045\u0052\u004e\u0045\u004c_API_KEY)?.trim()||void 0}var Ln=require("playwright-extra"),ms=un(require("puppeteer-extra-plugin-stealth"),1),ys=require("playwright");function Z(e,t,n,a,i){if(a==="m")throw new TypeError("Private method is not writable");if(a==="a"&&!i)throw new TypeError("Private accessor was defined without a setter");if(typeof t=="function"?e!==t||!i:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return a==="a"?i.call(e,n):i?i.value=n:t.set(e,n),n}function K(e,t,n,a){if(n==="a"&&!a)throw new TypeError("Private accessor was defined without a getter");if(typeof t=="function"?e!==t||!a:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return n==="m"?a:n==="a"?a.call(e):a?a.value:t.get(e)}var ta=function(){let{crypto:e}=globalThis;if(e?.randomUUID)return ta=e.randomUUID.bind(e),e.randomUUID();let t=new Uint8Array(1),n=e?()=>e.getRandomValues(t)[0]:()=>Math.random()*255&255;return"10000000-1000-4000-8000-100000000000".replace(/[018]/g,a=>(+a^n()&15>>+a/4).toString(16))};function Be(e){return typeof e=="object"&&e!==null&&("name"in e&&e.name==="AbortError"||"message"in e&&String(e.message).includes("FetchRequestCanceledException"))}var De=e=>{if(e instanceof Error)return e;if(typeof e=="object"&&e!==null){try{if(Object.prototype.toString.call(e)==="[object Error]"){let t=new Error(e.message,e.cause?{cause:e.cause}:{});return e.stack&&(t.stack=e.stack),e.cause&&!t.cause&&(t.cause=e.cause),e.name&&(t.name=e.name),t}}catch{}try{return new Error(JSON.stringify(e))}catch{}}return new Error(e)};var V=class extends Error{},et=class e extends V{constructor(t,n,a,i){super(`${e.makeMessage(t,n,a)}`),this.status=t,this.headers=i,this.error=n}static makeMessage(t,n,a){let i=n?.message?typeof n.message=="string"?n.message:JSON.stringify(n.message):n?JSON.stringify(n):a;return t&&i?`${t} ${i}`:t?`${t} status code (no body)`:i||"(no status code or body)"}static generate(t,n,a,i){if(!t||!i)return new bt({message:a,cause:De(n)});let s=n;return t===400?new oe(t,s,a,i):t===401?new re(t,s,a,i):t===403?new de(t,s,a,i):t===404?new le(t,s,a,i):t===409?new Se(t,s,a,i):t===422?new Ue(t,s,a,i):t===429?new ue(t,s,a,i):t>=500?new ce(t,s,a,i):new e(t,s,a,i)}},st=class extends et{constructor({message:t}={}){super(void 0,void 0,t||"Request was aborted.",void 0)}},bt=class extends et{constructor({message:t,cause:n}){super(void 0,void 0,t||"Connection error.",void 0),n&&(this.cause=n)}},Tt=class extends bt{constructor({message:t}={}){super({message:t??"Request timed out."})}},oe=class extends et{},re=class extends et{},de=class extends et{},le=class extends et{},Se=class extends et{},Ue=class extends et{},ue=class extends et{},ce=class extends et{};var Go=/^[a-z][a-z0-9+.-]*:/i,ui=e=>Go.test(e),nt=e=>(nt=Array.isArray,nt(e)),ea=nt;function na(e){return typeof e!="object"?{}:e??{}}function aa(e){if(!e)return!0;for(let t in e)return!1;return!0}function ci(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var hi=(e,t)=>{if(typeof t!="number"||!Number.isInteger(t))throw new V(`${e} must be an integer`);if(t<0)throw new V(`${e} must be a positive integer`);return t},Vo=e=>{if(typeof e=="number")return Math.round(e);if(typeof e=="string")return parseInt(e,10);throw new V(`Could not coerce ${e} (type: ${typeof e}) into a number`)};var Yo=e=>typeof e=="boolean"?e:typeof e=="string"?e==="true":!!e,gi=e=>{if(e!=null)return Vo(e)};var ia=e=>{if(e!=null)return Yo(e)},pi=e=>{try{return JSON.parse(e)}catch{return}};var wi=e=>new Promise(t=>setTimeout(t,e));var _t="0.93.0";function Ko(){return typeof Deno<"u"&&Deno.build!=null?"deno":typeof EdgeRuntime<"u"?"edge":Object.prototype.toString.call(typeof globalThis.process<"u"?globalThis.process:0)==="[object process]"?"node":"unknown"}var Jo=()=>{let e=Ko();if(e==="deno")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":_t,"X-Stainless-OS":yi(Deno.build.os),"X-Stainless-Arch":mi(Deno.build.arch),"X-Stainless-Runtime":"deno","X-Stainless-Runtime-Version":typeof Deno.version=="string"?Deno.version:Deno.version?.deno??"unknown"};if(typeof EdgeRuntime<"u")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":_t,"X-Stainless-OS":"Unknown","X-Stainless-Arch":`other:${EdgeRuntime}`,"X-Stainless-Runtime":"edge","X-Stainless-Runtime-Version":globalThis.process.version};if(e==="node")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":_t,"X-Stainless-OS":yi(globalThis.process.platform??"unknown"),"X-Stainless-Arch":mi(globalThis.process.arch??"unknown"),"X-Stainless-Runtime":"node","X-Stainless-Runtime-Version":globalThis.process.version??"unknown"};let t=qo();return t?{"X-Stainless-Lang":"js","X-Stainless-Package-Version":_t,"X-Stainless-OS":"Unknown","X-Stainless-Arch":"unknown","X-Stainless-Runtime":`browser:${t.browser}`,"X-Stainless-Runtime-Version":t.version}:{"X-Stainless-Lang":"js","X-Stainless-Package-Version":_t,"X-Stainless-OS":"Unknown","X-Stainless-Arch":"unknown","X-Stainless-Runtime":"unknown","X-Stainless-Runtime-Version":"unknown"}};function qo(){if(typeof navigator>"u"||!navigator)return null;let e=[{key:"edge",pattern:/Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"ie",pattern:/MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"ie",pattern:/Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"chrome",pattern:/Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"firefox",pattern:/Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"safari",pattern:/(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/}];for(let{key:t,pattern:n}of e){let a=n.exec(navigator.userAgent);if(a){let i=a[1]||0,s=a[2]||0,o=a[3]||0;return{browser:t,version:`${i}.${s}.${o}`}}}return null}var mi=e=>e==="x32"?"x32":e==="x86_64"||e==="x64"?"x64":e==="arm"?"arm":e==="aarch64"||e==="arm64"?"arm64":e?`other:${e}`:"unknown",yi=e=>(e=e.toLowerCase(),e.includes("ios")?"iOS":e==="android"?"Android":e==="darwin"?"MacOS":e==="win32"?"Windows":e==="freebsd"?"FreeBSD":e==="openbsd"?"OpenBSD":e==="linux"?"Linux":e?`Other:${e}`:"Unknown"),Ci,Ti=()=>Ci??(Ci=Jo());function ki(){if(typeof fetch<"u")return fetch;throw new Error("`fetch` is not defined as a global; Either pass `fetch` to the client, `new \u004b\u0065\u0072\u006e\u0065\u006c({ fetch })` or polyfill the global, `globalThis.fetch = fetch`")}function sa(...e){let t=globalThis.ReadableStream;if(typeof t>"u")throw new Error("`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`");return new t(...e)}function cn(e){let t=Symbol.asyncIterator in e?e[Symbol.asyncIterator]():e[Symbol.iterator]();return sa({start(){},async pull(n){let{done:a,value:i}=await t.next();a?n.close():n.enqueue(i)},async cancel(){await t.return?.()}})}function oa(e){if(e[Symbol.asyncIterator])return e;let t=e.getReader();return{async next(){try{let n=await t.read();return n?.done&&t.releaseLock(),n}catch(n){throw t.releaseLock(),n}},async return(){let n=t.cancel();return t.releaseLock(),await n,{done:!0,value:void 0}},[Symbol.asyncIterator](){return this}}}async function fi(e){if(e===null||typeof e!="object")return;if(e[Symbol.asyncIterator]){await e[Symbol.asyncIterator]().return?.();return}let t=e.getReader(),n=t.cancel();t.releaseLock(),await n}var Mi=({headers:e,body:t})=>({bodyHeaders:{"content-type":"application/json"},body:JSON.stringify(t)});var ra="RFC3986",da=e=>String(e),la={RFC1738:e=>String(e).replace(/%20/g,"+"),RFC3986:da},Ni="RFC1738";var hn=(e,t)=>(hn=Object.hasOwn??Function.prototype.call.bind(Object.prototype.hasOwnProperty),hn(e,t)),wt=(()=>{let e=[];for(let t=0;t<256;++t)e.push("%"+((t<16?"0":"")+t.toString(16)).toUpperCase());return e})();var Sa=1024,vi=(e,t,n,a,i)=>{if(e.length===0)return e;let s=e;if(typeof e=="symbol"?s=Symbol.prototype.toString.call(e):typeof e!="string"&&(s=String(e)),n==="iso-8859-1")return escape(s).replace(/%u[0-9a-f]{4}/gi,function(d){return"%26%23"+parseInt(d.slice(2),16)+"%3B"});let o="";for(let d=0;d<s.length;d+=Sa){let l=s.length>=Sa?s.slice(d,d+Sa):s,U=[];for(let S=0;S<l.length;++S){let r=l.charCodeAt(S);if(r===45||r===46||r===95||r===126||r>=48&&r<=57||r>=65&&r<=90||r>=97&&r<=122||i===Ni&&(r===40||r===41)){U[U.length]=l.charAt(S);continue}if(r<128){U[U.length]=wt[r];continue}if(r<2048){U[U.length]=wt[192|r>>6]+wt[128|r&63];continue}if(r<55296||r>=57344){U[U.length]=wt[224|r>>12]+wt[128|r>>6&63]+wt[128|r&63];continue}S+=1,r=65536+((r&1023)<<10|l.charCodeAt(S)&1023),U[U.length]=wt[240|r>>18]+wt[128|r>>12&63]+wt[128|r>>6&63]+wt[128|r&63]}o+=U.join("")}return o};function bi(e){return!e||typeof e!="object"?!1:!!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e))}function Ua(e,t){if(nt(e)){let n=[];for(let a=0;a<e.length;a+=1)n.push(t(e[a]));return n}return t(e)}var Ei={brackets(e){return String(e)+"[]"},comma:"comma",indices(e,t){return String(e)+"["+t+"]"},repeat(e){return String(e)}},Pi=function(e,t){Array.prototype.push.apply(e,nt(t)?t:[t])},_i,j={addQueryPrefix:!1,allowDots:!1,allowEmptyArrays:!1,arrayFormat:"indices",charset:"utf-8",charsetSentinel:!1,delimiter:"&",encode:!0,encodeDotInKeys:!1,encoder:vi,encodeValuesOnly:!1,format:ra,formatter:da,indices:!1,serializeDate(e){return(_i??(_i=Function.prototype.call.bind(Date.prototype.toISOString)))(e)},skipNulls:!1,strictNullHandling:!1};function zo(e){return typeof e=="string"||typeof e=="number"||typeof e=="boolean"||typeof e=="symbol"||typeof e=="bigint"}var ua={};function Ii(e,t,n,a,i,s,o,d,l,U,S,r,u,c,h,m,f,M){let y=e,A=M,O=0,B=!1;for(;(A=A.get(ua))!==void 0&&!B;){let C=A.get(e);if(O+=1,typeof C<"u"){if(C===O)throw new RangeError("Cyclic object value");B=!0}typeof A.get(ua)>"u"&&(O=0)}if(typeof U=="function"?y=U(t,y):y instanceof Date?y=u?.(y):n==="comma"&&nt(y)&&(y=Ua(y,function(C){return C instanceof Date?u?.(C):C})),y===null){if(s)return l&&!m?l(t,j.encoder,f,"key",c):t;y=""}if(zo(y)||bi(y)){if(l){let C=m?t:l(t,j.encoder,f,"key",c);return[h?.(C)+"="+h?.(l(y,j.encoder,f,"value",c))]}return[h?.(t)+"="+h?.(String(y))]}let b=[];if(typeof y>"u")return b;let N;if(n==="comma"&&nt(y))m&&l&&(y=Ua(y,l)),N=[{value:y.length>0?y.join(",")||null:void 0}];else if(nt(U))N=U;else{let C=Object.keys(y);N=S?C.sort(S):C}let W=d?String(t).replace(/\./g,"%2E"):String(t),P=a&&nt(y)&&y.length===1?W+"[]":W;if(i&&nt(y)&&y.length===0)return P+"[]";for(let C=0;C<N.length;++C){let E=N[C],w=typeof E=="object"&&typeof E.value<"u"?E.value:y[E];if(o&&w===null)continue;let k=r&&d?E.replace(/\./g,"%2E"):E,v=nt(y)?typeof n=="function"?n(P,k):P:P+(r?"."+k:"["+k+"]");M.set(e,O);let I=new WeakMap;I.set(ua,M),Pi(b,Ii(w,v,n,a,i,s,o,d,n==="comma"&&m&&nt(y)?null:l,U,S,r,u,c,h,m,f,I))}return b}function $o(e=j){if(typeof e.allowEmptyArrays<"u"&&typeof e.allowEmptyArrays!="boolean")throw new TypeError("`allowEmptyArrays` option can only be `true` or `false`, when provided");if(typeof e.encodeDotInKeys<"u"&&typeof e.encodeDotInKeys!="boolean")throw new TypeError("`encodeDotInKeys` option can only be `true` or `false`, when provided");if(e.encoder!==null&&typeof e.encoder<"u"&&typeof e.encoder!="function")throw new TypeError("Encoder has to be a function.");let t=e.charset||j.charset;if(typeof e.charset<"u"&&e.charset!=="utf-8"&&e.charset!=="iso-8859-1")throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");let n=ra;if(typeof e.format<"u"){if(!hn(la,e.format))throw new TypeError("Unknown format option provided.");n=e.format}let a=la[n],i=j.filter;(typeof e.filter=="function"||nt(e.filter))&&(i=e.filter);let s;if(e.arrayFormat&&e.arrayFormat in Ei?s=e.arrayFormat:"indices"in e?s=e.indices?"indices":"repeat":s=j.arrayFormat,"commaRoundTrip"in e&&typeof e.commaRoundTrip!="boolean")throw new TypeError("`commaRoundTrip` must be a boolean, or absent");let o=typeof e.allowDots>"u"?e.encodeDotInKeys?!0:j.allowDots:!!e.allowDots;return{addQueryPrefix:typeof e.addQueryPrefix=="boolean"?e.addQueryPrefix:j.addQueryPrefix,allowDots:o,allowEmptyArrays:typeof e.allowEmptyArrays=="boolean"?!!e.allowEmptyArrays:j.allowEmptyArrays,arrayFormat:s,charset:t,charsetSentinel:typeof e.charsetSentinel=="boolean"?e.charsetSentinel:j.charsetSentinel,commaRoundTrip:!!e.commaRoundTrip,delimiter:typeof e.delimiter>"u"?j.delimiter:e.delimiter,encode:typeof e.encode=="boolean"?e.encode:j.encode,encodeDotInKeys:typeof e.encodeDotInKeys=="boolean"?e.encodeDotInKeys:j.encodeDotInKeys,encoder:typeof e.encoder=="function"?e.encoder:j.encoder,encodeValuesOnly:typeof e.encodeValuesOnly=="boolean"?e.encodeValuesOnly:j.encodeValuesOnly,filter:i,format:n,formatter:a,serializeDate:typeof e.serializeDate=="function"?e.serializeDate:j.serializeDate,skipNulls:typeof e.skipNulls=="boolean"?e.skipNulls:j.skipNulls,sort:typeof e.sort=="function"?e.sort:null,strictNullHandling:typeof e.strictNullHandling=="boolean"?e.strictNullHandling:j.strictNullHandling}}function Ai(e,t={}){let n=e,a=$o(t),i,s;typeof a.filter=="function"?(s=a.filter,n=s("",n)):nt(a.filter)&&(s=a.filter,i=s);let o=[];if(typeof n!="object"||n===null)return"";let d=Ei[a.arrayFormat],l=d==="comma"&&a.commaRoundTrip;i||(i=Object.keys(n)),a.sort&&i.sort(a.sort);let U=new WeakMap;for(let u=0;u<i.length;++u){let c=i[u];a.skipNulls&&n[c]===null||Pi(o,Ii(n[c],c,d,l,a.allowEmptyArrays,a.strictNullHandling,a.skipNulls,a.encodeDotInKeys,a.encode?a.encoder:null,a.filter,a.sort,a.allowDots,a.serializeDate,a.format,a.formatter,a.encodeValuesOnly,a.charset,U))}let S=o.join(a.delimiter),r=a.addQueryPrefix===!0?"?":"";return a.charsetSentinel&&(a.charset==="iso-8859-1"?r+="utf8=%26%2310003%3B&":r+="utf8=%E2%9C%93&"),S.length>0?r+S:""}function Li(e){return Ai(e,{arrayFormat:"comma"})}function Ri(e){let t=0;for(let i of e)t+=i.length;let n=new Uint8Array(t),a=0;for(let i of e)n.set(i,a),a+=i.length;return n}var xi;function Fe(e){let t;return(xi??(t=new globalThis.TextEncoder,xi=t.encode.bind(t)))(e)}var Oi;function ca(e){let t;return(Oi??(t=new globalThis.TextDecoder,Oi=t.decode.bind(t)))(e)}var St,Ut,Wt=class{constructor(){St.set(this,void 0),Ut.set(this,void 0),Z(this,St,new Uint8Array,"f"),Z(this,Ut,null,"f")}decode(t){if(t==null)return[];let n=t instanceof ArrayBuffer?new Uint8Array(t):typeof t=="string"?Fe(t):t;Z(this,St,Ri([K(this,St,"f"),n]),"f");let a=[],i;for(;(i=Zo(K(this,St,"f"),K(this,Ut,"f")))!=null;){if(i.carriage&&K(this,Ut,"f")==null){Z(this,Ut,i.index,"f");continue}if(K(this,Ut,"f")!=null&&(i.index!==K(this,Ut,"f")+1||i.carriage)){a.push(ca(K(this,St,"f").subarray(0,K(this,Ut,"f")-1))),Z(this,St,K(this,St,"f").subarray(K(this,Ut,"f")),"f"),Z(this,Ut,null,"f");continue}let s=K(this,Ut,"f")!==null?i.preceding-1:i.preceding,o=ca(K(this,St,"f").subarray(0,s));a.push(o),Z(this,St,K(this,St,"f").subarray(i.index),"f"),Z(this,Ut,null,"f")}return a}flush(){return K(this,St,"f").length?this.decode(`
|
|
1
|
+
"use strict";var Ao=Object.create;var Un=Object.defineProperty;var Lo=Object.getOwnPropertyDescriptor;var xo=Object.getOwnPropertyNames;var Oo=Object.getPrototypeOf,Ro=Object.prototype.hasOwnProperty;var Wo=(e,t)=>{for(var n in t)Un(e,n,{get:t[n],enumerable:!0})},li=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of xo(t))!Ro.call(e,i)&&i!==n&&Un(e,i,{get:()=>t[i],enumerable:!(a=Lo(t,i))||a.enumerable});return e};var un=(e,t,n)=>(n=e!=null?Ao(Oo(e)):{},li(t||!e||!e.__esModule?Un(n,"default",{value:e,enumerable:!0}):n,e)),Ho=e=>li(Un({},"__esModule",{value:!0}),e);var Ql={};Wo(Ql,{VideoGenerator:()=>zn,buildClipPrompts:()=>Kn,harvest:()=>Co});module.exports=Ho(Ql);var p=require("zod");var Qn="none",Do="none",Zn=p.z.object({query:p.z.string().min(1),location:p.z.string().optional(),gl:p.z.string().length(2).default("us"),hl:p.z.string().length(2).default("en"),device:p.z.enum(["desktop","mobile"]).default("desktop"),proxyMode:p.z.enum(["location","configured","none"]).default(Qn),proxyZip:p.z.string().regex(/^\d{5}$/).optional(),keepDefaultProxy:p.z.boolean().optional(),requireUsEgress:p.z.boolean().optional(),maxAttempts:p.z.number().int().min(1).max(12).optional(),debug:p.z.boolean().default(!1),depth:p.z.number().int().min(1).max(30).default(3),maxQuestions:p.z.number().int().min(1).max(100).default(100),headless:p.z.boolean().default(!1),profileDir:p.z.string().optional(),proxy:p.z.string().url().optional(),\u006b\u0065\u0072\u006e\u0065\u006cApiKey:p.z.string().optional(),\u006b\u0065\u0072\u006e\u0065\u006cProxyId:p.z.string().optional(),\u006b\u0065\u0072\u006e\u0065\u006cProfileName:p.z.string().optional(),\u006b\u0065\u0072\u006e\u0065\u006cProfileSaveChanges:p.z.boolean().optional(),\u006b\u0065\u0072\u006e\u0065\u006cStealth:p.z.boolean().optional(),serpIdentity:p.z.string().regex(/^[a-z0-9][a-z0-9_-]{0,63}$/).optional(),\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution:p.z.unknown().optional(),outputDir:p.z.string().default("./paa-output"),format:p.z.enum(["json","csv","both"]).default("both"),serpOnly:p.z.boolean().default(!1),questionsOnly:p.z.boolean().default(!1),questionGrowthRecoveryRounds:p.z.number().int().min(0).max(4).default(2),pages:p.z.number().int().min(1).max(2).default(1),includeAllSerpFeatures:p.z.boolean().default(!1),includeLocalPack:p.z.boolean().default(!1),includeForums:p.z.boolean().default(!1),includeVideos:p.z.boolean().default(!1),includeAiOverview:p.z.boolean().default(!1),includeWhatPeopleSaying:p.z.boolean().default(!1),includeShortVideos:p.z.boolean().default(!1),recency:p.z.enum(["day","week","month","year"]).optional(),softDeadlineMs:p.z.number().optional()});function He(e){switch(e){case"day":return"qdr:d";case"week":return"qdr:w";case"month":return"qdr:m";case"year":return"qdr:y";default:return}}var aS=p.z.object({businessName:p.z.string().min(1),location:p.z.string().min(1),gl:p.z.string().length(2).default("us"),hl:p.z.string().length(2).default("en"),includeReviews:p.z.boolean().default(!1),maxReviews:p.z.number().int().min(1).max(500).default(50),includeServices:p.z.boolean().default(!1),includeImages:p.z.boolean().default(!1),imageScope:p.z.enum(["owner","all"]).default("all"),maxImages:p.z.number().int().min(1).max(250).default(100),maxInlineImages:p.z.number().int().min(0).max(5).default(3),\u006b\u0065\u0072\u006e\u0065\u006cApiKey:p.z.string().optional(),\u006b\u0065\u0072\u006e\u0065\u006cProxyId:p.z.string().optional(),headless:p.z.boolean().default(!0)}),iS=p.z.object({query:p.z.string().min(1),location:p.z.string().optional(),gl:p.z.string().length(2).default("us"),hl:p.z.string().length(2).default("en"),maxResults:p.z.number().int().min(1).max(50).default(10),includeServices:p.z.boolean().default(!1),proxyMode:p.z.enum(["location","configured","none"]).default(Do),proxyZip:p.z.string().regex(/^\d{5}$/).optional(),serpRedirect:p.z.boolean().optional(),forceDirectEgress:p.z.boolean().optional(),debug:p.z.boolean().default(!1),\u006b\u0065\u0072\u006e\u0065\u006cApiKey:p.z.string().optional(),\u006b\u0065\u0072\u006e\u0065\u006cProxyId:p.z.string().optional(),\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution:p.z.unknown().optional(),headless:p.z.boolean().default(!0)}),Si=p.z.object({questionId:p.z.string().min(1),googleLinkId:p.z.string().nullable(),googleEvidenceId:p.z.string().nullable(),question:p.z.string().min(1),answer:p.z.string().optional(),sourceTitle:p.z.string().optional(),sourceSite:p.z.string().optional(),sourceCite:p.z.string().optional(),sources:p.z.array(p.z.object({title:p.z.string().nullable(),site:p.z.string().nullable(),url:p.z.string().min(1),rawUrl:p.z.string().min(1),resolvedUrl:p.z.string().nullable(),linkType:p.z.enum(["plain","google_url_redirect","google_goto_redirect"]),resolutionStatus:p.z.enum(["not_needed","resolved","unresolved","rejected"])})).default([])}),sS=p.z.object({name:p.z.string().nullable(),rating:p.z.string().nullable(),reviewCount:p.z.string().nullable(),category:p.z.string().nullable(),address:p.z.string().nullable(),hoursSummary:p.z.string().nullable(),phone:p.z.string().nullable(),phoneDisplay:p.z.string().nullable(),website:p.z.string().nullable(),plusCode:p.z.string().nullable(),bookingUrl:p.z.string().nullable()}),oS=p.z.object({day:p.z.string(),hours:p.z.string()}),rS=p.z.object({reviewHistogram:p.z.array(p.z.object({stars:p.z.number(),count:p.z.string()})),reviewTopics:p.z.array(p.z.object({label:p.z.string(),count:p.z.string()}))}),dS=p.z.object({reviewId:p.z.string(),author:p.z.string().nullable(),stars:p.z.string().nullable(),date:p.z.string().nullable(),text:p.z.string().nullable(),ownerResponse:p.z.string().nullable()}),lS=p.z.object({section:p.z.string(),attribute:p.z.string()});function Ui(){return(process.env.BROWSER_SERVICE_API_KEY??process.env.\u004b\u0045\u0052\u004e\u0045\u004c_API_KEY)?.trim()||void 0}var Ln=require("playwright-extra"),ms=un(require("puppeteer-extra-plugin-stealth"),1),ys=require("playwright");function Z(e,t,n,a,i){if(a==="m")throw new TypeError("Private method is not writable");if(a==="a"&&!i)throw new TypeError("Private accessor was defined without a setter");if(typeof t=="function"?e!==t||!i:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return a==="a"?i.call(e,n):i?i.value=n:t.set(e,n),n}function K(e,t,n,a){if(n==="a"&&!a)throw new TypeError("Private accessor was defined without a getter");if(typeof t=="function"?e!==t||!a:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return n==="m"?a:n==="a"?a.call(e):a?a.value:t.get(e)}var ta=function(){let{crypto:e}=globalThis;if(e?.randomUUID)return ta=e.randomUUID.bind(e),e.randomUUID();let t=new Uint8Array(1),n=e?()=>e.getRandomValues(t)[0]:()=>Math.random()*255&255;return"10000000-1000-4000-8000-100000000000".replace(/[018]/g,a=>(+a^n()&15>>+a/4).toString(16))};function Be(e){return typeof e=="object"&&e!==null&&("name"in e&&e.name==="AbortError"||"message"in e&&String(e.message).includes("FetchRequestCanceledException"))}var De=e=>{if(e instanceof Error)return e;if(typeof e=="object"&&e!==null){try{if(Object.prototype.toString.call(e)==="[object Error]"){let t=new Error(e.message,e.cause?{cause:e.cause}:{});return e.stack&&(t.stack=e.stack),e.cause&&!t.cause&&(t.cause=e.cause),e.name&&(t.name=e.name),t}}catch{}try{return new Error(JSON.stringify(e))}catch{}}return new Error(e)};var V=class extends Error{},et=class e extends V{constructor(t,n,a,i){super(`${e.makeMessage(t,n,a)}`),this.status=t,this.headers=i,this.error=n}static makeMessage(t,n,a){let i=n?.message?typeof n.message=="string"?n.message:JSON.stringify(n.message):n?JSON.stringify(n):a;return t&&i?`${t} ${i}`:t?`${t} status code (no body)`:i||"(no status code or body)"}static generate(t,n,a,i){if(!t||!i)return new _t({message:a,cause:De(n)});let s=n;return t===400?new oe(t,s,a,i):t===401?new re(t,s,a,i):t===403?new de(t,s,a,i):t===404?new le(t,s,a,i):t===409?new Se(t,s,a,i):t===422?new Ue(t,s,a,i):t===429?new ue(t,s,a,i):t>=500?new ce(t,s,a,i):new e(t,s,a,i)}},st=class extends et{constructor({message:t}={}){super(void 0,void 0,t||"Request was aborted.",void 0)}},_t=class extends et{constructor({message:t,cause:n}){super(void 0,void 0,t||"Connection error.",void 0),n&&(this.cause=n)}},Tt=class extends _t{constructor({message:t}={}){super({message:t??"Request timed out."})}},oe=class extends et{},re=class extends et{},de=class extends et{},le=class extends et{},Se=class extends et{},Ue=class extends et{},ue=class extends et{},ce=class extends et{};var Go=/^[a-z][a-z0-9+.-]*:/i,ui=e=>Go.test(e),nt=e=>(nt=Array.isArray,nt(e)),ea=nt;function na(e){return typeof e!="object"?{}:e??{}}function aa(e){if(!e)return!0;for(let t in e)return!1;return!0}function ci(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var hi=(e,t)=>{if(typeof t!="number"||!Number.isInteger(t))throw new V(`${e} must be an integer`);if(t<0)throw new V(`${e} must be a positive integer`);return t},Vo=e=>{if(typeof e=="number")return Math.round(e);if(typeof e=="string")return parseInt(e,10);throw new V(`Could not coerce ${e} (type: ${typeof e}) into a number`)};var Yo=e=>typeof e=="boolean"?e:typeof e=="string"?e==="true":!!e,gi=e=>{if(e!=null)return Vo(e)};var ia=e=>{if(e!=null)return Yo(e)},pi=e=>{try{return JSON.parse(e)}catch{return}};var wi=e=>new Promise(t=>setTimeout(t,e));var bt="0.93.0";function Ko(){return typeof Deno<"u"&&Deno.build!=null?"deno":typeof EdgeRuntime<"u"?"edge":Object.prototype.toString.call(typeof globalThis.process<"u"?globalThis.process:0)==="[object process]"?"node":"unknown"}var Jo=()=>{let e=Ko();if(e==="deno")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":bt,"X-Stainless-OS":yi(Deno.build.os),"X-Stainless-Arch":mi(Deno.build.arch),"X-Stainless-Runtime":"deno","X-Stainless-Runtime-Version":typeof Deno.version=="string"?Deno.version:Deno.version?.deno??"unknown"};if(typeof EdgeRuntime<"u")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":bt,"X-Stainless-OS":"Unknown","X-Stainless-Arch":`other:${EdgeRuntime}`,"X-Stainless-Runtime":"edge","X-Stainless-Runtime-Version":globalThis.process.version};if(e==="node")return{"X-Stainless-Lang":"js","X-Stainless-Package-Version":bt,"X-Stainless-OS":yi(globalThis.process.platform??"unknown"),"X-Stainless-Arch":mi(globalThis.process.arch??"unknown"),"X-Stainless-Runtime":"node","X-Stainless-Runtime-Version":globalThis.process.version??"unknown"};let t=qo();return t?{"X-Stainless-Lang":"js","X-Stainless-Package-Version":bt,"X-Stainless-OS":"Unknown","X-Stainless-Arch":"unknown","X-Stainless-Runtime":`browser:${t.browser}`,"X-Stainless-Runtime-Version":t.version}:{"X-Stainless-Lang":"js","X-Stainless-Package-Version":bt,"X-Stainless-OS":"Unknown","X-Stainless-Arch":"unknown","X-Stainless-Runtime":"unknown","X-Stainless-Runtime-Version":"unknown"}};function qo(){if(typeof navigator>"u"||!navigator)return null;let e=[{key:"edge",pattern:/Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"ie",pattern:/MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"ie",pattern:/Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"chrome",pattern:/Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"firefox",pattern:/Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/},{key:"safari",pattern:/(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/}];for(let{key:t,pattern:n}of e){let a=n.exec(navigator.userAgent);if(a){let i=a[1]||0,s=a[2]||0,o=a[3]||0;return{browser:t,version:`${i}.${s}.${o}`}}}return null}var mi=e=>e==="x32"?"x32":e==="x86_64"||e==="x64"?"x64":e==="arm"?"arm":e==="aarch64"||e==="arm64"?"arm64":e?`other:${e}`:"unknown",yi=e=>(e=e.toLowerCase(),e.includes("ios")?"iOS":e==="android"?"Android":e==="darwin"?"MacOS":e==="win32"?"Windows":e==="freebsd"?"FreeBSD":e==="openbsd"?"OpenBSD":e==="linux"?"Linux":e?`Other:${e}`:"Unknown"),Ci,Ti=()=>Ci??(Ci=Jo());function ki(){if(typeof fetch<"u")return fetch;throw new Error("`fetch` is not defined as a global; Either pass `fetch` to the client, `new \u004b\u0065\u0072\u006e\u0065\u006c({ fetch })` or polyfill the global, `globalThis.fetch = fetch`")}function sa(...e){let t=globalThis.ReadableStream;if(typeof t>"u")throw new Error("`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`");return new t(...e)}function cn(e){let t=Symbol.asyncIterator in e?e[Symbol.asyncIterator]():e[Symbol.iterator]();return sa({start(){},async pull(n){let{done:a,value:i}=await t.next();a?n.close():n.enqueue(i)},async cancel(){await t.return?.()}})}function oa(e){if(e[Symbol.asyncIterator])return e;let t=e.getReader();return{async next(){try{let n=await t.read();return n?.done&&t.releaseLock(),n}catch(n){throw t.releaseLock(),n}},async return(){let n=t.cancel();return t.releaseLock(),await n,{done:!0,value:void 0}},[Symbol.asyncIterator](){return this}}}async function fi(e){if(e===null||typeof e!="object")return;if(e[Symbol.asyncIterator]){await e[Symbol.asyncIterator]().return?.();return}let t=e.getReader(),n=t.cancel();t.releaseLock(),await n}var Mi=({headers:e,body:t})=>({bodyHeaders:{"content-type":"application/json"},body:JSON.stringify(t)});var ra="RFC3986",da=e=>String(e),la={RFC1738:e=>String(e).replace(/%20/g,"+"),RFC3986:da},Ni="RFC1738";var hn=(e,t)=>(hn=Object.hasOwn??Function.prototype.call.bind(Object.prototype.hasOwnProperty),hn(e,t)),wt=(()=>{let e=[];for(let t=0;t<256;++t)e.push("%"+((t<16?"0":"")+t.toString(16)).toUpperCase());return e})();var Sa=1024,vi=(e,t,n,a,i)=>{if(e.length===0)return e;let s=e;if(typeof e=="symbol"?s=Symbol.prototype.toString.call(e):typeof e!="string"&&(s=String(e)),n==="iso-8859-1")return escape(s).replace(/%u[0-9a-f]{4}/gi,function(d){return"%26%23"+parseInt(d.slice(2),16)+"%3B"});let o="";for(let d=0;d<s.length;d+=Sa){let l=s.length>=Sa?s.slice(d,d+Sa):s,U=[];for(let S=0;S<l.length;++S){let r=l.charCodeAt(S);if(r===45||r===46||r===95||r===126||r>=48&&r<=57||r>=65&&r<=90||r>=97&&r<=122||i===Ni&&(r===40||r===41)){U[U.length]=l.charAt(S);continue}if(r<128){U[U.length]=wt[r];continue}if(r<2048){U[U.length]=wt[192|r>>6]+wt[128|r&63];continue}if(r<55296||r>=57344){U[U.length]=wt[224|r>>12]+wt[128|r>>6&63]+wt[128|r&63];continue}S+=1,r=65536+((r&1023)<<10|l.charCodeAt(S)&1023),U[U.length]=wt[240|r>>18]+wt[128|r>>12&63]+wt[128|r>>6&63]+wt[128|r&63]}o+=U.join("")}return o};function _i(e){return!e||typeof e!="object"?!1:!!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e))}function Ua(e,t){if(nt(e)){let n=[];for(let a=0;a<e.length;a+=1)n.push(t(e[a]));return n}return t(e)}var Ei={brackets(e){return String(e)+"[]"},comma:"comma",indices(e,t){return String(e)+"["+t+"]"},repeat(e){return String(e)}},Pi=function(e,t){Array.prototype.push.apply(e,nt(t)?t:[t])},bi,j={addQueryPrefix:!1,allowDots:!1,allowEmptyArrays:!1,arrayFormat:"indices",charset:"utf-8",charsetSentinel:!1,delimiter:"&",encode:!0,encodeDotInKeys:!1,encoder:vi,encodeValuesOnly:!1,format:ra,formatter:da,indices:!1,serializeDate(e){return(bi??(bi=Function.prototype.call.bind(Date.prototype.toISOString)))(e)},skipNulls:!1,strictNullHandling:!1};function zo(e){return typeof e=="string"||typeof e=="number"||typeof e=="boolean"||typeof e=="symbol"||typeof e=="bigint"}var ua={};function Ii(e,t,n,a,i,s,o,d,l,U,S,r,u,c,h,m,f,M){let y=e,A=M,O=0,B=!1;for(;(A=A.get(ua))!==void 0&&!B;){let C=A.get(e);if(O+=1,typeof C<"u"){if(C===O)throw new RangeError("Cyclic object value");B=!0}typeof A.get(ua)>"u"&&(O=0)}if(typeof U=="function"?y=U(t,y):y instanceof Date?y=u?.(y):n==="comma"&&nt(y)&&(y=Ua(y,function(C){return C instanceof Date?u?.(C):C})),y===null){if(s)return l&&!m?l(t,j.encoder,f,"key",c):t;y=""}if(zo(y)||_i(y)){if(l){let C=m?t:l(t,j.encoder,f,"key",c);return[h?.(C)+"="+h?.(l(y,j.encoder,f,"value",c))]}return[h?.(t)+"="+h?.(String(y))]}let _=[];if(typeof y>"u")return _;let N;if(n==="comma"&&nt(y))m&&l&&(y=Ua(y,l)),N=[{value:y.length>0?y.join(",")||null:void 0}];else if(nt(U))N=U;else{let C=Object.keys(y);N=S?C.sort(S):C}let W=d?String(t).replace(/\./g,"%2E"):String(t),P=a&&nt(y)&&y.length===1?W+"[]":W;if(i&&nt(y)&&y.length===0)return P+"[]";for(let C=0;C<N.length;++C){let E=N[C],w=typeof E=="object"&&typeof E.value<"u"?E.value:y[E];if(o&&w===null)continue;let k=r&&d?E.replace(/\./g,"%2E"):E,v=nt(y)?typeof n=="function"?n(P,k):P:P+(r?"."+k:"["+k+"]");M.set(e,O);let I=new WeakMap;I.set(ua,M),Pi(_,Ii(w,v,n,a,i,s,o,d,n==="comma"&&m&&nt(y)?null:l,U,S,r,u,c,h,m,f,I))}return _}function $o(e=j){if(typeof e.allowEmptyArrays<"u"&&typeof e.allowEmptyArrays!="boolean")throw new TypeError("`allowEmptyArrays` option can only be `true` or `false`, when provided");if(typeof e.encodeDotInKeys<"u"&&typeof e.encodeDotInKeys!="boolean")throw new TypeError("`encodeDotInKeys` option can only be `true` or `false`, when provided");if(e.encoder!==null&&typeof e.encoder<"u"&&typeof e.encoder!="function")throw new TypeError("Encoder has to be a function.");let t=e.charset||j.charset;if(typeof e.charset<"u"&&e.charset!=="utf-8"&&e.charset!=="iso-8859-1")throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");let n=ra;if(typeof e.format<"u"){if(!hn(la,e.format))throw new TypeError("Unknown format option provided.");n=e.format}let a=la[n],i=j.filter;(typeof e.filter=="function"||nt(e.filter))&&(i=e.filter);let s;if(e.arrayFormat&&e.arrayFormat in Ei?s=e.arrayFormat:"indices"in e?s=e.indices?"indices":"repeat":s=j.arrayFormat,"commaRoundTrip"in e&&typeof e.commaRoundTrip!="boolean")throw new TypeError("`commaRoundTrip` must be a boolean, or absent");let o=typeof e.allowDots>"u"?e.encodeDotInKeys?!0:j.allowDots:!!e.allowDots;return{addQueryPrefix:typeof e.addQueryPrefix=="boolean"?e.addQueryPrefix:j.addQueryPrefix,allowDots:o,allowEmptyArrays:typeof e.allowEmptyArrays=="boolean"?!!e.allowEmptyArrays:j.allowEmptyArrays,arrayFormat:s,charset:t,charsetSentinel:typeof e.charsetSentinel=="boolean"?e.charsetSentinel:j.charsetSentinel,commaRoundTrip:!!e.commaRoundTrip,delimiter:typeof e.delimiter>"u"?j.delimiter:e.delimiter,encode:typeof e.encode=="boolean"?e.encode:j.encode,encodeDotInKeys:typeof e.encodeDotInKeys=="boolean"?e.encodeDotInKeys:j.encodeDotInKeys,encoder:typeof e.encoder=="function"?e.encoder:j.encoder,encodeValuesOnly:typeof e.encodeValuesOnly=="boolean"?e.encodeValuesOnly:j.encodeValuesOnly,filter:i,format:n,formatter:a,serializeDate:typeof e.serializeDate=="function"?e.serializeDate:j.serializeDate,skipNulls:typeof e.skipNulls=="boolean"?e.skipNulls:j.skipNulls,sort:typeof e.sort=="function"?e.sort:null,strictNullHandling:typeof e.strictNullHandling=="boolean"?e.strictNullHandling:j.strictNullHandling}}function Ai(e,t={}){let n=e,a=$o(t),i,s;typeof a.filter=="function"?(s=a.filter,n=s("",n)):nt(a.filter)&&(s=a.filter,i=s);let o=[];if(typeof n!="object"||n===null)return"";let d=Ei[a.arrayFormat],l=d==="comma"&&a.commaRoundTrip;i||(i=Object.keys(n)),a.sort&&i.sort(a.sort);let U=new WeakMap;for(let u=0;u<i.length;++u){let c=i[u];a.skipNulls&&n[c]===null||Pi(o,Ii(n[c],c,d,l,a.allowEmptyArrays,a.strictNullHandling,a.skipNulls,a.encodeDotInKeys,a.encode?a.encoder:null,a.filter,a.sort,a.allowDots,a.serializeDate,a.format,a.formatter,a.encodeValuesOnly,a.charset,U))}let S=o.join(a.delimiter),r=a.addQueryPrefix===!0?"?":"";return a.charsetSentinel&&(a.charset==="iso-8859-1"?r+="utf8=%26%2310003%3B&":r+="utf8=%E2%9C%93&"),S.length>0?r+S:""}function Li(e){return Ai(e,{arrayFormat:"comma"})}function Ri(e){let t=0;for(let i of e)t+=i.length;let n=new Uint8Array(t),a=0;for(let i of e)n.set(i,a),a+=i.length;return n}var xi;function Fe(e){let t;return(xi??(t=new globalThis.TextEncoder,xi=t.encode.bind(t)))(e)}var Oi;function ca(e){let t;return(Oi??(t=new globalThis.TextDecoder,Oi=t.decode.bind(t)))(e)}var St,Ut,Wt=class{constructor(){St.set(this,void 0),Ut.set(this,void 0),Z(this,St,new Uint8Array,"f"),Z(this,Ut,null,"f")}decode(t){if(t==null)return[];let n=t instanceof ArrayBuffer?new Uint8Array(t):typeof t=="string"?Fe(t):t;Z(this,St,Ri([K(this,St,"f"),n]),"f");let a=[],i;for(;(i=Zo(K(this,St,"f"),K(this,Ut,"f")))!=null;){if(i.carriage&&K(this,Ut,"f")==null){Z(this,Ut,i.index,"f");continue}if(K(this,Ut,"f")!=null&&(i.index!==K(this,Ut,"f")+1||i.carriage)){a.push(ca(K(this,St,"f").subarray(0,K(this,Ut,"f")-1))),Z(this,St,K(this,St,"f").subarray(K(this,Ut,"f")),"f"),Z(this,Ut,null,"f");continue}let s=K(this,Ut,"f")!==null?i.preceding-1:i.preceding,o=ca(K(this,St,"f").subarray(0,s));a.push(o),Z(this,St,K(this,St,"f").subarray(i.index),"f"),Z(this,Ut,null,"f")}return a}flush(){return K(this,St,"f").length?this.decode(`
|
|
2
2
|
`):[]}};St=new WeakMap,Ut=new WeakMap;Wt.NEWLINE_CHARS=new Set([`
|
|
3
3
|
`,"\r"]);Wt.NEWLINE_REGEXP=/\r\n|[\n\r]/g;function Zo(e,t){for(let i=t??0;i<e.length;i++){if(e[i]===10)return{preceding:i,index:i+1,carriage:!1};if(e[i]===13)return{preceding:i,index:i+1,carriage:!0}}return null}function Wi(e){for(let a=0;a<e.length-1;a++){if(e[a]===10&&e[a+1]===10||e[a]===13&&e[a+1]===13)return a+2;if(e[a]===13&&e[a+1]===10&&a+3<e.length&&e[a+2]===13&&e[a+3]===10)return a+4}return-1}var pn={off:0,error:200,warn:300,info:400,debug:500},ha=(e,t,n)=>{if(e){if(ci(pn,e))return e;z(n).warn(`${t} was set to ${JSON.stringify(e)}, expected one of ${JSON.stringify(Object.keys(pn))}`)}};function Ge(){}function gn(e,t,n){return!t||pn[e]>pn[n]?Ge:t[e].bind(t)}var tr={error:Ge,warn:Ge,info:Ge,debug:Ge},Hi=new WeakMap;function z(e){let t=e.logger,n=e.logLevel??"off";if(!t)return tr;let a=Hi.get(t);if(a&&a[0]===n)return a[1];let i={error:gn("error",t,n),warn:gn("warn",t,n),info:gn("info",t,n),debug:gn("debug",t,n)};return Hi.set(t,[n,i]),i}var kt=e=>(e.options&&(e.options={...e.options},delete e.options.headers),e.headers&&(e.headers=Object.fromEntries((e.headers instanceof Headers?[...e.headers]:Object.entries(e.headers)).map(([t,n])=>[t,t.toLowerCase()==="authorization"||t.toLowerCase()==="api-key"||t.toLowerCase()==="x-api-key"||t.toLowerCase()==="cookie"||t.toLowerCase()==="set-cookie"?"***":n]))),"retryOfRequestLogID"in e&&(e.retryOfRequestLogID&&(e.retryOf=e.retryOfRequestLogID),delete e.retryOfRequestLogID),e);var Ve,wn=class e{constructor(t,n,a){this.iterator=t,Ve.set(this,void 0),this.controller=n,Z(this,Ve,a,"f")}static fromSSEResponse(t,n,a){let i=!1,s=a?z(a):console;async function*o(){if(i)throw new V("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");i=!0;let d=!1;try{for await(let l of er(t,n))try{yield JSON.parse(l.data)}catch(U){throw s.error("Could not parse message into JSON:",l.data),s.error("From chunk:",l.raw),U}d=!0}catch(l){if(Be(l))return;throw l}finally{d||n.abort()}}return new e(o,n,a)}static fromReadableStream(t,n,a){let i=!1;async function*s(){let d=new Wt,l=oa(t);for await(let U of l)for(let S of d.decode(U))yield S;for(let U of d.flush())yield U}async function*o(){if(i)throw new V("Cannot iterate over a consumed stream, use `.tee()` to split the stream.");i=!0;let d=!1;try{for await(let l of s())d||l&&(yield JSON.parse(l));d=!0}catch(l){if(Be(l))return;throw l}finally{d||n.abort()}}return new e(o,n,a)}[(Ve=new WeakMap,Symbol.asyncIterator)](){return this.iterator()}tee(){let t=[],n=[],a=this.iterator(),i=s=>({next:()=>{if(s.length===0){let o=a.next();t.push(o),n.push(o)}return s.shift()}});return[new e(()=>i(t),this.controller,K(this,Ve,"f")),new e(()=>i(n),this.controller,K(this,Ve,"f"))]}toReadableStream(){let t=this,n;return sa({async start(){n=t[Symbol.asyncIterator]()},async pull(a){try{let{value:i,done:s}=await n.next();if(s)return a.close();let o=Fe(JSON.stringify(i)+`
|
|
4
4
|
`);a.enqueue(o)}catch(i){a.error(i)}},async cancel(){await n.return?.()}})}};async function*er(e,t){if(!e.body)throw t.abort(),typeof globalThis.navigator<"u"&&globalThis.navigator.product==="ReactNative"?new V("The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api"):new V("Attempted to iterate over a response with no body");let n=new ga,a=new Wt,i=oa(e.body);for await(let s of nr(i))for(let o of a.decode(s)){let d=n.decode(o);d&&(yield d)}for(let s of a.flush()){let o=n.decode(s);o&&(yield o)}}async function*nr(e){let t=new Uint8Array;for await(let n of e){if(n==null)continue;let a=n instanceof ArrayBuffer?new Uint8Array(n):typeof n=="string"?Fe(n):n,i=new Uint8Array(t.length+a.length);i.set(t),i.set(a,t.length),t=i;let s;for(;(s=Wi(t))!==-1;)yield t.slice(0,s),t=t.slice(s)}t.length>0&&(yield t)}var ga=class{constructor(){this.event=null,this.data=[],this.chunks=[]}decode(t){if(t.endsWith("\r")&&(t=t.substring(0,t.length-1)),!t){if(!this.event&&!this.data.length)return null;let s={event:this.event,data:this.data.join(`
|
|
5
|
-
`),raw:this.chunks};return this.event=null,this.data=[],this.chunks=[],s}if(this.chunks.push(t),t.startsWith(":"))return null;let[n,a,i]=ar(t,":");return i.startsWith(" ")&&(i=i.substring(1)),n==="event"?this.event=i:n==="data"&&this.data.push(i),null}};function ar(e,t){let n=e.indexOf(t);return n!==-1?[e.substring(0,n),t,e.substring(n+t.length)]:[e,"",""]}async function mn(e,t){let{response:n,requestLogID:a,retryOfRequestLogID:i,startTime:s}=t,o=await(async()=>{if(t.options.stream)return z(e).debug("response",n.status,n.url,n.headers,n.body),t.options.__streamClass?t.options.__streamClass.fromSSEResponse(n,t.controller,e):wn.fromSSEResponse(n,t.controller,e);if(n.status===204)return null;if(t.options.__binaryResponse)return n;let l=n.headers.get("content-type")?.split(";")[0]?.trim();return l?.includes("application/json")||l?.endsWith("+json")?n.headers.get("content-length")==="0"?void 0:await n.json():await n.text()})();return z(e).debug(`[${a}] response parsed`,kt({retryOfRequestLogID:i,url:n.url,status:n.status,body:o,durationMs:Date.now()-s})),o}var Ye,Ht=class e extends Promise{constructor(t,n,a=mn){super(i=>{i(null)}),this.responsePromise=n,this.parseResponse=a,Ye.set(this,void 0),Z(this,Ye,t,"f")}_thenUnwrap(t){return new e(K(this,Ye,"f"),this.responsePromise,async(n,a)=>t(await this.parseResponse(n,a),a))}asResponse(){return this.responsePromise.then(t=>t.response)}async withResponse(){let[t,n]=await Promise.all([this.parse(),this.asResponse()]);return{data:t,response:n}}parse(){return this.parsedPromise||(this.parsedPromise=this.responsePromise.then(t=>this.parseResponse(K(this,Ye,"f"),t))),this.parsedPromise}then(t,n){return this.parse().then(t,n)}catch(t){return this.parse().catch(t)}finally(t){return this.parse().finally(t)}};Ye=new WeakMap;var yn,Cn=class{constructor(t,n,a,i){yn.set(this,void 0),Z(this,yn,t,"f"),this.options=i,this.response=n,this.body=a}hasNextPage(){return this.getPaginatedItems().length?this.nextPageRequestOptions()!=null:!1}async getNextPage(){let t=this.nextPageRequestOptions();if(!t)throw new V("No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.");return await K(this,yn,"f").requestAPIList(this.constructor,t)}async*iterPages(){let t=this;for(yield t;t.hasNextPage();)t=await t.getNextPage(),yield t}async*[(yn=new WeakMap,Symbol.asyncIterator)](){for await(let t of this.iterPages())for(let n of t.getPaginatedItems())yield n}},Ke=class extends Ht{constructor(t,n,a){super(t,n,async(i,s)=>new a(i,s.response,await mn(i,s),s.options))}async*[Symbol.asyncIterator](){let t=await this;for await(let n of t)yield n}},Tn=class extends Cn{constructor(t,n,a,i){super(t,n,a,i),this.items=a||[],this.next_page_token=this.response.headers.get("x-next-page-token")??null,this.has_more=ia(this.response.headers.get("x-has-more"))??null}getPaginatedItems(){return this.items??[]}hasNextPage(){return this.has_more===!1?!1:super.hasNextPage()}nextPageRequestOptions(){let t=this.next_page_token;return t?{...this.options,query:{...na(this.options.query),page_token:t}}:null}},D=class extends Cn{constructor(t,n,a,i){super(t,n,a,i),this.items=a||[],this.has_more=ia(this.response.headers.get("x-has-more"))??null,this.next_offset=gi(this.response.headers.get("x-next-offset"))??null}getPaginatedItems(){return this.items??[]}hasNextPage(){return this.has_more===!1?!1:super.hasNextPage()}nextPageRequestOptions(){let t=this.next_offset;if(t==null){if(this.has_more)throw new V("Server reported X-Has-More: true without an X-Next-Offset header; refusing to silently truncate pagination");return null}return t===0?null:{...this.options,query:{...na(this.options.query),offset:t}}}};var ma=()=>{if(typeof File>"u"){let{process:e}=globalThis,t=typeof e?.versions?.node=="string"&&parseInt(e.versions.node.split("."))<20;throw new Error("`File` is not defined as a global, which is required for file uploads."+(t?" Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`.":""))}};function he(e,t,n){return ma(),new File(e,t??"unknown_file",n)}function Je(e){return(typeof e=="object"&&e!==null&&("name"in e&&e.name&&String(e.name)||"url"in e&&e.url&&String(e.url)||"filename"in e&&e.filename&&String(e.filename)||"path"in e&&e.path&&String(e.path))||"").split(/[\\/]/).pop()||void 0}var kn=e=>e!=null&&typeof e=="object"&&typeof e[Symbol.asyncIterator]=="function";var ft=async(e,t)=>({...e,body:await or(e.body,t)}),Bi=new WeakMap;function sr(e){let t=typeof e=="function"?e:e.fetch,n=Bi.get(t);if(n)return n;let a=(async()=>{try{let i="Response"in t?t.Response:(await t("data:,")).constructor,s=new FormData;return s.toString()!==await new i(s).text()}catch{return!0}})();return Bi.set(t,a),a}var or=async(e,t)=>{if(!await sr(t))throw new TypeError("The provided fetch function does not support file uploads with the current global FormData class.");let n=new FormData;return await Promise.all(Object.entries(e||{}).map(([a,i])=>wa(n,a,i))),n},Di=e=>e instanceof Blob&&"name"in e,rr=e=>typeof e=="object"&&e!==null&&(e instanceof Response||kn(e)||Di(e)),pa=e=>{if(rr(e))return!0;if(Array.isArray(e))return e.some(pa);if(e&&typeof e=="object"){for(let t in e)if(pa(e[t]))return!0}return!1},wa=async(e,t,n)=>{if(n!==void 0){if(n==null)throw new TypeError(`Received null for "${t}"; to pass null in FormData, you must use the string 'null'`);if(typeof n=="string"||typeof n=="number"||typeof n=="boolean")e.append(t,String(n));else if(n instanceof Response)e.append(t,he([await n.blob()],Je(n)));else if(kn(n))e.append(t,he([await new Response(cn(n)).blob()],Je(n)));else if(Di(n))e.append(t,n,Je(n));else if(Array.isArray(n))await Promise.all(n.map((a,i)=>wa(e,`${t}[${i}]`,a)));else if(typeof n=="object")!(t==="env_vars")&&!pa(n)?Object.entries(n).filter(([s,o])=>o!==void 0).length>0&&e.append(t,JSON.stringify(n)):await Promise.all(Object.entries(n).map(([i,s])=>wa(e,`${t}[${i}]`,s)));else throw new TypeError(`Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${n} instead`)}};var Fi=e=>e!=null&&typeof e=="object"&&typeof e.size=="number"&&typeof e.type=="string"&&typeof e.text=="function"&&typeof e.slice=="function"&&typeof e.arrayBuffer=="function",dr=e=>e!=null&&typeof e=="object"&&typeof e.name=="string"&&typeof e.lastModified=="number"&&Fi(e),lr=e=>e!=null&&typeof e=="object"&&typeof e.url=="string"&&typeof e.blob=="function";async function fn(e,t,n){if(ma(),e=await e,dr(e))return e instanceof File?e:he([await e.arrayBuffer()],e.name);if(lr(e)){let i=await e.blob();return t||(t=new URL(e.url).pathname.split(/[\\/]/).pop()),he(await ya(i),t,n)}let a=await ya(e);if(t||(t=Je(e)),!n?.type){let i=a.find(s=>typeof s=="object"&&"type"in s&&s.type);typeof i=="string"&&(n={...n,type:i})}return he(a,t,n)}async function ya(e){let t=[];if(typeof e=="string"||ArrayBuffer.isView(e)||e instanceof ArrayBuffer)t.push(e);else if(Fi(e))t.push(e instanceof Blob?e:await e.arrayBuffer());else if(kn(e))for await(let n of e)t.push(...await ya(n));else{let n=e?.constructor?.name;throw new Error(`Unexpected data type: ${typeof e}${n?`; constructor: ${n}`:""}${Sr(e)}`)}return t}function Sr(e){return typeof e!="object"||e===null?"":`; props: [${Object.getOwnPropertyNames(e).map(n=>`"${n}"`).join(", ")}]`}var
|
|
5
|
+
`),raw:this.chunks};return this.event=null,this.data=[],this.chunks=[],s}if(this.chunks.push(t),t.startsWith(":"))return null;let[n,a,i]=ar(t,":");return i.startsWith(" ")&&(i=i.substring(1)),n==="event"?this.event=i:n==="data"&&this.data.push(i),null}};function ar(e,t){let n=e.indexOf(t);return n!==-1?[e.substring(0,n),t,e.substring(n+t.length)]:[e,"",""]}async function mn(e,t){let{response:n,requestLogID:a,retryOfRequestLogID:i,startTime:s}=t,o=await(async()=>{if(t.options.stream)return z(e).debug("response",n.status,n.url,n.headers,n.body),t.options.__streamClass?t.options.__streamClass.fromSSEResponse(n,t.controller,e):wn.fromSSEResponse(n,t.controller,e);if(n.status===204)return null;if(t.options.__binaryResponse)return n;let l=n.headers.get("content-type")?.split(";")[0]?.trim();return l?.includes("application/json")||l?.endsWith("+json")?n.headers.get("content-length")==="0"?void 0:await n.json():await n.text()})();return z(e).debug(`[${a}] response parsed`,kt({retryOfRequestLogID:i,url:n.url,status:n.status,body:o,durationMs:Date.now()-s})),o}var Ye,Ht=class e extends Promise{constructor(t,n,a=mn){super(i=>{i(null)}),this.responsePromise=n,this.parseResponse=a,Ye.set(this,void 0),Z(this,Ye,t,"f")}_thenUnwrap(t){return new e(K(this,Ye,"f"),this.responsePromise,async(n,a)=>t(await this.parseResponse(n,a),a))}asResponse(){return this.responsePromise.then(t=>t.response)}async withResponse(){let[t,n]=await Promise.all([this.parse(),this.asResponse()]);return{data:t,response:n}}parse(){return this.parsedPromise||(this.parsedPromise=this.responsePromise.then(t=>this.parseResponse(K(this,Ye,"f"),t))),this.parsedPromise}then(t,n){return this.parse().then(t,n)}catch(t){return this.parse().catch(t)}finally(t){return this.parse().finally(t)}};Ye=new WeakMap;var yn,Cn=class{constructor(t,n,a,i){yn.set(this,void 0),Z(this,yn,t,"f"),this.options=i,this.response=n,this.body=a}hasNextPage(){return this.getPaginatedItems().length?this.nextPageRequestOptions()!=null:!1}async getNextPage(){let t=this.nextPageRequestOptions();if(!t)throw new V("No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.");return await K(this,yn,"f").requestAPIList(this.constructor,t)}async*iterPages(){let t=this;for(yield t;t.hasNextPage();)t=await t.getNextPage(),yield t}async*[(yn=new WeakMap,Symbol.asyncIterator)](){for await(let t of this.iterPages())for(let n of t.getPaginatedItems())yield n}},Ke=class extends Ht{constructor(t,n,a){super(t,n,async(i,s)=>new a(i,s.response,await mn(i,s),s.options))}async*[Symbol.asyncIterator](){let t=await this;for await(let n of t)yield n}},Tn=class extends Cn{constructor(t,n,a,i){super(t,n,a,i),this.items=a||[],this.next_page_token=this.response.headers.get("x-next-page-token")??null,this.has_more=ia(this.response.headers.get("x-has-more"))??null}getPaginatedItems(){return this.items??[]}hasNextPage(){return this.has_more===!1?!1:super.hasNextPage()}nextPageRequestOptions(){let t=this.next_page_token;return t?{...this.options,query:{...na(this.options.query),page_token:t}}:null}},D=class extends Cn{constructor(t,n,a,i){super(t,n,a,i),this.items=a||[],this.has_more=ia(this.response.headers.get("x-has-more"))??null,this.next_offset=gi(this.response.headers.get("x-next-offset"))??null}getPaginatedItems(){return this.items??[]}hasNextPage(){return this.has_more===!1?!1:super.hasNextPage()}nextPageRequestOptions(){let t=this.next_offset;if(t==null){if(this.has_more)throw new V("Server reported X-Has-More: true without an X-Next-Offset header; refusing to silently truncate pagination");return null}return t===0?null:{...this.options,query:{...na(this.options.query),offset:t}}}};var ma=()=>{if(typeof File>"u"){let{process:e}=globalThis,t=typeof e?.versions?.node=="string"&&parseInt(e.versions.node.split("."))<20;throw new Error("`File` is not defined as a global, which is required for file uploads."+(t?" Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`.":""))}};function he(e,t,n){return ma(),new File(e,t??"unknown_file",n)}function Je(e){return(typeof e=="object"&&e!==null&&("name"in e&&e.name&&String(e.name)||"url"in e&&e.url&&String(e.url)||"filename"in e&&e.filename&&String(e.filename)||"path"in e&&e.path&&String(e.path))||"").split(/[\\/]/).pop()||void 0}var kn=e=>e!=null&&typeof e=="object"&&typeof e[Symbol.asyncIterator]=="function";var ft=async(e,t)=>({...e,body:await or(e.body,t)}),Bi=new WeakMap;function sr(e){let t=typeof e=="function"?e:e.fetch,n=Bi.get(t);if(n)return n;let a=(async()=>{try{let i="Response"in t?t.Response:(await t("data:,")).constructor,s=new FormData;return s.toString()!==await new i(s).text()}catch{return!0}})();return Bi.set(t,a),a}var or=async(e,t)=>{if(!await sr(t))throw new TypeError("The provided fetch function does not support file uploads with the current global FormData class.");let n=new FormData;return await Promise.all(Object.entries(e||{}).map(([a,i])=>wa(n,a,i))),n},Di=e=>e instanceof Blob&&"name"in e,rr=e=>typeof e=="object"&&e!==null&&(e instanceof Response||kn(e)||Di(e)),pa=e=>{if(rr(e))return!0;if(Array.isArray(e))return e.some(pa);if(e&&typeof e=="object"){for(let t in e)if(pa(e[t]))return!0}return!1},wa=async(e,t,n)=>{if(n!==void 0){if(n==null)throw new TypeError(`Received null for "${t}"; to pass null in FormData, you must use the string 'null'`);if(typeof n=="string"||typeof n=="number"||typeof n=="boolean")e.append(t,String(n));else if(n instanceof Response)e.append(t,he([await n.blob()],Je(n)));else if(kn(n))e.append(t,he([await new Response(cn(n)).blob()],Je(n)));else if(Di(n))e.append(t,n,Je(n));else if(Array.isArray(n))await Promise.all(n.map((a,i)=>wa(e,`${t}[${i}]`,a)));else if(typeof n=="object")!(t==="env_vars")&&!pa(n)?Object.entries(n).filter(([s,o])=>o!==void 0).length>0&&e.append(t,JSON.stringify(n)):await Promise.all(Object.entries(n).map(([i,s])=>wa(e,`${t}[${i}]`,s)));else throw new TypeError(`Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${n} instead`)}};var Fi=e=>e!=null&&typeof e=="object"&&typeof e.size=="number"&&typeof e.type=="string"&&typeof e.text=="function"&&typeof e.slice=="function"&&typeof e.arrayBuffer=="function",dr=e=>e!=null&&typeof e=="object"&&typeof e.name=="string"&&typeof e.lastModified=="number"&&Fi(e),lr=e=>e!=null&&typeof e=="object"&&typeof e.url=="string"&&typeof e.blob=="function";async function fn(e,t,n){if(ma(),e=await e,dr(e))return e instanceof File?e:he([await e.arrayBuffer()],e.name);if(lr(e)){let i=await e.blob();return t||(t=new URL(e.url).pathname.split(/[\\/]/).pop()),he(await ya(i),t,n)}let a=await ya(e);if(t||(t=Je(e)),!n?.type){let i=a.find(s=>typeof s=="object"&&"type"in s&&s.type);typeof i=="string"&&(n={...n,type:i})}return he(a,t,n)}async function ya(e){let t=[];if(typeof e=="string"||ArrayBuffer.isView(e)||e instanceof ArrayBuffer)t.push(e);else if(Fi(e))t.push(e instanceof Blob?e:await e.arrayBuffer());else if(kn(e))for await(let n of e)t.push(...await ya(n));else{let n=e?.constructor?.name;throw new Error(`Unexpected data type: ${typeof e}${n?`; constructor: ${n}`:""}${Sr(e)}`)}return t}function Sr(e){return typeof e!="object"||e===null?"":`; props: [${Object.getOwnPropertyNames(e).map(n=>`"${n}"`).join(", ")}]`}var b=class{constructor(t){this._client=t}};var Gi=Symbol("brand.privateNullableHeaders");function*ur(e){if(!e)return;if(Gi in e){let{values:a,nulls:i}=e;yield*a.entries();for(let s of i)yield[s,null];return}let t=!1,n;e instanceof Headers?n=e.entries():ea(e)?n=e:(t=!0,n=Object.entries(e??{}));for(let a of n){let i=a[0];if(typeof i!="string")throw new TypeError("expected header name to be a string");let s=ea(a[1])?a[1]:[a[1]],o=!1;for(let d of s)d!==void 0&&(t&&!o&&(o=!0,yield[i,null]),yield[i,d])}}var T=e=>{let t=new Headers,n=new Set;for(let a of e){let i=new Set;for(let[s,o]of ur(a)){let d=s.toLowerCase();i.has(d)||(t.delete(s),i.add(d)),o===null?(t.delete(s),n.add(d)):(t.append(s,o),n.delete(d))}}return{[Gi]:!0,values:t,nulls:n}};function Yi(e){return e.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g,encodeURIComponent)}var Vi=Object.freeze(Object.create(null)),cr=(e=Yi)=>function(n,...a){if(n.length===1)return n[0];let i=!1,s=[],o=n.reduce((S,r,u)=>{/[?#]/.test(r)&&(i=!0);let c=a[u],h=(i?encodeURIComponent:e)(""+c);return u!==a.length&&(c==null||typeof c=="object"&&c.toString===Object.getPrototypeOf(Object.getPrototypeOf(c.hasOwnProperty??Vi)??Vi)?.toString)&&(h=c+"",s.push({start:S.length+r.length,length:h.length,error:`Value of type ${Object.prototype.toString.call(c).slice(8,-1)} is not a valid path parameter`})),S+r+(u===a.length?"":h)},""),d=o.split(/[?#]/,1)[0],l=/(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi,U;for(;(U=l.exec(d))!==null;)s.push({start:U.index,length:U[0].length,error:`Value "${U[0]}" can't be safely passed as a path parameter`});if(s.sort((S,r)=>S.start-r.start),s.length>0){let S=0,r=s.reduce((u,c)=>{let h=" ".repeat(c.start-S),m="^".repeat(c.length);return S=c.start+c.length,u+h+m},"");throw new V(`Path parameters result in path with invalid segments:
|
|
6
6
|
${s.map(u=>u.error).join(`
|
|
7
7
|
`)}
|
|
8
8
|
${o}
|
|
9
|
-
${r}`)}return o},g=cr(Yi);var Bt=class extends _{create(t,n){return this._client.post("/org/api_keys",{body:t,...n})}retrieve(t,n={},a){return this._client.get(g`/org/api_keys/${t}`,{query:n,...a})}update(t,n,a){return this._client.patch(g`/org/api_keys/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/org/api_keys",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/org/api_keys/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}rotate(t,n={},a){return this._client.post(g`/org/api_keys/${t}/rotate`,{body:n,...a})}};var Dt=class extends _{list(t={},n){return this._client.getAPIList("/apps",D,{query:t,...n})}};var ge=class extends _{create(t,n){return this._client.post("/audit-logs/export/destinations",{body:t,...n})}retrieve(t,n){return this._client.get(g`/audit-logs/export/destinations/${t}`,n)}update(t,n,a){return this._client.patch(g`/audit-logs/export/destinations/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/audit-logs/export/destinations",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/audit-logs/export/destinations/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}test(t,n){return this._client.post(g`/audit-logs/export/destinations/${t}/test`,n)}};var gr=6,pr=5e4,wr=8e3,ht=class extends V{};async function Ji(e,t,n,a,i={}){if(!n||typeof n.write!="function")throw new TypeError("audit log download destination must provide write()");let{onProgress:s,maxTransferRetries:o=gr,...d}=i;if(!Number.isInteger(o)||o<0)throw new TypeError("maxTransferRetries must be a non-negative integer");let l=d.timeout??a,U,S={bytesWritten:0,chunks:0,rows:0},r=new Set;for(;;){let u=await mr(e,U?{...t,cursor:U}:t,d,o,l),{nextCursor:c,hasMore:h,rows:m}=yr(u.headers,U);if(h&&c){if(r.has(c))throw new ht("response repeated X-Next-Cursor header");r.add(c)}if(await kr(n,u.body),U=c,S.bytesWritten+=u.body.byteLength,S.chunks+=1,S.rows+=m,s&&await s({...S,chunkRows:m}),!h)return S}}async function mr(e,t,n,a,i){for(let s=0;;s+=1){let o=new AbortController,d=()=>o.abort();n.signal?.aborted?o.abort():n.signal?.addEventListener("abort",d,{once:!0});let l;try{l=await e(t,{...n,signal:o.signal})}catch(r){throw n.signal?.removeEventListener("abort",d),r}let U=!1,S=setTimeout(()=>{U=!0,o.abort()},i);try{let r=new Uint8Array(await l.arrayBuffer());if(clearTimeout(S),n.signal?.aborted)throw new st;if(U)throw new Tt;let u=l.headers.get("x-content-sha256");if(!u)throw new ht("response missing X-Content-Sha256 header");let c=await Cr(r);if(n.signal?.aborted)throw new st;if(c!==u)throw new ht(`audit log chunk checksum mismatch (got ${c}, want ${u})`);return{body:r,headers:l.headers}}catch(r){if(n.signal?.aborted&&!(r instanceof st)?r=new st:U&&(r=new Tt),s===a||r instanceof st)throw r;await Tr(s+1,n.signal)}finally{clearTimeout(S),n.signal?.removeEventListener("abort",d)}}}function yr(e,t){let n=e.get("x-has-more");if(n!=="true"&&n!=="false")throw new ht("response missing or invalid X-Has-More header");let a=n==="true",i=e.get("x-row-count");if(i===null||!/^[0-9]+$/.test(i))throw new ht("response missing or invalid X-Row-Count header");let s=Number(i);if(!Number.isSafeInteger(s)||s>pr)throw new ht("response missing or invalid X-Row-Count header");let o=e.get("x-next-cursor")||void 0;if(a&&(!o||o===t))throw new ht("response has invalid X-Next-Cursor header");if(!a&&o)throw new ht("response returned a cursor after the final chunk");return{rows:s,nextCursor:o,hasMore:a}}async function Cr(e){let t=await globalThis.crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(t),n=>n.toString(16).padStart(2,"0")).join("")}async function Tr(e,t){let n=Math.min(1e3*2**(e-1),wr);await new Promise((a,i)=>{if(t?.aborted){i(new st);return}let s=()=>{clearTimeout(o),i(new st)},o=setTimeout(()=>{t?.removeEventListener("abort",s),a()},n);t?.addEventListener("abort",s,{once:!0})})}async function kr(e,t){let n=0;for(;n<t.byteLength;){let a=await e.write(n===0?t:t.subarray(n));if(typeof a=="number"){n+=Ki(a,t.byteLength-n);continue}if(a&&typeof a=="object"&&"bytesWritten"in a){let i=a.bytesWritten;n+=Ki(i,t.byteLength-n);continue}return}}function Ki(e,t){if(!Number.isSafeInteger(e)||e<=0||e>t)throw new ht("audit log download destination performed a short write");return e}var Et=class extends _{constructor(){super(...arguments),this.exportDestinations=new ge(this._client)}list(t,n){return this._client.getAPIList("/audit-logs",Tn,{query:t,...n})}exportChunk(t,n){return this._client.get("/audit-logs/export/chunk",{query:t,...n,headers:T([{Accept:"application/octet-stream"},n?.headers]),__binaryResponse:!0})}download(t,n,a){return Ji((i,s)=>this.exportChunk(i,s),t,n,this._client.timeout,a)}};Et.ExportDestinations=ge;var pe=class extends _{create(t,n){return this._client.post("/auth/connections",{body:t,...n})}retrieve(t,n){return this._client.get(g`/auth/connections/${t}`,n)}update(t,n,a){return this._client.patch(g`/auth/connections/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/auth/connections",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/auth/connections/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}follow(t,n){return this._client.get(g`/auth/connections/${t}/events`,{...n,headers:T([{Accept:"text/event-stream"},n?.headers]),stream:!0})}login(t,n={},a){return this._client.post(g`/auth/connections/${t}/login`,{body:n,...a})}submit(t,n,a){return this._client.post(g`/auth/connections/${t}/submit`,{body:n,...a})}timeline(t,n={},a){return this._client.getAPIList(g`/auth/connections/${t}/timeline`,D,{query:n,...a})}};var we=class extends _{retrieve(t){return this._client.get("/auth/context",t)}};var Mt=class extends _{constructor(){super(...arguments),this.context=new we(this._client),this.connections=new pe(this._client)}};Mt.Context=we;Mt.Connections=pe;var Ft=class extends _{create(t,n){return this._client.post("/browser_pools",{body:t,...n})}retrieve(t,n){return this._client.get(g`/browser_pools/${t}`,n)}update(t,n,a){return this._client.patch(g`/browser_pools/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/browser_pools",D,{query:t,...n})}delete(t,n={},a){return this._client.delete(g`/browser_pools/${t}`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}acquire(t,n,a){return this._client.post(g`/browser_pools/${t}/acquire`,{body:n,...a})}flush(t,n){return this._client.post(g`/browser_pools/${t}/flush`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}release(t,n,a){return this._client.post(g`/browser_pools/${t}/release`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}};var me=class extends _{batch(t,n,a){return this._client.post(g`/browsers/${t}/computer/batch`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}captureScreenshot(t,n={},a){return this._client.post(g`/browsers/${t}/computer/screenshot`,{body:n,...a,headers:T([{Accept:"image/png"},a?.headers]),__binaryResponse:!0})}clickMouse(t,n,a){return this._client.post(g`/browsers/${t}/computer/click_mouse`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}dragMouse(t,n,a){return this._client.post(g`/browsers/${t}/computer/drag_mouse`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}getMousePosition(t,n){return this._client.post(g`/browsers/${t}/computer/get_mouse_position`,n)}moveMouse(t,n,a){return this._client.post(g`/browsers/${t}/computer/move_mouse`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}pressKey(t,n,a){return this._client.post(g`/browsers/${t}/computer/press_key`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}readClipboard(t,n){return this._client.post(g`/browsers/${t}/computer/clipboard/read`,n)}scroll(t,n,a){return this._client.post(g`/browsers/${t}/computer/scroll`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}setCursorVisibility(t,n,a){return this._client.post(g`/browsers/${t}/computer/cursor`,{body:n,...a})}typeText(t,n,a){return this._client.post(g`/browsers/${t}/computer/type`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}writeClipboard(t,n,a){return this._client.post(g`/browsers/${t}/computer/clipboard/write`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}};var ye=class extends _{stream(t,n,a){return this._client.get(g`/browsers/${t}/logs/stream`,{query:n,...a,headers:T([{Accept:"text/event-stream"},a?.headers]),stream:!0})}};var Ce=class extends _{execute(t,n,a){return this._client.post(g`/browsers/${t}/playwright/execute`,{body:n,...a})}};var Te=class extends _{exec(t,n,a){return this._client.post(g`/browsers/${t}/process/exec`,{body:n,...a})}kill(t,n,a){let{id:i,...s}=n;return this._client.post(g`/browsers/${i}/process/${t}/kill`,{body:s,...a})}resize(t,n,a){let{id:i,...s}=n;return this._client.post(g`/browsers/${i}/process/${t}/resize`,{body:s,...a})}spawn(t,n,a){return this._client.post(g`/browsers/${t}/process/spawn`,{body:n,...a})}status(t,n,a){let{id:i}=n;return this._client.get(g`/browsers/${i}/process/${t}/status`,a)}stdin(t,n,a){let{id:i,...s}=n;return this._client.post(g`/browsers/${i}/process/${t}/stdin`,{body:s,...a})}stdoutStream(t,n,a){let{id:i}=n;return this._client.get(g`/browsers/${i}/process/${t}/stdout/stream`,{...a,headers:T([{Accept:"text/event-stream"},a?.headers]),stream:!0})}};var ke=class extends _{list(t,n){return this._client.get(g`/browsers/${t}/replays`,n)}download(t,n,a){let{id:i}=n;return this._client.get(g`/browsers/${i}/replays/${t}`,{...a,headers:T([{Accept:"video/mp4"},a?.headers]),__binaryResponse:!0})}start(t,n={},a){return this._client.post(g`/browsers/${t}/replays`,{body:n,...a})}stop(t,n,a){let{id:i}=n;return this._client.post(g`/browsers/${i}/replays/${t}/stop`,{...a,headers:T([{Accept:"*/*"},a?.headers])})}};var fe=class extends _{events(t,n={},a){return this._client.getAPIList(g`/browsers/${t}/telemetry/events`,D,{query:n,...a})}stream(t,n={},a){let{"Last-Event-ID":i,...s}=n??{};return this._client.get(g`/browsers/${t}/telemetry/stream`,{query:s,...a,headers:T([{Accept:"text/event-stream",...i!=null?{"Last-Event-ID":i}:void 0},a?.headers]),stream:!0})}};var Me=class extends _{events(t,n,a){let{id:i}=n;return this._client.get(g`/browsers/${i}/fs/watch/${t}/events`,{...a,headers:T([{Accept:"text/event-stream"},a?.headers]),stream:!0})}start(t,n,a){return this._client.post(g`/browsers/${t}/fs/watch`,{body:n,...a})}stop(t,n,a){let{id:i}=n;return this._client.delete(g`/browsers/${i}/fs/watch/${t}`,{...a,headers:T([{Accept:"*/*"},a?.headers])})}};var Gt=class extends _{constructor(){super(...arguments),this.watch=new Me(this._client)}createDirectory(t,n,a){return this._client.put(g`/browsers/${t}/fs/create_directory`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}deleteDirectory(t,n,a){return this._client.put(g`/browsers/${t}/fs/delete_directory`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}deleteFile(t,n,a){return this._client.put(g`/browsers/${t}/fs/delete_file`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}downloadDirZip(t,n,a){return this._client.get(g`/browsers/${t}/fs/download_dir_zip`,{query:n,...a,headers:T([{Accept:"application/zip"},a?.headers]),__binaryResponse:!0})}fileInfo(t,n,a){return this._client.get(g`/browsers/${t}/fs/file_info`,{query:n,...a})}listFiles(t,n,a){return this._client.get(g`/browsers/${t}/fs/list_files`,{query:n,...a})}move(t,n,a){return this._client.put(g`/browsers/${t}/fs/move`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}readFile(t,n,a){return this._client.get(g`/browsers/${t}/fs/read_file`,{query:n,...a,headers:T([{Accept:"application/octet-stream"},a?.headers]),__binaryResponse:!0})}setFilePermissions(t,n,a){return this._client.put(g`/browsers/${t}/fs/set_file_permissions`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}upload(t,n,a){return this._client.post(g`/browsers/${t}/fs/upload`,ft({body:n,...a,headers:T([{Accept:"*/*"},a?.headers])},this._client))}uploadZip(t,n,a){return this._client.post(g`/browsers/${t}/fs/upload_zip`,ft({body:n,...a,headers:T([{Accept:"*/*"},a?.headers])},this._client))}writeFile(t,n,a,i){let{path:s,mode:o}=a;return this._client.put(g`/browsers/${t}/fs/write_file`,{body:n,query:{path:s,mode:o},...i,headers:T([{"Content-Type":"application/octet-stream",Accept:"*/*"},i?.headers])})}};Gt.Watch=Me;function Mn(e,t){return`${e.replace(/\/+$/,"")}${t.startsWith("/")?t:`/${t}`}`}async function qi(e,t,n,a){let i=e.browserRouteCache.get(t);if(!i)throw new V(`browser route cache does not contain session ${t}; create, retrieve, or list the browser before calling browser.fetch`);let{url:s,method:o,headers:d,body:l,signal:U,duplex:S,timeout_ms:r}=xr(n,a);Or(s);let u={url:s,jwt:i.jwt};r!==void 0&&(u.timeout_ms=r);let c=d.get("accept"),h={method:Lr(o),path:Mn(i.baseURL,"/curl/raw"),query:u,body:l,headers:T([{Authorization:null},c?{Accept:c}:{Accept:"*/*"},Rr(d)]),signal:U??null,__binaryResponse:!0};return S&&(h.fetchOptions={duplex:S}),e.request(h).asResponse()}function Lr(e){let t=e.toLowerCase();if(!new Set(["get","post","put","patch","delete"]).has(t))throw new V(`browser.fetch unsupported HTTP method: ${e}`);return t}function xr(e,t){let n=t&&"timeout_ms"in t?t.timeout_ms:void 0;if(e instanceof Request){let i=new Headers(e.headers);t?.headers&&new Headers(t.headers).forEach((U,S)=>{i.set(S,U)});let s={url:e.url,method:(t?.method??e.method)?.toUpperCase()||"GET",headers:i},o=t?.body??e.body;o!=null&&(s.body=o);let d=t?.signal??e.signal;return d!==void 0&&(s.signal=d),t?.duplex!==void 0&&(s.duplex=t.duplex),n!==void 0&&(s.timeout_ms=n),s}let a={url:e instanceof URL?e.href:String(e),method:(t?.method??"GET").toUpperCase(),headers:new Headers(t?.headers)};return t?.body!==void 0&&(a.body=t.body),t?.signal!==void 0&&(a.signal=t.signal),t?.duplex!==void 0&&(a.duplex=t.duplex),n!==void 0&&(a.timeout_ms=n),a}function Or(e){let t;try{t=new URL(e)}catch{throw new V(`browser.fetch target must be an absolute URL; received: ${e}`)}if(t.protocol!=="http:"&&t.protocol!=="https:")throw new V(`browser.fetch only supports http(s) URLs; received: ${t.protocol}`)}function Rr(e){let t={};return e.forEach((n,a)=>{switch(a.toLowerCase()){case"accept":case"content-length":case"connection":case"keep-alive":case"proxy-authenticate":case"proxy-authorization":case"te":case"trailers":case"transfer-encoding":case"upgrade":return;default:t[a]=n}}),t}var dt=class extends _{constructor(){super(...arguments),this.telemetry=new fe(this._client),this.replays=new ke(this._client),this.fs=new Gt(this._client),this.process=new Te(this._client),this.logs=new ye(this._client),this.computer=new me(this._client),this.playwright=new Ce(this._client)}create(t={},n){return this._client.post("/browsers",{body:t,...n})}retrieve(t,n={},a){return this._client.get(g`/browsers/${t}`,{query:n,...a})}update(t,n,a){return this._client.patch(g`/browsers/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/browsers",D,{query:t,...n})}curl(t,n,a){return this._client.post(g`/browsers/${t}/curl`,{body:n,...a})}fetch(t,n,a){return qi(this._client,t,n,a)}deleteByID(t,n){return this._client.delete(g`/browsers/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}loadExtensions(t,n,a){return this._client.post(g`/browsers/${t}/extensions`,ft({body:n,...a,headers:T([{Accept:"*/*"},a?.headers])},this._client))}};dt.Telemetry=fe;dt.Replays=ke;dt.Fs=Gt;dt.Process=Te;dt.Logs=ye;dt.Computer=me;dt.Playwright=Ce;var Vt=class extends _{create(t,n){return this._client.post("/org/credential_providers",{body:t,...n})}retrieve(t,n){return this._client.get(g`/org/credential_providers/${t}`,n)}update(t,n,a){return this._client.patch(g`/org/credential_providers/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/org/credential_providers",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/org/credential_providers/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}listItems(t,n){return this._client.get(g`/org/credential_providers/${t}/items`,n)}test(t,n){return this._client.post(g`/org/credential_providers/${t}/test`,n)}};var Yt=class extends _{create(t,n){return this._client.post("/credentials",{body:t,...n})}retrieve(t,n){return this._client.get(g`/credentials/${t}`,n)}update(t,n,a){return this._client.patch(g`/credentials/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/credentials",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/credentials/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}totpCode(t,n){return this._client.get(g`/credentials/${t}/totp-code`,n)}};var Kt=class extends _{create(t,n){return this._client.post("/deployments",ft({body:t,...n},this._client))}retrieve(t,n){return this._client.get(g`/deployments/${t}`,n)}list(t={},n){return this._client.getAPIList("/deployments",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/deployments/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}follow(t,n={},a){return this._client.get(g`/deployments/${t}/events`,{query:n,...a,headers:T([{Accept:"text/event-stream"},a?.headers]),stream:!0})}};var Jt=class extends _{list(t={},n){return this._client.getAPIList("/extensions",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/extensions/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}download(t,n){return this._client.get(g`/extensions/${t}`,{...n,headers:T([{Accept:"application/octet-stream"},n?.headers]),__binaryResponse:!0})}downloadFromChromeStore(t,n){return this._client.get("/extensions/from_chrome_store",{query:t,...n,headers:T([{Accept:"application/octet-stream"},n?.headers]),__binaryResponse:!0})}get(t,n){return this._client.get(g`/extensions/${t}/metadata`,n)}upload(t,n){return this._client.post("/extensions",ft({body:t,...n},this._client))}};var qt=class extends _{create(t,n){return this._client.post("/invocations",{body:t,...n})}retrieve(t,n){return this._client.get(g`/invocations/${t}`,n)}update(t,n,a){return this._client.patch(g`/invocations/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/invocations",D,{query:t,...n})}deleteBrowsers(t,n){return this._client.delete(g`/invocations/${t}/browsers`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}follow(t,n={},a){return this._client.get(g`/invocations/${t}/events`,{query:n,...a,headers:T([{Accept:"text/event-stream"},a?.headers]),stream:!0})}listBrowsers(t,n){return this._client.get(g`/invocations/${t}/browsers`,n)}};var Ne=class extends _{retrieve(t){return this._client.get("/org/entitlements",t)}};var ve=class extends _{retrieve(t){return this._client.get("/org/limits",t)}update(t,n){return this._client.patch("/org/limits",{body:t,...n})}};var Nt=class extends _{constructor(){super(...arguments),this.entitlements=new Ne(this._client),this.limits=new ve(this._client)}};Nt.Entitlements=Ne;Nt.Limits=ve;var Xt=class extends _{create(t,n){return this._client.post("/profiles",{body:t,...n})}retrieve(t,n){return this._client.get(g`/profiles/${t}`,n)}update(t,n,a){return this._client.patch(g`/profiles/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/profiles",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/profiles/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}download(t,n={},a){return this._client.get(g`/profiles/${t}/download`,{query:n,...a,headers:T([{Accept:"application/octet-stream"},a?.headers]),__binaryResponse:!0})}};var be=class extends _{retrieve(t,n){return this._client.get(g`/org/projects/${t}/limits`,n)}update(t,n,a){return this._client.patch(g`/org/projects/${t}/limits`,{body:n,...a})}};var Pt=class extends _{constructor(){super(...arguments),this.limits=new be(this._client)}create(t,n){return this._client.post("/org/projects",{body:t,...n})}retrieve(t,n){return this._client.get(g`/org/projects/${t}`,n)}update(t,n,a){return this._client.patch(g`/org/projects/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/org/projects",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/org/projects/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}};Pt.Limits=be;var jt=class extends _{create(t,n){return this._client.post("/proxies",{body:t,...n})}retrieve(t,n){return this._client.get(g`/proxies/${t}`,n)}update(t,n,a){return this._client.patch(g`/proxies/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/proxies",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/proxies/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}check(t,n={},a){return this._client.post(g`/proxies/${t}/check`,{body:n,...a})}};var _e=class extends _{create(t,n){return this._client.post("/telemetry/destinations",{body:t,...n})}retrieve(t,n){return this._client.get(g`/telemetry/destinations/${t}`,n)}update(t,n,a){return this._client.patch(g`/telemetry/destinations/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/telemetry/destinations",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/telemetry/destinations/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}};var It=class extends _{constructor(){super(...arguments),this.destinations=new _e(this._client)}};It.Destinations=_e;var qe=class{constructor(){this.entries=new Map}get(t){return this.entries.get(t)}set(t){this.entries.set(t.sessionId,t)}delete(t){this.entries.delete(t)}clear(){this.entries.clear()}},Xi="\u004b\u0045\u0052\u004e\u0045\u004c_BROWSER_ROUTING_SUBRESOURCES",Gr=["curl","telemetry/stream"],Vr=/^\/(?:v\d+\/)?browsers(?:\/[^/]+)?\/?$/,Yr=/^\/(?:v\d+\/)?browser_pools\/[^/]+\/acquire\/?$/,Kr=/^\/(?:v\d+\/)?browsers\/([^/]+)\/?$/,Jr=/^\/(?:v\d+\/)?browser_pools\/[^/]+\/release\/?$/;function Ta(){let e=sd();return e===void 0?[...Gr]:e.trim()===""?[]:e.split(",").map(t=>t.trim()).filter(Boolean)}function ka(e,{apiBaseURL:t,subresources:n,cache:a}){let i=[...n].map(o=>o.trim().replace(/^\/+|\/+$/g,"")).filter(Boolean),s=new URL(t).origin;return async(o,d)=>{let l=new Request(o,d),U=qr(l,s),S=await td(e,{input:o,init:d,request:l},s,i,a);return U&&await Qr(S,a),await Xr(l,S,s,a),S}}function qr(e,t){let n=new URL(e.url);return n.origin===t&&(Vr.test(n.pathname)||Yr.test(n.pathname))}async function Xr(e,t,n,a){if(!t.ok)return;let i=new URL(e.url);if(i.origin!==n)return;let s=jr(e,i.pathname)??await zr(e,i.pathname);s&&a.delete(s)}function jr(e,t){if(e.method.toUpperCase()!=="DELETE")return;let n=t.match(Kr);return n&&decodeURIComponent(n[1]??"")||void 0}async function zr(e,t){if(!(e.method.toUpperCase()!=="POST"||!Jr.test(t)))try{let n=await e.clone().json();if(!n||typeof n!="object")return;let a=n.session_id;return typeof a=="string"&&a.trim()?a.trim():void 0}catch{return}}function $r(e){if(!e||typeof e!="object")return;let t=e,n=typeof t.session_id=="string"?t.session_id.trim():"",a=typeof t.base_url=="string"?t.base_url.trim():"";if(!n||!a)return;let i=typeof t.jwt=="string"?t.jwt.trim():"",s=typeof t.cdp_ws_url=="string"?t.cdp_ws_url:void 0,o=i||id(s)||"";if(o)return{sessionId:n,baseURL:a,jwt:o}}async function Qr(e,t){if((e.headers.get("content-type")?.toLowerCase()??"").includes("application/json"))try{Ca(await e.clone().json(),t)}catch{}}function Ca(e,t){let n=$r(e);if(n&&t.set(n),Array.isArray(e)){for(let a of e)Ca(a,t);return}if(!(!e||typeof e!="object"))for(let a of Object.values(e))typeof a=="object"&&a!==null&&Ca(a,t)}function Zr(e,t){let n=e.replace(/^\/+|\/+$/g,"");return t.some(a=>n===a||n.startsWith(a+"/"))}async function td(e,{input:t,init:n,request:a},i,s,o){let d=new URL(a.url);if(d.origin!==i)return e(t,n);let l=d.pathname.match(/^\/(?:v\d+\/)?browsers\/([^/]+)\/([^/]+)(\/.*)?$/);if(!l)return e(t,n);let U=decodeURIComponent(l[1]??""),S=l[2]??"";if(!U||!Zr(S+(l[3]??""),s))return e(t,n);let r=o.get(U);if(r===void 0)return e(t,n);let u=new URL(Mn(r.baseURL,`/${S}${l[3]??""}`));d.searchParams.forEach((h,m)=>{m!=="jwt"&&u.searchParams.append(m,h)}),u.searchParams.get("jwt")||u.searchParams.set("jwt",r.jwt);let c=new Headers(a.headers);return c.delete("authorization"),e(u.toString(),ed(t,a,n,c))}function ed(e,t,n,a){let i=t.method.toUpperCase(),s={...n??{},method:i,headers:a,redirect:t.redirect,signal:n?.signal??(e instanceof Request?e.signal:void 0)};if(delete s.body,delete s.duplex,i!=="GET"&&i!=="HEAD"){let o=nd(t,n);o!==void 0&&(s.body=o),n?.duplex!==void 0?s.duplex=n.duplex:ad(o)&&(s.duplex="half")}return s}function nd(e,t){return t?.body!==void 0&&t.body!==null?t.body:e.body??void 0}function ad(e){return globalThis.ReadableStream&&e instanceof globalThis.ReadableStream||typeof e=="object"&&e!==null&&Symbol.asyncIterator in e}function id(e){if(e)try{return new URL(e).searchParams.get("jwt")??void 0}catch{return}}function sd(){if(typeof globalThis.process<"u"){let e=globalThis.process.env?.[Xi];return typeof e=="string"?e:void 0}if(typeof globalThis.Deno<"u"){let e=globalThis.Deno.env?.get?.(Xi);return typeof e=="string"?e:void 0}}var Nn=class{constructor(t){this.actions=new Map,this.name=t,ji.registerApp(this)}action(t,n){let a;if(n.length===0)throw new Error("Action handlers must accept at least the context parameter");if(n.length===1){let i=n;a=async(s,o)=>i(s)}else a=n;return this.actions.set(t,{name:t,handler:a}),a}getActions(){return Array.from(this.actions.values())}getAction(t){return this.actions.get(t)}toJSON(){return{name:this.name,actions:this.getActions().map(t=>({name:t.name}))}}},fa=class{constructor(){this.apps=new Map}registerApp(t){this.apps.set(t.name,t)}getApps(){return Array.from(this.apps.values())}getAppByName(t){return this.apps.get(t)}export(){return{apps:this.getApps().map(t=>t.toJSON())}}exportJSON(){return JSON.stringify(this.export(),null,2)}},ji=new fa;var Ee=e=>{if(typeof globalThis.process<"u")return globalThis.process.env?.[e]?.trim()||void 0;if(typeof globalThis.Deno<"u")return globalThis.Deno.env?.get?.(e)?.trim()||void 0};var Ma,Na,Xe,zi,$i={production:"https://api.on\u006b\u0065\u0072\u006e\u0065\u006c.com/",development:"https://localhost:3001/"},H=class{constructor({baseURL:t=Ee("\u004b\u0045\u0052\u004e\u0045\u004c_BASE_URL"),apiKey:n=Ee("\u004b\u0045\u0052\u004e\u0045\u004c_API_KEY"),projectID:a=null,project:i=null,...s}={}){if(Ma.add(this),Xe.set(this,void 0),this.deployments=new Kt(this),this.apps=new Dt(this),this.invocations=new qt(this),this.browsers=new dt(this),this.profiles=new Xt(this),this.auth=new Mt(this),this.telemetry=new It(this),this.proxies=new jt(this),this.extensions=new Jt(this),this.browserPools=new Ft(this),this.credentials=new Yt(this),this.projects=new Pt(this),this.organization=new Nt(this),this.auditLogs=new Et(this),this.apiKeys=new Bt(this),this.credentialProviders=new Vt(this),typeof globalThis<"u"&&typeof globalThis.Bun<"u"&&globalThis.Bun.version&&!Ee("\u004b\u0045\u0052\u004e\u0045\u004c_SUPPRESS_BUN_WARNING")&&z(this).warn("The Bun runtime was detected. Playwright may have CDP connection issues, proceed with caution. Suppress this warning by setting the \u004b\u0045\u0052\u004e\u0045\u004c_SUPPRESS_BUN_WARNING environment variable to true"),n===void 0)throw new V("The \u004b\u0045\u0052\u004e\u0045\u004c_API_KEY environment variable is missing or empty; either provide it, or instantiate the \u004b\u0065\u0072\u006e\u0065\u006c client with an apiKey option, like new \u004b\u0065\u0072\u006e\u0065\u006c({ apiKey: 'My API Key' }).");let o={apiKey:n,projectID:a,project:i,...s,baseURL:t,environment:s.environment??"production"};if(t&&s.environment)throw new V("Ambiguous URL; The `baseURL` option (or \u004b\u0045\u0052\u004e\u0045\u004c_BASE_URL env var) and the `environment` option are given. If you want to use the environment you must pass baseURL: null");this.baseURL=o.baseURL||$i[o.environment||"production"],this.timeout=o.timeout??Na.DEFAULT_TIMEOUT,this.logger=o.logger??console;let d="warn";this.logLevel=d,this.logLevel=ha(o.logLevel,"ClientOptions.logLevel",this)??ha(Ee("\u004b\u0045\u0052\u004e\u0045\u004c_LOG"),"process.env['\u004b\u0045\u0052\u004e\u0045\u004c_LOG']",this)??d,this.fetchOptions=o.fetchOptions,this.maxRetries=o.maxRetries??2,this.rawFetch=o.fetch??ki(),this.browserRouteCache=new qe,this.fetch=ka(this.rawFetch,{apiBaseURL:this.baseURL,subresources:Ta(),cache:this.browserRouteCache}),Z(this,Xe,Mi,"f");let l=Ee("\u004b\u0045\u0052\u004e\u0045\u004c_CUSTOM_HEADERS");if(l){let U={};for(let S of l.split(`
|
|
10
|
-
`)){let r=S.indexOf(":");r>=0&&(U[S.substring(0,r).trim()]=S.substring(r+1).trim())}o.defaultHeaders={...U,...o.defaultHeaders}}this._options=o,this.apiKey=n,this.projectID=a,this.project=i}withOptions(t){let n=new this.constructor({...this._options,environment:t.environment?t.environment:void 0,baseURL:t.environment?void 0:this.baseURL,maxRetries:this.maxRetries,timeout:this.timeout,logger:this.logger,logLevel:this.logLevel,fetch:this.rawFetch,fetchOptions:this.fetchOptions,apiKey:this.apiKey,projectID:this.projectID,project:this.project,...t});return n.browserRouteCache=this.browserRouteCache,n.fetch=ka(n.rawFetch,{apiBaseURL:n.baseURL,subresources:Ta(),cache:n.browserRouteCache}),n}defaultQuery(){return this._options.defaultQuery}validateHeaders({values:t,nulls:n}){}async authHeaders(t){return T([{Authorization:`Bearer ${this.apiKey}`}])}stringifyQuery(t){return Li(t)}getUserAgent(){return`${this.constructor.name}/JS ${_t}`}defaultIdempotencyKey(){return`stainless-node-retry-${ta()}`}makeStatusError(t,n,a,i){return et.generate(t,n,a,i)}buildURL(t,n,a){let i=!K(this,Ma,"m",zi).call(this)&&a||this.baseURL,s=ui(t)?new URL(t):new URL(i+(i.endsWith("/")&&t.startsWith("/")?t.slice(1):t)),o=this.defaultQuery(),d=Object.fromEntries(s.searchParams);return(!aa(o)||!aa(d))&&(n={...d,...o,...n}),typeof n=="object"&&n&&!Array.isArray(n)&&(s.search=this.stringifyQuery(n)),s.toString()}async prepareOptions(t){}async prepareRequest(t,{url:n,options:a}){}get(t,n){return this.methodRequest("get",t,n)}post(t,n){return this.methodRequest("post",t,n)}patch(t,n){return this.methodRequest("patch",t,n)}put(t,n){return this.methodRequest("put",t,n)}delete(t,n){return this.methodRequest("delete",t,n)}methodRequest(t,n,a){return this.request(Promise.resolve(a).then(i=>({method:t,path:n,...i})))}request(t,n=null){return new Ht(this,this.makeRequest(t,n,void 0))}async makeRequest(t,n,a){let i=await t,s=i.maxRetries??this.maxRetries;n==null&&(n=s),await this.prepareOptions(i);let{req:o,url:d,timeout:l}=await this.buildRequest(i,{retryCount:s-n});await this.prepareRequest(o,{url:d,options:i});let U="log_"+(Math.random()*(1<<24)|0).toString(16).padStart(6,"0"),S=a===void 0?"":`, retryOf: ${a}`,r=Date.now();if(z(this).debug(`[${U}] sending request`,kt({retryOfRequestLogID:a,method:i.method,url:d,options:i,headers:o.headers})),i.signal?.aborted)throw new st;let u=new AbortController,c=await this.fetchWithTimeout(d,o,l,u).catch(De),h=Date.now();if(c instanceof globalThis.Error){let f=`retrying, ${n} attempts remaining`;if(i.signal?.aborted)throw new st;let M=Be(c)||/timed? ?out/i.test(String(c)+("cause"in c?String(c.cause):""));if(n)return z(this).info(`[${U}] connection ${M?"timed out":"failed"} - ${f}`),z(this).debug(`[${U}] connection ${M?"timed out":"failed"} (${f})`,kt({retryOfRequestLogID:a,url:d,durationMs:h-r,message:c.message})),this.retryRequest(i,n,a??U);throw z(this).info(`[${U}] connection ${M?"timed out":"failed"} - error; no more retries left`),z(this).debug(`[${U}] connection ${M?"timed out":"failed"} (error; no more retries left)`,kt({retryOfRequestLogID:a,url:d,durationMs:h-r,message:c.message})),M?new Tt:new bt({cause:c})}let m=`[${U}${S}] ${o.method} ${d} ${c.ok?"succeeded":"failed"} with status ${c.status} in ${h-r}ms`;if(!c.ok){let f=await this.shouldRetry(c);if(n&&f){let b=`retrying, ${n} attempts remaining`;return await fi(c.body),z(this).info(`${m} - ${b}`),z(this).debug(`[${U}] response error (${b})`,kt({retryOfRequestLogID:a,url:c.url,status:c.status,headers:c.headers,durationMs:h-r})),this.retryRequest(i,n,a??U,c.headers)}let M=f?"error; no more retries left":"error; not retryable";z(this).info(`${m} - ${M}`);let y=await c.text().catch(b=>De(b).message),A=pi(y),O=A?void 0:y;throw z(this).debug(`[${U}] response error (${M})`,kt({retryOfRequestLogID:a,url:c.url,status:c.status,headers:c.headers,message:O,durationMs:Date.now()-r})),this.makeStatusError(c.status,A,O,c.headers)}return z(this).info(m),z(this).debug(`[${U}] response start`,kt({retryOfRequestLogID:a,url:c.url,status:c.status,headers:c.headers,durationMs:h-r})),{response:c,options:i,controller:u,requestLogID:U,retryOfRequestLogID:a,startTime:r}}getAPIList(t,n,a){return this.requestAPIList(n,a&&"then"in a?a.then(i=>({method:"get",path:t,...i})):{method:"get",path:t,...a})}requestAPIList(t,n){let a=this.makeRequest(n,null,void 0);return new Ke(this,a,t)}async fetchWithTimeout(t,n,a,i){let{signal:s,method:o,...d}=n||{},l=this._makeAbort(i);s&&s.addEventListener("abort",l,{once:!0});let U=setTimeout(l,a),S=globalThis.ReadableStream&&d.body instanceof globalThis.ReadableStream||typeof d.body=="object"&&d.body!==null&&Symbol.asyncIterator in d.body,r={signal:i.signal,...S?{duplex:"half"}:{},method:"GET",...d};o&&(r.method=o.toUpperCase());try{return await this.fetch.call(void 0,t,r)}finally{clearTimeout(U)}}async shouldRetry(t){let n=t.headers.get("x-should-retry");return n==="true"?!0:n==="false"?!1:t.status===408||t.status===409||t.status===429||t.status>=500}async retryRequest(t,n,a,i){let s,o=i?.get("retry-after-ms");if(o){let l=parseFloat(o);Number.isNaN(l)||(s=l)}let d=i?.get("retry-after");if(d&&!s){let l=parseFloat(d);Number.isNaN(l)?s=Date.parse(d)-Date.now():s=l*1e3}if(s===void 0){let l=t.maxRetries??this.maxRetries;s=this.calculateDefaultRetryTimeoutMillis(n,l)}return await wi(s),this.makeRequest(t,n-1,a)}calculateDefaultRetryTimeoutMillis(t,n){let s=n-t,o=Math.min(.5*Math.pow(2,s),8),d=1-Math.random()*.25;return o*d*1e3}async buildRequest(t,{retryCount:n=0}={}){let a={...t},{method:i,path:s,query:o,defaultBaseURL:d}=a,l=this.buildURL(s,o,d);"timeout"in a&&hi("timeout",a.timeout),a.timeout=a.timeout??this.timeout;let{bodyHeaders:U,body:S}=this.buildBody({options:a}),r=await this.buildHeaders({options:t,method:i,bodyHeaders:U,retryCount:n});return{req:{method:i,headers:r,...a.signal&&{signal:a.signal},...globalThis.ReadableStream&&S instanceof globalThis.ReadableStream&&{duplex:"half"},...S&&{body:S},...this.fetchOptions??{},...a.fetchOptions??{}},url:l,timeout:a.timeout}}async buildHeaders({options:t,method:n,bodyHeaders:a,retryCount:i}){let s={};this.idempotencyHeader&&n!=="get"&&(t.idempotencyKey||(t.idempotencyKey=this.defaultIdempotencyKey()),s[this.idempotencyHeader]=t.idempotencyKey);let o=T([s,{Accept:"application/json","User-Agent":this.getUserAgent(),"X-Stainless-Retry-Count":String(i),...t.timeout?{"X-Stainless-Timeout":String(Math.trunc(t.timeout/1e3))}:{},...Ti(),"X-\u004b\u0065\u0072\u006e\u0065\u006c-Project-Id":this.projectID,"X-\u004b\u0065\u0072\u006e\u0065\u006c-Project":this.project},await this.authHeaders(t),this._options.defaultHeaders,a,t.headers]);return this.validateHeaders(o),o.values}_makeAbort(t){return()=>t.abort()}buildBody({options:t}){let{body:n,headers:a}=t;if(!n)return n==null&&"body"in t?K(this,Xe,"f").call(this,{body:n,headers:T([a])}):{bodyHeaders:void 0,body:void 0};let i=T([a]);return ArrayBuffer.isView(n)||n instanceof ArrayBuffer||n instanceof DataView||typeof n=="string"&&i.values.has("content-type")||globalThis.Blob&&n instanceof globalThis.Blob||n instanceof FormData||n instanceof URLSearchParams||globalThis.ReadableStream&&n instanceof globalThis.ReadableStream?{bodyHeaders:void 0,body:n}:typeof n=="object"&&(Symbol.asyncIterator in n||Symbol.iterator in n&&"next"in n&&typeof n.next=="function")?{bodyHeaders:void 0,body:cn(n)}:typeof n=="object"&&i.values.get("content-type")==="application/x-www-form-urlencoded"?{bodyHeaders:{"content-type":"application/x-www-form-urlencoded"},body:this.stringifyQuery(n)}:K(this,Xe,"f").call(this,{body:n,headers:i})}app(t){return new Nn(t)}};Na=H,Xe=new WeakMap,Ma=new WeakSet,zi=function(){return this.baseURL!==$i[this._options.environment||"production"]};H.\u004b\u0065\u0072\u006e\u0065\u006c=Na;H.DEFAULT_TIMEOUT=6e4;H.\u004b\u0065\u0072\u006e\u0065\u006cError=V;H.APIError=et;H.APIConnectionError=bt;H.APIConnectionTimeoutError=Tt;H.APIUserAbortError=st;H.NotFoundError=le;H.ConflictError=Se;H.RateLimitError=ue;H.BadRequestError=oe;H.AuthenticationError=re;H.InternalServerError=ce;H.PermissionDeniedError=de;H.UnprocessableEntityError=Ue;H.toFile=fn;H.Deployments=Kt;H.Apps=Dt;H.Invocations=qt;H.Browsers=dt;H.Profiles=Xt;H.Auth=Mt;H.Telemetry=It;H.Proxies=jt;H.Extensions=Jt;H.BrowserPools=Ft;H.Credentials=Yt;H.Projects=Pt;H.Organization=Nt;H.AuditLogs=Et;H.APIKeys=Bt;H.CredentialProviders=Vt;var Y={container:".eJH8qe.adDDi",dataInitq:"[data-initq]",item:".related-question-pair",itemDataQ:"data-q",itemDataInitQ:"data-initq",itemQuestionEl:".JlqpRe",answerContainer:".bCOlv, .hgKElc, .wDYxhc, .LGOjhe, .fo7IQd, .fmW3u",aiAnswerBody:".pWvJNd",aiCitation:"a.PMDqCb[href]",aiSourceCard:"a.vIWmYe[href], a.Zbfntb[href]",sourceTitle:"h3",sourceSite:".VuuXrf",sourceCite:"cite",clickTarget:".JlqpRe",expandedClass:"aoRk1c",captchaMarker:'#captcha-form, #recaptcha, form[action*="/sorry/"], .g-recaptcha, [data-sitekey]'},Qi={container:'div[jscontroller="HWk0Gf"]',sectionHeading:'.mgAbYb[role="heading"]',item:"a.rIRoqf"},vn={udm:"39",item:"a.rIRoqf",durationPattern:/^\d+:\d+$/,platforms:["YouTube","TikTok","Instagram","Facebook","X"]},Zi={section:".ULSxyf",item:"a.KYg7td.INpicf",title:".hyYc0c",source:".K4ETW"},ts={sectionTag:"g-section-with-header",sectionHeadingText:"What people are saying",card:'.dRzkFf[role="listitem"]',cardLink:'a.WlydOe[jsname="YKoRaf"]',titleH1:"h1.WQWxe",titleDiv:".eAaXgc",popularCommentLabel:".qgdis",source:".sTl1Td",platformBadge:".appd0, .KrMNbf",ytChannel:".sjVJQd",ytDate:".PLq9Je",authorNote:".nDgy9d"},es={root:"[data-lhcontainer][data-streaming-container][eid]",legacyRoot:'[data-hveid="CBMQAA"]',wrapper:".Fgyi2e",controller:'[jscontroller="AkrxPe"]',contentSubtree:'[data-subtree="mfc"]',header:".heWuVc",heading:".Fzsovc.cwYVJe.RJPOee",showMoreButton:'[aria-label="Show more AI Overview"]',sourcesPanel:".OZ9ddf.WAUd4",disclaimer:".DuQANe.MSJHRb"},ns={root:'[data-hveid="CAUQAA"]',wrapper:".Fgyi2e",citations:'.Fgyi2e [data-hveid] a[jsname="pxBnId"]'},as={result:".wHYlTd.tF2Cxc",title:"h3.LC20lb",siteName:".VuuXrf",cite:"cite.tjvcx",snippet:".VwiC3b",redditCite:"cite.qLRx3b",ratingWrap:".Y0A0hc",ratingValue:".yi40Hd",reviewCount:".RDApEe"},is={headingText:"Businesses",card:".w7Dbne",name:".OSrXXb",ratingValue:".yi40Hd",reviewCount:".RDApEe"},ss="2026-05-07";var os="Google returned a CAPTCHA. Run with --headless=false to re-warm the browser profile, then retry.";var od=["request_aborted","captcha_exhausted","captcha_or_blocked","location_mismatch","proxy_tunnel_failed","proxy_unavailable","harvest_timeout","mcp_request_timeout","mcp_http_error","extraction_failed","concurrency_limit_exceeded","unauthorized","forbidden","invalid_request","rate_limited","upstream_rate_limited","insufficient_balance","service_unavailable","response_lost","vendor_unavailable","page_not_found","page_forbidden","page_rate_limited","page_server_error","page_http_error","bot_check_unresolved","page_too_large","page_unreachable","browser_session_interrupted","site_export_not_found","site_export_format_unavailable","site_export_read_failed","site_export_image_not_found","image_url_invalid","image_url_not_https","image_host_unresolvable","image_host_blocked","image_redirect_invalid","image_source_unavailable","image_too_large","image_redirect_limit","image_base64_invalid","image_source_missing","image_source_ambiguous","image_source_type_invalid","image_artifact_not_found","image_page_too_large","page_image_not_found","page_image_candidates_unusable","image_format_unsupported","image_storage_unconfigured","featured_image_unhostable"],rd=["request_aborted","captcha","location_mismatch","connection","timeout","extraction","concurrency_limit","unauthorized","forbidden","invalid_request","rate_limit","billing","service_unavailable"];var Qh=new Set(od),Zh=new Set(rd);function rs(e){return e.replace((new RegExp("https?:\\/\\/[^\\s]*(?:\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061|on\u006b\u0065\u0072\u006e\u0065\u006c|\u006b\u0065\u0072\u006e\u0065\u006c\\.sh)[^\\s]*", "gi")),"the service").replace(/bright\s*data/gi,"the service").replace((new RegExp("\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061", "gi")),"the service").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\.sh\\s+sessions?", "gi")),"sessions").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\.sh\\s+session", "gi")),"this session").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\.sh", "gi")),"the service").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\s+sessions?", "gi")),"sessions").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\s+session", "gi")),"this session").replace(/\b(?:sub|cus|sess|proxy)_[A-Za-z0-9_-]+\b/g,"[redacted]").replace((new RegExp("\\b(?:\u004b\u0045\u0052\u004e\u0045\u004c|\u0042\u0052\u0049\u0047\u0048\u0054\u0044\u0041\u0054\u0041|\u0042\u0052\u0049\u0047\u0048\u0054_\u0044\u0041\u0054\u0041)_[A-Z0-9_]*API_KEY\\b", "g")),"BROWSER_SERVICE_API_KEY").replace((new RegExp("\\b\u006b\u0065\u0072\u006e\u0065\u006c\\b", "gi")),"the service").replace(/ +/g," ").trim()}var at=class extends Error{constructor(n){super(`CAPTCHA detected. ${n}`);this.instructions=n}instructions;name="CaptchaError"},Pe=class extends Error{constructor(n,a){super(n);this.cause=a}cause;name="ExtractionError"};var gt=class extends Error{name="RequestAbortedError";constructor(t="Request aborted before harvest completed"){super(t)}},zt=class extends Error{name="PaaInteractionInterruptedError"},je=class extends Error{name="LocationMismatchError";constructor(t="Google returned results for a different location than requested"){super(t)}};async function bn(e,t,n,a){let i,s=!1,o,d=()=>{},l=()=>a?.reason instanceof DOMException&&a.reason.name==="TimeoutError"?a.reason:new gt,U=()=>d(l()),S=new Promise((u,c)=>{d=c}),r=async u=>{let c;try{await Promise.race([u.close().catch(()=>{}),new Promise(h=>{c=setTimeout(h,2e3)})])}finally{c&&clearTimeout(c)}};if(a?.aborted)throw l();a?.addEventListener("abort",U,{once:!0}),o=setTimeout(()=>d(new DOMException("Optional pagination timed out","TimeoutError")),3e4);try{return await Promise.race([(async()=>{let u=await e.newPage();if(s)throw await r(u),new gt;if(i=u,await t(u),s)throw new gt;return n(u)})(),S])}finally{s=!0,o&&clearTimeout(o),a?.removeEventListener("abort",U),i&&await r(i)}}var Ea=require("crypto");var ds=require("@libsql/client/http"),ze=require("crypto"),Q=require("zod");var vt="strftime('%Y-%m-%dT%H:%M:%fZ','now')";var dd=[`CREATE TABLE IF NOT EXISTS oauth_store_metadata (
|
|
9
|
+
${r}`)}return o},g=cr(Yi);var Bt=class extends b{create(t,n){return this._client.post("/org/api_keys",{body:t,...n})}retrieve(t,n={},a){return this._client.get(g`/org/api_keys/${t}`,{query:n,...a})}update(t,n,a){return this._client.patch(g`/org/api_keys/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/org/api_keys",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/org/api_keys/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}rotate(t,n={},a){return this._client.post(g`/org/api_keys/${t}/rotate`,{body:n,...a})}};var Dt=class extends b{list(t={},n){return this._client.getAPIList("/apps",D,{query:t,...n})}};var ge=class extends b{create(t,n){return this._client.post("/audit-logs/export/destinations",{body:t,...n})}retrieve(t,n){return this._client.get(g`/audit-logs/export/destinations/${t}`,n)}update(t,n,a){return this._client.patch(g`/audit-logs/export/destinations/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/audit-logs/export/destinations",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/audit-logs/export/destinations/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}test(t,n){return this._client.post(g`/audit-logs/export/destinations/${t}/test`,n)}};var gr=6,pr=5e4,wr=8e3,ht=class extends V{};async function Ji(e,t,n,a,i={}){if(!n||typeof n.write!="function")throw new TypeError("audit log download destination must provide write()");let{onProgress:s,maxTransferRetries:o=gr,...d}=i;if(!Number.isInteger(o)||o<0)throw new TypeError("maxTransferRetries must be a non-negative integer");let l=d.timeout??a,U,S={bytesWritten:0,chunks:0,rows:0},r=new Set;for(;;){let u=await mr(e,U?{...t,cursor:U}:t,d,o,l),{nextCursor:c,hasMore:h,rows:m}=yr(u.headers,U);if(h&&c){if(r.has(c))throw new ht("response repeated X-Next-Cursor header");r.add(c)}if(await kr(n,u.body),U=c,S.bytesWritten+=u.body.byteLength,S.chunks+=1,S.rows+=m,s&&await s({...S,chunkRows:m}),!h)return S}}async function mr(e,t,n,a,i){for(let s=0;;s+=1){let o=new AbortController,d=()=>o.abort();n.signal?.aborted?o.abort():n.signal?.addEventListener("abort",d,{once:!0});let l;try{l=await e(t,{...n,signal:o.signal})}catch(r){throw n.signal?.removeEventListener("abort",d),r}let U=!1,S=setTimeout(()=>{U=!0,o.abort()},i);try{let r=new Uint8Array(await l.arrayBuffer());if(clearTimeout(S),n.signal?.aborted)throw new st;if(U)throw new Tt;let u=l.headers.get("x-content-sha256");if(!u)throw new ht("response missing X-Content-Sha256 header");let c=await Cr(r);if(n.signal?.aborted)throw new st;if(c!==u)throw new ht(`audit log chunk checksum mismatch (got ${c}, want ${u})`);return{body:r,headers:l.headers}}catch(r){if(n.signal?.aborted&&!(r instanceof st)?r=new st:U&&(r=new Tt),s===a||r instanceof st)throw r;await Tr(s+1,n.signal)}finally{clearTimeout(S),n.signal?.removeEventListener("abort",d)}}}function yr(e,t){let n=e.get("x-has-more");if(n!=="true"&&n!=="false")throw new ht("response missing or invalid X-Has-More header");let a=n==="true",i=e.get("x-row-count");if(i===null||!/^[0-9]+$/.test(i))throw new ht("response missing or invalid X-Row-Count header");let s=Number(i);if(!Number.isSafeInteger(s)||s>pr)throw new ht("response missing or invalid X-Row-Count header");let o=e.get("x-next-cursor")||void 0;if(a&&(!o||o===t))throw new ht("response has invalid X-Next-Cursor header");if(!a&&o)throw new ht("response returned a cursor after the final chunk");return{rows:s,nextCursor:o,hasMore:a}}async function Cr(e){let t=await globalThis.crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(t),n=>n.toString(16).padStart(2,"0")).join("")}async function Tr(e,t){let n=Math.min(1e3*2**(e-1),wr);await new Promise((a,i)=>{if(t?.aborted){i(new st);return}let s=()=>{clearTimeout(o),i(new st)},o=setTimeout(()=>{t?.removeEventListener("abort",s),a()},n);t?.addEventListener("abort",s,{once:!0})})}async function kr(e,t){let n=0;for(;n<t.byteLength;){let a=await e.write(n===0?t:t.subarray(n));if(typeof a=="number"){n+=Ki(a,t.byteLength-n);continue}if(a&&typeof a=="object"&&"bytesWritten"in a){let i=a.bytesWritten;n+=Ki(i,t.byteLength-n);continue}return}}function Ki(e,t){if(!Number.isSafeInteger(e)||e<=0||e>t)throw new ht("audit log download destination performed a short write");return e}var Et=class extends b{constructor(){super(...arguments),this.exportDestinations=new ge(this._client)}list(t,n){return this._client.getAPIList("/audit-logs",Tn,{query:t,...n})}exportChunk(t,n){return this._client.get("/audit-logs/export/chunk",{query:t,...n,headers:T([{Accept:"application/octet-stream"},n?.headers]),__binaryResponse:!0})}download(t,n,a){return Ji((i,s)=>this.exportChunk(i,s),t,n,this._client.timeout,a)}};Et.ExportDestinations=ge;var pe=class extends b{create(t,n){return this._client.post("/auth/connections",{body:t,...n})}retrieve(t,n){return this._client.get(g`/auth/connections/${t}`,n)}update(t,n,a){return this._client.patch(g`/auth/connections/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/auth/connections",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/auth/connections/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}follow(t,n){return this._client.get(g`/auth/connections/${t}/events`,{...n,headers:T([{Accept:"text/event-stream"},n?.headers]),stream:!0})}login(t,n={},a){return this._client.post(g`/auth/connections/${t}/login`,{body:n,...a})}submit(t,n,a){return this._client.post(g`/auth/connections/${t}/submit`,{body:n,...a})}timeline(t,n={},a){return this._client.getAPIList(g`/auth/connections/${t}/timeline`,D,{query:n,...a})}};var we=class extends b{retrieve(t){return this._client.get("/auth/context",t)}};var Mt=class extends b{constructor(){super(...arguments),this.context=new we(this._client),this.connections=new pe(this._client)}};Mt.Context=we;Mt.Connections=pe;var Ft=class extends b{create(t,n){return this._client.post("/browser_pools",{body:t,...n})}retrieve(t,n){return this._client.get(g`/browser_pools/${t}`,n)}update(t,n,a){return this._client.patch(g`/browser_pools/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/browser_pools",D,{query:t,...n})}delete(t,n={},a){return this._client.delete(g`/browser_pools/${t}`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}acquire(t,n,a){return this._client.post(g`/browser_pools/${t}/acquire`,{body:n,...a})}flush(t,n){return this._client.post(g`/browser_pools/${t}/flush`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}release(t,n,a){return this._client.post(g`/browser_pools/${t}/release`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}};var me=class extends b{batch(t,n,a){return this._client.post(g`/browsers/${t}/computer/batch`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}captureScreenshot(t,n={},a){return this._client.post(g`/browsers/${t}/computer/screenshot`,{body:n,...a,headers:T([{Accept:"image/png"},a?.headers]),__binaryResponse:!0})}clickMouse(t,n,a){return this._client.post(g`/browsers/${t}/computer/click_mouse`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}dragMouse(t,n,a){return this._client.post(g`/browsers/${t}/computer/drag_mouse`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}getMousePosition(t,n){return this._client.post(g`/browsers/${t}/computer/get_mouse_position`,n)}moveMouse(t,n,a){return this._client.post(g`/browsers/${t}/computer/move_mouse`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}pressKey(t,n,a){return this._client.post(g`/browsers/${t}/computer/press_key`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}readClipboard(t,n){return this._client.post(g`/browsers/${t}/computer/clipboard/read`,n)}scroll(t,n,a){return this._client.post(g`/browsers/${t}/computer/scroll`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}setCursorVisibility(t,n,a){return this._client.post(g`/browsers/${t}/computer/cursor`,{body:n,...a})}typeText(t,n,a){return this._client.post(g`/browsers/${t}/computer/type`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}writeClipboard(t,n,a){return this._client.post(g`/browsers/${t}/computer/clipboard/write`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}};var ye=class extends b{stream(t,n,a){return this._client.get(g`/browsers/${t}/logs/stream`,{query:n,...a,headers:T([{Accept:"text/event-stream"},a?.headers]),stream:!0})}};var Ce=class extends b{execute(t,n,a){return this._client.post(g`/browsers/${t}/playwright/execute`,{body:n,...a})}};var Te=class extends b{exec(t,n,a){return this._client.post(g`/browsers/${t}/process/exec`,{body:n,...a})}kill(t,n,a){let{id:i,...s}=n;return this._client.post(g`/browsers/${i}/process/${t}/kill`,{body:s,...a})}resize(t,n,a){let{id:i,...s}=n;return this._client.post(g`/browsers/${i}/process/${t}/resize`,{body:s,...a})}spawn(t,n,a){return this._client.post(g`/browsers/${t}/process/spawn`,{body:n,...a})}status(t,n,a){let{id:i}=n;return this._client.get(g`/browsers/${i}/process/${t}/status`,a)}stdin(t,n,a){let{id:i,...s}=n;return this._client.post(g`/browsers/${i}/process/${t}/stdin`,{body:s,...a})}stdoutStream(t,n,a){let{id:i}=n;return this._client.get(g`/browsers/${i}/process/${t}/stdout/stream`,{...a,headers:T([{Accept:"text/event-stream"},a?.headers]),stream:!0})}};var ke=class extends b{list(t,n){return this._client.get(g`/browsers/${t}/replays`,n)}download(t,n,a){let{id:i}=n;return this._client.get(g`/browsers/${i}/replays/${t}`,{...a,headers:T([{Accept:"video/mp4"},a?.headers]),__binaryResponse:!0})}start(t,n={},a){return this._client.post(g`/browsers/${t}/replays`,{body:n,...a})}stop(t,n,a){let{id:i}=n;return this._client.post(g`/browsers/${i}/replays/${t}/stop`,{...a,headers:T([{Accept:"*/*"},a?.headers])})}};var fe=class extends b{events(t,n={},a){return this._client.getAPIList(g`/browsers/${t}/telemetry/events`,D,{query:n,...a})}stream(t,n={},a){let{"Last-Event-ID":i,...s}=n??{};return this._client.get(g`/browsers/${t}/telemetry/stream`,{query:s,...a,headers:T([{Accept:"text/event-stream",...i!=null?{"Last-Event-ID":i}:void 0},a?.headers]),stream:!0})}};var Me=class extends b{events(t,n,a){let{id:i}=n;return this._client.get(g`/browsers/${i}/fs/watch/${t}/events`,{...a,headers:T([{Accept:"text/event-stream"},a?.headers]),stream:!0})}start(t,n,a){return this._client.post(g`/browsers/${t}/fs/watch`,{body:n,...a})}stop(t,n,a){let{id:i}=n;return this._client.delete(g`/browsers/${i}/fs/watch/${t}`,{...a,headers:T([{Accept:"*/*"},a?.headers])})}};var Gt=class extends b{constructor(){super(...arguments),this.watch=new Me(this._client)}createDirectory(t,n,a){return this._client.put(g`/browsers/${t}/fs/create_directory`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}deleteDirectory(t,n,a){return this._client.put(g`/browsers/${t}/fs/delete_directory`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}deleteFile(t,n,a){return this._client.put(g`/browsers/${t}/fs/delete_file`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}downloadDirZip(t,n,a){return this._client.get(g`/browsers/${t}/fs/download_dir_zip`,{query:n,...a,headers:T([{Accept:"application/zip"},a?.headers]),__binaryResponse:!0})}fileInfo(t,n,a){return this._client.get(g`/browsers/${t}/fs/file_info`,{query:n,...a})}listFiles(t,n,a){return this._client.get(g`/browsers/${t}/fs/list_files`,{query:n,...a})}move(t,n,a){return this._client.put(g`/browsers/${t}/fs/move`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}readFile(t,n,a){return this._client.get(g`/browsers/${t}/fs/read_file`,{query:n,...a,headers:T([{Accept:"application/octet-stream"},a?.headers]),__binaryResponse:!0})}setFilePermissions(t,n,a){return this._client.put(g`/browsers/${t}/fs/set_file_permissions`,{body:n,...a,headers:T([{Accept:"*/*"},a?.headers])})}upload(t,n,a){return this._client.post(g`/browsers/${t}/fs/upload`,ft({body:n,...a,headers:T([{Accept:"*/*"},a?.headers])},this._client))}uploadZip(t,n,a){return this._client.post(g`/browsers/${t}/fs/upload_zip`,ft({body:n,...a,headers:T([{Accept:"*/*"},a?.headers])},this._client))}writeFile(t,n,a,i){let{path:s,mode:o}=a;return this._client.put(g`/browsers/${t}/fs/write_file`,{body:n,query:{path:s,mode:o},...i,headers:T([{"Content-Type":"application/octet-stream",Accept:"*/*"},i?.headers])})}};Gt.Watch=Me;function Mn(e,t){return`${e.replace(/\/+$/,"")}${t.startsWith("/")?t:`/${t}`}`}async function qi(e,t,n,a){let i=e.browserRouteCache.get(t);if(!i)throw new V(`browser route cache does not contain session ${t}; create, retrieve, or list the browser before calling browser.fetch`);let{url:s,method:o,headers:d,body:l,signal:U,duplex:S,timeout_ms:r}=xr(n,a);Or(s);let u={url:s,jwt:i.jwt};r!==void 0&&(u.timeout_ms=r);let c=d.get("accept"),h={method:Lr(o),path:Mn(i.baseURL,"/curl/raw"),query:u,body:l,headers:T([{Authorization:null},c?{Accept:c}:{Accept:"*/*"},Rr(d)]),signal:U??null,__binaryResponse:!0};return S&&(h.fetchOptions={duplex:S}),e.request(h).asResponse()}function Lr(e){let t=e.toLowerCase();if(!new Set(["get","post","put","patch","delete"]).has(t))throw new V(`browser.fetch unsupported HTTP method: ${e}`);return t}function xr(e,t){let n=t&&"timeout_ms"in t?t.timeout_ms:void 0;if(e instanceof Request){let i=new Headers(e.headers);t?.headers&&new Headers(t.headers).forEach((U,S)=>{i.set(S,U)});let s={url:e.url,method:(t?.method??e.method)?.toUpperCase()||"GET",headers:i},o=t?.body??e.body;o!=null&&(s.body=o);let d=t?.signal??e.signal;return d!==void 0&&(s.signal=d),t?.duplex!==void 0&&(s.duplex=t.duplex),n!==void 0&&(s.timeout_ms=n),s}let a={url:e instanceof URL?e.href:String(e),method:(t?.method??"GET").toUpperCase(),headers:new Headers(t?.headers)};return t?.body!==void 0&&(a.body=t.body),t?.signal!==void 0&&(a.signal=t.signal),t?.duplex!==void 0&&(a.duplex=t.duplex),n!==void 0&&(a.timeout_ms=n),a}function Or(e){let t;try{t=new URL(e)}catch{throw new V(`browser.fetch target must be an absolute URL; received: ${e}`)}if(t.protocol!=="http:"&&t.protocol!=="https:")throw new V(`browser.fetch only supports http(s) URLs; received: ${t.protocol}`)}function Rr(e){let t={};return e.forEach((n,a)=>{switch(a.toLowerCase()){case"accept":case"content-length":case"connection":case"keep-alive":case"proxy-authenticate":case"proxy-authorization":case"te":case"trailers":case"transfer-encoding":case"upgrade":return;default:t[a]=n}}),t}var dt=class extends b{constructor(){super(...arguments),this.telemetry=new fe(this._client),this.replays=new ke(this._client),this.fs=new Gt(this._client),this.process=new Te(this._client),this.logs=new ye(this._client),this.computer=new me(this._client),this.playwright=new Ce(this._client)}create(t={},n){return this._client.post("/browsers",{body:t,...n})}retrieve(t,n={},a){return this._client.get(g`/browsers/${t}`,{query:n,...a})}update(t,n,a){return this._client.patch(g`/browsers/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/browsers",D,{query:t,...n})}curl(t,n,a){return this._client.post(g`/browsers/${t}/curl`,{body:n,...a})}fetch(t,n,a){return qi(this._client,t,n,a)}deleteByID(t,n){return this._client.delete(g`/browsers/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}loadExtensions(t,n,a){return this._client.post(g`/browsers/${t}/extensions`,ft({body:n,...a,headers:T([{Accept:"*/*"},a?.headers])},this._client))}};dt.Telemetry=fe;dt.Replays=ke;dt.Fs=Gt;dt.Process=Te;dt.Logs=ye;dt.Computer=me;dt.Playwright=Ce;var Vt=class extends b{create(t,n){return this._client.post("/org/credential_providers",{body:t,...n})}retrieve(t,n){return this._client.get(g`/org/credential_providers/${t}`,n)}update(t,n,a){return this._client.patch(g`/org/credential_providers/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/org/credential_providers",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/org/credential_providers/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}listItems(t,n){return this._client.get(g`/org/credential_providers/${t}/items`,n)}test(t,n){return this._client.post(g`/org/credential_providers/${t}/test`,n)}};var Yt=class extends b{create(t,n){return this._client.post("/credentials",{body:t,...n})}retrieve(t,n){return this._client.get(g`/credentials/${t}`,n)}update(t,n,a){return this._client.patch(g`/credentials/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/credentials",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/credentials/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}totpCode(t,n){return this._client.get(g`/credentials/${t}/totp-code`,n)}};var Kt=class extends b{create(t,n){return this._client.post("/deployments",ft({body:t,...n},this._client))}retrieve(t,n){return this._client.get(g`/deployments/${t}`,n)}list(t={},n){return this._client.getAPIList("/deployments",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/deployments/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}follow(t,n={},a){return this._client.get(g`/deployments/${t}/events`,{query:n,...a,headers:T([{Accept:"text/event-stream"},a?.headers]),stream:!0})}};var Jt=class extends b{list(t={},n){return this._client.getAPIList("/extensions",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/extensions/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}download(t,n){return this._client.get(g`/extensions/${t}`,{...n,headers:T([{Accept:"application/octet-stream"},n?.headers]),__binaryResponse:!0})}downloadFromChromeStore(t,n){return this._client.get("/extensions/from_chrome_store",{query:t,...n,headers:T([{Accept:"application/octet-stream"},n?.headers]),__binaryResponse:!0})}get(t,n){return this._client.get(g`/extensions/${t}/metadata`,n)}upload(t,n){return this._client.post("/extensions",ft({body:t,...n},this._client))}};var qt=class extends b{create(t,n){return this._client.post("/invocations",{body:t,...n})}retrieve(t,n){return this._client.get(g`/invocations/${t}`,n)}update(t,n,a){return this._client.patch(g`/invocations/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/invocations",D,{query:t,...n})}deleteBrowsers(t,n){return this._client.delete(g`/invocations/${t}/browsers`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}follow(t,n={},a){return this._client.get(g`/invocations/${t}/events`,{query:n,...a,headers:T([{Accept:"text/event-stream"},a?.headers]),stream:!0})}listBrowsers(t,n){return this._client.get(g`/invocations/${t}/browsers`,n)}};var Ne=class extends b{retrieve(t){return this._client.get("/org/entitlements",t)}};var ve=class extends b{retrieve(t){return this._client.get("/org/limits",t)}update(t,n){return this._client.patch("/org/limits",{body:t,...n})}};var Nt=class extends b{constructor(){super(...arguments),this.entitlements=new Ne(this._client),this.limits=new ve(this._client)}};Nt.Entitlements=Ne;Nt.Limits=ve;var Xt=class extends b{create(t,n){return this._client.post("/profiles",{body:t,...n})}retrieve(t,n){return this._client.get(g`/profiles/${t}`,n)}update(t,n,a){return this._client.patch(g`/profiles/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/profiles",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/profiles/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}download(t,n={},a){return this._client.get(g`/profiles/${t}/download`,{query:n,...a,headers:T([{Accept:"application/octet-stream"},a?.headers]),__binaryResponse:!0})}};var _e=class extends b{retrieve(t,n){return this._client.get(g`/org/projects/${t}/limits`,n)}update(t,n,a){return this._client.patch(g`/org/projects/${t}/limits`,{body:n,...a})}};var Pt=class extends b{constructor(){super(...arguments),this.limits=new _e(this._client)}create(t,n){return this._client.post("/org/projects",{body:t,...n})}retrieve(t,n){return this._client.get(g`/org/projects/${t}`,n)}update(t,n,a){return this._client.patch(g`/org/projects/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/org/projects",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/org/projects/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}};Pt.Limits=_e;var jt=class extends b{create(t,n){return this._client.post("/proxies",{body:t,...n})}retrieve(t,n){return this._client.get(g`/proxies/${t}`,n)}update(t,n,a){return this._client.patch(g`/proxies/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/proxies",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/proxies/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}check(t,n={},a){return this._client.post(g`/proxies/${t}/check`,{body:n,...a})}};var be=class extends b{create(t,n){return this._client.post("/telemetry/destinations",{body:t,...n})}retrieve(t,n){return this._client.get(g`/telemetry/destinations/${t}`,n)}update(t,n,a){return this._client.patch(g`/telemetry/destinations/${t}`,{body:n,...a})}list(t={},n){return this._client.getAPIList("/telemetry/destinations",D,{query:t,...n})}delete(t,n){return this._client.delete(g`/telemetry/destinations/${t}`,{...n,headers:T([{Accept:"*/*"},n?.headers])})}};var It=class extends b{constructor(){super(...arguments),this.destinations=new be(this._client)}};It.Destinations=be;var qe=class{constructor(){this.entries=new Map}get(t){return this.entries.get(t)}set(t){this.entries.set(t.sessionId,t)}delete(t){this.entries.delete(t)}clear(){this.entries.clear()}},Xi="\u004b\u0045\u0052\u004e\u0045\u004c_BROWSER_ROUTING_SUBRESOURCES",Gr=["curl","telemetry/stream"],Vr=/^\/(?:v\d+\/)?browsers(?:\/[^/]+)?\/?$/,Yr=/^\/(?:v\d+\/)?browser_pools\/[^/]+\/acquire\/?$/,Kr=/^\/(?:v\d+\/)?browsers\/([^/]+)\/?$/,Jr=/^\/(?:v\d+\/)?browser_pools\/[^/]+\/release\/?$/;function Ta(){let e=sd();return e===void 0?[...Gr]:e.trim()===""?[]:e.split(",").map(t=>t.trim()).filter(Boolean)}function ka(e,{apiBaseURL:t,subresources:n,cache:a}){let i=[...n].map(o=>o.trim().replace(/^\/+|\/+$/g,"")).filter(Boolean),s=new URL(t).origin;return async(o,d)=>{let l=new Request(o,d),U=qr(l,s),S=await td(e,{input:o,init:d,request:l},s,i,a);return U&&await Qr(S,a),await Xr(l,S,s,a),S}}function qr(e,t){let n=new URL(e.url);return n.origin===t&&(Vr.test(n.pathname)||Yr.test(n.pathname))}async function Xr(e,t,n,a){if(!t.ok)return;let i=new URL(e.url);if(i.origin!==n)return;let s=jr(e,i.pathname)??await zr(e,i.pathname);s&&a.delete(s)}function jr(e,t){if(e.method.toUpperCase()!=="DELETE")return;let n=t.match(Kr);return n&&decodeURIComponent(n[1]??"")||void 0}async function zr(e,t){if(!(e.method.toUpperCase()!=="POST"||!Jr.test(t)))try{let n=await e.clone().json();if(!n||typeof n!="object")return;let a=n.session_id;return typeof a=="string"&&a.trim()?a.trim():void 0}catch{return}}function $r(e){if(!e||typeof e!="object")return;let t=e,n=typeof t.session_id=="string"?t.session_id.trim():"",a=typeof t.base_url=="string"?t.base_url.trim():"";if(!n||!a)return;let i=typeof t.jwt=="string"?t.jwt.trim():"",s=typeof t.cdp_ws_url=="string"?t.cdp_ws_url:void 0,o=i||id(s)||"";if(o)return{sessionId:n,baseURL:a,jwt:o}}async function Qr(e,t){if((e.headers.get("content-type")?.toLowerCase()??"").includes("application/json"))try{Ca(await e.clone().json(),t)}catch{}}function Ca(e,t){let n=$r(e);if(n&&t.set(n),Array.isArray(e)){for(let a of e)Ca(a,t);return}if(!(!e||typeof e!="object"))for(let a of Object.values(e))typeof a=="object"&&a!==null&&Ca(a,t)}function Zr(e,t){let n=e.replace(/^\/+|\/+$/g,"");return t.some(a=>n===a||n.startsWith(a+"/"))}async function td(e,{input:t,init:n,request:a},i,s,o){let d=new URL(a.url);if(d.origin!==i)return e(t,n);let l=d.pathname.match(/^\/(?:v\d+\/)?browsers\/([^/]+)\/([^/]+)(\/.*)?$/);if(!l)return e(t,n);let U=decodeURIComponent(l[1]??""),S=l[2]??"";if(!U||!Zr(S+(l[3]??""),s))return e(t,n);let r=o.get(U);if(r===void 0)return e(t,n);let u=new URL(Mn(r.baseURL,`/${S}${l[3]??""}`));d.searchParams.forEach((h,m)=>{m!=="jwt"&&u.searchParams.append(m,h)}),u.searchParams.get("jwt")||u.searchParams.set("jwt",r.jwt);let c=new Headers(a.headers);return c.delete("authorization"),e(u.toString(),ed(t,a,n,c))}function ed(e,t,n,a){let i=t.method.toUpperCase(),s={...n??{},method:i,headers:a,redirect:t.redirect,signal:n?.signal??(e instanceof Request?e.signal:void 0)};if(delete s.body,delete s.duplex,i!=="GET"&&i!=="HEAD"){let o=nd(t,n);o!==void 0&&(s.body=o),n?.duplex!==void 0?s.duplex=n.duplex:ad(o)&&(s.duplex="half")}return s}function nd(e,t){return t?.body!==void 0&&t.body!==null?t.body:e.body??void 0}function ad(e){return globalThis.ReadableStream&&e instanceof globalThis.ReadableStream||typeof e=="object"&&e!==null&&Symbol.asyncIterator in e}function id(e){if(e)try{return new URL(e).searchParams.get("jwt")??void 0}catch{return}}function sd(){if(typeof globalThis.process<"u"){let e=globalThis.process.env?.[Xi];return typeof e=="string"?e:void 0}if(typeof globalThis.Deno<"u"){let e=globalThis.Deno.env?.get?.(Xi);return typeof e=="string"?e:void 0}}var Nn=class{constructor(t){this.actions=new Map,this.name=t,ji.registerApp(this)}action(t,n){let a;if(n.length===0)throw new Error("Action handlers must accept at least the context parameter");if(n.length===1){let i=n;a=async(s,o)=>i(s)}else a=n;return this.actions.set(t,{name:t,handler:a}),a}getActions(){return Array.from(this.actions.values())}getAction(t){return this.actions.get(t)}toJSON(){return{name:this.name,actions:this.getActions().map(t=>({name:t.name}))}}},fa=class{constructor(){this.apps=new Map}registerApp(t){this.apps.set(t.name,t)}getApps(){return Array.from(this.apps.values())}getAppByName(t){return this.apps.get(t)}export(){return{apps:this.getApps().map(t=>t.toJSON())}}exportJSON(){return JSON.stringify(this.export(),null,2)}},ji=new fa;var Ee=e=>{if(typeof globalThis.process<"u")return globalThis.process.env?.[e]?.trim()||void 0;if(typeof globalThis.Deno<"u")return globalThis.Deno.env?.get?.(e)?.trim()||void 0};var Ma,Na,Xe,zi,$i={production:"https://api.on\u006b\u0065\u0072\u006e\u0065\u006c.com/",development:"https://localhost:3001/"},H=class{constructor({baseURL:t=Ee("\u004b\u0045\u0052\u004e\u0045\u004c_BASE_URL"),apiKey:n=Ee("\u004b\u0045\u0052\u004e\u0045\u004c_API_KEY"),projectID:a=null,project:i=null,...s}={}){if(Ma.add(this),Xe.set(this,void 0),this.deployments=new Kt(this),this.apps=new Dt(this),this.invocations=new qt(this),this.browsers=new dt(this),this.profiles=new Xt(this),this.auth=new Mt(this),this.telemetry=new It(this),this.proxies=new jt(this),this.extensions=new Jt(this),this.browserPools=new Ft(this),this.credentials=new Yt(this),this.projects=new Pt(this),this.organization=new Nt(this),this.auditLogs=new Et(this),this.apiKeys=new Bt(this),this.credentialProviders=new Vt(this),typeof globalThis<"u"&&typeof globalThis.Bun<"u"&&globalThis.Bun.version&&!Ee("\u004b\u0045\u0052\u004e\u0045\u004c_SUPPRESS_BUN_WARNING")&&z(this).warn("The Bun runtime was detected. Playwright may have CDP connection issues, proceed with caution. Suppress this warning by setting the \u004b\u0045\u0052\u004e\u0045\u004c_SUPPRESS_BUN_WARNING environment variable to true"),n===void 0)throw new V("The \u004b\u0045\u0052\u004e\u0045\u004c_API_KEY environment variable is missing or empty; either provide it, or instantiate the \u004b\u0065\u0072\u006e\u0065\u006c client with an apiKey option, like new \u004b\u0065\u0072\u006e\u0065\u006c({ apiKey: 'My API Key' }).");let o={apiKey:n,projectID:a,project:i,...s,baseURL:t,environment:s.environment??"production"};if(t&&s.environment)throw new V("Ambiguous URL; The `baseURL` option (or \u004b\u0045\u0052\u004e\u0045\u004c_BASE_URL env var) and the `environment` option are given. If you want to use the environment you must pass baseURL: null");this.baseURL=o.baseURL||$i[o.environment||"production"],this.timeout=o.timeout??Na.DEFAULT_TIMEOUT,this.logger=o.logger??console;let d="warn";this.logLevel=d,this.logLevel=ha(o.logLevel,"ClientOptions.logLevel",this)??ha(Ee("\u004b\u0045\u0052\u004e\u0045\u004c_LOG"),"process.env['\u004b\u0045\u0052\u004e\u0045\u004c_LOG']",this)??d,this.fetchOptions=o.fetchOptions,this.maxRetries=o.maxRetries??2,this.rawFetch=o.fetch??ki(),this.browserRouteCache=new qe,this.fetch=ka(this.rawFetch,{apiBaseURL:this.baseURL,subresources:Ta(),cache:this.browserRouteCache}),Z(this,Xe,Mi,"f");let l=Ee("\u004b\u0045\u0052\u004e\u0045\u004c_CUSTOM_HEADERS");if(l){let U={};for(let S of l.split(`
|
|
10
|
+
`)){let r=S.indexOf(":");r>=0&&(U[S.substring(0,r).trim()]=S.substring(r+1).trim())}o.defaultHeaders={...U,...o.defaultHeaders}}this._options=o,this.apiKey=n,this.projectID=a,this.project=i}withOptions(t){let n=new this.constructor({...this._options,environment:t.environment?t.environment:void 0,baseURL:t.environment?void 0:this.baseURL,maxRetries:this.maxRetries,timeout:this.timeout,logger:this.logger,logLevel:this.logLevel,fetch:this.rawFetch,fetchOptions:this.fetchOptions,apiKey:this.apiKey,projectID:this.projectID,project:this.project,...t});return n.browserRouteCache=this.browserRouteCache,n.fetch=ka(n.rawFetch,{apiBaseURL:n.baseURL,subresources:Ta(),cache:n.browserRouteCache}),n}defaultQuery(){return this._options.defaultQuery}validateHeaders({values:t,nulls:n}){}async authHeaders(t){return T([{Authorization:`Bearer ${this.apiKey}`}])}stringifyQuery(t){return Li(t)}getUserAgent(){return`${this.constructor.name}/JS ${bt}`}defaultIdempotencyKey(){return`stainless-node-retry-${ta()}`}makeStatusError(t,n,a,i){return et.generate(t,n,a,i)}buildURL(t,n,a){let i=!K(this,Ma,"m",zi).call(this)&&a||this.baseURL,s=ui(t)?new URL(t):new URL(i+(i.endsWith("/")&&t.startsWith("/")?t.slice(1):t)),o=this.defaultQuery(),d=Object.fromEntries(s.searchParams);return(!aa(o)||!aa(d))&&(n={...d,...o,...n}),typeof n=="object"&&n&&!Array.isArray(n)&&(s.search=this.stringifyQuery(n)),s.toString()}async prepareOptions(t){}async prepareRequest(t,{url:n,options:a}){}get(t,n){return this.methodRequest("get",t,n)}post(t,n){return this.methodRequest("post",t,n)}patch(t,n){return this.methodRequest("patch",t,n)}put(t,n){return this.methodRequest("put",t,n)}delete(t,n){return this.methodRequest("delete",t,n)}methodRequest(t,n,a){return this.request(Promise.resolve(a).then(i=>({method:t,path:n,...i})))}request(t,n=null){return new Ht(this,this.makeRequest(t,n,void 0))}async makeRequest(t,n,a){let i=await t,s=i.maxRetries??this.maxRetries;n==null&&(n=s),await this.prepareOptions(i);let{req:o,url:d,timeout:l}=await this.buildRequest(i,{retryCount:s-n});await this.prepareRequest(o,{url:d,options:i});let U="log_"+(Math.random()*(1<<24)|0).toString(16).padStart(6,"0"),S=a===void 0?"":`, retryOf: ${a}`,r=Date.now();if(z(this).debug(`[${U}] sending request`,kt({retryOfRequestLogID:a,method:i.method,url:d,options:i,headers:o.headers})),i.signal?.aborted)throw new st;let u=new AbortController,c=await this.fetchWithTimeout(d,o,l,u).catch(De),h=Date.now();if(c instanceof globalThis.Error){let f=`retrying, ${n} attempts remaining`;if(i.signal?.aborted)throw new st;let M=Be(c)||/timed? ?out/i.test(String(c)+("cause"in c?String(c.cause):""));if(n)return z(this).info(`[${U}] connection ${M?"timed out":"failed"} - ${f}`),z(this).debug(`[${U}] connection ${M?"timed out":"failed"} (${f})`,kt({retryOfRequestLogID:a,url:d,durationMs:h-r,message:c.message})),this.retryRequest(i,n,a??U);throw z(this).info(`[${U}] connection ${M?"timed out":"failed"} - error; no more retries left`),z(this).debug(`[${U}] connection ${M?"timed out":"failed"} (error; no more retries left)`,kt({retryOfRequestLogID:a,url:d,durationMs:h-r,message:c.message})),M?new Tt:new _t({cause:c})}let m=`[${U}${S}] ${o.method} ${d} ${c.ok?"succeeded":"failed"} with status ${c.status} in ${h-r}ms`;if(!c.ok){let f=await this.shouldRetry(c);if(n&&f){let _=`retrying, ${n} attempts remaining`;return await fi(c.body),z(this).info(`${m} - ${_}`),z(this).debug(`[${U}] response error (${_})`,kt({retryOfRequestLogID:a,url:c.url,status:c.status,headers:c.headers,durationMs:h-r})),this.retryRequest(i,n,a??U,c.headers)}let M=f?"error; no more retries left":"error; not retryable";z(this).info(`${m} - ${M}`);let y=await c.text().catch(_=>De(_).message),A=pi(y),O=A?void 0:y;throw z(this).debug(`[${U}] response error (${M})`,kt({retryOfRequestLogID:a,url:c.url,status:c.status,headers:c.headers,message:O,durationMs:Date.now()-r})),this.makeStatusError(c.status,A,O,c.headers)}return z(this).info(m),z(this).debug(`[${U}] response start`,kt({retryOfRequestLogID:a,url:c.url,status:c.status,headers:c.headers,durationMs:h-r})),{response:c,options:i,controller:u,requestLogID:U,retryOfRequestLogID:a,startTime:r}}getAPIList(t,n,a){return this.requestAPIList(n,a&&"then"in a?a.then(i=>({method:"get",path:t,...i})):{method:"get",path:t,...a})}requestAPIList(t,n){let a=this.makeRequest(n,null,void 0);return new Ke(this,a,t)}async fetchWithTimeout(t,n,a,i){let{signal:s,method:o,...d}=n||{},l=this._makeAbort(i);s&&s.addEventListener("abort",l,{once:!0});let U=setTimeout(l,a),S=globalThis.ReadableStream&&d.body instanceof globalThis.ReadableStream||typeof d.body=="object"&&d.body!==null&&Symbol.asyncIterator in d.body,r={signal:i.signal,...S?{duplex:"half"}:{},method:"GET",...d};o&&(r.method=o.toUpperCase());try{return await this.fetch.call(void 0,t,r)}finally{clearTimeout(U)}}async shouldRetry(t){let n=t.headers.get("x-should-retry");return n==="true"?!0:n==="false"?!1:t.status===408||t.status===409||t.status===429||t.status>=500}async retryRequest(t,n,a,i){let s,o=i?.get("retry-after-ms");if(o){let l=parseFloat(o);Number.isNaN(l)||(s=l)}let d=i?.get("retry-after");if(d&&!s){let l=parseFloat(d);Number.isNaN(l)?s=Date.parse(d)-Date.now():s=l*1e3}if(s===void 0){let l=t.maxRetries??this.maxRetries;s=this.calculateDefaultRetryTimeoutMillis(n,l)}return await wi(s),this.makeRequest(t,n-1,a)}calculateDefaultRetryTimeoutMillis(t,n){let s=n-t,o=Math.min(.5*Math.pow(2,s),8),d=1-Math.random()*.25;return o*d*1e3}async buildRequest(t,{retryCount:n=0}={}){let a={...t},{method:i,path:s,query:o,defaultBaseURL:d}=a,l=this.buildURL(s,o,d);"timeout"in a&&hi("timeout",a.timeout),a.timeout=a.timeout??this.timeout;let{bodyHeaders:U,body:S}=this.buildBody({options:a}),r=await this.buildHeaders({options:t,method:i,bodyHeaders:U,retryCount:n});return{req:{method:i,headers:r,...a.signal&&{signal:a.signal},...globalThis.ReadableStream&&S instanceof globalThis.ReadableStream&&{duplex:"half"},...S&&{body:S},...this.fetchOptions??{},...a.fetchOptions??{}},url:l,timeout:a.timeout}}async buildHeaders({options:t,method:n,bodyHeaders:a,retryCount:i}){let s={};this.idempotencyHeader&&n!=="get"&&(t.idempotencyKey||(t.idempotencyKey=this.defaultIdempotencyKey()),s[this.idempotencyHeader]=t.idempotencyKey);let o=T([s,{Accept:"application/json","User-Agent":this.getUserAgent(),"X-Stainless-Retry-Count":String(i),...t.timeout?{"X-Stainless-Timeout":String(Math.trunc(t.timeout/1e3))}:{},...Ti(),"X-\u004b\u0065\u0072\u006e\u0065\u006c-Project-Id":this.projectID,"X-\u004b\u0065\u0072\u006e\u0065\u006c-Project":this.project},await this.authHeaders(t),this._options.defaultHeaders,a,t.headers]);return this.validateHeaders(o),o.values}_makeAbort(t){return()=>t.abort()}buildBody({options:t}){let{body:n,headers:a}=t;if(!n)return n==null&&"body"in t?K(this,Xe,"f").call(this,{body:n,headers:T([a])}):{bodyHeaders:void 0,body:void 0};let i=T([a]);return ArrayBuffer.isView(n)||n instanceof ArrayBuffer||n instanceof DataView||typeof n=="string"&&i.values.has("content-type")||globalThis.Blob&&n instanceof globalThis.Blob||n instanceof FormData||n instanceof URLSearchParams||globalThis.ReadableStream&&n instanceof globalThis.ReadableStream?{bodyHeaders:void 0,body:n}:typeof n=="object"&&(Symbol.asyncIterator in n||Symbol.iterator in n&&"next"in n&&typeof n.next=="function")?{bodyHeaders:void 0,body:cn(n)}:typeof n=="object"&&i.values.get("content-type")==="application/x-www-form-urlencoded"?{bodyHeaders:{"content-type":"application/x-www-form-urlencoded"},body:this.stringifyQuery(n)}:K(this,Xe,"f").call(this,{body:n,headers:i})}app(t){return new Nn(t)}};Na=H,Xe=new WeakMap,Ma=new WeakSet,zi=function(){return this.baseURL!==$i[this._options.environment||"production"]};H.\u004b\u0065\u0072\u006e\u0065\u006c=Na;H.DEFAULT_TIMEOUT=6e4;H.\u004b\u0065\u0072\u006e\u0065\u006cError=V;H.APIError=et;H.APIConnectionError=_t;H.APIConnectionTimeoutError=Tt;H.APIUserAbortError=st;H.NotFoundError=le;H.ConflictError=Se;H.RateLimitError=ue;H.BadRequestError=oe;H.AuthenticationError=re;H.InternalServerError=ce;H.PermissionDeniedError=de;H.UnprocessableEntityError=Ue;H.toFile=fn;H.Deployments=Kt;H.Apps=Dt;H.Invocations=qt;H.Browsers=dt;H.Profiles=Xt;H.Auth=Mt;H.Telemetry=It;H.Proxies=jt;H.Extensions=Jt;H.BrowserPools=Ft;H.Credentials=Yt;H.Projects=Pt;H.Organization=Nt;H.AuditLogs=Et;H.APIKeys=Bt;H.CredentialProviders=Vt;var Y={container:".eJH8qe.adDDi",dataInitq:"[data-initq]",item:".related-question-pair",itemDataQ:"data-q",itemDataInitQ:"data-initq",itemQuestionEl:".JlqpRe",answerContainer:".bCOlv, .hgKElc, .wDYxhc, .LGOjhe, .fo7IQd, .fmW3u",aiAnswerBody:".pWvJNd",aiCitation:"a.PMDqCb[href]",aiSourceCard:"a.vIWmYe[href], a.Zbfntb[href]",sourceTitle:"h3",sourceSite:".VuuXrf",sourceCite:"cite",clickTarget:".JlqpRe",expandedClass:"aoRk1c",captchaMarker:'#captcha-form, #recaptcha, form[action*="/sorry/"], .g-recaptcha, [data-sitekey]'},Qi={container:'div[jscontroller="HWk0Gf"]',sectionHeading:'.mgAbYb[role="heading"]',item:"a.rIRoqf"},vn={udm:"39",item:"a.rIRoqf",durationPattern:/^\d+:\d+$/,platforms:["YouTube","TikTok","Instagram","Facebook","X"]},Zi={section:".ULSxyf",item:"a.KYg7td.INpicf",title:".hyYc0c",source:".K4ETW"},ts={sectionTag:"g-section-with-header",sectionHeadingText:"What people are saying",card:'.dRzkFf[role="listitem"]',cardLink:'a.WlydOe[jsname="YKoRaf"]',titleH1:"h1.WQWxe",titleDiv:".eAaXgc",popularCommentLabel:".qgdis",source:".sTl1Td",platformBadge:".appd0, .KrMNbf",ytChannel:".sjVJQd",ytDate:".PLq9Je",authorNote:".nDgy9d"},es={root:"[data-lhcontainer][data-streaming-container][eid]",legacyRoot:'[data-hveid="CBMQAA"]',wrapper:".Fgyi2e",controller:'[jscontroller="AkrxPe"]',contentSubtree:'[data-subtree="mfc"]',header:".heWuVc",heading:".Fzsovc.cwYVJe.RJPOee",showMoreButton:'[aria-label="Show more AI Overview"]',sourcesPanel:".OZ9ddf.WAUd4",disclaimer:".DuQANe.MSJHRb"},ns={root:'[data-hveid="CAUQAA"]',wrapper:".Fgyi2e",citations:'.Fgyi2e [data-hveid] a[jsname="pxBnId"]'},as={result:".wHYlTd.tF2Cxc",title:"h3.LC20lb",siteName:".VuuXrf",cite:"cite.tjvcx",snippet:".VwiC3b",redditCite:"cite.qLRx3b",ratingWrap:".Y0A0hc",ratingValue:".yi40Hd",reviewCount:".RDApEe"},is={headingText:"Businesses",card:".w7Dbne",name:".OSrXXb",ratingValue:".yi40Hd",reviewCount:".RDApEe"},ss="2026-05-07";var os="Google returned a CAPTCHA. Run with --headless=false to re-warm the browser profile, then retry.";var od=["request_aborted","captcha_exhausted","captcha_or_blocked","location_mismatch","proxy_tunnel_failed","proxy_unavailable","harvest_timeout","mcp_request_timeout","mcp_http_error","extraction_failed","concurrency_limit_exceeded","unauthorized","forbidden","invalid_request","rate_limited","upstream_rate_limited","insufficient_balance","service_unavailable","response_lost","vendor_unavailable","page_not_found","page_forbidden","page_rate_limited","page_server_error","page_http_error","bot_check_unresolved","page_too_large","page_unreachable","browser_session_interrupted","site_export_not_found","site_export_format_unavailable","site_export_read_failed","site_export_image_not_found","image_url_invalid","image_url_not_https","image_host_unresolvable","image_host_blocked","image_redirect_invalid","image_source_unavailable","image_too_large","image_redirect_limit","image_base64_invalid","image_source_missing","image_source_ambiguous","image_source_type_invalid","image_artifact_not_found","image_page_too_large","page_image_not_found","page_image_candidates_unusable","image_format_unsupported","image_storage_unconfigured","featured_image_unhostable"],rd=["request_aborted","captcha","location_mismatch","connection","timeout","extraction","concurrency_limit","unauthorized","forbidden","invalid_request","rate_limit","billing","service_unavailable"];var Qh=new Set(od),Zh=new Set(rd);function rs(e){return e.replace((new RegExp("https?:\\/\\/[^\\s]*(?:\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061|on\u006b\u0065\u0072\u006e\u0065\u006c|\u006b\u0065\u0072\u006e\u0065\u006c\\.sh)[^\\s]*", "gi")),"the service").replace(/bright\s*data/gi,"the service").replace((new RegExp("\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061", "gi")),"the service").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\.sh\\s+sessions?", "gi")),"sessions").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\.sh\\s+session", "gi")),"this session").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\.sh", "gi")),"the service").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\s+sessions?", "gi")),"sessions").replace((new RegExp("\u006b\u0065\u0072\u006e\u0065\u006c\\s+session", "gi")),"this session").replace(/\b(?:sub|cus|sess|proxy)_[A-Za-z0-9_-]+\b/g,"[redacted]").replace((new RegExp("\\b(?:\u004b\u0045\u0052\u004e\u0045\u004c|\u0042\u0052\u0049\u0047\u0048\u0054\u0044\u0041\u0054\u0041|\u0042\u0052\u0049\u0047\u0048\u0054_\u0044\u0041\u0054\u0041)_[A-Z0-9_]*API_KEY\\b", "g")),"BROWSER_SERVICE_API_KEY").replace((new RegExp("\\b\u006b\u0065\u0072\u006e\u0065\u006c\\b", "gi")),"the service").replace(/ +/g," ").trim()}var at=class extends Error{constructor(n){super(`CAPTCHA detected. ${n}`);this.instructions=n}instructions;name="CaptchaError"},Pe=class extends Error{constructor(n,a){super(n);this.cause=a}cause;name="ExtractionError"};var gt=class extends Error{name="RequestAbortedError";constructor(t="Request aborted before harvest completed"){super(t)}},zt=class extends Error{name="PaaInteractionInterruptedError"},je=class extends Error{name="LocationMismatchError";constructor(t="Google returned results for a different location than requested"){super(t)}};async function _n(e,t,n,a){let i,s=!1,o,d=()=>{},l=()=>a?.reason instanceof DOMException&&a.reason.name==="TimeoutError"?a.reason:new gt,U=()=>d(l()),S=new Promise((u,c)=>{d=c}),r=async u=>{let c;try{await Promise.race([u.close().catch(()=>{}),new Promise(h=>{c=setTimeout(h,2e3)})])}finally{c&&clearTimeout(c)}};if(a?.aborted)throw l();a?.addEventListener("abort",U,{once:!0}),o=setTimeout(()=>d(new DOMException("Optional pagination timed out","TimeoutError")),3e4);try{return await Promise.race([(async()=>{let u=await e.newPage();if(s)throw await r(u),new gt;if(i=u,await t(u),s)throw new gt;return n(u)})(),S])}finally{s=!0,o&&clearTimeout(o),a?.removeEventListener("abort",U),i&&await r(i)}}var Ea=require("crypto");var ds=require("@libsql/client/http"),ze=require("crypto"),Q=require("zod");var vt="strftime('%Y-%m-%dT%H:%M:%fZ','now')";var dd=[`CREATE TABLE IF NOT EXISTS oauth_store_metadata (
|
|
11
11
|
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
12
12
|
store_id TEXT NOT NULL UNIQUE,
|
|
13
13
|
schema_version INTEGER NOT NULL CHECK (schema_version > 0),
|
|
@@ -118,7 +118,7 @@ ${r}`)}return o},g=cr(Yi);var Bt=class extends _{create(t,n){return this._client
|
|
|
118
118
|
updated_at TEXT NOT NULL DEFAULT (${vt}),
|
|
119
119
|
PRIMARY KEY (scope, key_digest, window_start, window_seconds)
|
|
120
120
|
) STRICT`,`CREATE INDEX IF NOT EXISTS oauth_rate_limit_buckets_expiry_idx
|
|
121
|
-
ON oauth_rate_limit_buckets(expires_at, scope, key_digest, window_start, window_seconds)`],ig=[...dd,...ld,...Sd];var ud=process.env.TURSO_DATABASE_URL??"file:./paa-api.db",cd=process.env.TURSO_AUTH_TOKEN,va=null;function
|
|
121
|
+
ON oauth_rate_limit_buckets(expires_at, scope, key_digest, window_start, window_seconds)`],ig=[...dd,...ld,...Sd];var ud=process.env.TURSO_DATABASE_URL??"file:./paa-api.db",cd=process.env.TURSO_AUTH_TOKEN,va=null;function bn(){return va||(va=(0,ds.createClient)({url:ud,authToken:cd})),va}var cg=32*1024;var hg=Q.z.object({id:Q.z.string(),user_id:Q.z.number(),status:Q.z.string().default("pending"),client_domain:Q.z.string(),session_path:Q.z.string(),request:Q.z.string(),result:Q.z.string().nullable(),error:Q.z.string().nullable(),created_at:Q.z.string(),updated_at:Q.z.string()}),gg=Q.z.object({id:Q.z.number(),job_id:Q.z.string(),phase:Q.z.string(),completed_at:Q.z.string(),output_summary:Q.z.string()});var ls=require("async_hooks"),Ss="MCP_SCRAPER_ALLOW_HEADLESS_HARVEST_TEST",Us=new ls.AsyncLocalStorage;function us(e,t){return Us.run(e,t)}function $t(){return Us.getStore()}var hd=166667e-10,gd=.0001333336,cs=new Set(["serp","fb_search","fb_ad","instagram"]),pd=.00111,wd=4,md=4e-4;function Ie(e,t){let n=process.env[e]?.trim();if(!n)return t;let a=Number(n);return Number.isFinite(a)&&a>=0?a:t}var yd=Ie("NANGO_USD_PER_CONNECTION_MONTH",1),Cd=Ie("NANGO_USD_PER_FUNCTION_RUN",1e-4),Td=Ie("NANGO_USD_PER_PROXY_REQUEST",1e-4),kd=Ie("NANGO_USD_PER_COMPUTE_SEC",2e-4),fd=Ie("\u0042\u0052\u0049\u0047\u0048\u0054\u0044\u0041\u0054\u0041_BROWSER_USD_PER_GB",8),yg=Ie("\u0042\u0052\u0049\u0047\u0048\u0054\u0044\u0041\u0054\u0041_SERP_USD_PER_REQUEST",.002836168);function _a(e,t){return Math.max(0,e)/1e3*(t?gd:hd)}function hs(e,t){return e==="fal_wizper"?Math.max(0,t)/wd*pd:e==="deepinfra_qwen"?Math.max(0,t)/1e3*md:e==="openrouter"||e==="mcp_memory_video"||e==="mcp_memory_ai"?Math.max(0,t):e==="nango_connection"?Math.max(0,t)*yd:e==="nango_function_run"?Math.max(0,t)*Cd:e==="nango_proxy_request"?Math.max(0,t)*Td:e==="nango_compute"?Math.max(0,t)*kd:e==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061_browser_api"?Math.max(0,t)/1e9*fd:0}var ba=!1,$e=null;async function gs(){if(!ba)return $e||($e=Md().finally(()=>{$e=null}),$e)}async function Md(){let e=bn(),t=await e.execute(`
|
|
122
122
|
SELECT
|
|
123
123
|
(SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name IN ('\u006b\u0065\u0072\u006e\u0065\u006c_session_log', 'vendor_usage_log', 'cost_probe_runs')) = 3
|
|
124
124
|
AND (SELECT COUNT(*) FROM pragma_table_info('\u006b\u0065\u0072\u006e\u0065\u006c_session_log') WHERE name IN ('proxy_source', 'proxy_type', 'method')) = 3
|
|
@@ -126,7 +126,7 @@ ${r}`)}return o},g=cr(Yi);var Bt=class extends _{create(t,n){return this._client
|
|
|
126
126
|
AND (SELECT COUNT(*) FROM sqlite_master WHERE type = 'index' AND name = 'vendor_usage_log_vendor_source_key') = 1
|
|
127
127
|
AND (SELECT COUNT(*) FROM pragma_table_info('cost_probe_runs') WHERE name IN ('units', 'unit_type', 'mode')) = 3
|
|
128
128
|
AS ready
|
|
129
|
-
`);if(Number(t.rows[0]?.ready??0)===1){
|
|
129
|
+
`);if(Number(t.rows[0]?.ready??0)===1){ba=!0;return}await e.execute(`
|
|
130
130
|
CREATE TABLE IF NOT EXISTS \u006b\u0065\u0072\u006e\u0065\u006c_session_log (
|
|
131
131
|
id TEXT PRIMARY KEY,
|
|
132
132
|
\u006b\u0065\u0072\u006e\u0065\u006c_session_id TEXT,
|
|
@@ -164,7 +164,7 @@ ${r}`)}return o},g=cr(Yi);var Bt=class extends _{create(t,n){return this._client
|
|
|
164
164
|
provider_status TEXT,
|
|
165
165
|
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
166
166
|
)
|
|
167
|
-
`),await e.execute("CREATE INDEX IF NOT EXISTS vendor_usage_log_op ON vendor_usage_log(op)"),await e.execute("CREATE INDEX IF NOT EXISTS vendor_usage_log_probe ON vendor_usage_log(probe_run_id)"),await e.execute("CREATE INDEX IF NOT EXISTS vendor_usage_log_created ON vendor_usage_log(created_at)");try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN method TEXT")}catch{}try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN source_key TEXT")}catch{}try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN provider_duration_ms INTEGER")}catch{}try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN provider_captcha INTEGER")}catch{}try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN provider_status TEXT")}catch{}await e.execute("CREATE UNIQUE INDEX IF NOT EXISTS vendor_usage_log_vendor_source_key ON vendor_usage_log(vendor, source_key) WHERE source_key IS NOT NULL"),await e.execute(
|
|
167
|
+
`),await e.execute("CREATE INDEX IF NOT EXISTS vendor_usage_log_op ON vendor_usage_log(op)"),await e.execute("CREATE INDEX IF NOT EXISTS vendor_usage_log_probe ON vendor_usage_log(probe_run_id)"),await e.execute("CREATE INDEX IF NOT EXISTS vendor_usage_log_created ON vendor_usage_log(created_at)");try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN method TEXT")}catch{}try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN source_key TEXT")}catch{}try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN provider_duration_ms INTEGER")}catch{}try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN provider_captcha INTEGER")}catch{}try{await e.execute("ALTER TABLE vendor_usage_log ADD COLUMN provider_status TEXT")}catch{}await e.execute("CREATE UNIQUE INDEX IF NOT EXISTS vendor_usage_log_vendor_source_key ON vendor_usage_log(vendor, source_key) WHERE source_key IS NOT NULL"),await e.execute(`
|
|
168
168
|
CREATE TABLE IF NOT EXISTS cost_probe_runs (
|
|
169
169
|
id TEXT PRIMARY KEY,
|
|
170
170
|
tool TEXT NOT NULL,
|
|
@@ -186,11 +186,11 @@ ${r}`)}return o},g=cr(Yi);var Bt=class extends _{create(t,n){return this._client
|
|
|
186
186
|
margin_usd_headful_starter REAL NOT NULL DEFAULT 0,
|
|
187
187
|
notes TEXT
|
|
188
188
|
)
|
|
189
|
-
`),await e.execute("CREATE INDEX IF NOT EXISTS cost_probe_runs_tool ON cost_probe_runs(tool)");try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN units REAL")}catch{}try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN unit_type TEXT")}catch{}try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN mode TEXT")}catch{}
|
|
189
|
+
`),await e.execute("CREATE INDEX IF NOT EXISTS cost_probe_runs_tool ON cost_probe_runs(tool)");try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN units REAL")}catch{}try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN unit_type TEXT")}catch{}try{await e.execute("ALTER TABLE cost_probe_runs ADD COLUMN mode TEXT")}catch{}ba=!0}async function ps(e){try{await gs();let t=$t(),n=Math.max(0,e.closedAtMs-e.openedAtMs);await bn().execute({sql:`INSERT INTO \u006b\u0065\u0072\u006e\u0065\u006c_session_log
|
|
190
190
|
(id, \u006b\u0065\u0072\u006e\u0065\u006c_session_id, op, source, probe_run_id, user_id, stealth, headless_sent, proxy_used, proxy_source, proxy_type, fallback, opened_at, closed_at, duration_ms, est_cost_usd_headless, est_cost_usd_headful, error, method)
|
|
191
|
-
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,args:[(0,Ea.randomUUID)(),e.\u006b\u0065\u0072\u006e\u0065\u006cSessionId??null,t?.op??null,e.source,t?.probeRunId??null,t?.userId??null,En(e.stealth),En(e.headlessSent),En(e.proxyUsed),e.proxySource??null,e.proxyType??null,e.fallback?1:0,new Date(e.openedAtMs).toISOString(),new Date(e.closedAtMs).toISOString(),n,
|
|
191
|
+
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,args:[(0,Ea.randomUUID)(),e.\u006b\u0065\u0072\u006e\u0065\u006cSessionId??null,t?.op??null,e.source,t?.probeRunId??null,t?.userId??null,En(e.stealth),En(e.headlessSent),En(e.proxyUsed),e.proxySource??null,e.proxyType??null,e.fallback?1:0,new Date(e.openedAtMs).toISOString(),new Date(e.closedAtMs).toISOString(),n,_a(n,!1),_a(n,!0),e.error??null,t?.subOp??null]})}catch(t){console.warn("[cost-telemetry] record\u004b\u0065\u0072\u006e\u0065\u006cSession failed:",t instanceof Error?t.message:String(t))}}async function Pa(e){try{await gs();let t=$t();return(await bn().execute({sql:`INSERT OR IGNORE INTO vendor_usage_log
|
|
192
192
|
(id, op, probe_run_id, user_id, vendor, model, units, unit_type, est_cost_usd, error, method, source_key, provider_duration_ms, provider_captcha, provider_status)
|
|
193
|
-
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,args:[(0,Ea.randomUUID)(),e.op??t?.op??null,e.probeRunId??t?.probeRunId??null,e.userId??t?.userId??null,e.vendor,e.model??null,e.units,e.unitType,hs(e.vendor,e.units),e.error??null,e.method??t?.subOp??null,e.sourceKey??null,e.providerDurationMs??null,En(e.providerCaptcha),e.providerStatus??null]})).rowsAffected===1}catch(t){return console.warn("[cost-telemetry] recordVendorUsage failed:",t instanceof Error?t.message:String(t)),!1}}function En(e){return e==null?null:e?1:0}var Nd=/\b(?:HeadlessChrome|Chrome|Chromium|Firefox)\/\d+|\bVersion\/\d+.*\bSafari\//;async function Pn(e){try{let t=await e.evaluate(()=>navigator.userAgent);return typeof t=="string"&&Nd.test(t)?t:null}catch{return null}}async function In(e){let t=null;try{let n=e.contexts().flatMap(a=>a.pages())[0];return n||(t=await e.newContext(),n=t.pages()[0]??await t.newPage()),await Pn(n)}catch{return null}finally{t&&await t.close().catch(()=>{})}}Ln.chromium.use((0,ms.default)());var vd=180,bd=3e3,_d=5e3,Ed='#search, #rso, a[href] h3, [data-snhf], [role="main"]';function Ia(e,t){return e?Math.max(1,Math.min(t,e-Date.now())):t}function Pd(e,t){let n=process.env[e];if(!n)return t;let a=Number(n);return Number.isInteger(a)&&a>0?a:t}function Aa(e){return e?e.slice(-6):null}function ws(e,t){let n=(t??process.env.SERP_REDIRECT_BASE)?.trim().replace(/\/+$/,"");return n?`${n}/g/${Buffer.from(e,"utf8").toString("base64url")}`:e}function Id(e){return e?/united states|u\.?s\.?a?\.?|^us$/i.test(e.trim()):!1}function Le(e){return e instanceof Error?e.message:String(e)}function Ad(e){return/\b409\b|conflict|already exists/i.test(Le(e))}function Ld(e){return/\b404\b|not[ _-]?found|already (?:gone|deleted|closed)|does not exist/i.test(Le(e))}async function xd(e,t){try{await e.profiles.create({name:t})}catch(n){if(!Ad(n))throw n}}function An(e,t){return{viewport:e.viewport,locale:e.locale,...t?{userAgent:t}:{},...e.deviceScaleFactor?{deviceScaleFactor:e.deviceScaleFactor}:{},...e.isMobile!==void 0?{isMobile:e.isMobile}:{},...e.hasTouch!==void 0?{hasTouch:e.hasTouch}:{}}}async function Ae(e,t,n){let a;try{return await Promise.race([e,new Promise((i,s)=>{a=setTimeout(()=>s(new Error(`${n} timed out after ${t}ms`)),t)})])}finally{a&&clearTimeout(a)}}function Od(e){let t=e.trim();if(!t)throw new Error("channelHandle is required");if(/^https?:\/\//i.test(t)||/^(www\.|m\.)?youtube\.com\//i.test(t)){let o=new URL(/^https?:\/\//i.test(t)?t:`https://${t}`);if(o.hostname.replace(/^www\./,"").replace(/^m\./,"").toLowerCase()!=="youtube.com")throw new Error("channel URL must be on youtube.com");let l=o.pathname.split("/").filter(Boolean),U=l[0]??"",S=l[1]??"";if(U.startsWith("@"))return`https://www.youtube.com/${U}/videos`;if(U==="channel"&&S)return`https://www.youtube.com/channel/${S}/videos`;if((U==="c"||U==="user")&&S)return`https://www.youtube.com/${U}/${S}/videos`;throw new Error("channel URL must be a YouTube handle, /channel/UC..., /c/..., or /user/... URL")}let i=t.replace(/^\/+/,"").replace(/\/+$/,"").replace(/\/videos$/i,"");if(/^UC[\w-]{20,}$/.test(i))return`https://www.youtube.com/channel/${i}/videos`;let s=i.startsWith("@")?i:`@${i}`;if(!/^@[\w.-]+$/.test(s))throw new Error("channelHandle must be an @handle, UC channel ID, or YouTube channel URL");return`https://www.youtube.com/${s}/videos`}var xn=class{browser=null;context=null;page=null;\u006b\u0065\u0072\u006e\u0065\u006cClient=null;\u006b\u0065\u0072\u006e\u0065\u006cSessionId=null;\u006b\u0065\u0072\u006e\u0065\u006cOpenedAtMs=null;\u006b\u0065\u0072\u006e\u0065\u006cStealth=null;\u006b\u0065\u0072\u006e\u0065\u006cProxyUsed=null;\u006b\u0065\u0072\u006e\u0065\u006cProxySource=null;\u006b\u0065\u0072\u006e\u0065\u006cProxyType=null;\u006b\u0065\u0072\u006e\u0065\u006cHeadlessSent=null;debugEnabled=!1;debugSnapshot={\u006b\u0065\u0072\u006e\u0065\u006c:null,context:null,networkLocation:null,serpNavigation:null};async launch(t){this.debugEnabled=t.debug===!0;let n=t.proxyMode??(t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId?"configured":"none"),a=t.isMobile?"mobile":"desktop";if(this.debugSnapshot={\u006b\u0065\u0072\u006e\u0065\u006c:null,context:{viewport:t.viewport,locale:t.locale,device:a,userAgent:null,deviceScaleFactor:t.deviceScaleFactor??null,isMobile:t.isMobile===!0,hasTouch:t.hasTouch===!0},networkLocation:null,serpNavigation:null},t.\u006b\u0065\u0072\u006e\u0065\u006cApiKey){this.\u006b\u0065\u0072\u006e\u0065\u006cClient=new H({apiKey:t.\u006b\u0065\u0072\u006e\u0065\u006cApiKey});let s=Number.isInteger(t.\u006b\u0065\u0072\u006e\u0065\u006cTimeoutSeconds)&&Number(t.\u006b\u0065\u0072\u006e\u0065\u006cTimeoutSeconds)>0?Number(t.\u006b\u0065\u0072\u006e\u0065\u006cTimeoutSeconds):Pd("\u004b\u0045\u0052\u004e\u0045\u004c_BROWSER_TIMEOUT_SECONDS",vd),o=Math.min(s,600);t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName&&t.\u006b\u0065\u0072\u006e\u0065\u006cProfileSaveChanges===!0&&await xd(this.\u006b\u0065\u0072\u006e\u0065\u006cClient,t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName);let d=$t(),l;t.headlessMode==="headful"||d?.forceHeadful===!0?l=!1:t.headlessMode==="headless"?l=!0:l=d?.forceHeadless===!0||process.env.\u004b\u0045\u0052\u004e\u0045\u004c_HEADLESS_DISABLED!=="true"&&!!d?.op&&cs.has(d.op),this.\u006b\u0065\u0072\u006e\u0065\u006cHeadlessSent=l?!0:null,d?.headlessSentOut&&(d.headlessSentOut.value=this.\u006b\u0065\u0072\u006e\u0065\u006cHeadlessSent);let U=await this.\u006b\u0065\u0072\u006e\u0065\u006cClient.browsers.create({stealth:t.\u006b\u0065\u0072\u006e\u0065\u006cStealth===!0,timeout_seconds:o,...l?{headless:!0}:{},...t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId?{proxy_id:t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId}:{},...t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName?{profile:{name:t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName,...typeof t.\u006b\u0065\u0072\u006e\u0065\u006cProfileSaveChanges=="boolean"?{save_changes:t.\u006b\u0065\u0072\u006e\u0065\u006cProfileSaveChanges}:{}}}:{}});this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId=U.session_id,this.\u006b\u0065\u0072\u006e\u0065\u006cOpenedAtMs=Date.now(),this.\u006b\u0065\u0072\u006e\u0065\u006cStealth=typeof U.stealth=="boolean"?U.stealth:null,this.\u006b\u0065\u0072\u006e\u0065\u006cProxyUsed=typeof U.proxy_id=="string"?!!U.proxy_id:!!t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId,this.\u006b\u0065\u0072\u006e\u0065\u006cProxySource=t.\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution?.source??null,this.\u006b\u0065\u0072\u006e\u0065\u006cProxyType=t.\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution?.proxyType??null;let S=null,r=null;if(!t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId&&!t.keepDefaultProxy)try{await Ae(this.\u006b\u0065\u0072\u006e\u0065\u006cClient.browsers.update(this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,{disable_default_proxy:!0}),5e3,`\u004b\u0065\u0072\u006e\u0065\u006c session ${this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId} disable default proxy`),S=!0}catch(c){S=!1,r=Le(c)}let u={sessionId:this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,proxyMode:n,requestedProxyIdPresent:!!t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId,requestedProxyIdSuffix:Aa(t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId),createdProxyIdPresent:typeof U.proxy_id=="string"?!!U.proxy_id:null,createdProxyIdSuffix:Aa(U.proxy_id),retrievedProxyIdPresent:null,retrievedProxyIdSuffix:null,retrievedProxyIdMatchesRequested:null,defaultProxyDisabled:S,defaultProxyDisableError:r,proxyResolution:t.\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution??null,timeoutSeconds:o,stealth:typeof U.stealth=="boolean"?U.stealth:null,profilePresent:null,poolPresent:null,retrieveError:null};if(this.debugSnapshot.\u006b\u0065\u0072\u006e\u0065\u006c=u,console.info(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_browser_created",\u006b\u0065\u0072\u006e\u0065\u006c_session_id:this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,timeout_seconds:o,proxy_mode:n,proxy_id_present:!!t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId,profile_name_present:!!t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName,proxy_resolution_source:t.\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution?.source})),this.debugEnabled&&await this.populate\u004b\u0065\u0072\u006e\u0065\u006cRetrieveDebug(u,t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId),this.browser=await ys.chromium.connectOverCDP(U.cdp_ws_url),t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName||t.preserve\u004b\u0065\u0072\u006e\u0065\u006cContext)this.context=this.browser.contexts()[0]??await this.browser.newContext(An(t)),this.page=this.context.pages()[0]??await this.context.newPage(),this.debugSnapshot.context.userAgent=await Pn(this.page);else{let c=await In(this.browser);this.debugSnapshot.context.userAgent=c,this.context=await this.browser.newContext(An(t,c)),this.page=await this.context.newPage()}if(await this.installEsbuildHelperShims(this.context),t.preserve\u004b\u0065\u0072\u006e\u0065\u006cContext||await this.page.setViewportSize(t.viewport),(this.debugEnabled||t.requireUsEgress)&&(this.debugSnapshot.networkLocation=await this.captureBrowserNetworkLocation()),t.requireUsEgress){let c=this.debugSnapshot.networkLocation?.country??null;if(!Id(c))throw new at(`Non-US egress (${c??"unknown"}) \u2014 retrying with a fresh session`)}return}let i={headless:t.headless,proxy:t.proxy?{server:t.proxy}:void 0,...t.browserExecutablePath?{executablePath:t.browserExecutablePath}:{},...t.ignoreDefaultArgs?{ignoreDefaultArgs:t.ignoreDefaultArgs}:{}};if(t.profileDir)this.context=await Ln.chromium.launchPersistentContext(t.profileDir,{...i,...An(t)}),await this.installEsbuildHelperShims(this.context),this.page=await this.context.newPage(),this.debugSnapshot.context.userAgent=await Pn(this.page);else{this.browser=await Ln.chromium.launch(i);let s=await In(this.browser);this.debugSnapshot.context.userAgent=s,this.context=await this.browser.newContext(An(t,s)),await this.installEsbuildHelperShims(this.context),this.page=await this.context.newPage()}this.debugEnabled&&(this.debugSnapshot.networkLocation=await this.captureBrowserNetworkLocation())}async populate\u004b\u0065\u0072\u006e\u0065\u006cRetrieveDebug(t,n){if(!(!this.\u006b\u0065\u0072\u006e\u0065\u006cClient||!this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId))try{let a=await Ae(this.\u006b\u0065\u0072\u006e\u0065\u006cClient.browsers.retrieve(this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId),5e3,`\u004b\u0065\u0072\u006e\u0065\u006c session ${this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId} retrieve`);t.retrievedProxyIdPresent=typeof a.proxy_id=="string"?!!a.proxy_id:!1,t.retrievedProxyIdSuffix=Aa(a.proxy_id),t.retrievedProxyIdMatchesRequested=n?a.proxy_id===n:!a.proxy_id,t.timeoutSeconds=typeof a.timeout_seconds=="number"?a.timeout_seconds:t.timeoutSeconds,t.stealth=typeof a.stealth=="boolean"?a.stealth:t.stealth,t.profilePresent=!!a.profile,t.poolPresent=!!a.pool}catch(a){t.retrieveError=Le(a)}}async captureBrowserNetworkLocation(){let t=(a,i="ipapi.co")=>({source:i,ip:null,city:null,region:null,country:null,org:null,timezone:null,error:a});if(!this.context)return t("browser context is not available");let n=null;try{n=await this.context.newPage();let a=await this.loadJsonInDebugPage(n,"https://ipwho.is/");if(a){let d=typeof a.connection=="object"&&a.connection!==null?a.connection:{};return{source:"ipwho.is",ip:typeof a.ip=="string"?a.ip:null,city:typeof a.city=="string"?a.city:null,region:typeof a.region=="string"?a.region:null,country:typeof a.country=="string"?a.country:null,org:typeof d.org=="string"?d.org:null,timezone:typeof a.timezone=="object"&&a.timezone!==null&&typeof a.timezone.id=="string"?a.timezone.id:null,error:null}}let i=await this.loadJsonInDebugPage(n,"https://api64.ipify.org?format=json");if(i)return{source:"api64.ipify.org",ip:typeof i.ip=="string"?i.ip:null,city:null,region:null,country:null,org:null,timezone:null,error:null};await Ae(n.goto("https://ipapi.co/json/",{waitUntil:"domcontentloaded",timeout:7e3}),8e3,"browser network location navigation");let s=await n.locator("body").innerText({timeout:2e3}),o=JSON.parse(s);return{source:"ipapi.co",ip:typeof o.ip=="string"?o.ip:null,city:typeof o.city=="string"?o.city:null,region:typeof o.region=="string"?o.region:null,country:typeof o.country_name=="string"?o.country_name:typeof o.country=="string"?o.country:null,org:typeof o.org=="string"?o.org:null,timezone:typeof o.timezone=="string"?o.timezone:null,error:null}}catch(a){return t(Le(a))}finally{await n?.close().catch(()=>{})}}async loadJsonInDebugPage(t,n){try{await Ae(t.goto(n,{waitUntil:"domcontentloaded",timeout:7e3}),8e3,`browser network location navigation ${n}`);let a=await t.locator("body").innerText({timeout:2e3});return JSON.parse(a)}catch{return null}}async installEsbuildHelperShims(t){await t.addInitScript(()=>{let n=globalThis;typeof n.__name!="function"&&(n.__name=a=>a),typeof n.__publicField!="function"&&(n.__publicField=(a,i,s)=>(a[i]=s,s))})}async withTemporaryPage(t,n){if(!this.context)throw new Error("Browser context is not available");return bn(this.context,async()=>{},t,n)}async navigateToSERP(t,n,a,i,s){let o=new URLSearchParams({q:t,gl:a,hl:i,pws:"0"});s?.tbs&&o.set("tbs",s.tbs),n&&o.set("uule",n);let d="https://www.google.com/search?"+o.toString(),l=ws(d),U=s?.debug?{requestedUrl:d,finalUrl:null,title:null,bodySnippet:null,hasPaa:null,captchaDetected:null,googleSorryUrl:null,redirected:null}:null;U&&(this.debugSnapshot.serpNavigation=U);try{await this.page.goto(l,{waitUntil:"domcontentloaded",timeout:Ia(s?.deadlineMs,s?.purpose==="serp"?8e3:45e3)})}catch(r){await this.updateSerpNavigationDebug(U,d,{hasPaa:null,captchaDetected:null});let u=await this.captureDiagnostics(d);throw new Pe(`page.goto failed: ${r.message} | ${u}`)}if(await this.isSerpChallengeVisible())throw await this.updateSerpNavigationDebug(U,d,{hasPaa:!1,captchaDetected:!0}),new at(this.captchaMessage());if(s?.purpose==="serp"){await this.page.waitForSelector(Ed,{timeout:Ia(s.deadlineMs,1500)}).catch(()=>null);let r=await this.page.locator(Y.item).count().catch(()=>0)>0;return await this.updateSerpNavigationDebug(U,d,{hasPaa:r,captchaDetected:!1}),{hasPaa:r}}if(await this.page.waitForSelector(Y.item,{timeout:Ia(s?.deadlineMs,4e3)}).catch(()=>null))return await this.updateSerpNavigationDebug(U,d,{hasPaa:!0,captchaDetected:!1}),{hasPaa:!0};if(await this.isSerpChallengeVisible())throw await this.updateSerpNavigationDebug(U,d,{hasPaa:!1,captchaDetected:!0}),new at(this.captchaMessage());for(let r=1;r<=6;r++)if(await this.page.evaluate(c=>{window.scrollTo(0,document.body.scrollHeight*c)},r/6),await this.page.waitForTimeout(600),await this.page.locator(Y.item).count()>0)return await this.updateSerpNavigationDebug(U,d,{hasPaa:!0,captchaDetected:!1}),{hasPaa:!0};return await this.updateSerpNavigationDebug(U,d,{hasPaa:!1,captchaDetected:!1}),{hasPaa:!1}}async isSerpChallengeVisible(){if(!this.page)return!1;if(await this.page.locator(Y.captchaMarker).count().catch(()=>0)>0)return!0;let n=this.page.url();if(/google\.[^/]+\/sorry\//i.test(n))return!0;let a=await this.page.evaluate(()=>(document.body?.innerText??"").replace(/\s+/g," ").trim().slice(0,1e3)).catch(()=>"");return/recaptcha|unusual traffic|are you a robot|about this page|detected unusual traffic/i.test(a)}async updateSerpNavigationDebug(t,n,a){if(!(!t||!this.page))try{let i=this.page.url(),s=await this.page.title().catch(()=>""),o=await this.page.evaluate(()=>(document.body?.innerText??"").replace(/\s+/g," ").trim().slice(0,500)).catch(()=>""),d=/recaptcha|unusual traffic|are you a robot/i.test(o);t.finalUrl=i,t.title=s,t.bodySnippet=o,t.hasPaa=a.hasPaa,t.captchaDetected=a.captchaDetected??d,t.googleSorryUrl=/google\.[^/]+\/sorry\//i.test(i),t.redirected=i!==n}catch(i){t.bodySnippet=`debug capture failed: ${Le(i)}`}}async captureDiagnostics(t){try{let n=this.page.url(),a=await this.page.title().catch(()=>""),i=await this.page.evaluate(()=>(document.body?.innerText??"").replace(/\s+/g," ").trim().slice(0,400)).catch(()=>""),s=/consent\.google\./.test(n)||/before you continue/i.test(i),o=/recaptcha|unusual traffic|are you a robot/i.test(i),d=[s?"CONSENT_WALL":"",o?"BOT_CHALLENGE":"",n!==t?"REDIRECTED":""].filter(Boolean).join(",");return`intended=${t} | final=${n} | title="${a}" | flags=[${d}] | body="${i}"`}catch(n){return`diagnostics-failed: ${n.message}`}}captchaMessage(){return this.\u006b\u0065\u0072\u006e\u0065\u006cClient?"Google returned a CAPTCHA on this session \u2014 retrying with a fresh session.":os}async navigateTo(t){let n=process.env.ADS_ARRIVAL_REDIRECT_BASE?.trim(),a=n?ws(t,n):t;try{if(await this.page.goto(a,{waitUntil:"domcontentloaded",timeout:45e3}),/google\.[^/]+\/search\?/i.test(t)&&await this.isSerpChallengeVisible())throw new at(this.captchaMessage())}catch(i){if(i instanceof at)throw i;let s=await this.captureDiagnostics(t);throw new Pe(`page.goto failed: ${i.message} | ${s}`)}}async navigateToChannel(t){let n=Od(t);try{await this.page.goto(n,{waitUntil:"networkidle",timeout:3e4})}catch(a){let i=await this.captureDiagnostics(n);throw new Pe(`navigateToChannel failed: ${a.message} | ${i}`)}}async evaluate(t,n){return this.page.evaluate(t,n)}getPage(){return this.page}get\u004b\u0065\u0072\u006e\u0065\u006cSessionId(){return this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId}getProviderSessionMetadata(){return{provider:this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId?"\u006b\u0065\u0072\u006e\u0065\u006c":"local",providerSessionId:this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,disconnectObservation:null}}getDebugSnapshot(){return this.debugSnapshot}async close(){if(this.browser){let t=this.browser,n=this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,a=this.\u006b\u0065\u0072\u006e\u0065\u006cClient,i=this.\u006b\u0065\u0072\u006e\u0065\u006cOpenedAtMs,s=this.\u006b\u0065\u0072\u006e\u0065\u006cStealth,o=this.\u006b\u0065\u0072\u006e\u0065\u006cProxyUsed,d=this.\u006b\u0065\u0072\u006e\u0065\u006cProxySource,l=this.\u006b\u0065\u0072\u006e\u0065\u006cProxyType,U=this.\u006b\u0065\u0072\u006e\u0065\u006cHeadlessSent,S=this.getProviderSessionMetadata();if(this.browser=null,this.context=null,this.page=null,this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId=null,this.\u006b\u0065\u0072\u006e\u0065\u006cClient=null,this.\u006b\u0065\u0072\u006e\u0065\u006cOpenedAtMs=null,this.\u006b\u0065\u0072\u006e\u0065\u006cHeadlessSent=null,this.\u006b\u0065\u0072\u006e\u0065\u006cProxySource=null,this.\u006b\u0065\u0072\u006e\u0065\u006cProxyType=null,a&&n&&i!=null&&ps({\u006b\u0065\u0072\u006e\u0065\u006cSessionId:n,source:"browser_driver",stealth:s,headlessSent:U,proxyUsed:o,proxySource:d,proxyType:l,openedAtMs:i,closedAtMs:Date.now()}),a&&n){console.info(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_browser_delete_started",\u006b\u0065\u0072\u006e\u0065\u006c_session_id:n}));let r=Ae(a.browsers.deleteByID(n),_d,`\u004b\u0065\u0072\u006e\u0065\u006c session ${n} delete`),u=Ae(t.close(),bd,`\u004b\u0065\u0072\u006e\u0065\u006c browser ${n} close`),[c,h]=await Promise.allSettled([r,u]),m=c.status==="rejected"&&Ld(c.reason),f={\u006b\u0065\u0072\u006e\u0065\u006cSessionId:n,\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted:!0,\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded:c.status==="fulfilled"||m,\u006b\u0065\u0072\u006e\u0065\u006cDeleteError:c.status==="rejected"&&!m?c.reason instanceof Error?c.reason.message:String(c.reason):null,browserCloseSucceeded:h.status==="fulfilled",browserCloseError:h.status==="rejected"?h.reason instanceof Error?h.reason.message:String(h.reason):null,provider:S.provider,providerSessionId:S.providerSessionId,providerDisconnectObserved:!1,providerDisconnectMessage:null};return c.status==="rejected"&&!m?(console.warn(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_browser_delete_failed",\u006b\u0065\u0072\u006e\u0065\u006c_session_id:n,message:f.\u006b\u0065\u0072\u006e\u0065\u006cDeleteError})),console.warn(`\u004b\u0065\u0072\u006e\u0065\u006c session cleanup failed for ${n}:`,c.reason)):console.info(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_browser_delete_succeeded",\u006b\u0065\u0072\u006e\u0065\u006c_session_id:n})),h.status==="rejected"&&(console.warn(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_browser_close_failed",\u006b\u0065\u0072\u006e\u0065\u006c_session_id:n,message:f.browserCloseError})),console.warn(`\u004b\u0065\u0072\u006e\u0065\u006c browser close failed for ${n}:`,h.reason)),f}return await t.close(),{\u006b\u0065\u0072\u006e\u0065\u006cSessionId:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted:!1,\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteError:null,browserCloseSucceeded:!0,browserCloseError:null,provider:S.provider,providerSessionId:S.providerSessionId,providerDisconnectObserved:!1,providerDisconnectMessage:null}}else if(this.context){let t=this.context;return this.context=null,this.page=null,await t.close(),{\u006b\u0065\u0072\u006e\u0065\u006cSessionId:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted:!1,\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteError:null,browserCloseSucceeded:!0,browserCloseError:null,provider:"local",providerSessionId:null,providerDisconnectObserved:!1,providerDisconnectMessage:null}}return{\u006b\u0065\u0072\u006e\u0065\u006cSessionId:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted:!1,\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteError:null,browserCloseSucceeded:null,browserCloseError:null,provider:"local",providerSessionId:null,providerDisconnectObserved:!1,providerDisconnectMessage:null}}};var Ns=require("playwright");function Rd(e,t){if(typeof e!="string")return null;let n=e.replace(/[\u0000-\u001f\u007f]+/g," ").replace(/\s+/g," ").trim();return n?n.slice(0,t):null}function Cs(e){let t=Rd(e,320);return t?t.replace(/\b(?:wss?|https?):\/\/\S+/gi,"[redacted endpoint]").replace(/\b(?:authorization|proxy-authorization):\s*\S+/gi,"$1: [redacted]").replace(/\bBearer\s+\S+/gi,"Bearer [redacted]").slice(0,320):null}function Ts(e){return Cs(e)}function ks(e){if(typeof e!="string"||e.length===0||e.length>512||e.trim()!==e||/[\s\u0000-\u001f\u007f]/.test(e)||/:\/\//.test(e))throw new Error("\u0042\u0072\u0069\u0067\u0068\u0074 \u0044\u0061\u0074\u0061 did not return a valid browser session ID");return e}function La(e,t,n=new Date().toISOString()){let a=Cs(t);return{source:e,message:a??e.replaceAll("_"," "),observedAt:n}}function Wd(e){return{provider:e.provider,providerDisconnectObserved:e.disconnectObservation!==null,providerDisconnectMessage:e.disconnectObservation?.message??null}}function fs(e){return{...Wd(e),providerSessionId:e.providerSessionId}}var Hd=new Set(["image","media","font","stylesheet","ping"]),Bd=["doubleclick.net","googleadservices.com","googlesyndication.com","google-analytics.com"],Dd='#search, #rso, a[href] h3, [data-snhf], [role="main"]',Fd=3e4,Ms=1500;function On(e,t){return e?Math.max(1,Math.min(t,e-Date.now())):t}function vs(){return process.env.\u0042\u0052\u0049\u0047\u0048\u0054\u0044\u0041\u0054\u0041_BROWSER_WSS?.trim()||null}function bs(){return process.env.SERP_BROWSER_PROVIDER?.trim().toLowerCase()==="\u006b\u0065\u0072\u006e\u0065\u006c"?!1:!!vs()}async function xa(e,t=!1){let n=e.request();try{let a=await n.allHeaders(),i=await fetch(n.url(),{method:n.method(),headers:{accept:a.accept??"*/*","accept-language":a["accept-language"]??"en-US,en;q=0.9","user-agent":a["user-agent"]??"Mozilla/5.0",...t?{cookie:a.cookie??"",referer:a.referer??"https://www.google.com/",...a["x-client-data"]?{"x-client-data":a["x-client-data"]}:{}}:{}},body:n.method()==="GET"||n.method()==="HEAD"?void 0:n.postData()});if(!i.ok)return!1;let s=Buffer.from(await i.arrayBuffer());return await e.fulfill({status:i.status,contentType:i.headers.get("content-type")??"application/octet-stream",headers:{"cache-control":"public, max-age=3600"},body:s}),!0}catch{return!1}}var Rn=class{browser=null;context=null;page=null;cdpSession=null;providerSessionId=null;disconnectObservation=null;closing=!1;observeDisconnect(t,n){this.closing||this.disconnectObservation||(this.disconnectObservation=La(t,n))}async launch(t){if(this.page)return;this.closing=!1,this.providerSessionId=null,this.disconnectObservation=null;let n=vs();if(!n)throw new Error("SERP browser service is not configured");this.browser=await Ns.chromium.connectOverCDP(n,{timeout:On(t.operationDeadlineMs,Fd)}),this.context=this.browser.contexts()[0]??await this.browser.newContext(),await this.context.addInitScript(()=>{let s=globalThis;typeof s.__name!="function"&&(s.__name=o=>o),typeof s.__publicField!="function"&&(s.__publicField=(o,d,l)=>(o[d]=l,l))}),this.page=this.context.pages()[0]??await this.context.newPage(),this.browser.on("disconnected",()=>this.observeDisconnect("browser_disconnected")),this.context.on("close",()=>this.observeDisconnect("context_closed")),this.page.on("close",()=>this.observeDisconnect("page_closed")),this.page.on("crash",()=>this.observeDisconnect("page_crashed")),this.cdpSession=await this.context.newCDPSession(this.page);let i=await this.cdpSession.send("Browser.getSessionId");this.providerSessionId=ks(i?.sessionId),await this.setupPage(this.page)}async setupPage(t){await t.route("**/*",async n=>{let a=n.request(),i=a.resourceType(),s;try{s=new URL(a.url())}catch{await n.continue();return}let o=s.hostname.toLowerCase();if(!(s.pathname==="/sgasync"&&await xa(n,!0))&&!(s.pathname.includes("/shared_dict/")&&await xa(n))&&!(i==="script"&&(o==="www.google.com"||o==="www.gstatic.com")&&await xa(n))){if(Hd.has(i)){await n.abort("blockedbyclient");return}if(Bd.some(d=>o===d||o.endsWith(`.${d}`))){await n.abort("blockedbyclient");return}await n.continue()}})}async withTemporaryPage(t,n){if(!this.context||this.closing)throw new Error("Browser context is not available");return bn(this.context,a=>this.setupPage(a),t,n)}async navigateToSERP(t,n,a,i,s){if(!this.page)throw new Error("Browser page is not available");let o=new URLSearchParams({q:t,gl:a,hl:i,pws:"0"});return s?.tbs&&o.set("tbs",s.tbs),n&&o.set("uule",n),await this.page.goto(`https://www.google.com/search?${o}`,{waitUntil:"domcontentloaded",timeout:On(s?.deadlineMs,s?.purpose==="serp"?8e3:45e3)}),s?.purpose==="serp"?(await this.page.waitForSelector(Dd,{timeout:On(s.deadlineMs,1500)}).catch(()=>null),{hasPaa:await this.page.locator(Y.item).count().catch(()=>0)>0}):{hasPaa:!!await this.page.waitForSelector(Y.item,{timeout:On(s?.deadlineMs,8e3)}).catch(()=>null)}}async navigateTo(t){if(!this.page)throw new Error("Browser page is not available");await this.page.goto(t,{waitUntil:"load",timeout:45e3})}async navigateToChannel(){throw new Error("YouTube navigation is not supported by the SERP browser driver")}async evaluate(t,n){if(!this.page)throw new Error("Browser page is not available");return this.page.evaluate(t,n)}getPage(){if(!this.page)throw new Error("Browser page is not available");return this.page}get\u004b\u0065\u0072\u006e\u0065\u006cSessionId(){return null}getProviderSessionMetadata(){return{provider:"\u0062\u0072\u0069\u0067\u0068\u0074_\u0064\u0061\u0074\u0061_browser_api",providerSessionId:this.providerSessionId,disconnectObservation:this.disconnectObservation}}getDebugSnapshot(){return{\u006b\u0065\u0072\u006e\u0065\u006c:null,context:null,networkLocation:null,serpNavigation:null}}async close(){this.closing=!0;let t=null,n;try{let i=this.browser?.close();i&&await Promise.race([i,new Promise((s,o)=>{n=setTimeout(()=>o(new Error(`Browser close acknowledgement exceeded ${Ms}ms`)),Ms)})])}catch(i){t=Ts(i instanceof Error?i.message:String(i))??"\u0042\u0072\u0069\u0067\u0068\u0074 \u0044\u0061\u0074\u0061 browser close failed",this.disconnectObservation??=La("browser_close_error",t)}finally{n&&clearTimeout(n)}let a=fs(this.getProviderSessionMetadata());return this.browser=null,this.context=null,this.page=null,this.cdpSession=null,{\u006b\u0065\u0072\u006e\u0065\u006cSessionId:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted:!1,\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteError:null,browserCloseSucceeded:t===null,browserCloseError:t,...a}}};function _s(e){return e.plannedProvider==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061"?new Rn:new xn}var Qt={austin:"Austin,Texas,United States","new york":"New York,New York,United States","new york city":"New York,New York,United States",nyc:"New York,New York,United States","los angeles":"Los Angeles,California,United States",la:"Los Angeles,California,United States",chicago:"Chicago,Illinois,United States",houston:"Houston,Texas,United States",phoenix:"Phoenix,Arizona,United States",philadelphia:"Philadelphia,Pennsylvania,United States",philly:"Philadelphia,Pennsylvania,United States","san antonio":"San Antonio,Texas,United States",dallas:"Dallas,Texas,United States",miami:"Miami,Florida,United States",seattle:"Seattle,Washington,United States",denver:"Denver,Colorado,United States",loveland:"Loveland,Colorado,United States","loveland co":"Loveland,Colorado,United States","fort collins":"Fort Collins,Colorado,United States",boulder:"Boulder,Colorado,United States","colorado springs":"Colorado Springs,Colorado,United States",boston:"Boston,Massachusetts,United States",atlanta:"Atlanta,Georgia,United States","san francisco":"San Francisco,California,United States",sf:"San Francisco,California,United States",portland:"Portland,Oregon,United States","las vegas":"Las Vegas,Nevada,United States",minneapolis:"Minneapolis,Minnesota,United States",detroit:"Detroit,Michigan,United States",nashville:"Nashville,Tennessee,United States",charlotte:"Charlotte,North Carolina,United States",orlando:"Orlando,Florida,United States","san diego":"San Diego,California,United States",baltimore:"Baltimore,Maryland,United States",sacramento:"Sacramento,California,United States",columbus:"Columbus,Ohio,United States",indianapolis:"Indianapolis,Indiana,United States","san jose":"San Jose,California,United States","fort worth":"Fort Worth,Texas,United States",jacksonville:"Jacksonville,Florida,United States",memphis:"Memphis,Tennessee,United States",louisville:"Louisville,Kentucky,United States",raleigh:"Raleigh,North Carolina,United States",richmond:"Richmond,Virginia,United States","salt lake city":"Salt Lake City,Utah,United States",toronto:"Toronto,Ontario,Canada",vancouver:"Vancouver,British Columbia,Canada",montreal:"Montreal,Quebec,Canada",calgary:"Calgary,Alberta,Canada",ottawa:"Ottawa,Ontario,Canada",london:"London,England,United Kingdom",manchester:"Manchester,England,United Kingdom",birmingham:"Birmingham,England,United Kingdom",edinburgh:"Edinburgh,Scotland,United Kingdom",glasgow:"Glasgow,Scotland,United Kingdom",leeds:"Leeds,England,United Kingdom",sydney:"Sydney,New South Wales,Australia",melbourne:"Melbourne,Victoria,Australia",brisbane:"Brisbane,Queensland,Australia",perth:"Perth,Western Australia,Australia",adelaide:"Adelaide,South Australia,Australia",dublin:"Dublin,Leinster,Ireland"};var Es=`3, Nanjemoy,Maryland,United States
|
|
193
|
+
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`,args:[(0,Ea.randomUUID)(),e.op??t?.op??null,e.probeRunId??t?.probeRunId??null,e.userId??t?.userId??null,e.vendor,e.model??null,e.units,e.unitType,hs(e.vendor,e.units),e.error??null,e.method??t?.subOp??null,e.sourceKey??null,e.providerDurationMs??null,En(e.providerCaptcha),e.providerStatus??null]})).rowsAffected===1}catch(t){return console.warn("[cost-telemetry] recordVendorUsage failed:",t instanceof Error?t.message:String(t)),!1}}function En(e){return e==null?null:e?1:0}var Nd=/\b(?:HeadlessChrome|Chrome|Chromium|Firefox)\/\d+|\bVersion\/\d+.*\bSafari\//;async function Pn(e){try{let t=await e.evaluate(()=>navigator.userAgent);return typeof t=="string"&&Nd.test(t)?t:null}catch{return null}}async function In(e){let t=null;try{let n=e.contexts().flatMap(a=>a.pages())[0];return n||(t=await e.newContext(),n=t.pages()[0]??await t.newPage()),await Pn(n)}catch{return null}finally{t&&await t.close().catch(()=>{})}}Ln.chromium.use((0,ms.default)());var vd=180,_d=3e3,bd=5e3,Ed='#search, #rso, a[href] h3, [data-snhf], [role="main"]';function Ia(e,t){return e?Math.max(1,Math.min(t,e-Date.now())):t}function Pd(e,t){let n=process.env[e];if(!n)return t;let a=Number(n);return Number.isInteger(a)&&a>0?a:t}function Aa(e){return e?e.slice(-6):null}function ws(e,t){let n=(t??process.env.SERP_REDIRECT_BASE)?.trim().replace(/\/+$/,"");return n?`${n}/g/${Buffer.from(e,"utf8").toString("base64url")}`:e}function Id(e){return e?/united states|u\.?s\.?a?\.?|^us$/i.test(e.trim()):!1}function Le(e){return e instanceof Error?e.message:String(e)}function Ad(e){return/\b409\b|conflict|already exists/i.test(Le(e))}function Ld(e){return/\b404\b|not[ _-]?found|already (?:gone|deleted|closed)|does not exist/i.test(Le(e))}async function xd(e,t){try{await e.profiles.create({name:t})}catch(n){if(!Ad(n))throw n}}function An(e,t){return{viewport:e.viewport,locale:e.locale,...t?{userAgent:t}:{},...e.deviceScaleFactor?{deviceScaleFactor:e.deviceScaleFactor}:{},...e.isMobile!==void 0?{isMobile:e.isMobile}:{},...e.hasTouch!==void 0?{hasTouch:e.hasTouch}:{}}}async function Ae(e,t,n){let a;try{return await Promise.race([e,new Promise((i,s)=>{a=setTimeout(()=>s(new Error(`${n} timed out after ${t}ms`)),t)})])}finally{a&&clearTimeout(a)}}function Od(e){let t=e.trim();if(!t)throw new Error("channelHandle is required");if(/^https?:\/\//i.test(t)||/^(www\.|m\.)?youtube\.com\//i.test(t)){let o=new URL(/^https?:\/\//i.test(t)?t:`https://${t}`);if(o.hostname.replace(/^www\./,"").replace(/^m\./,"").toLowerCase()!=="youtube.com")throw new Error("channel URL must be on youtube.com");let l=o.pathname.split("/").filter(Boolean),U=l[0]??"",S=l[1]??"";if(U.startsWith("@"))return`https://www.youtube.com/${U}/videos`;if(U==="channel"&&S)return`https://www.youtube.com/channel/${S}/videos`;if((U==="c"||U==="user")&&S)return`https://www.youtube.com/${U}/${S}/videos`;throw new Error("channel URL must be a YouTube handle, /channel/UC..., /c/..., or /user/... URL")}let i=t.replace(/^\/+/,"").replace(/\/+$/,"").replace(/\/videos$/i,"");if(/^UC[\w-]{20,}$/.test(i))return`https://www.youtube.com/channel/${i}/videos`;let s=i.startsWith("@")?i:`@${i}`;if(!/^@[\w.-]+$/.test(s))throw new Error("channelHandle must be an @handle, UC channel ID, or YouTube channel URL");return`https://www.youtube.com/${s}/videos`}var xn=class{browser=null;context=null;page=null;\u006b\u0065\u0072\u006e\u0065\u006cClient=null;\u006b\u0065\u0072\u006e\u0065\u006cSessionId=null;\u006b\u0065\u0072\u006e\u0065\u006cOpenedAtMs=null;\u006b\u0065\u0072\u006e\u0065\u006cStealth=null;\u006b\u0065\u0072\u006e\u0065\u006cProxyUsed=null;\u006b\u0065\u0072\u006e\u0065\u006cProxySource=null;\u006b\u0065\u0072\u006e\u0065\u006cProxyType=null;\u006b\u0065\u0072\u006e\u0065\u006cHeadlessSent=null;last\u004b\u0065\u0072\u006e\u0065\u006cBillingMode=null;last\u004b\u0065\u0072\u006e\u0065\u006cOpenedAtMs=null;last\u004b\u0065\u0072\u006e\u0065\u006cClosedAtMs=null;debugEnabled=!1;debugSnapshot={\u006b\u0065\u0072\u006e\u0065\u006c:null,context:null,networkLocation:null,serpNavigation:null};async launch(t){this.debugEnabled=t.debug===!0;let n=t.proxyMode??(t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId?"configured":"none"),a=t.isMobile?"mobile":"desktop";if(this.debugSnapshot={\u006b\u0065\u0072\u006e\u0065\u006c:null,context:{viewport:t.viewport,locale:t.locale,device:a,userAgent:null,deviceScaleFactor:t.deviceScaleFactor??null,isMobile:t.isMobile===!0,hasTouch:t.hasTouch===!0},networkLocation:null,serpNavigation:null},t.\u006b\u0065\u0072\u006e\u0065\u006cApiKey){this.\u006b\u0065\u0072\u006e\u0065\u006cClient=new H({apiKey:t.\u006b\u0065\u0072\u006e\u0065\u006cApiKey});let s=Number.isInteger(t.\u006b\u0065\u0072\u006e\u0065\u006cTimeoutSeconds)&&Number(t.\u006b\u0065\u0072\u006e\u0065\u006cTimeoutSeconds)>0?Number(t.\u006b\u0065\u0072\u006e\u0065\u006cTimeoutSeconds):Pd("\u004b\u0045\u0052\u004e\u0045\u004c_BROWSER_TIMEOUT_SECONDS",vd),o=Math.min(s,600);t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName&&t.\u006b\u0065\u0072\u006e\u0065\u006cProfileSaveChanges===!0&&await xd(this.\u006b\u0065\u0072\u006e\u0065\u006cClient,t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName);let d=$t(),l;t.headlessMode==="headful"||d?.forceHeadful===!0?l=!1:t.headlessMode==="headless"?l=!0:l=d?.forceHeadless===!0||process.env.\u004b\u0045\u0052\u004e\u0045\u004c_HEADLESS_DISABLED!=="true"&&!!d?.op&&cs.has(d.op),this.\u006b\u0065\u0072\u006e\u0065\u006cHeadlessSent=l?!0:null,this.last\u004b\u0065\u0072\u006e\u0065\u006cBillingMode=l?"headless":"headful",d?.headlessSentOut&&(d.headlessSentOut.value=this.\u006b\u0065\u0072\u006e\u0065\u006cHeadlessSent);let U=await this.\u006b\u0065\u0072\u006e\u0065\u006cClient.browsers.create({stealth:t.\u006b\u0065\u0072\u006e\u0065\u006cStealth===!0,timeout_seconds:o,...l?{headless:!0}:{},...t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId?{proxy_id:t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId}:{},...t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName?{profile:{name:t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName,...typeof t.\u006b\u0065\u0072\u006e\u0065\u006cProfileSaveChanges=="boolean"?{save_changes:t.\u006b\u0065\u0072\u006e\u0065\u006cProfileSaveChanges}:{}}}:{}});this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId=U.session_id,this.\u006b\u0065\u0072\u006e\u0065\u006cOpenedAtMs=Date.now(),this.last\u004b\u0065\u0072\u006e\u0065\u006cOpenedAtMs=this.\u006b\u0065\u0072\u006e\u0065\u006cOpenedAtMs,this.last\u004b\u0065\u0072\u006e\u0065\u006cClosedAtMs=null,this.\u006b\u0065\u0072\u006e\u0065\u006cStealth=typeof U.stealth=="boolean"?U.stealth:null,this.\u006b\u0065\u0072\u006e\u0065\u006cProxyUsed=typeof U.proxy_id=="string"?!!U.proxy_id:!!t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId,this.\u006b\u0065\u0072\u006e\u0065\u006cProxySource=t.\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution?.source??null,this.\u006b\u0065\u0072\u006e\u0065\u006cProxyType=t.\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution?.proxyType??null;let S=null,r=null;if(!t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId&&!t.keepDefaultProxy)try{await Ae(this.\u006b\u0065\u0072\u006e\u0065\u006cClient.browsers.update(this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,{disable_default_proxy:!0}),5e3,`\u004b\u0065\u0072\u006e\u0065\u006c session ${this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId} disable default proxy`),S=!0}catch(c){S=!1,r=Le(c)}let u={sessionId:this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,proxyMode:n,requestedProxyIdPresent:!!t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId,requestedProxyIdSuffix:Aa(t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId),createdProxyIdPresent:typeof U.proxy_id=="string"?!!U.proxy_id:null,createdProxyIdSuffix:Aa(U.proxy_id),retrievedProxyIdPresent:null,retrievedProxyIdSuffix:null,retrievedProxyIdMatchesRequested:null,defaultProxyDisabled:S,defaultProxyDisableError:r,proxyResolution:t.\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution??null,timeoutSeconds:o,stealth:typeof U.stealth=="boolean"?U.stealth:null,profilePresent:null,poolPresent:null,retrieveError:null};if(this.debugSnapshot.\u006b\u0065\u0072\u006e\u0065\u006c=u,console.info(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_browser_created",\u006b\u0065\u0072\u006e\u0065\u006c_session_id:this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,timeout_seconds:o,proxy_mode:n,proxy_id_present:!!t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId,profile_name_present:!!t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName,proxy_resolution_source:t.\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution?.source})),this.debugEnabled&&await this.populate\u004b\u0065\u0072\u006e\u0065\u006cRetrieveDebug(u,t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId),this.browser=await ys.chromium.connectOverCDP(U.cdp_ws_url),t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName||t.preserve\u004b\u0065\u0072\u006e\u0065\u006cContext)this.context=this.browser.contexts()[0]??await this.browser.newContext(An(t)),this.page=this.context.pages()[0]??await this.context.newPage(),this.debugSnapshot.context.userAgent=await Pn(this.page);else{let c=await In(this.browser);this.debugSnapshot.context.userAgent=c,this.context=await this.browser.newContext(An(t,c)),this.page=await this.context.newPage()}if(await this.installEsbuildHelperShims(this.context),t.preserve\u004b\u0065\u0072\u006e\u0065\u006cContext||await this.page.setViewportSize(t.viewport),(this.debugEnabled||t.requireUsEgress)&&(this.debugSnapshot.networkLocation=await this.captureBrowserNetworkLocation()),t.requireUsEgress){let c=this.debugSnapshot.networkLocation?.country??null;if(!Id(c))throw new at(`Non-US egress (${c??"unknown"}) \u2014 retrying with a fresh session`)}return}let i={headless:t.headless,proxy:t.proxy?{server:t.proxy}:void 0,...t.browserExecutablePath?{executablePath:t.browserExecutablePath}:{},...t.ignoreDefaultArgs?{ignoreDefaultArgs:t.ignoreDefaultArgs}:{}};if(t.profileDir)this.context=await Ln.chromium.launchPersistentContext(t.profileDir,{...i,...An(t)}),await this.installEsbuildHelperShims(this.context),this.page=await this.context.newPage(),this.debugSnapshot.context.userAgent=await Pn(this.page);else{this.browser=await Ln.chromium.launch(i);let s=await In(this.browser);this.debugSnapshot.context.userAgent=s,this.context=await this.browser.newContext(An(t,s)),await this.installEsbuildHelperShims(this.context),this.page=await this.context.newPage()}this.debugEnabled&&(this.debugSnapshot.networkLocation=await this.captureBrowserNetworkLocation())}async populate\u004b\u0065\u0072\u006e\u0065\u006cRetrieveDebug(t,n){if(!(!this.\u006b\u0065\u0072\u006e\u0065\u006cClient||!this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId))try{let a=await Ae(this.\u006b\u0065\u0072\u006e\u0065\u006cClient.browsers.retrieve(this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId),5e3,`\u004b\u0065\u0072\u006e\u0065\u006c session ${this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId} retrieve`);t.retrievedProxyIdPresent=typeof a.proxy_id=="string"?!!a.proxy_id:!1,t.retrievedProxyIdSuffix=Aa(a.proxy_id),t.retrievedProxyIdMatchesRequested=n?a.proxy_id===n:!a.proxy_id,t.timeoutSeconds=typeof a.timeout_seconds=="number"?a.timeout_seconds:t.timeoutSeconds,t.stealth=typeof a.stealth=="boolean"?a.stealth:t.stealth,t.profilePresent=!!a.profile,t.poolPresent=!!a.pool}catch(a){t.retrieveError=Le(a)}}async captureBrowserNetworkLocation(){let t=(a,i="ipapi.co")=>({source:i,ip:null,city:null,region:null,country:null,org:null,timezone:null,error:a});if(!this.context)return t("browser context is not available");let n=null;try{n=await this.context.newPage();let a=await this.loadJsonInDebugPage(n,"https://ipwho.is/");if(a){let d=typeof a.connection=="object"&&a.connection!==null?a.connection:{};return{source:"ipwho.is",ip:typeof a.ip=="string"?a.ip:null,city:typeof a.city=="string"?a.city:null,region:typeof a.region=="string"?a.region:null,country:typeof a.country=="string"?a.country:null,org:typeof d.org=="string"?d.org:null,timezone:typeof a.timezone=="object"&&a.timezone!==null&&typeof a.timezone.id=="string"?a.timezone.id:null,error:null}}let i=await this.loadJsonInDebugPage(n,"https://api64.ipify.org?format=json");if(i)return{source:"api64.ipify.org",ip:typeof i.ip=="string"?i.ip:null,city:null,region:null,country:null,org:null,timezone:null,error:null};await Ae(n.goto("https://ipapi.co/json/",{waitUntil:"domcontentloaded",timeout:7e3}),8e3,"browser network location navigation");let s=await n.locator("body").innerText({timeout:2e3}),o=JSON.parse(s);return{source:"ipapi.co",ip:typeof o.ip=="string"?o.ip:null,city:typeof o.city=="string"?o.city:null,region:typeof o.region=="string"?o.region:null,country:typeof o.country_name=="string"?o.country_name:typeof o.country=="string"?o.country:null,org:typeof o.org=="string"?o.org:null,timezone:typeof o.timezone=="string"?o.timezone:null,error:null}}catch(a){return t(Le(a))}finally{await n?.close().catch(()=>{})}}async loadJsonInDebugPage(t,n){try{await Ae(t.goto(n,{waitUntil:"domcontentloaded",timeout:7e3}),8e3,`browser network location navigation ${n}`);let a=await t.locator("body").innerText({timeout:2e3});return JSON.parse(a)}catch{return null}}async installEsbuildHelperShims(t){await t.addInitScript(()=>{let n=globalThis;typeof n.__name!="function"&&(n.__name=a=>a),typeof n.__publicField!="function"&&(n.__publicField=(a,i,s)=>(a[i]=s,s))})}async withTemporaryPage(t,n){if(!this.context)throw new Error("Browser context is not available");return _n(this.context,async()=>{},t,n)}async navigateToSERP(t,n,a,i,s){let o=new URLSearchParams({q:t,gl:a,hl:i,pws:"0"});s?.tbs&&o.set("tbs",s.tbs),n&&o.set("uule",n);let d="https://www.google.com/search?"+o.toString(),l=ws(d),U=s?.debug?{requestedUrl:d,finalUrl:null,title:null,bodySnippet:null,hasPaa:null,captchaDetected:null,googleSorryUrl:null,redirected:null}:null;U&&(this.debugSnapshot.serpNavigation=U);try{await this.page.goto(l,{waitUntil:"domcontentloaded",timeout:Ia(s?.deadlineMs,s?.purpose==="serp"?8e3:45e3)})}catch(r){await this.updateSerpNavigationDebug(U,d,{hasPaa:null,captchaDetected:null});let u=await this.captureDiagnostics(d);throw new Pe(`page.goto failed: ${r.message} | ${u}`)}if(await this.isSerpChallengeVisible())throw await this.updateSerpNavigationDebug(U,d,{hasPaa:!1,captchaDetected:!0}),new at(this.captchaMessage());if(s?.purpose==="serp"){await this.page.waitForSelector(Ed,{timeout:Ia(s.deadlineMs,1500)}).catch(()=>null);let r=await this.page.locator(Y.item).count().catch(()=>0)>0;return await this.updateSerpNavigationDebug(U,d,{hasPaa:r,captchaDetected:!1}),{hasPaa:r}}if(await this.page.waitForSelector(Y.item,{timeout:Ia(s?.deadlineMs,4e3)}).catch(()=>null))return await this.updateSerpNavigationDebug(U,d,{hasPaa:!0,captchaDetected:!1}),{hasPaa:!0};if(await this.isSerpChallengeVisible())throw await this.updateSerpNavigationDebug(U,d,{hasPaa:!1,captchaDetected:!0}),new at(this.captchaMessage());for(let r=1;r<=6;r++)if(await this.page.evaluate(c=>{window.scrollTo(0,document.body.scrollHeight*c)},r/6),await this.page.waitForTimeout(600),await this.page.locator(Y.item).count()>0)return await this.updateSerpNavigationDebug(U,d,{hasPaa:!0,captchaDetected:!1}),{hasPaa:!0};return await this.updateSerpNavigationDebug(U,d,{hasPaa:!1,captchaDetected:!1}),{hasPaa:!1}}async isSerpChallengeVisible(){if(!this.page)return!1;if(await this.page.locator(Y.captchaMarker).count().catch(()=>0)>0)return!0;let n=this.page.url();if(/google\.[^/]+\/sorry\//i.test(n))return!0;let a=await this.page.evaluate(()=>(document.body?.innerText??"").replace(/\s+/g," ").trim().slice(0,1e3)).catch(()=>"");return/recaptcha|unusual traffic|are you a robot|about this page|detected unusual traffic/i.test(a)}async updateSerpNavigationDebug(t,n,a){if(!(!t||!this.page))try{let i=this.page.url(),s=await this.page.title().catch(()=>""),o=await this.page.evaluate(()=>(document.body?.innerText??"").replace(/\s+/g," ").trim().slice(0,500)).catch(()=>""),d=/recaptcha|unusual traffic|are you a robot/i.test(o);t.finalUrl=i,t.title=s,t.bodySnippet=o,t.hasPaa=a.hasPaa,t.captchaDetected=a.captchaDetected??d,t.googleSorryUrl=/google\.[^/]+\/sorry\//i.test(i),t.redirected=i!==n}catch(i){t.bodySnippet=`debug capture failed: ${Le(i)}`}}async captureDiagnostics(t){try{let n=this.page.url(),a=await this.page.title().catch(()=>""),i=await this.page.evaluate(()=>(document.body?.innerText??"").replace(/\s+/g," ").trim().slice(0,400)).catch(()=>""),s=/consent\.google\./.test(n)||/before you continue/i.test(i),o=/recaptcha|unusual traffic|are you a robot/i.test(i),d=[s?"CONSENT_WALL":"",o?"BOT_CHALLENGE":"",n!==t?"REDIRECTED":""].filter(Boolean).join(",");return`intended=${t} | final=${n} | title="${a}" | flags=[${d}] | body="${i}"`}catch(n){return`diagnostics-failed: ${n.message}`}}captchaMessage(){return this.\u006b\u0065\u0072\u006e\u0065\u006cClient?"Google returned a CAPTCHA on this session \u2014 retrying with a fresh session.":os}async navigateTo(t){let n=process.env.ADS_ARRIVAL_REDIRECT_BASE?.trim(),a=n?ws(t,n):t;try{if(await this.page.goto(a,{waitUntil:"domcontentloaded",timeout:45e3}),/google\.[^/]+\/search\?/i.test(t)&&await this.isSerpChallengeVisible())throw new at(this.captchaMessage())}catch(i){if(i instanceof at)throw i;let s=await this.captureDiagnostics(t);throw new Pe(`page.goto failed: ${i.message} | ${s}`)}}async navigateToChannel(t){let n=Od(t);try{await this.page.goto(n,{waitUntil:"networkidle",timeout:3e4})}catch(a){let i=await this.captureDiagnostics(n);throw new Pe(`navigateToChannel failed: ${a.message} | ${i}`)}}async evaluate(t,n){return this.page.evaluate(t,n)}getPage(){return this.page}get\u004b\u0065\u0072\u006e\u0065\u006cSessionId(){return this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId}get\u004b\u0065\u0072\u006e\u0065\u006cMeteringEvidence(){return{sessionId:this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId??this.debugSnapshot.\u006b\u0065\u0072\u006e\u0065\u006c?.sessionId??null,billingMode:this.last\u004b\u0065\u0072\u006e\u0065\u006cBillingMode,openedAtMs:this.last\u004b\u0065\u0072\u006e\u0065\u006cOpenedAtMs,closedAtMs:this.last\u004b\u0065\u0072\u006e\u0065\u006cClosedAtMs}}getProviderSessionMetadata(){return{provider:this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId?"\u006b\u0065\u0072\u006e\u0065\u006c":"local",providerSessionId:this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,disconnectObservation:null,billingMode:this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId?this.\u006b\u0065\u0072\u006e\u0065\u006cHeadlessSent?"headless":"headful":null}}getDebugSnapshot(){return this.debugSnapshot}async close(){if(this.browser){let t=this.browser,n=this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,a=this.\u006b\u0065\u0072\u006e\u0065\u006cClient,i=this.\u006b\u0065\u0072\u006e\u0065\u006cOpenedAtMs,s=this.\u006b\u0065\u0072\u006e\u0065\u006cStealth,o=this.\u006b\u0065\u0072\u006e\u0065\u006cProxyUsed,d=this.\u006b\u0065\u0072\u006e\u0065\u006cProxySource,l=this.\u006b\u0065\u0072\u006e\u0065\u006cProxyType,U=this.\u006b\u0065\u0072\u006e\u0065\u006cHeadlessSent,S=this.getProviderSessionMetadata();if(this.browser=null,this.context=null,this.page=null,this.\u006b\u0065\u0072\u006e\u0065\u006cSessionId=null,this.\u006b\u0065\u0072\u006e\u0065\u006cClient=null,this.\u006b\u0065\u0072\u006e\u0065\u006cOpenedAtMs=null,this.\u006b\u0065\u0072\u006e\u0065\u006cHeadlessSent=null,this.\u006b\u0065\u0072\u006e\u0065\u006cProxySource=null,this.\u006b\u0065\u0072\u006e\u0065\u006cProxyType=null,a&&n){console.info(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_browser_delete_started",\u006b\u0065\u0072\u006e\u0065\u006c_session_id:n}));let r=Ae(a.browsers.deleteByID(n),bd,`\u004b\u0065\u0072\u006e\u0065\u006c session ${n} delete`),u=Ae(t.close(),_d,`\u004b\u0065\u0072\u006e\u0065\u006c browser ${n} close`),[c,h]=await Promise.allSettled([r,u]);this.last\u004b\u0065\u0072\u006e\u0065\u006cClosedAtMs=Date.now(),i!=null&&ps({\u006b\u0065\u0072\u006e\u0065\u006cSessionId:n,source:"browser_driver",stealth:s,headlessSent:U,proxyUsed:o,proxySource:d,proxyType:l,openedAtMs:i,closedAtMs:this.last\u004b\u0065\u0072\u006e\u0065\u006cClosedAtMs});let m=c.status==="rejected"&&Ld(c.reason),f={\u006b\u0065\u0072\u006e\u0065\u006cSessionId:n,\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted:!0,\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded:c.status==="fulfilled"||m,\u006b\u0065\u0072\u006e\u0065\u006cDeleteError:c.status==="rejected"&&!m?c.reason instanceof Error?c.reason.message:String(c.reason):null,browserCloseSucceeded:h.status==="fulfilled",browserCloseError:h.status==="rejected"?h.reason instanceof Error?h.reason.message:String(h.reason):null,provider:S.provider,providerSessionId:S.providerSessionId,providerDisconnectObserved:!1,providerDisconnectMessage:null};return c.status==="rejected"&&!m?(console.warn(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_browser_delete_failed",\u006b\u0065\u0072\u006e\u0065\u006c_session_id:n,message:f.\u006b\u0065\u0072\u006e\u0065\u006cDeleteError})),console.warn(`\u004b\u0065\u0072\u006e\u0065\u006c session cleanup failed for ${n}:`,c.reason)):console.info(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_browser_delete_succeeded",\u006b\u0065\u0072\u006e\u0065\u006c_session_id:n})),h.status==="rejected"&&(console.warn(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_browser_close_failed",\u006b\u0065\u0072\u006e\u0065\u006c_session_id:n,message:f.browserCloseError})),console.warn(`\u004b\u0065\u0072\u006e\u0065\u006c browser close failed for ${n}:`,h.reason)),f}return await t.close(),{\u006b\u0065\u0072\u006e\u0065\u006cSessionId:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted:!1,\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteError:null,browserCloseSucceeded:!0,browserCloseError:null,provider:S.provider,providerSessionId:S.providerSessionId,providerDisconnectObserved:!1,providerDisconnectMessage:null}}else if(this.context){let t=this.context;return this.context=null,this.page=null,await t.close(),{\u006b\u0065\u0072\u006e\u0065\u006cSessionId:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted:!1,\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteError:null,browserCloseSucceeded:!0,browserCloseError:null,provider:"local",providerSessionId:null,providerDisconnectObserved:!1,providerDisconnectMessage:null}}return{\u006b\u0065\u0072\u006e\u0065\u006cSessionId:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted:!1,\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteError:null,browserCloseSucceeded:null,browserCloseError:null,provider:"local",providerSessionId:null,providerDisconnectObserved:!1,providerDisconnectMessage:null}}};var Ns=require("playwright");function Rd(e,t){if(typeof e!="string")return null;let n=e.replace(/[\u0000-\u001f\u007f]+/g," ").replace(/\s+/g," ").trim();return n?n.slice(0,t):null}function Cs(e){let t=Rd(e,320);return t?t.replace(/\b(?:wss?|https?):\/\/\S+/gi,"[redacted endpoint]").replace(/\b(?:authorization|proxy-authorization):\s*\S+/gi,"$1: [redacted]").replace(/\bBearer\s+\S+/gi,"Bearer [redacted]").slice(0,320):null}function Ts(e){return Cs(e)}function ks(e){if(typeof e!="string"||e.length===0||e.length>512||e.trim()!==e||/[\s\u0000-\u001f\u007f]/.test(e)||/:\/\//.test(e))throw new Error("\u0042\u0072\u0069\u0067\u0068\u0074 \u0044\u0061\u0074\u0061 did not return a valid browser session ID");return e}function La(e,t,n=new Date().toISOString()){let a=Cs(t);return{source:e,message:a??e.replaceAll("_"," "),observedAt:n}}function Wd(e){return{provider:e.provider,providerDisconnectObserved:e.disconnectObservation!==null,providerDisconnectMessage:e.disconnectObservation?.message??null}}function fs(e){return{...Wd(e),providerSessionId:e.providerSessionId}}var Hd=new Set(["image","media","font","stylesheet","ping"]),Bd=["doubleclick.net","googleadservices.com","googlesyndication.com","google-analytics.com"],Dd='#search, #rso, a[href] h3, [data-snhf], [role="main"]',Fd=3e4,Ms=1500;function On(e,t){return e?Math.max(1,Math.min(t,e-Date.now())):t}function vs(){return process.env.\u0042\u0052\u0049\u0047\u0048\u0054\u0044\u0041\u0054\u0041_BROWSER_WSS?.trim()||null}function _s(){return process.env.SERP_BROWSER_PROVIDER?.trim().toLowerCase()==="\u006b\u0065\u0072\u006e\u0065\u006c"?!1:!!vs()}async function xa(e,t=!1){let n=e.request();try{let a=await n.allHeaders(),i=await fetch(n.url(),{method:n.method(),headers:{accept:a.accept??"*/*","accept-language":a["accept-language"]??"en-US,en;q=0.9","user-agent":a["user-agent"]??"Mozilla/5.0",...t?{cookie:a.cookie??"",referer:a.referer??"https://www.google.com/",...a["x-client-data"]?{"x-client-data":a["x-client-data"]}:{}}:{}},body:n.method()==="GET"||n.method()==="HEAD"?void 0:n.postData()});if(!i.ok)return!1;let s=Buffer.from(await i.arrayBuffer());return await e.fulfill({status:i.status,contentType:i.headers.get("content-type")??"application/octet-stream",headers:{"cache-control":"public, max-age=3600"},body:s}),!0}catch{return!1}}var Rn=class{browser=null;context=null;page=null;cdpSession=null;providerSessionId=null;disconnectObservation=null;closing=!1;observeDisconnect(t,n){this.closing||this.disconnectObservation||(this.disconnectObservation=La(t,n))}async launch(t){if(this.page)return;this.closing=!1,this.providerSessionId=null,this.disconnectObservation=null;let n=vs();if(!n)throw new Error("SERP browser service is not configured");this.browser=await Ns.chromium.connectOverCDP(n,{timeout:On(t.operationDeadlineMs,Fd)}),this.context=this.browser.contexts()[0]??await this.browser.newContext(),await this.context.addInitScript(()=>{let s=globalThis;typeof s.__name!="function"&&(s.__name=o=>o),typeof s.__publicField!="function"&&(s.__publicField=(o,d,l)=>(o[d]=l,l))}),this.page=this.context.pages()[0]??await this.context.newPage(),this.browser.on("disconnected",()=>this.observeDisconnect("browser_disconnected")),this.context.on("close",()=>this.observeDisconnect("context_closed")),this.page.on("close",()=>this.observeDisconnect("page_closed")),this.page.on("crash",()=>this.observeDisconnect("page_crashed")),this.cdpSession=await this.context.newCDPSession(this.page);let i=await this.cdpSession.send("Browser.getSessionId");this.providerSessionId=ks(i?.sessionId),await this.setupPage(this.page)}async setupPage(t){await t.route("**/*",async n=>{let a=n.request(),i=a.resourceType(),s;try{s=new URL(a.url())}catch{await n.continue();return}let o=s.hostname.toLowerCase();if(!(s.pathname==="/sgasync"&&await xa(n,!0))&&!(s.pathname.includes("/shared_dict/")&&await xa(n))&&!(i==="script"&&(o==="www.google.com"||o==="www.gstatic.com")&&await xa(n))){if(Hd.has(i)){await n.abort("blockedbyclient");return}if(Bd.some(d=>o===d||o.endsWith(`.${d}`))){await n.abort("blockedbyclient");return}await n.continue()}})}async withTemporaryPage(t,n){if(!this.context||this.closing)throw new Error("Browser context is not available");return _n(this.context,a=>this.setupPage(a),t,n)}async navigateToSERP(t,n,a,i,s){if(!this.page)throw new Error("Browser page is not available");let o=new URLSearchParams({q:t,gl:a,hl:i,pws:"0"});return s?.tbs&&o.set("tbs",s.tbs),n&&o.set("uule",n),await this.page.goto(`https://www.google.com/search?${o}`,{waitUntil:"domcontentloaded",timeout:On(s?.deadlineMs,s?.purpose==="serp"?8e3:45e3)}),s?.purpose==="serp"?(await this.page.waitForSelector(Dd,{timeout:On(s.deadlineMs,1500)}).catch(()=>null),{hasPaa:await this.page.locator(Y.item).count().catch(()=>0)>0}):{hasPaa:!!await this.page.waitForSelector(Y.item,{timeout:On(s?.deadlineMs,8e3)}).catch(()=>null)}}async navigateTo(t){if(!this.page)throw new Error("Browser page is not available");await this.page.goto(t,{waitUntil:"load",timeout:45e3})}async navigateToChannel(){throw new Error("YouTube navigation is not supported by the SERP browser driver")}async evaluate(t,n){if(!this.page)throw new Error("Browser page is not available");return this.page.evaluate(t,n)}getPage(){if(!this.page)throw new Error("Browser page is not available");return this.page}get\u004b\u0065\u0072\u006e\u0065\u006cSessionId(){return null}getProviderSessionMetadata(){return{provider:"\u0062\u0072\u0069\u0067\u0068\u0074_\u0064\u0061\u0074\u0061_browser_api",providerSessionId:this.providerSessionId,disconnectObservation:this.disconnectObservation}}getDebugSnapshot(){return{\u006b\u0065\u0072\u006e\u0065\u006c:null,context:null,networkLocation:null,serpNavigation:null}}async close(){this.closing=!0;let t=null,n;try{let i=this.browser?.close();i&&await Promise.race([i,new Promise((s,o)=>{n=setTimeout(()=>o(new Error(`Browser close acknowledgement exceeded ${Ms}ms`)),Ms)})])}catch(i){t=Ts(i instanceof Error?i.message:String(i))??"\u0042\u0072\u0069\u0067\u0068\u0074 \u0044\u0061\u0074\u0061 browser close failed",this.disconnectObservation??=La("browser_close_error",t)}finally{n&&clearTimeout(n)}let a=fs(this.getProviderSessionMetadata());return this.browser=null,this.context=null,this.page=null,this.cdpSession=null,{\u006b\u0065\u0072\u006e\u0065\u006cSessionId:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted:!1,\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteError:null,browserCloseSucceeded:t===null,browserCloseError:t,...a}}};function bs(e){return e.plannedProvider==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061"?new Rn:new xn}var Qt={austin:"Austin,Texas,United States","new york":"New York,New York,United States","new york city":"New York,New York,United States",nyc:"New York,New York,United States","los angeles":"Los Angeles,California,United States",la:"Los Angeles,California,United States",chicago:"Chicago,Illinois,United States",houston:"Houston,Texas,United States",phoenix:"Phoenix,Arizona,United States",philadelphia:"Philadelphia,Pennsylvania,United States",philly:"Philadelphia,Pennsylvania,United States","san antonio":"San Antonio,Texas,United States",dallas:"Dallas,Texas,United States",miami:"Miami,Florida,United States",seattle:"Seattle,Washington,United States",denver:"Denver,Colorado,United States",loveland:"Loveland,Colorado,United States","loveland co":"Loveland,Colorado,United States","fort collins":"Fort Collins,Colorado,United States",boulder:"Boulder,Colorado,United States","colorado springs":"Colorado Springs,Colorado,United States",boston:"Boston,Massachusetts,United States",atlanta:"Atlanta,Georgia,United States","san francisco":"San Francisco,California,United States",sf:"San Francisco,California,United States",portland:"Portland,Oregon,United States","las vegas":"Las Vegas,Nevada,United States",minneapolis:"Minneapolis,Minnesota,United States",detroit:"Detroit,Michigan,United States",nashville:"Nashville,Tennessee,United States",charlotte:"Charlotte,North Carolina,United States",orlando:"Orlando,Florida,United States","san diego":"San Diego,California,United States",baltimore:"Baltimore,Maryland,United States",sacramento:"Sacramento,California,United States",columbus:"Columbus,Ohio,United States",indianapolis:"Indianapolis,Indiana,United States","san jose":"San Jose,California,United States","fort worth":"Fort Worth,Texas,United States",jacksonville:"Jacksonville,Florida,United States",memphis:"Memphis,Tennessee,United States",louisville:"Louisville,Kentucky,United States",raleigh:"Raleigh,North Carolina,United States",richmond:"Richmond,Virginia,United States","salt lake city":"Salt Lake City,Utah,United States",toronto:"Toronto,Ontario,Canada",vancouver:"Vancouver,British Columbia,Canada",montreal:"Montreal,Quebec,Canada",calgary:"Calgary,Alberta,Canada",ottawa:"Ottawa,Ontario,Canada",london:"London,England,United Kingdom",manchester:"Manchester,England,United Kingdom",birmingham:"Birmingham,England,United Kingdom",edinburgh:"Edinburgh,Scotland,United Kingdom",glasgow:"Glasgow,Scotland,United Kingdom",leeds:"Leeds,England,United Kingdom",sydney:"Sydney,New South Wales,Australia",melbourne:"Melbourne,Victoria,Australia",brisbane:"Brisbane,Queensland,Australia",perth:"Perth,Western Australia,Australia",adelaide:"Adelaide,South Australia,Australia",dublin:"Dublin,Leinster,Ireland"};var Es=`3, Nanjemoy,Maryland,United States
|
|
194
194
|
Aaronsburg,Pennsylvania,United States
|
|
195
195
|
Abbeville,Alabama,United States
|
|
196
196
|
Abbeville,Georgia,United States
|
|
@@ -21892,14 +21892,14 @@ Zwolle,Louisiana,United States`,Ps={ad:"Andorra",ae:"United Arab Emirates",af:"A
|
|
|
21892
21892
|
`).replace(/\n{3,}/g,`
|
|
21893
21893
|
|
|
21894
21894
|
`).trim();return!R||/not available|try again|can't generate/i.test(R)?null:R}function U(C){if(!C||C.startsWith("javascript:"))return null;try{let E=new URL(C,window.location.href);return!["http:","https:"].includes(E.protocol)||E.username||E.password?null:{href:E.href,rawHref:E.href}}catch{return null}}function S(C){if(!C)return[];let E=new Set,w=[];for(let k of Array.from(C.querySelectorAll("a[href]"))){let v=U(k.getAttribute("href")??"");if(!v||E.has(v.rawHref))continue;E.add(v.rawHref);let I="";try{I=new URL(v.href).hostname.replace(/^www\./,"")}catch{}w.push({text:i(k)||I||v.href,href:v.href,rawHref:v.rawHref})}return w}async function r(C){let E=C.querySelector(t.aio.showMoreButton);if(!E||E.getAttribute("aria-expanded")!=="false")return!1;E.click();let w=t.expandWaitMs??1500;return w>0&&await new Promise(k=>setTimeout(k,w)),!0}let u=d(),c=null,h=[],m=!1,f=!1,M=[];if(u){m=await r(u);let C=u.querySelector(t.aio.controller),E=u.querySelector(t.aio.contentSubtree),w=u.querySelector(t.aio.showMoreButton);f=C?.getAttribute("data-trnct")==="false"||w?.getAttribute("aria-expanded")==="true"||!w,c=l(E??C??u),M=(c??"").split(`
|
|
21895
|
-
`).map(k=>k.trim()).filter(k=>/^\d+\.\s+.+/.test(k)),h=S(u)}let y=document.querySelector(t.aim.root),A=a==="aim"&&!!y,O=y?.closest(t.aim.wrapper)??y,B=A?l(O):null,b=A&&s(B),N=b?B:null,W=b?S(O):[],P=!!u&&s(c);return{surface:a,aiOverview:{detected:P,text:P?c:null,citations:P?h:[],expanded:P?m:!1,fullyExpanded:P?f:!1,sections:P?M:[]},aiMode:{detected:b&&N!==null,text:N,citations:W}}}var Fs=require("crypto"),Gs=8e3,Vs=3e3,Ys=1e4,nl=8;function Lt(e){return/(^|\.)google\.(?:com|[a-z]{2,3}(?:\.[a-z]{2})?)$/i.test(e)}function tn(e){if(!e||e.length>Gs)return null;try{let t=new URL(e);return t.protocol!=="http:"&&t.protocol!=="https:"||t.username||t.password?null:t}catch{return null}}function al(e,t){if(!e||e.length>Gs||/^javascript:/i.test(e))return null;try{let n=new URL(e,t);return tn(n.href)}catch{return null}}function Ze(e){let t=tn(e);return!t||t.protocol!=="https:"||!Lt(t.hostname)||t.pathname!=="/goto"?null:t.searchParams.get("url")?t:null}function Ba(e){if(e.linkType!=="google_goto_redirect"||e.resolutionStatus!=="resolved"||!Ze(e.rawUrl)||!e.resolvedUrl)return!1;let t=tn(e.resolvedUrl);return!!(t&&!Lt(t.hostname)&&t.href===e.resolvedUrl&&e.url===t.href)}function Zt(e){let t=e.normalize("NFKC").toLocaleLowerCase("en-US").replace(/[^\p{L}\p{N}\s]/gu,"").replace(/\s+/g," ").trim();return`paa_${(0,Fs.createHash)("sha256").update(t).digest("hex").slice(0,16)}`}function Hn(e,t){let n=al(e,t);if(!n)return null;let a=n.href;if(!Lt(n.hostname))return{url:a,rawUrl:a,resolvedUrl:a,linkType:"plain",resolutionStatus:"not_needed"};if(n.pathname==="/url"){let i=tn(n.searchParams.get("q")??n.searchParams.get("url")??"");return!i||Lt(i.hostname)?null:{url:i.href,rawUrl:a,resolvedUrl:i.href,linkType:"google_url_redirect",resolutionStatus:"resolved"}}return n.pathname==="/goto"&&n.searchParams.get("url")?{url:a,rawUrl:a,resolvedUrl:null,linkType:"google_goto_redirect",resolutionStatus:"unresolved"}:null}function Da(e){return Ze(e)?.searchParams.get("url")??null}function Ks(e,t){try{let n=new URL(e),a=tn(new URL(t,n).href);return!a||Lt(a.hostname)?null:(!a.hash&&n.hash&&(a.hash=n.hash),a.href)}catch{return null}}async function Js(e,t={}){let n=[...new Set([...e].flatMap(r=>Ze(r)?[r]:[]))],a=new Map(n.map(r=>[r,{rawUrl:r,resolvedUrl:null,resolutionStatus:"unresolved"}])),i=typeof globalThis.fetch=="function"?globalThis.fetch.bind(globalThis):null,s=t.fetchImpl??i;if(n.length===0||!s)return{resolutions:[...a.values()],nonGoogleRequestsObserved:0};let o=Math.max(1,t.timeoutMs??Vs),d=Date.now()+Math.max(1,t.totalBudgetMs??Ys),l=Math.max(1,Math.min(16,Math.floor(t.concurrency??nl))),U=0,S=async()=>{for(;U<n.length;){let r=n[U++],u=Ze(r),c=u?.searchParams.get("url");if(!u||!c){a.set(r,{rawUrl:r,resolvedUrl:null,resolutionStatus:"rejected"});continue}u.hash="";let h=u.href;for(let m=0;m<2;m++){let f=d-Date.now();if(f<=0)return;let M=new AbortController,y=setTimeout(()=>M.abort(),Math.min(o,f)),A;try{A=await s(h,{method:"GET",redirect:"manual",headers:{accept:"*/*","user-agent":"Mozilla/5.0"},signal:M.signal})}catch{break}finally{clearTimeout(y)}if(A.status<300||A.status>=400)break;let O=A.headers.get("location");if(!O)break;let B=Ks(r,O);if(B){a.set(r,{rawUrl:r,resolvedUrl:B,resolutionStatus:"resolved"});break}let b;try{b=new URL(O,h)}catch{a.set(r,{rawUrl:r,resolvedUrl:null,resolutionStatus:"rejected"});break}if(!Lt(b.hostname)||Da(b.href)!==c){a.set(r,{rawUrl:r,resolvedUrl:null,resolutionStatus:"rejected"});break}h=b.href}}};return await Promise.all(Array.from({length:Math.min(l,n.length)},()=>S())),{resolutions:[...a.values()],nonGoogleRequestsObserved:0}}function Ds(e,t){try{return new URL(e.resolvedUrl??e.url).hostname.replace(/^www\./,"")}catch{return t}}async function qs(e,t={}){let n=[],a=r=>{for(let u of r)n.push(u),a(u.children??[])};a(e.tree??[]);let i=[...e.flat.flatMap(r=>r.sources??[]),...n.flatMap(r=>r.sources),...e.organicResults??[],...(e.aiOverview?.citations??[]).map(({text:r,href:u,...c})=>({...c,url:u})),...(e.aiMode?.citations??[]).map(({text:r,href:u,...c})=>({...c,url:u}))],s=new Map(i.filter(r=>!!r?.rawUrl).map(r=>[r.rawUrl,r])),o=[...s.values()].filter(r=>r.linkType==="google_goto_redirect"&&r.resolutionStatus!=="resolved").map(r=>r.rawUrl);if(o.length>0){let r=await Js(o,t);for(let u of r.resolutions){let c=s.get(u.rawUrl);c&&s.set(u.rawUrl,u.resolutionStatus==="resolved"&&u.resolvedUrl?{...c,url:u.resolvedUrl,resolvedUrl:u.resolvedUrl,resolutionStatus:"resolved"}:{...c,resolutionStatus:u.resolutionStatus})}}let d=r=>({...r,...s.get(r.rawUrl)??r}),l=r=>r.map(u=>{let c=d(u);return{...c,site:Ds(c,u.site)}});for(let r of e.flat){r.sources=l(r.sources??[]);let u=r.sources[0];r.source_title=u?.title??r.source_title,r.source_site=u?.site??r.source_site,r.source_cite=u?.url??r.source_cite}for(let r of n){r.sources=l(r.sources??[]);let u=r.sources[0];r.sourceTitle=u?.title??r.sourceTitle,r.sourceSite=u?.site??r.sourceSite,r.sourceCite=u?.url??r.sourceCite}for(let r=0;r<(e.organicResults?.length??0);r++){let u=d(e.organicResults[r]);e.organicResults[r]={...u,domain:Ds(u,e.organicResults[r].domain)??""}}let U=r=>{let u=d({url:r.href,rawUrl:r.rawUrl,resolvedUrl:r.resolvedUrl,linkType:r.linkType,resolutionStatus:r.resolutionStatus}),{url:c,...h}=u;return{...r,...h,href:c}};e.aiOverview&&(e.aiOverview.citations=(e.aiOverview.citations??[]).map(U)),e.aiMode&&(e.aiMode.citations=(e.aiMode.citations??[]).map(U));let S=[...s.values()];return e.diagnostics.links={linkCandidatesObserved:s.size,plainLinksObserved:S.filter(r=>r.linkType==="plain").length,googleUrlRedirectsObserved:S.filter(r=>r.linkType==="google_url_redirect").length,googleGotoRedirectsObserved:S.filter(r=>r.linkType==="google_goto_redirect").length,redirectsResolved:S.filter(r=>r.linkType!=="plain"&&r.resolutionStatus==="resolved").length,redirectsUnresolved:S.filter(r=>r.resolutionStatus==="unresolved").length,redirectsRejected:S.filter(r=>r.resolutionStatus==="rejected").length,resolverNonGoogleRequestsObserved:0,paaSourcesPreserved:e.flat.reduce((r,u)=>r+u.sources.length,0),aiOverviewLabelValidated:e.aiOverview?.detected??!1},e}async function Xs(e,t,n={}){let a=new Map;for(let u of t){let c=a.get(u.rawUrl);c&&Ba(c)||a.set(u.rawUrl,u.linkType==="google_goto_redirect"&&!Ba(u)?{...u,url:u.rawUrl,resolvedUrl:null,resolutionStatus:"unresolved"}:u)}let i=[...a.values()].filter(u=>u.linkType==="google_goto_redirect"&&!Ba(u));if(i.length===0)return a;let s=Date.now()+(n.totalBudgetMs??Ys),o=await Js(i.map(u=>u.rawUrl),n);for(let u of o.resolutions){let c=a.get(u.rawUrl);c&&a.set(u.rawUrl,u.resolutionStatus==="resolved"&&u.resolvedUrl?{...c,url:u.resolvedUrl,resolvedUrl:u.resolvedUrl,resolutionStatus:"resolved"}:{...c,resolutionStatus:u.resolutionStatus})}let d=i.filter(u=>a.get(u.rawUrl)?.resolutionStatus==="unresolved");if(d.length===0||n.browserFallback===!1||Date.now()>=s)return n.onNetworkAudit?.({nonGoogleRequestsObserved:0}),a;let l=n.timeoutMs??Vs,U=await e.context().newPage().catch(()=>null);if(!U)return n.onNetworkAudit?.({nonGoogleRequestsObserved:0}),a;let S=null,r=0;try{await U.route("**/*",async u=>{let c=u.request().url();try{Lt(new URL(c).hostname)||(r+=1)}catch{}let h=Da(c);if(!S||h!==S.token){await u.abort("blockedbyclient").catch(()=>{});return}let m=S;try{let f=await u.fetch({maxRedirects:0,timeout:m.timeoutMs});m.location=f.headers().location??null}finally{await u.abort("blockedbyclient").catch(()=>{}),m.finish()}});for(let u of d){let c=s-Date.now();if(c<=0)break;let h=Ze(u.rawUrl),m=h?.searchParams.get("url");if(!h||!m){a.set(u.rawUrl,{...u,resolutionStatus:"rejected"});continue}let f=Math.min(l,c);h.hash="";let M=h.href,y=!1;for(let A=0;A<2;A++){let O,B=new Promise(C=>{O=C}),b=`mcp-goto-${Math.random().toString(36).slice(2)}`;S={token:m,timeoutMs:f,location:null,finish:O},await U.evaluate(({url:C,id:E})=>{let w=document.createElement("iframe");w.id=E,w.hidden=!0,w.src=C,document.body.append(w)},{url:M,id:b}).catch(()=>null),await Promise.race([B,new Promise(C=>setTimeout(C,f))]);let N=S.location;if(S=null,await U.evaluate(C=>document.getElementById(C)?.remove(),b).catch(()=>null),!N)break;let W=Ks(u.rawUrl,N);if(W){a.set(u.rawUrl,{...u,url:W,resolvedUrl:W,resolutionStatus:"resolved"});break}let P;try{P=new URL(N,M)}catch{y=!0;break}if(!Lt(P.hostname)||Da(P.href)!==m){y=!0;break}M=P.href}y&&a.get(u.rawUrl)?.resolutionStatus!=="resolved"&&a.set(u.rawUrl,{...u,resolutionStatus:"rejected"})}}finally{S=null,await U.close().catch(()=>{}),n.onNetworkAudit?.({nonGoogleRequestsObserved:r})}return a}var js=String.raw`^(?:an error has occurred(?:[.!…]\s*)?(?:please try again later[.!…]?)?|loading|please wait|try again|something went wrong)[.!…\s]*$`,il=700,sl=1e3,ol=1400,zs=900,rl=3,$s=250,Bn=class{constructor(t,n,a,i){this.driver=t;this.reporter=n;this.onPaaProgress=a;this.onProviderSession=i}driver;reporter;onPaaProgress;onProviderSession;completeness={paaWithoutAnswer:0,paaWithoutSource:0,paaAnswersRecovered:0,aioShareCaptured:null};aioShareUrlEarly=null;linkDiagnostics=this.emptyLinkDiagnostics();collectedRows=[];partialContext=null;progressSequence=0;clickedQuestions=new Set;paaLifecycle=this.emptyPaaLifecycle(0);checkpointMaterial=null;interactionObservations=[];phaseTimings={};currentPhaseTimings(t){return{...this.phaseTimings,totalServerMs:Math.max(0,Date.now()-t)}}emptyPaaLifecycle(t){return{requestedQuestions:t,questionsFound:0,targetStatus:"not_met",discoveryStatus:"in_progress",materialStatus:"partial",completionReason:"PAA expansion is still running.",automaticRetries:0,retryBreakdown:{controlRetries:0,browserRetries:0,providerFallbacks:0,runtimeRecoveries:0,idempotentReplays:0},knownQuestions:0,processedQuestions:0,failedInteractions:0,noGrowthConfirmations:0,visibleControls:0,eligibleControls:0,dispatchedInteractions:0,confirmedInteractions:0,unconfirmedInteractions:0}}emptyLinkDiagnostics(){return{linkCandidatesObserved:0,plainLinksObserved:0,googleUrlRedirectsObserved:0,googleGotoRedirectsObserved:0,redirectsResolved:0,redirectsUnresolved:0,redirectsRejected:0,resolverNonGoogleRequestsObserved:0,paaSourcesPreserved:0,aiOverviewLabelValidated:!1}}mergePaaSources(t=[],n=[]){let a=new Map;for(let i of[...t,...n]){let s=a.get(i.rawUrl);if(!s){a.set(i.rawUrl,i);continue}let o=i.resolutionStatus==="resolved"&&s.resolutionStatus!=="resolved"?i:s;a.set(i.rawUrl,{...o,title:o.title??s.title??i.title,site:o.site??s.site??i.site})}return[...a.values()]}normalizeAICitations(t,n){let a=new Set;return n.flatMap(i=>{let s=Hn(i.rawHref??i.href,t);if(!s||a.has(s.rawUrl))return[];a.add(s.rawUrl);let{url:o,...d}=s;return[{...d,text:i.text,href:o}]})}async resolveMaterialLinks(t,n,a,i,s){let o=Date.now(),d=[...n.flatMap(h=>h.sources??[]),...a,...i.citations.map(({text:h,href:m,...f})=>({...f,url:m})),...s.citations.map(({text:h,href:m,...f})=>({...f,url:m}))],l=new Map(d.map(h=>[h.rawUrl,h])),U=0,S=await Xs(t,d,{onNetworkAudit:h=>{U=h.nonGoogleRequestsObserved}}),r=h=>({...h,...S.get(h.rawUrl)??h});for(let h of n){h.sources=(h.sources??[]).map(r);let m=h.sources[0];h.source_title=m?.title??h.source_title,h.source_site=m?.site??h.source_site,h.source_cite=m?.url??h.source_cite}for(let h=0;h<a.length;h++){let m=r(a[h]);if(m.resolvedUrl)try{m.domain=new URL(m.resolvedUrl).hostname.replace(/^www\./,"")}catch{}a[h]=m}let u=h=>{let m=r({url:h.href,rawUrl:h.rawUrl,resolvedUrl:h.resolvedUrl,linkType:h.linkType,resolutionStatus:h.resolutionStatus}),{url:f,...M}=m;return{...M,text:h.text,href:f}};i.citations=i.citations.map(u),s.citations=s.citations.map(u);let c=[...S.values()];this.linkDiagnostics={linkCandidatesObserved:l.size,plainLinksObserved:c.filter(h=>h.linkType==="plain").length,googleUrlRedirectsObserved:c.filter(h=>h.linkType==="google_url_redirect").length,googleGotoRedirectsObserved:c.filter(h=>h.linkType==="google_goto_redirect").length,redirectsResolved:c.filter(h=>h.linkType!=="plain"&&h.resolutionStatus==="resolved").length,redirectsUnresolved:c.filter(h=>h.resolutionStatus==="unresolved").length,redirectsRejected:c.filter(h=>h.resolutionStatus==="rejected").length,resolverNonGoogleRequestsObserved:U,paaSourcesPreserved:n.reduce((h,m)=>h+(m.sources??[]).length,0),aiOverviewLabelValidated:i.detected},this.phaseTimings.linkResolutionMs=(this.phaseTimings.linkResolutionMs??0)+(Date.now()-o)}normalizeQuestion(t){return t.toLowerCase().replace(/[^\w\s]/g,"").replace(/\s+/g," ").trim()}throwIfAborted(t){if(t?.aborted)throw t.reason instanceof DOMException&&t.reason.name==="TimeoutError"?t.reason:new gt}async throwIfCaptcha(t,n){if(await t.locator(Y.captchaMarker).count().catch(()=>0)>0)throw new at(`${n} returned a CAPTCHA \u2014 retrying with a fresh session.`)}async extractVisibleItems(t,n){let a=Y,i=await t.evaluate(({selectors:o,onlyQuestion:d,answerPlaceholderPattern:l})=>{function U(r){if(!r)return"";let u=[];for(let c of r.childNodes)if(c.nodeType===Node.TEXT_NODE){let h=c.textContent?.trim();h&&u.push(h)}else{if(c.tagName==="STYLE"||c.tagName==="SCRIPT")continue;{let h=U(c);h&&u.push(h)}}return u.join(" ").replace(/\s+/g," ").trim()}function S(r){return(r??"").replace(/\s*\(\+\d+\)\s*-\s*View related links.*$/i,"").replace(/\s*-\s*Opens in new tab.*$/i,"").trim()}return Array.from(document.querySelectorAll(o.item)).filter(r=>!d||(r.getAttribute(o.itemDataQ)||r.getAttribute(o.itemDataInitQ)||r.querySelector(o.itemQuestionEl)?.innerText?.trim()||"")===d).map(r=>{let u=r.querySelector(o.clickTarget),c=r.classList.contains(o.expandedClass)||u?.getAttribute("aria-expanded")==="true",h=r.querySelector(o.answerContainer),f=h?.querySelector(o.aiAnswerBody)??h,M=U(f),y=new RegExp(l,"i").test(M),A=[...Array.from((f??r).querySelectorAll("a[href]")),...Array.from(r.querySelectorAll(o.aiCitation)),...Array.from(r.querySelectorAll(o.aiSourceCard))],O=!y&&(c&&M.length>=10||M.length>30&&A.some(W=>/^https?:\/\//.test(W.href))),B=O&&r.querySelector(o.sourceTitle)?.innerText?.trim()||void 0,b=O&&r.querySelector(o.sourceSite)?.innerText?.trim()||void 0,N=[];if(O){let W=new Set;for(let C of A)!/^https?:\/\//.test(C.href)||W.has(C.href)||(W.add(C.href),N.push({title:S(C.getAttribute("aria-label"))||(C.textContent||"").trim(),rawHref:C.href}));let P=N.find(C=>C.title.length>2)??N[0];P&&(B=B||P.title||void 0)}return{googleLinkId:r.getAttribute("data-lk")||r.querySelector("[data-lk]")?.getAttribute("data-lk")||null,googleEvidenceId:r.getAttribute("data-ved")||r.querySelector("[data-ved]")?.getAttribute("data-ved")||null,question:r.getAttribute(o.itemDataQ)||r.getAttribute(o.itemDataInitQ)||r.querySelector(o.itemQuestionEl)?.innerText?.trim()||"",answer:O&&M||void 0,sourceTitle:B,sourceSite:b,sources:N}})},{selectors:a,onlyQuestion:n,answerPlaceholderPattern:js}),s=typeof t.url=="function"?t.url():"https://www.google.com/";return i.flatMap(o=>{let d=[],l=new Set;for(let u of o.sources){let c=Hn(u.rawHref,s);if(!c||l.has(c.rawUrl))continue;l.add(c.rawUrl);let h=o.sourceSite??null;try{h||=new URL(c.resolvedUrl??c.rawUrl).hostname.replace(/^www\./,"")}catch{}d.push({...c,title:u.title||o.sourceTitle||null,site:h})}let U=d[0],S={questionId:Zt(o.question),googleLinkId:o.googleLinkId,googleEvidenceId:o.googleEvidenceId,question:o.question,answer:Hs(o.answer,o.question,o.sourceTitle),sourceTitle:U?.title??o.sourceTitle,sourceSite:U?.site??o.sourceSite,sourceCite:U?.url,sources:d},r=Si.safeParse(S);return r.success?[r.data]:(console.warn("[PAAExtractor] item parse failed:",o.question,r.error.issues[0]?.message),[])})}jitteredDelayMs(t,n){return t+Math.floor(Math.random()*(n-t+1))}async clickItem(t,n){try{await t.locator(`${Y.item}[data-q="${n}"], ${Y.item}[data-initq="${n}"]`).first().click()}catch{}}toFlatRow(t,n,a,i){return{seed_query:i,question_id:t.questionId??Zt(t.question),google_link_id:t.googleLinkId??"",google_evidence_id:t.googleEvidenceId??"",question:t.question,answer:t.answer??"",source_title:t.sourceTitle??"",source_site:t.sourceSite??"",source_cite:t.sourceCite??"",sources:t.sources??[],depth:n,parent_question:a??"",extracted_at:new Date().toISOString()}}upsertCollectedRow(t){let n=this.normalizeQuestion(t.question),a=this.collectedRows.findIndex(d=>this.normalizeQuestion(d.question)===n);if(a<0)return this.collectedRows.push({...t}),!0;let i=this.collectedRows[a],s={...i,...t,answer:t.answer||i.answer,source_title:t.source_title||i.source_title,source_site:t.source_site||i.source_site,source_cite:t.source_cite||i.source_cite,sources:this.mergePaaSources(i.sources,t.sources),extracted_at:t.extracted_at||i.extracted_at},o=s.answer!==i.answer||s.source_title!==i.source_title||s.source_site!==i.source_site||s.source_cite!==i.source_cite||JSON.stringify(s.sources)!==JSON.stringify(i.sources);return o&&(this.collectedRows[a]=s),o}async emitProgress(t){if(!this.onPaaProgress||this.collectedRows.length===0&&!this.checkpointMaterial)return;let n={sequence:++this.progressSequence,observedAt:new Date().toISOString(),clickedQuestions:[...this.clickedQuestions],phase:t,records:this.collectedRows.map(a=>({...a})),lifecycle:{...this.paaLifecycle},...this.checkpointMaterial?{material:structuredClone(this.checkpointMaterial)}:{},interactions:this.interactionObservations.map(a=>({...a,confirmationSignals:[...a.confirmationSignals]}))};try{await this.onPaaProgress(n)}catch(a){console.warn(JSON.stringify({event:"paa_progress_sink_failed",sequence:n.sequence,phase:n.phase,message:a instanceof Error?a.message:String(a)}))}}getPartialResult(){let t=this.partialContext;if(!t||this.collectedRows.length===0&&!this.checkpointMaterial)return null;let n=this.collectedRows.map(d=>({...d})),a=this.checkpointMaterial,i=t.questionsOnly?0:n.filter(d=>!d.answer?.trim()).length,s=t.questionsOnly?0:n.filter(d=>(d.sources??[]).length===0).length,o={seed:t.seed,totalQuestions:n.length,maxDepthReached:n.reduce((d,l)=>Math.max(d,l.depth),0),durationMs:Date.now()-t.startMs,errorCount:0};return{seed:t.seed,location:t.location,extractedAt:new Date().toISOString(),diagnostics:{phaseTimings:this.currentPhaseTimings(t.startMs),completionStatus:"paa_found",problem:null,...a?.pagination?{pagination:{...a.pagination}}:{},resultQuality:"partial",degradedResult:!1,retryRecommended:!0,paaLifecycle:{...this.paaLifecycle,questionsFound:n.length,targetStatus:n.length>=(t.maxQuestions??0)?"met":"not_met",discoveryStatus:"interrupted",materialStatus:i>0||s>0?"partial":"complete",completionReason:"The browser attempt ended before frontier exhaustion could be proven."},completeness:{...this.completeness,paaWithoutAnswer:i,paaWithoutSource:s,paaRequested:t.maxQuestions,paaReturned:n.length,paaUnique:n.length},warnings:[{code:"paa_partial",surface:"paa",message:`Harvest stopped before finishing; returning the ${n.length} question(s) collected up to that point.`,retryable:!0}]},totalQuestions:n.length,surface:a?.surface??"web",aiOverview:a?.aiOverview??{detected:!1,text:null,citations:[]},aiMode:a?.aiMode??{detected:!1,text:null,citations:[]},whatPeopleSaying:a?.whatPeopleSaying??[],tree:this.buildTree(n,t.seed),flat:n,videos:a?.videos??[],forums:a?.forums??[],organicResults:a?.organicResults??[],localPack:a?.localPack??[],entityIds:a?.entityIds??{entities:[],kgIds:[],cids:[],gcids:[]},stats:o}}async runBFS(t,n,a){await t.waitForTimeout(700);let i=new Set,s=new Set,o=[];this.clickedQuestions=new Set,this.interactionObservations=[],this.phaseTimings={};let d=new Set,l=new Map,U=new Set,S=new Set,r=new Map,u=2,c=3,h=0,m={sel:Y.item,dataQ:Y.itemDataQ,dataInitQ:Y.itemDataInitQ,questionEl:Y.itemQuestionEl,answerSel:Y.answerContainer,expandedClass:Y.expandedClass,clickTarget:Y.clickTarget,answerPlaceholderPattern:js,questionsOnly:n.questionsOnly,sourceSel:"a[href]"},f=()=>t.evaluate(({sel:b,dataQ:N,dataInitQ:W,questionEl:P,expandedClass:C,clickTarget:E,answerSel:w,answerPlaceholderPattern:k,questionsOnly:v})=>{let I=R=>{if(!R)return"";let L=[];for(let x of R.childNodes){if(x.nodeType===Node.TEXT_NODE){let it=x.textContent?.trim();it&&L.push(it);continue}if(x.nodeType!==Node.ELEMENT_NODE)continue;let X=x;if(X.tagName==="STYLE"||X.tagName==="SCRIPT"||X.getAttribute("aria-hidden")==="true")continue;let ut=I(X);ut&&L.push(ut)}return L.join(" ").replace(/\s+/g," ").trim()};return Array.from(document.querySelectorAll(b)).map((R,L)=>{let x=I(R.querySelector(w)).replace(/An AI Overview is not available for this search/gi," ").replace(/Can't generate an AI overview right now\.?\s*Try again later\.?/gi," ").replace(/\bAI Overview\b/gi," ").replace(/\s+/g," ").trim(),X=R.classList.contains(C)||R.querySelector(E)?.getAttribute("aria-expanded")==="true",ut=x.length>=10&&!new RegExp(k,"i").test(x);return{q:R.getAttribute(N)||R.getAttribute(W)||R.querySelector(P)?.innerText?.trim()||"",done:X&&(v||ut),expanded:X,index:L}}).filter(R=>R.q)},m),M=async(b,N,W,P,C,E)=>{let w=Date.now(),k={id:`${E}:${Zt(b)}:${C}`,questionId:Zt(b),question:b,batchNumber:E,controlAttempt:C,observedAt:new Date(w).toISOString(),beforeQuestionCount:N,expandedBefore:P},v=W>=0?t.locator(m.sel).nth(W).locator(m.clickTarget):null,I=null,R=v?await(async()=>(P&&(await v.click({timeout:zs,force:!0}),await t.waitForTimeout(120)),await v.click({timeout:zs,force:!0}),!0))().catch(F=>(I=F instanceof Error&&(F.name==="TimeoutError"||/timeout/i.test(F.message))?"click_ack_timeout":"click_failed",!1)):!1,L=Date.now()-w;if(!R&&I!=="click_ack_timeout")return{dispatched:!1,confirmed:!1,observation:{...k,dispatched:!1,outcome:"dispatch_failed",confirmationSignals:[],confirmationCheckpointMs:null,confirmedAtMs:null,dispatchDurationMs:L,totalDurationMs:L,afterQuestionCount:N,newQuestionCount:0,expandedAfter:P,answerObserved:!1,sourceCount:0,errorCode:W<0?"control_missing":I??"click_failed"}};let x={exists:!0,expanded:P,answerReady:!1,sourceCount:0,questionCount:N},X=[],ut=null,it=null,J=!1;for(let F of[il,sl,ol]){let yt=w+F-Date.now();if(yt>0&&await t.waitForTimeout(yt),x=await t.evaluate(({sel:G,dataQ:tt,dataInitQ:q,questionEl:$,expandedClass:pt,clickTarget:Ct,answerSel:sn,answerPlaceholderPattern:ae,sourceSel:on,target:We})=>{let rn=se=>{if(!se)return"";let $n=[];for(let ln of se.childNodes){if(ln.nodeType===Node.TEXT_NODE){let di=ln.textContent?.trim();di&&$n.push(di);continue}if(ln.nodeType!==Node.ELEMENT_NODE)continue;let Sn=ln;if(Sn.tagName==="STYLE"||Sn.tagName==="SCRIPT"||Sn.getAttribute("aria-hidden")==="true")continue;let ri=rn(Sn);ri&&$n.push(ri)}return $n.join(" ").replace(/\s+/g," ").trim()},ie=Array.from(document.querySelectorAll(G)),dn=ie.find(se=>(se.getAttribute(tt)||se.getAttribute(q)||se.querySelector($)?.innerText?.trim())===We);if(!dn)return{exists:!1,expanded:!1,answerReady:!1,sourceCount:0,questionCount:ie.length};let Io=dn.classList.contains(pt)||dn.querySelector(Ct)?.getAttribute("aria-expanded")==="true",ii=dn.querySelector(sn),si=rn(ii).replace(/An AI Overview is not available for this search/gi," ").replace(/Can't generate an AI overview right now\.?\s*Try again later\.?/gi," ").replace(/\bAI Overview\b/gi," ").replace(/\s+/g," ").trim(),oi=si.length>=10&&!new RegExp(ae,"i").test(si);return{exists:!0,expanded:Io,answerReady:oi,sourceCount:oi?ii?.querySelectorAll(on).length??0:0,questionCount:ie.length}},{...m,target:b}).catch(()=>x),X=[...x.expanded?["expanded"]:[],...x.answerReady?["answer"]:[],...x.sourceCount>0?["source"]:[],...x.questionCount>N?["question_growth"]:[]],x.answerReady||x.sourceCount>0||x.questionCount>N){J=!0,ut=F,it=Date.now()-w;break}}let ct=Date.now()-w,Re={...k,dispatched:R,outcome:J?"confirmed":R?"unconfirmed":"dispatch_failed",confirmationSignals:X,confirmationCheckpointMs:ut,confirmedAtMs:it,dispatchDurationMs:L,totalDurationMs:ct,afterQuestionCount:x.questionCount,newQuestionCount:Math.max(0,x.questionCount-N),expandedAfter:x.expanded,answerObserved:x.answerReady,sourceCount:x.sourceCount,errorCode:R?J?null:x.exists?"confirmation_timeout":"control_missing":I};return{dispatched:R,confirmed:J,observation:Re}},y=0;t:for(;;){if(n.softDeadlineMs&&Date.now()>=n.softDeadlineMs)throw this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"interrupted",completionReason:"The execution deadline arrived before frontier exhaustion could be proven."},new zt(this.paaLifecycle.completionReason);this.throwIfAborted(a);let b=await f(),N=!1;for(let w of b)s.has(w.q)||(s.add(w.q),o.push(w.q),o.length<=n.maxQuestions&&(N=this.upsertCollectedRow(this.toFlatRow({questionId:Zt(w.q),googleLinkId:null,googleEvidenceId:null,question:w.q,sources:[]},1,null,n.query))||N)),w.done&&U.add(w.q);if(this.paaLifecycle={...this.paaLifecycle,questionsFound:Math.min(o.length,n.maxQuestions),targetStatus:o.length>=n.maxQuestions?"met":"not_met",knownQuestions:o.length,processedQuestions:U.size,failedInteractions:S.size,visibleControls:b.length},N&&await this.emitProgress("discovered"),n.questionsOnly&&s.size>=n.maxQuestions){this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"target_reached",targetStatus:"met",completionReason:"The requested unique-question count was observed."};break}if(!n.questionsOnly&&s.size>=n.maxQuestions){let w=!1,k=new Set(o.slice(0,n.maxQuestions));for(let v of await this.extractVisibleItems(t)){if(!k.has(v.question))continue;let I=r.get(v.question),R={...v,answer:v.answer??I?.answer,sourceTitle:v.sourceTitle??I?.sourceTitle,sourceSite:v.sourceSite??I?.sourceSite,sourceCite:v.sourceCite??I?.sourceCite,sources:this.mergePaaSources(I?.sources,v.sources)};r.set(v.question,R),w=this.upsertCollectedRow(this.toFlatRow(R,1,null,n.query))||w}if(w&&await this.emitProgress("answer_captured"),[...k].every(v=>{let I=r.get(v);return!!(I?.answer?.trim()&&I.sources.length>0)})){S.clear(),this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"target_reached",targetStatus:"met",failedInteractions:0,completionReason:"The requested unique-question count and its answer/source material were observed."};break}}let W=new Set(o.slice(0,n.maxQuestions)),P=b.filter(w=>W.has(w.q)&&!w.done&&(l.get(w.q)??0)<u&&!d.has(w.q)),C=P.slice(-rl);if(this.paaLifecycle={...this.paaLifecycle,eligibleControls:P.length},C.length===0){if(s.size>=n.maxQuestions){this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"target_reached",targetStatus:"met",completionReason:"The requested unique-question count was observed."};break}let w=new Set(b.map(v=>v.q)),k=o.slice(0,n.maxQuestions).filter(v=>!U.has(v)&&(S.has(v)||!w.has(v)));if(k.length>0)throw this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"interrupted",failedInteractions:new Set([...S,...k]).size,completionReason:"At least one known PAA control failed or disappeared before it could be confirmed."},await this.emitProgress("expansion_finished"),new zt(this.paaLifecycle.completionReason);for(let v=1;v<=c;v++){this.throwIfAborted(a),await this.throwIfCaptcha(t,"Google PAA exhaustion confirmation"),await t.mouse.wheel(0,320);let I=await t.waitForFunction(({sel:L,min:x})=>document.querySelectorAll(L).length>x,{sel:Y.item,min:b.length},{timeout:1500,polling:100}).catch(()=>null);if(this.paaLifecycle={...this.paaLifecycle,noGrowthConfirmations:v},I||(await f()).some(L=>!s.has(L.q)))continue t}this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"frontier_exhausted",targetStatus:"not_met",failedInteractions:0,noGrowthConfirmations:c,completionReason:"Every known eligible PAA control was processed and three healthy no-growth confirmations found no additional questions."};break}await this.throwIfCaptcha(t,"Google PAA expansion"),h+=1;for(let w of C){if(this.reporter.onDepth(++y),(l.get(w.q)??0)>0){let k=this.paaLifecycle.retryBreakdown.controlRetries+1;this.paaLifecycle={...this.paaLifecycle,automaticRetries:k+this.paaLifecycle.retryBreakdown.browserRetries+this.paaLifecycle.retryBreakdown.runtimeRecoveries,retryBreakdown:{...this.paaLifecycle.retryBreakdown,controlRetries:k}}}l.set(w.q,(l.get(w.q)??0)+1)}let E=await Promise.all(C.map(async w=>({target:w,result:await M(w.q,b.length,w.index,w.expanded,l.get(w.q)??1,h)})));for(let{target:w,result:k}of E)(k.dispatched||k.confirmed)&&this.clickedQuestions.add(w.q),this.interactionObservations.push(k.observation);if(this.interactionObservations.length>$s&&this.interactionObservations.splice(0,this.interactionObservations.length-$s),!n.questionsOnly){let w=new Set(C.map(k=>k.q));for(let k of await this.extractVisibleItems(t))w.has(k.question)&&(r.set(k.question,k),this.upsertCollectedRow(this.toFlatRow(k,1,null,n.query))&&await this.emitProgress("answer_captured"))}for(let{target:w,result:k}of E){let v=r.get(w.q);k.confirmed||v?.answer?.trim()?(U.add(w.q),S.delete(w.q)):(l.get(w.q)??0)>=u&&(S.add(w.q),d.add(w.q))}this.paaLifecycle={...this.paaLifecycle,processedQuestions:U.size,failedInteractions:S.size,noGrowthConfirmations:0,dispatchedInteractions:this.interactionObservations.filter(w=>w.dispatched).length,confirmedInteractions:this.interactionObservations.filter(w=>w.outcome==="confirmed").length,unconfirmedInteractions:this.interactionObservations.filter(w=>w.outcome!=="confirmed").length},await this.emitProgress("click_observed")}let A=n.questionsOnly?new Map:new Map(r);n.questionsOnly||await this.fillIncompleteItems(t,o,A,n,d);let O=[];for(let b of o){if(O.length>=n.maxQuestions)break;let N=this.normalizeQuestion(b);if(i.has(N))continue;i.add(N);let W=A.get(b);if(W){let P=this.toFlatRow(W,1,null,n.query);this.upsertCollectedRow(P),O.push(P),this.reporter.onQuestion({questionId:W.questionId,googleLinkId:W.googleLinkId,googleEvidenceId:W.googleEvidenceId,question:W.question,answer:W.answer??null,sourceTitle:W.sourceTitle??null,sourceSite:W.sourceSite??null,sourceCite:W.sourceCite??null,sources:W.sources,depth:1,parentQuestion:null,children:[]})}else{let P=this.toFlatRow({questionId:Zt(b),googleLinkId:null,googleEvidenceId:null,question:b,answer:void 0,sourceTitle:void 0,sourceSite:void 0,sourceCite:void 0,sources:[]},1,null,n.query);this.upsertCollectedRow(P),O.push(P)}}this.completeness.paaWithoutAnswer=n.questionsOnly?0:O.filter(b=>!b.answer).length,this.completeness.paaWithoutSource=n.questionsOnly?0:O.filter(b=>(b.sources??[]).length===0).length,this.completeness.paaRequested=n.maxQuestions,this.completeness.paaReturned=O.length,this.completeness.paaUnique=i.size;let B=!n.questionsOnly&&(this.completeness.paaWithoutAnswer>0||this.completeness.paaWithoutSource>0);return this.paaLifecycle={...this.paaLifecycle,questionsFound:O.length,targetStatus:O.length>=n.maxQuestions?"met":"not_met",materialStatus:B?"partial":"complete",processedQuestions:U.size,failedInteractions:S.size},await this.emitProgress("fill_incomplete"),await this.emitProgress("expansion_finished"),O}async fillIncompleteItems(t,n,a,i,s){let o=new Set(n.slice(0,i.maxQuestions)),d=S=>!S?.answer||(S.sources??[]).length===0,l=new Set([...o].filter(S=>d(a.get(S)))),U=new Set([...l].filter(S=>!a.get(S)?.answer));if(l.size!==0){for(let S of l){if(i.softDeadlineMs&&Date.now()>=i.softDeadlineMs)break;let r=(await this.extractVisibleItems(t,S))[0];if(!r)continue;let u=a.get(S);a.set(S,{...r,answer:r.answer??u?.answer,sourceTitle:r.sourceTitle??u?.sourceTitle,sourceSite:r.sourceSite??u?.sourceSite,sourceCite:r.sourceCite??u?.sourceCite,sources:this.mergePaaSources(u?.sources,r.sources)});let c=a.get(S);c&&this.upsertCollectedRow(this.toFlatRow(c,1,null,i.query))&&await this.emitProgress("fill_incomplete")}this.completeness.paaAnswersRecovered=[...U].filter(S=>a.get(S)?.answer).length}}async reExpandCollapsedItems(t){let n=`${Y.item}:not(.${Y.expandedClass}) ${Y.clickTarget}`,a=await t.locator(n).count().catch(()=>0);if(a===0)return!1;for(let i=0;i<a;i++)try{let s=t.locator(n).first();await s.scrollIntoViewIfNeeded(),await s.click({force:!0}),await t.waitForTimeout(this.jitteredDelayMs(300,500))}catch{}return!0}async extractVideos(t){let n=Qi;return t.evaluate(a=>{let i=[],s=Array.from(document.querySelectorAll(a.container));for(let o of s){let U=(o.querySelector(a.sectionHeading)?.textContent?.trim()??"").toLowerCase().includes("short")?"short_video":"video",S=Array.from(o.querySelectorAll(a.item));for(let r of S){let u=r.href;if(!u||!u.includes("youtube")&&!u.includes("youtu.be"))continue;let c=r.textContent?.trim()??"",h=c.indexOf("YouTube");if(h===-1)continue;let m=c.slice(0,h).trim(),M=c.slice(h+7).replace(/^[·\s·]+/,"").match(/^([^·\n]+)/),y=M?M[1].trim():"";m&&i.push({type:U,title:m,channel:y,platform:"YouTube",duration:"",url:u})}}return i},n)}async extractForums(t){let n=Zi;return t.evaluate(a=>{let i=[],o=Array.from(document.querySelectorAll(a.section)).find(l=>l.textContent?.includes("Discussions"));if(!o)return i;let d=Array.from(o.querySelectorAll(a.item));for(let l of d){let U=l.href;if(!U)continue;let S=l.querySelector(a.title),r=l.querySelector(a.source),u=S?.textContent?.trim()??"",c=r?.textContent?.trim()??"";u&&i.push({title:u,source:c,url:U})}return i},n)}async extractShortVideos(t,n){try{await t.goto(n,{waitUntil:"domcontentloaded"}),await t.waitForTimeout(1500)}catch{return[]}await this.throwIfCaptcha(t,"Google short video search");let a={item:vn.item,platforms:[...vn.platforms]};return(await t.evaluate(s=>{let o=new Set,d=[],l=Array.from(document.querySelectorAll(s.item)),U=["youtube.com","youtu.be","tiktok.com","instagram.com","facebook.com","fb.watch"],S=new Map;for(let r of l){let u=r.href;if(!u||!U.some(h=>u.includes(h)))continue;let c=r.textContent?.trim()??"";S.has(u)||S.set(u,[]),S.get(u).push(c)}for(let[r,u]of S.entries()){if(o.has(r))continue;o.add(r);let c=u.find(y=>/^\d+:\d+$/.test(y))??"",h=u.find(y=>!/^\d+:\d+$/.test(y)&&y.length>5)??"";if(!h)continue;let m=h,f="",M="";for(let y of s.platforms){let A=-1,O=0;for(;;){let P=h.indexOf(y,O);if(P===-1)break;A=P,O=P+1}if(A===-1)continue;let B=h.slice(A+y.length);if(!(/^[\s·]/.test(B)||B.trim()===""))continue;m=h.slice(0,A).trim(),f=y;let N=B.replace(/^[\s·]+/,""),W=N.indexOf("\xB7");M=(W===-1?N:N.slice(0,W)).trim();break}m&&d.push({title:m,channel:M,platform:f,duration:c,url:r})}return d},a)).map(s=>({type:"short_video",...s}))}async extractWhatPeopleSaying(t){let n=ts;return t.evaluate(a=>{let i=Array.from(document.querySelectorAll(a.sectionTag)).find(s=>s.textContent?.includes(a.sectionHeadingText))??document.querySelector(".yG4QQe.TBC9ub.NbhJ1c");return i?Array.from(i.querySelectorAll(a.card)).map(s=>{let d=s.querySelector(a.cardLink)?.href??"",l=s.querySelector(a.titleH1)?.textContent?.trim(),U=s.querySelector(a.titleDiv)?.textContent?.trim(),S=l??U??"",r=s.querySelector(a.source)?.textContent?.trim()??"",c=s.querySelector(a.platformBadge)?.textContent?.trim()??"",h=s.querySelector(a.ytChannel)?.textContent?.trim()??"",m=s.querySelector(a.ytDate)?.textContent?.trim()??"",f=s.querySelector(a.authorNote)?.textContent?.trim()??null,M=s.querySelector(a.popularCommentLabel),y=null;if(M){let I=M.nextSibling;for(;I;){let R=I.textContent?.trim();if(R){y=R;break}I=I.nextSibling}}let A=Array.from(s.querySelectorAll("span")),O=A.find(I=>/^\d+:\d+$/.test(I.textContent?.trim()??""))?.textContent?.trim()??null,b=A.map(I=>I.textContent?.trim()??"").filter(I=>/\d/.test(I)&&(I.includes("comment")||I.includes("reaction")||I.includes("view")||I.includes("like")||I.includes("share")))[0]??"",N=A.map(I=>I.textContent?.trim()??"").filter(I=>/\d+ (day|week|month|year|hour)s? ago|Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec/.test(I)),W=m||(N[0]??""),P=c||(h?"YouTube":""),C=h||r,E="unknown",w=P.toLowerCase(),k=C.toLowerCase(),v=r.toLowerCase();return w.includes("reddit")||k.startsWith("r/")?E="reddit":w.includes("facebook")||v.includes("facebook")?E="facebook":w.includes("instagram")||v.includes("instagram")?E="instagram":w.includes("tiktok")||v.includes("tiktok")?E="tiktok":w.includes("youtube")||h?E="youtube":E="news",{type:E,title:S,url:d,source:C,platform:P,popularComment:y,engagement:b,date:W,duration:O,authorNote:f}}):[]},n)}async extractOrganicResults(t){let n=as,a=await t.evaluate(s=>{let o=[],d=0;return document.querySelectorAll(s.result).forEach(l=>{let U=l.querySelector(s.title);if(!U)return;let S=U.textContent?.trim()??"",u=U.closest("a")?.href??"";if(!S||!u)return;d++;let c=l.querySelector(s.cite)?.textContent?.trim()??null,h=l.querySelector(s.snippet)?.textContent?.trim()??null,m=!!l.querySelector(s.redditCite),f=l.querySelector(s.ratingWrap),M=f?{value:f.querySelector(s.ratingValue)?.textContent?.trim()??"",count:f.querySelector(s.reviewCount)?.textContent?.trim()??""}:null,y="";try{y=new URL(u).hostname.replace(/^www\./,"")}catch{y=l.querySelector(s.siteName)?.textContent?.trim()??""}o.push({position:d,title:S,url:u,domain:y,cite:c,snippet:h,isRedditStyle:m,inlineRating:M})}),o},n),i=typeof t.url=="function"?t.url():"https://www.google.com/";return a.flatMap(s=>{let o=Hn(s.url,i);if(!o)return[];let d=s.domain;try{d=new URL(o.resolvedUrl??o.rawUrl).hostname.replace(/^www\./,"")}catch{}return[{...s,...o,domain:d}]})}async extractLocalPack(t){let n=is;return t.evaluate(a=>{let i=[],s=null;return document.querySelectorAll('[role="heading"]').forEach(o=>{!s&&o.textContent?.includes(a.headingText)&&(s=o.closest("[data-hveid]"))}),s&&s.querySelectorAll(a.card).forEach((o,d)=>{let l=o.querySelector(a.name)?.textContent?.trim()??"";if(!l)return;let U=o.querySelector(a.ratingValue)?.textContent?.trim()??null,S=o.querySelector(a.reviewCount)?.textContent?.trim()??null,r=S?S.replace(/[()]/g,"").trim():null,u=o.querySelector("a[data-cid]")?.getAttribute("data-cid")??null;if(!u)for(let M of Array.from(o.querySelectorAll("a[href]"))){let y=M.href.match(/[?&]cid=(\d+)/);if(y){u=y[1];break}let A=M.href.match(/!1s0x[0-9a-f]+:0x([0-9a-f]+)/i);if(A){try{u=BigInt("0x"+A[1]).toString()}catch{}if(u)break}}let c=[];o.querySelectorAll("div, span").forEach(M=>{let y=Array.from(M.childNodes).filter(A=>A.nodeType===3).map(A=>A.textContent?.trim()??"").filter(A=>A.length>1&&A.length<120).join(" ");y&&!c.includes(y)&&c.push(y)});let h=Array.from(o.querySelectorAll("a[href]")),m=h.find(M=>M.href.includes("google.com/maps"))?.href??null,f=h.find(M=>!M.href.includes("google.com")&&M.href.startsWith("http"))?.href??null;i.push({position:d+1,name:l,cid:u,rating:U,reviewCount:r,metadata:c,websiteUrl:f,directionsUrl:m})}),i},n)}async extractEntityIds(t){return t.evaluate(()=>{let n=new Set,a=new Set,i=new Set,s=new Map;function o(l){let U=[".OSrXXb",".dbg0pd",".tzt0oe",'[role="heading"]',"h3"];for(let S of U){let r=l.querySelector(S);if(r?.textContent?.trim())return r.textContent.trim()}return""}document.querySelectorAll('[id^="pv-/g/"]').forEach(l=>{let U=l.getAttribute("id");if(!U)return;let S=U.replace("pv-","");n.add(S);let r=o(l),c=l.querySelector("a[data-cid]")?.getAttribute("data-cid")??null;c&&a.add(c),r&&s.set(S,{name:r,kgId:S,cid:c,gcid:null})}),document.querySelectorAll("[data-mid]").forEach(l=>{let U=l.getAttribute("data-mid");if(U?.startsWith("/g/")&&(n.add(U),!s.has(U))){let S=o(l);S&&s.set(U,{name:S,kgId:U,cid:null,gcid:null})}}),document.querySelectorAll(".w7Dbne").forEach(l=>{let S=l.querySelector("a[data-cid]")?.getAttribute("data-cid")??null;if(!S)return;a.add(S);let r=l.querySelector(".OSrXXb")?.textContent?.trim()??"";if(!r)return;let u=l.querySelector('[id^="pv-/g/"]'),c=u?u.getAttribute("id").replace("pv-",""):null,h=c??`cid:${S}`;if(s.has(h)){let m=s.get(h);m.cid||s.set(h,{...m,cid:S})}else s.set(h,{name:r,kgId:c,cid:S,gcid:null})}),document.querySelectorAll("a[data-cid]").forEach(l=>{let U=l.getAttribute("data-cid");if(!U)return;if(a.add(U),![...s.values()].some(r=>r.cid===U)){let r=l.parentElement,u="";for(let c=0;c<8&&r;c++){let h=r.querySelector('.OSrXXb, .dbg0pd, [role="heading"], h3');if(h?.textContent?.trim()){u=h.textContent.trim();break}r=r.parentElement}u&&s.set(`cid:${U}`,{name:u,kgId:null,cid:U,gcid:null})}});let d=Array.from(document.querySelectorAll("script:not([src])")).map(l=>l.textContent??"").filter(l=>l.length>1e4).join(`
|
|
21896
|
-
`);for(let l of d.matchAll(/\/g\/[a-zA-Z0-9_-]{5,20}/g))n.add(l[0]);for(let l of d.matchAll(/gcid:[a-zA-Z0-9_]+/g))i.add(l[0]);for(let l of d.matchAll(/0x[0-9a-f]+:0x([0-9a-f]+)/gi))try{a.add(BigInt("0x"+l[1]).toString())}catch{}return{entities:[...s.values()],kgIds:[...n],cids:[...a],gcids:[...i]}})}mergeLocalPackIntoEntities(t,n){let a=new Set(t.cids),i=t.entities.map(s=>({...s}));for(let s of n){if(!s.cid)continue;a.add(s.cid);let o=s.name.toLowerCase().trim(),d=i.find(l=>l.name.toLowerCase().trim()===o);d?d.cid||(d.cid=s.cid):i.find(l=>l.cid===s.cid)||i.push({name:s.name,kgId:null,cid:s.cid,gcid:null})}return{...t,entities:i,cids:[...a]}}async extractAISurfaces(t,n){let a=await t.evaluate(Bs,{aio:es,aim:ns,expandWaitMs:1500}),i=typeof t.url=="function"?t.url():"https://www.google.com/",s={surface:a.surface,aiOverview:{...a.aiOverview,citations:this.normalizeAICitations(i,a.aiOverview.citations)},aiMode:{...a.aiMode,citations:this.normalizeAICitations(i,a.aiMode.citations)}};if(!s.aiOverview.detected)return this.completeness.aioShareCaptured=null,s;let o=this.aioShareUrlEarly??await this.captureAIOverviewShareUrl(t,n).catch(()=>null);return this.completeness.aioShareCaptured=o!==null,{...s,aiOverview:{...s.aiOverview,shareUrl:o}}}async captureAIOverviewShareUrl(t,n){if(n?.softDeadlineMs&&Date.now()>=n.softDeadlineMs||!await t.evaluate(()=>{let s=Array.from(document.querySelectorAll('h1,h2,h3,[role="heading"],div')).filter(o=>(o.textContent||"").trim()==="AI Overview");for(let o of s){let d=o;for(let l=0;l<8&&d;l++){let U=d.querySelector('[aria-label="Share"]');if(U)return U.scrollIntoView({block:"center"}),U.click(),!0;d=d.parentElement}}return!1}).catch(()=>!1))return null;let i=null;try{i=await(await t.waitForFunction(()=>{let o=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT);for(;o.nextNode();){let d=(o.currentNode.textContent||"").match(/https:\/\/share\.google\/aimode\/\S+/);if(d)return d[0]}return!1},void 0,{timeout:4500,polling:250})).jsonValue()}catch{i=null}return await t.keyboard.press("Escape").catch(()=>{}),i}buildTree(t,n){let a=[],i=new Map;for(let s of t){let o={questionId:s.question_id,googleLinkId:s.google_link_id||null,googleEvidenceId:s.google_evidence_id||null,question:s.question,answer:s.answer||null,sourceTitle:s.source_title||null,sourceSite:s.source_site||null,sourceCite:s.source_cite||null,sources:s.sources??[],depth:s.depth,parentQuestion:s.parent_question||null,children:[]};i.set(s.question,o)}for(let s of i.values())s.parentQuestion&&i.has(s.parentQuestion)?i.get(s.parentQuestion).children.push(s):a.push(s);return a}getBrowserDebugSnapshot(){return this.driver.getDebugSnapshot()}buildHarvestDebugSnapshot(t,n,a,i,s){if(t.debug)return{enabled:!0,request:{query:t.query,locationInput:t.location??null,canonicalLocation:n,locationResolved:s?s.matched:null,locationMatchSource:s?s.source:null,locationAmbiguousCandidates:s?s.ambiguousCandidates:null,uule:a,gl:t.gl,hl:t.hl,device:t.device,proxyMode:t.proxyMode,proxyZip:t.proxyZip??null,serpIdentity:t.serpIdentity??null,serpOnly:t.serpOnly,pages:t.pages??1},browser:this.getBrowserDebugSnapshot(),...i?{locationEvidence:i}:{}}}async captureSecondOrganicPage(t,n,a){if(this.throwIfAborted(a),!this.driver.withTemporaryPage)return{organic:[],status:"failed",failureCode:"unsupported_driver"};let i;try{let s=new URL(t.url()),o=U=>{try{let S=new URL(U,s);return s.origin==="https://www.google.com"&&S.origin===s.origin&&!S.username&&!S.password&&S.pathname==="/search"&&S.searchParams.getAll("q").length===1&&S.searchParams.get("q")===n.query&&S.searchParams.getAll("start").length===1&&S.searchParams.get("start")==="10"&&(!S.searchParams.has("num")||S.searchParams.get("num")==="10")&&["gl","hl"].every(r=>!S.searchParams.has(r)||S.searchParams.getAll(r).length===1&&S.searchParams.get(r)===n[r])&&["uule","tbs","udm","tbm","pws"].every(r=>S.searchParams.getAll(r).length<=1&&S.searchParams.get(r)===s.searchParams.get(r))}catch{return!1}},d=await t.evaluate(()=>document.querySelector('a#pnnext, a[rel="next"]')?.getAttribute("href")??null);if(!d)return{organic:[],status:"unavailable",failureCode:"missing_next"};if(!o(d))return{organic:[],status:"unavailable",failureCode:"invalid_next"};let l=await this.driver.withTemporaryPage(async U=>{if(await U.route("**/*",async S=>{let r=S.request();r.isNavigationRequest()&&r.frame()===U.mainFrame()&&!o(r.url())?(i=/^https:\/\/www\.google\.com\/sorry(?:\/|\?)/.test(r.url())?"captcha":"invalid_next",await S.abort("blockedbyclient")):await S.fallback()}),await U.goto(new URL(d,s).href,{waitUntil:"domcontentloaded",timeout:2e4}),this.throwIfAborted(a),await this.throwIfCaptcha(U,"Google SERP page 2"),!o(U.url()))throw i="invalid_next",new Error("Invalid pagination landing");return this.extractOrganicResults(U)},a);return this.throwIfAborted(a),l.length>0?{organic:l.map(U=>({...U,position:U.position+10})),status:"captured"}:{organic:[],status:"unavailable",failureCode:"empty_page"}}catch(s){if(this.throwIfAborted(a),s instanceof gt)throw s;return{organic:[],status:"failed",failureCode:i??(s instanceof at?"captcha":s instanceof Error&&(s.name==="TimeoutError"||/timed? ?out/i.test(s.message))?"timeout":"navigation_error")}}}async extract(t,n){let a=Date.now();this.completeness={paaWithoutAnswer:0,paaWithoutSource:0,paaAnswersRecovered:0,aioShareCaptured:null},this.linkDiagnostics=this.emptyLinkDiagnostics(),this.aioShareUrlEarly=null,this.collectedRows=[],this.progressSequence=0,this.checkpointMaterial=null,this.clickedQuestions=new Set,this.paaLifecycle=this.emptyPaaLifecycle(t.maxQuestions),this.partialContext={seed:t.query,location:t.location??null,startMs:a,maxQuestions:t.maxQuestions,questionsOnly:t.questionsOnly};let i=t.device==="mobile",s={headless:t.headless,profileDir:t.profileDir,proxy:t.proxy,\u006b\u0065\u0072\u006e\u0065\u006cApiKey:t.\u006b\u0065\u0072\u006e\u0065\u006cApiKey,\u006b\u0065\u0072\u006e\u0065\u006cProxyId:t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId,\u006b\u0065\u0072\u006e\u0065\u006cProfileName:t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName,\u006b\u0065\u0072\u006e\u0065\u006cProfileSaveChanges:t.\u006b\u0065\u0072\u006e\u0065\u006cProfileSaveChanges,\u006b\u0065\u0072\u006e\u0065\u006cStealth:t.\u006b\u0065\u0072\u006e\u0065\u006cStealth,\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution:t.\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution,proxyMode:t.proxyMode,keepDefaultProxy:t.keepDefaultProxy,requireUsEgress:t.requireUsEgress,viewport:i?{width:390,height:844}:{width:1280,height:800},locale:`${t.hl}-${t.gl.toUpperCase()}`,deviceScaleFactor:i?3:1,isMobile:i,hasTouch:i,debug:t.debug,operationDeadlineMs:t.softDeadlineMs},o=0,d=[];try{this.throwIfAborted(n);let l=Date.now();await this.driver.launch(s),this.phaseTimings.providerConnectMs=Date.now()-l;let U=this.driver.getProviderSessionMetadata();if(U?.providerSessionId&&this.onProviderSession)try{await this.onProviderSession(U)}catch(G){console.warn(JSON.stringify({event:"paa_provider_session_sink_failed",provider:U.provider,message:G instanceof Error?G.message:String(G)}))}this.throwIfAborted(n);let S=t.location?Wa(t.location):null,r=t.location?S?.canonical??t.location:null,u=r?Ls(r):null,c=t,h=t.includeAllSerpFeatures,m=h||t.includeLocalPack,f=h||t.includeForums,M=h||t.includeVideos,y=h||t.includeAiOverview,A=h||t.includeWhatPeopleSaying,O={surface:"web",aiOverview:{detected:!1,text:null,citations:[]},aiMode:{detected:!1,text:null,citations:[]}},B=Date.now(),{hasPaa:b}=await this.driver.navigateToSERP(c.query,u,t.gl,t.hl,{...He(t.recency)?{tbs:He(t.recency)}:{},debug:t.debug,purpose:t.serpOnly?"serp":"paa",...t.softDeadlineMs?{deadlineMs:t.softDeadlineMs}:{}});this.phaseTimings.navigationMs=Date.now()-B,this.throwIfAborted(n);let N=this.driver.getPage();if(await this.throwIfCaptcha(N,"Google SERP"),b||(this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"no_paa_observed",materialStatus:"complete",completionReason:"A readable Google SERP was observed without a People Also Ask block."}),t.questionsOnly){let G=Date.now(),tt=b?await this.runBFS(N,c,n):[];this.phaseTimings.paaExpansionMs=Date.now()-G,await this.resolveMaterialLinks(N,tt,[],O.aiOverview,O.aiMode);let q={seed:c.query,totalQuestions:tt.length,maxDepthReached:tt.reduce(($,pt)=>Math.max($,pt.depth),0),durationMs:Date.now()-a,errorCount:o};return this.reporter.onComplete(q),{seed:c.query,location:t.location??null,extractedAt:new Date().toISOString(),diagnostics:{phaseTimings:this.currentPhaseTimings(a),completionStatus:b?"paa_found":"no_paa",...b?{}:{noPaaObserved:!0},problem:null,paaLifecycle:{...this.paaLifecycle},completeness:{...this.completeness},links:{...this.linkDiagnostics},...t.debug?{debug:this.buildHarvestDebugSnapshot(c,r,u,void 0,S)}:{}},totalQuestions:tt.length,surface:"web",aiOverview:{detected:!1,text:null,citations:[]},aiMode:{detected:!1,text:null,citations:[]},whatPeopleSaying:[],tree:this.buildTree(tt,c.query),flat:tt,videos:[],forums:[],organicResults:[],localPack:[],entityIds:{entities:[],kgIds:[],cids:[],gcids:[]},stats:q}}if(y&&(this.aioShareUrlEarly=await this.captureAIOverviewShareUrl(N,t).catch(()=>null)),t.serpOnly){let G=Date.now(),[tt,q,$]=await Promise.all([this.extractOrganicResults(N),m?this.extractLocalPack(N):Promise.resolve([]),this.extractEntityIds(N)]),pt=this.mergeLocalPackIntoEntities($,q),Ct=y?await this.extractAISurfaces(N,t):O;this.phaseTimings.serpParseMs=Date.now()-G;let sn=t.debug?Qe(r,tt,q):void 0,ae=tt;if((t.pages??1)>=2){let We=new URLSearchParams({q:c.query,gl:t.gl,hl:t.hl,pws:"0",start:"10"});He(t.recency)&&We.set("tbs",He(t.recency)),u&&We.set("uule",u),await this.driver.navigateTo("https://www.google.com/search?"+We.toString()),await this.throwIfCaptcha(N,"Google SERP page 2");let rn=await this.extractOrganicResults(N);ae=[...tt,...rn.map(ie=>({...ie,position:ie.position+10}))],t.debug&&(sn=Qe(r,ae,q))}await this.resolveMaterialLinks(N,[],ae,Ct.aiOverview,Ct.aiMode);let on={seed:c.query,totalQuestions:0,maxDepthReached:0,durationMs:Date.now()-a,errorCount:o};return this.reporter.onComplete(on),{seed:c.query,location:t.location??null,extractedAt:new Date().toISOString(),diagnostics:{phaseTimings:this.currentPhaseTimings(a),completionStatus:"serp_only",problem:null,completeness:{...this.completeness},links:{...this.linkDiagnostics},...t.debug?{debug:this.buildHarvestDebugSnapshot(c,r,u,sn,S)}:{}},totalQuestions:0,surface:Ct.surface,aiOverview:Ct.aiOverview,aiMode:Ct.aiMode,whatPeopleSaying:[],tree:[],flat:[],videos:[],forums:[],organicResults:ae,localPack:q,entityIds:pt,stats:on}}let[W,P,C,E,w,k]=await Promise.all([M?this.extractVideos(N):Promise.resolve([]),f?this.extractForums(N):Promise.resolve([]),A?this.extractWhatPeopleSaying(N):Promise.resolve([]),this.extractEntityIds(N),this.extractOrganicResults(N),m?this.extractLocalPack(N):Promise.resolve([])]),v=this.mergeLocalPackIntoEntities(E,k),I=t.debug?Qe(r,w,k):void 0;this.reporter.onVideos(W),this.reporter.onForums(P);let R=y?await this.extractAISurfaces(N,t):O,L={requestedPages:(t.pages??1)>=2?2:1,capturedPages:1,page2Status:(t.pages??1)>=2?"not_attempted":"not_requested",page1OrganicCount:w.length,page2OrganicCount:0},x=w;if(this.checkpointMaterial={surface:R.surface,aiOverview:R.aiOverview,aiMode:R.aiMode,whatPeopleSaying:C,videos:W,forums:P,organicResults:x,localPack:k,entityIds:v,pagination:L},await this.emitProgress("serp_captured"),L.requestedPages===2){let G=await this.captureSecondOrganicPage(N,c,n);x=[...w,...G.organic],L={...L,capturedPages:G.status==="captured"?2:1,page2Status:G.status,page2OrganicCount:G.organic.length,...G.failureCode?{failureCode:G.failureCode}:{}},this.checkpointMaterial={...this.checkpointMaterial,organicResults:x,pagination:L},await this.emitProgress("serp_captured"),await this.resolveMaterialLinks(N,[],x,R.aiOverview,R.aiMode),this.checkpointMaterial={...this.checkpointMaterial,organicResults:x},await this.emitProgress("serp_captured")}let X=t.debug?Qe(r,x,k):I;if(!b){await this.resolveMaterialLinks(N,[],x,R.aiOverview,R.aiMode),this.checkpointMaterial={...this.checkpointMaterial,organicResults:x},await this.emitProgress("serp_captured");let G={seed:c.query,totalQuestions:0,maxDepthReached:0,durationMs:Date.now()-a,errorCount:o};return this.reporter.onComplete(G),{seed:c.query,location:t.location??null,extractedAt:new Date().toISOString(),diagnostics:{phaseTimings:this.currentPhaseTimings(a),completionStatus:"no_paa",noPaaObserved:!0,problem:null,pagination:L,paaLifecycle:{...this.paaLifecycle},completeness:{...this.completeness},links:{...this.linkDiagnostics},...t.debug?{debug:this.buildHarvestDebugSnapshot(c,r,u,X,S)}:{}},totalQuestions:0,surface:R.surface,aiOverview:R.aiOverview,aiMode:R.aiMode,whatPeopleSaying:C,tree:[],flat:[],videos:W,forums:P,organicResults:x,localPack:k,entityIds:v,stats:G}}let ut=Date.now(),it=await this.runBFS(N,c,n);this.phaseTimings.paaExpansionMs=Date.now()-ut,this.throwIfAborted(n);let J=new URLSearchParams({q:c.query,gl:t.gl,hl:t.hl,pws:"0",udm:vn.udm});u&&J.set("uule",u);let ct=[];if(t.includeShortVideos!==!1)try{ct=await this.extractShortVideos(N,"https://www.google.com/search?"+J.toString())}catch(G){if(!(G instanceof at))throw G;o++,d.push({code:"short_videos_captcha_skipped",surface:"short_videos",message:G.message,retryable:!0})}this.reporter.onVideos(ct),await this.resolveMaterialLinks(N,it,x,R.aiOverview,R.aiMode),this.checkpointMaterial={...this.checkpointMaterial,surface:R.surface,aiOverview:R.aiOverview,aiMode:R.aiMode,videos:[...W,...ct],organicResults:x},await this.emitProgress("expansion_finished");let Re=[...W,...ct],F=this.buildTree(it,c.query),yt={seed:c.query,totalQuestions:it.length,maxDepthReached:it.reduce((G,tt)=>Math.max(G,tt.depth),0),durationMs:Date.now()-a,errorCount:o};return this.reporter.onComplete(yt),{seed:c.query,location:t.location??null,extractedAt:new Date().toISOString(),diagnostics:{phaseTimings:this.currentPhaseTimings(a),completionStatus:"paa_found",problem:null,pagination:L,paaLifecycle:{...this.paaLifecycle},completeness:{...this.completeness},links:{...this.linkDiagnostics},...d.length>0?{warnings:d}:{},...t.debug?{debug:this.buildHarvestDebugSnapshot(c,r,u,X,S)}:{}},totalQuestions:it.length,surface:R.surface,aiOverview:R.aiOverview,aiMode:R.aiMode,whatPeopleSaying:C,tree:F,flat:it,videos:Re,forums:P,organicResults:x,localPack:k,entityIds:v,stats:yt}}catch(l){throw o++,this.paaLifecycle.discoveryStatus==="in_progress"&&(this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"interrupted",completionReason:"The browser attempt ended before frontier exhaustion could be proven."}),await this.emitProgress("attempt_ending").catch(()=>{}),this.reporter.onError(l instanceof Error?l:new Error(String(l))),l}}};var ot=require("fs"),xt=un(require("path"),1),te=un(require("papaparse"),1);async function Qs(e){if((process.env.NODE_ENV==="test"||process.env.VITEST)&&process.env.MCP_SCRAPER_ENABLE_MEMORY_LIBRARY_SINK_IN_TESTS!=="1")return;let t=process.env.MCP_SCRAPER_API_KEY?.trim(),n=(process.env.MCP_SCRAPER_BASE_URL??"https://mcpscraper.dev").replace(/\/$/,"");if(t)try{let a=await fetch(`${n}/memory/mcp-call`,{method:"POST",headers:{"content-type":"application/json","x-api-key":t},body:JSON.stringify({toolName:"libraryIngestTool",args:e})}),i=await a.json().catch(()=>null);(!a.ok||i?.ok===!1)&&console.warn("[memory-library-sink] ingest not accepted:",a.status,i?.error??"")}catch(a){console.warn("[memory-library-sink] ingest failed:",a?.message)}}var Dn=class{async writeJSON(t,n){await ot.promises.mkdir(n,{recursive:!0});let i=`${t.seed.toLowerCase().replace(/\W+/g,"-").slice(0,40)}-${Date.now()}.json`,s=xt.default.join(n,i);return await ot.promises.writeFile(s,JSON.stringify(t,null,2),"utf8"),await Qs({title:`${t.seed} scrape`,content:JSON.stringify(t),source:`mcp-scraper:${s}`}),s}async writeCSV(t,n){await ot.promises.mkdir(n,{recursive:!0});let i=(t[0]?.seed_query??"paa").toLowerCase().replace(/\W+/g,"-").slice(0,40),s=te.default.unparse(t.map(({sources:l,...U})=>({...U,sources_json:JSON.stringify(l)})),{header:!0}),o=`${i}-${Date.now()}.csv`,d=xt.default.join(n,o);return await ot.promises.writeFile(d,s,"utf8"),d}async writeVideoCSV(t,n,a){await ot.promises.mkdir(a,{recursive:!0});let i=n.toLowerCase().replace(/\W+/g,"-").slice(0,40),s=te.default.unparse(t,{header:!0}),o=`${i}-videos-${Date.now()}.csv`,d=xt.default.join(a,o);return await ot.promises.writeFile(d,s,"utf8"),d}async writeForumCSV(t,n,a){await ot.promises.mkdir(a,{recursive:!0});let i=n.toLowerCase().replace(/\W+/g,"-").slice(0,40),s=te.default.unparse(t,{header:!0}),o=`${i}-forums-${Date.now()}.csv`,d=xt.default.join(a,o);return await ot.promises.writeFile(d,s,"utf8"),d}async writeAIOverviewCSV(t,n,a,i){await ot.promises.mkdir(i,{recursive:!0});let s=a.toLowerCase().replace(/\W+/g,"-").slice(0,40),o=t.map((S,r)=>({seed_query:a,response_text:r===0?n??"":"",citation_text:S.text,citation_href:S.href})),d=te.default.unparse(o,{header:!0}),l=`${s}-ai-overview-${Date.now()}.csv`,U=xt.default.join(i,l);return await ot.promises.writeFile(U,d,"utf8"),U}async writeAIModeCSV(t,n,a,i){await ot.promises.mkdir(i,{recursive:!0});let s=a.toLowerCase().replace(/\W+/g,"-").slice(0,40),o=t.map((S,r)=>({seed_query:a,response_text:r===0?n??"":"",citation_text:S.text,citation_href:S.href})),d=te.default.unparse(o,{header:!0}),l=`${s}-ai-mode-${Date.now()}.csv`,U=xt.default.join(i,l);return await ot.promises.writeFile(U,d,"utf8"),U}async writeWhatPeopleSayingCSV(t,n,a){await ot.promises.mkdir(a,{recursive:!0});let i=n.toLowerCase().replace(/\W+/g,"-").slice(0,40),s=t.map(U=>({seed_query:n,...U})),o=te.default.unparse(s,{header:!0}),d=`${i}-what-people-saying-${Date.now()}.csv`,l=xt.default.join(a,d);return await ot.promises.writeFile(l,o,"utf8"),l}};var Fn=class{onQuestion(t){process.stdout.write(JSON.stringify({event:"question",depth:t.depth,question:t.question})+`
|
|
21895
|
+
`).map(k=>k.trim()).filter(k=>/^\d+\.\s+.+/.test(k)),h=S(u)}let y=document.querySelector(t.aim.root),A=a==="aim"&&!!y,O=y?.closest(t.aim.wrapper)??y,B=A?l(O):null,_=A&&s(B),N=_?B:null,W=_?S(O):[],P=!!u&&s(c);return{surface:a,aiOverview:{detected:P,text:P?c:null,citations:P?h:[],expanded:P?m:!1,fullyExpanded:P?f:!1,sections:P?M:[]},aiMode:{detected:_&&N!==null,text:N,citations:W}}}var Fs=require("crypto"),Gs=8e3,Vs=3e3,Ys=1e4,nl=8;function Lt(e){return/(^|\.)google\.(?:com|[a-z]{2,3}(?:\.[a-z]{2})?)$/i.test(e)}function tn(e){if(!e||e.length>Gs)return null;try{let t=new URL(e);return t.protocol!=="http:"&&t.protocol!=="https:"||t.username||t.password?null:t}catch{return null}}function al(e,t){if(!e||e.length>Gs||/^javascript:/i.test(e))return null;try{let n=new URL(e,t);return tn(n.href)}catch{return null}}function Ze(e){let t=tn(e);return!t||t.protocol!=="https:"||!Lt(t.hostname)||t.pathname!=="/goto"?null:t.searchParams.get("url")?t:null}function Ba(e){if(e.linkType!=="google_goto_redirect"||e.resolutionStatus!=="resolved"||!Ze(e.rawUrl)||!e.resolvedUrl)return!1;let t=tn(e.resolvedUrl);return!!(t&&!Lt(t.hostname)&&t.href===e.resolvedUrl&&e.url===t.href)}function Zt(e){let t=e.normalize("NFKC").toLocaleLowerCase("en-US").replace(/[^\p{L}\p{N}\s]/gu,"").replace(/\s+/g," ").trim();return`paa_${(0,Fs.createHash)("sha256").update(t).digest("hex").slice(0,16)}`}function Hn(e,t){let n=al(e,t);if(!n)return null;let a=n.href;if(!Lt(n.hostname))return{url:a,rawUrl:a,resolvedUrl:a,linkType:"plain",resolutionStatus:"not_needed"};if(n.pathname==="/url"){let i=tn(n.searchParams.get("q")??n.searchParams.get("url")??"");return!i||Lt(i.hostname)?null:{url:i.href,rawUrl:a,resolvedUrl:i.href,linkType:"google_url_redirect",resolutionStatus:"resolved"}}return n.pathname==="/goto"&&n.searchParams.get("url")?{url:a,rawUrl:a,resolvedUrl:null,linkType:"google_goto_redirect",resolutionStatus:"unresolved"}:null}function Da(e){return Ze(e)?.searchParams.get("url")??null}function Ks(e,t){try{let n=new URL(e),a=tn(new URL(t,n).href);return!a||Lt(a.hostname)?null:(!a.hash&&n.hash&&(a.hash=n.hash),a.href)}catch{return null}}async function Js(e,t={}){let n=[...new Set([...e].flatMap(r=>Ze(r)?[r]:[]))],a=new Map(n.map(r=>[r,{rawUrl:r,resolvedUrl:null,resolutionStatus:"unresolved"}])),i=typeof globalThis.fetch=="function"?globalThis.fetch.bind(globalThis):null,s=t.fetchImpl??i;if(n.length===0||!s)return{resolutions:[...a.values()],nonGoogleRequestsObserved:0};let o=Math.max(1,t.timeoutMs??Vs),d=Date.now()+Math.max(1,t.totalBudgetMs??Ys),l=Math.max(1,Math.min(16,Math.floor(t.concurrency??nl))),U=0,S=async()=>{for(;U<n.length;){let r=n[U++],u=Ze(r),c=u?.searchParams.get("url");if(!u||!c){a.set(r,{rawUrl:r,resolvedUrl:null,resolutionStatus:"rejected"});continue}u.hash="";let h=u.href;for(let m=0;m<2;m++){let f=d-Date.now();if(f<=0)return;let M=new AbortController,y=setTimeout(()=>M.abort(),Math.min(o,f)),A;try{A=await s(h,{method:"GET",redirect:"manual",headers:{accept:"*/*","user-agent":"Mozilla/5.0"},signal:M.signal})}catch{break}finally{clearTimeout(y)}if(A.status<300||A.status>=400)break;let O=A.headers.get("location");if(!O)break;let B=Ks(r,O);if(B){a.set(r,{rawUrl:r,resolvedUrl:B,resolutionStatus:"resolved"});break}let _;try{_=new URL(O,h)}catch{a.set(r,{rawUrl:r,resolvedUrl:null,resolutionStatus:"rejected"});break}if(!Lt(_.hostname)||Da(_.href)!==c){a.set(r,{rawUrl:r,resolvedUrl:null,resolutionStatus:"rejected"});break}h=_.href}}};return await Promise.all(Array.from({length:Math.min(l,n.length)},()=>S())),{resolutions:[...a.values()],nonGoogleRequestsObserved:0}}function Ds(e,t){try{return new URL(e.resolvedUrl??e.url).hostname.replace(/^www\./,"")}catch{return t}}async function qs(e,t={}){let n=[],a=r=>{for(let u of r)n.push(u),a(u.children??[])};a(e.tree??[]);let i=[...e.flat.flatMap(r=>r.sources??[]),...n.flatMap(r=>r.sources),...e.organicResults??[],...(e.aiOverview?.citations??[]).map(({text:r,href:u,...c})=>({...c,url:u})),...(e.aiMode?.citations??[]).map(({text:r,href:u,...c})=>({...c,url:u}))],s=new Map(i.filter(r=>!!r?.rawUrl).map(r=>[r.rawUrl,r])),o=[...s.values()].filter(r=>r.linkType==="google_goto_redirect"&&r.resolutionStatus!=="resolved").map(r=>r.rawUrl);if(o.length>0){let r=await Js(o,t);for(let u of r.resolutions){let c=s.get(u.rawUrl);c&&s.set(u.rawUrl,u.resolutionStatus==="resolved"&&u.resolvedUrl?{...c,url:u.resolvedUrl,resolvedUrl:u.resolvedUrl,resolutionStatus:"resolved"}:{...c,resolutionStatus:u.resolutionStatus})}}let d=r=>({...r,...s.get(r.rawUrl)??r}),l=r=>r.map(u=>{let c=d(u);return{...c,site:Ds(c,u.site)}});for(let r of e.flat){r.sources=l(r.sources??[]);let u=r.sources[0];r.source_title=u?.title??r.source_title,r.source_site=u?.site??r.source_site,r.source_cite=u?.url??r.source_cite}for(let r of n){r.sources=l(r.sources??[]);let u=r.sources[0];r.sourceTitle=u?.title??r.sourceTitle,r.sourceSite=u?.site??r.sourceSite,r.sourceCite=u?.url??r.sourceCite}for(let r=0;r<(e.organicResults?.length??0);r++){let u=d(e.organicResults[r]);e.organicResults[r]={...u,domain:Ds(u,e.organicResults[r].domain)??""}}let U=r=>{let u=d({url:r.href,rawUrl:r.rawUrl,resolvedUrl:r.resolvedUrl,linkType:r.linkType,resolutionStatus:r.resolutionStatus}),{url:c,...h}=u;return{...r,...h,href:c}};e.aiOverview&&(e.aiOverview.citations=(e.aiOverview.citations??[]).map(U)),e.aiMode&&(e.aiMode.citations=(e.aiMode.citations??[]).map(U));let S=[...s.values()];return e.diagnostics.links={linkCandidatesObserved:s.size,plainLinksObserved:S.filter(r=>r.linkType==="plain").length,googleUrlRedirectsObserved:S.filter(r=>r.linkType==="google_url_redirect").length,googleGotoRedirectsObserved:S.filter(r=>r.linkType==="google_goto_redirect").length,redirectsResolved:S.filter(r=>r.linkType!=="plain"&&r.resolutionStatus==="resolved").length,redirectsUnresolved:S.filter(r=>r.resolutionStatus==="unresolved").length,redirectsRejected:S.filter(r=>r.resolutionStatus==="rejected").length,resolverNonGoogleRequestsObserved:0,paaSourcesPreserved:e.flat.reduce((r,u)=>r+u.sources.length,0),aiOverviewLabelValidated:e.aiOverview?.detected??!1},e}async function Xs(e,t,n={}){let a=new Map;for(let u of t){let c=a.get(u.rawUrl);c&&Ba(c)||a.set(u.rawUrl,u.linkType==="google_goto_redirect"&&!Ba(u)?{...u,url:u.rawUrl,resolvedUrl:null,resolutionStatus:"unresolved"}:u)}let i=[...a.values()].filter(u=>u.linkType==="google_goto_redirect"&&!Ba(u));if(i.length===0)return a;let s=Date.now()+(n.totalBudgetMs??Ys),o=await Js(i.map(u=>u.rawUrl),n);for(let u of o.resolutions){let c=a.get(u.rawUrl);c&&a.set(u.rawUrl,u.resolutionStatus==="resolved"&&u.resolvedUrl?{...c,url:u.resolvedUrl,resolvedUrl:u.resolvedUrl,resolutionStatus:"resolved"}:{...c,resolutionStatus:u.resolutionStatus})}let d=i.filter(u=>a.get(u.rawUrl)?.resolutionStatus==="unresolved");if(d.length===0||n.browserFallback===!1||Date.now()>=s)return n.onNetworkAudit?.({nonGoogleRequestsObserved:0}),a;let l=n.timeoutMs??Vs,U=await e.context().newPage().catch(()=>null);if(!U)return n.onNetworkAudit?.({nonGoogleRequestsObserved:0}),a;let S=null,r=0;try{await U.route("**/*",async u=>{let c=u.request().url();try{Lt(new URL(c).hostname)||(r+=1)}catch{}let h=Da(c);if(!S||h!==S.token){await u.abort("blockedbyclient").catch(()=>{});return}let m=S;try{let f=await u.fetch({maxRedirects:0,timeout:m.timeoutMs});m.location=f.headers().location??null}finally{await u.abort("blockedbyclient").catch(()=>{}),m.finish()}});for(let u of d){let c=s-Date.now();if(c<=0)break;let h=Ze(u.rawUrl),m=h?.searchParams.get("url");if(!h||!m){a.set(u.rawUrl,{...u,resolutionStatus:"rejected"});continue}let f=Math.min(l,c);h.hash="";let M=h.href,y=!1;for(let A=0;A<2;A++){let O,B=new Promise(C=>{O=C}),_=`mcp-goto-${Math.random().toString(36).slice(2)}`;S={token:m,timeoutMs:f,location:null,finish:O},await U.evaluate(({url:C,id:E})=>{let w=document.createElement("iframe");w.id=E,w.hidden=!0,w.src=C,document.body.append(w)},{url:M,id:_}).catch(()=>null),await Promise.race([B,new Promise(C=>setTimeout(C,f))]);let N=S.location;if(S=null,await U.evaluate(C=>document.getElementById(C)?.remove(),_).catch(()=>null),!N)break;let W=Ks(u.rawUrl,N);if(W){a.set(u.rawUrl,{...u,url:W,resolvedUrl:W,resolutionStatus:"resolved"});break}let P;try{P=new URL(N,M)}catch{y=!0;break}if(!Lt(P.hostname)||Da(P.href)!==m){y=!0;break}M=P.href}y&&a.get(u.rawUrl)?.resolutionStatus!=="resolved"&&a.set(u.rawUrl,{...u,resolutionStatus:"rejected"})}}finally{S=null,await U.close().catch(()=>{}),n.onNetworkAudit?.({nonGoogleRequestsObserved:r})}return a}var js=String.raw`^(?:an error has occurred(?:[.!…]\s*)?(?:please try again later[.!…]?)?|loading|please wait|try again|something went wrong)[.!…\s]*$`,il=700,sl=1e3,ol=1400,zs=900,rl=3,$s=250,Bn=class{constructor(t,n,a,i){this.driver=t;this.reporter=n;this.onPaaProgress=a;this.onProviderSession=i}driver;reporter;onPaaProgress;onProviderSession;completeness={paaWithoutAnswer:0,paaWithoutSource:0,paaAnswersRecovered:0,aioShareCaptured:null};aioShareUrlEarly=null;linkDiagnostics=this.emptyLinkDiagnostics();collectedRows=[];partialContext=null;progressSequence=0;clickedQuestions=new Set;paaLifecycle=this.emptyPaaLifecycle(0);checkpointMaterial=null;interactionObservations=[];phaseTimings={};currentPhaseTimings(t){return{...this.phaseTimings,totalServerMs:Math.max(0,Date.now()-t)}}emptyPaaLifecycle(t){return{requestedQuestions:t,questionsFound:0,targetStatus:"not_met",discoveryStatus:"in_progress",materialStatus:"partial",completionReason:"PAA expansion is still running.",automaticRetries:0,retryBreakdown:{controlRetries:0,browserRetries:0,providerFallbacks:0,runtimeRecoveries:0,idempotentReplays:0},knownQuestions:0,processedQuestions:0,failedInteractions:0,noGrowthConfirmations:0,visibleControls:0,eligibleControls:0,dispatchedInteractions:0,confirmedInteractions:0,unconfirmedInteractions:0}}emptyLinkDiagnostics(){return{linkCandidatesObserved:0,plainLinksObserved:0,googleUrlRedirectsObserved:0,googleGotoRedirectsObserved:0,redirectsResolved:0,redirectsUnresolved:0,redirectsRejected:0,resolverNonGoogleRequestsObserved:0,paaSourcesPreserved:0,aiOverviewLabelValidated:!1}}mergePaaSources(t=[],n=[]){let a=new Map;for(let i of[...t,...n]){let s=a.get(i.rawUrl);if(!s){a.set(i.rawUrl,i);continue}let o=i.resolutionStatus==="resolved"&&s.resolutionStatus!=="resolved"?i:s;a.set(i.rawUrl,{...o,title:o.title??s.title??i.title,site:o.site??s.site??i.site})}return[...a.values()]}normalizeAICitations(t,n){let a=new Set;return n.flatMap(i=>{let s=Hn(i.rawHref??i.href,t);if(!s||a.has(s.rawUrl))return[];a.add(s.rawUrl);let{url:o,...d}=s;return[{...d,text:i.text,href:o}]})}async resolveMaterialLinks(t,n,a,i,s){let o=Date.now(),d=[...n.flatMap(h=>h.sources??[]),...a,...i.citations.map(({text:h,href:m,...f})=>({...f,url:m})),...s.citations.map(({text:h,href:m,...f})=>({...f,url:m}))],l=new Map(d.map(h=>[h.rawUrl,h])),U=0,S=await Xs(t,d,{onNetworkAudit:h=>{U=h.nonGoogleRequestsObserved}}),r=h=>({...h,...S.get(h.rawUrl)??h});for(let h of n){h.sources=(h.sources??[]).map(r);let m=h.sources[0];h.source_title=m?.title??h.source_title,h.source_site=m?.site??h.source_site,h.source_cite=m?.url??h.source_cite}for(let h=0;h<a.length;h++){let m=r(a[h]);if(m.resolvedUrl)try{m.domain=new URL(m.resolvedUrl).hostname.replace(/^www\./,"")}catch{}a[h]=m}let u=h=>{let m=r({url:h.href,rawUrl:h.rawUrl,resolvedUrl:h.resolvedUrl,linkType:h.linkType,resolutionStatus:h.resolutionStatus}),{url:f,...M}=m;return{...M,text:h.text,href:f}};i.citations=i.citations.map(u),s.citations=s.citations.map(u);let c=[...S.values()];this.linkDiagnostics={linkCandidatesObserved:l.size,plainLinksObserved:c.filter(h=>h.linkType==="plain").length,googleUrlRedirectsObserved:c.filter(h=>h.linkType==="google_url_redirect").length,googleGotoRedirectsObserved:c.filter(h=>h.linkType==="google_goto_redirect").length,redirectsResolved:c.filter(h=>h.linkType!=="plain"&&h.resolutionStatus==="resolved").length,redirectsUnresolved:c.filter(h=>h.resolutionStatus==="unresolved").length,redirectsRejected:c.filter(h=>h.resolutionStatus==="rejected").length,resolverNonGoogleRequestsObserved:U,paaSourcesPreserved:n.reduce((h,m)=>h+(m.sources??[]).length,0),aiOverviewLabelValidated:i.detected},this.phaseTimings.linkResolutionMs=(this.phaseTimings.linkResolutionMs??0)+(Date.now()-o)}normalizeQuestion(t){return t.toLowerCase().replace(/[^\w\s]/g,"").replace(/\s+/g," ").trim()}throwIfAborted(t){if(t?.aborted)throw t.reason instanceof DOMException&&t.reason.name==="TimeoutError"?t.reason:new gt}async throwIfCaptcha(t,n){if(await t.locator(Y.captchaMarker).count().catch(()=>0)>0)throw new at(`${n} returned a CAPTCHA \u2014 retrying with a fresh session.`)}async extractVisibleItems(t,n){let a=Y,i=await t.evaluate(({selectors:o,onlyQuestion:d,answerPlaceholderPattern:l})=>{function U(r){if(!r)return"";let u=[];for(let c of r.childNodes)if(c.nodeType===Node.TEXT_NODE){let h=c.textContent?.trim();h&&u.push(h)}else{if(c.tagName==="STYLE"||c.tagName==="SCRIPT")continue;{let h=U(c);h&&u.push(h)}}return u.join(" ").replace(/\s+/g," ").trim()}function S(r){return(r??"").replace(/\s*\(\+\d+\)\s*-\s*View related links.*$/i,"").replace(/\s*-\s*Opens in new tab.*$/i,"").trim()}return Array.from(document.querySelectorAll(o.item)).filter(r=>!d||(r.getAttribute(o.itemDataQ)||r.getAttribute(o.itemDataInitQ)||r.querySelector(o.itemQuestionEl)?.innerText?.trim()||"")===d).map(r=>{let u=r.querySelector(o.clickTarget),c=r.classList.contains(o.expandedClass)||u?.getAttribute("aria-expanded")==="true",h=r.querySelector(o.answerContainer),f=h?.querySelector(o.aiAnswerBody)??h,M=U(f),y=new RegExp(l,"i").test(M),A=[...Array.from((f??r).querySelectorAll("a[href]")),...Array.from(r.querySelectorAll(o.aiCitation)),...Array.from(r.querySelectorAll(o.aiSourceCard))],O=!y&&(c&&M.length>=10||M.length>30&&A.some(W=>/^https?:\/\//.test(W.href))),B=O&&r.querySelector(o.sourceTitle)?.innerText?.trim()||void 0,_=O&&r.querySelector(o.sourceSite)?.innerText?.trim()||void 0,N=[];if(O){let W=new Set;for(let C of A)!/^https?:\/\//.test(C.href)||W.has(C.href)||(W.add(C.href),N.push({title:S(C.getAttribute("aria-label"))||(C.textContent||"").trim(),rawHref:C.href}));let P=N.find(C=>C.title.length>2)??N[0];P&&(B=B||P.title||void 0)}return{googleLinkId:r.getAttribute("data-lk")||r.querySelector("[data-lk]")?.getAttribute("data-lk")||null,googleEvidenceId:r.getAttribute("data-ved")||r.querySelector("[data-ved]")?.getAttribute("data-ved")||null,question:r.getAttribute(o.itemDataQ)||r.getAttribute(o.itemDataInitQ)||r.querySelector(o.itemQuestionEl)?.innerText?.trim()||"",answer:O&&M||void 0,sourceTitle:B,sourceSite:_,sources:N}})},{selectors:a,onlyQuestion:n,answerPlaceholderPattern:js}),s=typeof t.url=="function"?t.url():"https://www.google.com/";return i.flatMap(o=>{let d=[],l=new Set;for(let u of o.sources){let c=Hn(u.rawHref,s);if(!c||l.has(c.rawUrl))continue;l.add(c.rawUrl);let h=o.sourceSite??null;try{h||=new URL(c.resolvedUrl??c.rawUrl).hostname.replace(/^www\./,"")}catch{}d.push({...c,title:u.title||o.sourceTitle||null,site:h})}let U=d[0],S={questionId:Zt(o.question),googleLinkId:o.googleLinkId,googleEvidenceId:o.googleEvidenceId,question:o.question,answer:Hs(o.answer,o.question,o.sourceTitle),sourceTitle:U?.title??o.sourceTitle,sourceSite:U?.site??o.sourceSite,sourceCite:U?.url,sources:d},r=Si.safeParse(S);return r.success?[r.data]:(console.warn("[PAAExtractor] item parse failed:",o.question,r.error.issues[0]?.message),[])})}jitteredDelayMs(t,n){return t+Math.floor(Math.random()*(n-t+1))}async clickItem(t,n){try{await t.locator(`${Y.item}[data-q="${n}"], ${Y.item}[data-initq="${n}"]`).first().click()}catch{}}toFlatRow(t,n,a,i){return{seed_query:i,question_id:t.questionId??Zt(t.question),google_link_id:t.googleLinkId??"",google_evidence_id:t.googleEvidenceId??"",question:t.question,answer:t.answer??"",source_title:t.sourceTitle??"",source_site:t.sourceSite??"",source_cite:t.sourceCite??"",sources:t.sources??[],depth:n,parent_question:a??"",extracted_at:new Date().toISOString()}}upsertCollectedRow(t){let n=this.normalizeQuestion(t.question),a=this.collectedRows.findIndex(d=>this.normalizeQuestion(d.question)===n);if(a<0)return this.collectedRows.push({...t}),!0;let i=this.collectedRows[a],s={...i,...t,answer:t.answer||i.answer,source_title:t.source_title||i.source_title,source_site:t.source_site||i.source_site,source_cite:t.source_cite||i.source_cite,sources:this.mergePaaSources(i.sources,t.sources),extracted_at:t.extracted_at||i.extracted_at},o=s.answer!==i.answer||s.source_title!==i.source_title||s.source_site!==i.source_site||s.source_cite!==i.source_cite||JSON.stringify(s.sources)!==JSON.stringify(i.sources);return o&&(this.collectedRows[a]=s),o}async emitProgress(t){if(!this.onPaaProgress||this.collectedRows.length===0&&!this.checkpointMaterial)return;let n={sequence:++this.progressSequence,observedAt:new Date().toISOString(),clickedQuestions:[...this.clickedQuestions],phase:t,records:this.collectedRows.map(a=>({...a})),lifecycle:{...this.paaLifecycle},...this.checkpointMaterial?{material:structuredClone(this.checkpointMaterial)}:{},interactions:this.interactionObservations.map(a=>({...a,confirmationSignals:[...a.confirmationSignals]}))};try{await this.onPaaProgress(n)}catch(a){console.warn(JSON.stringify({event:"paa_progress_sink_failed",sequence:n.sequence,phase:n.phase,message:a instanceof Error?a.message:String(a)}))}}getPartialResult(){let t=this.partialContext;if(!t||this.collectedRows.length===0&&!this.checkpointMaterial)return null;let n=this.collectedRows.map(d=>({...d})),a=this.checkpointMaterial,i=t.questionsOnly?0:n.filter(d=>!d.answer?.trim()).length,s=t.questionsOnly?0:n.filter(d=>(d.sources??[]).length===0).length,o={seed:t.seed,totalQuestions:n.length,maxDepthReached:n.reduce((d,l)=>Math.max(d,l.depth),0),durationMs:Date.now()-t.startMs,errorCount:0};return{seed:t.seed,location:t.location,extractedAt:new Date().toISOString(),diagnostics:{phaseTimings:this.currentPhaseTimings(t.startMs),completionStatus:"paa_found",problem:null,...a?.pagination?{pagination:{...a.pagination}}:{},resultQuality:"partial",degradedResult:!1,retryRecommended:!0,paaLifecycle:{...this.paaLifecycle,questionsFound:n.length,targetStatus:n.length>=(t.maxQuestions??0)?"met":"not_met",discoveryStatus:"interrupted",materialStatus:i>0||s>0?"partial":"complete",completionReason:"The browser attempt ended before frontier exhaustion could be proven."},completeness:{...this.completeness,paaWithoutAnswer:i,paaWithoutSource:s,paaRequested:t.maxQuestions,paaReturned:n.length,paaUnique:n.length},warnings:[{code:"paa_partial",surface:"paa",message:`Harvest stopped before finishing; returning the ${n.length} question(s) collected up to that point.`,retryable:!0}]},totalQuestions:n.length,surface:a?.surface??"web",aiOverview:a?.aiOverview??{detected:!1,text:null,citations:[]},aiMode:a?.aiMode??{detected:!1,text:null,citations:[]},whatPeopleSaying:a?.whatPeopleSaying??[],tree:this.buildTree(n,t.seed),flat:n,videos:a?.videos??[],forums:a?.forums??[],organicResults:a?.organicResults??[],localPack:a?.localPack??[],entityIds:a?.entityIds??{entities:[],kgIds:[],cids:[],gcids:[]},stats:o}}async runBFS(t,n,a){await t.waitForTimeout(700);let i=new Set,s=new Set,o=[];this.clickedQuestions=new Set,this.interactionObservations=[],this.phaseTimings={};let d=new Set,l=new Map,U=new Set,S=new Set,r=new Map,u=2,c=3,h=0,m={sel:Y.item,dataQ:Y.itemDataQ,dataInitQ:Y.itemDataInitQ,questionEl:Y.itemQuestionEl,answerSel:Y.answerContainer,expandedClass:Y.expandedClass,clickTarget:Y.clickTarget,answerPlaceholderPattern:js,questionsOnly:n.questionsOnly,sourceSel:"a[href]"},f=()=>t.evaluate(({sel:_,dataQ:N,dataInitQ:W,questionEl:P,expandedClass:C,clickTarget:E,answerSel:w,answerPlaceholderPattern:k,questionsOnly:v})=>{let I=R=>{if(!R)return"";let L=[];for(let x of R.childNodes){if(x.nodeType===Node.TEXT_NODE){let it=x.textContent?.trim();it&&L.push(it);continue}if(x.nodeType!==Node.ELEMENT_NODE)continue;let X=x;if(X.tagName==="STYLE"||X.tagName==="SCRIPT"||X.getAttribute("aria-hidden")==="true")continue;let ut=I(X);ut&&L.push(ut)}return L.join(" ").replace(/\s+/g," ").trim()};return Array.from(document.querySelectorAll(_)).map((R,L)=>{let x=I(R.querySelector(w)).replace(/An AI Overview is not available for this search/gi," ").replace(/Can't generate an AI overview right now\.?\s*Try again later\.?/gi," ").replace(/\bAI Overview\b/gi," ").replace(/\s+/g," ").trim(),X=R.classList.contains(C)||R.querySelector(E)?.getAttribute("aria-expanded")==="true",ut=x.length>=10&&!new RegExp(k,"i").test(x);return{q:R.getAttribute(N)||R.getAttribute(W)||R.querySelector(P)?.innerText?.trim()||"",done:X&&(v||ut),expanded:X,index:L}}).filter(R=>R.q)},m),M=async(_,N,W,P,C,E)=>{let w=Date.now(),k={id:`${E}:${Zt(_)}:${C}`,questionId:Zt(_),question:_,batchNumber:E,controlAttempt:C,observedAt:new Date(w).toISOString(),beforeQuestionCount:N,expandedBefore:P},v=W>=0?t.locator(m.sel).nth(W).locator(m.clickTarget):null,I=null,R=v?await(async()=>(P&&(await v.click({timeout:zs,force:!0}),await t.waitForTimeout(120)),await v.click({timeout:zs,force:!0}),!0))().catch(F=>(I=F instanceof Error&&(F.name==="TimeoutError"||/timeout/i.test(F.message))?"click_ack_timeout":"click_failed",!1)):!1,L=Date.now()-w;if(!R&&I!=="click_ack_timeout")return{dispatched:!1,confirmed:!1,observation:{...k,dispatched:!1,outcome:"dispatch_failed",confirmationSignals:[],confirmationCheckpointMs:null,confirmedAtMs:null,dispatchDurationMs:L,totalDurationMs:L,afterQuestionCount:N,newQuestionCount:0,expandedAfter:P,answerObserved:!1,sourceCount:0,errorCode:W<0?"control_missing":I??"click_failed"}};let x={exists:!0,expanded:P,answerReady:!1,sourceCount:0,questionCount:N},X=[],ut=null,it=null,q=!1;for(let F of[il,sl,ol]){let yt=w+F-Date.now();if(yt>0&&await t.waitForTimeout(yt),x=await t.evaluate(({sel:G,dataQ:tt,dataInitQ:J,questionEl:$,expandedClass:pt,clickTarget:Ct,answerSel:sn,answerPlaceholderPattern:ae,sourceSel:on,target:We})=>{let rn=se=>{if(!se)return"";let $n=[];for(let ln of se.childNodes){if(ln.nodeType===Node.TEXT_NODE){let di=ln.textContent?.trim();di&&$n.push(di);continue}if(ln.nodeType!==Node.ELEMENT_NODE)continue;let Sn=ln;if(Sn.tagName==="STYLE"||Sn.tagName==="SCRIPT"||Sn.getAttribute("aria-hidden")==="true")continue;let ri=rn(Sn);ri&&$n.push(ri)}return $n.join(" ").replace(/\s+/g," ").trim()},ie=Array.from(document.querySelectorAll(G)),dn=ie.find(se=>(se.getAttribute(tt)||se.getAttribute(J)||se.querySelector($)?.innerText?.trim())===We);if(!dn)return{exists:!1,expanded:!1,answerReady:!1,sourceCount:0,questionCount:ie.length};let Io=dn.classList.contains(pt)||dn.querySelector(Ct)?.getAttribute("aria-expanded")==="true",ii=dn.querySelector(sn),si=rn(ii).replace(/An AI Overview is not available for this search/gi," ").replace(/Can't generate an AI overview right now\.?\s*Try again later\.?/gi," ").replace(/\bAI Overview\b/gi," ").replace(/\s+/g," ").trim(),oi=si.length>=10&&!new RegExp(ae,"i").test(si);return{exists:!0,expanded:Io,answerReady:oi,sourceCount:oi?ii?.querySelectorAll(on).length??0:0,questionCount:ie.length}},{...m,target:_}).catch(()=>x),X=[...x.expanded?["expanded"]:[],...x.answerReady?["answer"]:[],...x.sourceCount>0?["source"]:[],...x.questionCount>N?["question_growth"]:[]],x.answerReady||x.sourceCount>0||x.questionCount>N){q=!0,ut=F,it=Date.now()-w;break}}let ct=Date.now()-w,Re={...k,dispatched:R,outcome:q?"confirmed":R?"unconfirmed":"dispatch_failed",confirmationSignals:X,confirmationCheckpointMs:ut,confirmedAtMs:it,dispatchDurationMs:L,totalDurationMs:ct,afterQuestionCount:x.questionCount,newQuestionCount:Math.max(0,x.questionCount-N),expandedAfter:x.expanded,answerObserved:x.answerReady,sourceCount:x.sourceCount,errorCode:R?q?null:x.exists?"confirmation_timeout":"control_missing":I};return{dispatched:R,confirmed:q,observation:Re}},y=0;t:for(;;){if(n.softDeadlineMs&&Date.now()>=n.softDeadlineMs)throw this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"interrupted",completionReason:"The execution deadline arrived before frontier exhaustion could be proven."},new zt(this.paaLifecycle.completionReason);this.throwIfAborted(a);let _=await f(),N=!1;for(let w of _)s.has(w.q)||(s.add(w.q),o.push(w.q),o.length<=n.maxQuestions&&(N=this.upsertCollectedRow(this.toFlatRow({questionId:Zt(w.q),googleLinkId:null,googleEvidenceId:null,question:w.q,sources:[]},1,null,n.query))||N)),w.done&&U.add(w.q);if(this.paaLifecycle={...this.paaLifecycle,questionsFound:Math.min(o.length,n.maxQuestions),targetStatus:o.length>=n.maxQuestions?"met":"not_met",knownQuestions:o.length,processedQuestions:U.size,failedInteractions:S.size,visibleControls:_.length},N&&await this.emitProgress("discovered"),n.questionsOnly&&s.size>=n.maxQuestions){this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"target_reached",targetStatus:"met",completionReason:"The requested unique-question count was observed."};break}if(!n.questionsOnly&&s.size>=n.maxQuestions){let w=!1,k=new Set(o.slice(0,n.maxQuestions));for(let v of await this.extractVisibleItems(t)){if(!k.has(v.question))continue;let I=r.get(v.question),R={...v,answer:v.answer??I?.answer,sourceTitle:v.sourceTitle??I?.sourceTitle,sourceSite:v.sourceSite??I?.sourceSite,sourceCite:v.sourceCite??I?.sourceCite,sources:this.mergePaaSources(I?.sources,v.sources)};r.set(v.question,R),w=this.upsertCollectedRow(this.toFlatRow(R,1,null,n.query))||w}if(w&&await this.emitProgress("answer_captured"),[...k].every(v=>{let I=r.get(v);return!!(I?.answer?.trim()&&I.sources.length>0)})){S.clear(),this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"target_reached",targetStatus:"met",failedInteractions:0,completionReason:"The requested unique-question count and its answer/source material were observed."};break}}let W=new Set(o.slice(0,n.maxQuestions)),P=_.filter(w=>W.has(w.q)&&!w.done&&(l.get(w.q)??0)<u&&!d.has(w.q)),C=P.slice(-rl);if(this.paaLifecycle={...this.paaLifecycle,eligibleControls:P.length},C.length===0){if(s.size>=n.maxQuestions){this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"target_reached",targetStatus:"met",completionReason:"The requested unique-question count was observed."};break}let w=new Set(_.map(v=>v.q)),k=o.slice(0,n.maxQuestions).filter(v=>!U.has(v)&&(S.has(v)||!w.has(v)));if(k.length>0)throw this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"interrupted",failedInteractions:new Set([...S,...k]).size,completionReason:"At least one known PAA control failed or disappeared before it could be confirmed."},await this.emitProgress("expansion_finished"),new zt(this.paaLifecycle.completionReason);for(let v=1;v<=c;v++){this.throwIfAborted(a),await this.throwIfCaptcha(t,"Google PAA exhaustion confirmation"),await t.mouse.wheel(0,320);let I=await t.waitForFunction(({sel:L,min:x})=>document.querySelectorAll(L).length>x,{sel:Y.item,min:_.length},{timeout:1500,polling:100}).catch(()=>null);if(this.paaLifecycle={...this.paaLifecycle,noGrowthConfirmations:v},I||(await f()).some(L=>!s.has(L.q)))continue t}this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"frontier_exhausted",targetStatus:"not_met",failedInteractions:0,noGrowthConfirmations:c,completionReason:"Every known eligible PAA control was processed and three healthy no-growth confirmations found no additional questions."};break}await this.throwIfCaptcha(t,"Google PAA expansion"),h+=1;for(let w of C){if(this.reporter.onDepth(++y),(l.get(w.q)??0)>0){let k=this.paaLifecycle.retryBreakdown.controlRetries+1;this.paaLifecycle={...this.paaLifecycle,automaticRetries:k+this.paaLifecycle.retryBreakdown.browserRetries+this.paaLifecycle.retryBreakdown.runtimeRecoveries,retryBreakdown:{...this.paaLifecycle.retryBreakdown,controlRetries:k}}}l.set(w.q,(l.get(w.q)??0)+1)}let E=await Promise.all(C.map(async w=>({target:w,result:await M(w.q,_.length,w.index,w.expanded,l.get(w.q)??1,h)})));for(let{target:w,result:k}of E)(k.dispatched||k.confirmed)&&this.clickedQuestions.add(w.q),this.interactionObservations.push(k.observation);if(this.interactionObservations.length>$s&&this.interactionObservations.splice(0,this.interactionObservations.length-$s),!n.questionsOnly){let w=new Set(C.map(k=>k.q));for(let k of await this.extractVisibleItems(t))w.has(k.question)&&(r.set(k.question,k),this.upsertCollectedRow(this.toFlatRow(k,1,null,n.query))&&await this.emitProgress("answer_captured"))}for(let{target:w,result:k}of E){let v=r.get(w.q);k.confirmed||v?.answer?.trim()?(U.add(w.q),S.delete(w.q)):(l.get(w.q)??0)>=u&&(S.add(w.q),d.add(w.q))}this.paaLifecycle={...this.paaLifecycle,processedQuestions:U.size,failedInteractions:S.size,noGrowthConfirmations:0,dispatchedInteractions:this.interactionObservations.filter(w=>w.dispatched).length,confirmedInteractions:this.interactionObservations.filter(w=>w.outcome==="confirmed").length,unconfirmedInteractions:this.interactionObservations.filter(w=>w.outcome!=="confirmed").length},await this.emitProgress("click_observed")}let A=n.questionsOnly?new Map:new Map(r);n.questionsOnly||await this.fillIncompleteItems(t,o,A,n,d);let O=[];for(let _ of o){if(O.length>=n.maxQuestions)break;let N=this.normalizeQuestion(_);if(i.has(N))continue;i.add(N);let W=A.get(_);if(W){let P=this.toFlatRow(W,1,null,n.query);this.upsertCollectedRow(P),O.push(P),this.reporter.onQuestion({questionId:W.questionId,googleLinkId:W.googleLinkId,googleEvidenceId:W.googleEvidenceId,question:W.question,answer:W.answer??null,sourceTitle:W.sourceTitle??null,sourceSite:W.sourceSite??null,sourceCite:W.sourceCite??null,sources:W.sources,depth:1,parentQuestion:null,children:[]})}else{let P=this.toFlatRow({questionId:Zt(_),googleLinkId:null,googleEvidenceId:null,question:_,answer:void 0,sourceTitle:void 0,sourceSite:void 0,sourceCite:void 0,sources:[]},1,null,n.query);this.upsertCollectedRow(P),O.push(P)}}this.completeness.paaWithoutAnswer=n.questionsOnly?0:O.filter(_=>!_.answer).length,this.completeness.paaWithoutSource=n.questionsOnly?0:O.filter(_=>(_.sources??[]).length===0).length,this.completeness.paaRequested=n.maxQuestions,this.completeness.paaReturned=O.length,this.completeness.paaUnique=i.size;let B=!n.questionsOnly&&(this.completeness.paaWithoutAnswer>0||this.completeness.paaWithoutSource>0);return this.paaLifecycle={...this.paaLifecycle,questionsFound:O.length,targetStatus:O.length>=n.maxQuestions?"met":"not_met",materialStatus:B?"partial":"complete",processedQuestions:U.size,failedInteractions:S.size},await this.emitProgress("fill_incomplete"),await this.emitProgress("expansion_finished"),O}async fillIncompleteItems(t,n,a,i,s){let o=new Set(n.slice(0,i.maxQuestions)),d=S=>!S?.answer||(S.sources??[]).length===0,l=new Set([...o].filter(S=>d(a.get(S)))),U=new Set([...l].filter(S=>!a.get(S)?.answer));if(l.size!==0){for(let S of l){if(i.softDeadlineMs&&Date.now()>=i.softDeadlineMs)break;let r=(await this.extractVisibleItems(t,S))[0];if(!r)continue;let u=a.get(S);a.set(S,{...r,answer:r.answer??u?.answer,sourceTitle:r.sourceTitle??u?.sourceTitle,sourceSite:r.sourceSite??u?.sourceSite,sourceCite:r.sourceCite??u?.sourceCite,sources:this.mergePaaSources(u?.sources,r.sources)});let c=a.get(S);c&&this.upsertCollectedRow(this.toFlatRow(c,1,null,i.query))&&await this.emitProgress("fill_incomplete")}this.completeness.paaAnswersRecovered=[...U].filter(S=>a.get(S)?.answer).length}}async reExpandCollapsedItems(t){let n=`${Y.item}:not(.${Y.expandedClass}) ${Y.clickTarget}`,a=await t.locator(n).count().catch(()=>0);if(a===0)return!1;for(let i=0;i<a;i++)try{let s=t.locator(n).first();await s.scrollIntoViewIfNeeded(),await s.click({force:!0}),await t.waitForTimeout(this.jitteredDelayMs(300,500))}catch{}return!0}async extractVideos(t){let n=Qi;return t.evaluate(a=>{let i=[],s=Array.from(document.querySelectorAll(a.container));for(let o of s){let U=(o.querySelector(a.sectionHeading)?.textContent?.trim()??"").toLowerCase().includes("short")?"short_video":"video",S=Array.from(o.querySelectorAll(a.item));for(let r of S){let u=r.href;if(!u||!u.includes("youtube")&&!u.includes("youtu.be"))continue;let c=r.textContent?.trim()??"",h=c.indexOf("YouTube");if(h===-1)continue;let m=c.slice(0,h).trim(),M=c.slice(h+7).replace(/^[·\s·]+/,"").match(/^([^·\n]+)/),y=M?M[1].trim():"";m&&i.push({type:U,title:m,channel:y,platform:"YouTube",duration:"",url:u})}}return i},n)}async extractForums(t){let n=Zi;return t.evaluate(a=>{let i=[],o=Array.from(document.querySelectorAll(a.section)).find(l=>l.textContent?.includes("Discussions"));if(!o)return i;let d=Array.from(o.querySelectorAll(a.item));for(let l of d){let U=l.href;if(!U)continue;let S=l.querySelector(a.title),r=l.querySelector(a.source),u=S?.textContent?.trim()??"",c=r?.textContent?.trim()??"";u&&i.push({title:u,source:c,url:U})}return i},n)}async extractShortVideos(t,n){try{await t.goto(n,{waitUntil:"domcontentloaded"}),await t.waitForTimeout(1500)}catch{return[]}await this.throwIfCaptcha(t,"Google short video search");let a={item:vn.item,platforms:[...vn.platforms]};return(await t.evaluate(s=>{let o=new Set,d=[],l=Array.from(document.querySelectorAll(s.item)),U=["youtube.com","youtu.be","tiktok.com","instagram.com","facebook.com","fb.watch"],S=new Map;for(let r of l){let u=r.href;if(!u||!U.some(h=>u.includes(h)))continue;let c=r.textContent?.trim()??"";S.has(u)||S.set(u,[]),S.get(u).push(c)}for(let[r,u]of S.entries()){if(o.has(r))continue;o.add(r);let c=u.find(y=>/^\d+:\d+$/.test(y))??"",h=u.find(y=>!/^\d+:\d+$/.test(y)&&y.length>5)??"";if(!h)continue;let m=h,f="",M="";for(let y of s.platforms){let A=-1,O=0;for(;;){let P=h.indexOf(y,O);if(P===-1)break;A=P,O=P+1}if(A===-1)continue;let B=h.slice(A+y.length);if(!(/^[\s·]/.test(B)||B.trim()===""))continue;m=h.slice(0,A).trim(),f=y;let N=B.replace(/^[\s·]+/,""),W=N.indexOf("\xB7");M=(W===-1?N:N.slice(0,W)).trim();break}m&&d.push({title:m,channel:M,platform:f,duration:c,url:r})}return d},a)).map(s=>({type:"short_video",...s}))}async extractWhatPeopleSaying(t){let n=ts;return t.evaluate(a=>{let i=Array.from(document.querySelectorAll(a.sectionTag)).find(s=>s.textContent?.includes(a.sectionHeadingText))??document.querySelector(".yG4QQe.TBC9ub.NbhJ1c");return i?Array.from(i.querySelectorAll(a.card)).map(s=>{let d=s.querySelector(a.cardLink)?.href??"",l=s.querySelector(a.titleH1)?.textContent?.trim(),U=s.querySelector(a.titleDiv)?.textContent?.trim(),S=l??U??"",r=s.querySelector(a.source)?.textContent?.trim()??"",c=s.querySelector(a.platformBadge)?.textContent?.trim()??"",h=s.querySelector(a.ytChannel)?.textContent?.trim()??"",m=s.querySelector(a.ytDate)?.textContent?.trim()??"",f=s.querySelector(a.authorNote)?.textContent?.trim()??null,M=s.querySelector(a.popularCommentLabel),y=null;if(M){let I=M.nextSibling;for(;I;){let R=I.textContent?.trim();if(R){y=R;break}I=I.nextSibling}}let A=Array.from(s.querySelectorAll("span")),O=A.find(I=>/^\d+:\d+$/.test(I.textContent?.trim()??""))?.textContent?.trim()??null,_=A.map(I=>I.textContent?.trim()??"").filter(I=>/\d/.test(I)&&(I.includes("comment")||I.includes("reaction")||I.includes("view")||I.includes("like")||I.includes("share")))[0]??"",N=A.map(I=>I.textContent?.trim()??"").filter(I=>/\d+ (day|week|month|year|hour)s? ago|Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec/.test(I)),W=m||(N[0]??""),P=c||(h?"YouTube":""),C=h||r,E="unknown",w=P.toLowerCase(),k=C.toLowerCase(),v=r.toLowerCase();return w.includes("reddit")||k.startsWith("r/")?E="reddit":w.includes("facebook")||v.includes("facebook")?E="facebook":w.includes("instagram")||v.includes("instagram")?E="instagram":w.includes("tiktok")||v.includes("tiktok")?E="tiktok":w.includes("youtube")||h?E="youtube":E="news",{type:E,title:S,url:d,source:C,platform:P,popularComment:y,engagement:_,date:W,duration:O,authorNote:f}}):[]},n)}async extractOrganicResults(t){let n=as,a=await t.evaluate(s=>{let o=[],d=0;return document.querySelectorAll(s.result).forEach(l=>{let U=l.querySelector(s.title);if(!U)return;let S=U.textContent?.trim()??"",u=U.closest("a")?.href??"";if(!S||!u)return;d++;let c=l.querySelector(s.cite)?.textContent?.trim()??null,h=l.querySelector(s.snippet)?.textContent?.trim()??null,m=!!l.querySelector(s.redditCite),f=l.querySelector(s.ratingWrap),M=f?{value:f.querySelector(s.ratingValue)?.textContent?.trim()??"",count:f.querySelector(s.reviewCount)?.textContent?.trim()??""}:null,y="";try{y=new URL(u).hostname.replace(/^www\./,"")}catch{y=l.querySelector(s.siteName)?.textContent?.trim()??""}o.push({position:d,title:S,url:u,domain:y,cite:c,snippet:h,isRedditStyle:m,inlineRating:M})}),o},n),i=typeof t.url=="function"?t.url():"https://www.google.com/";return a.flatMap(s=>{let o=Hn(s.url,i);if(!o)return[];let d=s.domain;try{d=new URL(o.resolvedUrl??o.rawUrl).hostname.replace(/^www\./,"")}catch{}return[{...s,...o,domain:d}]})}async extractLocalPack(t){let n=is;return t.evaluate(a=>{let i=[],s=null;return document.querySelectorAll('[role="heading"]').forEach(o=>{!s&&o.textContent?.includes(a.headingText)&&(s=o.closest("[data-hveid]"))}),s&&s.querySelectorAll(a.card).forEach((o,d)=>{let l=o.querySelector(a.name)?.textContent?.trim()??"";if(!l)return;let U=o.querySelector(a.ratingValue)?.textContent?.trim()??null,S=o.querySelector(a.reviewCount)?.textContent?.trim()??null,r=S?S.replace(/[()]/g,"").trim():null,u=o.querySelector("a[data-cid]")?.getAttribute("data-cid")??null;if(!u)for(let M of Array.from(o.querySelectorAll("a[href]"))){let y=M.href.match(/[?&]cid=(\d+)/);if(y){u=y[1];break}let A=M.href.match(/!1s0x[0-9a-f]+:0x([0-9a-f]+)/i);if(A){try{u=BigInt("0x"+A[1]).toString()}catch{}if(u)break}}let c=[];o.querySelectorAll("div, span").forEach(M=>{let y=Array.from(M.childNodes).filter(A=>A.nodeType===3).map(A=>A.textContent?.trim()??"").filter(A=>A.length>1&&A.length<120).join(" ");y&&!c.includes(y)&&c.push(y)});let h=Array.from(o.querySelectorAll("a[href]")),m=h.find(M=>M.href.includes("google.com/maps"))?.href??null,f=h.find(M=>!M.href.includes("google.com")&&M.href.startsWith("http"))?.href??null;i.push({position:d+1,name:l,cid:u,rating:U,reviewCount:r,metadata:c,websiteUrl:f,directionsUrl:m})}),i},n)}async extractEntityIds(t){return t.evaluate(()=>{let n=new Set,a=new Set,i=new Set,s=new Map;function o(l){let U=[".OSrXXb",".dbg0pd",".tzt0oe",'[role="heading"]',"h3"];for(let S of U){let r=l.querySelector(S);if(r?.textContent?.trim())return r.textContent.trim()}return""}document.querySelectorAll('[id^="pv-/g/"]').forEach(l=>{let U=l.getAttribute("id");if(!U)return;let S=U.replace("pv-","");n.add(S);let r=o(l),c=l.querySelector("a[data-cid]")?.getAttribute("data-cid")??null;c&&a.add(c),r&&s.set(S,{name:r,kgId:S,cid:c,gcid:null})}),document.querySelectorAll("[data-mid]").forEach(l=>{let U=l.getAttribute("data-mid");if(U?.startsWith("/g/")&&(n.add(U),!s.has(U))){let S=o(l);S&&s.set(U,{name:S,kgId:U,cid:null,gcid:null})}}),document.querySelectorAll(".w7Dbne").forEach(l=>{let S=l.querySelector("a[data-cid]")?.getAttribute("data-cid")??null;if(!S)return;a.add(S);let r=l.querySelector(".OSrXXb")?.textContent?.trim()??"";if(!r)return;let u=l.querySelector('[id^="pv-/g/"]'),c=u?u.getAttribute("id").replace("pv-",""):null,h=c??`cid:${S}`;if(s.has(h)){let m=s.get(h);m.cid||s.set(h,{...m,cid:S})}else s.set(h,{name:r,kgId:c,cid:S,gcid:null})}),document.querySelectorAll("a[data-cid]").forEach(l=>{let U=l.getAttribute("data-cid");if(!U)return;if(a.add(U),![...s.values()].some(r=>r.cid===U)){let r=l.parentElement,u="";for(let c=0;c<8&&r;c++){let h=r.querySelector('.OSrXXb, .dbg0pd, [role="heading"], h3');if(h?.textContent?.trim()){u=h.textContent.trim();break}r=r.parentElement}u&&s.set(`cid:${U}`,{name:u,kgId:null,cid:U,gcid:null})}});let d=Array.from(document.querySelectorAll("script:not([src])")).map(l=>l.textContent??"").filter(l=>l.length>1e4).join(`
|
|
21896
|
+
`);for(let l of d.matchAll(/\/g\/[a-zA-Z0-9_-]{5,20}/g))n.add(l[0]);for(let l of d.matchAll(/gcid:[a-zA-Z0-9_]+/g))i.add(l[0]);for(let l of d.matchAll(/0x[0-9a-f]+:0x([0-9a-f]+)/gi))try{a.add(BigInt("0x"+l[1]).toString())}catch{}return{entities:[...s.values()],kgIds:[...n],cids:[...a],gcids:[...i]}})}mergeLocalPackIntoEntities(t,n){let a=new Set(t.cids),i=t.entities.map(s=>({...s}));for(let s of n){if(!s.cid)continue;a.add(s.cid);let o=s.name.toLowerCase().trim(),d=i.find(l=>l.name.toLowerCase().trim()===o);d?d.cid||(d.cid=s.cid):i.find(l=>l.cid===s.cid)||i.push({name:s.name,kgId:null,cid:s.cid,gcid:null})}return{...t,entities:i,cids:[...a]}}async extractAISurfaces(t,n){let a=await t.evaluate(Bs,{aio:es,aim:ns,expandWaitMs:1500}),i=typeof t.url=="function"?t.url():"https://www.google.com/",s={surface:a.surface,aiOverview:{...a.aiOverview,citations:this.normalizeAICitations(i,a.aiOverview.citations)},aiMode:{...a.aiMode,citations:this.normalizeAICitations(i,a.aiMode.citations)}};if(!s.aiOverview.detected)return this.completeness.aioShareCaptured=null,s;let o=this.aioShareUrlEarly??await this.captureAIOverviewShareUrl(t,n).catch(()=>null);return this.completeness.aioShareCaptured=o!==null,{...s,aiOverview:{...s.aiOverview,shareUrl:o}}}async captureAIOverviewShareUrl(t,n){if(n?.softDeadlineMs&&Date.now()>=n.softDeadlineMs||!await t.evaluate(()=>{let s=Array.from(document.querySelectorAll('h1,h2,h3,[role="heading"],div')).filter(o=>(o.textContent||"").trim()==="AI Overview");for(let o of s){let d=o;for(let l=0;l<8&&d;l++){let U=d.querySelector('[aria-label="Share"]');if(U)return U.scrollIntoView({block:"center"}),U.click(),!0;d=d.parentElement}}return!1}).catch(()=>!1))return null;let i=null;try{i=await(await t.waitForFunction(()=>{let o=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT);for(;o.nextNode();){let d=(o.currentNode.textContent||"").match(/https:\/\/share\.google\/aimode\/\S+/);if(d)return d[0]}return!1},void 0,{timeout:4500,polling:250})).jsonValue()}catch{i=null}return await t.keyboard.press("Escape").catch(()=>{}),i}buildTree(t,n){let a=[],i=new Map;for(let s of t){let o={questionId:s.question_id,googleLinkId:s.google_link_id||null,googleEvidenceId:s.google_evidence_id||null,question:s.question,answer:s.answer||null,sourceTitle:s.source_title||null,sourceSite:s.source_site||null,sourceCite:s.source_cite||null,sources:s.sources??[],depth:s.depth,parentQuestion:s.parent_question||null,children:[]};i.set(s.question,o)}for(let s of i.values())s.parentQuestion&&i.has(s.parentQuestion)?i.get(s.parentQuestion).children.push(s):a.push(s);return a}getBrowserDebugSnapshot(){return this.driver.getDebugSnapshot()}buildHarvestDebugSnapshot(t,n,a,i,s){if(t.debug)return{enabled:!0,request:{query:t.query,locationInput:t.location??null,canonicalLocation:n,locationResolved:s?s.matched:null,locationMatchSource:s?s.source:null,locationAmbiguousCandidates:s?s.ambiguousCandidates:null,uule:a,gl:t.gl,hl:t.hl,device:t.device,proxyMode:t.proxyMode,proxyZip:t.proxyZip??null,serpIdentity:t.serpIdentity??null,serpOnly:t.serpOnly,pages:t.pages??1},browser:this.getBrowserDebugSnapshot(),...i?{locationEvidence:i}:{}}}async captureSecondOrganicPage(t,n,a){if(this.throwIfAborted(a),!this.driver.withTemporaryPage)return{organic:[],status:"failed",failureCode:"unsupported_driver"};let i;try{let s=new URL(t.url()),o=U=>{try{let S=new URL(U,s);return s.origin==="https://www.google.com"&&S.origin===s.origin&&!S.username&&!S.password&&S.pathname==="/search"&&S.searchParams.getAll("q").length===1&&S.searchParams.get("q")===n.query&&S.searchParams.getAll("start").length===1&&S.searchParams.get("start")==="10"&&(!S.searchParams.has("num")||S.searchParams.get("num")==="10")&&["gl","hl"].every(r=>!S.searchParams.has(r)||S.searchParams.getAll(r).length===1&&S.searchParams.get(r)===n[r])&&["uule","tbs","udm","tbm","pws"].every(r=>S.searchParams.getAll(r).length<=1&&S.searchParams.get(r)===s.searchParams.get(r))}catch{return!1}},d=await t.evaluate(()=>document.querySelector('a#pnnext, a[rel="next"]')?.getAttribute("href")??null);if(!d)return{organic:[],status:"unavailable",failureCode:"missing_next"};if(!o(d))return{organic:[],status:"unavailable",failureCode:"invalid_next"};let l=await this.driver.withTemporaryPage(async U=>{if(await U.route("**/*",async S=>{let r=S.request();r.isNavigationRequest()&&r.frame()===U.mainFrame()&&!o(r.url())?(i=/^https:\/\/www\.google\.com\/sorry(?:\/|\?)/.test(r.url())?"captcha":"invalid_next",await S.abort("blockedbyclient")):await S.fallback()}),await U.goto(new URL(d,s).href,{waitUntil:"domcontentloaded",timeout:2e4}),this.throwIfAborted(a),await this.throwIfCaptcha(U,"Google SERP page 2"),!o(U.url()))throw i="invalid_next",new Error("Invalid pagination landing");return this.extractOrganicResults(U)},a);return this.throwIfAborted(a),l.length>0?{organic:l.map(U=>({...U,position:U.position+10})),status:"captured"}:{organic:[],status:"unavailable",failureCode:"empty_page"}}catch(s){if(this.throwIfAborted(a),s instanceof gt)throw s;return{organic:[],status:"failed",failureCode:i??(s instanceof at?"captcha":s instanceof Error&&(s.name==="TimeoutError"||/timed? ?out/i.test(s.message))?"timeout":"navigation_error")}}}async extract(t,n){let a=Date.now();this.completeness={paaWithoutAnswer:0,paaWithoutSource:0,paaAnswersRecovered:0,aioShareCaptured:null},this.linkDiagnostics=this.emptyLinkDiagnostics(),this.aioShareUrlEarly=null,this.collectedRows=[],this.progressSequence=0,this.checkpointMaterial=null,this.clickedQuestions=new Set,this.paaLifecycle=this.emptyPaaLifecycle(t.maxQuestions),this.partialContext={seed:t.query,location:t.location??null,startMs:a,maxQuestions:t.maxQuestions,questionsOnly:t.questionsOnly};let i=t.device==="mobile",s={headless:t.headless,profileDir:t.profileDir,proxy:t.proxy,\u006b\u0065\u0072\u006e\u0065\u006cApiKey:t.\u006b\u0065\u0072\u006e\u0065\u006cApiKey,\u006b\u0065\u0072\u006e\u0065\u006cProxyId:t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId,\u006b\u0065\u0072\u006e\u0065\u006cProfileName:t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName,\u006b\u0065\u0072\u006e\u0065\u006cProfileSaveChanges:t.\u006b\u0065\u0072\u006e\u0065\u006cProfileSaveChanges,\u006b\u0065\u0072\u006e\u0065\u006cStealth:t.\u006b\u0065\u0072\u006e\u0065\u006cStealth,\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution:t.\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution,proxyMode:t.proxyMode,keepDefaultProxy:t.keepDefaultProxy,requireUsEgress:t.requireUsEgress,viewport:i?{width:390,height:844}:{width:1280,height:800},locale:`${t.hl}-${t.gl.toUpperCase()}`,deviceScaleFactor:i?3:1,isMobile:i,hasTouch:i,debug:t.debug,operationDeadlineMs:t.softDeadlineMs},o=0,d=[];try{this.throwIfAborted(n);let l=Date.now();await this.driver.launch(s),this.phaseTimings.providerConnectMs=Date.now()-l;let U=this.driver.getProviderSessionMetadata();if(U?.providerSessionId&&this.onProviderSession)try{await this.onProviderSession(U)}catch(G){console.warn(JSON.stringify({event:"paa_provider_session_sink_failed",provider:U.provider,message:G instanceof Error?G.message:String(G)}))}this.throwIfAborted(n);let S=t.location?Wa(t.location):null,r=t.location?S?.canonical??t.location:null,u=r?Ls(r):null,c=t,h=t.includeAllSerpFeatures,m=h||t.includeLocalPack,f=h||t.includeForums,M=h||t.includeVideos,y=h||t.includeAiOverview,A=h||t.includeWhatPeopleSaying,O={surface:"web",aiOverview:{detected:!1,text:null,citations:[]},aiMode:{detected:!1,text:null,citations:[]}},B=Date.now(),{hasPaa:_}=await this.driver.navigateToSERP(c.query,u,t.gl,t.hl,{...He(t.recency)?{tbs:He(t.recency)}:{},debug:t.debug,purpose:t.serpOnly?"serp":"paa",...t.softDeadlineMs?{deadlineMs:t.softDeadlineMs}:{}});this.phaseTimings.navigationMs=Date.now()-B,this.throwIfAborted(n);let N=this.driver.getPage();if(await this.throwIfCaptcha(N,"Google SERP"),_||(this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"no_paa_observed",materialStatus:"complete",completionReason:"A readable Google SERP was observed without a People Also Ask block."}),t.questionsOnly){let G=Date.now(),tt=_?await this.runBFS(N,c,n):[];this.phaseTimings.paaExpansionMs=Date.now()-G,await this.resolveMaterialLinks(N,tt,[],O.aiOverview,O.aiMode);let J={seed:c.query,totalQuestions:tt.length,maxDepthReached:tt.reduce(($,pt)=>Math.max($,pt.depth),0),durationMs:Date.now()-a,errorCount:o};return this.reporter.onComplete(J),{seed:c.query,location:t.location??null,extractedAt:new Date().toISOString(),diagnostics:{phaseTimings:this.currentPhaseTimings(a),completionStatus:_?"paa_found":"no_paa",..._?{}:{noPaaObserved:!0},problem:null,paaLifecycle:{...this.paaLifecycle},completeness:{...this.completeness},links:{...this.linkDiagnostics},...t.debug?{debug:this.buildHarvestDebugSnapshot(c,r,u,void 0,S)}:{}},totalQuestions:tt.length,surface:"web",aiOverview:{detected:!1,text:null,citations:[]},aiMode:{detected:!1,text:null,citations:[]},whatPeopleSaying:[],tree:this.buildTree(tt,c.query),flat:tt,videos:[],forums:[],organicResults:[],localPack:[],entityIds:{entities:[],kgIds:[],cids:[],gcids:[]},stats:J}}if(y&&(this.aioShareUrlEarly=await this.captureAIOverviewShareUrl(N,t).catch(()=>null)),t.serpOnly){let G=Date.now(),[tt,J,$]=await Promise.all([this.extractOrganicResults(N),m?this.extractLocalPack(N):Promise.resolve([]),this.extractEntityIds(N)]),pt=this.mergeLocalPackIntoEntities($,J),Ct=y?await this.extractAISurfaces(N,t):O;this.phaseTimings.serpParseMs=Date.now()-G;let sn=t.debug?Qe(r,tt,J):void 0,ae=tt;if((t.pages??1)>=2){let We=new URLSearchParams({q:c.query,gl:t.gl,hl:t.hl,pws:"0",start:"10"});He(t.recency)&&We.set("tbs",He(t.recency)),u&&We.set("uule",u),await this.driver.navigateTo("https://www.google.com/search?"+We.toString()),await this.throwIfCaptcha(N,"Google SERP page 2");let rn=await this.extractOrganicResults(N);ae=[...tt,...rn.map(ie=>({...ie,position:ie.position+10}))],t.debug&&(sn=Qe(r,ae,J))}await this.resolveMaterialLinks(N,[],ae,Ct.aiOverview,Ct.aiMode);let on={seed:c.query,totalQuestions:0,maxDepthReached:0,durationMs:Date.now()-a,errorCount:o};return this.reporter.onComplete(on),{seed:c.query,location:t.location??null,extractedAt:new Date().toISOString(),diagnostics:{phaseTimings:this.currentPhaseTimings(a),completionStatus:"serp_only",problem:null,completeness:{...this.completeness},links:{...this.linkDiagnostics},...t.debug?{debug:this.buildHarvestDebugSnapshot(c,r,u,sn,S)}:{}},totalQuestions:0,surface:Ct.surface,aiOverview:Ct.aiOverview,aiMode:Ct.aiMode,whatPeopleSaying:[],tree:[],flat:[],videos:[],forums:[],organicResults:ae,localPack:J,entityIds:pt,stats:on}}let[W,P,C,E,w,k]=await Promise.all([M?this.extractVideos(N):Promise.resolve([]),f?this.extractForums(N):Promise.resolve([]),A?this.extractWhatPeopleSaying(N):Promise.resolve([]),this.extractEntityIds(N),this.extractOrganicResults(N),m?this.extractLocalPack(N):Promise.resolve([])]),v=this.mergeLocalPackIntoEntities(E,k),I=t.debug?Qe(r,w,k):void 0;this.reporter.onVideos(W),this.reporter.onForums(P);let R=y?await this.extractAISurfaces(N,t):O,L={requestedPages:(t.pages??1)>=2?2:1,capturedPages:1,page2Status:(t.pages??1)>=2?"not_attempted":"not_requested",page1OrganicCount:w.length,page2OrganicCount:0},x=w;if(this.checkpointMaterial={surface:R.surface,aiOverview:R.aiOverview,aiMode:R.aiMode,whatPeopleSaying:C,videos:W,forums:P,organicResults:x,localPack:k,entityIds:v,pagination:L},await this.emitProgress("serp_captured"),L.requestedPages===2){let G=await this.captureSecondOrganicPage(N,c,n);x=[...w,...G.organic],L={...L,capturedPages:G.status==="captured"?2:1,page2Status:G.status,page2OrganicCount:G.organic.length,...G.failureCode?{failureCode:G.failureCode}:{}},this.checkpointMaterial={...this.checkpointMaterial,organicResults:x,pagination:L},await this.emitProgress("serp_captured"),await this.resolveMaterialLinks(N,[],x,R.aiOverview,R.aiMode),this.checkpointMaterial={...this.checkpointMaterial,organicResults:x},await this.emitProgress("serp_captured")}let X=t.debug?Qe(r,x,k):I;if(!_){await this.resolveMaterialLinks(N,[],x,R.aiOverview,R.aiMode),this.checkpointMaterial={...this.checkpointMaterial,organicResults:x},await this.emitProgress("serp_captured");let G={seed:c.query,totalQuestions:0,maxDepthReached:0,durationMs:Date.now()-a,errorCount:o};return this.reporter.onComplete(G),{seed:c.query,location:t.location??null,extractedAt:new Date().toISOString(),diagnostics:{phaseTimings:this.currentPhaseTimings(a),completionStatus:"no_paa",noPaaObserved:!0,problem:null,pagination:L,paaLifecycle:{...this.paaLifecycle},completeness:{...this.completeness},links:{...this.linkDiagnostics},...t.debug?{debug:this.buildHarvestDebugSnapshot(c,r,u,X,S)}:{}},totalQuestions:0,surface:R.surface,aiOverview:R.aiOverview,aiMode:R.aiMode,whatPeopleSaying:C,tree:[],flat:[],videos:W,forums:P,organicResults:x,localPack:k,entityIds:v,stats:G}}let ut=Date.now(),it=await this.runBFS(N,c,n);this.phaseTimings.paaExpansionMs=Date.now()-ut,this.throwIfAborted(n);let q=new URLSearchParams({q:c.query,gl:t.gl,hl:t.hl,pws:"0",udm:vn.udm});u&&q.set("uule",u);let ct=[];if(t.includeShortVideos!==!1)try{ct=await this.extractShortVideos(N,"https://www.google.com/search?"+q.toString())}catch(G){if(!(G instanceof at))throw G;o++,d.push({code:"short_videos_captcha_skipped",surface:"short_videos",message:G.message,retryable:!0})}this.reporter.onVideos(ct),await this.resolveMaterialLinks(N,it,x,R.aiOverview,R.aiMode),this.checkpointMaterial={...this.checkpointMaterial,surface:R.surface,aiOverview:R.aiOverview,aiMode:R.aiMode,videos:[...W,...ct],organicResults:x},await this.emitProgress("expansion_finished");let Re=[...W,...ct],F=this.buildTree(it,c.query),yt={seed:c.query,totalQuestions:it.length,maxDepthReached:it.reduce((G,tt)=>Math.max(G,tt.depth),0),durationMs:Date.now()-a,errorCount:o};return this.reporter.onComplete(yt),{seed:c.query,location:t.location??null,extractedAt:new Date().toISOString(),diagnostics:{phaseTimings:this.currentPhaseTimings(a),completionStatus:"paa_found",problem:null,pagination:L,paaLifecycle:{...this.paaLifecycle},completeness:{...this.completeness},links:{...this.linkDiagnostics},...d.length>0?{warnings:d}:{},...t.debug?{debug:this.buildHarvestDebugSnapshot(c,r,u,X,S)}:{}},totalQuestions:it.length,surface:R.surface,aiOverview:R.aiOverview,aiMode:R.aiMode,whatPeopleSaying:C,tree:F,flat:it,videos:Re,forums:P,organicResults:x,localPack:k,entityIds:v,stats:yt}}catch(l){throw o++,this.paaLifecycle.discoveryStatus==="in_progress"&&(this.paaLifecycle={...this.paaLifecycle,discoveryStatus:"interrupted",completionReason:"The browser attempt ended before frontier exhaustion could be proven."}),await this.emitProgress("attempt_ending").catch(()=>{}),this.reporter.onError(l instanceof Error?l:new Error(String(l))),l}}};var ot=require("fs"),xt=un(require("path"),1),te=un(require("papaparse"),1);async function Qs(e){if((process.env.NODE_ENV==="test"||process.env.VITEST)&&process.env.MCP_SCRAPER_ENABLE_MEMORY_LIBRARY_SINK_IN_TESTS!=="1")return;let t=process.env.MCP_SCRAPER_API_KEY?.trim(),n=(process.env.MCP_SCRAPER_BASE_URL??"https://mcpscraper.dev").replace(/\/$/,"");if(t)try{let a=await fetch(`${n}/memory/mcp-call`,{method:"POST",headers:{"content-type":"application/json","x-api-key":t},body:JSON.stringify({toolName:"libraryIngestTool",args:e})}),i=await a.json().catch(()=>null);(!a.ok||i?.ok===!1)&&console.warn("[memory-library-sink] ingest not accepted:",a.status,i?.error??"")}catch(a){console.warn("[memory-library-sink] ingest failed:",a?.message)}}var Dn=class{async writeJSON(t,n){await ot.promises.mkdir(n,{recursive:!0});let i=`${t.seed.toLowerCase().replace(/\W+/g,"-").slice(0,40)}-${Date.now()}.json`,s=xt.default.join(n,i);return await ot.promises.writeFile(s,JSON.stringify(t,null,2),"utf8"),await Qs({title:`${t.seed} scrape`,content:JSON.stringify(t),source:`mcp-scraper:${s}`}),s}async writeCSV(t,n){await ot.promises.mkdir(n,{recursive:!0});let i=(t[0]?.seed_query??"paa").toLowerCase().replace(/\W+/g,"-").slice(0,40),s=te.default.unparse(t.map(({sources:l,...U})=>({...U,sources_json:JSON.stringify(l)})),{header:!0}),o=`${i}-${Date.now()}.csv`,d=xt.default.join(n,o);return await ot.promises.writeFile(d,s,"utf8"),d}async writeVideoCSV(t,n,a){await ot.promises.mkdir(a,{recursive:!0});let i=n.toLowerCase().replace(/\W+/g,"-").slice(0,40),s=te.default.unparse(t,{header:!0}),o=`${i}-videos-${Date.now()}.csv`,d=xt.default.join(a,o);return await ot.promises.writeFile(d,s,"utf8"),d}async writeForumCSV(t,n,a){await ot.promises.mkdir(a,{recursive:!0});let i=n.toLowerCase().replace(/\W+/g,"-").slice(0,40),s=te.default.unparse(t,{header:!0}),o=`${i}-forums-${Date.now()}.csv`,d=xt.default.join(a,o);return await ot.promises.writeFile(d,s,"utf8"),d}async writeAIOverviewCSV(t,n,a,i){await ot.promises.mkdir(i,{recursive:!0});let s=a.toLowerCase().replace(/\W+/g,"-").slice(0,40),o=t.map((S,r)=>({seed_query:a,response_text:r===0?n??"":"",citation_text:S.text,citation_href:S.href})),d=te.default.unparse(o,{header:!0}),l=`${s}-ai-overview-${Date.now()}.csv`,U=xt.default.join(i,l);return await ot.promises.writeFile(U,d,"utf8"),U}async writeAIModeCSV(t,n,a,i){await ot.promises.mkdir(i,{recursive:!0});let s=a.toLowerCase().replace(/\W+/g,"-").slice(0,40),o=t.map((S,r)=>({seed_query:a,response_text:r===0?n??"":"",citation_text:S.text,citation_href:S.href})),d=te.default.unparse(o,{header:!0}),l=`${s}-ai-mode-${Date.now()}.csv`,U=xt.default.join(i,l);return await ot.promises.writeFile(U,d,"utf8"),U}async writeWhatPeopleSayingCSV(t,n,a){await ot.promises.mkdir(a,{recursive:!0});let i=n.toLowerCase().replace(/\W+/g,"-").slice(0,40),s=t.map(U=>({seed_query:n,...U})),o=te.default.unparse(s,{header:!0}),d=`${i}-what-people-saying-${Date.now()}.csv`,l=xt.default.join(a,d);return await ot.promises.writeFile(l,o,"utf8"),l}};var Fn=class{onQuestion(t){process.stdout.write(JSON.stringify({event:"question",depth:t.depth,question:t.question})+`
|
|
21897
21897
|
`)}onDepth(t){process.stdout.write(JSON.stringify({event:"depth",depth:t})+`
|
|
21898
21898
|
`)}onVideos(t){for(let n of t)process.stdout.write(JSON.stringify({event:"video",type:n.type,platform:n.platform,duration:n.duration,title:n.title,channel:n.channel,url:n.url})+`
|
|
21899
21899
|
`)}onForums(t){for(let n of t)process.stdout.write(JSON.stringify({event:"forum",title:n.title,source:n.source,url:n.url})+`
|
|
21900
21900
|
`)}onComplete(t){process.stdout.write(JSON.stringify({event:"complete",...t})+`
|
|
21901
21901
|
`)}onError(t){process.stderr.write(JSON.stringify({event:"error",type:t.constructor.name,message:t.message})+`
|
|
21902
|
-
`)}};var Zs=require("crypto");var dl="pr.oxylabs.io",ll=7777,Sl=10;function to(){return process.env.OXYLABS_USERNAME?.trim()||void 0}function eo(){return process.env.OXYLABS_PASSWORD?.trim()||void 0}function Ul(){return(process.env.OXYLABS_COUNTRY?.trim()||"US").toUpperCase()}function no(){return!!(to()&&eo())}function ul(){let e="";for(let t=0;t<10;t++)e+=String((0,Zs.randomInt)(0,10));return e}function cl(e={}){let t=to();if(!t)return;let n=t.startsWith("customer-")?t:`customer-${t}`,a=(e.country?.trim()||Ul()).toUpperCase(),i=e.sticky?`-sessid-${ul()}-sesstime-${Sl}`:"";return`${n}-cc-${a}${i}`}function Fa(e){return e.replace(/pr\.oxylabs\.io(:\d+)?/gi,"backup proxy").replace(/oxylabs/gi,"backup proxy")}function hl(e){return`mcp-backup-custom-${`${Date.now()}-${e??0}-${Math.random().toString(36).slice(2,8)}`}`}async function ao(e,t={}){let n=cl({sticky:t.sticky}),a=eo();if(!n||!a)throw new Error("backup proxy pool is not configured");let i=new H({apiKey:e});try{let s=await i.proxies.create({type:"custom",name:hl(t.attemptIndex),protocol:"http",config:{host:dl,port:ll,username:n,password:a}});if(!s.id)throw new Error("backup proxy creation did not return a proxy id");return s.id}catch(s){let o=s instanceof Error?s.message:String(s);throw new Error(Fa(o))}}var gl={alabama:"AL",alaska:"AK",arizona:"AZ",arkansas:"AR",california:"CA",colorado:"CO",connecticut:"CT",delaware:"DE",florida:"FL",georgia:"GA",hawaii:"HI",idaho:"ID",illinois:"IL",indiana:"IN",iowa:"IA",kansas:"KS",kentucky:"KY",louisiana:"LA",maine:"ME",maryland:"MD",massachusetts:"MA",michigan:"MI",minnesota:"MN",mississippi:"MS",missouri:"MO",montana:"MT",nebraska:"NE",nevada:"NV","new hampshire":"NH","new jersey":"NJ","new mexico":"NM","new york":"NY","north carolina":"NC","north dakota":"ND",ohio:"OH",oklahoma:"OK",oregon:"OR",pennsylvania:"PA","rhode island":"RI","south carolina":"SC","south dakota":"SD",tennessee:"TN",texas:"TX",utah:"UT",vermont:"VT",virginia:"VA",washington:"WA","west virginia":"WV",wisconsin:"WI",wyoming:"WY"},pl={"atlanta|GA":"30303","austin|TX":"78701","baltimore|MD":"21201","boston|MA":"02108","boulder|CO":"80302","charlotte|NC":"28202","chicago|IL":"60601","colorado_springs|CO":"80903","columbus|OH":"43215","dallas|TX":"75201","denver|CO":"80202","detroit|MI":"48226","fort_collins|CO":"80524","fort_worth|TX":"76102","houston|TX":"77002","indianapolis|IN":"46204","jacksonville|FL":"32202","las_vegas|NV":"89101","los_angeles|CA":"90012","louisville|KY":"40202","loveland|CO":"80537","memphis|TN":"38103","miami|FL":"33131","minneapolis|MN":"55401","nashville|TN":"37203","new_york|NY":"10001","orlando|FL":"32801","philadelphia|PA":"19103","phoenix|AZ":"85004","portland|OR":"97205","raleigh|NC":"27601","richmond|VA":"23219","sacramento|CA":"95814","salt_lake_city|UT":"84101","san_antonio|TX":"78205","san_diego|CA":"92101","san_francisco|CA":"94103","san_jose|CA":"95113","seattle|WA":"98101"};function wl(e){return e?e.slice(-6):null}function rt(e,t,n,a,i,s=!1){return{\u006b\u0065\u0072\u006e\u0065\u006cProxyId:n,...s&&n?{disposableProxyId:n}:{},resolution:{source:e,proxyType:e==="disabled"?"none":e==="configured_fallback"?"configured":e==="isp_created"?"isp":e==="backup_custom"?"custom":e==="location_created"||e==="location_reused"?"residential":"unknown",proxyMode:t,proxyIdPresent:!!n,proxyIdSuffix:wl(n),target:a,error:i,disposable:s}}}function ml(e){return e.trim().toLowerCase().replace(/\s+/g," ")}function yl(e){return e.trim().toLowerCase().replace(/\./g,"").replace(/\s+/g," ")}function Cl(e){if(!e)return!0;let t=yl(e);return t==="united states"||t==="united states of america"||t==="usa"||t==="us"}function io(e){let t=e.trim();return/^[A-Za-z]{2}$/.test(t)?t.toUpperCase():gl[ml(t)]??null}function Tl(e){let n=e.normalize("NFKD").replace(/[^\x00-\x7F]/g,"").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean),a=n.join("_"),i=n.join("");return Array.from(new Set([a,i].filter(Boolean)))}function Rt(e,t,n){return n?`mcp-serp-residential-${e.toLowerCase()}-${t.toLowerCase()}-${n}`:`mcp-serp-residential-${e.toLowerCase()}-${t.toLowerCase()}`}function Gn(e,t){let n=`${Date.now()}-${t??0}-${Math.random().toString(36).slice(2,8)}`;return`${e}-fresh-${n}`}function kl(e){return`mcp-serp-residential-us-zip-${e}`}function fl(e,t){if(!e||t.toLowerCase()!=="us")return null;let n=xs(e),a=n.split(",").map(U=>U.trim()).filter(Boolean);if(a.length>1&&Cl(a[a.length-1])&&(a=a.slice(0,-1)),a.length===1){let U=io(a[0]);return U?{canonicalLocation:n,level:"state",country:"US",state:U,city:"",cityCandidates:[],proxyName:Rt("US",U),config:{country:"US",state:U}}:null}let[i="",s=""]=a;if(!i||!s)return null;let o=io(s);if(!o)return null;let d=Tl(i),l=d[0];return l?{canonicalLocation:n,level:"city",country:"US",state:o,city:l,cityCandidates:d,proxyName:Rt("US",o,l),config:{country:"US",state:o,city:l}}:null}function Ml(e){return`${e.city}|${e.state}`}function so(e,t){return t&&/^\d{5}$/.test(t)?t:pl[Ml(e)]??null}function oo(e,t){return{...e,level:"zip",zip:t,proxyName:kl(t),config:{country:e.country,state:e.state,zip:t}}}function Ga(e,t){return{...e,proxyName:t}}function Ya(e,t,n){return t.level==="zip"?e?.country?.toUpperCase()===t.country&&e?.zip===t.zip:e?.country?.toUpperCase()===t.country&&e?.state?.toUpperCase()===t.state&&(n?e?.city===n:!e?.city)}function Nl(e,t){return e.find(n=>n.type==="residential"&&n.status!=="unavailable"&&!!n.id&&(n.name===t.proxyName||Ya(n.config,t,t.level==="city"?t.city:void 0)))??null}function vl(e,t){for(let n of t.cityCandidates){let a=Rt(t.country,t.state,n),i=e.find(s=>s.type==="residential"&&s.status!=="unavailable"&&!!s.id&&(s.name===a||Ya(s.config,t,n)));if(i)return i}return null}function Vn(e){return{...e,level:"state",proxyName:Rt(e.country,e.state),config:{country:e.country,state:e.state}}}function bl(e,t){let n=Rt(t.country,t.state);return e.find(a=>a.type==="residential"&&a.status!=="unavailable"&&!!a.id&&(a.name===n||Ya(a.config,t)))??null}function _l(e,t){return Vn(e)}function Ot(e){return e instanceof Error?e.message:String(e)}function El(e,t,n){let a=[],i=so(e,t);if(i){let o=oo(e,i);a.push(Ga(o,Gn(o.proxyName,n)))}for(let o of e.cityCandidates){let d={...e,level:"city",city:o,proxyName:Rt(e.country,e.state,o),config:{country:e.country,state:e.state,city:o}};a.push(Ga(d,Gn(d.proxyName,n)))}let s=Vn(e);return a.push(Ga(s,Gn(s.proxyName,n))),a}async function Va(e,t,n){if(e.backupOnExhaustion&&n.length>0&&e.\u006b\u0065\u0072\u006e\u0065\u006cApiKey&&no())try{let a=await ao(e.\u006b\u0065\u0072\u006e\u0065\u006cApiKey,{attemptIndex:e.attemptIndex});return rt("backup_custom",e.proxyMode,a,t,null,!0)}catch(a){n.push(`backup: ${Fa(Ot(a))}`)}return rt("configured_fallback",e.proxyMode,e.configured\u004b\u0065\u0072\u006e\u0065\u006cProxyId,t,n.join(" | "))}async function Pl(e,t,n){let a=[];for(let i of El(n,t.proxyZip,t.attemptIndex))try{let s=await e.proxies.create({type:"residential",name:i.proxyName,config:i.level==="zip"?{country:i.country,zip:i.zip}:i.config});if(s.id)return rt("location_created",t.proxyMode,s.id,i,null,!0);a.push(`${i.proxyName}: \u004b\u0065\u0072\u006e\u0065\u006c did not return a proxy id`)}catch(s){a.push(`${i.proxyName}: ${Ot(s)}`)}if(process.env.\u004b\u0045\u0052\u004e\u0045\u004c_PROXY_TYPE!=="residential"){let i=Vn(n);try{let s=await e.proxies.create({type:"isp",name:Gn(`mcp-serp-isp-${i.country.toLowerCase()}-${(i.state??"").toLowerCase()}`,t.attemptIndex),config:{country:i.country,...i.state?{state:i.state}:{}}});if(s.id)return rt("isp_created",t.proxyMode,s.id,i,null,!0);a.push("isp: \u004b\u0065\u0072\u006e\u0065\u006c did not return a proxy id")}catch(s){a.push(`isp: ${Ot(s)}`)}}return Va(t,n,a)}async function ro(e,t){if(!e||!t)return;await new H({apiKey:e}).proxies.delete(t)}async function lo(e){if(e.proxyMode==="none")return rt("disabled",e.proxyMode,void 0,null,null);if(e.proxyMode==="configured")return rt("configured_fallback",e.proxyMode,e.configured\u004b\u0065\u0072\u006e\u0065\u006cProxyId,null,null);let t=fl(e.location,e.gl);if(!t||!e.\u006b\u0065\u0072\u006e\u0065\u006cApiKey)return rt("configured_fallback",e.proxyMode,e.configured\u004b\u0065\u0072\u006e\u0065\u006cProxyId,t,t?null:"location could not be normalized to a US city/state proxy target");let n=new H({apiKey:e.\u006b\u0065\u0072\u006e\u0065\u006cApiKey});try{let a=e.attemptIndex??0;if(e.fresh)return await Pl(n,e,t);if(a>=1){let S=_l(t,a),r=[];try{let u=await n.proxies.create({type:"residential",name:S.proxyName,config:S.config});if(u.id)return rt("location_created",e.proxyMode,u.id,S,null);r.push(`${S.state}: \u004b\u0065\u0072\u006e\u0065\u006c did not return a proxy id`)}catch(u){r.push(`${S.state}: ${Ot(u)}`)}return Va(e,S,r)}let i=[];for await(let S of await n.proxies.list())i.push(S);let s=so(t,e.proxyZip),o=[];if(s){let S=oo(t,s),r=Nl(i,S);if(r?.id)return rt("location_reused",e.proxyMode,r.id,S,null);try{let u=await n.proxies.create({type:"residential",name:S.proxyName,config:{country:S.country,zip:s}});if(u.id)return rt("location_created",e.proxyMode,u.id,S,null);o.push(`${s}: \u004b\u0065\u0072\u006e\u0065\u006c did not return a proxy id`)}catch(u){o.push(`${s}: ${Ot(u)}`)}}let d=vl(i,t);if(d?.id)return rt("location_reused",e.proxyMode,d.id,t,o.join(" | ")||null);for(let S of t.cityCandidates)try{let r=await n.proxies.create({type:"residential",name:Rt(t.country,t.state,S),config:{country:t.country,state:t.state,city:S}});if(r.id)return rt("location_created",e.proxyMode,r.id,{...t,level:"city",city:S,proxyName:Rt(t.country,t.state,S),config:{country:t.country,state:t.state,city:S}},null);o.push(`${S}: \u004b\u0065\u0072\u006e\u0065\u006c did not return a proxy id`)}catch(r){o.push(`${S}: ${Ot(r)}`)}let l=Vn(t),U=bl(i,l);if(U?.id)return rt("location_reused",e.proxyMode,U.id,l,o.join(" | "));try{let S=await n.proxies.create({type:"residential",name:l.proxyName,config:l.config});if(S.id)return rt("location_created",e.proxyMode,S.id,l,o.join(" | "));o.push(`${l.state}: \u004b\u0065\u0072\u006e\u0065\u006c did not return a proxy id`)}catch(S){o.push(`${l.state}: ${Ot(S)}`)}return Va(e,t,o)}catch(a){return rt("configured_fallback",e.proxyMode,e.configured\u004b\u0065\u0072\u006e\u0065\u006cProxyId,t,Ot(a))}}var en=class extends Error{constructor(t,n){super(`SERP provider mismatch: planned ${t}, observed ${n}`),this.name="SerpProviderMismatchError"}};function So(e){return e==="\u0062\u0072\u0069\u0067\u0068\u0074_\u0064\u0061\u0074\u0061_browser_api"?"\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061":"\u006b\u0065\u0072\u006e\u0065\u006c"}function Uo(e){return Il({intent:e.intent,\u0062\u0072\u0069\u0067\u0068\u0074\u0044\u0061\u0074\u0061Available:e.\u0062\u0072\u0069\u0067\u0068\u0074\u0044\u0061\u0074\u0061Available,\u006b\u0065\u0072\u006e\u0065\u006cAvailable:!0,persistent\u004b\u0065\u0072\u006e\u0065\u006cIdentityRequested:e.persistent\u004b\u0065\u0072\u006e\u0065\u006cIdentityRequested,retryIndex:e.retryIndex,priorTerminalReason:e.priorTerminalReason,allowedFallbacks:e.\u006b\u0065\u0072\u006e\u0065\u006cFallbackAvailable&&e.intent!=="\u006b\u0065\u0072\u006e\u0065\u006c"?["\u006b\u0065\u0072\u006e\u0065\u006c"]:[],timeoutMs:e.softDeadlineMs==null?4e5:Math.max(1,e.softDeadlineMs-Date.now())})}function uo(e){if(e.forceManagedSerp&&e.force\u004b\u0065\u0072\u006e\u0065\u006cSerp)throw new Error("forceManagedSerp and force\u004b\u0065\u0072\u006e\u0065\u006cSerp cannot both be true");return e.forceManagedSerp?"\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061":e.force\u004b\u0065\u0072\u006e\u0065\u006cSerp?"\u006b\u0065\u0072\u006e\u0065\u006c":"auto"}function Yn(e,t){if(!t)throw new Error(`Requested SERP provider is unavailable: ${e}`);return e}function Il(e){if(!Number.isInteger(e.retryIndex)||e.retryIndex<0)throw new Error("retryIndex must be a non-negative integer");if(!Number.isFinite(e.timeoutMs)||e.timeoutMs<=0)throw new Error("timeoutMs must be a positive number");let t,n;e.intent==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061"?(t=Yn("\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061",e.\u0062\u0072\u0069\u0067\u0068\u0074\u0044\u0061\u0074\u0061Available),n="explicit_\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061"):e.intent==="\u006b\u0065\u0072\u006e\u0065\u006c"?(t=Yn("\u006b\u0065\u0072\u006e\u0065\u006c",e.\u006b\u0065\u0072\u006e\u0065\u006cAvailable),n="explicit_\u006b\u0065\u0072\u006e\u0065\u006c"):e.persistent\u004b\u0065\u0072\u006e\u0065\u006cIdentityRequested?(t=Yn("\u006b\u0065\u0072\u006e\u0065\u006c",e.\u006b\u0065\u0072\u006e\u0065\u006cAvailable),n="persistent_\u006b\u0065\u0072\u006e\u0065\u006c_identity"):e.\u0062\u0072\u0069\u0067\u0068\u0074\u0044\u0061\u0074\u0061Available?(t="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061",n="managed_default"):(t=Yn("\u006b\u0065\u0072\u006e\u0065\u006c",e.\u006b\u0065\u0072\u006e\u0065\u006cAvailable),n="\u006b\u0065\u0072\u006e\u0065\u006c_default");let a=e.allowedFallbacks.find(o=>o!==t&&(o==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061"?e.\u0062\u0072\u0069\u0067\u0068\u0074\u0044\u0061\u0074\u0061Available:e.\u006b\u0065\u0072\u006e\u0065\u006cAvailable)),i=e.retryIndex>0&&a?a:t,s=e.retryIndex===0?"primary":i===t?"same_provider_retry":"provider_fallback";return Object.freeze({plannedProvider:i,attemptKind:s,reasonCode:s==="primary"?n:s==="provider_fallback"?"provider_fallback":"same_provider_retry",retryIndex:e.retryIndex,priorTerminalReason:e.priorTerminalReason??null,timeoutMs:Math.floor(e.timeoutMs),fallbackAllowed:!!a})}var Ja=2,Al=2,Ll=3e3;function qa(e){return e.reason instanceof DOMException&&e.reason.name==="TimeoutError"?e.reason:new gt}function xl(e){if(!e||typeof e!="object")return;let t=e.signal;if(t instanceof AbortSignal)return t}function Ol(e){if(!e||typeof e!="object")return;let t=e.onAttemptEvent;return typeof t=="function"?t:void 0}function Rl(e){if(!e||typeof e!="object")return;let t=e.onPaaProgress;return typeof t=="function"?t:void 0}function Wl(e){if(!e||typeof e!="object")return;let t=e.onPaaDomEvidence;return typeof t=="function"?t:void 0}async function Hl(e){let t=await e.evaluate(n=>{let a=n,i=Array.from(document.querySelectorAll(a.item)),s=i.map(l=>l.querySelector(a.clickTarget)).filter(l=>l!=null),o=l=>{let U=l.getBoundingClientRect();if(U.width<=0||U.height<=0)return!1;let S=U.left+U.width/2,r=U.top+U.height/2;if(S<0||r<0||S>=window.innerWidth||r>=window.innerHeight)return!1;let u=document.elementFromPoint(S,r);return u!=null&&u!==l&&!l.contains(u)&&!u.contains(l)},d=Array.from(document.querySelectorAll("body *")).filter(l=>{let U=window.getComputedStyle(l);if(U.position!=="fixed"&&U.position!=="sticky")return!1;let S=l.getBoundingClientRect();return S.width*S.height>=window.innerWidth*window.innerHeight*.15&&U.visibility!=="hidden"&&U.display!=="none"});return{itemCount:i.length,expandedItemCount:i.filter(l=>l.classList.contains(a.expandedClass)||l.querySelector(a.clickTarget)?.getAttribute("aria-expanded")==="true").length,answeredItemCount:i.filter(l=>(l.querySelector(a.answerContainer)?.textContent?.trim().length??0)>=10).length,sourcedItemCount:i.filter(l=>l.querySelector(`${a.answerContainer} a[href]`)!=null).length,clickTargetCount:s.length,clickTargetsWithButtonRole:s.filter(l=>l.getAttribute("role")==="button"||l.tagName==="BUTTON").length,clickTargetsWithExpandedState:s.filter(l=>l.hasAttribute("aria-expanded")).length,clickTargetsOffscreen:s.filter(l=>{let U=l.getBoundingClientRect(),S=U.left+U.width/2,r=U.top+U.height/2;return S<0||r<0||S>=window.innerWidth||r>=window.innerHeight}).length,clickTargetsBlockedAtCenter:s.filter(o).length,fixedOrStickyOverlayCount:d.length}},{item:Y.item,answerContainer:Y.answerContainer,clickTarget:Y.clickTarget,expandedClass:Y.expandedClass});return{capturedAt:new Date().toISOString(),...t,selectorVersion:ss}}async function xe(e,t){if(e)try{await e(t)}catch(n){console.warn(JSON.stringify({event:"harvest_attempt_log_failed",attempt_number:t.attemptNumber,message:n instanceof Error?n.message:String(n)}))}}function nn(e){if(e instanceof en)return"error";if(e instanceof at)return"captcha";if(e instanceof je)return"location_mismatch";if(e instanceof gt)return"request_aborted";if(e instanceof zt)return"browser_session_interrupted";if(e instanceof DOMException&&(e.name==="TimeoutError"||e.name==="AbortError"))return"timeout";let t=e instanceof Error?e.message:String(e);return/browser (?:has been )?closed|context (?:has been )?closed|target page, context or browser has been closed|session closed|page has been closed/i.test(t)?"browser_session_interrupted":Vl(t)?"proxy_tunnel_failed":Yl(t)?"proxy_unavailable":/timeout|timed out|Timeout \d+ms exceeded|deadline/i.test(t)?"timeout":"error"}function Bl(e){return e.diagnostics.degradedResult?"degraded_result":e.diagnostics?.completionStatus??(e.totalQuestions>0?"paa_found":"no_paa")}function Dl(e){return e.flat.length>0||e.organicResults.length>0||e.localPack.length>0||e.videos.length>0||e.forums.length>0||e.whatPeopleSaying.length>0||e.aiOverview.detected||e.aiMode.detected}function co(e,t,n){let a=Dl(e),i=(e.diagnostics.warnings?.length??0)>0,s=new Set(e.flat.map(m=>m.question.toLowerCase().replace(/[^\w\s]/g,"").replace(/\s+/g," ").trim())).size,o=n?0:e.flat.filter(m=>!m.answer?.trim()).length,d=n?0:e.flat.filter(m=>!m.source_cite?.trim()).length,l=e.diagnostics.completionStatus==="no_paa"&&(e.diagnostics.noPaaObserved===!0||a),U=e.diagnostics.completionStatus==="paa_found",S=e.diagnostics.paaLifecycle?.discoveryStatus,r=S==="interrupted"||S==="recovery_exhausted",u=U&&(s<t&&S!=="frontier_exhausted"||o>0||d>0||!!e.diagnostics.interruption||r),c=l?"complete":U&&s>0?u||i?"partial":"complete":a?i?"partial":"complete":"degraded",h=c==="degraded";return e.diagnostics={...e.diagnostics,resultQuality:c,degradedResult:h,degradationReasons:h?["empty_primary_serp"]:[],retryRecommended:h||c==="partial"&&(u||e.diagnostics.warnings?.some(m=>m.retryable)===!0),completeness:{paaWithoutAnswer:o,paaWithoutSource:d,paaAnswersRecovered:e.diagnostics.completeness?.paaAnswersRecovered??0,aioShareCaptured:e.diagnostics.completeness?.aioShareCaptured??null,paaRequested:t,paaReturned:e.flat.length,paaUnique:s},...e.diagnostics.paaLifecycle?{paaLifecycle:{...e.diagnostics.paaLifecycle,questionsFound:s,targetStatus:s>=t?"met":"not_met",materialStatus:o>0||d>0?"partial":"complete"}}:{}},e}function ho(e,t,n){let a=e.diagnostics.paaLifecycle;if(!a)return e;let i={...a.retryBreakdown,browserRetries:t,providerFallbacks:n};return{...e,diagnostics:{...e.diagnostics,paaLifecycle:{...a,retryBreakdown:i,automaticRetries:i.controlRetries+i.browserRetries+i.runtimeRecoveries}}}}function Fl(e){return(e.diagnostics.degradationReasons??[]).includes("empty_primary_serp")?"No usable primary SERP surface was captured; the result may be incomplete.":"The harvest result was marked degraded."}function mt(e){return e instanceof Error?e.message:String(e)}function Gl(e){return e==="location"?Al:Ja}function Vl(e){return/ERR_TUNNEL_CONNECTION_FAILED|ERR_PROXY_CONNECTION_FAILED|ERR_SOCKS_CONNECTION_FAILED|tunnel connection failed|proxy connection failed|transport error: proxy/i.test(e)}function Yl(e){return/proxy unavailable|proxy_unavailable|connection_test_failed|did not return a proxy id|configured fallback/i.test(e)}function go(e){return e==="captcha"||e==="proxy_tunnel_failed"||e==="proxy_unavailable"}function po(e){return e==="browser_session_interrupted"}function Kl(e){let t=e.diagnostics.debug?.locationEvidence,n=t?.expected?.canonicalLocation??e.location??"requested location",a=t?.candidates.slice(0,3).map(i=>`${i.city}, ${i.regionCode}`).join("; ");return a?`Google returned results for ${a}, not ${n}`:`Google returned results for a different location than ${n}`}function Jl(e,t){return t==="location"&&e.diagnostics.debug?.locationEvidence?.status==="mismatch"}function wo(e,t){if(t||!e.diagnostics.debug)return e;let n={...e.diagnostics};return delete n.debug,{...e,diagnostics:n}}async function mo(e,t){let n=t==null?3e3:t-Date.now();if(n<=0)return e;try{return await qs(e,{totalBudgetMs:Math.min(3e3,n)})}catch(a){return console.warn(JSON.stringify({event:"harvest_goto_resolution_failed",message:mt(a)})),e}}async function Ka(e,t){if(!(!e||!t))try{await ro(e,t),console.info(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_proxy_deleted",proxy_id_suffix:t.slice(-6)}))}catch(n){console.warn(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_proxy_delete_failed",proxy_id_suffix:t.slice(-6),message:mt(n)}))}}async function yo(e,t,n,a,i,s){let o=_s(t),d=new Fn,l=new Bn(o,d,a,i);if(n?.aborted)return{result:null,error:qa(n),cleanup:await o.close(),debug:null};let U,S=n?new Promise((m,f)=>{U=()=>f(qa(n)),n.addEventListener("abort",U,{once:!0})}):null,r=null,u=null,c,h=null;try{let m=l.extract(e,n);S&&m.catch(()=>{}),r=await(S?Promise.race([m,S]):m)}catch(m){u=m}finally{if(n&&U&&n.removeEventListener("abort",U),s){let m;try{let f=Hl(o);f.catch(()=>{});let M=await Promise.race([f,new Promise((y,A)=>{m=setTimeout(()=>A(new DOMException("PAA DOM evidence timed out","TimeoutError")),2e3)})]);await s(M)}catch(f){console.warn(JSON.stringify({event:"paa_dom_evidence_failed",message:mt(f)}))}finally{m&&clearTimeout(m)}}h=r?.diagnostics.debug??(e.debug?{enabled:!0,request:{query:e.query,locationInput:e.location??null,canonicalLocation:null,locationResolved:null,locationMatchSource:null,locationAmbiguousCandidates:null,uule:null,gl:e.gl,hl:e.hl,device:e.device,proxyMode:e.proxyMode,proxyZip:e.proxyZip??null,serpIdentity:e.serpIdentity??null,serpOnly:e.serpOnly,pages:e.pages??1},browser:o.getDebugSnapshot()}:null),c=await o.close()}if(u){let m=nn(u),f=m==="timeout"||m==="request_aborted"||m==="browser_session_interrupted"?m:null,M=null;if(f)try{M=typeof l.getPartialResult=="function"?l.getPartialResult():null}catch{M=null}return M&&f?(M.diagnostics={...M.diagnostics,interruption:{code:f,reasonSource:"client_runtime",message:mt(u)}},{result:M,error:u,cleanup:c,debug:h,salvagedFrom:u}):{result:null,error:u,cleanup:c,debug:h}}return{result:r,error:null,cleanup:c,debug:h}}async function Co(e){let t=typeof e=="object"&&e!==null?e:{},n=xl(e),a=Ol(e),i=Rl(e),s=Wl(e),o=t.forceManagedSerp===!0,d=t.force\u004b\u0065\u0072\u006e\u0065\u006cSerp===!0,l=uo({forceManagedSerp:o,force\u004b\u0065\u0072\u006e\u0065\u006cSerp:d}),U=t.proxyMode,S=U==="location"||U==="none"||U==="configured"?U:Qn,r=typeof t.\u006b\u0065\u0072\u006e\u0065\u006cApiKey=="string"?t.\u006b\u0065\u0072\u006e\u0065\u006cApiKey.trim():Ui(),u=typeof t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId=="string"?t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId.trim():void 0,c={\u006b\u0065\u0072\u006e\u0065\u006cApiKey:r,proxyMode:S,configured\u004b\u0065\u0072\u006e\u0065\u006cProxyId:u,location:typeof t.location=="string"?t.location:void 0,proxyZip:typeof t.proxyZip=="string"?t.proxyZip:void 0,gl:typeof t.gl=="string"?t.gl:"us"},h=typeof t.debug=="boolean"?t.debug:!1,m=S==="location"&&!!c.location,f=t.maxAttempts,M=typeof f=="number"&&Number.isInteger(f)&&f>=1?Math.min(Ja,f):Gl(S),y=Math.min(Ja,M),A=typeof t.softDeadlineMs=="number"?t.softDeadlineMs:null,O=new Dn,B=null,b=S,N=0,W=()=>A==null||A-Date.now()>=Ll;for(let P=0;P<y;P++){let C=P+1,E=Date.now();try{if(n?.aborted)throw qa(n);let w=Uo({intent:l,\u0062\u0072\u0069\u0067\u0068\u0074\u0044\u0061\u0074\u0061Available:bs(),\u006b\u0065\u0072\u006e\u0065\u006cFallbackAvailable:!!r,persistent\u004b\u0065\u0072\u006e\u0065\u006cIdentityRequested:!!(t.serpIdentity||t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName),retryIndex:P,priorTerminalReason:B==null?null:nn(B),softDeadlineMs:A}),k=Zn.parse({...t,\u006b\u0065\u0072\u006e\u0065\u006cApiKey:r,proxyMode:b,debug:h||m}),v=w.plannedProvider==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061"?"\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061_browser":k.serpIdentity?"\u006b\u0065\u0072\u006e\u0065\u006c_persistent_identity":"\u006b\u0065\u0072\u006e\u0065\u006c_browser";await xe(a,{type:"started",attemptNumber:C,maxAttempts:y,method:v,provider:v==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061_browser"?"\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061":"\u006b\u0065\u0072\u006e\u0065\u006c",planReason:w.reasonCode,planTimeoutMs:w.timeoutMs,retryKind:C===1?null:w.attemptKind==="provider_fallback"?"provider_fallback":"same_method",retryReason:C===1||B==null?null:nn(B),query:k.query,location:k.location??null,maxQuestions:k.maxQuestions,startedAt:new Date(E).toISOString()});let I=w.plannedProvider==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061"?null:await lo({...c,proxyMode:b,attemptIndex:P,fresh:b==="location"});if(w.plannedProvider==="\u006b\u0065\u0072\u006e\u0065\u006c"&&!I)throw new Error("\u004b\u0065\u0072\u006e\u0065\u006c proxy resolution did not produce an execution plan");let R={...t,\u006b\u0065\u0072\u006e\u0065\u006cApiKey:r,...I?{\u006b\u0065\u0072\u006e\u0065\u006cProxyId:I.\u006b\u0065\u0072\u006e\u0065\u006cProxyId,\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution:I.resolution}:{},proxyMode:b,keepDefaultProxy:P>0,softDeadlineMs:A==null?void 0:E+w.timeoutMs,debug:h||m};b==="none"&&(R.\u006b\u0065\u0072\u006e\u0065\u006cProxyId=void 0);let L=Zn.parse(R);console.info(JSON.stringify({event:"harvest_attempt_started",attempt_number:C,max_attempts:y,query:L.query,location:L.location??null,max_questions:L.maxQuestions}));let x=$t(),X=null,ut=async q=>{So(q.provider)!==w.plannedProvider&&(X=new en(w.plannedProvider,q.provider)),await xe(a,{type:"provider_session_started",attemptNumber:C,maxAttempts:y,provider:q.provider,providerSessionId:q.providerSessionId,observedAt:new Date().toISOString()})},it=x?.harvestBrowserMode==="headless-test"&&process.env[Ss]==="true",J=x?await us({...x,forceHeadless:it,forceHeadful:!it},()=>yo(L,w,n,i,ut,s)):await yo(L,w,n,i,ut,s);if(J.error||X){let q=X??J.error,$=nn(q);($==="captcha"||$==="proxy_tunnel_failed")&&b==="location"&&(N++,N>=2&&(b="none"));let pt=!J.result&&P<y-1&&W()&&($==="captcha"||po($)||S==="location"&&go($));if($==="captcha"?console.warn(JSON.stringify({event:"harvest_attempt_captcha",attempt_number:C,max_attempts:y,message:mt(q),will_retry:pt})):pt&&console.warn(JSON.stringify({event:"harvest_attempt_proxy_retry",attempt_number:C,max_attempts:y,outcome:$,message:mt(q),will_retry:pt})),await xe(a,{type:"finished",attemptNumber:C,maxAttempts:y,outcome:$,\u006b\u0065\u0072\u006e\u0065\u006cSessionId:J.cleanup.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,questionCount:J.result?.totalQuestions??0,durationMs:Date.now()-E,error:mt(q),willRetry:pt,cleanup:J.cleanup,debug:J.debug,completedAt:new Date().toISOString()}),await Ka(r,I?.disposableProxyId),B=q,pt)continue;if(J.result&&!X){let Ct=await mo(J.result,A);return ho(co(wo(Ct,h),L.maxQuestions,L.questionsOnly),P,w.attemptKind==="provider_fallback"?1:0)}break}let ct=J.result;if(!ct)throw new Error("Harvest attempt completed without a result");if(Jl(ct,S)){let q=new je(Kl(ct)),$=P<y-1&&W();if(console.warn(JSON.stringify({event:"harvest_attempt_location_mismatch",attempt_number:C,max_attempts:y,message:q.message,will_retry:$})),await xe(a,{type:"finished",attemptNumber:C,maxAttempts:y,outcome:"location_mismatch",\u006b\u0065\u0072\u006e\u0065\u006cSessionId:J.cleanup.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,questionCount:ct.totalQuestions,durationMs:Date.now()-E,error:q.message,willRetry:$,cleanup:J.cleanup,debug:J.debug,completedAt:new Date().toISOString()}),await Ka(r,I?.disposableProxyId),B=q,$)continue;break}let Re=await mo(ct,A),F=ho(co(wo(Re,h),L.maxQuestions,L.questionsOnly),P,w.attemptKind==="provider_fallback"?1:0),yt=Bl(F),G=yt==="degraded_result"&&P<y-1&&W(),tt=yt==="degraded_result"?Fl(F):null;if(G&&console.warn(JSON.stringify({event:"harvest_attempt_degraded_result",attempt_number:C,max_attempts:y,degradation_reasons:F.diagnostics.degradationReasons,will_retry:!0})),await xe(a,{type:"finished",attemptNumber:C,maxAttempts:y,outcome:yt,\u006b\u0065\u0072\u006e\u0065\u006cSessionId:J.cleanup.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,questionCount:F.totalQuestions,durationMs:Date.now()-E,error:tt,willRetry:G,cleanup:J.cleanup,debug:J.debug,completedAt:new Date().toISOString()}),await Ka(r,I?.disposableProxyId),G)continue;return(L.format==="json"||L.format==="both")&&await O.writeJSON(F,L.outputDir),(L.format==="csv"||L.format==="both")&&await Promise.all([O.writeCSV(F.flat,L.outputDir),F.videos.length>0?O.writeVideoCSV(F.videos,F.seed,L.outputDir):Promise.resolve(""),F.forums.length>0?O.writeForumCSV(F.forums,F.seed,L.outputDir):Promise.resolve(""),F.aiOverview.detected?O.writeAIOverviewCSV(F.aiOverview.citations,F.aiOverview.text,F.seed,L.outputDir):Promise.resolve(""),F.aiMode.detected?O.writeAIModeCSV(F.aiMode.citations,F.aiMode.text,F.seed,L.outputDir):Promise.resolve(""),F.whatPeopleSaying.length>0?O.writeWhatPeopleSayingCSV(F.whatPeopleSaying,F.seed,L.outputDir):Promise.resolve("")]),F}catch(w){let k=nn(w);(k==="captcha"||k==="proxy_tunnel_failed")&&b==="location"&&(N++,N>=2&&(b="none"));let v=P<y-1&&W()&&(k==="captcha"||po(k)||S==="location"&&go(k));if(k==="captcha"?console.warn(JSON.stringify({event:"harvest_attempt_captcha",attempt_number:C,max_attempts:y,message:mt(w),will_retry:v})):v&&console.warn(JSON.stringify({event:"harvest_attempt_proxy_retry",attempt_number:C,max_attempts:y,outcome:k,message:mt(w),will_retry:v})),await xe(a,{type:"finished",attemptNumber:C,maxAttempts:y,outcome:k,\u006b\u0065\u0072\u006e\u0065\u006cSessionId:null,questionCount:0,durationMs:Date.now()-E,error:mt(w),willRetry:v,cleanup:{\u006b\u0065\u0072\u006e\u0065\u006cSessionId:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted:!1,\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteError:null,browserCloseSucceeded:null,browserCloseError:null},debug:null,completedAt:new Date().toISOString()}),B=w,v)continue;if(k==="captcha")break;throw w}}throw B&&!(B instanceof at)?B:(console.warn(JSON.stringify({event:"harvest_captcha_exhausted",max_attempts:y,session_kind:r?"\u006b\u0065\u0072\u006e\u0065\u006c":"local"})),new at(rs(`CAPTCHA on all ${y} fresh sessions. Try again in a few minutes.`)))}var Po=require("child_process"),lt=require("fs"),ai=require("os"),ee=require("path"),ne=require("@fal-ai/client");var ql="https://api.deepinfra.com/v1/openai/chat/completions",ko="https://openrouter.ai/api/v1/chat/completions",Xa="Qwen/Qwen3.6-35B-A3B",Xl=`You are a video prompt engineer for Seedance 2.0 text-to-video AI.
|
|
21902
|
+
`)}};var Zs=require("crypto");var dl="pr.oxylabs.io",ll=7777,Sl=10;function to(){return process.env.OXYLABS_USERNAME?.trim()||void 0}function eo(){return process.env.OXYLABS_PASSWORD?.trim()||void 0}function Ul(){return(process.env.OXYLABS_COUNTRY?.trim()||"US").toUpperCase()}function no(){return!!(to()&&eo())}function ul(){let e="";for(let t=0;t<10;t++)e+=String((0,Zs.randomInt)(0,10));return e}function cl(e={}){let t=to();if(!t)return;let n=t.startsWith("customer-")?t:`customer-${t}`,a=(e.country?.trim()||Ul()).toUpperCase(),i=e.sticky?`-sessid-${ul()}-sesstime-${Sl}`:"";return`${n}-cc-${a}${i}`}function Fa(e){return e.replace(/pr\.oxylabs\.io(:\d+)?/gi,"backup proxy").replace(/oxylabs/gi,"backup proxy")}function hl(e){return`mcp-backup-custom-${`${Date.now()}-${e??0}-${Math.random().toString(36).slice(2,8)}`}`}async function ao(e,t={}){let n=cl({sticky:t.sticky}),a=eo();if(!n||!a)throw new Error("backup proxy pool is not configured");let i=new H({apiKey:e});try{let s=await i.proxies.create({type:"custom",name:hl(t.attemptIndex),protocol:"http",config:{host:dl,port:ll,username:n,password:a}});if(!s.id)throw new Error("backup proxy creation did not return a proxy id");return s.id}catch(s){let o=s instanceof Error?s.message:String(s);throw new Error(Fa(o))}}var gl={alabama:"AL",alaska:"AK",arizona:"AZ",arkansas:"AR",california:"CA",colorado:"CO",connecticut:"CT",delaware:"DE",florida:"FL",georgia:"GA",hawaii:"HI",idaho:"ID",illinois:"IL",indiana:"IN",iowa:"IA",kansas:"KS",kentucky:"KY",louisiana:"LA",maine:"ME",maryland:"MD",massachusetts:"MA",michigan:"MI",minnesota:"MN",mississippi:"MS",missouri:"MO",montana:"MT",nebraska:"NE",nevada:"NV","new hampshire":"NH","new jersey":"NJ","new mexico":"NM","new york":"NY","north carolina":"NC","north dakota":"ND",ohio:"OH",oklahoma:"OK",oregon:"OR",pennsylvania:"PA","rhode island":"RI","south carolina":"SC","south dakota":"SD",tennessee:"TN",texas:"TX",utah:"UT",vermont:"VT",virginia:"VA",washington:"WA","west virginia":"WV",wisconsin:"WI",wyoming:"WY"},pl={"atlanta|GA":"30303","austin|TX":"78701","baltimore|MD":"21201","boston|MA":"02108","boulder|CO":"80302","charlotte|NC":"28202","chicago|IL":"60601","colorado_springs|CO":"80903","columbus|OH":"43215","dallas|TX":"75201","denver|CO":"80202","detroit|MI":"48226","fort_collins|CO":"80524","fort_worth|TX":"76102","houston|TX":"77002","indianapolis|IN":"46204","jacksonville|FL":"32202","las_vegas|NV":"89101","los_angeles|CA":"90012","louisville|KY":"40202","loveland|CO":"80537","memphis|TN":"38103","miami|FL":"33131","minneapolis|MN":"55401","nashville|TN":"37203","new_york|NY":"10001","orlando|FL":"32801","philadelphia|PA":"19103","phoenix|AZ":"85004","portland|OR":"97205","raleigh|NC":"27601","richmond|VA":"23219","sacramento|CA":"95814","salt_lake_city|UT":"84101","san_antonio|TX":"78205","san_diego|CA":"92101","san_francisco|CA":"94103","san_jose|CA":"95113","seattle|WA":"98101"};function wl(e){return e?e.slice(-6):null}function rt(e,t,n,a,i,s=!1){return{\u006b\u0065\u0072\u006e\u0065\u006cProxyId:n,...s&&n?{disposableProxyId:n}:{},resolution:{source:e,proxyType:e==="disabled"?"none":e==="configured_fallback"?"configured":e==="isp_created"?"isp":e==="backup_custom"?"custom":e==="location_created"||e==="location_reused"?"residential":"unknown",proxyMode:t,proxyIdPresent:!!n,proxyIdSuffix:wl(n),target:a,error:i,disposable:s}}}function ml(e){return e.trim().toLowerCase().replace(/\s+/g," ")}function yl(e){return e.trim().toLowerCase().replace(/\./g,"").replace(/\s+/g," ")}function Cl(e){if(!e)return!0;let t=yl(e);return t==="united states"||t==="united states of america"||t==="usa"||t==="us"}function io(e){let t=e.trim();return/^[A-Za-z]{2}$/.test(t)?t.toUpperCase():gl[ml(t)]??null}function Tl(e){let n=e.normalize("NFKD").replace(/[^\x00-\x7F]/g,"").toLowerCase().split(/[^a-z0-9]+/).filter(Boolean),a=n.join("_"),i=n.join("");return Array.from(new Set([a,i].filter(Boolean)))}function Rt(e,t,n){return n?`mcp-serp-residential-${e.toLowerCase()}-${t.toLowerCase()}-${n}`:`mcp-serp-residential-${e.toLowerCase()}-${t.toLowerCase()}`}function Gn(e,t){let n=`${Date.now()}-${t??0}-${Math.random().toString(36).slice(2,8)}`;return`${e}-fresh-${n}`}function kl(e){return`mcp-serp-residential-us-zip-${e}`}function fl(e,t){if(!e||t.toLowerCase()!=="us")return null;let n=xs(e),a=n.split(",").map(U=>U.trim()).filter(Boolean);if(a.length>1&&Cl(a[a.length-1])&&(a=a.slice(0,-1)),a.length===1){let U=io(a[0]);return U?{canonicalLocation:n,level:"state",country:"US",state:U,city:"",cityCandidates:[],proxyName:Rt("US",U),config:{country:"US",state:U}}:null}let[i="",s=""]=a;if(!i||!s)return null;let o=io(s);if(!o)return null;let d=Tl(i),l=d[0];return l?{canonicalLocation:n,level:"city",country:"US",state:o,city:l,cityCandidates:d,proxyName:Rt("US",o,l),config:{country:"US",state:o,city:l}}:null}function Ml(e){return`${e.city}|${e.state}`}function so(e,t){return t&&/^\d{5}$/.test(t)?t:pl[Ml(e)]??null}function oo(e,t){return{...e,level:"zip",zip:t,proxyName:kl(t),config:{country:e.country,state:e.state,zip:t}}}function Ga(e,t){return{...e,proxyName:t}}function Ya(e,t,n){return t.level==="zip"?e?.country?.toUpperCase()===t.country&&e?.zip===t.zip:e?.country?.toUpperCase()===t.country&&e?.state?.toUpperCase()===t.state&&(n?e?.city===n:!e?.city)}function Nl(e,t){return e.find(n=>n.type==="residential"&&n.status!=="unavailable"&&!!n.id&&(n.name===t.proxyName||Ya(n.config,t,t.level==="city"?t.city:void 0)))??null}function vl(e,t){for(let n of t.cityCandidates){let a=Rt(t.country,t.state,n),i=e.find(s=>s.type==="residential"&&s.status!=="unavailable"&&!!s.id&&(s.name===a||Ya(s.config,t,n)));if(i)return i}return null}function Vn(e){return{...e,level:"state",proxyName:Rt(e.country,e.state),config:{country:e.country,state:e.state}}}function _l(e,t){let n=Rt(t.country,t.state);return e.find(a=>a.type==="residential"&&a.status!=="unavailable"&&!!a.id&&(a.name===n||Ya(a.config,t)))??null}function bl(e,t){return Vn(e)}function Ot(e){return e instanceof Error?e.message:String(e)}function El(e,t,n){let a=[],i=so(e,t);if(i){let o=oo(e,i);a.push(Ga(o,Gn(o.proxyName,n)))}for(let o of e.cityCandidates){let d={...e,level:"city",city:o,proxyName:Rt(e.country,e.state,o),config:{country:e.country,state:e.state,city:o}};a.push(Ga(d,Gn(d.proxyName,n)))}let s=Vn(e);return a.push(Ga(s,Gn(s.proxyName,n))),a}async function Va(e,t,n){if(e.backupOnExhaustion&&n.length>0&&e.\u006b\u0065\u0072\u006e\u0065\u006cApiKey&&no())try{let a=await ao(e.\u006b\u0065\u0072\u006e\u0065\u006cApiKey,{attemptIndex:e.attemptIndex});return rt("backup_custom",e.proxyMode,a,t,null,!0)}catch(a){n.push(`backup: ${Fa(Ot(a))}`)}return rt("configured_fallback",e.proxyMode,e.configured\u004b\u0065\u0072\u006e\u0065\u006cProxyId,t,n.join(" | "))}async function Pl(e,t,n){let a=[];for(let i of El(n,t.proxyZip,t.attemptIndex))try{let s=await e.proxies.create({type:"residential",name:i.proxyName,config:i.level==="zip"?{country:i.country,zip:i.zip}:i.config});if(s.id)return rt("location_created",t.proxyMode,s.id,i,null,!0);a.push(`${i.proxyName}: \u004b\u0065\u0072\u006e\u0065\u006c did not return a proxy id`)}catch(s){a.push(`${i.proxyName}: ${Ot(s)}`)}if(process.env.\u004b\u0045\u0052\u004e\u0045\u004c_PROXY_TYPE!=="residential"){let i=Vn(n);try{let s=await e.proxies.create({type:"isp",name:Gn(`mcp-serp-isp-${i.country.toLowerCase()}-${(i.state??"").toLowerCase()}`,t.attemptIndex),config:{country:i.country,...i.state?{state:i.state}:{}}});if(s.id)return rt("isp_created",t.proxyMode,s.id,i,null,!0);a.push("isp: \u004b\u0065\u0072\u006e\u0065\u006c did not return a proxy id")}catch(s){a.push(`isp: ${Ot(s)}`)}}return Va(t,n,a)}async function ro(e,t){if(!e||!t)return;await new H({apiKey:e}).proxies.delete(t)}async function lo(e){if(e.proxyMode==="none")return rt("disabled",e.proxyMode,void 0,null,null);if(e.proxyMode==="configured")return rt("configured_fallback",e.proxyMode,e.configured\u004b\u0065\u0072\u006e\u0065\u006cProxyId,null,null);let t=fl(e.location,e.gl);if(!t||!e.\u006b\u0065\u0072\u006e\u0065\u006cApiKey)return rt("configured_fallback",e.proxyMode,e.configured\u004b\u0065\u0072\u006e\u0065\u006cProxyId,t,t?null:"location could not be normalized to a US city/state proxy target");let n=new H({apiKey:e.\u006b\u0065\u0072\u006e\u0065\u006cApiKey});try{let a=e.attemptIndex??0;if(e.fresh)return await Pl(n,e,t);if(a>=1){let S=bl(t,a),r=[];try{let u=await n.proxies.create({type:"residential",name:S.proxyName,config:S.config});if(u.id)return rt("location_created",e.proxyMode,u.id,S,null);r.push(`${S.state}: \u004b\u0065\u0072\u006e\u0065\u006c did not return a proxy id`)}catch(u){r.push(`${S.state}: ${Ot(u)}`)}return Va(e,S,r)}let i=[];for await(let S of await n.proxies.list())i.push(S);let s=so(t,e.proxyZip),o=[];if(s){let S=oo(t,s),r=Nl(i,S);if(r?.id)return rt("location_reused",e.proxyMode,r.id,S,null);try{let u=await n.proxies.create({type:"residential",name:S.proxyName,config:{country:S.country,zip:s}});if(u.id)return rt("location_created",e.proxyMode,u.id,S,null);o.push(`${s}: \u004b\u0065\u0072\u006e\u0065\u006c did not return a proxy id`)}catch(u){o.push(`${s}: ${Ot(u)}`)}}let d=vl(i,t);if(d?.id)return rt("location_reused",e.proxyMode,d.id,t,o.join(" | ")||null);for(let S of t.cityCandidates)try{let r=await n.proxies.create({type:"residential",name:Rt(t.country,t.state,S),config:{country:t.country,state:t.state,city:S}});if(r.id)return rt("location_created",e.proxyMode,r.id,{...t,level:"city",city:S,proxyName:Rt(t.country,t.state,S),config:{country:t.country,state:t.state,city:S}},null);o.push(`${S}: \u004b\u0065\u0072\u006e\u0065\u006c did not return a proxy id`)}catch(r){o.push(`${S}: ${Ot(r)}`)}let l=Vn(t),U=_l(i,l);if(U?.id)return rt("location_reused",e.proxyMode,U.id,l,o.join(" | "));try{let S=await n.proxies.create({type:"residential",name:l.proxyName,config:l.config});if(S.id)return rt("location_created",e.proxyMode,S.id,l,o.join(" | "));o.push(`${l.state}: \u004b\u0065\u0072\u006e\u0065\u006c did not return a proxy id`)}catch(S){o.push(`${l.state}: ${Ot(S)}`)}return Va(e,t,o)}catch(a){return rt("configured_fallback",e.proxyMode,e.configured\u004b\u0065\u0072\u006e\u0065\u006cProxyId,t,Ot(a))}}var en=class extends Error{constructor(t,n){super(`SERP provider mismatch: planned ${t}, observed ${n}`),this.name="SerpProviderMismatchError"}};function So(e){return e==="\u0062\u0072\u0069\u0067\u0068\u0074_\u0064\u0061\u0074\u0061_browser_api"?"\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061":"\u006b\u0065\u0072\u006e\u0065\u006c"}function Uo(e){return Il({intent:e.intent,\u0062\u0072\u0069\u0067\u0068\u0074\u0044\u0061\u0074\u0061Available:e.\u0062\u0072\u0069\u0067\u0068\u0074\u0044\u0061\u0074\u0061Available,\u006b\u0065\u0072\u006e\u0065\u006cAvailable:!0,persistent\u004b\u0065\u0072\u006e\u0065\u006cIdentityRequested:e.persistent\u004b\u0065\u0072\u006e\u0065\u006cIdentityRequested,retryIndex:e.retryIndex,priorTerminalReason:e.priorTerminalReason,allowedFallbacks:e.\u006b\u0065\u0072\u006e\u0065\u006cFallbackAvailable&&e.intent!=="\u006b\u0065\u0072\u006e\u0065\u006c"?["\u006b\u0065\u0072\u006e\u0065\u006c"]:[],timeoutMs:e.softDeadlineMs==null?4e5:Math.max(1,e.softDeadlineMs-Date.now())})}function uo(e){if(e.forceManagedSerp&&e.force\u004b\u0065\u0072\u006e\u0065\u006cSerp)throw new Error("forceManagedSerp and force\u004b\u0065\u0072\u006e\u0065\u006cSerp cannot both be true");return e.forceManagedSerp?"\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061":e.force\u004b\u0065\u0072\u006e\u0065\u006cSerp?"\u006b\u0065\u0072\u006e\u0065\u006c":"auto"}function Yn(e,t){if(!t)throw new Error(`Requested SERP provider is unavailable: ${e}`);return e}function Il(e){if(!Number.isInteger(e.retryIndex)||e.retryIndex<0)throw new Error("retryIndex must be a non-negative integer");if(!Number.isFinite(e.timeoutMs)||e.timeoutMs<=0)throw new Error("timeoutMs must be a positive number");let t,n;e.intent==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061"?(t=Yn("\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061",e.\u0062\u0072\u0069\u0067\u0068\u0074\u0044\u0061\u0074\u0061Available),n="explicit_\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061"):e.intent==="\u006b\u0065\u0072\u006e\u0065\u006c"?(t=Yn("\u006b\u0065\u0072\u006e\u0065\u006c",e.\u006b\u0065\u0072\u006e\u0065\u006cAvailable),n="explicit_\u006b\u0065\u0072\u006e\u0065\u006c"):e.persistent\u004b\u0065\u0072\u006e\u0065\u006cIdentityRequested?(t=Yn("\u006b\u0065\u0072\u006e\u0065\u006c",e.\u006b\u0065\u0072\u006e\u0065\u006cAvailable),n="persistent_\u006b\u0065\u0072\u006e\u0065\u006c_identity"):e.\u0062\u0072\u0069\u0067\u0068\u0074\u0044\u0061\u0074\u0061Available?(t="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061",n="managed_default"):(t=Yn("\u006b\u0065\u0072\u006e\u0065\u006c",e.\u006b\u0065\u0072\u006e\u0065\u006cAvailable),n="\u006b\u0065\u0072\u006e\u0065\u006c_default");let a=e.allowedFallbacks.find(o=>o!==t&&(o==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061"?e.\u0062\u0072\u0069\u0067\u0068\u0074\u0044\u0061\u0074\u0061Available:e.\u006b\u0065\u0072\u006e\u0065\u006cAvailable)),i=e.retryIndex>0&&a?a:t,s=e.retryIndex===0?"primary":i===t?"same_provider_retry":"provider_fallback";return Object.freeze({plannedProvider:i,attemptKind:s,reasonCode:s==="primary"?n:s==="provider_fallback"?"provider_fallback":"same_provider_retry",retryIndex:e.retryIndex,priorTerminalReason:e.priorTerminalReason??null,timeoutMs:Math.floor(e.timeoutMs),fallbackAllowed:!!a})}var Ja=2,Al=2,Ll=3e3;function qa(e){return e.reason instanceof DOMException&&e.reason.name==="TimeoutError"?e.reason:new gt}function xl(e){if(!e||typeof e!="object")return;let t=e.signal;if(t instanceof AbortSignal)return t}function Ol(e){if(!e||typeof e!="object")return;let t=e.onAttemptEvent;return typeof t=="function"?t:void 0}function Rl(e){if(!e||typeof e!="object")return;let t=e.onPaaProgress;return typeof t=="function"?t:void 0}function Wl(e){if(!e||typeof e!="object")return;let t=e.onPaaDomEvidence;return typeof t=="function"?t:void 0}async function Hl(e){let t=await e.evaluate(n=>{let a=n,i=Array.from(document.querySelectorAll(a.item)),s=i.map(l=>l.querySelector(a.clickTarget)).filter(l=>l!=null),o=l=>{let U=l.getBoundingClientRect();if(U.width<=0||U.height<=0)return!1;let S=U.left+U.width/2,r=U.top+U.height/2;if(S<0||r<0||S>=window.innerWidth||r>=window.innerHeight)return!1;let u=document.elementFromPoint(S,r);return u!=null&&u!==l&&!l.contains(u)&&!u.contains(l)},d=Array.from(document.querySelectorAll("body *")).filter(l=>{let U=window.getComputedStyle(l);if(U.position!=="fixed"&&U.position!=="sticky")return!1;let S=l.getBoundingClientRect();return S.width*S.height>=window.innerWidth*window.innerHeight*.15&&U.visibility!=="hidden"&&U.display!=="none"});return{itemCount:i.length,expandedItemCount:i.filter(l=>l.classList.contains(a.expandedClass)||l.querySelector(a.clickTarget)?.getAttribute("aria-expanded")==="true").length,answeredItemCount:i.filter(l=>(l.querySelector(a.answerContainer)?.textContent?.trim().length??0)>=10).length,sourcedItemCount:i.filter(l=>l.querySelector(`${a.answerContainer} a[href]`)!=null).length,clickTargetCount:s.length,clickTargetsWithButtonRole:s.filter(l=>l.getAttribute("role")==="button"||l.tagName==="BUTTON").length,clickTargetsWithExpandedState:s.filter(l=>l.hasAttribute("aria-expanded")).length,clickTargetsOffscreen:s.filter(l=>{let U=l.getBoundingClientRect(),S=U.left+U.width/2,r=U.top+U.height/2;return S<0||r<0||S>=window.innerWidth||r>=window.innerHeight}).length,clickTargetsBlockedAtCenter:s.filter(o).length,fixedOrStickyOverlayCount:d.length}},{item:Y.item,answerContainer:Y.answerContainer,clickTarget:Y.clickTarget,expandedClass:Y.expandedClass});return{capturedAt:new Date().toISOString(),...t,selectorVersion:ss}}async function xe(e,t){if(e)try{await e(t)}catch(n){console.warn(JSON.stringify({event:"harvest_attempt_log_failed",attempt_number:t.attemptNumber,message:n instanceof Error?n.message:String(n)}))}}function nn(e){if(e instanceof en)return"error";if(e instanceof at)return"captcha";if(e instanceof je)return"location_mismatch";if(e instanceof gt)return"request_aborted";if(e instanceof zt)return"browser_session_interrupted";if(e instanceof DOMException&&(e.name==="TimeoutError"||e.name==="AbortError"))return"timeout";let t=e instanceof Error?e.message:String(e);return/browser (?:has been )?closed|context (?:has been )?closed|target page, context or browser has been closed|session closed|page has been closed/i.test(t)?"browser_session_interrupted":Vl(t)?"proxy_tunnel_failed":Yl(t)?"proxy_unavailable":/timeout|timed out|Timeout \d+ms exceeded|deadline/i.test(t)?"timeout":"error"}function Bl(e){return e.diagnostics.degradedResult?"degraded_result":e.diagnostics?.completionStatus??(e.totalQuestions>0?"paa_found":"no_paa")}function Dl(e){return e.flat.length>0||e.organicResults.length>0||e.localPack.length>0||e.videos.length>0||e.forums.length>0||e.whatPeopleSaying.length>0||e.aiOverview.detected||e.aiMode.detected}function co(e,t,n){let a=Dl(e),i=(e.diagnostics.warnings?.length??0)>0,s=new Set(e.flat.map(m=>m.question.toLowerCase().replace(/[^\w\s]/g,"").replace(/\s+/g," ").trim())).size,o=n?0:e.flat.filter(m=>!m.answer?.trim()).length,d=n?0:e.flat.filter(m=>!m.source_cite?.trim()).length,l=e.diagnostics.completionStatus==="no_paa"&&(e.diagnostics.noPaaObserved===!0||a),U=e.diagnostics.completionStatus==="paa_found",S=e.diagnostics.paaLifecycle?.discoveryStatus,r=S==="interrupted"||S==="recovery_exhausted",u=U&&(s<t&&S!=="frontier_exhausted"||o>0||d>0||!!e.diagnostics.interruption||r),c=l?"complete":U&&s>0?u||i?"partial":"complete":a?i?"partial":"complete":"degraded",h=c==="degraded";return e.diagnostics={...e.diagnostics,resultQuality:c,degradedResult:h,degradationReasons:h?["empty_primary_serp"]:[],retryRecommended:h||c==="partial"&&(u||e.diagnostics.warnings?.some(m=>m.retryable)===!0),completeness:{paaWithoutAnswer:o,paaWithoutSource:d,paaAnswersRecovered:e.diagnostics.completeness?.paaAnswersRecovered??0,aioShareCaptured:e.diagnostics.completeness?.aioShareCaptured??null,paaRequested:t,paaReturned:e.flat.length,paaUnique:s},...e.diagnostics.paaLifecycle?{paaLifecycle:{...e.diagnostics.paaLifecycle,questionsFound:s,targetStatus:s>=t?"met":"not_met",materialStatus:o>0||d>0?"partial":"complete"}}:{}},e}function ho(e,t,n){let a=e.diagnostics.paaLifecycle;if(!a)return e;let i={...a.retryBreakdown,browserRetries:t,providerFallbacks:n};return{...e,diagnostics:{...e.diagnostics,paaLifecycle:{...a,retryBreakdown:i,automaticRetries:i.controlRetries+i.browserRetries+i.runtimeRecoveries}}}}function Fl(e){return(e.diagnostics.degradationReasons??[]).includes("empty_primary_serp")?"No usable primary SERP surface was captured; the result may be incomplete.":"The harvest result was marked degraded."}function mt(e){return e instanceof Error?e.message:String(e)}function Gl(e){return e==="location"?Al:Ja}function Vl(e){return/ERR_TUNNEL_CONNECTION_FAILED|ERR_PROXY_CONNECTION_FAILED|ERR_SOCKS_CONNECTION_FAILED|tunnel connection failed|proxy connection failed|transport error: proxy/i.test(e)}function Yl(e){return/proxy unavailable|proxy_unavailable|connection_test_failed|did not return a proxy id|configured fallback/i.test(e)}function go(e){return e==="captcha"||e==="proxy_tunnel_failed"||e==="proxy_unavailable"}function po(e){return e==="browser_session_interrupted"}function Kl(e){let t=e.diagnostics.debug?.locationEvidence,n=t?.expected?.canonicalLocation??e.location??"requested location",a=t?.candidates.slice(0,3).map(i=>`${i.city}, ${i.regionCode}`).join("; ");return a?`Google returned results for ${a}, not ${n}`:`Google returned results for a different location than ${n}`}function Jl(e,t){return t==="location"&&e.diagnostics.debug?.locationEvidence?.status==="mismatch"}function wo(e,t){if(t||!e.diagnostics.debug)return e;let n={...e.diagnostics};return delete n.debug,{...e,diagnostics:n}}async function mo(e,t){let n=t==null?3e3:t-Date.now();if(n<=0)return e;try{return await qs(e,{totalBudgetMs:Math.min(3e3,n)})}catch(a){return console.warn(JSON.stringify({event:"harvest_goto_resolution_failed",message:mt(a)})),e}}async function Ka(e,t){if(!(!e||!t))try{await ro(e,t),console.info(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_proxy_deleted",proxy_id_suffix:t.slice(-6)}))}catch(n){console.warn(JSON.stringify({event:"\u006b\u0065\u0072\u006e\u0065\u006c_proxy_delete_failed",proxy_id_suffix:t.slice(-6),message:mt(n)}))}}async function yo(e,t,n,a,i,s){let o=bs(t),d=new Fn,l=new Bn(o,d,a,i);if(n?.aborted)return{result:null,error:qa(n),cleanup:await o.close(),debug:null};let U,S=n?new Promise((m,f)=>{U=()=>f(qa(n)),n.addEventListener("abort",U,{once:!0})}):null,r=null,u=null,c,h=null;try{let m=l.extract(e,n);S&&m.catch(()=>{}),r=await(S?Promise.race([m,S]):m)}catch(m){u=m}finally{if(n&&U&&n.removeEventListener("abort",U),s){let m;try{let f=Hl(o);f.catch(()=>{});let M=await Promise.race([f,new Promise((y,A)=>{m=setTimeout(()=>A(new DOMException("PAA DOM evidence timed out","TimeoutError")),2e3)})]);await s(M)}catch(f){console.warn(JSON.stringify({event:"paa_dom_evidence_failed",message:mt(f)}))}finally{m&&clearTimeout(m)}}h=r?.diagnostics.debug??(e.debug?{enabled:!0,request:{query:e.query,locationInput:e.location??null,canonicalLocation:null,locationResolved:null,locationMatchSource:null,locationAmbiguousCandidates:null,uule:null,gl:e.gl,hl:e.hl,device:e.device,proxyMode:e.proxyMode,proxyZip:e.proxyZip??null,serpIdentity:e.serpIdentity??null,serpOnly:e.serpOnly,pages:e.pages??1},browser:o.getDebugSnapshot()}:null),c=await o.close()}if(u){let m=nn(u),f=m==="timeout"||m==="request_aborted"||m==="browser_session_interrupted"?m:null,M=null;if(f)try{M=typeof l.getPartialResult=="function"?l.getPartialResult():null}catch{M=null}return M&&f?(M.diagnostics={...M.diagnostics,interruption:{code:f,reasonSource:"client_runtime",message:mt(u)}},{result:M,error:u,cleanup:c,debug:h,salvagedFrom:u}):{result:null,error:u,cleanup:c,debug:h}}return{result:r,error:null,cleanup:c,debug:h}}async function Co(e){let t=typeof e=="object"&&e!==null?e:{},n=xl(e),a=Ol(e),i=Rl(e),s=Wl(e),o=t.forceManagedSerp===!0,d=t.force\u004b\u0065\u0072\u006e\u0065\u006cSerp===!0,l=uo({forceManagedSerp:o,force\u004b\u0065\u0072\u006e\u0065\u006cSerp:d}),U=t.proxyMode,S=U==="location"||U==="none"||U==="configured"?U:Qn,r=typeof t.\u006b\u0065\u0072\u006e\u0065\u006cApiKey=="string"?t.\u006b\u0065\u0072\u006e\u0065\u006cApiKey.trim():Ui(),u=typeof t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId=="string"?t.\u006b\u0065\u0072\u006e\u0065\u006cProxyId.trim():void 0,c={\u006b\u0065\u0072\u006e\u0065\u006cApiKey:r,proxyMode:S,configured\u004b\u0065\u0072\u006e\u0065\u006cProxyId:u,location:typeof t.location=="string"?t.location:void 0,proxyZip:typeof t.proxyZip=="string"?t.proxyZip:void 0,gl:typeof t.gl=="string"?t.gl:"us"},h=typeof t.debug=="boolean"?t.debug:!1,m=S==="location"&&!!c.location,f=t.maxAttempts,M=typeof f=="number"&&Number.isInteger(f)&&f>=1?Math.min(Ja,f):Gl(S),y=Math.min(Ja,M),A=typeof t.softDeadlineMs=="number"?t.softDeadlineMs:null,O=new Dn,B=null,_=S,N=0,W=()=>A==null||A-Date.now()>=Ll;for(let P=0;P<y;P++){let C=P+1,E=Date.now();try{if(n?.aborted)throw qa(n);let w=Uo({intent:l,\u0062\u0072\u0069\u0067\u0068\u0074\u0044\u0061\u0074\u0061Available:_s(),\u006b\u0065\u0072\u006e\u0065\u006cFallbackAvailable:!!r,persistent\u004b\u0065\u0072\u006e\u0065\u006cIdentityRequested:!!(t.serpIdentity||t.\u006b\u0065\u0072\u006e\u0065\u006cProfileName),retryIndex:P,priorTerminalReason:B==null?null:nn(B),softDeadlineMs:A}),k=Zn.parse({...t,\u006b\u0065\u0072\u006e\u0065\u006cApiKey:r,proxyMode:_,debug:h||m}),v=w.plannedProvider==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061"?"\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061_browser":k.serpIdentity?"\u006b\u0065\u0072\u006e\u0065\u006c_persistent_identity":"\u006b\u0065\u0072\u006e\u0065\u006c_browser";await xe(a,{type:"started",attemptNumber:C,maxAttempts:y,method:v,provider:v==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061_browser"?"\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061":"\u006b\u0065\u0072\u006e\u0065\u006c",planReason:w.reasonCode,planTimeoutMs:w.timeoutMs,retryKind:C===1?null:w.attemptKind==="provider_fallback"?"provider_fallback":"same_method",retryReason:C===1||B==null?null:nn(B),query:k.query,location:k.location??null,maxQuestions:k.maxQuestions,startedAt:new Date(E).toISOString()});let I=w.plannedProvider==="\u0062\u0072\u0069\u0067\u0068\u0074\u0064\u0061\u0074\u0061"?null:await lo({...c,proxyMode:_,attemptIndex:P,fresh:_==="location"});if(w.plannedProvider==="\u006b\u0065\u0072\u006e\u0065\u006c"&&!I)throw new Error("\u004b\u0065\u0072\u006e\u0065\u006c proxy resolution did not produce an execution plan");let R={...t,\u006b\u0065\u0072\u006e\u0065\u006cApiKey:r,...I?{\u006b\u0065\u0072\u006e\u0065\u006cProxyId:I.\u006b\u0065\u0072\u006e\u0065\u006cProxyId,\u006b\u0065\u0072\u006e\u0065\u006cProxyResolution:I.resolution}:{},proxyMode:_,keepDefaultProxy:P>0,softDeadlineMs:A==null?void 0:E+w.timeoutMs,debug:h||m};_==="none"&&(R.\u006b\u0065\u0072\u006e\u0065\u006cProxyId=void 0);let L=Zn.parse(R);console.info(JSON.stringify({event:"harvest_attempt_started",attempt_number:C,max_attempts:y,query:L.query,location:L.location??null,max_questions:L.maxQuestions}));let x=$t(),X=null,ut=async J=>{So(J.provider)!==w.plannedProvider&&(X=new en(w.plannedProvider,J.provider)),await xe(a,{type:"provider_session_started",attemptNumber:C,maxAttempts:y,provider:J.provider,providerSessionId:J.providerSessionId,billingMode:J.billingMode,observedAt:new Date().toISOString()})},it=x?.harvestBrowserMode==="headless-test"&&process.env[Ss]==="true",q=x?await us({...x,forceHeadless:it,forceHeadful:!it},()=>yo(L,w,n,i,ut,s)):await yo(L,w,n,i,ut,s);if(q.error||X){let J=X??q.error,$=nn(J);($==="captcha"||$==="proxy_tunnel_failed")&&_==="location"&&(N++,N>=2&&(_="none"));let pt=!q.result&&P<y-1&&W()&&($==="captcha"||po($)||S==="location"&&go($));if($==="captcha"?console.warn(JSON.stringify({event:"harvest_attempt_captcha",attempt_number:C,max_attempts:y,message:mt(J),will_retry:pt})):pt&&console.warn(JSON.stringify({event:"harvest_attempt_proxy_retry",attempt_number:C,max_attempts:y,outcome:$,message:mt(J),will_retry:pt})),await xe(a,{type:"finished",attemptNumber:C,maxAttempts:y,outcome:$,\u006b\u0065\u0072\u006e\u0065\u006cSessionId:q.cleanup.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,questionCount:q.result?.totalQuestions??0,durationMs:Date.now()-E,error:mt(J),willRetry:pt,cleanup:q.cleanup,debug:q.debug,completedAt:new Date().toISOString()}),await Ka(r,I?.disposableProxyId),B=J,pt)continue;if(q.result&&!X){let Ct=await mo(q.result,A);return ho(co(wo(Ct,h),L.maxQuestions,L.questionsOnly),P,w.attemptKind==="provider_fallback"?1:0)}break}let ct=q.result;if(!ct)throw new Error("Harvest attempt completed without a result");if(Jl(ct,S)){let J=new je(Kl(ct)),$=P<y-1&&W();if(console.warn(JSON.stringify({event:"harvest_attempt_location_mismatch",attempt_number:C,max_attempts:y,message:J.message,will_retry:$})),await xe(a,{type:"finished",attemptNumber:C,maxAttempts:y,outcome:"location_mismatch",\u006b\u0065\u0072\u006e\u0065\u006cSessionId:q.cleanup.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,questionCount:ct.totalQuestions,durationMs:Date.now()-E,error:J.message,willRetry:$,cleanup:q.cleanup,debug:q.debug,completedAt:new Date().toISOString()}),await Ka(r,I?.disposableProxyId),B=J,$)continue;break}let Re=await mo(ct,A),F=ho(co(wo(Re,h),L.maxQuestions,L.questionsOnly),P,w.attemptKind==="provider_fallback"?1:0),yt=Bl(F),G=yt==="degraded_result"&&P<y-1&&W(),tt=yt==="degraded_result"?Fl(F):null;if(G&&console.warn(JSON.stringify({event:"harvest_attempt_degraded_result",attempt_number:C,max_attempts:y,degradation_reasons:F.diagnostics.degradationReasons,will_retry:!0})),await xe(a,{type:"finished",attemptNumber:C,maxAttempts:y,outcome:yt,\u006b\u0065\u0072\u006e\u0065\u006cSessionId:q.cleanup.\u006b\u0065\u0072\u006e\u0065\u006cSessionId,questionCount:F.totalQuestions,durationMs:Date.now()-E,error:tt,willRetry:G,cleanup:q.cleanup,debug:q.debug,completedAt:new Date().toISOString()}),await Ka(r,I?.disposableProxyId),G)continue;return(L.format==="json"||L.format==="both")&&await O.writeJSON(F,L.outputDir),(L.format==="csv"||L.format==="both")&&await Promise.all([O.writeCSV(F.flat,L.outputDir),F.videos.length>0?O.writeVideoCSV(F.videos,F.seed,L.outputDir):Promise.resolve(""),F.forums.length>0?O.writeForumCSV(F.forums,F.seed,L.outputDir):Promise.resolve(""),F.aiOverview.detected?O.writeAIOverviewCSV(F.aiOverview.citations,F.aiOverview.text,F.seed,L.outputDir):Promise.resolve(""),F.aiMode.detected?O.writeAIModeCSV(F.aiMode.citations,F.aiMode.text,F.seed,L.outputDir):Promise.resolve(""),F.whatPeopleSaying.length>0?O.writeWhatPeopleSayingCSV(F.whatPeopleSaying,F.seed,L.outputDir):Promise.resolve("")]),F}catch(w){let k=nn(w);(k==="captcha"||k==="proxy_tunnel_failed")&&_==="location"&&(N++,N>=2&&(_="none"));let v=P<y-1&&W()&&(k==="captcha"||po(k)||S==="location"&&go(k));if(k==="captcha"?console.warn(JSON.stringify({event:"harvest_attempt_captcha",attempt_number:C,max_attempts:y,message:mt(w),will_retry:v})):v&&console.warn(JSON.stringify({event:"harvest_attempt_proxy_retry",attempt_number:C,max_attempts:y,outcome:k,message:mt(w),will_retry:v})),await xe(a,{type:"finished",attemptNumber:C,maxAttempts:y,outcome:k,\u006b\u0065\u0072\u006e\u0065\u006cSessionId:null,questionCount:0,durationMs:Date.now()-E,error:mt(w),willRetry:v,cleanup:{\u006b\u0065\u0072\u006e\u0065\u006cSessionId:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteStarted:!1,\u006b\u0065\u0072\u006e\u0065\u006cDeleteSucceeded:null,\u006b\u0065\u0072\u006e\u0065\u006cDeleteError:null,browserCloseSucceeded:null,browserCloseError:null},debug:null,completedAt:new Date().toISOString()}),B=w,v)continue;if(k==="captcha")break;throw w}}throw B&&!(B instanceof at)?B:(console.warn(JSON.stringify({event:"harvest_captcha_exhausted",max_attempts:y,session_kind:r?"\u006b\u0065\u0072\u006e\u0065\u006c":"local"})),new at(rs(`CAPTCHA on all ${y} fresh sessions. Try again in a few minutes.`)))}var Po=require("child_process"),lt=require("fs"),ai=require("os"),ee=require("path"),ne=require("@fal-ai/client");var ql="https://api.deepinfra.com/v1/openai/chat/completions",ko="https://openrouter.ai/api/v1/chat/completions",Xa="Qwen/Qwen3.6-35B-A3B",Xl=`You are a video prompt engineer for Seedance 2.0 text-to-video AI.
|
|
21903
21903
|
|
|
21904
21904
|
IMPORTANT TECHNICAL CONTEXT: Clip 2 will be generated using image-to-video, meaning it will start from the exact last frame of Clip 1. The two clips will be visually seamless \u2014 same location, same characters, continuous motion. You must write prompts that make this feel like one uninterrupted 16-second video.
|
|
21905
21905
|
|
|
@@ -21923,18 +21923,18 @@ Rules for visuals:
|
|
|
21923
21923
|
Respond with JSON only:
|
|
21924
21924
|
{"clip1": "...", "clip2": "...", "voiceover": "...", "audioMood": "..."}`;async function To(e,t,n,a){let i=await fetch(t,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({model:Xa,temperature:.7,messages:[{role:"system",content:Xl},{role:"user",content:`Question: ${n}
|
|
21925
21925
|
|
|
21926
|
-
Answer: ${a.slice(0,500)}`}]})});if(!i.ok)throw new Error(`LLM call failed (${i.status}): ${await i.text()}`);let s=await i.json();t===ko?Pa({vendor:"openrouter",model:Xa,units:s.usage?.cost??0,unitType:"usd"}):Pa({vendor:"deepinfra_qwen",model:Xa,units:s.usage?.completion_tokens??0,unitType:"tokens"});let o=s.choices[0]?.message?.content?.trim()??"",d=o.match(/\{[\s\S]*\}/);if(!d)throw new Error(`No JSON in QWEN response: ${o.slice(0,200)}`);let l=JSON.parse(d[0]);if(!l.clip1||!l.clip2||!l.voiceover||!l.audioMood)throw new Error(`QWEN response missing fields: ${o.slice(0,200)}`);return l}async function Kn(e,t){let n=process.env.DEEPINFRA_API_KEY,a=process.env.OPENROUTER_API_KEY;if(n)try{return await To(n,ql,e,t)}catch(i){console.warn("[promptBuilder] DeepInfra failed, trying OpenRouter:",i.message)}if(a)return await To(a,ko,e,t);throw new Error("No LLM key \u2014 set DEEPINFRA_API_KEY or OPENROUTER_API_KEY")}function fo(e){if(!e.clip1||!e.clip2||!e.voiceover||!e.audioMood)throw new Error("Episode brief is missing prompt fields \u2014 run blog-to-video skill to regenerate");return{clip1:e.clip1,clip2:e.clip2,voiceover:e.voiceover,audioMood:e.audioMood}}var an=require("fs"),ja=require("path"),No=require("os"),Jn=require("@fal-ai/client"),jl="fal-ai/mmaudio-v2",zl="fal-ai/elevenlabs/tts",$l="fal-ai/google/gemini-2.5-flash-preview-tts";async function Mo(e){let t=await fetch(e);if(!t.ok)throw new Error(`Failed to download TTS audio (${t.status})`);return Buffer.from(await t.arrayBuffer())}async function za(e){console.log("[AudioGenerator] Generating voiceover...");let t=(0,ja.join)((0,No.tmpdir)(),`tts-${Date.now()}`);(0,an.mkdirSync)(t,{recursive:!0});let n=(0,ja.join)(t,"voiceover.mp3");try{let s=process.env.ELEVENLABS_VOICE_ID??"pNInz6obpgDQGcFmaJgB",o=await Jn.fal.run(zl,{input:{text:e,voice_id:s,model_id:"eleven_v3"}});return(0,an.writeFileSync)(n,await Mo(o.audio.url)),console.log("[AudioGenerator] TTS: ElevenLabs via fal"),n}catch(s){console.warn("[AudioGenerator] ElevenLabs via fal failed, trying Gemini:",s.message)}let a=process.env.GEMINI_TTS_VOICE??"Kore",i=await Jn.fal.run($l,{input:{text:e,voice:a}});return(0,an.writeFileSync)(n,await Mo(i.audio.url)),console.log("[AudioGenerator] TTS: Gemini via fal"),n}async function $a(e,t,n){return console.log("[AudioGenerator] Adding background audio via MMAudio V2..."),(await Jn.fal.run(jl,{input:{video_url:e,prompt:t,negative_prompt:"speech, voice, talking, dialogue, narration, vocals, singing, human voice, conversation, words, lyrics, announcer, commentary",duration:n,cfg_strength:4.5}})).video.url}var Za=require("child_process"),qn=require("fs"),Oe=require("path"),vo=require("@fal-ai/client");async function Qa(e,t){let n=await fetch(e);if(!n.ok)throw new Error(`Download failed (${n.status}): ${e}`);(0,qn.writeFileSync)(t,Buffer.from(await n.arrayBuffer()))}async function ti(e,t,n){(0,qn.mkdirSync)(n,{recursive:!0});let a=Date.now(),i=(0,Oe.join)(n,`clip1-${a}.mp4`),s=(0,Oe.join)(n,`clip2-${a}.mp4`),o=(0,Oe.join)(n,`combined-${a}.mp4`);return console.log("[VideoMixer] Downloading clips..."),await Promise.all([Qa(e,i),Qa(t,s)]),console.log("[VideoMixer] Concatenating..."),(0,Za.execSync)(`ffmpeg -i "${i}" -i "${s}" -filter_complex "[0:v][1:v]concat=n=2:v=1:a=0[v]" -map "[v]" -y "${o}" -loglevel error`),o}async function ei(e){let{readFileSync:t}=await import("fs"),n=new Blob([t(e)],{type:"video/mp4"}),a=await vo.fal.storage.upload(n);return console.log("[VideoMixer] Uploaded to fal:",a),a}async function ni(e,t,n){let a=Date.now(),i=(0,Oe.join)(n,`voiceover-${a}.wav`),s=(0,Oe.join)(n,`final-${a}.mp4`);return console.log("[VideoMixer] Downloading voiceover..."),await Qa(t,i),console.log("[VideoMixer] Mixing voiceover over background audio..."),(0,Za.execSync)(`ffmpeg -i "${e}" -i "${i}" -filter_complex "[0:a]volume=0.2[bg];[1:a]volume=1.0[vo];[bg][vo]amix=inputs=2:duration=first[a]" -map 0:v -map "[a]" -c:v copy -y "${s}" -loglevel error`),s}var
|
|
21926
|
+
Answer: ${a.slice(0,500)}`}]})});if(!i.ok)throw new Error(`LLM call failed (${i.status}): ${await i.text()}`);let s=await i.json();t===ko?Pa({vendor:"openrouter",model:Xa,units:s.usage?.cost??0,unitType:"usd"}):Pa({vendor:"deepinfra_qwen",model:Xa,units:s.usage?.completion_tokens??0,unitType:"tokens"});let o=s.choices[0]?.message?.content?.trim()??"",d=o.match(/\{[\s\S]*\}/);if(!d)throw new Error(`No JSON in QWEN response: ${o.slice(0,200)}`);let l=JSON.parse(d[0]);if(!l.clip1||!l.clip2||!l.voiceover||!l.audioMood)throw new Error(`QWEN response missing fields: ${o.slice(0,200)}`);return l}async function Kn(e,t){let n=process.env.DEEPINFRA_API_KEY,a=process.env.OPENROUTER_API_KEY;if(n)try{return await To(n,ql,e,t)}catch(i){console.warn("[promptBuilder] DeepInfra failed, trying OpenRouter:",i.message)}if(a)return await To(a,ko,e,t);throw new Error("No LLM key \u2014 set DEEPINFRA_API_KEY or OPENROUTER_API_KEY")}function fo(e){if(!e.clip1||!e.clip2||!e.voiceover||!e.audioMood)throw new Error("Episode brief is missing prompt fields \u2014 run blog-to-video skill to regenerate");return{clip1:e.clip1,clip2:e.clip2,voiceover:e.voiceover,audioMood:e.audioMood}}var an=require("fs"),ja=require("path"),No=require("os"),Jn=require("@fal-ai/client"),jl="fal-ai/mmaudio-v2",zl="fal-ai/elevenlabs/tts",$l="fal-ai/google/gemini-2.5-flash-preview-tts";async function Mo(e){let t=await fetch(e);if(!t.ok)throw new Error(`Failed to download TTS audio (${t.status})`);return Buffer.from(await t.arrayBuffer())}async function za(e){console.log("[AudioGenerator] Generating voiceover...");let t=(0,ja.join)((0,No.tmpdir)(),`tts-${Date.now()}`);(0,an.mkdirSync)(t,{recursive:!0});let n=(0,ja.join)(t,"voiceover.mp3");try{let s=process.env.ELEVENLABS_VOICE_ID??"pNInz6obpgDQGcFmaJgB",o=await Jn.fal.run(zl,{input:{text:e,voice_id:s,model_id:"eleven_v3"}});return(0,an.writeFileSync)(n,await Mo(o.audio.url)),console.log("[AudioGenerator] TTS: ElevenLabs via fal"),n}catch(s){console.warn("[AudioGenerator] ElevenLabs via fal failed, trying Gemini:",s.message)}let a=process.env.GEMINI_TTS_VOICE??"Kore",i=await Jn.fal.run($l,{input:{text:e,voice:a}});return(0,an.writeFileSync)(n,await Mo(i.audio.url)),console.log("[AudioGenerator] TTS: Gemini via fal"),n}async function $a(e,t,n){return console.log("[AudioGenerator] Adding background audio via MMAudio V2..."),(await Jn.fal.run(jl,{input:{video_url:e,prompt:t,negative_prompt:"speech, voice, talking, dialogue, narration, vocals, singing, human voice, conversation, words, lyrics, announcer, commentary",duration:n,cfg_strength:4.5}})).video.url}var Za=require("child_process"),qn=require("fs"),Oe=require("path"),vo=require("@fal-ai/client");async function Qa(e,t){let n=await fetch(e);if(!n.ok)throw new Error(`Download failed (${n.status}): ${e}`);(0,qn.writeFileSync)(t,Buffer.from(await n.arrayBuffer()))}async function ti(e,t,n){(0,qn.mkdirSync)(n,{recursive:!0});let a=Date.now(),i=(0,Oe.join)(n,`clip1-${a}.mp4`),s=(0,Oe.join)(n,`clip2-${a}.mp4`),o=(0,Oe.join)(n,`combined-${a}.mp4`);return console.log("[VideoMixer] Downloading clips..."),await Promise.all([Qa(e,i),Qa(t,s)]),console.log("[VideoMixer] Concatenating..."),(0,Za.execSync)(`ffmpeg -i "${i}" -i "${s}" -filter_complex "[0:v][1:v]concat=n=2:v=1:a=0[v]" -map "[v]" -y "${o}" -loglevel error`),o}async function ei(e){let{readFileSync:t}=await import("fs"),n=new Blob([t(e)],{type:"video/mp4"}),a=await vo.fal.storage.upload(n);return console.log("[VideoMixer] Uploaded to fal:",a),a}async function ni(e,t,n){let a=Date.now(),i=(0,Oe.join)(n,`voiceover-${a}.wav`),s=(0,Oe.join)(n,`final-${a}.mp4`);return console.log("[VideoMixer] Downloading voiceover..."),await Qa(t,i),console.log("[VideoMixer] Mixing voiceover over background audio..."),(0,Za.execSync)(`ffmpeg -i "${e}" -i "${i}" -filter_complex "[0:a]volume=0.2[bg];[1:a]volume=1.0[vo];[bg][vo]amix=inputs=2:duration=first[a]" -map 0:v -map "[a]" -c:v copy -y "${s}" -loglevel error`),s}var _o="bytedance/seedance-2.0/text-to-video",bo="bytedance/seedance-2.0/image-to-video";function Xn(e,t,n,a){return{prompt:e,resolution:t.resolution??"720p",duration:t.clipDurationSeconds??8,aspect_ratio:t.aspectRatio??"16:9",generate_audio:!1,...n!==void 0?{seed:n}:{},...a!==void 0?{image_url:a}:{}}}async function jn(e,t){let{request_id:n}=await ne.fal.queue.submit(e,{input:t});for(console.log(`[fal] submitted ${e} \u2192 ${n}`);;){await new Promise(s=>setTimeout(s,5e3));let a=await ne.fal.queue.status(e,{requestId:n,logs:!1});if(console.log(`[fal] ${n} \u2192 ${a.status}`),a.status==="FAILED")throw new Error(`Request ${n} failed`);if(a.status!=="COMPLETED")continue;return(await ne.fal.queue.result(e,{requestId:n})).data}}async function Eo(e,t){let n=Date.now(),a=(0,ee.join)(t,`clip1-raw-${n}.mp4`),i=(0,ee.join)(t,`last-frame-${n}.jpg`),s=await fetch(e);if(!s.ok)throw new Error(`Failed to download clip 1 (${s.status})`);(0,lt.writeFileSync)(a,Buffer.from(await s.arrayBuffer()));try{(0,Po.execSync)(`ffmpeg -sseof -0.1 -i "${a}" -vframes 1 -y "${i}" -loglevel error`)}finally{try{(0,lt.unlinkSync)(a)}catch{}}return i}var zn=class{constructor(t){let n=t??process.env.FAL_KEY;if(!n)throw new Error("FAL_KEY is required");ne.fal.config({credentials:n})}async generateClipPair(t,n,a={}){let i=a.outputDir??(0,ee.join)((0,ai.tmpdir)(),`paa-video-${Date.now()}`);(0,lt.mkdirSync)(i,{recursive:!0}),console.log(`
|
|
21927
21927
|
[1/7] Generating prompts via QWEN 3.6...`);let s=await Kn(t,n);console.log(" Voiceover:",s.voiceover),console.log(" Audio mood:",s.audioMood),console.log(`
|
|
21928
|
-
[2/7] Generating clip 1 (text-to-video)...`);let o=await jn(
|
|
21928
|
+
[2/7] Generating clip 1 (text-to-video)...`);let o=await jn(_o,Xn(s.clip1,a,a.seed));console.log(`
|
|
21929
21929
|
[3/7] Extracting last frame \u2192 clip 2 start...`);let d=await Eo(o.video.url,i),l=new Blob([(0,lt.readFileSync)(d)],{type:"image/jpeg"}),U=await ne.fal.storage.upload(l);try{(0,lt.unlinkSync)(d)}catch{}console.log(`
|
|
21930
|
-
[4/7] Generating clip 2 (image-to-video from last frame)...`);let S=a.seed!==void 0?a.seed+1:void 0,r=await jn(
|
|
21930
|
+
[4/7] Generating clip 2 (image-to-video from last frame)...`);let S=a.seed!==void 0?a.seed+1:void 0,r=await jn(bo,Xn(s.clip2,a,S,U));console.log(`
|
|
21931
21931
|
[5/7] Concatenating clips + generating voiceover (parallel)...`);let[u,c]=await Promise.all([ti(o.video.url,r.video.url,i),za(s.voiceover)]);console.log(`
|
|
21932
21932
|
[6/7] Adding background audio via MMAudio V2...`);let h=await ei(u),m=(a.clipDurationSeconds??8)*2,f=await $a(h,s.audioMood,m);console.log(`
|
|
21933
21933
|
[7/7] Overlaying voiceover on final video...`);let M=(0,ee.join)(i,`with-bg-audio-${Date.now()}.mp4`),y=await fetch(f);(0,lt.writeFileSync)(M,Buffer.from(await y.arrayBuffer()));let A=await ni(M,c,i);return{clip1Url:o.video.url,clip2Url:r.video.url,finalVideoPath:A,seed:o.seed,promptClip1:s.clip1,promptClip2:s.clip2,voiceover:s.voiceover,audioMood:s.audioMood}}async generateEpisode(t,n={}){let a=n.outputDir??(0,ee.join)((0,ai.tmpdir)(),`episode-${t.episodeNumber}-${Date.now()}`);(0,lt.mkdirSync)(a,{recursive:!0});let i=fo(t);console.log(`
|
|
21934
21934
|
[Episode ${t.episodeNumber}/${t.episodeCount}] ${t.sectionTitle}`),console.log(" Voiceover:",i.voiceover),console.log(`
|
|
21935
|
-
[2/7] Generating clip 1 (text-to-video)...`);let s=await jn(
|
|
21935
|
+
[2/7] Generating clip 1 (text-to-video)...`);let s=await jn(_o,Xn(i.clip1,n,n.seed));console.log(`
|
|
21936
21936
|
[3/7] Extracting last frame \u2192 clip 2 start...`);let o=await Eo(s.video.url,a),d=new Blob([(0,lt.readFileSync)(o)],{type:"image/jpeg"}),l=await ne.fal.storage.upload(d);try{(0,lt.unlinkSync)(o)}catch{}console.log(`
|
|
21937
|
-
[4/7] Generating clip 2 (image-to-video from last frame)...`);let U=n.seed!==void 0?n.seed+1:void 0,S=await jn(
|
|
21937
|
+
[4/7] Generating clip 2 (image-to-video from last frame)...`);let U=n.seed!==void 0?n.seed+1:void 0,S=await jn(bo,Xn(i.clip2,n,U,l));console.log(`
|
|
21938
21938
|
[5/7] Concatenating clips + generating voiceover (parallel)...`);let[r,u]=await Promise.all([ti(s.video.url,S.video.url,a),za(i.voiceover)]);console.log(`
|
|
21939
21939
|
[6/7] Adding background audio via MMAudio V2...`);let c=await ei(r),h=(n.clipDurationSeconds??8)*2,m=await $a(c,i.audioMood,h);console.log(`
|
|
21940
21940
|
[7/7] Overlaying voiceover on final video...`);let f=(0,ee.join)(a,`with-bg-audio-${Date.now()}.mp4`),M=await fetch(m);(0,lt.writeFileSync)(f,Buffer.from(await M.arrayBuffer()));let y=await ni(f,u,a);return{clip1Url:s.video.url,clip2Url:S.video.url,finalVideoPath:y,seed:s.seed,promptClip1:i.clip1,promptClip2:i.clip2,voiceover:i.voiceover,audioMood:i.audioMood}}};0&&(module.exports={VideoGenerator,buildClipPrompts,harvest});
|