@privatrak/tracker 1.3.0 → 1.3.1

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 CHANGED
@@ -12,6 +12,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
12
12
 
13
13
  ## [Unreleased]
14
14
 
15
+ ## [1.3.1] - 2026-10-07
16
+
17
+ ### Fixed
18
+
19
+ - A harmless browser warning, "ResizeObserver loop completed with undelivered
20
+ notifications", is no longer recorded as an error after a click. It is the
21
+ browser deferring layout notifications by a frame, not a failure in your
22
+ page, so it no longer shows up as an error click.
23
+
15
24
  ## [1.3.0] - 2026-10-07
16
25
 
17
26
  ### Added
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- function codePointLength(value){let n=0;for(let _ of value)n++;return n}function quote(value){let shown="",n=0;for(let ch of value){if(n===20)return`${JSON.stringify(shown)}\u2026`;shown+=ch,n++}return JSON.stringify(shown)}function describeNonString(value){return typeof value=="number"||typeof value=="boolean"?String(value):value===null?"null":`a value of type ${typeof value}`}function cleanTraits(value){if(!Array.isArray(value))return{traits:[],dropped:[`${describeNonString(value)} (not a list of traits)`]};let traits2=[],dropped=[],seen2=new Set,overLimit=[];for(let raw of value){if(typeof raw!="string"){dropped.push(`${describeNonString(raw)} (not a string)`);continue}let trait=raw.trim();if(trait===""){dropped.push(`${JSON.stringify(raw)} (empty)`);continue}if(codePointLength(trait)>64){dropped.push(`${quote(trait)} (longer than ${String(64)} characters)`);continue}seen2.has(trait)||(seen2.add(trait),traits2.length<50?traits2.push(trait):overLimit.push(quote(trait)))}if(overLimit.length>0){let extra=overLimit.length-10,names=overLimit.slice(0,10).join(", "),tail=extra>0?` and ${String(extra)} more`:"";dropped.push(`${names}${tail} (over the limit of ${String(50)} traits)`)}return{traits:traits2,dropped}}function describeDroppedTraits(source,dropped){let named=dropped.slice(0,10).join("; "),rest=dropped.length-10,more=rest>0?`; and ${String(rest)} more`:"";return`[tracker] ${source} left out traits the API would refuse: ${named}${more}. The other traits are sent as usual.`}function acceptTraits(value,source){let{traits:traits2,dropped}=cleanTraits(value);return dropped.length>0&&console.warn(describeDroppedTraits(source,dropped)),traits2}var LEGACY_DEAD_CLICK_WAIT_MS=5e3,MAX_QUEUE_CAP=100,config={flush_interval_ms:5e3,max_queue_size:10,walk_depth:3,max_text_length:100,autocapture_pageviews:!0,autocapture:!0,autocapture_elements:["a","button","input[type=submit]","[role=button]","[role=link]","[role=menuitem]","[role=menuitemcheckbox]","[role=menuitemradio]","[role=option]","[role=tab]","[role=switch]","[role=checkbox]","[role=radio]","[role=combobox]"],pii_url_params:["email","token","key","password","secret"],normalize_path_ids:!0,pii_path_patterns:[],excluded_urls:[],capture_dead_clicks:!0,capture_rage_clicks:!0,capture_error_clicks:!0,capture_slow_clicks:!0,dead_click_window_ms:1e3,slow_click_threshold_ms:1e3,dead_click_wait_ms:5e3,rage_click_threshold:3,rage_click_window_ms:1e3},apiBase="",apiKey="",configLoaded=!1,trackingDisabled=!1,traits=[];function setApiBase(value){apiBase=value}function setApiKey(value){apiKey=value}function setConfigLoaded(value){configLoaded=value}function setTrackingDisabled(value){trackingDisabled=value}function setTraits(value,source="setTraits()"){traits=acceptTraits(value,source)}function applyServerConfig(server){if(typeof server!="object"||server===null)return;let s=server;if(typeof s.flush_interval_ms=="number"&&(config.flush_interval_ms=s.flush_interval_ms),typeof s.max_queue_size=="number"&&(config.max_queue_size=s.max_queue_size),typeof s.walk_depth=="number"&&(config.walk_depth=s.walk_depth),typeof s.max_text_length=="number"&&(config.max_text_length=s.max_text_length),typeof s.autocapture_pageviews=="boolean"&&(config.autocapture_pageviews=s.autocapture_pageviews),typeof s.autocapture=="boolean"&&(config.autocapture=s.autocapture),Array.isArray(s.autocapture_elements)&&(config.autocapture_elements=s.autocapture_elements),Array.isArray(s.pii_url_params)&&(config.pii_url_params=s.pii_url_params),typeof s.normalize_path_ids=="boolean"&&(config.normalize_path_ids=s.normalize_path_ids),Array.isArray(s.pii_path_patterns)&&(config.pii_path_patterns=s.pii_path_patterns),Array.isArray(s.excluded_urls)&&(config.excluded_urls=s.excluded_urls),typeof s.capture_dead_clicks=="boolean"&&(config.capture_dead_clicks=s.capture_dead_clicks),typeof s.capture_rage_clicks=="boolean"&&(config.capture_rage_clicks=s.capture_rage_clicks),typeof s.capture_error_clicks=="boolean"&&(config.capture_error_clicks=s.capture_error_clicks),typeof s.capture_slow_clicks=="boolean"&&(config.capture_slow_clicks=s.capture_slow_clicks),typeof s.dead_click_window_ms=="number"){let w=s.dead_click_window_ms;config.dead_click_window_ms=w,config.slow_click_threshold_ms=w,config.dead_click_wait_ms=Math.max(w,LEGACY_DEAD_CLICK_WAIT_MS)}typeof s.slow_click_threshold_ms=="number"&&(config.slow_click_threshold_ms=s.slow_click_threshold_ms),typeof s.dead_click_wait_ms=="number"&&(config.dead_click_wait_ms=s.dead_click_wait_ms),typeof s.rage_click_threshold=="number"&&(config.rage_click_threshold=s.rage_click_threshold),typeof s.rage_click_window_ms=="number"&&(config.rage_click_window_ms=s.rage_click_window_ms)}var CONFIG_FETCH_ATTEMPTS=5,CONFIG_RETRY_DELAYS_MS=[500,1e3,2e3,4e3],CONFIG_FETCH_TIMEOUT_MS=3e3;function isRetryableStatus(status){return status===408||status===429||status>=500}function delay(ms){return new Promise(resolve2=>setTimeout(resolve2,ms))}async function attemptConfigFetch(){let controller=new AbortController,timer2=setTimeout(()=>{controller.abort()},CONFIG_FETCH_TIMEOUT_MS);try{let response=await fetch(`${apiBase}/api/config`,{headers:{"X-API-Key":apiKey},credentials:"omit",signal:controller.signal});if(!response.ok)return isRetryableStatus(response.status)?{kind:"retry",status:response.status}:{kind:"permanent",status:response.status};let data=await response.json();return applyServerConfig(data),{kind:"ok"}}catch{return{kind:"retry"}}finally{clearTimeout(timer2)}}async function fetchConfig(){let status;for(let attempt=0;attempt<CONFIG_FETCH_ATTEMPTS;attempt++){let outcome=await attemptConfigFetch();if(outcome.kind==="ok")return{loaded:!0,attempts:attempt+1};if(outcome.kind==="permanent")return{loaded:!1,attempts:attempt+1,status:outcome.status};status=outcome.status;let wait=CONFIG_RETRY_DELAYS_MS[attempt];if(wait===void 0)break;await delay(wait)}return{loaded:!1,attempts:CONFIG_FETCH_ATTEMPTS,...status!==void 0&&{status}}}var CONFIG_FAILURE_REASONS={401:"the API key is missing or not valid",403:"this site's origin is not in the project's allowed domains"};function describeConfigFailure(result){let attempts=result.attempts===1?"1 attempt":`${String(result.attempts)} attempts`;if(result.status===void 0)return`no response after ${attempts} (network error or timeout)`;let reason=CONFIG_FAILURE_REASONS[result.status],http=`HTTP ${String(result.status)}`;return reason===void 0?`${http} after ${attempts}`:`${http} after ${attempts} (${reason})`}function applyInitConfig(initConfig){initConfig.apiKey!==void 0&&(apiKey=initConfig.apiKey),initConfig.apiHost!==void 0&&(apiBase=initConfig.apiHost),initConfig.flushIntervalMs!==void 0&&(config.flush_interval_ms=initConfig.flushIntervalMs),initConfig.maxQueueSize!==void 0&&(config.max_queue_size=initConfig.maxQueueSize),initConfig.walkDepth!==void 0&&(config.walk_depth=initConfig.walkDepth),initConfig.maxTextLength!==void 0&&(config.max_text_length=initConfig.maxTextLength),initConfig.autocapturePageviews!==void 0&&(config.autocapture_pageviews=initConfig.autocapturePageviews),initConfig.autocapture!==void 0&&(config.autocapture=initConfig.autocapture),initConfig.autocaptureElements!==void 0&&(config.autocapture_elements=initConfig.autocaptureElements),initConfig.piiUrlParams!==void 0&&(config.pii_url_params=initConfig.piiUrlParams),typeof initConfig.normalizePathIds=="boolean"&&(config.normalize_path_ids=initConfig.normalizePathIds),Array.isArray(initConfig.piiPathPatterns)&&(config.pii_path_patterns=initConfig.piiPathPatterns),initConfig.excludedUrls!==void 0&&(config.excluded_urls=initConfig.excludedUrls),initConfig.traits!==void 0&&setTraits(initConfig.traits,"The traits setting")}var ID_PATTERNS=[/^\d+$/,/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,/^[0-9a-f]{8,}$/i];function isIdSegment(segment){return ID_PATTERNS.some(p=>p.test(segment))}function buildPiiPattern(){if(config.pii_url_params.length===0)return null;let escaped=config.pii_url_params.map(p=>p.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"));return new RegExp("("+escaped.join("|")+")","i")}function buildPiiPathPattern(){if(config.pii_path_patterns.length===0)return null;try{return new RegExp("^("+config.pii_path_patterns.join("|")+")$","i")}catch{return null}}function sanitizeUrl(url){try{let u=new URL(url),segments=u.pathname.split("/"),piiPathRegex=buildPiiPathPattern(),pathChanged=!1;for(let i=0;i<segments.length;i++){let seg=segments[i];if(seg){if(config.normalize_path_ids&&isIdSegment(seg)){segments[i]=":id",pathChanged=!0;continue}piiPathRegex?.test(seg)&&(segments[i]=":redacted",pathChanged=!0)}}pathChanged&&(u.pathname=segments.join("/"));let paramPattern=buildPiiPattern();if(paramPattern){let toRedact=[];u.searchParams.forEach((_v,k)=>{paramPattern.test(k)&&toRedact.push(k)});for(let k of toRedact)u.searchParams.set(k,":redacted")}return u.toString()}catch{return url}}function matchGlob(pattern,url){try{let path=new URL(url).pathname,escaped=pattern.replace(/[.+^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+escaped.replace(/\*/g,".*")+"$").test(path)}catch{return!1}}function isExcludedUrl(url){return config.excluded_urls.some(pattern=>matchGlob(pattern,url))}function disableTracking(queue2){setTrackingDisabled(!0),queue2.length=0,config.autocapture_pageviews=!1,config.autocapture=!1}function extractText(el){let raw=el.textContent;if(!raw)return;let trimmed=raw.trim().replace(/\s+/g," ");if(trimmed.length!==0)return trimmed.length>config.max_text_length?trimmed.slice(0,config.max_text_length):trimmed}function extractDataTrack(el){let current=el;for(let i=0;i<=config.walk_depth&&current;i++){let trackValue=current.getAttribute("data-track");if(trackValue!==null){let attrs={};for(let attr of current.attributes)if(attr.name.startsWith("data-track-")){let key=attr.name.slice(11);attrs[key]=attr.value}return{dataTrack:trackValue||void 0,dataTrackAttrs:Object.keys(attrs).length>0?attrs:void 0}}current=current.parentElement}return{dataTrack:void 0,dataTrackAttrs:void 0}}function getSegment(el){let seg=el.tagName.toLowerCase();el instanceof HTMLInputElement&&el.type&&(seg+='[type="'+CSS.escape(el.type)+'"]');let role=el.getAttribute("role");role&&(seg+='[role="'+CSS.escape(role)+'"]');let parent=el.parentElement;if(parent){let tag=el.tagName,siblings=parent.children,sameTag=0,idx=0;for(let i=0;i<siblings.length;i++){let sib=siblings[i];sib&&sib.tagName===tag&&(sameTag++,sib===el&&(idx=sameTag))}sameTag>1&&(seg+=":nth-of-type("+String(idx)+")")}return seg}var BODY="body > ",SEPARATOR=" > ",NTH_OF_TYPE=":nth-of-type(";function normalizeSelector(s){if(!s.startsWith(BODY))return s;let rest=s.slice(BODY.length),i=rest.indexOf(SEPARATOR),first=i>=0?rest.slice(0,i):rest,tail=i>=0?rest.slice(i):"";return BODY+withoutPosition(first)+tail}function withoutPosition(seg){if(!seg.endsWith(")"))return seg;let open=seg.lastIndexOf(NTH_OF_TYPE);if(open<0)return seg;let index=seg.slice(open+NTH_OF_TYPE.length,seg.length-1);if(index==="")return seg;for(let k=0;k<index.length;k++){let c=index[k];if(c===void 0||c<"0"||c>"9")return seg}return seg.slice(0,open)}function capped(parts){let result=parts.join(SEPARATOR);for(;result.length>200&&parts.length>1;)parts.shift(),result=parts.join(SEPARATOR);return result}function computeSelector(target){let parts=[],el=target;for(;el&&el!==document.documentElement;)parts.unshift(getSegment(el)),el=el.parentElement;return capped(normalizeSelector(parts.join(SEPARATOR)).split(SEPARATOR))}function getGenericSegment(el){let seg=el.tagName.toLowerCase();el instanceof HTMLInputElement&&el.type&&(seg+='[type="'+CSS.escape(el.type)+'"]');let role=el.getAttribute("role");return role&&(seg+='[role="'+CSS.escape(role)+'"]'),seg}function computeGenericSelector(target){let parts=[],el=target;for(;el&&el!==document.documentElement;)parts.unshift(getGenericSegment(el)),el=el.parentElement;return capped(parts)}function createPageviewEvent(referrer){return{event_type:"pageview",page_url:window.location.href,referrer:referrer===""?void 0:referrer,timestamp:new Date().toISOString()}}function createClickEvent(el){return createElementEvent(el,"click")}function createElementEvent(el,type){let{dataTrack,dataTrackAttrs}=extractDataTrack(el);return{event_type:type,page_url:window.location.href,element_tag:el.tagName.toLowerCase(),element_selector:computeSelector(el),element_selector_generalized:computeGenericSelector(el),element_text:extractText(el),data_track:dataTrack,data_track_attrs:dataTrackAttrs,timestamp:new Date().toISOString()}}function createFormSubmitEvent(form){let{dataTrack,dataTrackAttrs}=extractDataTrack(form);return{event_type:"form_submit",page_url:window.location.href,element_tag:form.tagName.toLowerCase(),element_selector:computeSelector(form),element_selector_generalized:computeGenericSelector(form),data_track:dataTrack,data_track_attrs:dataTrackAttrs,timestamp:new Date().toISOString()}}var pickerActive=!1,pickerDashboardOrigin=null;function setPickerActive(value){pickerActive=value}function setPickerDashboardOrigin(value){pickerDashboardOrigin=value}function backoffMs(attempt,random){let base=Math.min(6e4,2e3*2**Math.max(0,attempt-1));return Math.round(base/2+base/2*Math.min(1,Math.max(0,random)))}function retryAfterMs(value,now){if(value===null)return null;let v=value.trim(),ms;if(/^\d+$/.test(v))ms=Number(v)*1e3;else{let at=Date.parse(v);if(Number.isNaN(at))return null;ms=at-now}return Math.min(6e5,Math.max(0,ms))}function waitMs(attempt,retryAfter,random){return retryAfter===null?backoffMs(attempt,random):Math.max(retryAfter,backoffMs(1,random))}var REJECTION_REASONS={401:"the API key is missing or not valid",403:"this site's origin is not in the project's allowed domains",429:"the project is over its plan's monthly event limit"},MONTHLY_LIMIT="limit_events_per_month",MAX_BATCH=100,backoff={until:0,attempts:0,noted:!1},queue=[],lastUrl="",isFlushing=!1;function setLastUrl(value){lastUrl=value}function sanitizeEvent(event){let pageUrl=sanitizeUrl(event.page_url),referrer=event.referrer===void 0?void 0:sanitizeUrl(event.referrer);return pageUrl===event.page_url&&referrer===event.referrer?event:{...event,page_url:pageUrl,...referrer!==void 0&&{referrer}}}function prepareEvents(events){return filterEvents(events.map(sanitizeEvent))}function filterEvents(events){return events.filter(event=>!(isExcludedUrl(event.page_url)||event.event_type==="pageview"&&!config.autocapture_pageviews||(event.event_type==="click"||event.event_type==="form_submit")&&!config.autocapture&&!event.data_track||event.event_type==="dead_click"&&!(config.autocapture&&config.capture_dead_clicks)||event.event_type==="rage_click"&&!(config.autocapture&&config.capture_rage_clicks)||event.event_type==="error_click"&&!(config.autocapture&&config.capture_error_clicks)||event.event_type==="slow_click"&&!(config.autocapture&&config.capture_slow_clicks)))}function enqueue(event){trackingDisabled||pickerActive||apiKey&&(queue.length>=MAX_QUEUE_CAP||(queue.push(event),configLoaded&&queue.length>=config.max_queue_size&&flush()))}var flushing=null;async function flush(){if(trackingDisabled||pickerActive||!configLoaded||isFlushing||queue.length===0||Date.now()<backoff.until)return;isFlushing=!0;let events=prepareEvents(queue.splice(0,MAX_BATCH));if(events.length===0){isFlushing=!1;return}let sent=send(events,!1,null);flushing=sent;try{await sent}finally{flushing=null,isFlushing=!1}}async function send(events,beacon,before){let body={events,...traits.length>0&&{traits}};beacon&&apiKey&&(body.api_key=apiKey);let headers={"Content-Type":"application/json"};apiKey&&(headers["X-API-Key"]=apiKey);let response;try{response=await fetch(`${apiBase}/api/events`,{method:"POST",headers,body:JSON.stringify(body),keepalive:!0,credentials:"omit"})}catch{return putBack(events,null,before)}if(response.ok)return backoff.until=0,backoff.attempts=0,0;let status=response.status;return status===401||status===403||status===429&&await errorCode(response)===MONTHLY_LIMIT?(trackingDisabled||console.warn(`[tracker] The API rejected events with HTTP ${String(status)} \u2014 ${REJECTION_REASONS[status]??"the request was refused"}. Tracking is now off for this page.`),disableTracking(queue),0):status===429||status>=500?(status===429&&!backoff.noted&&(backoff.noted=!0,console.info("[tracker] The API asked to slow down (HTTP 429). Events are kept and sent again shortly.")),putBack(events,response,before)):0}async function errorCode(response){try{let body=await response.json(),code=typeof body=="object"&&body!==null?body.error_code:void 0;return typeof code=="string"?code:void 0}catch{return}}async function putBack(events,response,before){let at=before?await before:0;return trackingDisabled?0:(queue.splice(Math.min(at,queue.length),0,...events),queue.length>MAX_QUEUE_CAP&&(queue.length=MAX_QUEUE_CAP),backOff(response),events.length)}function backOff(response){backoff.attempts++;let now=Date.now(),told=response?retryAfterMs(response.headers.get("Retry-After"),now):null;backoff.until=now+waitMs(backoff.attempts,told,Math.random())}function flushBeacon(){if(trackingDisabled||!configLoaded||queue.length===0)return;let events=prepareEvents(queue.splice(0,MAX_BATCH));events.length!==0&&send(events,!0,flushing)}function readOnlyNotice(value){if(typeof value!="object"||value===null)return null;let v=value,{message,linkLabel,linkUrl}=v;return typeof message!="string"||!message||typeof linkLabel!="string"||typeof linkUrl!="string"||!/^https?:\/\//i.test(linkUrl)?null:{message,linkLabel,linkUrl}}function scanEnabledOption(value){return value!==!1}var PICKER_HANDOFF_KEY="__stPickerHandoff";function isSensitive(el){if(el instanceof HTMLInputElement){let t=el.type.toLowerCase();if(t==="password"||t==="hidden")return!0}let ac=el.getAttribute("autocomplete");return!!(ac&&ac.toLowerCase().startsWith("cc-"))}function isInteractive(el){if(el.hasAttribute("data-track"))return!0;if(!config.autocapture)return!1;for(let selector of config.autocapture_elements)try{if(el.matches(selector))return!0}catch{}return!1}function findInteractiveAncestor(target){let el=target;for(let i=0;i<=config.walk_depth&&el;i++){if(isInteractive(el))return el;el=el.parentElement}return null}function isPickerTarget(el){return isInteractive(el)||el.matches("form")}function findPickerTarget(target){let el=target;for(let i=0;i<=config.walk_depth&&el;i++){if(isPickerTarget(el))return el;el=el.parentElement}return null}function trackableElements(){let selectors=["[data-track]"];config.autocapture&&selectors.push("form",...config.autocapture_elements);let seen2=new Set;for(let selector of selectors){let found;try{found=document.querySelectorAll(selector)}catch{continue}for(let el of found)seen2.add(el)}let result=[];for(let el of seen2)isSensitive(el)||result.push(el);return result}var PICKER_FILE="tracker-picker.js",picker=null,loading=!1,failed=!1,pendingOptions=null,pickerHostApi={setActive:setPickerActive,setDashboardOrigin:setPickerDashboardOrigin,clearQueue:()=>{queue.length=0},computeSelector,computeGenericSelector,extractText,extractDataTrack,findPickerTarget,trackableElements,sanitizeUrl};function pickerScriptUrl(){for(let script of document.querySelectorAll("script[src]")){let src=script.getAttribute("src");if(src?.includes("tracker.js"))try{return new URL(PICKER_FILE,new URL(src,document.baseURI)).toString()}catch{}}return apiBase?apiBase.replace(/\/+$/,"")+"/"+PICKER_FILE:"/"+PICKER_FILE}function registerPicker(module){if(picker=module,loading=!1,pendingOptions){let options=pendingOptions;pendingOptions=null,activate(module,options)}}function activate(module,options){module.activate({...options,dashboardOrigin:pickerDashboardOrigin})}function abandonLoad(url){loading=!1,failed=!0,pendingOptions=null,setPickerActive(!1),console.warn(`[tracker] Could not load the Element Picker from ${url}. Tracking is unaffected.`)}function loadPicker(){let url=pickerScriptUrl(),script=document.createElement("script");script.src=url,script.async=!0,script[PICKER_HANDOFF_KEY]={host:pickerHostApi,register:registerPicker},script.addEventListener("load",()=>{script.remove(),picker||abandonLoad(url)}),script.addEventListener("error",()=>{script.remove(),abandonLoad(url)}),document.head.appendChild(script)}function requestPicker(options){if(picker){activate(picker,options??{});return}failed||(setPickerActive(!0),queue.length=0,pendingOptions=options??{},!loading&&(loading=!0,loadPicker()))}function onPickerNavigation(){picker?.onNavigation()}function onPickerWindowMessage(e){if(picker){picker.handleMessage(e);return}if(typeof e.data!="object"||e.data===null)return;let data=e.data;if(data.type!=="st-picker-activate"||pickerDashboardOrigin&&e.origin!==pickerDashboardOrigin)return;let readOnly=readOnlyNotice(data.readOnly);if(readOnly&&loading&&pendingOptions){pendingOptions={...pendingOptions,readOnly};return}pickerActive||!window.opener||requestPicker({...data.mode==="click-map"&&{mode:"click-map"},...readOnly&&{readOnly}})}function parsePickerHash(hash){let m=/^#st-picker=([^&]+)(?:&(.*))?$/.exec(hash),raw=m?.[1];if(!m||!raw)return null;let origin;try{origin=decodeURIComponent(raw)}catch{return null}let mode="rules";for(let pair of(m[2]??"").split("&"))pair==="mode=click-map"&&(mode="click-map");return{origin,mode}}var PRESS_MS=5e3,press=null;function disabled(el){return el.matches(":is(button,input,select,textarea):disabled")||el.getAttribute("aria-disabled")==="true"}function notePress(e){if(press=null,!e.isTrusted||e.button!==0)return;let target=e.target;if(!(target instanceof Element))return;let control=findInteractiveAncestor(target);!control||isSensitive(control)||disabled(control)||(press={id:e.pointerId,control,rect:control.getBoundingClientRect(),at:Date.now(),click:null,target:null})}function inside(r,x,y){return x>=r.left&&x<=r.right&&y>=r.top&&y<=r.bottom}function clickTarget(e){let target=e.target,p=press;if(!p||!e.isTrusted||e.detail===0)return target;if(p.click===e)return p.target??target;if(p.click!==null||(p.click=e,!(target instanceof Element)||findInteractiveAncestor(target)!==null||Date.now()-p.at>PRESS_MS||!p.control.isConnected))return target;let id=e.pointerId;if(typeof id=="number"&&id!==-1&&id!==p.id)return target;let x=e.clientX,y=e.clientY;return!inside(p.rect,x,y)&&!inside(p.control.getBoundingClientRect(),x,y)?target:(p.target=p.control,p.control)}function findLooksClickable(target,depth,parent,look2){let el=target;for(let i=0;i<=depth&&el;i++){let f=look2(el);if(f&12)return null;if(f&1){let top=el,up=parent(el);for(;up;i++){let g=look2(up);if(!(g&1))return top;if(g&8||i>=depth)return null;top=up,up=parent(up)}return top}if(f&2)return el;el=parent(el)}return null}function walkUp(target,depth,parent,pred){let el=target;for(let i=0;i<=depth&&el;i++){if(pred(el))return el;el=parent(el)}return null}function leavesDocument(href,page){try{let u=new URL(href,page);if(u.protocol==="javascript:")return!1;if(!href.includes("#"))return!0;let p=new URL(page);return u.hash="",p.hash="",u.href!==p.href}catch{return!0}}function reloadsDocument(href,page){try{let u=new URL(href,page);if(u.protocol==="javascript:")return!1;let p=new URL(page);return u.hash="",p.hash="",u.href===p.href}catch{return!1}}var UNDECIDED=0,FOLLOWED=1,CANCELLED=2,INTERCEPTED=3;function linkFate(dispatching,prevented){return prevented?CANCELLED:dispatching?UNDECIDED:FOLLOWED}function navFate(dispatching,done,inFlight){return dispatching?UNDECIDED:done?FOLLOWED:inFlight?INTERCEPTED:FOLLOWED}function abortMeans(navigationType,userInitiated){return navigationType==="traverse"||userInitiated?"moved-on":"live"}function decideLinks(pending2,fate){for(let i=0;i<pending2.length;i++){let p=pending2[i];if(p?.link===void 0)continue;let f=fate(p);f===FOLLOWED?pending2.splice(i--,1):f!==UNDECIDED&&delete p.link}}function elementKey(ev){return JSON.stringify([ev.element_selector_generalized??null,ev.element_text??null,ev.element_tag??null])}var MAX_REPORTED=100;function claim(seen2,key){return seen2.has(key)||seen2.size>=MAX_REPORTED?!1:(seen2.add(key),!0)}function nextBurst(burst2,key,first,now,windowMs){return burst2?.key===key&&now-burst2.last<=windowMs?(burst2.count++,burst2.last=now,burst2):{key,first,count:1,last:now}}var MAX_CLICK_COUNT=1e3;function rageCount(count,threshold,selected=!1){return count>=Math.max(selected?4:3,threshold)?Math.min(count,MAX_CLICK_COUNT):null}function selectionIsEffect(current,made,touchesMade=!1){return current!==null&&!touchesMade&&!(made&&made.anchor===current.anchor&&made.anchorOffset===current.anchorOffset&&made.focus===current.focus&&made.focusOffset===current.focusOffset)}var MAX_PENDING=8;function openWindow(pending2,seen2,p){if(seen2.every(s=>s.has(p.key))||pending2.length>=MAX_PENDING)return!1;for(let q of pending2)if(q.key===p.key)return!1;return pending2.push(p),!0}var IGNORE=0,LIVE=1,CAUSED=2,SUSPECT=3;function classify(related,noisy2,global=!1,ticking=!1){return noisy2?related?LIVE:IGNORE:related||global?CAUSED:ticking?SUSPECT:LIVE}function isRelated(node,el,depth,parent,contains2){return contains2(el,node)||walkUp(el,depth,parent,n=>n===node)!==null}function inHead(node,head,contains2){return head!==null&&contains2(head,node)}var DRAWS_NOTHING=/^(script|title|meta|base|noscript|template)$/;function drawsNothing(tag,rel){return tag==="link"?!/(^|\s)stylesheet(\s|$)/i.test(rel??""):DRAWS_NOTHING.test(tag)}function unseenMutation(type,target,attribute,added,removed,read){let silent=el=>{let tag=el===null?null:read.tag(el);return el!==null&&tag!==null&&drawsNothing(tag,read.rel(el))};if(type==="attributes"&&attribute==="rel"&&read.tag(target)==="link")return!1;if(type!=="childList")return silent(read.tag(target)===null?read.parent(target):target);for(let nodes of[added,removed])for(let i=0;i<nodes.length;i++){let n=nodes[i];if(read.tag(n)!==null?!silent(n):!read.blank(n)&&!silent(target))return!1}return!0}var NOISE_GAP_MS=6e3,NOISE_REPEAT_MS=250;function noteStreak(s,t){return s?(t-s.last>NOISE_GAP_MS?(s.start=s.beatAt=t,s.since=1/0,s.beats=1):(s.since===1/0&&t-s.start>=NOISE_REPEAT_MS&&(s.since=t),t-s.beatAt>=NOISE_REPEAT_MS&&(s.beats++,s.beatAt=t)),s.last=t,s):{start:t,last:t,since:1/0,beats:1,beatAt:t}}function noisyAt(s,at){return s!==void 0&&s.since<at}function tickingAt(s,at,t){return s!==void 0&&s.start<at&&t-s.last<=NOISE_GAP_MS}var MAX_DOUBTS=8;function addDoubt(doubts,node,t,beats){for(let d of doubts)if(d.node===node)return!0;return doubts.length>=MAX_DOUBTS?!1:(doubts.push({node,t,beats}),!0)}function judgeDoubts(doubts,at,now,streakOf2){let open=!1;for(let d of doubts){let s=streakOf2(d.node);if(!s||s.start>=at||now-s.last>NOISE_GAP_MS)return"live";s.beats-d.beats<2&&(open=!0)}return open?"open":"noise"}var NONE=0,DROP=1,SLOW=2,DOUBT=3;function effectOn(p,kind,t){return kind===IGNORE?NONE:kind===SUSPECT?DOUBT:kind===LIVE||t<p.slowAt||t>=p.due?DROP:SLOW}function effectOnRoute(p,answers,kind,t){return kind===IGNORE?NONE:!answers||kind===SUSPECT?(p.stirred=!0,NONE):effectOn(p,kind,t)===SLOW?SLOW:DROP}function moveOn(pending2,now,el){for(let p of pending2)p.el!==el&&!p.verdict&&(p.due=Math.max(p.slowAt,Math.min(p.due,now)))}var MAX_RESPONSE_MS=6e4;function responseMs(at,t){return Math.min(MAX_RESPONSE_MS,Math.max(0,Math.round(t-at)))}function errorEventCounts(trusted,rejection){return trusted||rejection}var ERROR_NAME=/^[A-Za-z_$][A-Za-z0-9_$.]{0,63}$/;function errorType(err,rejection){if(!(err instanceof Error))return rejection?"UnhandledRejection":"Error";let name;try{name=err.name}catch{return"Error"}return typeof name=="string"&&ERROR_NAME.test(name)?name:"Error"}function ambientError(last,at,windowMs){return last!==void 0&&last<at&&at-last<=windowMs}function takeSettled(pending2,now,final,streakOf2,gone2=()=>!1){let out=[];for(let i=0;i<pending2.length;i++){let p=pending2[i];if(!p)continue;if(!p.verdict){if(p.due>now)continue;if(p.stirred&&(p.appeared||!gone2(p))){pending2.splice(i--,1);continue}p.verdict="dead"}let j=judgeDoubts(p.doubts,p.at,now,streakOf2);if(j==="open"&&!final){p.due<=now&&(p.due=now+NOISE_REPEAT_MS);continue}pending2.splice(i--,1),j==="noise"&&out.push(p)}return out}function nextDue(pending2){let next=1/0;for(let p of pending2)p.due<next&&(next=p.due);return next}function holdsClick(prev,key,now,windowMs,detail){return detail!==0&&prev?.key===key&&now-prev.at<=windowMs}var MAX_HELD=32;function openHeld(held2,el,at,due,live2){if(held2.length>=MAX_HELD)return null;let h={ev:null,el,at,due,live:live2};return held2.push(h),h}function attachHeld(held2,h,ev){let i=held2.indexOf(h);return i<0?!1:h.live?(held2.splice(i,1),!1):(h.ev=ev,!0)}function releaseHeld(held2,did=()=>!0){let out=[];for(let i=0;i<held2.length;i++){let h=held2[i];!h||h.live||!did(h)||(h.ev!==null?(out.push(h.ev),held2.splice(i--,1)):h.live=!0)}return out}function takeDueHeld(held2,now){let out=[];for(let i=0;i<held2.length;i++){let h=held2[i];h&&h.due<=now&&(h.ev!==null&&!h.live&&out.push(h.ev),held2.splice(i--,1))}return out}function heldWaiting(held2){for(let h of held2)if(!h.live)return!0;return!1}var PRESS_MS2=5e3,STALL_MS=250,MAX_ERROR_TYPES=32;function newSeen(){return{dead:new Set,rage:new Set,slow:new Set,error:new Set}}var seen=newSeen(),nav=null,aborted=null,pending=[],burst=null,lastKey="",madeSel=null,madeEl=null,lastClick=null,held=[],holding=null,holdTarget=null,errClick=null,errorTimes=new Map,streaks=new WeakMap,pressTarget=null,pressEl=null,pressAt=0,pressUntil=0,pressEffect=!1,pressDoubts=[],inTask=!1,observer=null,observing=!1,listening=!1,timer,timerDue=0,live=()=>LIVE,caused=()=>CAUSED,notNav=p=>!p.nav;function parentOf(el){return el.parentElement}function nearParent(n){let p=n.parentNode;return p instanceof Element&&p!==document.body&&p!==document.documentElement?p:null}function contains(outer,inner){return outer.contains(inner)}function noisy(node,at){return walkUp(node,config.walk_depth,nearParent,n=>noisyAt(streaks.get(n),at))!==null}function tickingNode(node,at,t){let found=null,n=node;for(let i=0;i<=config.walk_depth&&n;i++)tickingAt(streaks.get(n),at,t)&&(found=n),n=nearParent(n);return found}function streakOf(n){return streaks.get(n)}function note(node,t){let s=streaks.get(node),n=noteStreak(s,t);s||streaks.set(node,n)}function isDisabled(el){return el.matches(":is(button,input,select,textarea):disabled")||el.getAttribute("aria-disabled")==="true"&&isInteractive(el)}function isEditable(el){return el instanceof HTMLInputElement?!/^(button|submit|image)$/.test(el.type):/^(TEXTAREA|SELECT)$/.test(el.tagName)||el.isContentEditable}function look(el){if(/^(canvas|video|audio|input|textarea|select)$/i.test(el.tagName)||isEditable(el))return 4;let s=getComputedStyle(el),f=s.cursor==="pointer"?1:0;return el===document.body||el===document.documentElement?f|8:el.tagName==="IMG"||el.tagName==="svg"||s.textDecorationLine.includes("underline")?f|2:f}function active(){return!pickerActive&&!trackingDisabled&&config.autocapture&&(config.capture_dead_clicks||config.capture_rage_clicks||config.capture_slow_clicks||config.capture_error_clicks)}function rolling(){return active()&&(config.capture_dead_clicks||config.capture_slow_clicks)}function idle(links=!0){return(links?pending.length===0:pending.every(p=>p.link))&&(pressEffect||!pressTarget)&&!heldWaiting(held)}function fateOf(p){let e=p.link;if(!e)return FOLLOWED;let f=linkFate(e.eventPhase!==0,e.defaultPrevented);if(f!==FOLLOWED||!p.nav)return f;let n=navigation();return navFate(p.nav.e.eventPhase!==0,p.nav.done,!!n&&n.transition!==null)}function navigation(){return window.navigation??null}function gone(p){let a=p.route;if(!a)return!1;if(!a.isConnected)return!0;if(a.getClientRects().length>0)return!1;if(getComputedStyle(a).display!=="contents")return!0;for(let i=0;i<a.children.length;i++)if((a.children[i]?.getClientRects().length??0)>0)return!1;return!0}function decide(){decideLinks(pending,fateOf)}function resolve(target){if(target.closest("#st-picker-host"))return null;let control=findInteractiveAncestor(target);if(control)return isSensitive(control)||isEditable(control)?null:control;let t=target;for(;t instanceof SVGElement&&t.ownerSVGElement;)t=t.ownerSVGElement;let el=findLooksClickable(t,config.walk_depth,parentOf,look);return el&&!isSensitive(el)?el:null}function selection(){let s=getSelection();return s&&!s.isCollapsed?{anchor:s.anchorNode,anchorOffset:s.anchorOffset,focus:s.focusNode,focusOffset:s.focusOffset}:null}function selectionEffect(){let s=getSelection();return selectionIsEffect(selection(),madeSel,!!madeEl&&!!s&&s.containsNode(madeEl,!0))}function startTask(){inTask||(inTask=!0,setTimeout(()=>{inTask=!1},0))}function report(el,now,detail,dead,target,doubts,disabled2=!1,click){let ev=createElementEvent(el,"dead_click"),key=elementKey(ev),rage=detail!==0,threshold=config.slow_click_threshold_ms,wait=Math.max(threshold,config.dead_click_wait_ms),multi=detail>=2&&key===lastKey;if(madeSel=multi?selection():null,madeEl=multi?el:null,lastKey=key,holding=null,holdTarget=target,rage&&(holdsClick(lastClick,key,now,config.rage_click_window_ms,detail)&&(holding=openHeld(held,el,now,now+threshold,!dead)),lastClick={key,at:now}),rage&&config.capture_rage_clicks){let next=nextBurst(burst,key,ev,now,config.rage_click_window_ms);next!==burst&&endBurst(),burst=next;let s=getSelection();next.selected=!!s&&!s.isCollapsed&&s.containsNode(el,!0)}errClick=config.capture_error_clicks&&!seen.error.has(key)?{key,ev,el,at:now,due:now+wait}:null;let link=el.closest("a[href]"),href=link?.getAttribute("href")??"",leaves=!!link&&leavesDocument(href,location.href),reloads=leaves&&reloadsDocument(href,location.href),route=leaves&&click&&!reloads?link:null;if((dead||route)&&!(leaves&&(!click||reloads))&&!el.closest("label")){let kinds=[];config.capture_dead_clicks&&kinds.push(seen.dead),config.capture_slow_clicks&&!disabled2&&kinds.push(seen.slow);let slowAt=now+threshold,p={key,ev,el,at:now,slowAt,due:disabled2?slowAt:now+wait,doubts:route?[]:doubts.slice(),seen};route&&(p.link=click,p.route=route,(!dead||doubts.length>0)&&(p.stirred=!0)),openWindow(pending,kinds,p)&&route&&setTimeout(sync,0)}sync()}function endBurst(){let b=burst;burst=null;let n=b&&rageCount(b.count,config.rage_click_threshold,b.selected);b&&n&&claim(seen.rage,b.key)&&enqueue({...b.first,event_type:"rage_click",click_count:n})}function happen(kindAt,suspect,answers,appears=!1){let t=Date.now();decide();let doubt=(doubts,at)=>{let n=suspect?.(at),s=n?streaks.get(n):void 0;return!!n&&!!s&&addDoubt(doubts,n,t,s.beats)};if(pressTarget&&!pressEffect){let k=inTask||!pressEl?LIVE:kindAt(pressEl,pressAt);k!==IGNORE&&!(k===SUSPECT&&doubt(pressDoubts,pressAt))&&(pressEffect=!0)}for(let i=0;i<pending.length;i++){let p=pending[i];if(!p||p.verdict)continue;if(p.route){let k=inTask?LIVE:kindAt(p.el,p.at),r2=effectOnRoute(p,answers?.(p)??!1,k,t);r2===NONE&&appears&&k!==IGNORE&&(p.appeared=!0),r2===SLOW?(p.verdict="slow",p.answeredAt=t):r2!==NONE&&pending.splice(i--,1);continue}let r=effectOn(p,inTask?LIVE:kindAt(p.el,p.at),t);r===NONE||r===DOUBT&&doubt(p.doubts,p.at)||(r===SLOW?(p.verdict="slow",p.answeredAt=t):pending.splice(i--,1))}let did=h=>{let k=inTask?LIVE:kindAt(h.el,h.at);return k!==IGNORE&&k!==SUSPECT};for(let ev of releaseHeld(held,did))enqueue(ev)}function markLive(){idle()||(happen(live),sync())}function markCaused(){idle()||(happen(caused),sync())}function onToggle(e){idle()||(happen(caused,void 0,void 0,e.newState!=="closed"),sync())}function markHistory(changed){changed?idle()||(happen(caused,void 0,notNav),sync()):markLive()}function settle(now,final){decide();for(let p of takeSettled(pending,now,final,streakOf,gone))p.verdict==="slow"?config.capture_slow_clicks&&claim(p.seen.slow,p.key)&&enqueue({...p.ev,event_type:"slow_click",response_ms:responseMs(p.at,p.answeredAt??now)}):config.capture_dead_clicks&&claim(p.seen.dead,p.key)&&enqueue(p.ev)}function movedOn(now,el,errors){if(errors&&errClick&&errClick.el!==el&&(errClick=null),pending.length===0)return;let records=observer?.takeRecords();records?.length&&onMutations(records),selectionEffect()&&happen(live),moveOn(pending,now,el),settle(now,!1)}var reader={tag:n=>n instanceof Element?n.tagName.toLowerCase():null,rel:n=>n instanceof Element?n.getAttribute("rel"):null,blank:n=>n.nodeType===8||!n.textContent?.trim(),parent:n=>n.parentNode};function unseen(r,head){return inHead(r.target,head,contains)&&unseenMutation(r.type,r.target,r.attributeName,r.addedNodes,r.removedNodes,reader)}function adds(r,head){if(r.type!=="childList"||inHead(r.target,head,contains))return!1;for(let i=0;i<r.addedNodes.length;i++){let n=r.addedNodes[i];if(n&&(n instanceof Element||!reader.blank(n)))return!0}return!1}function onMutations(records){let t=Date.now(),head=document.head,shown=records;for(let r of records)if(unseen(r,head)){shown=records.filter(q=>!unseen(q,head));break}for(let r of shown)note(r.target,t);for(let r of shown){if(idle())break;let node=r.target,dialog=r.attributeName==="open"&&/^(DIALOG|DETAILS)$/.test(node.nodeName);happen(dialog?caused:(el,at)=>classify(isRelated(node,el,config.walk_depth,nearParent,contains),noisy(node,at),!1,tickingNode(node,at,t)!==null),at=>tickingNode(node,at,t),p=>!!p.route&&p.route.contains(node)&&(node!==p.route||r.type!=="attributes"||r.attributeName==="aria-busy"),dialog&&node instanceof Element&&node.hasAttribute("open")||adds(r,head))}sync()}function holdClick(e,ev){let h=holding;return holding=null,!!h&&e.isTrusted&&e.detail!==0&&clickTarget(e)===holdTarget&&attachHeld(held,h,ev)}function onFocusIn(e){let f=e.target;pressTarget&&f instanceof Node&&f.contains(pressTarget)||markCaused()}function onScroll(e){let node=e.target instanceof Node?e.target:document;note(node,Date.now()),!idle()&&(happen((el,at)=>classify(node.contains(el),noisyAt(streaks.get(node),at),!0)),sync())}function onKeyDown(e){if(!e.isTrusted||pending.length===0&&!errClick)return;let t=e.target;movedOn(Date.now(),(e.key==="Enter"||e.key===" ")&&t instanceof Element?t:null,!0),sync()}function onWheel(e){!e.isTrusted||pending.length===0||(movedOn(Date.now(),null,!1),sync())}function onLeave(){movedOn(Date.now(),null,!1),markLive(),sync()}function onNavigate(e){let prev=aborted??(nav&&!nav.done?nav:null);if(aborted=null,prev){prev.done=!0;let ne=e;abortMeans(ne.navigationType??"",ne.userInitiated===!0)==="moved-on"?navMovedOn(prev):navAnswer(prev,!1)}let n={e,done:!1};nav=n;for(let p of pending){let c=p.link;c&&c.eventPhase===0&&!c.defaultPrevented&&!p.nav&&(p.nav=n)}}function navDone(ok){let n=nav;!n||n.done||(n.done=!0,navAnswer(n,ok))}function onNavigateError(e){let n=nav,err=e.error;if(!(typeof err=="object"&&err!==null&&err.name==="AbortError")||!n||n.done){navDone(!1);return}n.done=!0,aborted=n,setTimeout(()=>{aborted===n&&(aborted=null,navAnswer(n,!1))},0)}function navMovedOn(n){decide();let now=Date.now();for(let p of pending)p.nav===n&&!p.link&&!p.verdict&&(p.due=Math.max(p.slowAt,Math.min(p.due,now)));sync()}function navAnswer(n,ok){if(pending.length===0)return;let t=Date.now();decide();for(let i=0;i<pending.length;i++){let p=pending[i];if(!p||p.nav!==n||p.link||p.verdict)continue;let r=effectOnRoute(p,!0,ok?CAUSED:LIVE,t);r===SLOW?(p.verdict="slow",p.answeredAt=t):r!==NONE&&pending.splice(i--,1)}sync()}function noteError(type){let now=Date.now(),last=errorTimes.get(type);last===void 0&&errorTimes.size>=MAX_ERROR_TYPES&&errorTimes.clear(),errorTimes.set(type,now);let c=errClick;!c||now>c.due||!active()||!config.capture_error_clicks||!inTask&&ambientError(last,c.at,NOISE_GAP_MS)||(errClick=null,claim(seen.error,c.key)&&enqueue({...c.ev,event_type:"error_click",error_type:type}))}function onError(e){e instanceof ErrorEvent&&errorEventCounts(e.isTrusted,!1)&&noteError(errorType(e.error,!1))}function onRejection(e){errorEventCounts(e.isTrusted,!0)&&noteError(errorType(e.reason,!0))}function sync(){settle(Date.now(),!1);let watch=!idle(),observe=watch||rolling();observe!==observing&&(observe?(typeof MutationObserver=="function"&&(observer??=new MutationObserver(onMutations)),observer?.observe(document,{subtree:!0,childList:!0,attributes:!0,characterData:!0})):observer?.disconnect(),observing=observe);let leave=watch&&!idle(!1);leave!==listening&&(listening=leave,leave?window.addEventListener("beforeunload",onLeave):window.removeEventListener("beforeunload",onLeave));let next=Math.min(nextDue(pending),nextDue(held),burst?burst.last+config.rage_click_window_ms+1:1/0,pressTarget?pressUntil:1/0);clearTimeout(timer),timer=void 0,next<1/0&&(timerDue=next,timer=setTimeout(tick,Math.max(0,next-Date.now())))}function tick(){let now=Date.now(),late=now-timerDue>STALL_MS,records=observer?.takeRecords();records?.length&&onMutations(records),(late||selectionEffect())&&happen(live),settle(now,!1);for(let ev of takeDueHeld(held,now))active()||enqueue(ev);burst&&now-burst.last>config.rage_click_window_ms&&endBurst(),pressTarget&&now>=pressUntil&&(pressTarget=pressEl=null),sync()}function onPointerDown(e){if(!e.isTrusted)return;let target=e.target,now=Date.now();if(!(target instanceof Element)||e.button!==0||!active()){movedOn(now,null,!0),sync();return}let disabled2=walkUp(target,config.walk_depth,parentOf,isDisabled),el=disabled2??resolve(target);if(movedOn(now,el,!0),startTask(),holding=null,pressTarget=target,pressEffect=!1,pressDoubts=[],pressAt=now,pressUntil=now+PRESS_MS2,disabled2){pressEl=null,pressEffect=!0,!isSensitive(disabled2)&&!target.closest("#st-picker-host")?report(disabled2,now,1,!0,target,[],!0):sync();return}pressEl=el,pressEl||(pressTarget=null),sync()}function onClick(e){if(!e.isTrusted||!active())return;let target=clickTarget(e);if(!(target instanceof Element))return;startTask();let press2=pressTarget,effect=press2!==null&&pressEffect,el=press2===target?pressEl:resolve(target);pressTarget=pressEl=null;let multi=e.detail>=2;el&&!walkUp(target,config.walk_depth,parentOf,isDisabled)&&(isInteractive(el)||multi||getSelection()?.isCollapsed!==!1)?report(el,Date.now(),e.detail,!effect,target,press2?pressDoubts:[],!1,e):sync()}function onFrustrationHide(){onLeave(),settle(Date.now(),!0),endBurst()}function resetFrustration(){let own=nav&&!nav.done?nav:null,waiting=own?pending.filter(p=>p.nav===own):[];for(let p of waiting)pending.splice(pending.indexOf(p),1);movedOn(Date.now(),null,!1),markLive();for(let p of waiting)pending.push(p);waiting.length>0&&sync(),endBurst(),lastClick=null,lastKey="",madeSel=null,madeEl=null,seen=newSeen()}function startFrustration(){let capture={capture:!0,passive:!0};window.addEventListener("pointerdown",onPointerDown,capture),window.addEventListener("click",onClick,capture),window.addEventListener("focusin",onFocusIn,capture),window.addEventListener("keydown",onKeyDown,capture),window.addEventListener("wheel",onWheel,capture),window.addEventListener("error",onError),window.addEventListener("unhandledrejection",onRejection);for(let type of["blur","pagehide","popstate","hashchange"])window.addEventListener(type,onLeave);let n=navigation();n&&(n.addEventListener("navigate",onNavigate),n.addEventListener("navigatesuccess",()=>{navDone(!0)}),n.addEventListener("navigateerror",onNavigateError)),document.addEventListener("scroll",onScroll,capture),document.addEventListener("toggle",onToggle,capture);for(let type of["submit","invalid","change","play","copy"])document.addEventListener(type,markLive,capture);sync()}function onClickCapture(e){if(pickerActive)return;let target=clickTarget(e);if(!(target instanceof Element))return;let interactive=findInteractiveAncestor(target);if(!interactive||isSensitive(interactive))return;let ev=createClickEvent(interactive);holdClick(e,ev)||enqueue(ev)}function onSubmitCapture(e){if(pickerActive)return;let form=e.target;form instanceof HTMLFormElement&&(isSensitive(form)||!config.autocapture&&!extractDataTrack(form).dataTrack||enqueue(createFormSubmitEvent(form)))}function onSpaNavigation(){if(pickerActive){onPickerNavigation();return}if(!config.autocapture_pageviews)return;let currentUrl=window.location.href;if(currentUrl===lastUrl)return;let referrer=lastUrl;setLastUrl(currentUrl),resetFrustration(),enqueue(createPageviewEvent(referrer))}var inHistoryCall=!1;function onHistoryChange(urlChanged){markHistory(urlChanged),onSpaNavigation()}function patchHistory(onChange=onHistoryChange){let origPushState=history.pushState.bind(history),origReplaceState=history.replaceState.bind(history);history.pushState=function(...args){let before=location.href;inHistoryCall=!0;try{origPushState(...args)}finally{inHistoryCall=!1}onChange(location.href!==before)},history.replaceState=function(...args){let before=location.href;inHistoryCall=!0;try{origReplaceState(...args)}finally{inHistoryCall=!1}onChange(location.href!==before)}}function listenNavigation(onChange=onSpaNavigation){window.navigation?.addEventListener("currententrychange",()=>{inHistoryCall||onChange()})}var version="1.3.0",initialized=!1,storedInitConfig={},pickerOnly=!1;function init(initConfig){if(!(typeof window>"u")){if(initialized){console.warn("[tracker] Already initialized. Ignoring duplicate init() call."+(pickerOnly?" The first init() call was picker-only, so nothing is tracked on this page load.":apiKey?"":" The first init() call had no apiKey, so tracking stays off for this page load."));return}if(initialized=!0,storedInitConfig=initConfig??{},storedInitConfig.pickerOnly===!0){initPickerOnly(storedInitConfig);return}if(storedInitConfig.apiKey!==void 0&&setApiKey(storedInitConfig.apiKey),storedInitConfig.apiHost!==void 0&&setApiBase(storedInitConfig.apiHost),!apiKey){console.error("[tracker] Missing apiKey. Events will not be sent. Later init() calls are ignored, so call init() once, with the key.");return}storedInitConfig.traits!==void 0&&(storedInitConfig={...storedInitConfig,traits:acceptTraits(storedInitConfig.traits,"The traits setting")}),applyInitConfig(storedInitConfig),setLastUrl(window.location.href),config.autocapture_pageviews&&enqueue(createPageviewEvent(document.referrer)),patchHistory(),window.addEventListener("popstate",onSpaNavigation),listenNavigation(),window.addEventListener("pointerdown",notePress,{capture:!0,passive:!0}),document.addEventListener("click",onClickCapture,{capture:!0}),document.addEventListener("submit",onSubmitCapture,{capture:!0}),startFrustration(),listenForPicker(),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&(onFrustrationHide(),flushBeacon())}),fetchConfig().then(result=>{if(!result.loaded){failClosed(result);return}applyInitConfig(storedInitConfig),!trackingDisabled&&(setConfigLoaded(!0),setInterval(()=>{flush()},config.flush_interval_ms),flush())})}}function initPickerOnly(initConfig){pickerOnly=!0;let{apiKey:ignoredKey,traits:_traits,...rest}=initConfig;applyInitConfig(rest),ignoredKey?console.warn("[tracker] pickerOnly is set, so the apiKey is ignored: nothing is tracked or sent from this page. Remove one of the two."):console.info("[tracker] Picker-only mode: nothing is tracked or sent from this page, and track() and setTraits() do nothing."),patchHistory(onPickerOnlyNavigation),window.addEventListener("popstate",onPickerOnlyNavigation),listenNavigation(onPickerOnlyNavigation),listenForPicker()}function onPickerOnlyNavigation(){pickerActive&&onPickerNavigation()}function listenForPicker(){window.addEventListener("message",onPickerWindowMessage);let pickerHash=parsePickerHash(window.location.hash);if(pickerHash){let{origin,mode}=pickerHash;setPickerDashboardOrigin(origin);let clickMap=mode==="click-map";try{sessionStorage.setItem("st-picker",JSON.stringify({active:!0,origin,...clickMap&&{mode}}))}catch{}history.replaceState(null,"",window.location.pathname+window.location.search),window.opener&&requestPicker(clickMap?{mode}:void 0)}else try{let stored=sessionStorage.getItem("st-picker");if(stored&&window.opener){let parsed=JSON.parse(stored);if(typeof parsed=="object"&&parsed!==null&&"active"in parsed&&"origin"in parsed){let obj=parsed;if(obj.active&&typeof obj.origin=="string"){setPickerDashboardOrigin(obj.origin);let storedScan=scanEnabledOption(obj.scanEnabled),storedNav="navigateMode"in obj&&obj.navigateMode===!0,rawMode="selectorMode"in obj?obj.selectorMode:null,storedMode=rawMode==="generic"||rawMode==="exact"?rawMode:null,readOnly=readOnlyNotice(obj.readOnly);requestPicker({scanEnabled:storedScan,navigateMode:storedNav,selectorMode:storedMode,..."mode"in obj&&obj.mode==="click-map"&&{mode:"click-map"},...readOnly&&{readOnly}})}}}}catch{}}function failClosed(result){console.warn(`[tracker] Could not load this project's settings from ${apiBase}/api/config \u2014 ${describeConfigFailure(result)}. No events were sent from this page load: without those settings the tracker cannot apply the project's URL redaction rules, and sending unredacted URLs would be worse than sending nothing.`),disableTracking(queue)}function track(name,attrs){typeof window>"u"||pickerOnly||trackingDisabled||name&&enqueue({event_type:"custom",page_url:window.location.href,data_track:name,data_track_attrs:attrs,timestamp:new Date().toISOString()})}function setTraits2(newTraits){typeof window>"u"||pickerOnly||setTraits(newTraits)}export{init,setTraits2 as setTraits,track,version};
1
+ function codePointLength(value){let n=0;for(let _ of value)n++;return n}function quote(value){let shown="",n=0;for(let ch of value){if(n===20)return`${JSON.stringify(shown)}\u2026`;shown+=ch,n++}return JSON.stringify(shown)}function describeNonString(value){return typeof value=="number"||typeof value=="boolean"?String(value):value===null?"null":`a value of type ${typeof value}`}function cleanTraits(value){if(!Array.isArray(value))return{traits:[],dropped:[`${describeNonString(value)} (not a list of traits)`]};let traits2=[],dropped=[],seen2=new Set,overLimit=[];for(let raw of value){if(typeof raw!="string"){dropped.push(`${describeNonString(raw)} (not a string)`);continue}let trait=raw.trim();if(trait===""){dropped.push(`${JSON.stringify(raw)} (empty)`);continue}if(codePointLength(trait)>64){dropped.push(`${quote(trait)} (longer than ${String(64)} characters)`);continue}seen2.has(trait)||(seen2.add(trait),traits2.length<50?traits2.push(trait):overLimit.push(quote(trait)))}if(overLimit.length>0){let extra=overLimit.length-10,names=overLimit.slice(0,10).join(", "),tail=extra>0?` and ${String(extra)} more`:"";dropped.push(`${names}${tail} (over the limit of ${String(50)} traits)`)}return{traits:traits2,dropped}}function describeDroppedTraits(source,dropped){let named=dropped.slice(0,10).join("; "),rest=dropped.length-10,more=rest>0?`; and ${String(rest)} more`:"";return`[tracker] ${source} left out traits the API would refuse: ${named}${more}. The other traits are sent as usual.`}function acceptTraits(value,source){let{traits:traits2,dropped}=cleanTraits(value);return dropped.length>0&&console.warn(describeDroppedTraits(source,dropped)),traits2}var LEGACY_DEAD_CLICK_WAIT_MS=5e3,MAX_QUEUE_CAP=100,config={flush_interval_ms:5e3,max_queue_size:10,walk_depth:3,max_text_length:100,autocapture_pageviews:!0,autocapture:!0,autocapture_elements:["a","button","input[type=submit]","[role=button]","[role=link]","[role=menuitem]","[role=menuitemcheckbox]","[role=menuitemradio]","[role=option]","[role=tab]","[role=switch]","[role=checkbox]","[role=radio]","[role=combobox]"],pii_url_params:["email","token","key","password","secret"],normalize_path_ids:!0,pii_path_patterns:[],excluded_urls:[],capture_dead_clicks:!0,capture_rage_clicks:!0,capture_error_clicks:!0,capture_slow_clicks:!0,dead_click_window_ms:1e3,slow_click_threshold_ms:1e3,dead_click_wait_ms:5e3,rage_click_threshold:3,rage_click_window_ms:1e3},apiBase="",apiKey="",configLoaded=!1,trackingDisabled=!1,traits=[];function setApiBase(value){apiBase=value}function setApiKey(value){apiKey=value}function setConfigLoaded(value){configLoaded=value}function setTrackingDisabled(value){trackingDisabled=value}function setTraits(value,source="setTraits()"){traits=acceptTraits(value,source)}function applyServerConfig(server){if(typeof server!="object"||server===null)return;let s=server;if(typeof s.flush_interval_ms=="number"&&(config.flush_interval_ms=s.flush_interval_ms),typeof s.max_queue_size=="number"&&(config.max_queue_size=s.max_queue_size),typeof s.walk_depth=="number"&&(config.walk_depth=s.walk_depth),typeof s.max_text_length=="number"&&(config.max_text_length=s.max_text_length),typeof s.autocapture_pageviews=="boolean"&&(config.autocapture_pageviews=s.autocapture_pageviews),typeof s.autocapture=="boolean"&&(config.autocapture=s.autocapture),Array.isArray(s.autocapture_elements)&&(config.autocapture_elements=s.autocapture_elements),Array.isArray(s.pii_url_params)&&(config.pii_url_params=s.pii_url_params),typeof s.normalize_path_ids=="boolean"&&(config.normalize_path_ids=s.normalize_path_ids),Array.isArray(s.pii_path_patterns)&&(config.pii_path_patterns=s.pii_path_patterns),Array.isArray(s.excluded_urls)&&(config.excluded_urls=s.excluded_urls),typeof s.capture_dead_clicks=="boolean"&&(config.capture_dead_clicks=s.capture_dead_clicks),typeof s.capture_rage_clicks=="boolean"&&(config.capture_rage_clicks=s.capture_rage_clicks),typeof s.capture_error_clicks=="boolean"&&(config.capture_error_clicks=s.capture_error_clicks),typeof s.capture_slow_clicks=="boolean"&&(config.capture_slow_clicks=s.capture_slow_clicks),typeof s.dead_click_window_ms=="number"){let w=s.dead_click_window_ms;config.dead_click_window_ms=w,config.slow_click_threshold_ms=w,config.dead_click_wait_ms=Math.max(w,LEGACY_DEAD_CLICK_WAIT_MS)}typeof s.slow_click_threshold_ms=="number"&&(config.slow_click_threshold_ms=s.slow_click_threshold_ms),typeof s.dead_click_wait_ms=="number"&&(config.dead_click_wait_ms=s.dead_click_wait_ms),typeof s.rage_click_threshold=="number"&&(config.rage_click_threshold=s.rage_click_threshold),typeof s.rage_click_window_ms=="number"&&(config.rage_click_window_ms=s.rage_click_window_ms)}var CONFIG_FETCH_ATTEMPTS=5,CONFIG_RETRY_DELAYS_MS=[500,1e3,2e3,4e3],CONFIG_FETCH_TIMEOUT_MS=3e3;function isRetryableStatus(status){return status===408||status===429||status>=500}function delay(ms){return new Promise(resolve2=>setTimeout(resolve2,ms))}async function attemptConfigFetch(){let controller=new AbortController,timer2=setTimeout(()=>{controller.abort()},CONFIG_FETCH_TIMEOUT_MS);try{let response=await fetch(`${apiBase}/api/config`,{headers:{"X-API-Key":apiKey},credentials:"omit",signal:controller.signal});if(!response.ok)return isRetryableStatus(response.status)?{kind:"retry",status:response.status}:{kind:"permanent",status:response.status};let data=await response.json();return applyServerConfig(data),{kind:"ok"}}catch{return{kind:"retry"}}finally{clearTimeout(timer2)}}async function fetchConfig(){let status;for(let attempt=0;attempt<CONFIG_FETCH_ATTEMPTS;attempt++){let outcome=await attemptConfigFetch();if(outcome.kind==="ok")return{loaded:!0,attempts:attempt+1};if(outcome.kind==="permanent")return{loaded:!1,attempts:attempt+1,status:outcome.status};status=outcome.status;let wait=CONFIG_RETRY_DELAYS_MS[attempt];if(wait===void 0)break;await delay(wait)}return{loaded:!1,attempts:CONFIG_FETCH_ATTEMPTS,...status!==void 0&&{status}}}var CONFIG_FAILURE_REASONS={401:"the API key is missing or not valid",403:"this site's origin is not in the project's allowed domains"};function describeConfigFailure(result){let attempts=result.attempts===1?"1 attempt":`${String(result.attempts)} attempts`;if(result.status===void 0)return`no response after ${attempts} (network error or timeout)`;let reason=CONFIG_FAILURE_REASONS[result.status],http=`HTTP ${String(result.status)}`;return reason===void 0?`${http} after ${attempts}`:`${http} after ${attempts} (${reason})`}function applyInitConfig(initConfig){initConfig.apiKey!==void 0&&(apiKey=initConfig.apiKey),initConfig.apiHost!==void 0&&(apiBase=initConfig.apiHost),initConfig.flushIntervalMs!==void 0&&(config.flush_interval_ms=initConfig.flushIntervalMs),initConfig.maxQueueSize!==void 0&&(config.max_queue_size=initConfig.maxQueueSize),initConfig.walkDepth!==void 0&&(config.walk_depth=initConfig.walkDepth),initConfig.maxTextLength!==void 0&&(config.max_text_length=initConfig.maxTextLength),initConfig.autocapturePageviews!==void 0&&(config.autocapture_pageviews=initConfig.autocapturePageviews),initConfig.autocapture!==void 0&&(config.autocapture=initConfig.autocapture),initConfig.autocaptureElements!==void 0&&(config.autocapture_elements=initConfig.autocaptureElements),initConfig.piiUrlParams!==void 0&&(config.pii_url_params=initConfig.piiUrlParams),typeof initConfig.normalizePathIds=="boolean"&&(config.normalize_path_ids=initConfig.normalizePathIds),Array.isArray(initConfig.piiPathPatterns)&&(config.pii_path_patterns=initConfig.piiPathPatterns),initConfig.excludedUrls!==void 0&&(config.excluded_urls=initConfig.excludedUrls),initConfig.traits!==void 0&&setTraits(initConfig.traits,"The traits setting")}var ID_PATTERNS=[/^\d+$/,/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,/^[0-9a-f]{8,}$/i];function isIdSegment(segment){return ID_PATTERNS.some(p=>p.test(segment))}function buildPiiPattern(){if(config.pii_url_params.length===0)return null;let escaped=config.pii_url_params.map(p=>p.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"));return new RegExp("("+escaped.join("|")+")","i")}function buildPiiPathPattern(){if(config.pii_path_patterns.length===0)return null;try{return new RegExp("^("+config.pii_path_patterns.join("|")+")$","i")}catch{return null}}function sanitizeUrl(url){try{let u=new URL(url),segments=u.pathname.split("/"),piiPathRegex=buildPiiPathPattern(),pathChanged=!1;for(let i=0;i<segments.length;i++){let seg=segments[i];if(seg){if(config.normalize_path_ids&&isIdSegment(seg)){segments[i]=":id",pathChanged=!0;continue}piiPathRegex?.test(seg)&&(segments[i]=":redacted",pathChanged=!0)}}pathChanged&&(u.pathname=segments.join("/"));let paramPattern=buildPiiPattern();if(paramPattern){let toRedact=[];u.searchParams.forEach((_v,k)=>{paramPattern.test(k)&&toRedact.push(k)});for(let k of toRedact)u.searchParams.set(k,":redacted")}return u.toString()}catch{return url}}function matchGlob(pattern,url){try{let path=new URL(url).pathname,escaped=pattern.replace(/[.+^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+escaped.replace(/\*/g,".*")+"$").test(path)}catch{return!1}}function isExcludedUrl(url){return config.excluded_urls.some(pattern=>matchGlob(pattern,url))}function disableTracking(queue2){setTrackingDisabled(!0),queue2.length=0,config.autocapture_pageviews=!1,config.autocapture=!1}function extractText(el){let raw=el.textContent;if(!raw)return;let trimmed=raw.trim().replace(/\s+/g," ");if(trimmed.length!==0)return trimmed.length>config.max_text_length?trimmed.slice(0,config.max_text_length):trimmed}function extractDataTrack(el){let current=el;for(let i=0;i<=config.walk_depth&&current;i++){let trackValue=current.getAttribute("data-track");if(trackValue!==null){let attrs={};for(let attr of current.attributes)if(attr.name.startsWith("data-track-")){let key=attr.name.slice(11);attrs[key]=attr.value}return{dataTrack:trackValue||void 0,dataTrackAttrs:Object.keys(attrs).length>0?attrs:void 0}}current=current.parentElement}return{dataTrack:void 0,dataTrackAttrs:void 0}}function getSegment(el){let seg=el.tagName.toLowerCase();el instanceof HTMLInputElement&&el.type&&(seg+='[type="'+CSS.escape(el.type)+'"]');let role=el.getAttribute("role");role&&(seg+='[role="'+CSS.escape(role)+'"]');let parent=el.parentElement;if(parent){let tag=el.tagName,siblings=parent.children,sameTag=0,idx=0;for(let i=0;i<siblings.length;i++){let sib=siblings[i];sib&&sib.tagName===tag&&(sameTag++,sib===el&&(idx=sameTag))}sameTag>1&&(seg+=":nth-of-type("+String(idx)+")")}return seg}var BODY="body > ",SEPARATOR=" > ",NTH_OF_TYPE=":nth-of-type(";function normalizeSelector(s){if(!s.startsWith(BODY))return s;let rest=s.slice(BODY.length),i=rest.indexOf(SEPARATOR),first=i>=0?rest.slice(0,i):rest,tail=i>=0?rest.slice(i):"";return BODY+withoutPosition(first)+tail}function withoutPosition(seg){if(!seg.endsWith(")"))return seg;let open=seg.lastIndexOf(NTH_OF_TYPE);if(open<0)return seg;let index=seg.slice(open+NTH_OF_TYPE.length,seg.length-1);if(index==="")return seg;for(let k=0;k<index.length;k++){let c=index[k];if(c===void 0||c<"0"||c>"9")return seg}return seg.slice(0,open)}function capped(parts){let result=parts.join(SEPARATOR);for(;result.length>200&&parts.length>1;)parts.shift(),result=parts.join(SEPARATOR);return result}function computeSelector(target){let parts=[],el=target;for(;el&&el!==document.documentElement;)parts.unshift(getSegment(el)),el=el.parentElement;return capped(normalizeSelector(parts.join(SEPARATOR)).split(SEPARATOR))}function getGenericSegment(el){let seg=el.tagName.toLowerCase();el instanceof HTMLInputElement&&el.type&&(seg+='[type="'+CSS.escape(el.type)+'"]');let role=el.getAttribute("role");return role&&(seg+='[role="'+CSS.escape(role)+'"]'),seg}function computeGenericSelector(target){let parts=[],el=target;for(;el&&el!==document.documentElement;)parts.unshift(getGenericSegment(el)),el=el.parentElement;return capped(parts)}function createPageviewEvent(referrer){return{event_type:"pageview",page_url:window.location.href,referrer:referrer===""?void 0:referrer,timestamp:new Date().toISOString()}}function createClickEvent(el){return createElementEvent(el,"click")}function createElementEvent(el,type){let{dataTrack,dataTrackAttrs}=extractDataTrack(el);return{event_type:type,page_url:window.location.href,element_tag:el.tagName.toLowerCase(),element_selector:computeSelector(el),element_selector_generalized:computeGenericSelector(el),element_text:extractText(el),data_track:dataTrack,data_track_attrs:dataTrackAttrs,timestamp:new Date().toISOString()}}function createFormSubmitEvent(form){let{dataTrack,dataTrackAttrs}=extractDataTrack(form);return{event_type:"form_submit",page_url:window.location.href,element_tag:form.tagName.toLowerCase(),element_selector:computeSelector(form),element_selector_generalized:computeGenericSelector(form),data_track:dataTrack,data_track_attrs:dataTrackAttrs,timestamp:new Date().toISOString()}}var pickerActive=!1,pickerDashboardOrigin=null;function setPickerActive(value){pickerActive=value}function setPickerDashboardOrigin(value){pickerDashboardOrigin=value}function backoffMs(attempt,random){let base=Math.min(6e4,2e3*2**Math.max(0,attempt-1));return Math.round(base/2+base/2*Math.min(1,Math.max(0,random)))}function retryAfterMs(value,now){if(value===null)return null;let v=value.trim(),ms;if(/^\d+$/.test(v))ms=Number(v)*1e3;else{let at=Date.parse(v);if(Number.isNaN(at))return null;ms=at-now}return Math.min(6e5,Math.max(0,ms))}function waitMs(attempt,retryAfter,random){return retryAfter===null?backoffMs(attempt,random):Math.max(retryAfter,backoffMs(1,random))}var REJECTION_REASONS={401:"the API key is missing or not valid",403:"this site's origin is not in the project's allowed domains",429:"the project is over its plan's monthly event limit"},MONTHLY_LIMIT="limit_events_per_month",MAX_BATCH=100,backoff={until:0,attempts:0,noted:!1},queue=[],lastUrl="",isFlushing=!1;function setLastUrl(value){lastUrl=value}function sanitizeEvent(event){let pageUrl=sanitizeUrl(event.page_url),referrer=event.referrer===void 0?void 0:sanitizeUrl(event.referrer);return pageUrl===event.page_url&&referrer===event.referrer?event:{...event,page_url:pageUrl,...referrer!==void 0&&{referrer}}}function prepareEvents(events){return filterEvents(events.map(sanitizeEvent))}function filterEvents(events){return events.filter(event=>!(isExcludedUrl(event.page_url)||event.event_type==="pageview"&&!config.autocapture_pageviews||(event.event_type==="click"||event.event_type==="form_submit")&&!config.autocapture&&!event.data_track||event.event_type==="dead_click"&&!(config.autocapture&&config.capture_dead_clicks)||event.event_type==="rage_click"&&!(config.autocapture&&config.capture_rage_clicks)||event.event_type==="error_click"&&!(config.autocapture&&config.capture_error_clicks)||event.event_type==="slow_click"&&!(config.autocapture&&config.capture_slow_clicks)))}function enqueue(event){trackingDisabled||pickerActive||apiKey&&(queue.length>=MAX_QUEUE_CAP||(queue.push(event),configLoaded&&queue.length>=config.max_queue_size&&flush()))}var flushing=null;async function flush(){if(trackingDisabled||pickerActive||!configLoaded||isFlushing||queue.length===0||Date.now()<backoff.until)return;isFlushing=!0;let events=prepareEvents(queue.splice(0,MAX_BATCH));if(events.length===0){isFlushing=!1;return}let sent=send(events,!1,null);flushing=sent;try{await sent}finally{flushing=null,isFlushing=!1}}async function send(events,beacon,before){let body={events,...traits.length>0&&{traits}};beacon&&apiKey&&(body.api_key=apiKey);let headers={"Content-Type":"application/json"};apiKey&&(headers["X-API-Key"]=apiKey);let response;try{response=await fetch(`${apiBase}/api/events`,{method:"POST",headers,body:JSON.stringify(body),keepalive:!0,credentials:"omit"})}catch{return putBack(events,null,before)}if(response.ok)return backoff.until=0,backoff.attempts=0,0;let status=response.status;return status===401||status===403||status===429&&await errorCode(response)===MONTHLY_LIMIT?(trackingDisabled||console.warn(`[tracker] The API rejected events with HTTP ${String(status)} \u2014 ${REJECTION_REASONS[status]??"the request was refused"}. Tracking is now off for this page.`),disableTracking(queue),0):status===429||status>=500?(status===429&&!backoff.noted&&(backoff.noted=!0,console.info("[tracker] The API asked to slow down (HTTP 429). Events are kept and sent again shortly.")),putBack(events,response,before)):0}async function errorCode(response){try{let body=await response.json(),code=typeof body=="object"&&body!==null?body.error_code:void 0;return typeof code=="string"?code:void 0}catch{return}}async function putBack(events,response,before){let at=before?await before:0;return trackingDisabled?0:(queue.splice(Math.min(at,queue.length),0,...events),queue.length>MAX_QUEUE_CAP&&(queue.length=MAX_QUEUE_CAP),backOff(response),events.length)}function backOff(response){backoff.attempts++;let now=Date.now(),told=response?retryAfterMs(response.headers.get("Retry-After"),now):null;backoff.until=now+waitMs(backoff.attempts,told,Math.random())}function flushBeacon(){if(trackingDisabled||!configLoaded||queue.length===0)return;let events=prepareEvents(queue.splice(0,MAX_BATCH));events.length!==0&&send(events,!0,flushing)}function readOnlyNotice(value){if(typeof value!="object"||value===null)return null;let v=value,{message,linkLabel,linkUrl}=v;return typeof message!="string"||!message||typeof linkLabel!="string"||typeof linkUrl!="string"||!/^https?:\/\//i.test(linkUrl)?null:{message,linkLabel,linkUrl}}function scanEnabledOption(value){return value!==!1}var PICKER_HANDOFF_KEY="__stPickerHandoff";function isSensitive(el){if(el instanceof HTMLInputElement){let t=el.type.toLowerCase();if(t==="password"||t==="hidden")return!0}let ac=el.getAttribute("autocomplete");return!!(ac&&ac.toLowerCase().startsWith("cc-"))}function isInteractive(el){if(el.hasAttribute("data-track"))return!0;if(!config.autocapture)return!1;for(let selector of config.autocapture_elements)try{if(el.matches(selector))return!0}catch{}return!1}function findInteractiveAncestor(target){let el=target;for(let i=0;i<=config.walk_depth&&el;i++){if(isInteractive(el))return el;el=el.parentElement}return null}function isPickerTarget(el){return isInteractive(el)||el.matches("form")}function findPickerTarget(target){let el=target;for(let i=0;i<=config.walk_depth&&el;i++){if(isPickerTarget(el))return el;el=el.parentElement}return null}function trackableElements(){let selectors=["[data-track]"];config.autocapture&&selectors.push("form",...config.autocapture_elements);let seen2=new Set;for(let selector of selectors){let found;try{found=document.querySelectorAll(selector)}catch{continue}for(let el of found)seen2.add(el)}let result=[];for(let el of seen2)isSensitive(el)||result.push(el);return result}var PICKER_FILE="tracker-picker.js",picker=null,loading=!1,failed=!1,pendingOptions=null,pickerHostApi={setActive:setPickerActive,setDashboardOrigin:setPickerDashboardOrigin,clearQueue:()=>{queue.length=0},computeSelector,computeGenericSelector,extractText,extractDataTrack,findPickerTarget,trackableElements,sanitizeUrl};function pickerScriptUrl(){for(let script of document.querySelectorAll("script[src]")){let src=script.getAttribute("src");if(src?.includes("tracker.js"))try{return new URL(PICKER_FILE,new URL(src,document.baseURI)).toString()}catch{}}return apiBase?apiBase.replace(/\/+$/,"")+"/"+PICKER_FILE:"/"+PICKER_FILE}function registerPicker(module){if(picker=module,loading=!1,pendingOptions){let options=pendingOptions;pendingOptions=null,activate(module,options)}}function activate(module,options){module.activate({...options,dashboardOrigin:pickerDashboardOrigin})}function abandonLoad(url){loading=!1,failed=!0,pendingOptions=null,setPickerActive(!1),console.warn(`[tracker] Could not load the Element Picker from ${url}. Tracking is unaffected.`)}function loadPicker(){let url=pickerScriptUrl(),script=document.createElement("script");script.src=url,script.async=!0,script[PICKER_HANDOFF_KEY]={host:pickerHostApi,register:registerPicker},script.addEventListener("load",()=>{script.remove(),picker||abandonLoad(url)}),script.addEventListener("error",()=>{script.remove(),abandonLoad(url)}),document.head.appendChild(script)}function requestPicker(options){if(picker){activate(picker,options??{});return}failed||(setPickerActive(!0),queue.length=0,pendingOptions=options??{},!loading&&(loading=!0,loadPicker()))}function onPickerNavigation(){picker?.onNavigation()}function onPickerWindowMessage(e){if(picker){picker.handleMessage(e);return}if(typeof e.data!="object"||e.data===null)return;let data=e.data;if(data.type!=="st-picker-activate"||pickerDashboardOrigin&&e.origin!==pickerDashboardOrigin)return;let readOnly=readOnlyNotice(data.readOnly);if(readOnly&&loading&&pendingOptions){pendingOptions={...pendingOptions,readOnly};return}pickerActive||!window.opener||requestPicker({...data.mode==="click-map"&&{mode:"click-map"},...readOnly&&{readOnly}})}function parsePickerHash(hash){let m=/^#st-picker=([^&]+)(?:&(.*))?$/.exec(hash),raw=m?.[1];if(!m||!raw)return null;let origin;try{origin=decodeURIComponent(raw)}catch{return null}let mode="rules";for(let pair of(m[2]??"").split("&"))pair==="mode=click-map"&&(mode="click-map");return{origin,mode}}var PRESS_MS=5e3,press=null;function disabled(el){return el.matches(":is(button,input,select,textarea):disabled")||el.getAttribute("aria-disabled")==="true"}function notePress(e){if(press=null,!e.isTrusted||e.button!==0)return;let target=e.target;if(!(target instanceof Element))return;let control=findInteractiveAncestor(target);!control||isSensitive(control)||disabled(control)||(press={id:e.pointerId,control,rect:control.getBoundingClientRect(),at:Date.now(),click:null,target:null})}function inside(r,x,y){return x>=r.left&&x<=r.right&&y>=r.top&&y<=r.bottom}function clickTarget(e){let target=e.target,p=press;if(!p||!e.isTrusted||e.detail===0)return target;if(p.click===e)return p.target??target;if(p.click!==null||(p.click=e,!(target instanceof Element)||findInteractiveAncestor(target)!==null||Date.now()-p.at>PRESS_MS||!p.control.isConnected))return target;let id=e.pointerId;if(typeof id=="number"&&id!==-1&&id!==p.id)return target;let x=e.clientX,y=e.clientY;return!inside(p.rect,x,y)&&!inside(p.control.getBoundingClientRect(),x,y)?target:(p.target=p.control,p.control)}function findLooksClickable(target,depth,parent,look2){let el=target;for(let i=0;i<=depth&&el;i++){let f=look2(el);if(f&12)return null;if(f&1){let top=el,up=parent(el);for(;up;i++){let g=look2(up);if(!(g&1))return top;if(g&8||i>=depth)return null;top=up,up=parent(up)}return top}if(f&2)return el;el=parent(el)}return null}function walkUp(target,depth,parent,pred){let el=target;for(let i=0;i<=depth&&el;i++){if(pred(el))return el;el=parent(el)}return null}function leavesDocument(href,page){try{let u=new URL(href,page);if(u.protocol==="javascript:")return!1;if(!href.includes("#"))return!0;let p=new URL(page);return u.hash="",p.hash="",u.href!==p.href}catch{return!0}}function reloadsDocument(href,page){try{let u=new URL(href,page);if(u.protocol==="javascript:")return!1;let p=new URL(page);return u.hash="",p.hash="",u.href===p.href}catch{return!1}}var UNDECIDED=0,FOLLOWED=1,CANCELLED=2,INTERCEPTED=3;function linkFate(dispatching,prevented){return prevented?CANCELLED:dispatching?UNDECIDED:FOLLOWED}function navFate(dispatching,done,inFlight){return dispatching?UNDECIDED:done?FOLLOWED:inFlight?INTERCEPTED:FOLLOWED}function abortMeans(navigationType,userInitiated){return navigationType==="traverse"||userInitiated?"moved-on":"live"}function decideLinks(pending2,fate){for(let i=0;i<pending2.length;i++){let p=pending2[i];if(p?.link===void 0)continue;let f=fate(p);f===FOLLOWED?pending2.splice(i--,1):f!==UNDECIDED&&delete p.link}}function elementKey(ev){return JSON.stringify([ev.element_selector_generalized??null,ev.element_text??null,ev.element_tag??null])}var MAX_REPORTED=100;function claim(seen2,key){return seen2.has(key)||seen2.size>=MAX_REPORTED?!1:(seen2.add(key),!0)}function nextBurst(burst2,key,first,now,windowMs){return burst2?.key===key&&now-burst2.last<=windowMs?(burst2.count++,burst2.last=now,burst2):{key,first,count:1,last:now}}var MAX_CLICK_COUNT=1e3;function rageCount(count,threshold,selected=!1){return count>=Math.max(selected?4:3,threshold)?Math.min(count,MAX_CLICK_COUNT):null}function selectionIsEffect(current,made,touchesMade=!1){return current!==null&&!touchesMade&&!(made&&made.anchor===current.anchor&&made.anchorOffset===current.anchorOffset&&made.focus===current.focus&&made.focusOffset===current.focusOffset)}var MAX_PENDING=8;function openWindow(pending2,seen2,p){if(seen2.every(s=>s.has(p.key))||pending2.length>=MAX_PENDING)return!1;for(let q of pending2)if(q.key===p.key)return!1;return pending2.push(p),!0}var IGNORE=0,LIVE=1,CAUSED=2,SUSPECT=3;function classify(related,noisy2,global=!1,ticking=!1){return noisy2?related?LIVE:IGNORE:related||global?CAUSED:ticking?SUSPECT:LIVE}function isRelated(node,el,depth,parent,contains2){return contains2(el,node)||walkUp(el,depth,parent,n=>n===node)!==null}function inHead(node,head,contains2){return head!==null&&contains2(head,node)}var DRAWS_NOTHING=/^(script|title|meta|base|noscript|template)$/;function drawsNothing(tag,rel){return tag==="link"?!/(^|\s)stylesheet(\s|$)/i.test(rel??""):DRAWS_NOTHING.test(tag)}function unseenMutation(type,target,attribute,added,removed,read){let silent=el=>{let tag=el===null?null:read.tag(el);return el!==null&&tag!==null&&drawsNothing(tag,read.rel(el))};if(type==="attributes"&&attribute==="rel"&&read.tag(target)==="link")return!1;if(type!=="childList")return silent(read.tag(target)===null?read.parent(target):target);for(let nodes of[added,removed])for(let i=0;i<nodes.length;i++){let n=nodes[i];if(read.tag(n)!==null?!silent(n):!read.blank(n)&&!silent(target))return!1}return!0}var NOISE_GAP_MS=6e3,NOISE_REPEAT_MS=250;function noteStreak(s,t){return s?(t-s.last>NOISE_GAP_MS?(s.start=s.beatAt=t,s.since=1/0,s.beats=1):(s.since===1/0&&t-s.start>=NOISE_REPEAT_MS&&(s.since=t),t-s.beatAt>=NOISE_REPEAT_MS&&(s.beats++,s.beatAt=t)),s.last=t,s):{start:t,last:t,since:1/0,beats:1,beatAt:t}}function noisyAt(s,at){return s!==void 0&&s.since<at}function tickingAt(s,at,t){return s!==void 0&&s.start<at&&t-s.last<=NOISE_GAP_MS}var MAX_DOUBTS=8;function addDoubt(doubts,node,t,beats){for(let d of doubts)if(d.node===node)return!0;return doubts.length>=MAX_DOUBTS?!1:(doubts.push({node,t,beats}),!0)}function judgeDoubts(doubts,at,now,streakOf2){let open=!1;for(let d of doubts){let s=streakOf2(d.node);if(!s||s.start>=at||now-s.last>NOISE_GAP_MS)return"live";s.beats-d.beats<2&&(open=!0)}return open?"open":"noise"}var NONE=0,DROP=1,SLOW=2,DOUBT=3;function effectOn(p,kind,t){return kind===IGNORE?NONE:kind===SUSPECT?DOUBT:kind===LIVE||t<p.slowAt||t>=p.due?DROP:SLOW}function effectOnRoute(p,answers,kind,t){return kind===IGNORE?NONE:!answers||kind===SUSPECT?(p.stirred=!0,NONE):effectOn(p,kind,t)===SLOW?SLOW:DROP}function moveOn(pending2,now,el){for(let p of pending2)p.el!==el&&!p.verdict&&(p.due=Math.max(p.slowAt,Math.min(p.due,now)))}var MAX_RESPONSE_MS=6e4;function responseMs(at,t){return Math.min(MAX_RESPONSE_MS,Math.max(0,Math.round(t-at)))}function errorEventCounts(trusted,rejection){return trusted||rejection}function benignErrorEvent(message,err){return!(err instanceof Error)&&message.startsWith("ResizeObserver loop")}var ERROR_NAME=/^[A-Za-z_$][A-Za-z0-9_$.]{0,63}$/;function errorType(err,rejection){if(!(err instanceof Error))return rejection?"UnhandledRejection":"Error";let name;try{name=err.name}catch{return"Error"}return typeof name=="string"&&ERROR_NAME.test(name)?name:"Error"}function ambientError(last,at,windowMs){return last!==void 0&&last<at&&at-last<=windowMs}function takeSettled(pending2,now,final,streakOf2,gone2=()=>!1){let out=[];for(let i=0;i<pending2.length;i++){let p=pending2[i];if(!p)continue;if(!p.verdict){if(p.due>now)continue;if(p.stirred&&(p.appeared||!gone2(p))){pending2.splice(i--,1);continue}p.verdict="dead"}let j=judgeDoubts(p.doubts,p.at,now,streakOf2);if(j==="open"&&!final){p.due<=now&&(p.due=now+NOISE_REPEAT_MS);continue}pending2.splice(i--,1),j==="noise"&&out.push(p)}return out}function nextDue(pending2){let next=1/0;for(let p of pending2)p.due<next&&(next=p.due);return next}function holdsClick(prev,key,now,windowMs,detail){return detail!==0&&prev?.key===key&&now-prev.at<=windowMs}var MAX_HELD=32;function openHeld(held2,el,at,due,live2){if(held2.length>=MAX_HELD)return null;let h={ev:null,el,at,due,live:live2};return held2.push(h),h}function attachHeld(held2,h,ev){let i=held2.indexOf(h);return i<0?!1:h.live?(held2.splice(i,1),!1):(h.ev=ev,!0)}function releaseHeld(held2,did=()=>!0){let out=[];for(let i=0;i<held2.length;i++){let h=held2[i];!h||h.live||!did(h)||(h.ev!==null?(out.push(h.ev),held2.splice(i--,1)):h.live=!0)}return out}function takeDueHeld(held2,now){let out=[];for(let i=0;i<held2.length;i++){let h=held2[i];h&&h.due<=now&&(h.ev!==null&&!h.live&&out.push(h.ev),held2.splice(i--,1))}return out}function heldWaiting(held2){for(let h of held2)if(!h.live)return!0;return!1}var PRESS_MS2=5e3,STALL_MS=250,MAX_ERROR_TYPES=32;function newSeen(){return{dead:new Set,rage:new Set,slow:new Set,error:new Set}}var seen=newSeen(),nav=null,aborted=null,pending=[],burst=null,lastKey="",madeSel=null,madeEl=null,lastClick=null,held=[],holding=null,holdTarget=null,errClick=null,errorTimes=new Map,streaks=new WeakMap,pressTarget=null,pressEl=null,pressAt=0,pressUntil=0,pressEffect=!1,pressDoubts=[],inTask=!1,observer=null,observing=!1,listening=!1,timer,timerDue=0,live=()=>LIVE,caused=()=>CAUSED,notNav=p=>!p.nav;function parentOf(el){return el.parentElement}function nearParent(n){let p=n.parentNode;return p instanceof Element&&p!==document.body&&p!==document.documentElement?p:null}function contains(outer,inner){return outer.contains(inner)}function noisy(node,at){return walkUp(node,config.walk_depth,nearParent,n=>noisyAt(streaks.get(n),at))!==null}function tickingNode(node,at,t){let found=null,n=node;for(let i=0;i<=config.walk_depth&&n;i++)tickingAt(streaks.get(n),at,t)&&(found=n),n=nearParent(n);return found}function streakOf(n){return streaks.get(n)}function note(node,t){let s=streaks.get(node),n=noteStreak(s,t);s||streaks.set(node,n)}function isDisabled(el){return el.matches(":is(button,input,select,textarea):disabled")||el.getAttribute("aria-disabled")==="true"&&isInteractive(el)}function isEditable(el){return el instanceof HTMLInputElement?!/^(button|submit|image)$/.test(el.type):/^(TEXTAREA|SELECT)$/.test(el.tagName)||el.isContentEditable}function look(el){if(/^(canvas|video|audio|input|textarea|select)$/i.test(el.tagName)||isEditable(el))return 4;let s=getComputedStyle(el),f=s.cursor==="pointer"?1:0;return el===document.body||el===document.documentElement?f|8:el.tagName==="IMG"||el.tagName==="svg"||s.textDecorationLine.includes("underline")?f|2:f}function active(){return!pickerActive&&!trackingDisabled&&config.autocapture&&(config.capture_dead_clicks||config.capture_rage_clicks||config.capture_slow_clicks||config.capture_error_clicks)}function rolling(){return active()&&(config.capture_dead_clicks||config.capture_slow_clicks)}function idle(links=!0){return(links?pending.length===0:pending.every(p=>p.link))&&(pressEffect||!pressTarget)&&!heldWaiting(held)}function fateOf(p){let e=p.link;if(!e)return FOLLOWED;let f=linkFate(e.eventPhase!==0,e.defaultPrevented);if(f!==FOLLOWED||!p.nav)return f;let n=navigation();return navFate(p.nav.e.eventPhase!==0,p.nav.done,!!n&&n.transition!==null)}function navigation(){return window.navigation??null}function gone(p){let a=p.route;if(!a)return!1;if(!a.isConnected)return!0;if(a.getClientRects().length>0)return!1;if(getComputedStyle(a).display!=="contents")return!0;for(let i=0;i<a.children.length;i++)if((a.children[i]?.getClientRects().length??0)>0)return!1;return!0}function decide(){decideLinks(pending,fateOf)}function resolve(target){if(target.closest("#st-picker-host"))return null;let control=findInteractiveAncestor(target);if(control)return isSensitive(control)||isEditable(control)?null:control;let t=target;for(;t instanceof SVGElement&&t.ownerSVGElement;)t=t.ownerSVGElement;let el=findLooksClickable(t,config.walk_depth,parentOf,look);return el&&!isSensitive(el)?el:null}function selection(){let s=getSelection();return s&&!s.isCollapsed?{anchor:s.anchorNode,anchorOffset:s.anchorOffset,focus:s.focusNode,focusOffset:s.focusOffset}:null}function selectionEffect(){let s=getSelection();return selectionIsEffect(selection(),madeSel,!!madeEl&&!!s&&s.containsNode(madeEl,!0))}function startTask(){inTask||(inTask=!0,setTimeout(()=>{inTask=!1},0))}function report(el,now,detail,dead,target,doubts,disabled2=!1,click){let ev=createElementEvent(el,"dead_click"),key=elementKey(ev),rage=detail!==0,threshold=config.slow_click_threshold_ms,wait=Math.max(threshold,config.dead_click_wait_ms),multi=detail>=2&&key===lastKey;if(madeSel=multi?selection():null,madeEl=multi?el:null,lastKey=key,holding=null,holdTarget=target,rage&&(holdsClick(lastClick,key,now,config.rage_click_window_ms,detail)&&(holding=openHeld(held,el,now,now+threshold,!dead)),lastClick={key,at:now}),rage&&config.capture_rage_clicks){let next=nextBurst(burst,key,ev,now,config.rage_click_window_ms);next!==burst&&endBurst(),burst=next;let s=getSelection();next.selected=!!s&&!s.isCollapsed&&s.containsNode(el,!0)}errClick=config.capture_error_clicks&&!seen.error.has(key)?{key,ev,el,at:now,due:now+wait}:null;let link=el.closest("a[href]"),href=link?.getAttribute("href")??"",leaves=!!link&&leavesDocument(href,location.href),reloads=leaves&&reloadsDocument(href,location.href),route=leaves&&click&&!reloads?link:null;if((dead||route)&&!(leaves&&(!click||reloads))&&!el.closest("label")){let kinds=[];config.capture_dead_clicks&&kinds.push(seen.dead),config.capture_slow_clicks&&!disabled2&&kinds.push(seen.slow);let slowAt=now+threshold,p={key,ev,el,at:now,slowAt,due:disabled2?slowAt:now+wait,doubts:route?[]:doubts.slice(),seen};route&&(p.link=click,p.route=route,(!dead||doubts.length>0)&&(p.stirred=!0)),openWindow(pending,kinds,p)&&route&&setTimeout(sync,0)}sync()}function endBurst(){let b=burst;burst=null;let n=b&&rageCount(b.count,config.rage_click_threshold,b.selected);b&&n&&claim(seen.rage,b.key)&&enqueue({...b.first,event_type:"rage_click",click_count:n})}function happen(kindAt,suspect,answers,appears=!1){let t=Date.now();decide();let doubt=(doubts,at)=>{let n=suspect?.(at),s=n?streaks.get(n):void 0;return!!n&&!!s&&addDoubt(doubts,n,t,s.beats)};if(pressTarget&&!pressEffect){let k=inTask||!pressEl?LIVE:kindAt(pressEl,pressAt);k!==IGNORE&&!(k===SUSPECT&&doubt(pressDoubts,pressAt))&&(pressEffect=!0)}for(let i=0;i<pending.length;i++){let p=pending[i];if(!p||p.verdict)continue;if(p.route){let k=inTask?LIVE:kindAt(p.el,p.at),r2=effectOnRoute(p,answers?.(p)??!1,k,t);r2===NONE&&appears&&k!==IGNORE&&(p.appeared=!0),r2===SLOW?(p.verdict="slow",p.answeredAt=t):r2!==NONE&&pending.splice(i--,1);continue}let r=effectOn(p,inTask?LIVE:kindAt(p.el,p.at),t);r===NONE||r===DOUBT&&doubt(p.doubts,p.at)||(r===SLOW?(p.verdict="slow",p.answeredAt=t):pending.splice(i--,1))}let did=h=>{let k=inTask?LIVE:kindAt(h.el,h.at);return k!==IGNORE&&k!==SUSPECT};for(let ev of releaseHeld(held,did))enqueue(ev)}function markLive(){idle()||(happen(live),sync())}function markCaused(){idle()||(happen(caused),sync())}function onToggle(e){idle()||(happen(caused,void 0,void 0,e.newState!=="closed"),sync())}function markHistory(changed){changed?idle()||(happen(caused,void 0,notNav),sync()):markLive()}function settle(now,final){decide();for(let p of takeSettled(pending,now,final,streakOf,gone))p.verdict==="slow"?config.capture_slow_clicks&&claim(p.seen.slow,p.key)&&enqueue({...p.ev,event_type:"slow_click",response_ms:responseMs(p.at,p.answeredAt??now)}):config.capture_dead_clicks&&claim(p.seen.dead,p.key)&&enqueue(p.ev)}function movedOn(now,el,errors){if(errors&&errClick&&errClick.el!==el&&(errClick=null),pending.length===0)return;let records=observer?.takeRecords();records?.length&&onMutations(records),selectionEffect()&&happen(live),moveOn(pending,now,el),settle(now,!1)}var reader={tag:n=>n instanceof Element?n.tagName.toLowerCase():null,rel:n=>n instanceof Element?n.getAttribute("rel"):null,blank:n=>n.nodeType===8||!n.textContent?.trim(),parent:n=>n.parentNode};function unseen(r,head){return inHead(r.target,head,contains)&&unseenMutation(r.type,r.target,r.attributeName,r.addedNodes,r.removedNodes,reader)}function adds(r,head){if(r.type!=="childList"||inHead(r.target,head,contains))return!1;for(let i=0;i<r.addedNodes.length;i++){let n=r.addedNodes[i];if(n&&(n instanceof Element||!reader.blank(n)))return!0}return!1}function onMutations(records){let t=Date.now(),head=document.head,shown=records;for(let r of records)if(unseen(r,head)){shown=records.filter(q=>!unseen(q,head));break}for(let r of shown)note(r.target,t);for(let r of shown){if(idle())break;let node=r.target,dialog=r.attributeName==="open"&&/^(DIALOG|DETAILS)$/.test(node.nodeName);happen(dialog?caused:(el,at)=>classify(isRelated(node,el,config.walk_depth,nearParent,contains),noisy(node,at),!1,tickingNode(node,at,t)!==null),at=>tickingNode(node,at,t),p=>!!p.route&&p.route.contains(node)&&(node!==p.route||r.type!=="attributes"||r.attributeName==="aria-busy"),dialog&&node instanceof Element&&node.hasAttribute("open")||adds(r,head))}sync()}function holdClick(e,ev){let h=holding;return holding=null,!!h&&e.isTrusted&&e.detail!==0&&clickTarget(e)===holdTarget&&attachHeld(held,h,ev)}function onFocusIn(e){let f=e.target;pressTarget&&f instanceof Node&&f.contains(pressTarget)||markCaused()}function onScroll(e){let node=e.target instanceof Node?e.target:document;note(node,Date.now()),!idle()&&(happen((el,at)=>classify(node.contains(el),noisyAt(streaks.get(node),at),!0)),sync())}function onKeyDown(e){if(!e.isTrusted||pending.length===0&&!errClick)return;let t=e.target;movedOn(Date.now(),(e.key==="Enter"||e.key===" ")&&t instanceof Element?t:null,!0),sync()}function onWheel(e){!e.isTrusted||pending.length===0||(movedOn(Date.now(),null,!1),sync())}function onLeave(){movedOn(Date.now(),null,!1),markLive(),sync()}function onNavigate(e){let prev=aborted??(nav&&!nav.done?nav:null);if(aborted=null,prev){prev.done=!0;let ne=e;abortMeans(ne.navigationType??"",ne.userInitiated===!0)==="moved-on"?navMovedOn(prev):navAnswer(prev,!1)}let n={e,done:!1};nav=n;for(let p of pending){let c=p.link;c&&c.eventPhase===0&&!c.defaultPrevented&&!p.nav&&(p.nav=n)}}function navDone(ok){let n=nav;!n||n.done||(n.done=!0,navAnswer(n,ok))}function onNavigateError(e){let n=nav,err=e.error;if(!(typeof err=="object"&&err!==null&&err.name==="AbortError")||!n||n.done){navDone(!1);return}n.done=!0,aborted=n,setTimeout(()=>{aborted===n&&(aborted=null,navAnswer(n,!1))},0)}function navMovedOn(n){decide();let now=Date.now();for(let p of pending)p.nav===n&&!p.link&&!p.verdict&&(p.due=Math.max(p.slowAt,Math.min(p.due,now)));sync()}function navAnswer(n,ok){if(pending.length===0)return;let t=Date.now();decide();for(let i=0;i<pending.length;i++){let p=pending[i];if(!p||p.nav!==n||p.link||p.verdict)continue;let r=effectOnRoute(p,!0,ok?CAUSED:LIVE,t);r===SLOW?(p.verdict="slow",p.answeredAt=t):r!==NONE&&pending.splice(i--,1)}sync()}function noteError(type){let now=Date.now(),last=errorTimes.get(type);last===void 0&&errorTimes.size>=MAX_ERROR_TYPES&&errorTimes.clear(),errorTimes.set(type,now);let c=errClick;!c||now>c.due||!active()||!config.capture_error_clicks||!inTask&&ambientError(last,c.at,NOISE_GAP_MS)||(errClick=null,claim(seen.error,c.key)&&enqueue({...c.ev,event_type:"error_click",error_type:type}))}function onError(e){e instanceof ErrorEvent&&errorEventCounts(e.isTrusted,!1)&&!benignErrorEvent(e.message,e.error)&&noteError(errorType(e.error,!1))}function onRejection(e){errorEventCounts(e.isTrusted,!0)&&noteError(errorType(e.reason,!0))}function sync(){settle(Date.now(),!1);let watch=!idle(),observe=watch||rolling();observe!==observing&&(observe?(typeof MutationObserver=="function"&&(observer??=new MutationObserver(onMutations)),observer?.observe(document,{subtree:!0,childList:!0,attributes:!0,characterData:!0})):observer?.disconnect(),observing=observe);let leave=watch&&!idle(!1);leave!==listening&&(listening=leave,leave?window.addEventListener("beforeunload",onLeave):window.removeEventListener("beforeunload",onLeave));let next=Math.min(nextDue(pending),nextDue(held),burst?burst.last+config.rage_click_window_ms+1:1/0,pressTarget?pressUntil:1/0);clearTimeout(timer),timer=void 0,next<1/0&&(timerDue=next,timer=setTimeout(tick,Math.max(0,next-Date.now())))}function tick(){let now=Date.now(),late=now-timerDue>STALL_MS,records=observer?.takeRecords();records?.length&&onMutations(records),(late||selectionEffect())&&happen(live),settle(now,!1);for(let ev of takeDueHeld(held,now))active()||enqueue(ev);burst&&now-burst.last>config.rage_click_window_ms&&endBurst(),pressTarget&&now>=pressUntil&&(pressTarget=pressEl=null),sync()}function onPointerDown(e){if(!e.isTrusted)return;let target=e.target,now=Date.now();if(!(target instanceof Element)||e.button!==0||!active()){movedOn(now,null,!0),sync();return}let disabled2=walkUp(target,config.walk_depth,parentOf,isDisabled),el=disabled2??resolve(target);if(movedOn(now,el,!0),startTask(),holding=null,pressTarget=target,pressEffect=!1,pressDoubts=[],pressAt=now,pressUntil=now+PRESS_MS2,disabled2){pressEl=null,pressEffect=!0,!isSensitive(disabled2)&&!target.closest("#st-picker-host")?report(disabled2,now,1,!0,target,[],!0):sync();return}pressEl=el,pressEl||(pressTarget=null),sync()}function onClick(e){if(!e.isTrusted||!active())return;let target=clickTarget(e);if(!(target instanceof Element))return;startTask();let press2=pressTarget,effect=press2!==null&&pressEffect,el=press2===target?pressEl:resolve(target);pressTarget=pressEl=null;let multi=e.detail>=2;el&&!walkUp(target,config.walk_depth,parentOf,isDisabled)&&(isInteractive(el)||multi||getSelection()?.isCollapsed!==!1)?report(el,Date.now(),e.detail,!effect,target,press2?pressDoubts:[],!1,e):sync()}function onFrustrationHide(){onLeave(),settle(Date.now(),!0),endBurst()}function resetFrustration(){let own=nav&&!nav.done?nav:null,waiting=own?pending.filter(p=>p.nav===own):[];for(let p of waiting)pending.splice(pending.indexOf(p),1);movedOn(Date.now(),null,!1),markLive();for(let p of waiting)pending.push(p);waiting.length>0&&sync(),endBurst(),lastClick=null,lastKey="",madeSel=null,madeEl=null,seen=newSeen()}function startFrustration(){let capture={capture:!0,passive:!0};window.addEventListener("pointerdown",onPointerDown,capture),window.addEventListener("click",onClick,capture),window.addEventListener("focusin",onFocusIn,capture),window.addEventListener("keydown",onKeyDown,capture),window.addEventListener("wheel",onWheel,capture),window.addEventListener("error",onError),window.addEventListener("unhandledrejection",onRejection);for(let type of["blur","pagehide","popstate","hashchange"])window.addEventListener(type,onLeave);let n=navigation();n&&(n.addEventListener("navigate",onNavigate),n.addEventListener("navigatesuccess",()=>{navDone(!0)}),n.addEventListener("navigateerror",onNavigateError)),document.addEventListener("scroll",onScroll,capture),document.addEventListener("toggle",onToggle,capture);for(let type of["submit","invalid","change","play","copy"])document.addEventListener(type,markLive,capture);sync()}function onClickCapture(e){if(pickerActive)return;let target=clickTarget(e);if(!(target instanceof Element))return;let interactive=findInteractiveAncestor(target);if(!interactive||isSensitive(interactive))return;let ev=createClickEvent(interactive);holdClick(e,ev)||enqueue(ev)}function onSubmitCapture(e){if(pickerActive)return;let form=e.target;form instanceof HTMLFormElement&&(isSensitive(form)||!config.autocapture&&!extractDataTrack(form).dataTrack||enqueue(createFormSubmitEvent(form)))}function onSpaNavigation(){if(pickerActive){onPickerNavigation();return}if(!config.autocapture_pageviews)return;let currentUrl=window.location.href;if(currentUrl===lastUrl)return;let referrer=lastUrl;setLastUrl(currentUrl),resetFrustration(),enqueue(createPageviewEvent(referrer))}var inHistoryCall=!1;function onHistoryChange(urlChanged){markHistory(urlChanged),onSpaNavigation()}function patchHistory(onChange=onHistoryChange){let origPushState=history.pushState.bind(history),origReplaceState=history.replaceState.bind(history);history.pushState=function(...args){let before=location.href;inHistoryCall=!0;try{origPushState(...args)}finally{inHistoryCall=!1}onChange(location.href!==before)},history.replaceState=function(...args){let before=location.href;inHistoryCall=!0;try{origReplaceState(...args)}finally{inHistoryCall=!1}onChange(location.href!==before)}}function listenNavigation(onChange=onSpaNavigation){window.navigation?.addEventListener("currententrychange",()=>{inHistoryCall||onChange()})}var version="1.3.1",initialized=!1,storedInitConfig={},pickerOnly=!1;function init(initConfig){if(!(typeof window>"u")){if(initialized){console.warn("[tracker] Already initialized. Ignoring duplicate init() call."+(pickerOnly?" The first init() call was picker-only, so nothing is tracked on this page load.":apiKey?"":" The first init() call had no apiKey, so tracking stays off for this page load."));return}if(initialized=!0,storedInitConfig=initConfig??{},storedInitConfig.pickerOnly===!0){initPickerOnly(storedInitConfig);return}if(storedInitConfig.apiKey!==void 0&&setApiKey(storedInitConfig.apiKey),storedInitConfig.apiHost!==void 0&&setApiBase(storedInitConfig.apiHost),!apiKey){console.error("[tracker] Missing apiKey. Events will not be sent. Later init() calls are ignored, so call init() once, with the key.");return}storedInitConfig.traits!==void 0&&(storedInitConfig={...storedInitConfig,traits:acceptTraits(storedInitConfig.traits,"The traits setting")}),applyInitConfig(storedInitConfig),setLastUrl(window.location.href),config.autocapture_pageviews&&enqueue(createPageviewEvent(document.referrer)),patchHistory(),window.addEventListener("popstate",onSpaNavigation),listenNavigation(),window.addEventListener("pointerdown",notePress,{capture:!0,passive:!0}),document.addEventListener("click",onClickCapture,{capture:!0}),document.addEventListener("submit",onSubmitCapture,{capture:!0}),startFrustration(),listenForPicker(),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&(onFrustrationHide(),flushBeacon())}),fetchConfig().then(result=>{if(!result.loaded){failClosed(result);return}applyInitConfig(storedInitConfig),!trackingDisabled&&(setConfigLoaded(!0),setInterval(()=>{flush()},config.flush_interval_ms),flush())})}}function initPickerOnly(initConfig){pickerOnly=!0;let{apiKey:ignoredKey,traits:_traits,...rest}=initConfig;applyInitConfig(rest),ignoredKey?console.warn("[tracker] pickerOnly is set, so the apiKey is ignored: nothing is tracked or sent from this page. Remove one of the two."):console.info("[tracker] Picker-only mode: nothing is tracked or sent from this page, and track() and setTraits() do nothing."),patchHistory(onPickerOnlyNavigation),window.addEventListener("popstate",onPickerOnlyNavigation),listenNavigation(onPickerOnlyNavigation),listenForPicker()}function onPickerOnlyNavigation(){pickerActive&&onPickerNavigation()}function listenForPicker(){window.addEventListener("message",onPickerWindowMessage);let pickerHash=parsePickerHash(window.location.hash);if(pickerHash){let{origin,mode}=pickerHash;setPickerDashboardOrigin(origin);let clickMap=mode==="click-map";try{sessionStorage.setItem("st-picker",JSON.stringify({active:!0,origin,...clickMap&&{mode}}))}catch{}history.replaceState(null,"",window.location.pathname+window.location.search),window.opener&&requestPicker(clickMap?{mode}:void 0)}else try{let stored=sessionStorage.getItem("st-picker");if(stored&&window.opener){let parsed=JSON.parse(stored);if(typeof parsed=="object"&&parsed!==null&&"active"in parsed&&"origin"in parsed){let obj=parsed;if(obj.active&&typeof obj.origin=="string"){setPickerDashboardOrigin(obj.origin);let storedScan=scanEnabledOption(obj.scanEnabled),storedNav="navigateMode"in obj&&obj.navigateMode===!0,rawMode="selectorMode"in obj?obj.selectorMode:null,storedMode=rawMode==="generic"||rawMode==="exact"?rawMode:null,readOnly=readOnlyNotice(obj.readOnly);requestPicker({scanEnabled:storedScan,navigateMode:storedNav,selectorMode:storedMode,..."mode"in obj&&obj.mode==="click-map"&&{mode:"click-map"},...readOnly&&{readOnly}})}}}}catch{}}function failClosed(result){console.warn(`[tracker] Could not load this project's settings from ${apiBase}/api/config \u2014 ${describeConfigFailure(result)}. No events were sent from this page load: without those settings the tracker cannot apply the project's URL redaction rules, and sending unredacted URLs would be worse than sending nothing.`),disableTracking(queue)}function track(name,attrs){typeof window>"u"||pickerOnly||trackingDisabled||name&&enqueue({event_type:"custom",page_url:window.location.href,data_track:name,data_track_attrs:attrs,timestamp:new Date().toISOString()})}function setTraits2(newTraits){typeof window>"u"||pickerOnly||setTraits(newTraits)}export{init,setTraits2 as setTraits,track,version};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@privatrak/tracker",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "Cookieless, privacy-first analytics tracker: auto-captures pageviews, clicks and form submissions with no cookies, no localStorage, no PII and no consent banner.",
5
5
  "keywords": [
6
6
  "analytics",