@loamly/tracker 2.0.0 → 2.0.2
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/dist/index.cjs +37 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.mjs +37 -2
- package/dist/index.mjs.map +1 -1
- package/dist/loamly.iife.global.js +37 -2
- package/dist/loamly.iife.global.js.map +1 -1
- package/dist/loamly.iife.min.global.js +1 -1
- package/dist/loamly.iife.min.global.js.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +1 -1
- package/src/core.ts +52 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var Loamly=(()=>{var J=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var Te=Object.getOwnPropertyNames;var Ee=Object.prototype.hasOwnProperty;var ke=(n,e)=>{for(var t in e)J(n,t,{get:e[t],enumerable:!0})},Se=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Te(e))!Ee.call(n,s)&&s!==t&&J(n,s,{get:()=>e[s],enumerable:!(i=we(e,s))||i.enumerable});return n};var Ie=n=>Se(J({},"__esModule",{value:!0}),n);var Je={};ke(Je,{default:()=>$e,loamly:()=>F});var S="2.0.0",a={apiHost:"https://app.loamly.ai",endpoints:{visit:"/api/ingest/visit",behavioral:"/api/ingest/behavioral",session:"/api/ingest/session",resolve:"/api/tracker/resolve",health:"/api/tracker/health",ping:"/api/tracker/ping"},pingInterval:3e4,batchSize:10,batchTimeout:5e3,sessionTimeout:18e5,maxTextLength:100,timeSpentThresholdMs:5e3},R={"chatgpt.com":"chatgpt","chat.openai.com":"chatgpt","claude.ai":"claude","perplexity.ai":"perplexity","bard.google.com":"bard","gemini.google.com":"gemini","copilot.microsoft.com":"copilot","github.com/copilot":"github-copilot","you.com":"you","phind.com":"phind","poe.com":"poe"};function le(){try{let n=performance.getEntriesByType("navigation");if(!n||n.length===0)return{nav_type:"unknown",confidence:0,signals:["no_timing_data"]};let e=n[0],t=[],i=0,s=e.fetchStart-e.startTime;s<5?(i+=.25,t.push("instant_fetch_start")):s<20&&(i+=.15,t.push("fast_fetch_start")),e.domainLookupEnd-e.domainLookupStart===0&&(i+=.15,t.push("no_dns_lookup")),e.connectEnd-e.connectStart===0&&(i+=.15,t.push("no_tcp_connect")),e.redirectCount===0&&(i+=.1,t.push("no_redirects")),Ce(e)<10&&(i+=.15,t.push("uniform_timing")),(!document.referrer||document.referrer==="")&&(i+=.1,t.push("no_referrer"));let m=Math.min(i,1);return{nav_type:i>=.5?"likely_paste":"likely_click",confidence:Math.round(m*1e3)/1e3,signals:t}}catch{return{nav_type:"unknown",confidence:0,signals:["detection_error"]}}}function Ce(n){let e=[n.fetchStart-n.startTime,n.domainLookupEnd-n.domainLookupStart,n.connectEnd-n.connectStart,n.responseStart-n.requestStart].filter(s=>s>=0);if(e.length===0)return 100;let t=e.reduce((s,r)=>s+r,0)/e.length,i=e.reduce((s,r)=>s+Math.pow(r-t,2),0)/e.length;return Math.sqrt(i)}function ce(n){if(!n)return null;try{let t=new URL(n).hostname.toLowerCase();for(let[i,s]of Object.entries(R))if(t.includes(i)||n.includes(i))return{isAI:!0,platform:s,confidence:.95,method:"referrer"};return null}catch{for(let[e,t]of Object.entries(R))if(n.toLowerCase().includes(e.toLowerCase()))return{isAI:!0,platform:t,confidence:.85,method:"referrer"};return null}}function ue(n){try{let t=new URL(n).searchParams.get("utm_source")?.toLowerCase();if(t){for(let[i,s]of Object.entries(R))if(t.includes(i.split(".")[0]))return{isAI:!0,platform:s,confidence:.99,method:"referrer"};if(t.includes("ai")||t.includes("llm")||t.includes("chatbot"))return{isAI:!0,platform:t,confidence:.9,method:"referrer"}}return null}catch{return null}}var de={human:{time_to_first_click_delayed:.85,time_to_first_click_normal:.75,time_to_first_click_fast:.5,time_to_first_click_immediate:.25,scroll_speed_variable:.8,scroll_speed_erratic:.7,scroll_speed_uniform:.35,scroll_speed_none:.45,nav_timing_click:.75,nav_timing_unknown:.55,nav_timing_paste:.35,has_referrer:.7,no_referrer:.45,homepage_landing:.65,deep_landing:.5,mouse_movement_curved:.9,mouse_movement_linear:.3,mouse_movement_none:.4,form_fill_normal:.85,form_fill_fast:.6,form_fill_instant:.2,focus_blur_normal:.75,focus_blur_rapid:.45},ai_influenced:{time_to_first_click_immediate:.75,time_to_first_click_fast:.55,time_to_first_click_normal:.4,time_to_first_click_delayed:.35,scroll_speed_none:.55,scroll_speed_uniform:.7,scroll_speed_variable:.35,scroll_speed_erratic:.4,nav_timing_paste:.75,nav_timing_unknown:.5,nav_timing_click:.35,no_referrer:.65,has_referrer:.4,deep_landing:.6,homepage_landing:.45,mouse_movement_none:.6,mouse_movement_linear:.75,mouse_movement_curved:.25,form_fill_instant:.8,form_fill_fast:.55,form_fill_normal:.3,focus_blur_rapid:.6,focus_blur_normal:.4}},me={human:.85,ai_influenced:.15},he=.5,B=class{constructor(e=1e4){this.classified=!1;this.result=null;this.onClassify=null;this.minSessionTime=e,this.data={firstClickTime:null,scrollEvents:[],mouseEvents:[],formEvents:[],focusBlurEvents:[],startTime:Date.now()}}setOnClassify(e){this.onClassify=e}recordClick(){this.data.firstClickTime===null&&(this.data.firstClickTime=Date.now()),this.checkAndClassify()}recordScroll(e){this.data.scrollEvents.push({time:Date.now(),position:e}),this.data.scrollEvents.length>50&&(this.data.scrollEvents=this.data.scrollEvents.slice(-50)),this.checkAndClassify()}recordMouse(e,t){this.data.mouseEvents.push({time:Date.now(),x:e,y:t}),this.data.mouseEvents.length>100&&(this.data.mouseEvents=this.data.mouseEvents.slice(-100)),this.checkAndClassify()}recordFormStart(e){this.data.formEvents.find(i=>i.fieldId===e&&i.endTime===0)||this.data.formEvents.push({fieldId:e,startTime:Date.now(),endTime:0})}recordFormEnd(e){let t=this.data.formEvents.find(i=>i.fieldId===e&&i.endTime===0);t&&(t.endTime=Date.now()),this.checkAndClassify()}recordFocusBlur(e){this.data.focusBlurEvents.push({type:e,time:Date.now()}),this.data.focusBlurEvents.length>20&&(this.data.focusBlurEvents=this.data.focusBlurEvents.slice(-20))}checkAndClassify(){this.classified||Date.now()-this.data.startTime<this.minSessionTime||!(this.data.scrollEvents.length>=2||this.data.mouseEvents.length>=5||this.data.firstClickTime!==null)||this.classify()}forceClassify(){return this.classified?this.result:this.classify()}classify(){let e=Date.now()-this.data.startTime,t=this.extractSignals(),i=Math.log(me.human),s=Math.log(me.ai_influenced);for(let k of t){let $=de.human[k]??he,ae=de.ai_influenced[k]??he;i+=Math.log($),s+=Math.log(ae)}let r=Math.max(i,s),d=Math.exp(i-r),h=Math.exp(s-r),m=d+h,u=d/m,o=h/m,E,w;return u>.6?(E="human",w=u):o>.6?(E="ai_influenced",w=o):(E="uncertain",w=Math.max(u,o)),this.result={classification:E,humanProbability:u,aiProbability:o,confidence:w,signals:t,timestamp:Date.now(),sessionDurationMs:e},this.classified=!0,this.onClassify&&this.onClassify(this.result),this.result}extractSignals(){let e=[];if(this.data.firstClickTime!==null){let i=this.data.firstClickTime-this.data.startTime;i<500?e.push("time_to_first_click_immediate"):i<2e3?e.push("time_to_first_click_fast"):i<1e4?e.push("time_to_first_click_normal"):e.push("time_to_first_click_delayed")}if(this.data.scrollEvents.length===0)e.push("scroll_speed_none");else if(this.data.scrollEvents.length>=3){let i=[];for(let m=1;m<this.data.scrollEvents.length;m++){let u=this.data.scrollEvents[m].time-this.data.scrollEvents[m-1].time;i.push(u)}let s=i.reduce((m,u)=>m+u,0)/i.length,r=i.reduce((m,u)=>m+Math.pow(u-s,2),0)/i.length,d=Math.sqrt(r),h=s>0?d/s:0;h<.2?e.push("scroll_speed_uniform"):h<.6?e.push("scroll_speed_variable"):e.push("scroll_speed_erratic")}if(this.data.mouseEvents.length===0)e.push("mouse_movement_none");else if(this.data.mouseEvents.length>=10){let i=Math.min(this.data.mouseEvents.length,20),s=this.data.mouseEvents.slice(-i),r=0,d=0,h=0,m=0;for(let g of s)r+=g.x,d+=g.y,h+=g.x*g.y,m+=g.x*g.x;let u=i*m-r*r,o=u!==0?(i*h-r*d)/u:0,E=(d-o*r)/i,w=0,k=0,$=d/i;for(let g of s){let be=o*g.x+E;w+=Math.pow(g.y-be,2),k+=Math.pow(g.y-$,2)}(k!==0?1-w/k:0)>.95?e.push("mouse_movement_linear"):e.push("mouse_movement_curved")}let t=this.data.formEvents.filter(i=>i.endTime>0);if(t.length>0){let i=t.reduce((s,r)=>s+(r.endTime-r.startTime),0)/t.length;i<100?e.push("form_fill_instant"):i<500?e.push("form_fill_fast"):e.push("form_fill_normal")}if(this.data.focusBlurEvents.length>=4){let i=this.data.focusBlurEvents.slice(-10),s=[];for(let d=1;d<i.length;d++)s.push(i[d].time-i[d-1].time);s.reduce((d,h)=>d+h,0)/s.length<1e3?e.push("focus_blur_rapid"):e.push("focus_blur_normal")}return e}addContextSignal(e){}getResult(){return this.result}hasClassified(){return this.classified}};var P=class{constructor(){this.sequence=[];this.firstInteractionTime=null;this.analyzed=!1;this.result=null;this.pageLoadTime=performance.now()}initTracking(){document.addEventListener("focus",t=>{this.recordEvent("focus",t.target)},!0),document.addEventListener("blur",t=>{this.recordEvent("blur",t.target)},!0),window.addEventListener("focus",()=>{this.recordEvent("window_focus",null)}),window.addEventListener("blur",()=>{this.recordEvent("window_blur",null)});let e=()=>{this.firstInteractionTime===null&&(this.firstInteractionTime=performance.now())};document.addEventListener("click",e,{once:!0,passive:!0}),document.addEventListener("keydown",e,{once:!0,passive:!0})}recordEvent(e,t){let i={type:e,target:t?.tagName||"WINDOW",timestamp:performance.now()};this.sequence.push(i),this.sequence.length>20&&(this.sequence=this.sequence.slice(-20))}analyze(){if(this.analyzed&&this.result)return this.result;let e=[],t=0,i=this.sequence.filter(o=>o.timestamp<this.pageLoadTime+500);i.some(o=>o.type==="window_focus")&&(e.push("early_window_focus"),t+=.15),i.some(o=>o.type==="focus"&&o.target==="BODY")&&(e.push("early_body_focus"),t+=.15),this.sequence.some(o=>o.type==="focus"&&o.target==="A")||(e.push("no_link_focus"),t+=.1);let h=this.sequence.find(o=>o.type==="focus");h&&(h.target==="BODY"||h.target==="HTML")&&(e.push("first_focus_body"),t+=.1),this.sequence.filter(o=>o.type==="window_focus"||o.type==="window_blur").length<=2&&(e.push("minimal_window_switches"),t+=.05),this.firstInteractionTime!==null&&this.firstInteractionTime-this.pageLoadTime>3e3&&(e.push("delayed_first_interaction"),t+=.1),t=Math.min(t,.65);let u;return t>=.35?u="likely_paste":e.length===0?u="unknown":u="likely_click",this.result={nav_type:u,confidence:t,signals:e,sequence:this.sequence.slice(-10),time_to_first_interaction_ms:this.firstInteractionTime?Math.round(this.firstInteractionTime-this.pageLoadTime):null},this.analyzed=!0,this.result}getResult(){return this.analyze()}hasAnalyzed(){return this.analyzed}getSequence(){return[...this.sequence]}reset(){this.sequence=[],this.pageLoadTime=performance.now(),this.firstInteractionTime=null,this.analyzed=!1,this.result=null}};var Z=class{constructor(){this.detected=!1;this.checkComplete=!1;this.observer=null}init(e=5e3){typeof document>"u"||(this.check(),!this.detected&&document.body&&(this.observer=new MutationObserver(()=>this.check()),this.observer.observe(document.body,{childList:!0,subtree:!0}),setTimeout(()=>{this.observer&&!this.detected&&(this.observer.disconnect(),this.observer=null,this.checkComplete=!0)},e)))}check(){document.querySelector(".pplx-agent-overlay-stop-button")&&(this.detected=!0,this.checkComplete=!0,this.observer&&(this.observer.disconnect(),this.observer=null))}isDetected(){return this.detected}isCheckComplete(){return this.checkComplete}destroy(){this.observer&&(this.observer.disconnect(),this.observer=null)}},ee=class{constructor(e=500){this.lastX=-1;this.lastY=-1;this.teleportingClicks=0;this.totalMovements=0;this.handleMove=e=>{this.totalMovements++,this.lastX=e.clientX,this.lastY=e.clientY};this.handleClick=e=>{if(this.lastX!==-1&&this.lastY!==-1){let t=Math.abs(e.clientX-this.lastX),i=Math.abs(e.clientY-this.lastY);(t>this.teleportThreshold||i>this.teleportThreshold)&&this.teleportingClicks++}this.lastX=e.clientX,this.lastY=e.clientY};this.teleportThreshold=e}init(){typeof document>"u"||(document.addEventListener("mousemove",this.handleMove,{passive:!0}),document.addEventListener("mousedown",this.handleClick,{passive:!0}))}getPatterns(){return{teleportingClicks:this.teleportingClicks,totalMovements:this.totalMovements}}destroy(){typeof document>"u"||(document.removeEventListener("mousemove",this.handleMove),document.removeEventListener("mousedown",this.handleClick))}},te=class{constructor(){this.detected=!1}detect(){if(typeof navigator>"u")return!1;if(navigator.webdriver)return this.detected=!0,!0;if(typeof window<"u"){let e=window,t=["__webdriver_evaluate","__selenium_evaluate","__webdriver_script_function","__webdriver_script_func","__webdriver_script_fn","__fxdriver_evaluate","__driver_unwrapped","__webdriver_unwrapped","__driver_evaluate","__selenium_unwrapped","__fxdriver_unwrapped"];for(let i of t)if(i in e)return this.detected=!0,!0}return!1}isDetected(){return this.detected}},N=class{constructor(){this.initialized=!1;this.cometDetector=new Z,this.mouseAnalyzer=new ee,this.cdpDetector=new te}init(){this.initialized||(this.initialized=!0,this.cometDetector.init(),this.mouseAnalyzer.init(),this.cdpDetector.detect())}getResult(){let e=[],t=0;this.cometDetector.isDetected()&&(e.push("comet_dom_detected"),t=Math.max(t,.85)),this.cdpDetector.isDetected()&&(e.push("cdp_detected"),t=Math.max(t,.92));let i=this.mouseAnalyzer.getPatterns();return i.teleportingClicks>0&&(e.push(`teleporting_clicks:${i.teleportingClicks}`),t=Math.max(t,.78)),{cometDOMDetected:this.cometDetector.isDetected(),cdpDetected:this.cdpDetector.isDetected(),mousePatterns:i,agenticProbability:t,signals:e}}destroy(){this.cometDetector.destroy(),this.mouseAnalyzer.destroy()}};var De={batchSize:a.batchSize,batchTimeout:a.batchTimeout,maxRetries:3,retryDelayMs:1e3,storageKey:"_loamly_queue"},H=class{constructor(e,t={}){this.queue=[];this.batchTimer=null;this.isFlushing=!1;this.endpoint=e,this.config={...De,...t},this.loadFromStorage()}push(e,t){let i={id:this.generateId(),type:e,payload:t,timestamp:Date.now(),retries:0};this.queue.push(i),this.saveToStorage(),this.scheduleBatch()}async flush(){if(!(this.isFlushing||this.queue.length===0)){this.isFlushing=!0,this.clearBatchTimer();try{let e=[...this.queue];this.queue=[],await this.sendBatch(e)}finally{this.isFlushing=!1,this.saveToStorage()}}}flushBeacon(){if(this.queue.length===0)return!0;let e=this.queue.map(i=>({type:i.type,...i.payload,_queue_id:i.id,_queue_timestamp:i.timestamp})),t=navigator.sendBeacon?.(this.endpoint,JSON.stringify({events:e,beacon:!0}))??!1;return t&&(this.queue=[],this.clearStorage()),t}get length(){return this.queue.length}scheduleBatch(){if(!this.batchTimer){if(this.queue.length>=this.config.batchSize){this.flush();return}this.batchTimer=setTimeout(()=>{this.batchTimer=null,this.flush()},this.config.batchTimeout)}}clearBatchTimer(){this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null)}async sendBatch(e){if(e.length===0)return;let t={events:e.map(i=>({type:i.type,...i.payload,_queue_id:i.id,_queue_timestamp:i.timestamp})),batch:!0};try{let i=await fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!i.ok)throw new Error(`HTTP ${i.status}`)}catch{for(let s of e)s.retries<this.config.maxRetries&&(s.retries++,this.queue.push(s));if(this.queue.length>0){let s=this.config.retryDelayMs*Math.pow(2,e[0].retries-1);setTimeout(()=>this.flush(),s)}}}loadFromStorage(){try{let e=localStorage.getItem(this.config.storageKey);if(e){let t=JSON.parse(e);if(Array.isArray(t)){let i=Date.now()-864e5;this.queue=t.filter(s=>s.timestamp>i)}}}catch{}}saveToStorage(){try{this.queue.length>0?localStorage.setItem(this.config.storageKey,JSON.stringify(this.queue)):this.clearStorage()}catch{}}clearStorage(){try{localStorage.removeItem(this.config.storageKey)}catch{}}generateId(){return`${Date.now()}-${Math.random().toString(36).substring(2,9)}`}};var O=class{constructor(e,t,i,s={}){this.intervalId=null;this.isVisible=!0;this.currentScrollDepth=0;this.ping=async()=>{let e=this.getData();if(this.config.onPing?.(e),this.config.endpoint)try{await fetch(this.config.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}catch{}};this.handleVisibilityChange=()=>{this.isVisible=document.visibilityState==="visible"};this.handleScroll=()=>{let e=Math.round((window.scrollY+window.innerHeight)/document.documentElement.scrollHeight*100);e>this.currentScrollDepth&&(this.currentScrollDepth=Math.min(e,100))};this.sessionId=e,this.visitorId=t,this.version=i,this.pageLoadTime=Date.now(),this.config={interval:a.pingInterval,endpoint:"",...s},document.addEventListener("visibilitychange",this.handleVisibilityChange),window.addEventListener("scroll",this.handleScroll,{passive:!0})}start(){this.intervalId||(this.intervalId=setInterval(()=>{this.isVisible&&this.ping()},this.config.interval),this.ping())}stop(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null),document.removeEventListener("visibilitychange",this.handleVisibilityChange),window.removeEventListener("scroll",this.handleScroll)}updateScrollDepth(e){e>this.currentScrollDepth&&(this.currentScrollDepth=e)}getData(){return{session_id:this.sessionId,visitor_id:this.visitorId,url:window.location.href,time_on_page_ms:Date.now()-this.pageLoadTime,scroll_depth:this.currentScrollDepth,is_active:this.isVisible,tracker_version:this.version}}};var Fe=[30,60,90,100],L=class{constructor(e={}){this.maxDepth=0;this.reportedChunks=new Set;this.ticking=!1;this.isVisible=!0;this.handleScroll=()=>{!this.ticking&&this.isVisible&&(requestAnimationFrame(()=>{this.checkScrollDepth(),this.ticking=!1}),this.ticking=!0)};this.handleVisibility=()=>{this.isVisible=document.visibilityState==="visible"};this.config={chunks:Fe,...e},this.startTime=Date.now()}start(){window.addEventListener("scroll",this.handleScroll,{passive:!0}),document.addEventListener("visibilitychange",this.handleVisibility),this.checkScrollDepth()}stop(){window.removeEventListener("scroll",this.handleScroll),document.removeEventListener("visibilitychange",this.handleVisibility)}getMaxDepth(){return this.maxDepth}getReportedChunks(){return Array.from(this.reportedChunks).sort((e,t)=>e-t)}getFinalEvent(){let e=document.documentElement.scrollHeight,t=window.innerHeight;return{depth:this.maxDepth,chunk:this.getChunkForDepth(this.maxDepth),time_to_reach_ms:Date.now()-this.startTime,total_height:e,viewport_height:t}}checkScrollDepth(){let e=window.scrollY,t=window.innerHeight,i=document.documentElement.scrollHeight;if(i<=t){this.updateDepth(100);return}let s=i-t,r=Math.min(100,Math.round(e/s*100));this.updateDepth(r)}updateDepth(e){if(!(e<=this.maxDepth)){this.maxDepth=e,this.config.onDepthChange?.(e);for(let t of this.config.chunks)e>=t&&!this.reportedChunks.has(t)&&(this.reportedChunks.add(t),this.reportChunk(t))}}reportChunk(e){let t=document.documentElement.scrollHeight,i=window.innerHeight,s={depth:this.maxDepth,chunk:e,time_to_reach_ms:Date.now()-this.startTime,total_height:t,viewport_height:i};this.config.onChunkReached?.(s)}getChunkForDepth(e){let t=this.config.chunks.sort((i,s)=>s-i);for(let i of t)if(e>=i)return i;return 0}};var Le={idleThresholdMs:3e4,updateIntervalMs:5e3},q=class{constructor(e={}){this.activeTime=0;this.idleTime=0;this.isVisible=!0;this.isIdle=!1;this.updateInterval=null;this.idleCheckInterval=null;this.handleVisibility=()=>{let e=this.isVisible;this.isVisible=document.visibilityState==="visible",e&&!this.isVisible?this.updateTimes():!e&&this.isVisible&&(this.lastUpdateTime=Date.now(),this.lastActivityTime=Date.now())};this.handleActivity=()=>{let e=Date.now();this.isIdle&&(this.isIdle=!1),this.lastActivityTime=e};this.config={...Le,...e},this.startTime=Date.now(),this.lastActivityTime=this.startTime,this.lastUpdateTime=this.startTime}start(){document.addEventListener("visibilitychange",this.handleVisibility),["mousemove","keydown","scroll","click","touchstart"].forEach(t=>{document.addEventListener(t,this.handleActivity,{passive:!0})}),this.updateInterval=setInterval(()=>{this.update()},this.config.updateIntervalMs),this.idleCheckInterval=setInterval(()=>{this.checkIdle()},1e3)}stop(){document.removeEventListener("visibilitychange",this.handleVisibility),["mousemove","keydown","scroll","click","touchstart"].forEach(t=>{document.removeEventListener(t,this.handleActivity)}),this.updateInterval&&(clearInterval(this.updateInterval),this.updateInterval=null),this.idleCheckInterval&&(clearInterval(this.idleCheckInterval),this.idleCheckInterval=null)}getMetrics(){return this.updateTimes(),{active_time_ms:this.activeTime,total_time_ms:Date.now()-this.startTime,idle_time_ms:this.idleTime,is_engaged:!this.isIdle&&this.isVisible}}getFinalMetrics(){return this.updateTimes(),this.getMetrics()}checkIdle(){let t=Date.now()-this.lastActivityTime;!this.isIdle&&t>=this.config.idleThresholdMs&&(this.isIdle=!0)}updateTimes(){let e=Date.now(),t=e-this.lastUpdateTime;this.isVisible&&(this.isIdle?this.idleTime+=t:this.activeTime+=t),this.lastUpdateTime=e}update(){this.isVisible&&(this.updateTimes(),this.config.onUpdate?.(this.getMetrics()))}};var fe={sensitiveFields:["password","pwd","pass","credit","card","cvv","cvc","ssn","social","secret","token","key"],trackableFields:["email","name","phone","company","first","last","city","country"],thankYouPatterns:[/thank[-_]?you/i,/success/i,/confirmation/i,/submitted/i,/complete/i]},U=class{constructor(e={}){this.formStartTimes=new Map;this.interactedForms=new Set;this.mutationObserver=null;this.handleFocusIn=e=>{let t=e.target;if(!this.isFormField(t))return;let i=t.closest("form"),s=this.getFormId(i||t);this.formStartTimes.has(s)||(this.formStartTimes.set(s,Date.now()),this.interactedForms.add(s),this.emitEvent({event_type:"form_start",form_id:s,form_type:this.detectFormType(i||t)}));let r=this.getFieldName(t);r&&!this.isSensitiveField(r)&&this.emitEvent({event_type:"form_field",form_id:s,form_type:this.detectFormType(i||t),field_name:this.sanitizeFieldName(r),field_type:t.type||t.tagName.toLowerCase()})};this.handleSubmit=e=>{let t=e.target;if(!t||t.tagName!=="FORM")return;let i=this.getFormId(t),s=this.formStartTimes.get(i);this.emitEvent({event_type:"form_submit",form_id:i,form_type:this.detectFormType(t),time_to_submit_ms:s?Date.now()-s:void 0,is_conversion:!0})};this.handleClick=e=>{let t=e.target;if(t.closest(".hs-button")||t.closest('[type="submit"]')){let i=t.closest("form");if(i&&i.classList.contains("hs-form")){let s=this.getFormId(i),r=this.formStartTimes.get(s);this.emitEvent({event_type:"form_submit",form_id:s,form_type:"hubspot",time_to_submit_ms:r?Date.now()-r:void 0,is_conversion:!0})}}t.closest('[data-qa="submit-button"]')&&this.emitEvent({event_type:"form_submit",form_id:"typeform_embed",form_type:"typeform",is_conversion:!0})};this.config={...fe,...e,sensitiveFields:[...fe.sensitiveFields,...e.sensitiveFields||[]]}}start(){document.addEventListener("focusin",this.handleFocusIn,{passive:!0}),document.addEventListener("submit",this.handleSubmit),document.addEventListener("click",this.handleClick,{passive:!0}),this.startMutationObserver(),this.checkThankYouPage(),this.scanForEmbeddedForms()}stop(){document.removeEventListener("focusin",this.handleFocusIn),document.removeEventListener("submit",this.handleSubmit),document.removeEventListener("click",this.handleClick),this.mutationObserver?.disconnect()}getInteractedForms(){return Array.from(this.interactedForms)}startMutationObserver(){this.mutationObserver=new MutationObserver(e=>{for(let t of e)for(let i of t.addedNodes)i instanceof HTMLElement&&((i.classList?.contains("hs-form")||i.querySelector?.(".hs-form"))&&this.trackEmbeddedForm(i,"hubspot"),(i.classList?.contains("typeform-widget")||i.querySelector?.("[data-tf-widget]"))&&this.trackEmbeddedForm(i,"typeform"),(i.classList?.contains("jotform-form")||i.querySelector?.(".jotform-form"))&&this.trackEmbeddedForm(i,"jotform"),(i.classList?.contains("gform_wrapper")||i.querySelector?.(".gform_wrapper"))&&this.trackEmbeddedForm(i,"gravity"))}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0})}scanForEmbeddedForms(){document.querySelectorAll(".hs-form").forEach(e=>{this.trackEmbeddedForm(e,"hubspot")}),document.querySelectorAll("[data-tf-widget], .typeform-widget").forEach(e=>{this.trackEmbeddedForm(e,"typeform")}),document.querySelectorAll(".jotform-form").forEach(e=>{this.trackEmbeddedForm(e,"jotform")}),document.querySelectorAll(".gform_wrapper").forEach(e=>{this.trackEmbeddedForm(e,"gravity")})}trackEmbeddedForm(e,t){let i=`${t}_${this.getFormId(e)}`;e.addEventListener("focusin",()=>{this.formStartTimes.has(i)||(this.formStartTimes.set(i,Date.now()),this.interactedForms.add(i),this.emitEvent({event_type:"form_start",form_id:i,form_type:t}))},{passive:!0})}checkThankYouPage(){let e=window.location.href.toLowerCase(),t=document.title.toLowerCase();for(let i of this.config.thankYouPatterns)if(i.test(e)||i.test(t)){this.emitEvent({event_type:"form_success",form_id:"page_conversion",form_type:"unknown",is_conversion:!0});break}}isFormField(e){let t=e.tagName;return t==="INPUT"||t==="TEXTAREA"||t==="SELECT"}getFormId(e){return e?e.id||e.getAttribute("name")||e.getAttribute("data-form-id")||"form_"+Math.random().toString(36).substring(2,8):"unknown"}getFieldName(e){return e.name||e.id||e.getAttribute("data-name")||""}isSensitiveField(e){let t=e.toLowerCase();return this.config.sensitiveFields.some(i=>t.includes(i))}sanitizeFieldName(e){return e.replace(/[0-9]+/g,"*").substring(0,50)}detectFormType(e){return e.classList.contains("hs-form")||e.closest(".hs-form")?"hubspot":e.classList.contains("typeform-widget")||e.closest("[data-tf-widget]")?"typeform":e.classList.contains("jotform-form")||e.closest(".jotform-form")?"jotform":e.classList.contains("gform_wrapper")||e.closest(".gform_wrapper")?"gravity":e.tagName==="FORM"?"native":"unknown"}emitEvent(e){this.config.onFormEvent?.(e)}};var z=class{constructor(e={}){this.originalPushState=null;this.originalReplaceState=null;this.handleStateChange=e=>{let t=window.location.href;t!==this.currentUrl&&this.emitNavigation(t,e)};this.handlePopState=()=>{let e=window.location.href;e!==this.currentUrl&&this.emitNavigation(e,"pop")};this.handleHashChange=()=>{let e=window.location.href;e!==this.currentUrl&&this.emitNavigation(e,"hash")};this.config=e,this.currentUrl=window.location.href,this.pageEnterTime=Date.now()}start(){this.patchHistoryAPI(),window.addEventListener("popstate",this.handlePopState),this.config.ignoreHashChange||window.addEventListener("hashchange",this.handleHashChange)}stop(){this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState),window.removeEventListener("popstate",this.handlePopState),window.removeEventListener("hashchange",this.handleHashChange)}navigate(e,t="push"){this.emitNavigation(e,t)}getCurrentUrl(){return this.currentUrl}getTimeOnPage(){return Date.now()-this.pageEnterTime}patchHistoryAPI(){this.originalPushState=history.pushState.bind(history),this.originalReplaceState=history.replaceState.bind(history),history.pushState=(...e)=>{let t=this.originalPushState(...e);return this.handleStateChange("push"),t},history.replaceState=(...e)=>{let t=this.originalReplaceState(...e);return this.handleStateChange("replace"),t}}emitNavigation(e,t){let i={from_url:this.currentUrl,to_url:e,navigation_type:t,time_on_previous_page_ms:Date.now()-this.pageEnterTime};this.currentUrl=e,this.pageEnterTime=Date.now(),this.config.onNavigate?.(i)}};function V(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let e=Math.random()*16|0;return(n==="x"?e:e&3|8).toString(16)})}function pe(){try{let n=localStorage.getItem("_loamly_vid");if(n)return n;let e=V();return localStorage.setItem("_loamly_vid",e),e}catch{return V()}}function ve(){try{let n=sessionStorage.getItem("loamly_session"),e=sessionStorage.getItem("loamly_start");if(n&&e)return{sessionId:n,isNew:!1};let t=V(),i=Date.now().toString();return sessionStorage.setItem("loamly_session",t),sessionStorage.setItem("loamly_start",i),{sessionId:t,isNew:!0}}catch{return{sessionId:V(),isNew:!0}}}function Y(n){let e={};try{let t=new URL(n).searchParams,i=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"];for(let s of i){let r=t.get(s);r&&(e[s]=r)}}catch{}return e}function ie(n,e){return n.length<=e?n:n.substring(0,e-3)+"..."}async function j(n,e,t=1e4){try{let i=new AbortController,s=setTimeout(()=>i.abort(),t),r=await fetch(n,{...e,signal:i.signal});return clearTimeout(s),r}catch{return null}}function G(n,e){return typeof navigator<"u"&&navigator.sendBeacon?navigator.sendBeacon(n,JSON.stringify(e)):!1}var ne={apiHost:a.apiHost},T=!1,se=!1,p=null,v=null,I=null,f=null,l=null,re=null,x=null,K=null,C=null,D=null,M=null,y=null,A=null,X=null,W=null;function c(...n){se&&console.log("[Loamly]",...n)}function b(n){return`${ne.apiHost}${n}`}function xe(n={}){if(T){c("Already initialized");return}ne={...ne,...n,apiHost:n.apiHost||a.apiHost},se=n.debug??!1,c("Initializing Loamly Tracker v"+S),p=pe(),c("Visitor ID:",p);let e=ve();v=e.sessionId,c("Session ID:",v,e.isNew?"(new)":"(existing)"),D=new H(b(a.endpoints.behavioral),{batchSize:a.batchSize,batchTimeout:a.batchTimeout}),I=le(),c("Navigation timing:",I),f=ce(document.referrer)||ue(window.location.href),f&&c("AI detected:",f),T=!0,n.disableAutoPageview||oe(),n.disableBehavioral||Me(),l=new B(1e4),l.setOnClassify(_e),Ne(),x=new P,x.initTracking(),setTimeout(()=>{x&&He(x.analyze())},5e3),C=new N,C.init(),p&&v&&(M=new O(v,p,S,{interval:a.pingInterval,endpoint:b(a.endpoints.ping)}),M.start()),W=new z({onNavigate:Ae}),W.start(),Re(),c("Initialization complete")}function Me(){y=new L({chunks:[30,60,90,100],onChunkReached:n=>{c("Scroll chunk:",n.chunk),_("scroll_depth",{depth:n.depth,chunk:n.chunk,time_to_reach_ms:n.time_to_reach_ms})}}),y.start(),A=new q({updateIntervalMs:1e4,onUpdate:n=>{n.active_time_ms>=a.timeSpentThresholdMs&&_("time_spent",{active_time_ms:n.active_time_ms,total_time_ms:n.total_time_ms,idle_time_ms:n.idle_time_ms,is_engaged:n.is_engaged})}}),A.start(),X=new U({onFormEvent:n=>{c("Form event:",n.event_type,n.form_id),_(n.event_type,{form_id:n.form_id,form_type:n.form_type,field_name:n.field_name,field_type:n.field_type,time_to_submit_ms:n.time_to_submit_ms,is_conversion:n.is_conversion})}}),X.start(),document.addEventListener("click",n=>{let t=n.target.closest("a");if(t&&t.href){let i=t.hostname!==window.location.hostname;_("click",{element:"link",href:ie(t.href,200),text:ie(t.textContent||"",100),is_external:i})}})}function _(n,e){D&&D.push(n,{visitor_id:p,session_id:v,event_type:n,...e,url:window.location.href,timestamp:new Date().toISOString(),tracker_version:S})}function Ae(n){c("SPA navigation:",n.navigation_type,n.to_url),D?.flush(),M?.updateScrollDepth(0),y?.stop(),y=new L({chunks:[30,60,90,100],onChunkReached:e=>{_("scroll_depth",{depth:e.depth,chunk:e.chunk,time_to_reach_ms:e.time_to_reach_ms})}}),y.start(),oe(n.to_url),_("spa_navigation",{from_url:n.from_url,to_url:n.to_url,navigation_type:n.navigation_type,time_on_previous_page_ms:n.time_on_previous_page_ms})}function Re(){let n=()=>{let e=y?.getFinalEvent();e&&G(b(a.endpoints.behavioral),{visitor_id:p,session_id:v,event_type:"scroll_depth_final",data:e,url:window.location.href});let t=A?.getFinalMetrics();t&&G(b(a.endpoints.behavioral),{visitor_id:p,session_id:v,event_type:"time_spent_final",data:t,url:window.location.href});let i=C?.getResult();if(i&&i.agenticProbability>0&&G(b(a.endpoints.behavioral),{visitor_id:p,session_id:v,event_type:"agentic_detection",data:i,url:window.location.href}),D?.flushBeacon(),l&&!l.hasClassified()){let s=l.forceClassify();s&&_e(s)}};window.addEventListener("beforeunload",n),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&n()})}function oe(n){if(!T){c("Not initialized, call init() first");return}let e=n||window.location.href,t={visitor_id:p,session_id:v,url:e,referrer:document.referrer||null,title:document.title||null,utm_source:Y(e).utm_source||null,utm_medium:Y(e).utm_medium||null,utm_campaign:Y(e).utm_campaign||null,user_agent:navigator.userAgent,screen_width:window.screen?.width,screen_height:window.screen?.height,language:navigator.language,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,tracker_version:S,navigation_timing:I,ai_platform:f?.platform||null,is_ai_referrer:f?.isAI||!1};c("Pageview:",t),j(b(a.endpoints.visit),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}function ge(n,e={}){if(!T){c("Not initialized, call init() first");return}let t={visitor_id:p,session_id:v,event_name:n,event_type:"custom",properties:e.properties||{},revenue:e.revenue,currency:e.currency||"USD",url:window.location.href,timestamp:new Date().toISOString(),tracker_version:S};c("Event:",n,t),j(b("/api/ingest/event"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}function Be(n,e,t="USD"){ge(n,{revenue:e,currency:t,properties:{type:"conversion"}})}function Pe(n,e={}){if(!T){c("Not initialized, call init() first");return}c("Identify:",n,e);let t={visitor_id:p,session_id:v,user_id:n,traits:e,timestamp:new Date().toISOString()};j(b("/api/ingest/identify"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}function Ne(){if(!l)return;let n=0;document.addEventListener("mousemove",t=>{n++,n%10===0&&l&&l.recordMouse(t.clientX,t.clientY)},{passive:!0}),document.addEventListener("click",()=>{l&&l.recordClick()},{passive:!0});let e=0;document.addEventListener("scroll",()=>{let t=window.scrollY;Math.abs(t-e)>50&&l&&(e=t,l.recordScroll(t))},{passive:!0}),document.addEventListener("focusin",t=>{if(l){l.recordFocusBlur("focus");let i=t.target;(i.tagName==="INPUT"||i.tagName==="TEXTAREA")&&l.recordFormStart(i.id||i.getAttribute("name")||"unknown")}},{passive:!0}),document.addEventListener("focusout",t=>{if(l){l.recordFocusBlur("blur");let i=t.target;(i.tagName==="INPUT"||i.tagName==="TEXTAREA")&&l.recordFormEnd(i.id||i.getAttribute("name")||"unknown")}},{passive:!0}),setTimeout(()=>{l&&!l.hasClassified()&&l.forceClassify()},3e4)}function _e(n){c("Behavioral ML classification:",n),re={classification:n.classification,humanProbability:n.humanProbability,aiProbability:n.aiProbability,confidence:n.confidence,signals:n.signals,sessionDurationMs:n.sessionDurationMs},_("ml_classification",{classification:n.classification,human_probability:n.humanProbability,ai_probability:n.aiProbability,confidence:n.confidence,signals:n.signals,session_duration_ms:n.sessionDurationMs,navigation_timing:I,ai_detection:f,focus_blur:K}),n.classification==="ai_influenced"&&n.confidence>=.7&&(f={isAI:!0,confidence:n.confidence,method:"behavioral"},c("AI detection updated from behavioral ML:",f))}function He(n){c("Focus/blur analysis:",n),K={navType:n.nav_type,confidence:n.confidence,signals:n.signals,timeToFirstInteractionMs:n.time_to_first_interaction_ms},_("focus_blur_analysis",{nav_type:n.nav_type,confidence:n.confidence,signals:n.signals,time_to_first_interaction_ms:n.time_to_first_interaction_ms,sequence_length:n.sequence.length}),n.nav_type==="likely_paste"&&n.confidence>=.4&&(!f||f.confidence<n.confidence)&&(f={isAI:!0,confidence:n.confidence,method:"behavioral"},c("AI detection updated from focus/blur analysis:",f))}function Oe(){return v}function qe(){return p}function Ue(){return f}function ze(){return I}function Ve(){return re}function Ye(){return K}function je(){return C?.getResult()||null}function Ge(){return T}function Xe(){c("Resetting tracker"),M?.stop(),y?.stop(),A?.stop(),X?.stop(),W?.stop(),C?.destroy(),T=!1,p=null,v=null,I=null,f=null,l=null,re=null,x=null,K=null,C=null,D=null,M=null,y=null,A=null,X=null,W=null;try{sessionStorage.removeItem("loamly_session"),sessionStorage.removeItem("loamly_start")}catch{}}function We(n){se=n,c("Debug mode:",n?"enabled":"disabled")}var F={init:xe,pageview:oe,track:ge,conversion:Be,identify:Pe,getSessionId:Oe,getVisitorId:qe,getAIDetection:Ue,getNavigationTiming:ze,getBehavioralML:Ve,getFocusBlur:Ye,getAgentic:je,isInitialized:Ge,reset:Xe,debug:We};function Ke(){let n=document.getElementsByTagName("script");for(let e of n){let t=e.src;if(t.includes("t.js")||t.includes("loamly"))try{let s=new URL(t).searchParams.get("d");if(s)return s}catch{}}return null}async function ye(n){try{let e=await fetch(`${a.apiHost}${a.endpoints.resolve}?domain=${encodeURIComponent(n)}`);if(!e.ok)return console.warn("[Loamly] Failed to resolve workspace for domain:",n),null;let t=await e.json();return t.workspace_id?{apiKey:t.workspace_api_key,apiHost:a.apiHost}:null}catch(e){return console.warn("[Loamly] Error resolving workspace:",e),null}}function Qe(){let n=document.getElementsByTagName("script");for(let e of n)if(e.src.includes("loamly")||e.dataset.loamly!==void 0){let t={};if(e.dataset.apiKey&&(t.apiKey=e.dataset.apiKey),e.dataset.apiHost&&(t.apiHost=e.dataset.apiHost),e.dataset.debug==="true"&&(t.debug=!0),e.dataset.disableAutoPageview==="true"&&(t.disableAutoPageview=!0),e.dataset.disableBehavioral==="true"&&(t.disableBehavioral=!0),t.apiKey)return t}return null}async function Q(){let n=Ke();if(n){let i=await ye(n);if(i){F.init(i);return}}let e=Qe();if(e){F.init(e);return}let t=window.location.hostname;if(t&&t!=="localhost"){let i=await ye(t);if(i){F.init(i);return}}}typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{typeof requestIdleCallback<"u"?requestIdleCallback(()=>Q()):setTimeout(Q,0)}):typeof requestIdleCallback<"u"?requestIdleCallback(()=>Q()):setTimeout(Q,0));var $e=F;return Ie(Je);})();
|
|
1
|
+
"use strict";var Loamly=(()=>{var Z=Object.defineProperty;var Te=Object.getOwnPropertyDescriptor;var Ee=Object.getOwnPropertyNames;var ke=Object.prototype.hasOwnProperty;var Se=(i,e)=>{for(var t in e)Z(i,t,{get:e[t],enumerable:!0})},Ie=(i,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Ee(e))!ke.call(i,s)&&s!==t&&Z(i,s,{get:()=>e[s],enumerable:!(n=Te(e,s))||n.enumerable});return i};var Ce=i=>Ie(Z({},"__esModule",{value:!0}),i);var Ze={};Se(Ze,{default:()=>Je,loamly:()=>M});var T="2.0.2",a={apiHost:"https://app.loamly.ai",endpoints:{visit:"/api/ingest/visit",behavioral:"/api/ingest/behavioral",session:"/api/ingest/session",resolve:"/api/tracker/resolve",health:"/api/tracker/health",ping:"/api/tracker/ping"},pingInterval:3e4,batchSize:10,batchTimeout:5e3,sessionTimeout:18e5,maxTextLength:100,timeSpentThresholdMs:5e3},H={"chatgpt.com":"chatgpt","chat.openai.com":"chatgpt","claude.ai":"claude","perplexity.ai":"perplexity","bard.google.com":"bard","gemini.google.com":"gemini","copilot.microsoft.com":"copilot","github.com/copilot":"github-copilot","you.com":"you","phind.com":"phind","poe.com":"poe"};function le(){try{let i=performance.getEntriesByType("navigation");if(!i||i.length===0)return{nav_type:"unknown",confidence:0,signals:["no_timing_data"]};let e=i[0],t=[],n=0,s=e.fetchStart-e.startTime;s<5?(n+=.25,t.push("instant_fetch_start")):s<20&&(n+=.15,t.push("fast_fetch_start")),e.domainLookupEnd-e.domainLookupStart===0&&(n+=.15,t.push("no_dns_lookup")),e.connectEnd-e.connectStart===0&&(n+=.15,t.push("no_tcp_connect")),e.redirectCount===0&&(n+=.1,t.push("no_redirects")),De(e)<10&&(n+=.15,t.push("uniform_timing")),(!document.referrer||document.referrer==="")&&(n+=.1,t.push("no_referrer"));let m=Math.min(n,1);return{nav_type:n>=.5?"likely_paste":"likely_click",confidence:Math.round(m*1e3)/1e3,signals:t}}catch{return{nav_type:"unknown",confidence:0,signals:["detection_error"]}}}function De(i){let e=[i.fetchStart-i.startTime,i.domainLookupEnd-i.domainLookupStart,i.connectEnd-i.connectStart,i.responseStart-i.requestStart].filter(s=>s>=0);if(e.length===0)return 100;let t=e.reduce((s,r)=>s+r,0)/e.length,n=e.reduce((s,r)=>s+Math.pow(r-t,2),0)/e.length;return Math.sqrt(n)}function ce(i){if(!i)return null;try{let t=new URL(i).hostname.toLowerCase();for(let[n,s]of Object.entries(H))if(t.includes(n)||i.includes(n))return{isAI:!0,platform:s,confidence:.95,method:"referrer"};return null}catch{for(let[e,t]of Object.entries(H))if(i.toLowerCase().includes(e.toLowerCase()))return{isAI:!0,platform:t,confidence:.85,method:"referrer"};return null}}function ue(i){try{let t=new URL(i).searchParams.get("utm_source")?.toLowerCase();if(t){for(let[n,s]of Object.entries(H))if(t.includes(n.split(".")[0]))return{isAI:!0,platform:s,confidence:.99,method:"referrer"};if(t.includes("ai")||t.includes("llm")||t.includes("chatbot"))return{isAI:!0,platform:t,confidence:.9,method:"referrer"}}return null}catch{return null}}var de={human:{time_to_first_click_delayed:.85,time_to_first_click_normal:.75,time_to_first_click_fast:.5,time_to_first_click_immediate:.25,scroll_speed_variable:.8,scroll_speed_erratic:.7,scroll_speed_uniform:.35,scroll_speed_none:.45,nav_timing_click:.75,nav_timing_unknown:.55,nav_timing_paste:.35,has_referrer:.7,no_referrer:.45,homepage_landing:.65,deep_landing:.5,mouse_movement_curved:.9,mouse_movement_linear:.3,mouse_movement_none:.4,form_fill_normal:.85,form_fill_fast:.6,form_fill_instant:.2,focus_blur_normal:.75,focus_blur_rapid:.45},ai_influenced:{time_to_first_click_immediate:.75,time_to_first_click_fast:.55,time_to_first_click_normal:.4,time_to_first_click_delayed:.35,scroll_speed_none:.55,scroll_speed_uniform:.7,scroll_speed_variable:.35,scroll_speed_erratic:.4,nav_timing_paste:.75,nav_timing_unknown:.5,nav_timing_click:.35,no_referrer:.65,has_referrer:.4,deep_landing:.6,homepage_landing:.45,mouse_movement_none:.6,mouse_movement_linear:.75,mouse_movement_curved:.25,form_fill_instant:.8,form_fill_fast:.55,form_fill_normal:.3,focus_blur_rapid:.6,focus_blur_normal:.4}},me={human:.85,ai_influenced:.15},he=.5,O=class{constructor(e=1e4){this.classified=!1;this.result=null;this.onClassify=null;this.minSessionTime=e,this.data={firstClickTime:null,scrollEvents:[],mouseEvents:[],formEvents:[],focusBlurEvents:[],startTime:Date.now()}}setOnClassify(e){this.onClassify=e}recordClick(){this.data.firstClickTime===null&&(this.data.firstClickTime=Date.now()),this.checkAndClassify()}recordScroll(e){this.data.scrollEvents.push({time:Date.now(),position:e}),this.data.scrollEvents.length>50&&(this.data.scrollEvents=this.data.scrollEvents.slice(-50)),this.checkAndClassify()}recordMouse(e,t){this.data.mouseEvents.push({time:Date.now(),x:e,y:t}),this.data.mouseEvents.length>100&&(this.data.mouseEvents=this.data.mouseEvents.slice(-100)),this.checkAndClassify()}recordFormStart(e){this.data.formEvents.find(n=>n.fieldId===e&&n.endTime===0)||this.data.formEvents.push({fieldId:e,startTime:Date.now(),endTime:0})}recordFormEnd(e){let t=this.data.formEvents.find(n=>n.fieldId===e&&n.endTime===0);t&&(t.endTime=Date.now()),this.checkAndClassify()}recordFocusBlur(e){this.data.focusBlurEvents.push({type:e,time:Date.now()}),this.data.focusBlurEvents.length>20&&(this.data.focusBlurEvents=this.data.focusBlurEvents.slice(-20))}checkAndClassify(){this.classified||Date.now()-this.data.startTime<this.minSessionTime||!(this.data.scrollEvents.length>=2||this.data.mouseEvents.length>=5||this.data.firstClickTime!==null)||this.classify()}forceClassify(){return this.classified?this.result:this.classify()}classify(){let e=Date.now()-this.data.startTime,t=this.extractSignals(),n=Math.log(me.human),s=Math.log(me.ai_influenced);for(let C of t){let J=de.human[C]??he,ae=de.ai_influenced[C]??he;n+=Math.log(J),s+=Math.log(ae)}let r=Math.max(n,s),d=Math.exp(n-r),h=Math.exp(s-r),m=d+h,u=d/m,o=h/m,I,w;return u>.6?(I="human",w=u):o>.6?(I="ai_influenced",w=o):(I="uncertain",w=Math.max(u,o)),this.result={classification:I,humanProbability:u,aiProbability:o,confidence:w,signals:t,timestamp:Date.now(),sessionDurationMs:e},this.classified=!0,this.onClassify&&this.onClassify(this.result),this.result}extractSignals(){let e=[];if(this.data.firstClickTime!==null){let n=this.data.firstClickTime-this.data.startTime;n<500?e.push("time_to_first_click_immediate"):n<2e3?e.push("time_to_first_click_fast"):n<1e4?e.push("time_to_first_click_normal"):e.push("time_to_first_click_delayed")}if(this.data.scrollEvents.length===0)e.push("scroll_speed_none");else if(this.data.scrollEvents.length>=3){let n=[];for(let m=1;m<this.data.scrollEvents.length;m++){let u=this.data.scrollEvents[m].time-this.data.scrollEvents[m-1].time;n.push(u)}let s=n.reduce((m,u)=>m+u,0)/n.length,r=n.reduce((m,u)=>m+Math.pow(u-s,2),0)/n.length,d=Math.sqrt(r),h=s>0?d/s:0;h<.2?e.push("scroll_speed_uniform"):h<.6?e.push("scroll_speed_variable"):e.push("scroll_speed_erratic")}if(this.data.mouseEvents.length===0)e.push("mouse_movement_none");else if(this.data.mouseEvents.length>=10){let n=Math.min(this.data.mouseEvents.length,20),s=this.data.mouseEvents.slice(-n),r=0,d=0,h=0,m=0;for(let g of s)r+=g.x,d+=g.y,h+=g.x*g.y,m+=g.x*g.x;let u=n*m-r*r,o=u!==0?(n*h-r*d)/u:0,I=(d-o*r)/n,w=0,C=0,J=d/n;for(let g of s){let we=o*g.x+I;w+=Math.pow(g.y-we,2),C+=Math.pow(g.y-J,2)}(C!==0?1-w/C:0)>.95?e.push("mouse_movement_linear"):e.push("mouse_movement_curved")}let t=this.data.formEvents.filter(n=>n.endTime>0);if(t.length>0){let n=t.reduce((s,r)=>s+(r.endTime-r.startTime),0)/t.length;n<100?e.push("form_fill_instant"):n<500?e.push("form_fill_fast"):e.push("form_fill_normal")}if(this.data.focusBlurEvents.length>=4){let n=this.data.focusBlurEvents.slice(-10),s=[];for(let d=1;d<n.length;d++)s.push(n[d].time-n[d-1].time);s.reduce((d,h)=>d+h,0)/s.length<1e3?e.push("focus_blur_rapid"):e.push("focus_blur_normal")}return e}addContextSignal(e){}getResult(){return this.result}hasClassified(){return this.classified}};var q=class{constructor(){this.sequence=[];this.firstInteractionTime=null;this.analyzed=!1;this.result=null;this.pageLoadTime=performance.now()}initTracking(){document.addEventListener("focus",t=>{this.recordEvent("focus",t.target)},!0),document.addEventListener("blur",t=>{this.recordEvent("blur",t.target)},!0),window.addEventListener("focus",()=>{this.recordEvent("window_focus",null)}),window.addEventListener("blur",()=>{this.recordEvent("window_blur",null)});let e=()=>{this.firstInteractionTime===null&&(this.firstInteractionTime=performance.now())};document.addEventListener("click",e,{once:!0,passive:!0}),document.addEventListener("keydown",e,{once:!0,passive:!0})}recordEvent(e,t){let n={type:e,target:t?.tagName||"WINDOW",timestamp:performance.now()};this.sequence.push(n),this.sequence.length>20&&(this.sequence=this.sequence.slice(-20))}analyze(){if(this.analyzed&&this.result)return this.result;let e=[],t=0,n=this.sequence.filter(o=>o.timestamp<this.pageLoadTime+500);n.some(o=>o.type==="window_focus")&&(e.push("early_window_focus"),t+=.15),n.some(o=>o.type==="focus"&&o.target==="BODY")&&(e.push("early_body_focus"),t+=.15),this.sequence.some(o=>o.type==="focus"&&o.target==="A")||(e.push("no_link_focus"),t+=.1);let h=this.sequence.find(o=>o.type==="focus");h&&(h.target==="BODY"||h.target==="HTML")&&(e.push("first_focus_body"),t+=.1),this.sequence.filter(o=>o.type==="window_focus"||o.type==="window_blur").length<=2&&(e.push("minimal_window_switches"),t+=.05),this.firstInteractionTime!==null&&this.firstInteractionTime-this.pageLoadTime>3e3&&(e.push("delayed_first_interaction"),t+=.1),t=Math.min(t,.65);let u;return t>=.35?u="likely_paste":e.length===0?u="unknown":u="likely_click",this.result={nav_type:u,confidence:t,signals:e,sequence:this.sequence.slice(-10),time_to_first_interaction_ms:this.firstInteractionTime?Math.round(this.firstInteractionTime-this.pageLoadTime):null},this.analyzed=!0,this.result}getResult(){return this.analyze()}hasAnalyzed(){return this.analyzed}getSequence(){return[...this.sequence]}reset(){this.sequence=[],this.pageLoadTime=performance.now(),this.firstInteractionTime=null,this.analyzed=!1,this.result=null}};var ee=class{constructor(){this.detected=!1;this.checkComplete=!1;this.observer=null}init(e=5e3){typeof document>"u"||(this.check(),!this.detected&&document.body&&(this.observer=new MutationObserver(()=>this.check()),this.observer.observe(document.body,{childList:!0,subtree:!0}),setTimeout(()=>{this.observer&&!this.detected&&(this.observer.disconnect(),this.observer=null,this.checkComplete=!0)},e)))}check(){document.querySelector(".pplx-agent-overlay-stop-button")&&(this.detected=!0,this.checkComplete=!0,this.observer&&(this.observer.disconnect(),this.observer=null))}isDetected(){return this.detected}isCheckComplete(){return this.checkComplete}destroy(){this.observer&&(this.observer.disconnect(),this.observer=null)}},te=class{constructor(e=500){this.lastX=-1;this.lastY=-1;this.teleportingClicks=0;this.totalMovements=0;this.handleMove=e=>{this.totalMovements++,this.lastX=e.clientX,this.lastY=e.clientY};this.handleClick=e=>{if(this.lastX!==-1&&this.lastY!==-1){let t=Math.abs(e.clientX-this.lastX),n=Math.abs(e.clientY-this.lastY);(t>this.teleportThreshold||n>this.teleportThreshold)&&this.teleportingClicks++}this.lastX=e.clientX,this.lastY=e.clientY};this.teleportThreshold=e}init(){typeof document>"u"||(document.addEventListener("mousemove",this.handleMove,{passive:!0}),document.addEventListener("mousedown",this.handleClick,{passive:!0}))}getPatterns(){return{teleportingClicks:this.teleportingClicks,totalMovements:this.totalMovements}}destroy(){typeof document>"u"||(document.removeEventListener("mousemove",this.handleMove),document.removeEventListener("mousedown",this.handleClick))}},ie=class{constructor(){this.detected=!1}detect(){if(typeof navigator>"u")return!1;if(navigator.webdriver)return this.detected=!0,!0;if(typeof window<"u"){let e=window,t=["__webdriver_evaluate","__selenium_evaluate","__webdriver_script_function","__webdriver_script_func","__webdriver_script_fn","__fxdriver_evaluate","__driver_unwrapped","__webdriver_unwrapped","__driver_evaluate","__selenium_unwrapped","__fxdriver_unwrapped"];for(let n of t)if(n in e)return this.detected=!0,!0}return!1}isDetected(){return this.detected}},U=class{constructor(){this.initialized=!1;this.cometDetector=new ee,this.mouseAnalyzer=new te,this.cdpDetector=new ie}init(){this.initialized||(this.initialized=!0,this.cometDetector.init(),this.mouseAnalyzer.init(),this.cdpDetector.detect())}getResult(){let e=[],t=0;this.cometDetector.isDetected()&&(e.push("comet_dom_detected"),t=Math.max(t,.85)),this.cdpDetector.isDetected()&&(e.push("cdp_detected"),t=Math.max(t,.92));let n=this.mouseAnalyzer.getPatterns();return n.teleportingClicks>0&&(e.push(`teleporting_clicks:${n.teleportingClicks}`),t=Math.max(t,.78)),{cometDOMDetected:this.cometDetector.isDetected(),cdpDetected:this.cdpDetector.isDetected(),mousePatterns:n,agenticProbability:t,signals:e}}destroy(){this.cometDetector.destroy(),this.mouseAnalyzer.destroy()}};var Fe={batchSize:a.batchSize,batchTimeout:a.batchTimeout,maxRetries:3,retryDelayMs:1e3,storageKey:"_loamly_queue"},z=class{constructor(e,t={}){this.queue=[];this.batchTimer=null;this.isFlushing=!1;this.endpoint=e,this.config={...Fe,...t},this.loadFromStorage()}push(e,t){let n={id:this.generateId(),type:e,payload:t,timestamp:Date.now(),retries:0};this.queue.push(n),this.saveToStorage(),this.scheduleBatch()}async flush(){if(!(this.isFlushing||this.queue.length===0)){this.isFlushing=!0,this.clearBatchTimer();try{let e=[...this.queue];this.queue=[],await this.sendBatch(e)}finally{this.isFlushing=!1,this.saveToStorage()}}}flushBeacon(){if(this.queue.length===0)return!0;let e=this.queue.map(n=>({type:n.type,...n.payload,_queue_id:n.id,_queue_timestamp:n.timestamp})),t=navigator.sendBeacon?.(this.endpoint,JSON.stringify({events:e,beacon:!0}))??!1;return t&&(this.queue=[],this.clearStorage()),t}get length(){return this.queue.length}scheduleBatch(){if(!this.batchTimer){if(this.queue.length>=this.config.batchSize){this.flush();return}this.batchTimer=setTimeout(()=>{this.batchTimer=null,this.flush()},this.config.batchTimeout)}}clearBatchTimer(){this.batchTimer&&(clearTimeout(this.batchTimer),this.batchTimer=null)}async sendBatch(e){if(e.length===0)return;let t={events:e.map(n=>({type:n.type,...n.payload,_queue_id:n.id,_queue_timestamp:n.timestamp})),batch:!0};try{let n=await fetch(this.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!n.ok)throw new Error(`HTTP ${n.status}`)}catch{for(let s of e)s.retries<this.config.maxRetries&&(s.retries++,this.queue.push(s));if(this.queue.length>0){let s=this.config.retryDelayMs*Math.pow(2,e[0].retries-1);setTimeout(()=>this.flush(),s)}}}loadFromStorage(){try{let e=localStorage.getItem(this.config.storageKey);if(e){let t=JSON.parse(e);if(Array.isArray(t)){let n=Date.now()-864e5;this.queue=t.filter(s=>s.timestamp>n)}}}catch{}}saveToStorage(){try{this.queue.length>0?localStorage.setItem(this.config.storageKey,JSON.stringify(this.queue)):this.clearStorage()}catch{}}clearStorage(){try{localStorage.removeItem(this.config.storageKey)}catch{}}generateId(){return`${Date.now()}-${Math.random().toString(36).substring(2,9)}`}};var V=class{constructor(e,t,n,s={}){this.intervalId=null;this.isVisible=!0;this.currentScrollDepth=0;this.ping=async()=>{let e=this.getData();if(this.config.onPing?.(e),this.config.endpoint)try{await fetch(this.config.endpoint,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)})}catch{}};this.handleVisibilityChange=()=>{this.isVisible=document.visibilityState==="visible"};this.handleScroll=()=>{let e=Math.round((window.scrollY+window.innerHeight)/document.documentElement.scrollHeight*100);e>this.currentScrollDepth&&(this.currentScrollDepth=Math.min(e,100))};this.sessionId=e,this.visitorId=t,this.version=n,this.pageLoadTime=Date.now(),this.config={interval:a.pingInterval,endpoint:"",...s},document.addEventListener("visibilitychange",this.handleVisibilityChange),window.addEventListener("scroll",this.handleScroll,{passive:!0})}start(){this.intervalId||(this.intervalId=setInterval(()=>{this.isVisible&&this.ping()},this.config.interval),this.ping())}stop(){this.intervalId&&(clearInterval(this.intervalId),this.intervalId=null),document.removeEventListener("visibilitychange",this.handleVisibilityChange),window.removeEventListener("scroll",this.handleScroll)}updateScrollDepth(e){e>this.currentScrollDepth&&(this.currentScrollDepth=e)}getData(){return{session_id:this.sessionId,visitor_id:this.visitorId,url:window.location.href,time_on_page_ms:Date.now()-this.pageLoadTime,scroll_depth:this.currentScrollDepth,is_active:this.isVisible,tracker_version:this.version}}};var Le=[30,60,90,100],A=class{constructor(e={}){this.maxDepth=0;this.reportedChunks=new Set;this.ticking=!1;this.isVisible=!0;this.handleScroll=()=>{!this.ticking&&this.isVisible&&(requestAnimationFrame(()=>{this.checkScrollDepth(),this.ticking=!1}),this.ticking=!0)};this.handleVisibility=()=>{this.isVisible=document.visibilityState==="visible"};this.config={chunks:Le,...e},this.startTime=Date.now()}start(){window.addEventListener("scroll",this.handleScroll,{passive:!0}),document.addEventListener("visibilitychange",this.handleVisibility),this.checkScrollDepth()}stop(){window.removeEventListener("scroll",this.handleScroll),document.removeEventListener("visibilitychange",this.handleVisibility)}getMaxDepth(){return this.maxDepth}getReportedChunks(){return Array.from(this.reportedChunks).sort((e,t)=>e-t)}getFinalEvent(){let e=document.documentElement.scrollHeight,t=window.innerHeight;return{depth:this.maxDepth,chunk:this.getChunkForDepth(this.maxDepth),time_to_reach_ms:Date.now()-this.startTime,total_height:e,viewport_height:t}}checkScrollDepth(){let e=window.scrollY,t=window.innerHeight,n=document.documentElement.scrollHeight;if(n<=t){this.updateDepth(100);return}let s=n-t,r=Math.min(100,Math.round(e/s*100));this.updateDepth(r)}updateDepth(e){if(!(e<=this.maxDepth)){this.maxDepth=e,this.config.onDepthChange?.(e);for(let t of this.config.chunks)e>=t&&!this.reportedChunks.has(t)&&(this.reportedChunks.add(t),this.reportChunk(t))}}reportChunk(e){let t=document.documentElement.scrollHeight,n=window.innerHeight,s={depth:this.maxDepth,chunk:e,time_to_reach_ms:Date.now()-this.startTime,total_height:t,viewport_height:n};this.config.onChunkReached?.(s)}getChunkForDepth(e){let t=this.config.chunks.sort((n,s)=>s-n);for(let n of t)if(e>=n)return n;return 0}};var xe={idleThresholdMs:3e4,updateIntervalMs:5e3},Y=class{constructor(e={}){this.activeTime=0;this.idleTime=0;this.isVisible=!0;this.isIdle=!1;this.updateInterval=null;this.idleCheckInterval=null;this.handleVisibility=()=>{let e=this.isVisible;this.isVisible=document.visibilityState==="visible",e&&!this.isVisible?this.updateTimes():!e&&this.isVisible&&(this.lastUpdateTime=Date.now(),this.lastActivityTime=Date.now())};this.handleActivity=()=>{let e=Date.now();this.isIdle&&(this.isIdle=!1),this.lastActivityTime=e};this.config={...xe,...e},this.startTime=Date.now(),this.lastActivityTime=this.startTime,this.lastUpdateTime=this.startTime}start(){document.addEventListener("visibilitychange",this.handleVisibility),["mousemove","keydown","scroll","click","touchstart"].forEach(t=>{document.addEventListener(t,this.handleActivity,{passive:!0})}),this.updateInterval=setInterval(()=>{this.update()},this.config.updateIntervalMs),this.idleCheckInterval=setInterval(()=>{this.checkIdle()},1e3)}stop(){document.removeEventListener("visibilitychange",this.handleVisibility),["mousemove","keydown","scroll","click","touchstart"].forEach(t=>{document.removeEventListener(t,this.handleActivity)}),this.updateInterval&&(clearInterval(this.updateInterval),this.updateInterval=null),this.idleCheckInterval&&(clearInterval(this.idleCheckInterval),this.idleCheckInterval=null)}getMetrics(){return this.updateTimes(),{active_time_ms:this.activeTime,total_time_ms:Date.now()-this.startTime,idle_time_ms:this.idleTime,is_engaged:!this.isIdle&&this.isVisible}}getFinalMetrics(){return this.updateTimes(),this.getMetrics()}checkIdle(){let t=Date.now()-this.lastActivityTime;!this.isIdle&&t>=this.config.idleThresholdMs&&(this.isIdle=!0)}updateTimes(){let e=Date.now(),t=e-this.lastUpdateTime;this.isVisible&&(this.isIdle?this.idleTime+=t:this.activeTime+=t),this.lastUpdateTime=e}update(){this.isVisible&&(this.updateTimes(),this.config.onUpdate?.(this.getMetrics()))}};var fe={sensitiveFields:["password","pwd","pass","credit","card","cvv","cvc","ssn","social","secret","token","key"],trackableFields:["email","name","phone","company","first","last","city","country"],thankYouPatterns:[/thank[-_]?you/i,/success/i,/confirmation/i,/submitted/i,/complete/i]},j=class{constructor(e={}){this.formStartTimes=new Map;this.interactedForms=new Set;this.mutationObserver=null;this.handleFocusIn=e=>{let t=e.target;if(!this.isFormField(t))return;let n=t.closest("form"),s=this.getFormId(n||t);this.formStartTimes.has(s)||(this.formStartTimes.set(s,Date.now()),this.interactedForms.add(s),this.emitEvent({event_type:"form_start",form_id:s,form_type:this.detectFormType(n||t)}));let r=this.getFieldName(t);r&&!this.isSensitiveField(r)&&this.emitEvent({event_type:"form_field",form_id:s,form_type:this.detectFormType(n||t),field_name:this.sanitizeFieldName(r),field_type:t.type||t.tagName.toLowerCase()})};this.handleSubmit=e=>{let t=e.target;if(!t||t.tagName!=="FORM")return;let n=this.getFormId(t),s=this.formStartTimes.get(n);this.emitEvent({event_type:"form_submit",form_id:n,form_type:this.detectFormType(t),time_to_submit_ms:s?Date.now()-s:void 0,is_conversion:!0})};this.handleClick=e=>{let t=e.target;if(t.closest(".hs-button")||t.closest('[type="submit"]')){let n=t.closest("form");if(n&&n.classList.contains("hs-form")){let s=this.getFormId(n),r=this.formStartTimes.get(s);this.emitEvent({event_type:"form_submit",form_id:s,form_type:"hubspot",time_to_submit_ms:r?Date.now()-r:void 0,is_conversion:!0})}}t.closest('[data-qa="submit-button"]')&&this.emitEvent({event_type:"form_submit",form_id:"typeform_embed",form_type:"typeform",is_conversion:!0})};this.config={...fe,...e,sensitiveFields:[...fe.sensitiveFields,...e.sensitiveFields||[]]}}start(){document.addEventListener("focusin",this.handleFocusIn,{passive:!0}),document.addEventListener("submit",this.handleSubmit),document.addEventListener("click",this.handleClick,{passive:!0}),this.startMutationObserver(),this.checkThankYouPage(),this.scanForEmbeddedForms()}stop(){document.removeEventListener("focusin",this.handleFocusIn),document.removeEventListener("submit",this.handleSubmit),document.removeEventListener("click",this.handleClick),this.mutationObserver?.disconnect()}getInteractedForms(){return Array.from(this.interactedForms)}startMutationObserver(){this.mutationObserver=new MutationObserver(e=>{for(let t of e)for(let n of t.addedNodes)n instanceof HTMLElement&&((n.classList?.contains("hs-form")||n.querySelector?.(".hs-form"))&&this.trackEmbeddedForm(n,"hubspot"),(n.classList?.contains("typeform-widget")||n.querySelector?.("[data-tf-widget]"))&&this.trackEmbeddedForm(n,"typeform"),(n.classList?.contains("jotform-form")||n.querySelector?.(".jotform-form"))&&this.trackEmbeddedForm(n,"jotform"),(n.classList?.contains("gform_wrapper")||n.querySelector?.(".gform_wrapper"))&&this.trackEmbeddedForm(n,"gravity"))}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0})}scanForEmbeddedForms(){document.querySelectorAll(".hs-form").forEach(e=>{this.trackEmbeddedForm(e,"hubspot")}),document.querySelectorAll("[data-tf-widget], .typeform-widget").forEach(e=>{this.trackEmbeddedForm(e,"typeform")}),document.querySelectorAll(".jotform-form").forEach(e=>{this.trackEmbeddedForm(e,"jotform")}),document.querySelectorAll(".gform_wrapper").forEach(e=>{this.trackEmbeddedForm(e,"gravity")})}trackEmbeddedForm(e,t){let n=`${t}_${this.getFormId(e)}`;e.addEventListener("focusin",()=>{this.formStartTimes.has(n)||(this.formStartTimes.set(n,Date.now()),this.interactedForms.add(n),this.emitEvent({event_type:"form_start",form_id:n,form_type:t}))},{passive:!0})}checkThankYouPage(){let e=window.location.href.toLowerCase(),t=document.title.toLowerCase();for(let n of this.config.thankYouPatterns)if(n.test(e)||n.test(t)){this.emitEvent({event_type:"form_success",form_id:"page_conversion",form_type:"unknown",is_conversion:!0});break}}isFormField(e){let t=e.tagName;return t==="INPUT"||t==="TEXTAREA"||t==="SELECT"}getFormId(e){return e?e.id||e.getAttribute("name")||e.getAttribute("data-form-id")||"form_"+Math.random().toString(36).substring(2,8):"unknown"}getFieldName(e){return e.name||e.id||e.getAttribute("data-name")||""}isSensitiveField(e){let t=e.toLowerCase();return this.config.sensitiveFields.some(n=>t.includes(n))}sanitizeFieldName(e){return e.replace(/[0-9]+/g,"*").substring(0,50)}detectFormType(e){return e.classList.contains("hs-form")||e.closest(".hs-form")?"hubspot":e.classList.contains("typeform-widget")||e.closest("[data-tf-widget]")?"typeform":e.classList.contains("jotform-form")||e.closest(".jotform-form")?"jotform":e.classList.contains("gform_wrapper")||e.closest(".gform_wrapper")?"gravity":e.tagName==="FORM"?"native":"unknown"}emitEvent(e){this.config.onFormEvent?.(e)}};var G=class{constructor(e={}){this.originalPushState=null;this.originalReplaceState=null;this.handleStateChange=e=>{let t=window.location.href;t!==this.currentUrl&&this.emitNavigation(t,e)};this.handlePopState=()=>{let e=window.location.href;e!==this.currentUrl&&this.emitNavigation(e,"pop")};this.handleHashChange=()=>{let e=window.location.href;e!==this.currentUrl&&this.emitNavigation(e,"hash")};this.config=e,this.currentUrl=window.location.href,this.pageEnterTime=Date.now()}start(){this.patchHistoryAPI(),window.addEventListener("popstate",this.handlePopState),this.config.ignoreHashChange||window.addEventListener("hashchange",this.handleHashChange)}stop(){this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState),window.removeEventListener("popstate",this.handlePopState),window.removeEventListener("hashchange",this.handleHashChange)}navigate(e,t="push"){this.emitNavigation(e,t)}getCurrentUrl(){return this.currentUrl}getTimeOnPage(){return Date.now()-this.pageEnterTime}patchHistoryAPI(){this.originalPushState=history.pushState.bind(history),this.originalReplaceState=history.replaceState.bind(history),history.pushState=(...e)=>{let t=this.originalPushState(...e);return this.handleStateChange("push"),t},history.replaceState=(...e)=>{let t=this.originalReplaceState(...e);return this.handleStateChange("replace"),t}}emitNavigation(e,t){let n={from_url:this.currentUrl,to_url:e,navigation_type:t,time_on_previous_page_ms:Date.now()-this.pageEnterTime};this.currentUrl=e,this.pageEnterTime=Date.now(),this.config.onNavigate?.(n)}};function X(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,i=>{let e=Math.random()*16|0;return(i==="x"?e:e&3|8).toString(16)})}function pe(){try{let i=localStorage.getItem("_loamly_vid");if(i)return i;let e=X();return localStorage.setItem("_loamly_vid",e),e}catch{return X()}}function ve(){try{let i=sessionStorage.getItem("loamly_session"),e=sessionStorage.getItem("loamly_start");if(i&&e)return{sessionId:i,isNew:!1};let t=X(),n=Date.now().toString();return sessionStorage.setItem("loamly_session",t),sessionStorage.setItem("loamly_start",n),{sessionId:t,isNew:!0}}catch{return{sessionId:X(),isNew:!0}}}function K(i){let e={};try{let t=new URL(i).searchParams,n=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"];for(let s of n){let r=t.get(s);r&&(e[s]=r)}}catch{}return e}function ne(i,e){return i.length<=e?i:i.substring(0,e-3)+"..."}async function R(i,e,t=1e4){try{let n=new AbortController,s=setTimeout(()=>n.abort(),t),r=await fetch(i,{...e,signal:n.signal});return clearTimeout(s),r}catch{return null}}function W(i,e){return typeof navigator<"u"&&navigator.sendBeacon?navigator.sendBeacon(i,JSON.stringify(e)):!1}var B={apiHost:a.apiHost},E=!1,se=!1,p=null,v=null,F=null,f=null,l=null,re=null,D=null,Q=null,k=null,S=null,L=null,_=null,x=null,P=null,N=null;function c(...i){se&&console.log("[Loamly]",...i)}function y(i){return`${B.apiHost}${i}`}function Me(i={}){if(E){c("Already initialized");return}B={...B,...i,apiHost:i.apiHost||a.apiHost},se=i.debug??!1,c("Initializing Loamly Tracker v"+T),p=pe(),c("Visitor ID:",p);let e=ve();v=e.sessionId,c("Session ID:",v,e.isNew?"(new)":"(existing)"),S=new z(y(a.endpoints.behavioral),{batchSize:a.batchSize,batchTimeout:a.batchTimeout}),F=le(),c("Navigation timing:",F),f=ce(document.referrer)||ue(window.location.href),f&&c("AI detected:",f),E=!0,i.disableAutoPageview||oe(),i.disableBehavioral||Ae(),l=new O(1e4),l.setOnClassify(_e),He(),D=new q,D.initTracking(),setTimeout(()=>{D&&Oe(D.analyze())},5e3),k=new U,k.init(),p&&v&&(L=new V(v,p,T,{interval:a.pingInterval,endpoint:y(a.endpoints.ping)}),L.start()),N=new G({onNavigate:Re}),N.start(),Be(),ye("initialized"),c("Initialization complete")}function Ae(){_=new A({chunks:[30,60,90,100],onChunkReached:i=>{c("Scroll chunk:",i.chunk),b("scroll_depth",{depth:i.depth,chunk:i.chunk,time_to_reach_ms:i.time_to_reach_ms})}}),_.start(),x=new Y({updateIntervalMs:1e4,onUpdate:i=>{i.active_time_ms>=a.timeSpentThresholdMs&&b("time_spent",{active_time_ms:i.active_time_ms,total_time_ms:i.total_time_ms,idle_time_ms:i.idle_time_ms,is_engaged:i.is_engaged})}}),x.start(),P=new j({onFormEvent:i=>{c("Form event:",i.event_type,i.form_id),b(i.event_type,{form_id:i.form_id,form_type:i.form_type,field_name:i.field_name,field_type:i.field_type,time_to_submit_ms:i.time_to_submit_ms,is_conversion:i.is_conversion})}}),P.start(),document.addEventListener("click",i=>{let t=i.target.closest("a");if(t&&t.href){let n=t.hostname!==window.location.hostname;b("click",{element:"link",href:ne(t.href,200),text:ne(t.textContent||"",100),is_external:n})}})}function b(i,e){S&&S.push(i,{visitor_id:p,session_id:v,event_type:i,...e,url:window.location.href,timestamp:new Date().toISOString(),tracker_version:T})}function Re(i){c("SPA navigation:",i.navigation_type,i.to_url),S?.flush(),L?.updateScrollDepth(0),_?.stop(),_=new A({chunks:[30,60,90,100],onChunkReached:e=>{b("scroll_depth",{depth:e.depth,chunk:e.chunk,time_to_reach_ms:e.time_to_reach_ms})}}),_.start(),oe(i.to_url),b("spa_navigation",{from_url:i.from_url,to_url:i.to_url,navigation_type:i.navigation_type,time_on_previous_page_ms:i.time_on_previous_page_ms})}function Be(){let i=()=>{let e=_?.getFinalEvent();e&&W(y(a.endpoints.behavioral),{visitor_id:p,session_id:v,event_type:"scroll_depth_final",data:e,url:window.location.href});let t=x?.getFinalMetrics();t&&W(y(a.endpoints.behavioral),{visitor_id:p,session_id:v,event_type:"time_spent_final",data:t,url:window.location.href});let n=k?.getResult();if(n&&n.agenticProbability>0&&W(y(a.endpoints.behavioral),{visitor_id:p,session_id:v,event_type:"agentic_detection",data:n,url:window.location.href}),S?.flushBeacon(),l&&!l.hasClassified()){let s=l.forceClassify();s&&_e(s)}};window.addEventListener("beforeunload",i),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&i()})}function oe(i){if(!E){c("Not initialized, call init() first");return}let e=i||window.location.href,t={visitor_id:p,session_id:v,url:e,referrer:document.referrer||null,title:document.title||null,utm_source:K(e).utm_source||null,utm_medium:K(e).utm_medium||null,utm_campaign:K(e).utm_campaign||null,user_agent:navigator.userAgent,screen_width:window.screen?.width,screen_height:window.screen?.height,language:navigator.language,timezone:Intl.DateTimeFormat().resolvedOptions().timeZone,tracker_version:T,navigation_timing:F,ai_platform:f?.platform||null,is_ai_referrer:f?.isAI||!1};c("Pageview:",t),R(y(a.endpoints.visit),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}function ge(i,e={}){if(!E){c("Not initialized, call init() first");return}let t={visitor_id:p,session_id:v,event_name:i,event_type:"custom",properties:e.properties||{},revenue:e.revenue,currency:e.currency||"USD",url:window.location.href,timestamp:new Date().toISOString(),tracker_version:T};c("Event:",i,t),R(y("/api/ingest/event"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}function Pe(i,e,t="USD"){ge(i,{revenue:e,currency:t,properties:{type:"conversion"}})}function Ne(i,e={}){if(!E){c("Not initialized, call init() first");return}c("Identify:",i,e);let t={visitor_id:p,session_id:v,user_id:i,traits:e,timestamp:new Date().toISOString()};R(y("/api/ingest/identify"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}function He(){if(!l)return;let i=0;document.addEventListener("mousemove",t=>{i++,i%10===0&&l&&l.recordMouse(t.clientX,t.clientY)},{passive:!0}),document.addEventListener("click",()=>{l&&l.recordClick()},{passive:!0});let e=0;document.addEventListener("scroll",()=>{let t=window.scrollY;Math.abs(t-e)>50&&l&&(e=t,l.recordScroll(t))},{passive:!0}),document.addEventListener("focusin",t=>{if(l){l.recordFocusBlur("focus");let n=t.target;(n.tagName==="INPUT"||n.tagName==="TEXTAREA")&&l.recordFormStart(n.id||n.getAttribute("name")||"unknown")}},{passive:!0}),document.addEventListener("focusout",t=>{if(l){l.recordFocusBlur("blur");let n=t.target;(n.tagName==="INPUT"||n.tagName==="TEXTAREA")&&l.recordFormEnd(n.id||n.getAttribute("name")||"unknown")}},{passive:!0}),setTimeout(()=>{l&&!l.hasClassified()&&l.forceClassify()},3e4)}function _e(i){c("Behavioral ML classification:",i),re={classification:i.classification,humanProbability:i.humanProbability,aiProbability:i.aiProbability,confidence:i.confidence,signals:i.signals,sessionDurationMs:i.sessionDurationMs},b("ml_classification",{classification:i.classification,human_probability:i.humanProbability,ai_probability:i.aiProbability,confidence:i.confidence,signals:i.signals,session_duration_ms:i.sessionDurationMs,navigation_timing:F,ai_detection:f,focus_blur:Q}),i.classification==="ai_influenced"&&i.confidence>=.7&&(f={isAI:!0,confidence:i.confidence,method:"behavioral"},c("AI detection updated from behavioral ML:",f))}function Oe(i){c("Focus/blur analysis:",i),Q={navType:i.nav_type,confidence:i.confidence,signals:i.signals,timeToFirstInteractionMs:i.time_to_first_interaction_ms},b("focus_blur_analysis",{nav_type:i.nav_type,confidence:i.confidence,signals:i.signals,time_to_first_interaction_ms:i.time_to_first_interaction_ms,sequence_length:i.sequence.length}),i.nav_type==="likely_paste"&&i.confidence>=.4&&(!f||f.confidence<i.confidence)&&(f={isAI:!0,confidence:i.confidence,method:"behavioral"},c("AI detection updated from focus/blur analysis:",f))}function qe(){return v}function Ue(){return p}function ze(){return f}function Ve(){return F}function Ye(){return re}function je(){return Q}function Ge(){return k?.getResult()||null}function Xe(){return E}function ye(i,e){if(B.apiKey)try{let t={workspace_id:B.apiKey,status:i,error_message:e||null,version:T,url:typeof window<"u"?window.location.href:null,user_agent:typeof navigator<"u"?navigator.userAgent:null,timestamp:new Date().toISOString(),features:{scroll_tracker:!!_,time_tracker:!!x,form_tracker:!!P,spa_router:!!N,behavioral_ml:!!l,focus_blur:!!D,agentic:!!k,ping_service:!!L,event_queue:!!S}};R(y(a.endpoints.health),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}).catch(()=>{}),c("Health reported:",i)}catch{}}function Ke(){c("Resetting tracker"),L?.stop(),_?.stop(),x?.stop(),P?.stop(),N?.stop(),k?.destroy(),E=!1,p=null,v=null,F=null,f=null,l=null,re=null,D=null,Q=null,k=null,S=null,L=null,_=null,x=null,P=null,N=null;try{sessionStorage.removeItem("loamly_session"),sessionStorage.removeItem("loamly_start")}catch{}}function We(i){se=i,c("Debug mode:",i?"enabled":"disabled")}var M={init:Me,pageview:oe,track:ge,conversion:Pe,identify:Ne,getSessionId:qe,getVisitorId:Ue,getAIDetection:ze,getNavigationTiming:Ve,getBehavioralML:Ye,getFocusBlur:je,getAgentic:Ge,isInitialized:Xe,reset:Ke,debug:We,reportHealth:ye};function Qe(){let i=document.getElementsByTagName("script");for(let e of i){let t=e.src;if(t.includes("t.js")||t.includes("loamly"))try{let s=new URL(t).searchParams.get("d");if(s)return s}catch{}}return null}async function be(i){try{let e=await fetch(`${a.apiHost}${a.endpoints.resolve}?domain=${encodeURIComponent(i)}`);if(!e.ok)return console.warn("[Loamly] Failed to resolve workspace for domain:",i),null;let t=await e.json();return t.workspace_id?{apiKey:t.workspace_api_key,apiHost:a.apiHost}:null}catch(e){return console.warn("[Loamly] Error resolving workspace:",e),null}}function $e(){let i=document.getElementsByTagName("script");for(let e of i)if(e.src.includes("loamly")||e.dataset.loamly!==void 0){let t={};if(e.dataset.apiKey&&(t.apiKey=e.dataset.apiKey),e.dataset.apiHost&&(t.apiHost=e.dataset.apiHost),e.dataset.debug==="true"&&(t.debug=!0),e.dataset.disableAutoPageview==="true"&&(t.disableAutoPageview=!0),e.dataset.disableBehavioral==="true"&&(t.disableBehavioral=!0),t.apiKey)return t}return null}async function $(){let i=Qe();if(i){let n=await be(i);if(n){M.init(n);return}}let e=$e();if(e){M.init(e);return}let t=window.location.hostname;if(t&&t!=="localhost"){let n=await be(t);if(n){M.init(n);return}}}typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{typeof requestIdleCallback<"u"?requestIdleCallback(()=>$()):setTimeout($,0)}):typeof requestIdleCallback<"u"?requestIdleCallback(()=>$()):setTimeout($,0));var Je=M;return Ce(Ze);})();
|
|
2
2
|
/**
|
|
3
3
|
* Loamly Tracker Configuration
|
|
4
4
|
*
|