(function(){if(window.gravityPixel&&typeof window.gravityPixel==="object"){return;} const DEFAULT_CONFIG={attrCookie:"gr_attrib",attrMaxAgeDays:180,sessionCookie:"gr_session",sessionMaxAgeDays:1,sessionTimeoutMinutes:30,sessionMaxPages:50,heartbeatIntervalMs:15000,eventEndpoint:"https://api.trygravity.ai/track/gr-events",sessionEndpoint:"https://api.trygravity.ai/track/gr-session",};const CONFIG=Object.assign({},DEFAULT_CONFIG,window.GRAVITY_PIXEL_CONFIG||{});const COOKIE_HISTORY_MAX=5;const MAX_URL_LENGTH=512;const MAX_TITLE_LENGTH=160;const now=Date.now();const params=new URLSearchParams(window.location.search||"");function uuid(prefix){return((prefix||"")+ Math.random().toString(36).slice(2,10)+ Math.random().toString(36).slice(2,10));} function safeParse(value,fallback){if(!value)return fallback;try{return JSON.parse(value);}catch(_){return fallback;}} function safeStringify(value){try{return JSON.stringify(value);}catch(_){return"";}} function truncateString(value,maxLength){if(typeof value!=="string")return value;if(maxLength>0&&value.length>maxLength){return value.slice(0,maxLength);} return value;} function historyStorageKey(sessionId){return"_history_"+sessionId;} function loadHistory(sessionId,fallback){if(!sessionId)return Array.isArray(fallback)?fallback.slice():[];try{if(!window.localStorage){return Array.isArray(fallback)?fallback.slice():[];} const raw=window.localStorage.getItem(historyStorageKey(sessionId));const parsed=safeParse(raw,null);if(Array.isArray(parsed)){return parsed;}}catch(_){} return Array.isArray(fallback)?fallback.slice():[];} function persistHistory(sessionId,history){if(!sessionId)return;try{if(!window.localStorage)return;if(!Array.isArray(history)){window.localStorage.removeItem(historyStorageKey(sessionId));return;} window.localStorage.setItem(historyStorageKey(sessionId),safeStringify(history));}catch(_){}} function historySnapshot(history){if(!Array.isArray(history)||!history.length)return[];const start=history.length>COOKIE_HISTORY_MAX?history.length-COOKIE_HISTORY_MAX:0;return history.slice(start);} function collectClientContext(){var nav=window.navigator||{};var screen=window.screen||{};var connection=nav.connection||nav.mozConnection||nav.webkitConnection||null;var uaData=nav.userAgentData&&typeof nav.userAgentData==="object"?nav.userAgentData:null;var platform=null;if(uaData&&typeof uaData.platform==="string"){platform=uaData.platform;}else if(typeof nav.platform==="string"){platform=nav.platform;} var timezone=null;try{timezone=Intl.DateTimeFormat().resolvedOptions().timeZone||Intl.DateTimeFormat().resolvedOptions().timezone;}catch(_){} return{timezone:timezone,viewport:{width:typeof window.innerWidth==="number"?window.innerWidth:null,height:typeof window.innerHeight==="number"?window.innerHeight:null,},screen:{width:screen.width||null,height:screen.height||null,color_depth:screen.colorDepth||null,pixel_depth:screen.pixelDepth||null,},platform:platform,user_agent_brands:uaData&&Array.isArray(uaData.brands)?uaData.brands:null,device_memory:typeof nav.deviceMemory==="number"?nav.deviceMemory:null,hardware_concurrency:typeof nav.hardwareConcurrency==="number"?nav.hardwareConcurrency:null,max_touch_points:typeof nav.maxTouchPoints==="number"?nav.maxTouchPoints:null,do_not_track:nav.doNotTrack||nav.msDoNotTrack||window.doNotTrack||null,connection:connection?{effective_type:connection.effectiveType||null,downlink:typeof connection.downlink==="number"?connection.downlink:null,rtt:typeof connection.rtt==="number"?connection.rtt:null,save_data:typeof connection.saveData==="boolean"?connection.saveData:null,}:null,};} function setCookie(name,value,days){try{const date=new Date();date.setTime(date.getTime()+days*24*60*60*1000);document.cookie=name+"="+ encodeURIComponent(value)+"; expires="+ date.toUTCString()+"; path=/; SameSite=Lax";}catch(_){}} function getCookie(name){try{const value=("; "+document.cookie).split("; "+name+"=").pop().split(";")[0];return value?decodeURIComponent(value):null;}catch(_){return null;}} function postJSON(url,payload,useBeacon){if(!url)return;const body=safeStringify(payload);const beaconEnabled=useBeacon!==false;if(beaconEnabled&&navigator.sendBeacon){try{const blob=new Blob([body],{type:"application/json"});if(navigator.sendBeacon(url,blob)){return;}}catch(_){}} try{fetch(url,{method:"POST",headers:{"Content-Type":"application/json"},body,keepalive:true,credentials:"omit",}).catch(()=>{});}catch(_){}} function captureAttribution(){const raw=getCookie(CONFIG.attrCookie);let attrib=safeParse(raw,{})||{};const firstSeen=attrib.first_seen||now;if(!attrib.gr_aid){attrib.gr_aid=uuid("gr_aid_");} const mappedParams=[["grclid",params.get("grclid")],["grcpid",params.get("grcpid")],["grpuid",params.get("grpuid")],["gradid",params.get("gradid")],];const utmKeys=["utm_source","utm_medium","utm_campaign","utm_term","utm_content","gclid","fbclid",];let touched=false;for(let i=0;isessionTimeout){isNew=true;session={id:uuid("gr_sess_"),started_at:now,last_seen:now,page_views:0,landing_url:truncateString(window.location.href||"",MAX_URL_LENGTH),entry_referrer:truncateString(document.referrer||"",MAX_URL_LENGTH)||null,page_history:[],};}else{session.last_seen=now;session.landing_url=truncateString(session.landing_url||"",MAX_URL_LENGTH);session.entry_referrer=truncateString(session.entry_referrer||"",MAX_URL_LENGTH)||null;} session.page_views=Number(session.page_views||0)+1;session.last_page_url=truncateString(window.location.href||"",MAX_URL_LENGTH);session.last_page_title=truncateString(document.title||"",MAX_TITLE_LENGTH)||null;session.last_seen=now;session.visitor_id=currentAttrib.gr_aid;const storedSnapshot=session.history_snapshot&&Array.isArray(session.history_snapshot)?session.history_snapshot:Array.isArray(session.page_history)?session.page_history:[];const existingHistory=loadHistory(session.id,storedSnapshot);session.page_history=Array.isArray(existingHistory)?existingHistory:[];session.page_history.push({url:truncateString(window.location.href||"",MAX_URL_LENGTH),title:truncateString(document.title||"",MAX_TITLE_LENGTH)||null,timestamp:new Date(now).toISOString(),});const maxPages=typeof CONFIG.sessionMaxPages==="number"&&CONFIG.sessionMaxPages>0?CONFIG.sessionMaxPages:50;if(session.page_history.length>maxPages){session.page_history.splice(0,session.page_history.length-maxPages);} persistSession(session);return{session,isNew};} function persistSession(session){const history=Array.isArray(session.page_history)?session.page_history:[];persistHistory(session.id,history);const cookiePayload={id:session.id,started_at:session.started_at,last_seen:session.last_seen,page_views:session.page_views,landing_url:truncateString(session.landing_url||"",MAX_URL_LENGTH),entry_referrer:truncateString(session.entry_referrer||"",MAX_URL_LENGTH)||null,last_page_url:truncateString(session.last_page_url||"",MAX_URL_LENGTH),last_page_title:truncateString(session.last_page_title||"",MAX_TITLE_LENGTH)||null,history_snapshot:historySnapshot(history),visitor_id:session.visitor_id||null,};setCookie(CONFIG.sessionCookie,safeStringify(cookiePayload),CONFIG.sessionMaxAgeDays);} const attribution=captureAttribution();const{session,isNew:isNewSession}=loadSession(attribution);let heartbeatTimer=null;let lastHeartbeat=now;function baseEventPayload(){return{event_id:uuid("gr_evt_"),event_timestamp:new Date().toISOString(),session_id:session.id,visitor_id:attribution.gr_aid,click_id:attribution.grclid||null,page_url:window.location.href,page_title:document.title||null,referrer:document.referrer||null,user_agent:navigator.userAgent||null,language:navigator.language||null,screen:{width:window.screen&&window.screen.width,height:window.screen&&window.screen.height,},};} function trackEvent(eventType,metadata){if(!CONFIG.eventEndpoint)return;metadata=metadata||{};const payload=baseEventPayload();payload.event_type=eventType;payload.session_start=isNewSession;metadata.visitor={id:attribution.gr_aid,click_id:attribution.grclid||null,};payload.metadata=metadata;payload.context=collectClientContext();payload.attribution=Object.assign({},attribution);postJSON(CONFIG.eventEndpoint,payload);} function sessionPayload(ended,reason){const durationMs=Date.now()-session.started_at;const pageHistory=Array.isArray(session.page_history)?session.page_history:[];return{session_id:session.id,visitor_id:attribution.gr_aid,new_session:isNewSession,started_at:new Date(session.started_at).toISOString(),last_seen_at:new Date(session.last_seen).toISOString(),duration_ms:durationMs,page_views:session.page_views,landing_url:session.landing_url,last_page_url:session.last_page_url,entry_referrer:session.entry_referrer,last_referrer:document.referrer||null,ended:!!ended,reason:reason||null,context:collectClientContext(),attribution:Object.assign({},attribution),page_history:pageHistory,};} function sendSessionUpdate(ended,reason,beacon){if(!CONFIG.sessionEndpoint)return;persistSession(session);const payload=sessionPayload(ended,reason);postJSON(CONFIG.sessionEndpoint,payload,beacon);} function heartbeat(reason){const nowHeartbeat=Date.now();if(nowHeartbeat-lastHeartbeat