@kryptonhq/analytics 0.1.2 → 0.1.4

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.
@@ -1,4 +1,4 @@
1
- "use strict";var KryptonAnalytics=(()=>{var Z=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var be=Object.prototype.hasOwnProperty;var Ce=(e,t)=>{for(var r in t)Z(e,r,{get:t[r],enumerable:!0})},xe=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Se(t))!be.call(e,n)&&n!==r&&Z(e,n,{get:()=>t[n],enumerable:!(i=we(t,n))||i.enumerable});return e};var Ie=e=>xe(Z({},"__esModule",{value:!0}),e);var at={};Ce(at,{Krypton:()=>q,default:()=>nt,init:()=>ye});var v;(function(e){e[e.Document=0]="Document",e[e.DocumentType=1]="DocumentType",e[e.Element=2]="Element",e[e.Text=3]="Text",e[e.CDATA=4]="CDATA",e[e.Comment=5]="Comment"})(v||(v={}));function Te(e){return e.nodeType===e.ELEMENT_NODE}function Ee(e){var t=e?.host;return t?.shadowRoot===e}function ee(e){return Object.prototype.toString.call(e)==="[object ShadowRoot]"}function Le(e){return e.includes(" background-clip: text;")&&!e.includes(" -webkit-background-clip: text;")&&(e=e.replace(" background-clip: text;"," -webkit-background-clip: text; background-clip: text;")),e}function te(e){try{var t=e.rules||e.cssRules;return t?Le(Array.from(t).map(Re).join("")):null}catch{return null}}function Re(e){var t=e.cssText;if(_e(e))try{t=te(e.styleSheet)||t}catch{}return t}function _e(e){return"styleSheet"in e}var Ne=(function(){function e(){this.idNodeMap=new Map,this.nodeMetaMap=new WeakMap}return e.prototype.getId=function(t){var r;if(!t)return-1;var i=(r=this.getMeta(t))===null||r===void 0?void 0:r.id;return i??-1},e.prototype.getNode=function(t){return this.idNodeMap.get(t)||null},e.prototype.getIds=function(){return Array.from(this.idNodeMap.keys())},e.prototype.getMeta=function(t){return this.nodeMetaMap.get(t)||null},e.prototype.removeNodeFromMap=function(t){var r=this,i=this.getId(t);this.idNodeMap.delete(i),t.childNodes&&t.childNodes.forEach(function(n){return r.removeNodeFromMap(n)})},e.prototype.has=function(t){return this.idNodeMap.has(t)},e.prototype.hasNode=function(t){return this.nodeMetaMap.has(t)},e.prototype.add=function(t,r){var i=r.id;this.idNodeMap.set(i,t),this.nodeMetaMap.set(t,r)},e.prototype.replace=function(t,r){var i=this.getNode(t);if(i){var n=this.nodeMetaMap.get(i);n&&this.nodeMetaMap.set(r,n)}this.idNodeMap.set(t,r)},e.prototype.reset=function(){this.idNodeMap=new Map,this.nodeMetaMap=new WeakMap},e})();function Oe(e){var t=e.maskInputOptions,r=e.tagName,i=e.type,n=e.value,a=e.maskInputFn,c=n||"";return(t[r.toLowerCase()]||t[i])&&(a?c=a(c):c="*".repeat(c.length)),c}var le="__rrweb_original__";function Me(e){var t=e.getContext("2d");if(!t)return!0;for(var r=50,i=0;i<e.width;i+=r)for(var n=0;n<e.height;n+=r){var a=t.getImageData,c=le in a?a[le]:a,u=new Uint32Array(c.call(t,i,n,Math.min(r,e.width-i),Math.min(r,e.height-n)).data.buffer);if(u.some(function(o){return o!==0}))return!1}return!0}var Ae=1,De=new RegExp("[^a-z0-9-_:]"),ue=-2;function Fe(){return Ae++}function Pe(e){if(e instanceof HTMLFormElement)return"form";var t=e.tagName.toLowerCase().trim();return De.test(t)?"div":t}function He(e){return e.cssRules?Array.from(e.cssRules).map(function(t){return t.cssText||""}).join(""):""}function Ue(e){var t="";return e.indexOf("//")>-1?t=e.split("/").slice(0,3).join("/"):t=e.split("/")[0],t=t.split("?")[0],t}var z,fe,We=/url\((?:(')([^']*)'|(")(.*?)"|([^)]*))\)/gm,Ke=/^(?!www\.|(?:http|ftp)s?:\/\/|[A-Za-z]:\\|\/\/|#).*/,Be=/^(data:)([^,]*),(.*)/i;function $(e,t){return(e||"").replace(We,function(r,i,n,a,c,u){var o=n||c||u,f=i||a||"";if(!o)return r;if(!Ke.test(o)||Be.test(o))return"url(".concat(f).concat(o).concat(f,")");if(o[0]==="/")return"url(".concat(f).concat(Ue(t)+o).concat(f,")");var l=t.split("/"),h=o.split("/");l.pop();for(var b=0,k=h;b<k.length;b++){var w=k[b];w!=="."&&(w===".."?l.pop():l.push(w))}return"url(".concat(f).concat(l.join("/")).concat(f,")")})}var ze=/^[^ \t\n\r\u000c]+/,je=/^[, \t\n\r\u000c]+/;function qe(e,t){if(t.trim()==="")return t;var r=0;function i(f){var l,h=f.exec(t.substring(r));return h?(l=h[0],r+=l.length,l):""}for(var n=[];i(je),!(r>=t.length);){var a=i(ze);if(a.slice(-1)===",")a=j(e,a.substring(0,a.length-1)),n.push(a);else{var c="";a=j(e,a);for(var u=!1;;){var o=t.charAt(r);if(o===""){n.push((a+c).trim());break}else if(u)o===")"&&(u=!1);else if(o===","){r+=1,n.push((a+c).trim());break}else o==="("&&(u=!0);c+=o,r+=1}}}return n.join(", ")}function j(e,t){if(!t||t.trim()==="")return t;var r=e.createElement("a");return r.href=t,r.href}function Ge(e){return!!(e.tagName==="svg"||e.ownerSVGElement)}function ie(){var e=document.createElement("a");return e.href="",e.href}function Qe(e,t,r,i){return r==="src"||r==="href"&&i&&!(t==="use"&&i[0]==="#")||r==="xlink:href"&&i&&i[0]!=="#"||r==="background"&&i&&(t==="table"||t==="td"||t==="th")?j(e,i):r==="srcset"&&i?qe(e,i):r==="style"&&i?$(i,ie()):t==="object"&&r==="data"&&i?j(e,i):i}function $e(e,t,r){if(typeof t=="string"){if(e.classList.contains(t))return!0}else for(var i=e.classList.length;i--;){var n=e.classList[i];if(t.test(n))return!0}return r?e.matches(r):!1}function re(e,t,r){if(!e)return!1;if(e.nodeType!==e.ELEMENT_NODE)return r?re(e.parentNode,t,r):!1;for(var i=e.classList.length;i--;){var n=e.classList[i];if(t.test(n))return!0}return r?re(e.parentNode,t,r):!1}function Je(e,t,r){var i=e.nodeType===e.ELEMENT_NODE?e:e.parentElement;if(i===null)return!1;if(typeof t=="string"){if(i.classList.contains(t)||i.closest(".".concat(t)))return!0}else if(re(i,t,!0))return!0;return!!(r&&(i.matches(r)||i.closest(r)))}function Ve(e,t,r){var i=e.contentWindow;if(i){var n=!1,a;try{a=i.document.readyState}catch{return}if(a!=="complete"){var c=setTimeout(function(){n||(t(),n=!0)},r);e.addEventListener("load",function(){clearTimeout(c),n=!0,t()});return}var u="about:blank";if(i.location.href!==u||e.src===u||e.src==="")return setTimeout(t,0),e.addEventListener("load",t);e.addEventListener("load",t)}}function Ye(e,t,r){var i=!1,n;try{n=e.sheet}catch{return}if(!n){var a=setTimeout(function(){i||(t(),i=!0)},r);e.addEventListener("load",function(){clearTimeout(a),i=!0,t()})}}function Xe(e,t){var r=t.doc,i=t.mirror,n=t.blockClass,a=t.blockSelector,c=t.maskTextClass,u=t.maskTextSelector,o=t.inlineStylesheet,f=t.maskInputOptions,l=f===void 0?{}:f,h=t.maskTextFn,b=t.maskInputFn,k=t.dataURLOptions,w=k===void 0?{}:k,x=t.inlineImages,I=t.recordCanvas,T=t.keepIframeSrcFn,p=t.newlyAddedElement,s=p===void 0?!1:p,y=Ze(r,i);switch(e.nodeType){case e.DOCUMENT_NODE:return e.compatMode!=="CSS1Compat"?{type:v.Document,childNodes:[],compatMode:e.compatMode}:{type:v.Document,childNodes:[]};case e.DOCUMENT_TYPE_NODE:return{type:v.DocumentType,name:e.name,publicId:e.publicId,systemId:e.systemId,rootId:y};case e.ELEMENT_NODE:return tt(e,{doc:r,blockClass:n,blockSelector:a,inlineStylesheet:o,maskInputOptions:l,maskInputFn:b,dataURLOptions:w,inlineImages:x,recordCanvas:I,keepIframeSrcFn:T,newlyAddedElement:s,rootId:y});case e.TEXT_NODE:return et(e,{maskTextClass:c,maskTextSelector:u,maskTextFn:h,rootId:y});case e.CDATA_SECTION_NODE:return{type:v.CDATA,textContent:"",rootId:y};case e.COMMENT_NODE:return{type:v.Comment,textContent:e.textContent||"",rootId:y};default:return!1}}function Ze(e,t){if(t.hasNode(e)){var r=t.getId(e);return r===1?void 0:r}}function et(e,t){var r,i=t.maskTextClass,n=t.maskTextSelector,a=t.maskTextFn,c=t.rootId,u=e.parentNode&&e.parentNode.tagName,o=e.textContent,f=u==="STYLE"?!0:void 0,l=u==="SCRIPT"?!0:void 0;if(f&&o){try{e.nextSibling||e.previousSibling||!((r=e.parentNode.sheet)===null||r===void 0)&&r.cssRules&&(o=He(e.parentNode.sheet))}catch(h){console.warn("Cannot get CSS styles from text's parentNode. Error: ".concat(h),e)}o=$(o,ie())}return l&&(o="SCRIPT_PLACEHOLDER"),!f&&!l&&o&&Je(e,i,n)&&(o=a?a(o):o.replace(/[\S]/g,"*")),{type:v.Text,textContent:o||"",isStyle:f,rootId:c}}function tt(e,t){for(var r=t.doc,i=t.blockClass,n=t.blockSelector,a=t.inlineStylesheet,c=t.maskInputOptions,u=c===void 0?{}:c,o=t.maskInputFn,f=t.dataURLOptions,l=f===void 0?{}:f,h=t.inlineImages,b=t.recordCanvas,k=t.keepIframeSrcFn,w=t.newlyAddedElement,x=w===void 0?!1:w,I=t.rootId,T=$e(e,i,n),p=Pe(e),s={},y=e.attributes.length,M=0;M<y;M++){var E=e.attributes[M];s[E.name]=Qe(r,p,E.name,E.value)}if(p==="link"&&a){var C=Array.from(r.styleSheets).find(function(R){return R.href===e.href}),m=null;C&&(m=te(C)),m&&(delete s.rel,delete s.href,s._cssText=$(m,C.href))}if(p==="style"&&e.sheet&&!(e.innerText||e.textContent||"").trim().length){var m=te(e.sheet);m&&(s._cssText=$(m,ie()))}if(p==="input"||p==="textarea"||p==="select"){var P=e.value,_=e.checked;s.type!=="radio"&&s.type!=="checkbox"&&s.type!=="submit"&&s.type!=="button"&&P?s.value=Oe({type:s.type,tagName:p,value:P,maskInputOptions:u,maskInputFn:o}):_&&(s.checked=_)}if(p==="option"&&(e.selected&&!u.select?s.selected=!0:delete s.selected),p==="canvas"&&b){if(e.__context==="2d")Me(e)||(s.rr_dataURL=e.toDataURL(l.type,l.quality));else if(!("__context"in e)){var L=e.toDataURL(l.type,l.quality),A=document.createElement("canvas");A.width=e.width,A.height=e.height;var D=A.toDataURL(l.type,l.quality);L!==D&&(s.rr_dataURL=L)}}if(p==="img"&&h){z||(z=r.createElement("canvas"),fe=z.getContext("2d"));var S=e,N=S.crossOrigin;S.crossOrigin="anonymous";var F=function(){try{z.width=S.naturalWidth,z.height=S.naturalHeight,fe.drawImage(S,0,0),s.rr_dataURL=z.toDataURL(l.type,l.quality)}catch(R){console.warn("Cannot inline img src=".concat(S.currentSrc,"! Error: ").concat(R))}N?s.crossOrigin=N:S.removeAttribute("crossorigin")};S.complete&&S.naturalWidth!==0?F():S.onload=F}if((p==="audio"||p==="video")&&(s.rr_mediaState=e.paused?"paused":"played",s.rr_mediaCurrentTime=e.currentTime),x||(e.scrollLeft&&(s.rr_scrollLeft=e.scrollLeft),e.scrollTop&&(s.rr_scrollTop=e.scrollTop)),T){var U=e.getBoundingClientRect(),W=U.width,O=U.height;s={class:s.class,rr_width:"".concat(W,"px"),rr_height:"".concat(O,"px")}}return p==="iframe"&&!k(s.src)&&(e.contentDocument||(s.rr_src=s.src),delete s.src),{type:v.Element,tagName:p,attributes:s,childNodes:[],isSVG:Ge(e)||void 0,needBlock:T,rootId:I}}function d(e){return e===void 0?"":e.toLowerCase()}function rt(e,t){if(t.comment&&e.type===v.Comment)return!0;if(e.type===v.Element){if(t.script&&(e.tagName==="script"||e.tagName==="link"&&e.attributes.rel==="preload"&&e.attributes.as==="script"||e.tagName==="link"&&e.attributes.rel==="prefetch"&&typeof e.attributes.href=="string"&&e.attributes.href.endsWith(".js")))return!0;if(t.headFavicon&&(e.tagName==="link"&&e.attributes.rel==="shortcut icon"||e.tagName==="meta"&&(d(e.attributes.name).match(/^msapplication-tile(image|color)$/)||d(e.attributes.name)==="application-name"||d(e.attributes.rel)==="icon"||d(e.attributes.rel)==="apple-touch-icon"||d(e.attributes.rel)==="shortcut icon")))return!0;if(e.tagName==="meta"){if(t.headMetaDescKeywords&&d(e.attributes.name).match(/^description|keywords$/))return!0;if(t.headMetaSocial&&(d(e.attributes.property).match(/^(og|twitter|fb):/)||d(e.attributes.name).match(/^(og|twitter):/)||d(e.attributes.name)==="pinterest"))return!0;if(t.headMetaRobots&&(d(e.attributes.name)==="robots"||d(e.attributes.name)==="googlebot"||d(e.attributes.name)==="bingbot"))return!0;if(t.headMetaHttpEquiv&&e.attributes["http-equiv"]!==void 0)return!0;if(t.headMetaAuthorship&&(d(e.attributes.name)==="author"||d(e.attributes.name)==="generator"||d(e.attributes.name)==="framework"||d(e.attributes.name)==="publisher"||d(e.attributes.name)==="progid"||d(e.attributes.property).match(/^article:/)||d(e.attributes.property).match(/^product:/)))return!0;if(t.headMetaVerification&&(d(e.attributes.name)==="google-site-verification"||d(e.attributes.name)==="yandex-verification"||d(e.attributes.name)==="csrf-token"||d(e.attributes.name)==="p:domain_verify"||d(e.attributes.name)==="verify-v1"||d(e.attributes.name)==="verification"||d(e.attributes.name)==="shopify-checkout-api-token"))return!0}}return!1}function Q(e,t){var r=t.doc,i=t.mirror,n=t.blockClass,a=t.blockSelector,c=t.maskTextClass,u=t.maskTextSelector,o=t.skipChild,f=o===void 0?!1:o,l=t.inlineStylesheet,h=l===void 0?!0:l,b=t.maskInputOptions,k=b===void 0?{}:b,w=t.maskTextFn,x=t.maskInputFn,I=t.slimDOMOptions,T=t.dataURLOptions,p=T===void 0?{}:T,s=t.inlineImages,y=s===void 0?!1:s,M=t.recordCanvas,E=M===void 0?!1:M,C=t.onSerialize,m=t.onIframeLoad,P=t.iframeLoadTimeout,_=P===void 0?5e3:P,L=t.onStylesheetLoad,A=t.stylesheetLoadTimeout,D=A===void 0?5e3:A,S=t.keepIframeSrcFn,N=S===void 0?function(){return!1}:S,F=t.newlyAddedElement,U=F===void 0?!1:F,W=t.preserveWhiteSpace,O=W===void 0?!0:W,R=Xe(e,{doc:r,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,inlineStylesheet:h,maskInputOptions:k,maskTextFn:w,maskInputFn:x,dataURLOptions:p,inlineImages:y,recordCanvas:E,keepIframeSrcFn:N,newlyAddedElement:U});if(!R)return console.warn(e,"not serialized"),null;var G;i.hasNode(e)?G=i.getId(e):rt(R,I)||!O&&R.type===v.Text&&!R.isStyle&&!R.textContent.replace(/^\s+|\s+$/gm,"").length?G=ue:G=Fe();var g=Object.assign(R,{id:G});if(i.add(e,g),G===ue)return null;C&&C(e);var J=!f;if(g.type===v.Element){J=J&&!g.needBlock,delete g.needBlock;var ne=e.shadowRoot;ne&&ee(ne)&&(g.isShadowHost=!0)}if((g.type===v.Document||g.type===v.Element)&&J){I.headWhitespace&&g.type===v.Element&&g.tagName==="head"&&(O=!1);for(var ae={doc:r,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,skipChild:f,inlineStylesheet:h,maskInputOptions:k,maskTextFn:w,maskInputFn:x,slimDOMOptions:I,dataURLOptions:p,inlineImages:y,recordCanvas:E,preserveWhiteSpace:O,onSerialize:C,onIframeLoad:m,iframeLoadTimeout:_,onStylesheetLoad:L,stylesheetLoadTimeout:D,keepIframeSrcFn:N},V=0,oe=Array.from(e.childNodes);V<oe.length;V++){var Y=oe[V],K=Q(Y,ae);K&&g.childNodes.push(K)}if(Te(e)&&e.shadowRoot)for(var X=0,se=Array.from(e.shadowRoot.childNodes);X<se.length;X++){var Y=se[X],K=Q(Y,ae);K&&(ee(e.shadowRoot)&&(K.isShadow=!0),g.childNodes.push(K))}}return e.parentNode&&Ee(e.parentNode)&&ee(e.parentNode)&&(g.isShadow=!0),g.type===v.Element&&g.tagName==="iframe"&&Ve(e,function(){var B=e.contentDocument;if(B&&m){var ce=Q(B,{doc:B,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,skipChild:!1,inlineStylesheet:h,maskInputOptions:k,maskTextFn:w,maskInputFn:x,slimDOMOptions:I,dataURLOptions:p,inlineImages:y,recordCanvas:E,preserveWhiteSpace:O,onSerialize:C,onIframeLoad:m,iframeLoadTimeout:_,onStylesheetLoad:L,stylesheetLoadTimeout:D,keepIframeSrcFn:N});ce&&m(e,ce)}},_),g.type===v.Element&&g.tagName==="link"&&g.attributes.rel==="stylesheet"&&Ye(e,function(){if(L){var B=Q(e,{doc:r,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,skipChild:!1,inlineStylesheet:h,maskInputOptions:k,maskTextFn:w,maskInputFn:x,slimDOMOptions:I,dataURLOptions:p,inlineImages:y,recordCanvas:E,preserveWhiteSpace:O,onSerialize:C,onIframeLoad:m,iframeLoadTimeout:_,onStylesheetLoad:L,stylesheetLoadTimeout:D,keepIframeSrcFn:N});B&&L(e,B)}},D),g}function de(e,t){var r=t||{},i=r.mirror,n=i===void 0?new Ne:i,a=r.blockClass,c=a===void 0?"rr-block":a,u=r.blockSelector,o=u===void 0?null:u,f=r.maskTextClass,l=f===void 0?"rr-mask":f,h=r.maskTextSelector,b=h===void 0?null:h,k=r.inlineStylesheet,w=k===void 0?!0:k,x=r.inlineImages,I=x===void 0?!1:x,T=r.recordCanvas,p=T===void 0?!1:T,s=r.maskAllInputs,y=s===void 0?!1:s,M=r.maskTextFn,E=r.maskInputFn,C=r.slimDOM,m=C===void 0?!1:C,P=r.dataURLOptions,_=r.preserveWhiteSpace,L=r.onSerialize,A=r.onIframeLoad,D=r.iframeLoadTimeout,S=r.onStylesheetLoad,N=r.stylesheetLoadTimeout,F=r.keepIframeSrcFn,U=F===void 0?function(){return!1}:F,W=y===!0?{color:!0,date:!0,"datetime-local":!0,email:!0,month:!0,number:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0,textarea:!0,select:!0,password:!0}:y===!1?{password:!0}:y,O=m===!0||m==="all"?{script:!0,comment:!0,headFavicon:!0,headWhitespace:!0,headMetaDescKeywords:m==="all",headMetaSocial:!0,headMetaRobots:!0,headMetaHttpEquiv:!0,headMetaAuthorship:!0,headMetaVerification:!0}:m===!1?{}:m;return Q(e,{doc:e,mirror:n,blockClass:c,blockSelector:o,maskTextClass:l,maskTextSelector:b,skipChild:!1,inlineStylesheet:w,maskInputOptions:W,maskTextFn:M,maskInputFn:E,slimDOMOptions:O,dataURLOptions:P,inlineImages:I,recordCanvas:p,preserveWhiteSpace:_,onSerialize:L,onIframeLoad:A,iframeLoadTimeout:D,onStylesheetLoad:S,stylesheetLoadTimeout:N,keepIframeSrcFn:U,newlyAddedElement:!1})}var it=/([^\\]):hover/,st=new RegExp(it.source,"g");function H(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function pe(){let e="_krypton_sid";try{if(typeof sessionStorage<"u"){let t=sessionStorage.getItem(e);return t||(t=H(),sessionStorage.setItem(e,t)),t}}catch{}return H()}function he(){let e="_krypton_did";try{if(typeof localStorage<"u"){let t=localStorage.getItem(e);return t||(t=H(),localStorage.setItem(e,t)),t}}catch{}return H()}function me(){if(typeof window>"u")return{};let e=new URLSearchParams(window.location.search),t={};for(let r of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let i=e.get(r);i&&(t[r]=i)}return t}function ge(){if(typeof window>"u")return"unknown";let e=window.innerWidth;return e<768?"mobile":e<1024?"tablet":"desktop"}function ve(e){if(e.id)return`#${e.id}`;let t=[],r=e;for(;r&&r!==document.body;){let i=r.tagName.toLowerCase();if(r.id){t.unshift(`#${r.id}`);break}if(r.className&&typeof r.className=="string"){let n=r.className.trim().split(/\s+/).slice(0,2).join(".");n&&(i+=`.${n}`)}t.unshift(i),r=r.parentElement}return t.join(" > ")}var q=class{constructor(t){this.eventQueue=[];this.heatmapQueue=[];this.flushTimer=null;this.initialized=!1;this.lastSnapshotUrl=null;this.heatmapSetup=!1;this.geoRequested=!1;this.geoContext=null;this.serverConfig=null;this.configFetched=!1;this.config={autoPageview:!0,heatmap:!1,consentRequired:!1,showConsentBanner:!1,consentCategories:{},flushInterval:5e3,batchSize:20,...t},this.distinctId=H(),this.sessionId=H(),this.consent=this.resolveInitialConsent(),this.canTrackAnalytics()&&this.promotePersistentIds(),this.init()}init(){this.initialized||(this.initialized=!0,this.fetchConfig().then(()=>{this.setupTracking(),this.config.consentRequired&&this.config.showConsentBanner&&!this.hasStoredConsent()&&this.showConsentBanner()}))}resolveInitialConsent(){let t=this.loadStoredConsent();return t||{...this.config.consentRequired?{analytics:!1,heatmaps:!1,geo:!1}:{analytics:!0,heatmaps:!!this.config.heatmap,geo:!1},...this.config.consentCategories}}consentStorageKey(){return`_krypton_consent_${this.config.apiKey}`}hasStoredConsent(){try{return typeof localStorage>"u"?!1:!!localStorage.getItem(this.consentStorageKey())}catch{return!1}}loadStoredConsent(){try{if(typeof localStorage>"u")return null;let t=localStorage.getItem(this.consentStorageKey());if(!t)return null;let r=JSON.parse(t);return{analytics:!!r.analytics,heatmaps:!!r.heatmaps,geo:!!r.geo}}catch{return null}}persistConsent(){try{if(typeof localStorage>"u")return;localStorage.setItem(this.consentStorageKey(),JSON.stringify(this.consent))}catch{}}promotePersistentIds(){this.distinctId=he(),this.sessionId=pe()}canTrackAnalytics(){return!!this.consent.analytics}isHeatmapFeatureEnabled(){return!this.config.heatmap||this.configFetched&&!this.serverConfig?.heatmaps_enabled?!1:!!this.consent.heatmaps}async fetchConfig(){if(typeof window>"u")return;let t=`_krypton_config_${this.config.apiKey}`,r=null;try{r=sessionStorage.getItem(t)}catch{r=null}if(r)try{let i=JSON.parse(r);if(i._ts&&Date.now()-i._ts<300*1e3){this.serverConfig=i,this.configFetched=!0;return}}catch{}try{let i=await fetch(`${this.config.endpoint}/api/v1/config?api_key=${encodeURIComponent(this.config.apiKey)}`);if(i.ok){let n=await i.json();this.serverConfig=n,this.configFetched=!0;try{sessionStorage.setItem(t,JSON.stringify({...n,_ts:Date.now()}))}catch{}}}catch{}}setupTracking(){if(this.flushTimer=setInterval(()=>this.flush(),this.config.flushInterval),typeof window>"u")return;window.addEventListener("beforeunload",()=>this.flush()),this.config.autoPageview&&this.canTrackAnalytics()&&this.trackPageview();let t=history.pushState;history.pushState=(...i)=>{t.apply(history,i),this.config.autoPageview&&this.canTrackAnalytics()&&setTimeout(()=>this.trackPageview(),0),this.isHeatmapFeatureEnabled()&&setTimeout(()=>this.captureSnapshot(),0)};let r=history.replaceState;history.replaceState=(...i)=>{r.apply(history,i),this.config.autoPageview&&this.canTrackAnalytics()&&setTimeout(()=>this.trackPageview(),0),this.isHeatmapFeatureEnabled()&&setTimeout(()=>this.captureSnapshot(),0)},window.addEventListener("popstate",()=>{this.config.autoPageview&&this.canTrackAnalytics()&&setTimeout(()=>this.trackPageview(),0),this.isHeatmapFeatureEnabled()&&setTimeout(()=>this.captureSnapshot(),0)}),this.isHeatmapFeatureEnabled()&&this.setupHeatmap(),this.consent.geo&&this.captureGeoOnce()}showConsentBanner(){if(typeof document>"u"||document.getElementById("krypton-consent-banner"))return;let t=document.createElement("div");t.id="krypton-consent-banner",t.style.cssText=["position:fixed","left:16px","right:16px","bottom:16px","z-index:2147483647","max-width:720px","margin:0 auto","background:#111827","color:#f9fafb","border-radius:12px","padding:16px","box-shadow:0 12px 30px rgba(0,0,0,0.35)","font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif","font-size:14px","line-height:1.4"].join(";");let r=a=>a?"checked":"";t.innerHTML=`
1
+ "use strict";var KryptonAnalytics=(()=>{var Z=Object.defineProperty;var ke=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var be=Object.prototype.hasOwnProperty;var Ce=(e,t)=>{for(var r in t)Z(e,r,{get:t[r],enumerable:!0})},xe=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Se(t))!be.call(e,n)&&n!==r&&Z(e,n,{get:()=>t[n],enumerable:!(i=ke(t,n))||i.enumerable});return e};var Ie=e=>xe(Z({},"__esModule",{value:!0}),e);var at={};Ce(at,{Krypton:()=>q,default:()=>nt,init:()=>ye});var v;(function(e){e[e.Document=0]="Document",e[e.DocumentType=1]="DocumentType",e[e.Element=2]="Element",e[e.Text=3]="Text",e[e.CDATA=4]="CDATA",e[e.Comment=5]="Comment"})(v||(v={}));function Te(e){return e.nodeType===e.ELEMENT_NODE}function Ee(e){var t=e?.host;return t?.shadowRoot===e}function ee(e){return Object.prototype.toString.call(e)==="[object ShadowRoot]"}function Le(e){return e.includes(" background-clip: text;")&&!e.includes(" -webkit-background-clip: text;")&&(e=e.replace(" background-clip: text;"," -webkit-background-clip: text; background-clip: text;")),e}function te(e){try{var t=e.rules||e.cssRules;return t?Le(Array.from(t).map(Re).join("")):null}catch{return null}}function Re(e){var t=e.cssText;if(_e(e))try{t=te(e.styleSheet)||t}catch{}return t}function _e(e){return"styleSheet"in e}var Ne=(function(){function e(){this.idNodeMap=new Map,this.nodeMetaMap=new WeakMap}return e.prototype.getId=function(t){var r;if(!t)return-1;var i=(r=this.getMeta(t))===null||r===void 0?void 0:r.id;return i??-1},e.prototype.getNode=function(t){return this.idNodeMap.get(t)||null},e.prototype.getIds=function(){return Array.from(this.idNodeMap.keys())},e.prototype.getMeta=function(t){return this.nodeMetaMap.get(t)||null},e.prototype.removeNodeFromMap=function(t){var r=this,i=this.getId(t);this.idNodeMap.delete(i),t.childNodes&&t.childNodes.forEach(function(n){return r.removeNodeFromMap(n)})},e.prototype.has=function(t){return this.idNodeMap.has(t)},e.prototype.hasNode=function(t){return this.nodeMetaMap.has(t)},e.prototype.add=function(t,r){var i=r.id;this.idNodeMap.set(i,t),this.nodeMetaMap.set(t,r)},e.prototype.replace=function(t,r){var i=this.getNode(t);if(i){var n=this.nodeMetaMap.get(i);n&&this.nodeMetaMap.set(r,n)}this.idNodeMap.set(t,r)},e.prototype.reset=function(){this.idNodeMap=new Map,this.nodeMetaMap=new WeakMap},e})();function Oe(e){var t=e.maskInputOptions,r=e.tagName,i=e.type,n=e.value,a=e.maskInputFn,c=n||"";return(t[r.toLowerCase()]||t[i])&&(a?c=a(c):c="*".repeat(c.length)),c}var le="__rrweb_original__";function Ae(e){var t=e.getContext("2d");if(!t)return!0;for(var r=50,i=0;i<e.width;i+=r)for(var n=0;n<e.height;n+=r){var a=t.getImageData,c=le in a?a[le]:a,u=new Uint32Array(c.call(t,i,n,Math.min(r,e.width-i),Math.min(r,e.height-n)).data.buffer);if(u.some(function(o){return o!==0}))return!1}return!0}var Me=1,Pe=new RegExp("[^a-z0-9-_:]"),ue=-2;function De(){return Me++}function Fe(e){if(e instanceof HTMLFormElement)return"form";var t=e.tagName.toLowerCase().trim();return Pe.test(t)?"div":t}function He(e){return e.cssRules?Array.from(e.cssRules).map(function(t){return t.cssText||""}).join(""):""}function Ue(e){var t="";return e.indexOf("//")>-1?t=e.split("/").slice(0,3).join("/"):t=e.split("/")[0],t=t.split("?")[0],t}var z,fe,We=/url\((?:(')([^']*)'|(")(.*?)"|([^)]*))\)/gm,Ke=/^(?!www\.|(?:http|ftp)s?:\/\/|[A-Za-z]:\\|\/\/|#).*/,Be=/^(data:)([^,]*),(.*)/i;function Q(e,t){return(e||"").replace(We,function(r,i,n,a,c,u){var o=n||c||u,f=i||a||"";if(!o)return r;if(!Ke.test(o)||Be.test(o))return"url(".concat(f).concat(o).concat(f,")");if(o[0]==="/")return"url(".concat(f).concat(Ue(t)+o).concat(f,")");var l=t.split("/"),h=o.split("/");l.pop();for(var b=0,w=h;b<w.length;b++){var k=w[b];k!=="."&&(k===".."?l.pop():l.push(k))}return"url(".concat(f).concat(l.join("/")).concat(f,")")})}var ze=/^[^ \t\n\r\u000c]+/,je=/^[, \t\n\r\u000c]+/;function qe(e,t){if(t.trim()==="")return t;var r=0;function i(f){var l,h=f.exec(t.substring(r));return h?(l=h[0],r+=l.length,l):""}for(var n=[];i(je),!(r>=t.length);){var a=i(ze);if(a.slice(-1)===",")a=j(e,a.substring(0,a.length-1)),n.push(a);else{var c="";a=j(e,a);for(var u=!1;;){var o=t.charAt(r);if(o===""){n.push((a+c).trim());break}else if(u)o===")"&&(u=!1);else if(o===","){r+=1,n.push((a+c).trim());break}else o==="("&&(u=!0);c+=o,r+=1}}}return n.join(", ")}function j(e,t){if(!t||t.trim()==="")return t;var r=e.createElement("a");return r.href=t,r.href}function $e(e){return!!(e.tagName==="svg"||e.ownerSVGElement)}function ie(){var e=document.createElement("a");return e.href="",e.href}function Ge(e,t,r,i){return r==="src"||r==="href"&&i&&!(t==="use"&&i[0]==="#")||r==="xlink:href"&&i&&i[0]!=="#"||r==="background"&&i&&(t==="table"||t==="td"||t==="th")?j(e,i):r==="srcset"&&i?qe(e,i):r==="style"&&i?Q(i,ie()):t==="object"&&r==="data"&&i?j(e,i):i}function Qe(e,t,r){if(typeof t=="string"){if(e.classList.contains(t))return!0}else for(var i=e.classList.length;i--;){var n=e.classList[i];if(t.test(n))return!0}return r?e.matches(r):!1}function re(e,t,r){if(!e)return!1;if(e.nodeType!==e.ELEMENT_NODE)return r?re(e.parentNode,t,r):!1;for(var i=e.classList.length;i--;){var n=e.classList[i];if(t.test(n))return!0}return r?re(e.parentNode,t,r):!1}function Je(e,t,r){var i=e.nodeType===e.ELEMENT_NODE?e:e.parentElement;if(i===null)return!1;if(typeof t=="string"){if(i.classList.contains(t)||i.closest(".".concat(t)))return!0}else if(re(i,t,!0))return!0;return!!(r&&(i.matches(r)||i.closest(r)))}function Ve(e,t,r){var i=e.contentWindow;if(i){var n=!1,a;try{a=i.document.readyState}catch{return}if(a!=="complete"){var c=setTimeout(function(){n||(t(),n=!0)},r);e.addEventListener("load",function(){clearTimeout(c),n=!0,t()});return}var u="about:blank";if(i.location.href!==u||e.src===u||e.src==="")return setTimeout(t,0),e.addEventListener("load",t);e.addEventListener("load",t)}}function Ye(e,t,r){var i=!1,n;try{n=e.sheet}catch{return}if(!n){var a=setTimeout(function(){i||(t(),i=!0)},r);e.addEventListener("load",function(){clearTimeout(a),i=!0,t()})}}function Xe(e,t){var r=t.doc,i=t.mirror,n=t.blockClass,a=t.blockSelector,c=t.maskTextClass,u=t.maskTextSelector,o=t.inlineStylesheet,f=t.maskInputOptions,l=f===void 0?{}:f,h=t.maskTextFn,b=t.maskInputFn,w=t.dataURLOptions,k=w===void 0?{}:w,x=t.inlineImages,I=t.recordCanvas,T=t.keepIframeSrcFn,p=t.newlyAddedElement,s=p===void 0?!1:p,y=Ze(r,i);switch(e.nodeType){case e.DOCUMENT_NODE:return e.compatMode!=="CSS1Compat"?{type:v.Document,childNodes:[],compatMode:e.compatMode}:{type:v.Document,childNodes:[]};case e.DOCUMENT_TYPE_NODE:return{type:v.DocumentType,name:e.name,publicId:e.publicId,systemId:e.systemId,rootId:y};case e.ELEMENT_NODE:return tt(e,{doc:r,blockClass:n,blockSelector:a,inlineStylesheet:o,maskInputOptions:l,maskInputFn:b,dataURLOptions:k,inlineImages:x,recordCanvas:I,keepIframeSrcFn:T,newlyAddedElement:s,rootId:y});case e.TEXT_NODE:return et(e,{maskTextClass:c,maskTextSelector:u,maskTextFn:h,rootId:y});case e.CDATA_SECTION_NODE:return{type:v.CDATA,textContent:"",rootId:y};case e.COMMENT_NODE:return{type:v.Comment,textContent:e.textContent||"",rootId:y};default:return!1}}function Ze(e,t){if(t.hasNode(e)){var r=t.getId(e);return r===1?void 0:r}}function et(e,t){var r,i=t.maskTextClass,n=t.maskTextSelector,a=t.maskTextFn,c=t.rootId,u=e.parentNode&&e.parentNode.tagName,o=e.textContent,f=u==="STYLE"?!0:void 0,l=u==="SCRIPT"?!0:void 0;if(f&&o){try{e.nextSibling||e.previousSibling||!((r=e.parentNode.sheet)===null||r===void 0)&&r.cssRules&&(o=He(e.parentNode.sheet))}catch(h){console.warn("Cannot get CSS styles from text's parentNode. Error: ".concat(h),e)}o=Q(o,ie())}return l&&(o="SCRIPT_PLACEHOLDER"),!f&&!l&&o&&Je(e,i,n)&&(o=a?a(o):o.replace(/[\S]/g,"*")),{type:v.Text,textContent:o||"",isStyle:f,rootId:c}}function tt(e,t){for(var r=t.doc,i=t.blockClass,n=t.blockSelector,a=t.inlineStylesheet,c=t.maskInputOptions,u=c===void 0?{}:c,o=t.maskInputFn,f=t.dataURLOptions,l=f===void 0?{}:f,h=t.inlineImages,b=t.recordCanvas,w=t.keepIframeSrcFn,k=t.newlyAddedElement,x=k===void 0?!1:k,I=t.rootId,T=Qe(e,i,n),p=Fe(e),s={},y=e.attributes.length,A=0;A<y;A++){var E=e.attributes[A];s[E.name]=Ge(r,p,E.name,E.value)}if(p==="link"&&a){var C=Array.from(r.styleSheets).find(function(R){return R.href===e.href}),m=null;C&&(m=te(C)),m&&(delete s.rel,delete s.href,s._cssText=Q(m,C.href))}if(p==="style"&&e.sheet&&!(e.innerText||e.textContent||"").trim().length){var m=te(e.sheet);m&&(s._cssText=Q(m,ie()))}if(p==="input"||p==="textarea"||p==="select"){var F=e.value,_=e.checked;s.type!=="radio"&&s.type!=="checkbox"&&s.type!=="submit"&&s.type!=="button"&&F?s.value=Oe({type:s.type,tagName:p,value:F,maskInputOptions:u,maskInputFn:o}):_&&(s.checked=_)}if(p==="option"&&(e.selected&&!u.select?s.selected=!0:delete s.selected),p==="canvas"&&b){if(e.__context==="2d")Ae(e)||(s.rr_dataURL=e.toDataURL(l.type,l.quality));else if(!("__context"in e)){var L=e.toDataURL(l.type,l.quality),M=document.createElement("canvas");M.width=e.width,M.height=e.height;var P=M.toDataURL(l.type,l.quality);L!==P&&(s.rr_dataURL=L)}}if(p==="img"&&h){z||(z=r.createElement("canvas"),fe=z.getContext("2d"));var S=e,N=S.crossOrigin;S.crossOrigin="anonymous";var D=function(){try{z.width=S.naturalWidth,z.height=S.naturalHeight,fe.drawImage(S,0,0),s.rr_dataURL=z.toDataURL(l.type,l.quality)}catch(R){console.warn("Cannot inline img src=".concat(S.currentSrc,"! Error: ").concat(R))}N?s.crossOrigin=N:S.removeAttribute("crossorigin")};S.complete&&S.naturalWidth!==0?D():S.onload=D}if((p==="audio"||p==="video")&&(s.rr_mediaState=e.paused?"paused":"played",s.rr_mediaCurrentTime=e.currentTime),x||(e.scrollLeft&&(s.rr_scrollLeft=e.scrollLeft),e.scrollTop&&(s.rr_scrollTop=e.scrollTop)),T){var U=e.getBoundingClientRect(),W=U.width,O=U.height;s={class:s.class,rr_width:"".concat(W,"px"),rr_height:"".concat(O,"px")}}return p==="iframe"&&!w(s.src)&&(e.contentDocument||(s.rr_src=s.src),delete s.src),{type:v.Element,tagName:p,attributes:s,childNodes:[],isSVG:$e(e)||void 0,needBlock:T,rootId:I}}function d(e){return e===void 0?"":e.toLowerCase()}function rt(e,t){if(t.comment&&e.type===v.Comment)return!0;if(e.type===v.Element){if(t.script&&(e.tagName==="script"||e.tagName==="link"&&e.attributes.rel==="preload"&&e.attributes.as==="script"||e.tagName==="link"&&e.attributes.rel==="prefetch"&&typeof e.attributes.href=="string"&&e.attributes.href.endsWith(".js")))return!0;if(t.headFavicon&&(e.tagName==="link"&&e.attributes.rel==="shortcut icon"||e.tagName==="meta"&&(d(e.attributes.name).match(/^msapplication-tile(image|color)$/)||d(e.attributes.name)==="application-name"||d(e.attributes.rel)==="icon"||d(e.attributes.rel)==="apple-touch-icon"||d(e.attributes.rel)==="shortcut icon")))return!0;if(e.tagName==="meta"){if(t.headMetaDescKeywords&&d(e.attributes.name).match(/^description|keywords$/))return!0;if(t.headMetaSocial&&(d(e.attributes.property).match(/^(og|twitter|fb):/)||d(e.attributes.name).match(/^(og|twitter):/)||d(e.attributes.name)==="pinterest"))return!0;if(t.headMetaRobots&&(d(e.attributes.name)==="robots"||d(e.attributes.name)==="googlebot"||d(e.attributes.name)==="bingbot"))return!0;if(t.headMetaHttpEquiv&&e.attributes["http-equiv"]!==void 0)return!0;if(t.headMetaAuthorship&&(d(e.attributes.name)==="author"||d(e.attributes.name)==="generator"||d(e.attributes.name)==="framework"||d(e.attributes.name)==="publisher"||d(e.attributes.name)==="progid"||d(e.attributes.property).match(/^article:/)||d(e.attributes.property).match(/^product:/)))return!0;if(t.headMetaVerification&&(d(e.attributes.name)==="google-site-verification"||d(e.attributes.name)==="yandex-verification"||d(e.attributes.name)==="csrf-token"||d(e.attributes.name)==="p:domain_verify"||d(e.attributes.name)==="verify-v1"||d(e.attributes.name)==="verification"||d(e.attributes.name)==="shopify-checkout-api-token"))return!0}}return!1}function G(e,t){var r=t.doc,i=t.mirror,n=t.blockClass,a=t.blockSelector,c=t.maskTextClass,u=t.maskTextSelector,o=t.skipChild,f=o===void 0?!1:o,l=t.inlineStylesheet,h=l===void 0?!0:l,b=t.maskInputOptions,w=b===void 0?{}:b,k=t.maskTextFn,x=t.maskInputFn,I=t.slimDOMOptions,T=t.dataURLOptions,p=T===void 0?{}:T,s=t.inlineImages,y=s===void 0?!1:s,A=t.recordCanvas,E=A===void 0?!1:A,C=t.onSerialize,m=t.onIframeLoad,F=t.iframeLoadTimeout,_=F===void 0?5e3:F,L=t.onStylesheetLoad,M=t.stylesheetLoadTimeout,P=M===void 0?5e3:M,S=t.keepIframeSrcFn,N=S===void 0?function(){return!1}:S,D=t.newlyAddedElement,U=D===void 0?!1:D,W=t.preserveWhiteSpace,O=W===void 0?!0:W,R=Xe(e,{doc:r,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,inlineStylesheet:h,maskInputOptions:w,maskTextFn:k,maskInputFn:x,dataURLOptions:p,inlineImages:y,recordCanvas:E,keepIframeSrcFn:N,newlyAddedElement:U});if(!R)return console.warn(e,"not serialized"),null;var $;i.hasNode(e)?$=i.getId(e):rt(R,I)||!O&&R.type===v.Text&&!R.isStyle&&!R.textContent.replace(/^\s+|\s+$/gm,"").length?$=ue:$=De();var g=Object.assign(R,{id:$});if(i.add(e,g),$===ue)return null;C&&C(e);var J=!f;if(g.type===v.Element){J=J&&!g.needBlock,delete g.needBlock;var ne=e.shadowRoot;ne&&ee(ne)&&(g.isShadowHost=!0)}if((g.type===v.Document||g.type===v.Element)&&J){I.headWhitespace&&g.type===v.Element&&g.tagName==="head"&&(O=!1);for(var ae={doc:r,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,skipChild:f,inlineStylesheet:h,maskInputOptions:w,maskTextFn:k,maskInputFn:x,slimDOMOptions:I,dataURLOptions:p,inlineImages:y,recordCanvas:E,preserveWhiteSpace:O,onSerialize:C,onIframeLoad:m,iframeLoadTimeout:_,onStylesheetLoad:L,stylesheetLoadTimeout:P,keepIframeSrcFn:N},V=0,oe=Array.from(e.childNodes);V<oe.length;V++){var Y=oe[V],K=G(Y,ae);K&&g.childNodes.push(K)}if(Te(e)&&e.shadowRoot)for(var X=0,se=Array.from(e.shadowRoot.childNodes);X<se.length;X++){var Y=se[X],K=G(Y,ae);K&&(ee(e.shadowRoot)&&(K.isShadow=!0),g.childNodes.push(K))}}return e.parentNode&&Ee(e.parentNode)&&ee(e.parentNode)&&(g.isShadow=!0),g.type===v.Element&&g.tagName==="iframe"&&Ve(e,function(){var B=e.contentDocument;if(B&&m){var ce=G(B,{doc:B,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,skipChild:!1,inlineStylesheet:h,maskInputOptions:w,maskTextFn:k,maskInputFn:x,slimDOMOptions:I,dataURLOptions:p,inlineImages:y,recordCanvas:E,preserveWhiteSpace:O,onSerialize:C,onIframeLoad:m,iframeLoadTimeout:_,onStylesheetLoad:L,stylesheetLoadTimeout:P,keepIframeSrcFn:N});ce&&m(e,ce)}},_),g.type===v.Element&&g.tagName==="link"&&g.attributes.rel==="stylesheet"&&Ye(e,function(){if(L){var B=G(e,{doc:r,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,skipChild:!1,inlineStylesheet:h,maskInputOptions:w,maskTextFn:k,maskInputFn:x,slimDOMOptions:I,dataURLOptions:p,inlineImages:y,recordCanvas:E,preserveWhiteSpace:O,onSerialize:C,onIframeLoad:m,iframeLoadTimeout:_,onStylesheetLoad:L,stylesheetLoadTimeout:P,keepIframeSrcFn:N});B&&L(e,B)}},P),g}function de(e,t){var r=t||{},i=r.mirror,n=i===void 0?new Ne:i,a=r.blockClass,c=a===void 0?"rr-block":a,u=r.blockSelector,o=u===void 0?null:u,f=r.maskTextClass,l=f===void 0?"rr-mask":f,h=r.maskTextSelector,b=h===void 0?null:h,w=r.inlineStylesheet,k=w===void 0?!0:w,x=r.inlineImages,I=x===void 0?!1:x,T=r.recordCanvas,p=T===void 0?!1:T,s=r.maskAllInputs,y=s===void 0?!1:s,A=r.maskTextFn,E=r.maskInputFn,C=r.slimDOM,m=C===void 0?!1:C,F=r.dataURLOptions,_=r.preserveWhiteSpace,L=r.onSerialize,M=r.onIframeLoad,P=r.iframeLoadTimeout,S=r.onStylesheetLoad,N=r.stylesheetLoadTimeout,D=r.keepIframeSrcFn,U=D===void 0?function(){return!1}:D,W=y===!0?{color:!0,date:!0,"datetime-local":!0,email:!0,month:!0,number:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0,textarea:!0,select:!0,password:!0}:y===!1?{password:!0}:y,O=m===!0||m==="all"?{script:!0,comment:!0,headFavicon:!0,headWhitespace:!0,headMetaDescKeywords:m==="all",headMetaSocial:!0,headMetaRobots:!0,headMetaHttpEquiv:!0,headMetaAuthorship:!0,headMetaVerification:!0}:m===!1?{}:m;return G(e,{doc:e,mirror:n,blockClass:c,blockSelector:o,maskTextClass:l,maskTextSelector:b,skipChild:!1,inlineStylesheet:k,maskInputOptions:W,maskTextFn:A,maskInputFn:E,slimDOMOptions:O,dataURLOptions:F,inlineImages:I,recordCanvas:p,preserveWhiteSpace:_,onSerialize:L,onIframeLoad:M,iframeLoadTimeout:P,onStylesheetLoad:S,stylesheetLoadTimeout:N,keepIframeSrcFn:U,newlyAddedElement:!1})}var it=/([^\\]):hover/,st=new RegExp(it.source,"g");function H(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function pe(){let e="_krypton_sid";try{if(typeof sessionStorage<"u"){let t=sessionStorage.getItem(e);return t||(t=H(),sessionStorage.setItem(e,t)),t}}catch{}return H()}function he(){let e="_krypton_did";try{if(typeof localStorage<"u"){let t=localStorage.getItem(e);return t||(t=H(),localStorage.setItem(e,t)),t}}catch{}return H()}function me(){if(typeof window>"u")return{};let e=new URLSearchParams(window.location.search),t={};for(let r of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let i=e.get(r);i&&(t[r]=i)}return t}function ge(){if(typeof window>"u")return"unknown";let e=window.innerWidth;return e<768?"mobile":e<1024?"tablet":"desktop"}function ve(e){if(e.id)return`#${e.id}`;let t=[],r=e;for(;r&&r!==document.body;){let i=r.tagName.toLowerCase();if(r.id){t.unshift(`#${r.id}`);break}if(r.className&&typeof r.className=="string"){let n=r.className.trim().split(/\s+/).slice(0,2).join(".");n&&(i+=`.${n}`)}t.unshift(i),r=r.parentElement}return t.join(" > ")}var q=class{constructor(t){this.eventQueue=[];this.heatmapQueue=[];this.flushTimer=null;this.initialized=!1;this.lastSnapshotUrl=null;this.heatmapSetup=!1;this.geoRequested=!1;this.geoContext=null;this.serverConfig=null;this.configFetched=!1;this.logPrefix="[Krypton SDK]";this.config={autoPageview:!0,heatmap:!1,consentRequired:!1,showConsentBanner:!1,consentCategories:{},flushInterval:5e3,batchSize:20,...t},this.distinctId=H(),this.sessionId=H(),this.consent=this.resolveInitialConsent(),this.canTrackAnalytics()&&this.promotePersistentIds(),this.init()}init(){this.initialized||(this.initialized=!0,this.fetchConfig().finally(()=>{this.setupTracking(),this.config.consentRequired&&this.config.showConsentBanner&&!this.hasStoredConsent()&&this.showConsentBanner()}))}resolveInitialConsent(){let t=this.loadStoredConsent();return t||{...this.config.consentRequired?{analytics:!1,heatmaps:!1,geo:!1}:{analytics:!0,heatmaps:!!this.config.heatmap,geo:!1},...this.config.consentCategories}}consentStorageKey(){return`_krypton_consent_${this.config.apiKey}`}hasStoredConsent(){try{return typeof localStorage>"u"?!1:!!localStorage.getItem(this.consentStorageKey())}catch{return!1}}loadStoredConsent(){try{if(typeof localStorage>"u")return null;let t=localStorage.getItem(this.consentStorageKey());if(!t)return null;let r=JSON.parse(t);return{analytics:!!r.analytics,heatmaps:!!r.heatmaps,geo:!!r.geo}}catch{return null}}persistConsent(){try{if(typeof localStorage>"u")return;localStorage.setItem(this.consentStorageKey(),JSON.stringify(this.consent))}catch{}}promotePersistentIds(){this.distinctId=he(),this.sessionId=pe()}canTrackAnalytics(){return!!this.consent.analytics}isHeatmapFeatureEnabled(){return!this.config.heatmap||this.configFetched&&!this.serverConfig?.heatmaps_enabled?!1:!!this.consent.heatmaps}async fetchConfig(){if(typeof window>"u")return;let t=`_krypton_config_${this.config.apiKey}`,r=null;try{r=sessionStorage.getItem(t)}catch{r=null}if(r)try{let i=JSON.parse(r);if(i._ts&&Date.now()-i._ts<300*1e3){this.serverConfig=i,this.configFetched=!0;return}}catch{}try{let i=new AbortController,n=setTimeout(()=>i.abort(),5e3),a=await fetch(`${this.config.endpoint}/api/v1/config?api_key=${encodeURIComponent(this.config.apiKey)}`,{signal:i.signal});if(clearTimeout(n),a.ok){let c=await a.json();this.serverConfig=c,this.configFetched=!0;try{sessionStorage.setItem(t,JSON.stringify({...c,_ts:Date.now()}))}catch{}}}catch{}}setupTracking(){if(this.flushTimer=setInterval(()=>{this.flush()},this.config.flushInterval),typeof window>"u")return;window.addEventListener("beforeunload",()=>{this.flush()}),this.config.autoPageview&&this.canTrackAnalytics()&&this.trackPageview();let t=history.pushState;history.pushState=(...i)=>{try{t.apply(history,i),this.config.autoPageview&&this.canTrackAnalytics()&&setTimeout(()=>this.trackPageview(),0),this.isHeatmapFeatureEnabled()&&setTimeout(()=>this.captureSnapshot(),0)}catch(n){this.warn("pushState hook failed",n)}};let r=history.replaceState;history.replaceState=(...i)=>{try{r.apply(history,i),this.config.autoPageview&&this.canTrackAnalytics()&&setTimeout(()=>this.trackPageview(),0),this.isHeatmapFeatureEnabled()&&setTimeout(()=>this.captureSnapshot(),0)}catch(n){this.warn("replaceState hook failed",n)}},window.addEventListener("popstate",()=>{try{this.config.autoPageview&&this.canTrackAnalytics()&&setTimeout(()=>this.trackPageview(),0),this.isHeatmapFeatureEnabled()&&setTimeout(()=>this.captureSnapshot(),0)}catch(i){this.warn("popstate hook failed",i)}}),this.isHeatmapFeatureEnabled()&&this.setupHeatmap(),this.consent.geo&&this.captureGeoOnce()}showConsentBanner(){if(typeof document>"u"||document.getElementById("krypton-consent-banner"))return;let t=document.createElement("div");t.id="krypton-consent-banner",t.style.cssText=["position:fixed","left:16px","right:16px","bottom:16px","z-index:2147483647","max-width:720px","margin:0 auto","background:#111827","color:#f9fafb","border-radius:12px","padding:16px","box-shadow:0 12px 30px rgba(0,0,0,0.35)","font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif","font-size:14px","line-height:1.4"].join(";");let r=a=>a?"checked":"";t.innerHTML=`
2
2
  <div style="font-weight:600;margin-bottom:6px">Privacy preferences</div>
3
3
  <div style="opacity:0.9;margin-bottom:10px">Choose what data you allow us to collect.</div>
4
4
  <label style="display:flex;gap:8px;align-items:flex-start;margin:6px 0">
@@ -18,4 +18,4 @@
18
18
  <button id="krypton-consent-all" style="border:0;background:#16a34a;color:#fff;padding:8px 12px;border-radius:8px;cursor:pointer">Accept all</button>
19
19
  <button id="krypton-consent-none" style="border:1px solid #4b5563;background:transparent;color:#f9fafb;padding:8px 12px;border-radius:8px;cursor:pointer">Reject all</button>
20
20
  </div>
21
- `;let i=()=>{t.remove()},n=a=>!!document.getElementById(a)?.checked;t.querySelector("#krypton-consent-save")?.addEventListener("click",()=>{this.setConsent({analytics:n("krypton-consent-analytics"),heatmaps:n("krypton-consent-heatmaps"),geo:n("krypton-consent-geo")}),i()}),t.querySelector("#krypton-consent-all")?.addEventListener("click",()=>{this.setConsent({analytics:!0,heatmaps:!0,geo:!0}),i()}),t.querySelector("#krypton-consent-none")?.addEventListener("click",()=>{this.setConsent({analytics:!1,heatmaps:!1,geo:!1}),i()}),document.body.appendChild(t)}setConsent(t,r=!0){let i={...this.consent};this.consent={analytics:t.analytics??i.analytics,heatmaps:t.heatmaps??i.heatmaps,geo:t.geo??i.geo},r&&this.persistConsent(),!i.analytics&&this.consent.analytics&&(this.promotePersistentIds(),this.config.autoPageview&&this.trackPageview()),i.analytics&&!this.consent.analytics&&(this.eventQueue=[]),!i.heatmaps&&this.isHeatmapFeatureEnabled()&&(this.setupHeatmap(),this.captureSnapshot()),i.heatmaps&&!this.consent.heatmaps&&(this.heatmapQueue=[]),!i.geo&&this.consent.geo&&this.captureGeoOnce()}getConsent(){return{...this.consent}}grantConsent(){this.setConsent({analytics:!0,heatmaps:!0,geo:!0})}revokeConsent(){this.setConsent({analytics:!1,heatmaps:!1,geo:!1}),this.eventQueue=[],this.heatmapQueue=[]}identify(t){if(this.distinctId=t,this.canTrackAnalytics())try{typeof localStorage<"u"&&localStorage.setItem("_krypton_did",t)}catch{}}trackPageview(t){this.canTrackAnalytics()&&this.track("$pageview",{...t})}track(t,r){if(!this.canTrackAnalytics())return;let i=me(),n={...r||{}};this.consent.geo&&this.geoContext&&(n.geo=this.geoContext);let a={project_id:this.config.apiKey,distinct_id:this.distinctId,event_name:t,timestamp:new Date().toISOString(),properties:n,page_url:typeof window<"u"?window.location.href:"",page_title:typeof document<"u"?document.title:"",referrer:typeof document<"u"?document.referrer:"",utm_source:i.utm_source||"",utm_medium:i.utm_medium||"",utm_campaign:i.utm_campaign||"",utm_term:i.utm_term||"",utm_content:i.utm_content||"",device_type:ge(),browser:this.getBrowser(),screen_width:typeof window<"u"?window.screen.width:0,screen_height:typeof window<"u"?window.screen.height:0,session_id:this.sessionId};this.eventQueue.push(a),this.eventQueue.length>=this.config.batchSize&&this.flush()}async flush(){await Promise.all([this.flushEvents(),this.flushHeatmapEvents()])}shutdown(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.flush()}captureGeoOnce(){this.geoRequested||this.consent.geo&&(typeof navigator>"u"||!navigator.geolocation||(this.geoRequested=!0,navigator.geolocation.getCurrentPosition(t=>{let r=(i,n=3)=>Number(i.toFixed(n));this.geoContext={lat:r(t.coords.latitude),lon:r(t.coords.longitude),accuracy_m:Math.round(t.coords.accuracy),captured_at:new Date().toISOString()}},()=>{},{enableHighAccuracy:!1,maximumAge:600*1e3,timeout:5e3})))}async flushEvents(){if(this.eventQueue.length===0)return;let t=this.eventQueue.splice(0,this.eventQueue.length),r={api_key:this.config.apiKey,events:t};try{await fetch(`${this.config.endpoint}/api/v1/ingest/batch`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),keepalive:!0})}catch{this.eventQueue.length<this.config.batchSize*5&&this.eventQueue.unshift(...t)}}async flushHeatmapEvents(){if(this.heatmapQueue.length===0)return;let t=this.heatmapQueue.splice(0,this.heatmapQueue.length),r={api_key:this.config.apiKey,events:t};try{await fetch(`${this.config.endpoint}/api/v1/heatmap`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),keepalive:!0})}catch{this.heatmapQueue.length<this.config.batchSize*5&&this.heatmapQueue.unshift(...t)}}captureSnapshot(){if(typeof window>"u"||typeof document>"u"||!this.isHeatmapFeatureEnabled())return;let t=window.location.href;this.lastSnapshotUrl!==t&&(this.lastSnapshotUrl=t,setTimeout(()=>{try{let r=de(document,{maskAllInputs:!0,blockSelector:"[data-krypton-block]",inlineStylesheet:!0});if(!r)return;let i=JSON.stringify(r),n={api_key:this.config.apiKey,page_url:t,snapshot:i,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_width:document.documentElement.scrollWidth,page_height:document.documentElement.scrollHeight,timestamp:new Date().toISOString()};fetch(`${this.config.endpoint}/api/v1/snapshot`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),keepalive:!0}).catch(()=>{})}catch{}},1e3))}setupHeatmap(){if(typeof window>"u"||this.heatmapSetup)return;this.heatmapSetup=!0,this.captureSnapshot(),document.addEventListener("click",i=>{if(!this.isHeatmapFeatureEnabled())return;let n=i.target;this.heatmapQueue.push({project_id:this.config.apiKey,distinct_id:this.distinctId,session_id:this.sessionId,timestamp:new Date().toISOString(),page_url:window.location.href,interaction_type:"click",x:i.clientX+window.scrollX,y:i.clientY+window.scrollY,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_width:document.documentElement.scrollWidth,page_height:document.documentElement.scrollHeight,selector:ve(n)})});let t=0,r=null;window.addEventListener("scroll",()=>{if(!this.isHeatmapFeatureEnabled())return;let i=window.scrollY||document.documentElement.scrollTop,n=document.documentElement.scrollHeight-window.innerHeight,a=n>0?i/n*100:0;a>t&&(t=a),r&&clearTimeout(r),r=setTimeout(()=>{this.heatmapQueue.push({project_id:this.config.apiKey,distinct_id:this.distinctId,session_id:this.sessionId,timestamp:new Date().toISOString(),page_url:window.location.href,interaction_type:"scroll",scroll_depth:t,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_width:document.documentElement.scrollWidth,page_height:document.documentElement.scrollHeight})},500)})}getBrowser(){if(typeof navigator>"u")return"unknown";let t=navigator.userAgent;return t.includes("Firefox")?"Firefox":t.includes("Edg")?"Edge":t.includes("Chrome")?"Chrome":t.includes("Safari")?"Safari":"Other"}};function ye(e){return new q(e)}var ke={Krypton:q,init:ye};typeof window<"u"&&(window.KryptonAnalytics=ke);var nt=ke;return Ie(at);})();
21
+ `;let i=()=>{t.remove();try{document.body&&(document.body.style.cursor=""),document.documentElement&&(document.documentElement.style.cursor="")}catch{}},n=a=>!!document.getElementById(a)?.checked;t.querySelector("#krypton-consent-save")?.addEventListener("click",()=>{let a={analytics:n("krypton-consent-analytics"),heatmaps:n("krypton-consent-heatmaps"),geo:n("krypton-consent-geo")};i(),setTimeout(()=>this.setConsent(a),0)}),t.querySelector("#krypton-consent-all")?.addEventListener("click",()=>{i(),setTimeout(()=>this.setConsent({analytics:!0,heatmaps:!0,geo:!0}),0)}),t.querySelector("#krypton-consent-none")?.addEventListener("click",()=>{i(),setTimeout(()=>this.setConsent({analytics:!1,heatmaps:!1,geo:!1}),0)}),document.body.appendChild(t)}setConsent(t,r=!0){try{let i={...this.consent};this.consent={analytics:t.analytics??i.analytics,heatmaps:t.heatmaps??i.heatmaps,geo:t.geo??i.geo},r&&this.persistConsent(),!i.analytics&&this.consent.analytics&&(this.promotePersistentIds(),this.config.autoPageview&&this.trackPageview()),i.analytics&&!this.consent.analytics&&(this.eventQueue=[]),!i.heatmaps&&this.isHeatmapFeatureEnabled()&&(this.setupHeatmap(),this.captureSnapshot()),i.heatmaps&&!this.consent.heatmaps&&(this.heatmapQueue=[]),!i.geo&&this.consent.geo&&this.captureGeoOnce()}catch(i){this.warn("setConsent failed",i)}}getConsent(){return{...this.consent}}grantConsent(){this.setConsent({analytics:!0,heatmaps:!0,geo:!0})}revokeConsent(){this.setConsent({analytics:!1,heatmaps:!1,geo:!1}),this.eventQueue=[],this.heatmapQueue=[]}identify(t){try{if(this.distinctId=t,this.canTrackAnalytics())try{typeof localStorage<"u"&&localStorage.setItem("_krypton_did",t)}catch{}}catch(r){this.warn("identify failed",r)}}trackPageview(t){try{if(!this.canTrackAnalytics())return;this.track("$pageview",{...t})}catch(r){this.warn("trackPageview failed",r)}}track(t,r){try{if(!this.canTrackAnalytics())return;let i=me(),n={...r||{}};this.consent.geo&&this.geoContext&&(n.geo=this.geoContext);let a={project_id:this.config.apiKey,distinct_id:this.distinctId,event_name:t,timestamp:new Date().toISOString(),properties:n,page_url:typeof window<"u"?window.location.href:"",page_title:typeof document<"u"?document.title:"",referrer:typeof document<"u"?document.referrer:"",utm_source:i.utm_source||"",utm_medium:i.utm_medium||"",utm_campaign:i.utm_campaign||"",utm_term:i.utm_term||"",utm_content:i.utm_content||"",device_type:ge(),browser:this.getBrowser(),screen_width:typeof window<"u"?window.screen.width:0,screen_height:typeof window<"u"?window.screen.height:0,session_id:this.sessionId};this.eventQueue.push(a),this.eventQueue.length>=this.config.batchSize&&this.flush()}catch(i){this.warn("track failed",i)}}async flush(){try{await Promise.all([this.flushEvents(),this.flushHeatmapEvents()])}catch(t){this.warn("flush failed",t)}}shutdown(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.flush()}captureGeoOnce(){this.geoRequested||this.consent.geo&&(typeof navigator>"u"||!navigator.geolocation||(this.geoRequested=!0,navigator.geolocation.getCurrentPosition(t=>{let r=(i,n=3)=>Number(i.toFixed(n));this.geoContext={lat:r(t.coords.latitude),lon:r(t.coords.longitude),accuracy_m:Math.round(t.coords.accuracy),captured_at:new Date().toISOString()}},()=>{},{enableHighAccuracy:!1,maximumAge:600*1e3,timeout:5e3})))}async flushEvents(){if(this.eventQueue.length===0)return;let t=this.eventQueue.splice(0,this.eventQueue.length),r={api_key:this.config.apiKey,events:t};await this.safePost(`${this.config.endpoint}/api/v1/ingest/batch`,r)||this.eventQueue.length<this.config.batchSize*5&&this.eventQueue.unshift(...t)}async flushHeatmapEvents(){if(this.heatmapQueue.length===0)return;let t=this.heatmapQueue.splice(0,this.heatmapQueue.length),r={api_key:this.config.apiKey,events:t};await this.safePost(`${this.config.endpoint}/api/v1/heatmap`,r)||this.heatmapQueue.length<this.config.batchSize*5&&this.heatmapQueue.unshift(...t)}captureSnapshot(){if(typeof window>"u"||typeof document>"u"||!this.isHeatmapFeatureEnabled())return;let t=window.location.href;this.lastSnapshotUrl!==t&&(this.lastSnapshotUrl=t,setTimeout(()=>{try{let r=de(document,{maskAllInputs:!0,blockSelector:"[data-krypton-block]",inlineStylesheet:!0});if(!r)return;let i=JSON.stringify(r),n={api_key:this.config.apiKey,page_url:t,snapshot:i,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_width:document.documentElement.scrollWidth,page_height:document.documentElement.scrollHeight,timestamp:new Date().toISOString()};this.safePost(`${this.config.endpoint}/api/v1/snapshot`,n)}catch{}},1e3))}setupHeatmap(){if(typeof window>"u"||this.heatmapSetup)return;this.heatmapSetup=!0,this.captureSnapshot(),document.addEventListener("click",i=>{if(this.isHeatmapFeatureEnabled())try{let n=i.target;this.heatmapQueue.push({project_id:this.config.apiKey,distinct_id:this.distinctId,session_id:this.sessionId,timestamp:new Date().toISOString(),page_url:window.location.href,interaction_type:"click",x:i.clientX+window.scrollX,y:i.clientY+window.scrollY,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_width:document.documentElement.scrollWidth,page_height:document.documentElement.scrollHeight,selector:ve(n)})}catch(n){this.warn("heatmap click capture failed",n)}});let t=0,r=null;window.addEventListener("scroll",()=>{if(this.isHeatmapFeatureEnabled())try{let i=window.scrollY||document.documentElement.scrollTop,n=document.documentElement.scrollHeight-window.innerHeight,a=n>0?i/n*100:0;a>t&&(t=a),r&&clearTimeout(r),r=setTimeout(()=>{this.heatmapQueue.push({project_id:this.config.apiKey,distinct_id:this.distinctId,session_id:this.sessionId,timestamp:new Date().toISOString(),page_url:window.location.href,interaction_type:"scroll",scroll_depth:t,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_width:document.documentElement.scrollWidth,page_height:document.documentElement.scrollHeight})},500)}catch(i){this.warn("heatmap scroll capture failed",i)}})}async safePost(t,r){try{let i=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),keepalive:!0});return i.ok?!0:(this.warn(`API request failed (${i.status})`,{url:t}),!1)}catch(i){return this.warn("API request failed",{url:t,err:i}),!1}}warn(t,r){try{console.warn(`${this.logPrefix} ${t}`,r??"")}catch{}}getBrowser(){if(typeof navigator>"u")return"unknown";let t=navigator.userAgent;return t.includes("Firefox")?"Firefox":t.includes("Edg")?"Edge":t.includes("Chrome")?"Chrome":t.includes("Safari")?"Safari":"Other"}};function ye(e){return new q(e)}var we={Krypton:q,init:ye};typeof window<"u"&&(window.KryptonAnalytics=we);var nt=we;return Ie(at);})();
package/dist/index.d.mts CHANGED
@@ -79,6 +79,7 @@ declare class Krypton {
79
79
  private consent;
80
80
  private serverConfig;
81
81
  private configFetched;
82
+ private readonly logPrefix;
82
83
  constructor(config: KryptonConfig);
83
84
  private init;
84
85
  private resolveInitialConsent;
@@ -113,6 +114,8 @@ declare class Krypton {
113
114
  private flushHeatmapEvents;
114
115
  private captureSnapshot;
115
116
  private setupHeatmap;
117
+ private safePost;
118
+ private warn;
116
119
  private getBrowser;
117
120
  }
118
121
  declare function createKrypton(config: KryptonConfig): Krypton;
package/dist/index.d.ts CHANGED
@@ -79,6 +79,7 @@ declare class Krypton {
79
79
  private consent;
80
80
  private serverConfig;
81
81
  private configFetched;
82
+ private readonly logPrefix;
82
83
  constructor(config: KryptonConfig);
83
84
  private init;
84
85
  private resolveInitialConsent;
@@ -113,6 +114,8 @@ declare class Krypton {
113
114
  private flushHeatmapEvents;
114
115
  private captureSnapshot;
115
116
  private setupHeatmap;
117
+ private safePost;
118
+ private warn;
116
119
  private getBrowser;
117
120
  }
118
121
  declare function createKrypton(config: KryptonConfig): Krypton;
package/dist/index.js CHANGED
@@ -117,6 +117,7 @@ var Krypton = class {
117
117
  this.geoContext = null;
118
118
  this.serverConfig = null;
119
119
  this.configFetched = false;
120
+ this.logPrefix = "[Krypton SDK]";
120
121
  this.config = {
121
122
  autoPageview: true,
122
123
  heatmap: false,
@@ -138,7 +139,7 @@ var Krypton = class {
138
139
  init() {
139
140
  if (this.initialized) return;
140
141
  this.initialized = true;
141
- this.fetchConfig().then(() => {
142
+ this.fetchConfig().finally(() => {
142
143
  this.setupTracking();
143
144
  if (this.config.consentRequired && this.config.showConsentBanner && !this.hasStoredConsent()) {
144
145
  this.showConsentBanner();
@@ -224,9 +225,13 @@ var Krypton = class {
224
225
  }
225
226
  }
226
227
  try {
228
+ const controller = new AbortController();
229
+ const timeout = setTimeout(() => controller.abort(), 5e3);
227
230
  const res = await fetch(
228
- `${this.config.endpoint}/api/v1/config?api_key=${encodeURIComponent(this.config.apiKey)}`
231
+ `${this.config.endpoint}/api/v1/config?api_key=${encodeURIComponent(this.config.apiKey)}`,
232
+ { signal: controller.signal }
229
233
  );
234
+ clearTimeout(timeout);
230
235
  if (res.ok) {
231
236
  const data = await res.json();
232
237
  this.serverConfig = data;
@@ -240,38 +245,54 @@ var Krypton = class {
240
245
  }
241
246
  }
242
247
  setupTracking() {
243
- this.flushTimer = setInterval(() => this.flush(), this.config.flushInterval);
248
+ this.flushTimer = setInterval(() => {
249
+ void this.flush();
250
+ }, this.config.flushInterval);
244
251
  if (typeof window === "undefined") return;
245
- window.addEventListener("beforeunload", () => this.flush());
252
+ window.addEventListener("beforeunload", () => {
253
+ void this.flush();
254
+ });
246
255
  if (this.config.autoPageview && this.canTrackAnalytics()) {
247
256
  this.trackPageview();
248
257
  }
249
258
  const originalPushState = history.pushState;
250
259
  history.pushState = (...args) => {
251
- originalPushState.apply(history, args);
252
- if (this.config.autoPageview && this.canTrackAnalytics()) {
253
- setTimeout(() => this.trackPageview(), 0);
254
- }
255
- if (this.isHeatmapFeatureEnabled()) {
256
- setTimeout(() => this.captureSnapshot(), 0);
260
+ try {
261
+ originalPushState.apply(history, args);
262
+ if (this.config.autoPageview && this.canTrackAnalytics()) {
263
+ setTimeout(() => this.trackPageview(), 0);
264
+ }
265
+ if (this.isHeatmapFeatureEnabled()) {
266
+ setTimeout(() => this.captureSnapshot(), 0);
267
+ }
268
+ } catch (err) {
269
+ this.warn("pushState hook failed", err);
257
270
  }
258
271
  };
259
272
  const originalReplaceState = history.replaceState;
260
273
  history.replaceState = (...args) => {
261
- originalReplaceState.apply(history, args);
262
- if (this.config.autoPageview && this.canTrackAnalytics()) {
263
- setTimeout(() => this.trackPageview(), 0);
264
- }
265
- if (this.isHeatmapFeatureEnabled()) {
266
- setTimeout(() => this.captureSnapshot(), 0);
274
+ try {
275
+ originalReplaceState.apply(history, args);
276
+ if (this.config.autoPageview && this.canTrackAnalytics()) {
277
+ setTimeout(() => this.trackPageview(), 0);
278
+ }
279
+ if (this.isHeatmapFeatureEnabled()) {
280
+ setTimeout(() => this.captureSnapshot(), 0);
281
+ }
282
+ } catch (err) {
283
+ this.warn("replaceState hook failed", err);
267
284
  }
268
285
  };
269
286
  window.addEventListener("popstate", () => {
270
- if (this.config.autoPageview && this.canTrackAnalytics()) {
271
- setTimeout(() => this.trackPageview(), 0);
272
- }
273
- if (this.isHeatmapFeatureEnabled()) {
274
- setTimeout(() => this.captureSnapshot(), 0);
287
+ try {
288
+ if (this.config.autoPageview && this.canTrackAnalytics()) {
289
+ setTimeout(() => this.trackPageview(), 0);
290
+ }
291
+ if (this.isHeatmapFeatureEnabled()) {
292
+ setTimeout(() => this.captureSnapshot(), 0);
293
+ }
294
+ } catch (err) {
295
+ this.warn("popstate hook failed", err);
275
296
  }
276
297
  });
277
298
  if (this.isHeatmapFeatureEnabled()) {
@@ -328,58 +349,68 @@ var Krypton = class {
328
349
  `;
329
350
  const remove = () => {
330
351
  banner.remove();
352
+ try {
353
+ if (document.body) document.body.style.cursor = "";
354
+ if (document.documentElement) document.documentElement.style.cursor = "";
355
+ } catch {
356
+ }
331
357
  };
332
358
  const readValue = (id) => {
333
359
  const el = document.getElementById(id);
334
360
  return !!el?.checked;
335
361
  };
336
362
  banner.querySelector("#krypton-consent-save")?.addEventListener("click", () => {
337
- this.setConsent({
363
+ const next = {
338
364
  analytics: readValue("krypton-consent-analytics"),
339
365
  heatmaps: readValue("krypton-consent-heatmaps"),
340
366
  geo: readValue("krypton-consent-geo")
341
- });
367
+ };
342
368
  remove();
369
+ setTimeout(() => this.setConsent(next), 0);
343
370
  });
344
371
  banner.querySelector("#krypton-consent-all")?.addEventListener("click", () => {
345
- this.setConsent({ analytics: true, heatmaps: true, geo: true });
346
372
  remove();
373
+ setTimeout(() => this.setConsent({ analytics: true, heatmaps: true, geo: true }), 0);
347
374
  });
348
375
  banner.querySelector("#krypton-consent-none")?.addEventListener("click", () => {
349
- this.setConsent({ analytics: false, heatmaps: false, geo: false });
350
376
  remove();
377
+ setTimeout(() => this.setConsent({ analytics: false, heatmaps: false, geo: false }), 0);
351
378
  });
352
379
  document.body.appendChild(banner);
353
380
  }
354
381
  /** Set one or more consent categories and apply changes immediately. */
355
382
  setConsent(next, persist = true) {
356
- const prev = { ...this.consent };
357
- this.consent = {
358
- analytics: next.analytics ?? prev.analytics,
359
- heatmaps: next.heatmaps ?? prev.heatmaps,
360
- geo: next.geo ?? prev.geo
361
- };
362
- if (persist) {
363
- this.persistConsent();
364
- }
365
- if (!prev.analytics && this.consent.analytics) {
366
- this.promotePersistentIds();
367
- if (this.config.autoPageview) {
368
- this.trackPageview();
383
+ try {
384
+ const prev = { ...this.consent };
385
+ this.consent = {
386
+ analytics: next.analytics ?? prev.analytics,
387
+ heatmaps: next.heatmaps ?? prev.heatmaps,
388
+ geo: next.geo ?? prev.geo
389
+ };
390
+ if (persist) {
391
+ this.persistConsent();
369
392
  }
370
- }
371
- if (prev.analytics && !this.consent.analytics) {
372
- this.eventQueue = [];
373
- }
374
- if (!prev.heatmaps && this.isHeatmapFeatureEnabled()) {
375
- this.setupHeatmap();
376
- this.captureSnapshot();
377
- }
378
- if (prev.heatmaps && !this.consent.heatmaps) {
379
- this.heatmapQueue = [];
380
- }
381
- if (!prev.geo && this.consent.geo) {
382
- this.captureGeoOnce();
393
+ if (!prev.analytics && this.consent.analytics) {
394
+ this.promotePersistentIds();
395
+ if (this.config.autoPageview) {
396
+ this.trackPageview();
397
+ }
398
+ }
399
+ if (prev.analytics && !this.consent.analytics) {
400
+ this.eventQueue = [];
401
+ }
402
+ if (!prev.heatmaps && this.isHeatmapFeatureEnabled()) {
403
+ this.setupHeatmap();
404
+ this.captureSnapshot();
405
+ }
406
+ if (prev.heatmaps && !this.consent.heatmaps) {
407
+ this.heatmapQueue = [];
408
+ }
409
+ if (!prev.geo && this.consent.geo) {
410
+ this.captureGeoOnce();
411
+ }
412
+ } catch (err) {
413
+ this.warn("setConsent failed", err);
383
414
  }
384
415
  }
385
416
  getConsent() {
@@ -397,65 +428,81 @@ var Krypton = class {
397
428
  }
398
429
  /** Identify a user with a custom distinct ID */
399
430
  identify(distinctId) {
400
- this.distinctId = distinctId;
401
- if (this.canTrackAnalytics()) {
402
- try {
403
- if (typeof localStorage !== "undefined") {
404
- localStorage.setItem("_krypton_did", distinctId);
431
+ try {
432
+ this.distinctId = distinctId;
433
+ if (this.canTrackAnalytics()) {
434
+ try {
435
+ if (typeof localStorage !== "undefined") {
436
+ localStorage.setItem("_krypton_did", distinctId);
437
+ }
438
+ } catch {
405
439
  }
406
- } catch {
407
440
  }
441
+ } catch (err) {
442
+ this.warn("identify failed", err);
408
443
  }
409
444
  }
410
445
  /** Track a pageview */
411
446
  trackPageview(properties) {
412
- if (!this.canTrackAnalytics()) return;
413
- this.track("$pageview", {
414
- ...properties
415
- });
447
+ try {
448
+ if (!this.canTrackAnalytics()) return;
449
+ this.track("$pageview", {
450
+ ...properties
451
+ });
452
+ } catch (err) {
453
+ this.warn("trackPageview failed", err);
454
+ }
416
455
  }
417
456
  /** Track a custom event */
418
457
  track(eventName, properties) {
419
- if (!this.canTrackAnalytics()) return;
420
- const utm = getUTMParams();
421
- const mergedProperties = { ...properties || {} };
422
- if (this.consent.geo && this.geoContext) {
423
- mergedProperties.geo = this.geoContext;
424
- }
425
- const event = {
426
- project_id: this.config.apiKey,
427
- distinct_id: this.distinctId,
428
- event_name: eventName,
429
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
430
- properties: mergedProperties,
431
- page_url: typeof window !== "undefined" ? window.location.href : "",
432
- page_title: typeof document !== "undefined" ? document.title : "",
433
- referrer: typeof document !== "undefined" ? document.referrer : "",
434
- utm_source: utm.utm_source || "",
435
- utm_medium: utm.utm_medium || "",
436
- utm_campaign: utm.utm_campaign || "",
437
- utm_term: utm.utm_term || "",
438
- utm_content: utm.utm_content || "",
439
- device_type: getDeviceType(),
440
- browser: this.getBrowser(),
441
- screen_width: typeof window !== "undefined" ? window.screen.width : 0,
442
- screen_height: typeof window !== "undefined" ? window.screen.height : 0,
443
- session_id: this.sessionId
444
- };
445
- this.eventQueue.push(event);
446
- if (this.eventQueue.length >= this.config.batchSize) {
447
- this.flush();
458
+ try {
459
+ if (!this.canTrackAnalytics()) return;
460
+ const utm = getUTMParams();
461
+ const mergedProperties = { ...properties || {} };
462
+ if (this.consent.geo && this.geoContext) {
463
+ mergedProperties.geo = this.geoContext;
464
+ }
465
+ const event = {
466
+ project_id: this.config.apiKey,
467
+ distinct_id: this.distinctId,
468
+ event_name: eventName,
469
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
470
+ properties: mergedProperties,
471
+ page_url: typeof window !== "undefined" ? window.location.href : "",
472
+ page_title: typeof document !== "undefined" ? document.title : "",
473
+ referrer: typeof document !== "undefined" ? document.referrer : "",
474
+ utm_source: utm.utm_source || "",
475
+ utm_medium: utm.utm_medium || "",
476
+ utm_campaign: utm.utm_campaign || "",
477
+ utm_term: utm.utm_term || "",
478
+ utm_content: utm.utm_content || "",
479
+ device_type: getDeviceType(),
480
+ browser: this.getBrowser(),
481
+ screen_width: typeof window !== "undefined" ? window.screen.width : 0,
482
+ screen_height: typeof window !== "undefined" ? window.screen.height : 0,
483
+ session_id: this.sessionId
484
+ };
485
+ this.eventQueue.push(event);
486
+ if (this.eventQueue.length >= this.config.batchSize) {
487
+ void this.flush();
488
+ }
489
+ } catch (err) {
490
+ this.warn("track failed", err);
448
491
  }
449
492
  }
450
493
  async flush() {
451
- await Promise.all([this.flushEvents(), this.flushHeatmapEvents()]);
494
+ try {
495
+ await Promise.all([this.flushEvents(), this.flushHeatmapEvents()]);
496
+ } catch (err) {
497
+ this.warn("flush failed", err);
498
+ }
452
499
  }
453
500
  shutdown() {
454
501
  if (this.flushTimer) {
455
502
  clearInterval(this.flushTimer);
456
503
  this.flushTimer = null;
457
504
  }
458
- this.flush();
505
+ void this.flush();
459
506
  }
460
507
  captureGeoOnce() {
461
508
  if (this.geoRequested) return;
@@ -488,14 +535,8 @@ var Krypton = class {
488
535
  api_key: this.config.apiKey,
489
536
  events
490
537
  };
491
- try {
492
- await fetch(`${this.config.endpoint}/api/v1/ingest/batch`, {
493
- method: "POST",
494
- headers: { "Content-Type": "application/json" },
495
- body: JSON.stringify(payload),
496
- keepalive: true
497
- });
498
- } catch {
538
+ const ok = await this.safePost(`${this.config.endpoint}/api/v1/ingest/batch`, payload);
539
+ if (!ok) {
499
540
  if (this.eventQueue.length < this.config.batchSize * 5) {
500
541
  this.eventQueue.unshift(...events);
501
542
  }
@@ -508,14 +549,8 @@ var Krypton = class {
508
549
  api_key: this.config.apiKey,
509
550
  events
510
551
  };
511
- try {
512
- await fetch(`${this.config.endpoint}/api/v1/heatmap`, {
513
- method: "POST",
514
- headers: { "Content-Type": "application/json" },
515
- body: JSON.stringify(payload),
516
- keepalive: true
517
- });
518
- } catch {
552
+ const ok = await this.safePost(`${this.config.endpoint}/api/v1/heatmap`, payload);
553
+ if (!ok) {
519
554
  if (this.heatmapQueue.length < this.config.batchSize * 5) {
520
555
  this.heatmapQueue.unshift(...events);
521
556
  }
@@ -546,13 +581,7 @@ var Krypton = class {
546
581
  page_height: document.documentElement.scrollHeight,
547
582
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
548
583
  };
549
- fetch(`${this.config.endpoint}/api/v1/snapshot`, {
550
- method: "POST",
551
- headers: { "Content-Type": "application/json" },
552
- body: JSON.stringify(payload),
553
- keepalive: true
554
- }).catch(() => {
555
- });
584
+ void this.safePost(`${this.config.endpoint}/api/v1/snapshot`, payload);
556
585
  } catch {
557
586
  }
558
587
  }, 1e3);
@@ -564,50 +593,82 @@ var Krypton = class {
564
593
  this.captureSnapshot();
565
594
  document.addEventListener("click", (e) => {
566
595
  if (!this.isHeatmapFeatureEnabled()) return;
567
- const target = e.target;
568
- this.heatmapQueue.push({
569
- project_id: this.config.apiKey,
570
- distinct_id: this.distinctId,
571
- session_id: this.sessionId,
572
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
573
- page_url: window.location.href,
574
- interaction_type: "click",
575
- x: e.clientX + window.scrollX,
576
- y: e.clientY + window.scrollY,
577
- viewport_width: window.innerWidth,
578
- viewport_height: window.innerHeight,
579
- page_width: document.documentElement.scrollWidth,
580
- page_height: document.documentElement.scrollHeight,
581
- selector: getSelector(target)
582
- });
583
- });
584
- let maxScrollDepth = 0;
585
- let scrollTimeout = null;
586
- window.addEventListener("scroll", () => {
587
- if (!this.isHeatmapFeatureEnabled()) return;
588
- const scrollTop = window.scrollY || document.documentElement.scrollTop;
589
- const docHeight = document.documentElement.scrollHeight - window.innerHeight;
590
- const depth = docHeight > 0 ? scrollTop / docHeight * 100 : 0;
591
- if (depth > maxScrollDepth) {
592
- maxScrollDepth = depth;
593
- }
594
- if (scrollTimeout) clearTimeout(scrollTimeout);
595
- scrollTimeout = setTimeout(() => {
596
+ try {
597
+ const target = e.target;
596
598
  this.heatmapQueue.push({
597
599
  project_id: this.config.apiKey,
598
600
  distinct_id: this.distinctId,
599
601
  session_id: this.sessionId,
600
602
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
601
603
  page_url: window.location.href,
602
- interaction_type: "scroll",
603
- scroll_depth: maxScrollDepth,
604
+ interaction_type: "click",
605
+ x: e.clientX + window.scrollX,
606
+ y: e.clientY + window.scrollY,
604
607
  viewport_width: window.innerWidth,
605
608
  viewport_height: window.innerHeight,
606
609
  page_width: document.documentElement.scrollWidth,
607
- page_height: document.documentElement.scrollHeight
610
+ page_height: document.documentElement.scrollHeight,
611
+ selector: getSelector(target)
608
612
  });
609
- }, 500);
613
+ } catch (err) {
614
+ this.warn("heatmap click capture failed", err);
615
+ }
610
616
  });
617
+ let maxScrollDepth = 0;
618
+ let scrollTimeout = null;
619
+ window.addEventListener("scroll", () => {
620
+ if (!this.isHeatmapFeatureEnabled()) return;
621
+ try {
622
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
623
+ const docHeight = document.documentElement.scrollHeight - window.innerHeight;
624
+ const depth = docHeight > 0 ? scrollTop / docHeight * 100 : 0;
625
+ if (depth > maxScrollDepth) {
626
+ maxScrollDepth = depth;
627
+ }
628
+ if (scrollTimeout) clearTimeout(scrollTimeout);
629
+ scrollTimeout = setTimeout(() => {
630
+ this.heatmapQueue.push({
631
+ project_id: this.config.apiKey,
632
+ distinct_id: this.distinctId,
633
+ session_id: this.sessionId,
634
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
635
+ page_url: window.location.href,
636
+ interaction_type: "scroll",
637
+ scroll_depth: maxScrollDepth,
638
+ viewport_width: window.innerWidth,
639
+ viewport_height: window.innerHeight,
640
+ page_width: document.documentElement.scrollWidth,
641
+ page_height: document.documentElement.scrollHeight
642
+ });
643
+ }, 500);
644
+ } catch (err) {
645
+ this.warn("heatmap scroll capture failed", err);
646
+ }
647
+ });
648
+ }
649
+ async safePost(url, payload) {
650
+ try {
651
+ const res = await fetch(url, {
652
+ method: "POST",
653
+ headers: { "Content-Type": "application/json" },
654
+ body: JSON.stringify(payload),
655
+ keepalive: true
656
+ });
657
+ if (!res.ok) {
658
+ this.warn(`API request failed (${res.status})`, { url });
659
+ return false;
660
+ }
661
+ return true;
662
+ } catch (err) {
663
+ this.warn("API request failed", { url, err });
664
+ return false;
665
+ }
666
+ }
667
+ warn(message, details) {
668
+ try {
669
+ console.warn(`${this.logPrefix} ${message}`, details ?? "");
670
+ } catch {
671
+ }
611
672
  }
612
673
  getBrowser() {
613
674
  if (typeof navigator === "undefined") return "unknown";
package/dist/index.mjs CHANGED
@@ -92,6 +92,7 @@ var Krypton = class {
92
92
  this.geoContext = null;
93
93
  this.serverConfig = null;
94
94
  this.configFetched = false;
95
+ this.logPrefix = "[Krypton SDK]";
95
96
  this.config = {
96
97
  autoPageview: true,
97
98
  heatmap: false,
@@ -113,7 +114,7 @@ var Krypton = class {
113
114
  init() {
114
115
  if (this.initialized) return;
115
116
  this.initialized = true;
116
- this.fetchConfig().then(() => {
117
+ this.fetchConfig().finally(() => {
117
118
  this.setupTracking();
118
119
  if (this.config.consentRequired && this.config.showConsentBanner && !this.hasStoredConsent()) {
119
120
  this.showConsentBanner();
@@ -199,9 +200,13 @@ var Krypton = class {
199
200
  }
200
201
  }
201
202
  try {
203
+ const controller = new AbortController();
204
+ const timeout = setTimeout(() => controller.abort(), 5e3);
202
205
  const res = await fetch(
203
- `${this.config.endpoint}/api/v1/config?api_key=${encodeURIComponent(this.config.apiKey)}`
206
+ `${this.config.endpoint}/api/v1/config?api_key=${encodeURIComponent(this.config.apiKey)}`,
207
+ { signal: controller.signal }
204
208
  );
209
+ clearTimeout(timeout);
205
210
  if (res.ok) {
206
211
  const data = await res.json();
207
212
  this.serverConfig = data;
@@ -215,38 +220,54 @@ var Krypton = class {
215
220
  }
216
221
  }
217
222
  setupTracking() {
218
- this.flushTimer = setInterval(() => this.flush(), this.config.flushInterval);
223
+ this.flushTimer = setInterval(() => {
224
+ void this.flush();
225
+ }, this.config.flushInterval);
219
226
  if (typeof window === "undefined") return;
220
- window.addEventListener("beforeunload", () => this.flush());
227
+ window.addEventListener("beforeunload", () => {
228
+ void this.flush();
229
+ });
221
230
  if (this.config.autoPageview && this.canTrackAnalytics()) {
222
231
  this.trackPageview();
223
232
  }
224
233
  const originalPushState = history.pushState;
225
234
  history.pushState = (...args) => {
226
- originalPushState.apply(history, args);
227
- if (this.config.autoPageview && this.canTrackAnalytics()) {
228
- setTimeout(() => this.trackPageview(), 0);
229
- }
230
- if (this.isHeatmapFeatureEnabled()) {
231
- setTimeout(() => this.captureSnapshot(), 0);
235
+ try {
236
+ originalPushState.apply(history, args);
237
+ if (this.config.autoPageview && this.canTrackAnalytics()) {
238
+ setTimeout(() => this.trackPageview(), 0);
239
+ }
240
+ if (this.isHeatmapFeatureEnabled()) {
241
+ setTimeout(() => this.captureSnapshot(), 0);
242
+ }
243
+ } catch (err) {
244
+ this.warn("pushState hook failed", err);
232
245
  }
233
246
  };
234
247
  const originalReplaceState = history.replaceState;
235
248
  history.replaceState = (...args) => {
236
- originalReplaceState.apply(history, args);
237
- if (this.config.autoPageview && this.canTrackAnalytics()) {
238
- setTimeout(() => this.trackPageview(), 0);
239
- }
240
- if (this.isHeatmapFeatureEnabled()) {
241
- setTimeout(() => this.captureSnapshot(), 0);
249
+ try {
250
+ originalReplaceState.apply(history, args);
251
+ if (this.config.autoPageview && this.canTrackAnalytics()) {
252
+ setTimeout(() => this.trackPageview(), 0);
253
+ }
254
+ if (this.isHeatmapFeatureEnabled()) {
255
+ setTimeout(() => this.captureSnapshot(), 0);
256
+ }
257
+ } catch (err) {
258
+ this.warn("replaceState hook failed", err);
242
259
  }
243
260
  };
244
261
  window.addEventListener("popstate", () => {
245
- if (this.config.autoPageview && this.canTrackAnalytics()) {
246
- setTimeout(() => this.trackPageview(), 0);
247
- }
248
- if (this.isHeatmapFeatureEnabled()) {
249
- setTimeout(() => this.captureSnapshot(), 0);
262
+ try {
263
+ if (this.config.autoPageview && this.canTrackAnalytics()) {
264
+ setTimeout(() => this.trackPageview(), 0);
265
+ }
266
+ if (this.isHeatmapFeatureEnabled()) {
267
+ setTimeout(() => this.captureSnapshot(), 0);
268
+ }
269
+ } catch (err) {
270
+ this.warn("popstate hook failed", err);
250
271
  }
251
272
  });
252
273
  if (this.isHeatmapFeatureEnabled()) {
@@ -303,58 +324,68 @@ var Krypton = class {
303
324
  `;
304
325
  const remove = () => {
305
326
  banner.remove();
327
+ try {
328
+ if (document.body) document.body.style.cursor = "";
329
+ if (document.documentElement) document.documentElement.style.cursor = "";
330
+ } catch {
331
+ }
306
332
  };
307
333
  const readValue = (id) => {
308
334
  const el = document.getElementById(id);
309
335
  return !!el?.checked;
310
336
  };
311
337
  banner.querySelector("#krypton-consent-save")?.addEventListener("click", () => {
312
- this.setConsent({
338
+ const next = {
313
339
  analytics: readValue("krypton-consent-analytics"),
314
340
  heatmaps: readValue("krypton-consent-heatmaps"),
315
341
  geo: readValue("krypton-consent-geo")
316
- });
342
+ };
317
343
  remove();
344
+ setTimeout(() => this.setConsent(next), 0);
318
345
  });
319
346
  banner.querySelector("#krypton-consent-all")?.addEventListener("click", () => {
320
- this.setConsent({ analytics: true, heatmaps: true, geo: true });
321
347
  remove();
348
+ setTimeout(() => this.setConsent({ analytics: true, heatmaps: true, geo: true }), 0);
322
349
  });
323
350
  banner.querySelector("#krypton-consent-none")?.addEventListener("click", () => {
324
- this.setConsent({ analytics: false, heatmaps: false, geo: false });
325
351
  remove();
352
+ setTimeout(() => this.setConsent({ analytics: false, heatmaps: false, geo: false }), 0);
326
353
  });
327
354
  document.body.appendChild(banner);
328
355
  }
329
356
  /** Set one or more consent categories and apply changes immediately. */
330
357
  setConsent(next, persist = true) {
331
- const prev = { ...this.consent };
332
- this.consent = {
333
- analytics: next.analytics ?? prev.analytics,
334
- heatmaps: next.heatmaps ?? prev.heatmaps,
335
- geo: next.geo ?? prev.geo
336
- };
337
- if (persist) {
338
- this.persistConsent();
339
- }
340
- if (!prev.analytics && this.consent.analytics) {
341
- this.promotePersistentIds();
342
- if (this.config.autoPageview) {
343
- this.trackPageview();
358
+ try {
359
+ const prev = { ...this.consent };
360
+ this.consent = {
361
+ analytics: next.analytics ?? prev.analytics,
362
+ heatmaps: next.heatmaps ?? prev.heatmaps,
363
+ geo: next.geo ?? prev.geo
364
+ };
365
+ if (persist) {
366
+ this.persistConsent();
344
367
  }
345
- }
346
- if (prev.analytics && !this.consent.analytics) {
347
- this.eventQueue = [];
348
- }
349
- if (!prev.heatmaps && this.isHeatmapFeatureEnabled()) {
350
- this.setupHeatmap();
351
- this.captureSnapshot();
352
- }
353
- if (prev.heatmaps && !this.consent.heatmaps) {
354
- this.heatmapQueue = [];
355
- }
356
- if (!prev.geo && this.consent.geo) {
357
- this.captureGeoOnce();
368
+ if (!prev.analytics && this.consent.analytics) {
369
+ this.promotePersistentIds();
370
+ if (this.config.autoPageview) {
371
+ this.trackPageview();
372
+ }
373
+ }
374
+ if (prev.analytics && !this.consent.analytics) {
375
+ this.eventQueue = [];
376
+ }
377
+ if (!prev.heatmaps && this.isHeatmapFeatureEnabled()) {
378
+ this.setupHeatmap();
379
+ this.captureSnapshot();
380
+ }
381
+ if (prev.heatmaps && !this.consent.heatmaps) {
382
+ this.heatmapQueue = [];
383
+ }
384
+ if (!prev.geo && this.consent.geo) {
385
+ this.captureGeoOnce();
386
+ }
387
+ } catch (err) {
388
+ this.warn("setConsent failed", err);
358
389
  }
359
390
  }
360
391
  getConsent() {
@@ -372,65 +403,81 @@ var Krypton = class {
372
403
  }
373
404
  /** Identify a user with a custom distinct ID */
374
405
  identify(distinctId) {
375
- this.distinctId = distinctId;
376
- if (this.canTrackAnalytics()) {
377
- try {
378
- if (typeof localStorage !== "undefined") {
379
- localStorage.setItem("_krypton_did", distinctId);
406
+ try {
407
+ this.distinctId = distinctId;
408
+ if (this.canTrackAnalytics()) {
409
+ try {
410
+ if (typeof localStorage !== "undefined") {
411
+ localStorage.setItem("_krypton_did", distinctId);
412
+ }
413
+ } catch {
380
414
  }
381
- } catch {
382
415
  }
416
+ } catch (err) {
417
+ this.warn("identify failed", err);
383
418
  }
384
419
  }
385
420
  /** Track a pageview */
386
421
  trackPageview(properties) {
387
- if (!this.canTrackAnalytics()) return;
388
- this.track("$pageview", {
389
- ...properties
390
- });
422
+ try {
423
+ if (!this.canTrackAnalytics()) return;
424
+ this.track("$pageview", {
425
+ ...properties
426
+ });
427
+ } catch (err) {
428
+ this.warn("trackPageview failed", err);
429
+ }
391
430
  }
392
431
  /** Track a custom event */
393
432
  track(eventName, properties) {
394
- if (!this.canTrackAnalytics()) return;
395
- const utm = getUTMParams();
396
- const mergedProperties = { ...properties || {} };
397
- if (this.consent.geo && this.geoContext) {
398
- mergedProperties.geo = this.geoContext;
399
- }
400
- const event = {
401
- project_id: this.config.apiKey,
402
- distinct_id: this.distinctId,
403
- event_name: eventName,
404
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
405
- properties: mergedProperties,
406
- page_url: typeof window !== "undefined" ? window.location.href : "",
407
- page_title: typeof document !== "undefined" ? document.title : "",
408
- referrer: typeof document !== "undefined" ? document.referrer : "",
409
- utm_source: utm.utm_source || "",
410
- utm_medium: utm.utm_medium || "",
411
- utm_campaign: utm.utm_campaign || "",
412
- utm_term: utm.utm_term || "",
413
- utm_content: utm.utm_content || "",
414
- device_type: getDeviceType(),
415
- browser: this.getBrowser(),
416
- screen_width: typeof window !== "undefined" ? window.screen.width : 0,
417
- screen_height: typeof window !== "undefined" ? window.screen.height : 0,
418
- session_id: this.sessionId
419
- };
420
- this.eventQueue.push(event);
421
- if (this.eventQueue.length >= this.config.batchSize) {
422
- this.flush();
433
+ try {
434
+ if (!this.canTrackAnalytics()) return;
435
+ const utm = getUTMParams();
436
+ const mergedProperties = { ...properties || {} };
437
+ if (this.consent.geo && this.geoContext) {
438
+ mergedProperties.geo = this.geoContext;
439
+ }
440
+ const event = {
441
+ project_id: this.config.apiKey,
442
+ distinct_id: this.distinctId,
443
+ event_name: eventName,
444
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
445
+ properties: mergedProperties,
446
+ page_url: typeof window !== "undefined" ? window.location.href : "",
447
+ page_title: typeof document !== "undefined" ? document.title : "",
448
+ referrer: typeof document !== "undefined" ? document.referrer : "",
449
+ utm_source: utm.utm_source || "",
450
+ utm_medium: utm.utm_medium || "",
451
+ utm_campaign: utm.utm_campaign || "",
452
+ utm_term: utm.utm_term || "",
453
+ utm_content: utm.utm_content || "",
454
+ device_type: getDeviceType(),
455
+ browser: this.getBrowser(),
456
+ screen_width: typeof window !== "undefined" ? window.screen.width : 0,
457
+ screen_height: typeof window !== "undefined" ? window.screen.height : 0,
458
+ session_id: this.sessionId
459
+ };
460
+ this.eventQueue.push(event);
461
+ if (this.eventQueue.length >= this.config.batchSize) {
462
+ void this.flush();
463
+ }
464
+ } catch (err) {
465
+ this.warn("track failed", err);
423
466
  }
424
467
  }
425
468
  async flush() {
426
- await Promise.all([this.flushEvents(), this.flushHeatmapEvents()]);
469
+ try {
470
+ await Promise.all([this.flushEvents(), this.flushHeatmapEvents()]);
471
+ } catch (err) {
472
+ this.warn("flush failed", err);
473
+ }
427
474
  }
428
475
  shutdown() {
429
476
  if (this.flushTimer) {
430
477
  clearInterval(this.flushTimer);
431
478
  this.flushTimer = null;
432
479
  }
433
- this.flush();
480
+ void this.flush();
434
481
  }
435
482
  captureGeoOnce() {
436
483
  if (this.geoRequested) return;
@@ -463,14 +510,8 @@ var Krypton = class {
463
510
  api_key: this.config.apiKey,
464
511
  events
465
512
  };
466
- try {
467
- await fetch(`${this.config.endpoint}/api/v1/ingest/batch`, {
468
- method: "POST",
469
- headers: { "Content-Type": "application/json" },
470
- body: JSON.stringify(payload),
471
- keepalive: true
472
- });
473
- } catch {
513
+ const ok = await this.safePost(`${this.config.endpoint}/api/v1/ingest/batch`, payload);
514
+ if (!ok) {
474
515
  if (this.eventQueue.length < this.config.batchSize * 5) {
475
516
  this.eventQueue.unshift(...events);
476
517
  }
@@ -483,14 +524,8 @@ var Krypton = class {
483
524
  api_key: this.config.apiKey,
484
525
  events
485
526
  };
486
- try {
487
- await fetch(`${this.config.endpoint}/api/v1/heatmap`, {
488
- method: "POST",
489
- headers: { "Content-Type": "application/json" },
490
- body: JSON.stringify(payload),
491
- keepalive: true
492
- });
493
- } catch {
527
+ const ok = await this.safePost(`${this.config.endpoint}/api/v1/heatmap`, payload);
528
+ if (!ok) {
494
529
  if (this.heatmapQueue.length < this.config.batchSize * 5) {
495
530
  this.heatmapQueue.unshift(...events);
496
531
  }
@@ -521,13 +556,7 @@ var Krypton = class {
521
556
  page_height: document.documentElement.scrollHeight,
522
557
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
523
558
  };
524
- fetch(`${this.config.endpoint}/api/v1/snapshot`, {
525
- method: "POST",
526
- headers: { "Content-Type": "application/json" },
527
- body: JSON.stringify(payload),
528
- keepalive: true
529
- }).catch(() => {
530
- });
559
+ void this.safePost(`${this.config.endpoint}/api/v1/snapshot`, payload);
531
560
  } catch {
532
561
  }
533
562
  }, 1e3);
@@ -539,50 +568,82 @@ var Krypton = class {
539
568
  this.captureSnapshot();
540
569
  document.addEventListener("click", (e) => {
541
570
  if (!this.isHeatmapFeatureEnabled()) return;
542
- const target = e.target;
543
- this.heatmapQueue.push({
544
- project_id: this.config.apiKey,
545
- distinct_id: this.distinctId,
546
- session_id: this.sessionId,
547
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
548
- page_url: window.location.href,
549
- interaction_type: "click",
550
- x: e.clientX + window.scrollX,
551
- y: e.clientY + window.scrollY,
552
- viewport_width: window.innerWidth,
553
- viewport_height: window.innerHeight,
554
- page_width: document.documentElement.scrollWidth,
555
- page_height: document.documentElement.scrollHeight,
556
- selector: getSelector(target)
557
- });
558
- });
559
- let maxScrollDepth = 0;
560
- let scrollTimeout = null;
561
- window.addEventListener("scroll", () => {
562
- if (!this.isHeatmapFeatureEnabled()) return;
563
- const scrollTop = window.scrollY || document.documentElement.scrollTop;
564
- const docHeight = document.documentElement.scrollHeight - window.innerHeight;
565
- const depth = docHeight > 0 ? scrollTop / docHeight * 100 : 0;
566
- if (depth > maxScrollDepth) {
567
- maxScrollDepth = depth;
568
- }
569
- if (scrollTimeout) clearTimeout(scrollTimeout);
570
- scrollTimeout = setTimeout(() => {
571
+ try {
572
+ const target = e.target;
571
573
  this.heatmapQueue.push({
572
574
  project_id: this.config.apiKey,
573
575
  distinct_id: this.distinctId,
574
576
  session_id: this.sessionId,
575
577
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
576
578
  page_url: window.location.href,
577
- interaction_type: "scroll",
578
- scroll_depth: maxScrollDepth,
579
+ interaction_type: "click",
580
+ x: e.clientX + window.scrollX,
581
+ y: e.clientY + window.scrollY,
579
582
  viewport_width: window.innerWidth,
580
583
  viewport_height: window.innerHeight,
581
584
  page_width: document.documentElement.scrollWidth,
582
- page_height: document.documentElement.scrollHeight
585
+ page_height: document.documentElement.scrollHeight,
586
+ selector: getSelector(target)
583
587
  });
584
- }, 500);
588
+ } catch (err) {
589
+ this.warn("heatmap click capture failed", err);
590
+ }
585
591
  });
592
+ let maxScrollDepth = 0;
593
+ let scrollTimeout = null;
594
+ window.addEventListener("scroll", () => {
595
+ if (!this.isHeatmapFeatureEnabled()) return;
596
+ try {
597
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
598
+ const docHeight = document.documentElement.scrollHeight - window.innerHeight;
599
+ const depth = docHeight > 0 ? scrollTop / docHeight * 100 : 0;
600
+ if (depth > maxScrollDepth) {
601
+ maxScrollDepth = depth;
602
+ }
603
+ if (scrollTimeout) clearTimeout(scrollTimeout);
604
+ scrollTimeout = setTimeout(() => {
605
+ this.heatmapQueue.push({
606
+ project_id: this.config.apiKey,
607
+ distinct_id: this.distinctId,
608
+ session_id: this.sessionId,
609
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
610
+ page_url: window.location.href,
611
+ interaction_type: "scroll",
612
+ scroll_depth: maxScrollDepth,
613
+ viewport_width: window.innerWidth,
614
+ viewport_height: window.innerHeight,
615
+ page_width: document.documentElement.scrollWidth,
616
+ page_height: document.documentElement.scrollHeight
617
+ });
618
+ }, 500);
619
+ } catch (err) {
620
+ this.warn("heatmap scroll capture failed", err);
621
+ }
622
+ });
623
+ }
624
+ async safePost(url, payload) {
625
+ try {
626
+ const res = await fetch(url, {
627
+ method: "POST",
628
+ headers: { "Content-Type": "application/json" },
629
+ body: JSON.stringify(payload),
630
+ keepalive: true
631
+ });
632
+ if (!res.ok) {
633
+ this.warn(`API request failed (${res.status})`, { url });
634
+ return false;
635
+ }
636
+ return true;
637
+ } catch (err) {
638
+ this.warn("API request failed", { url, err });
639
+ return false;
640
+ }
641
+ }
642
+ warn(message, details) {
643
+ try {
644
+ console.warn(`${this.logPrefix} ${message}`, details ?? "");
645
+ } catch {
646
+ }
586
647
  }
587
648
  getBrowser() {
588
649
  if (typeof navigator === "undefined") return "unknown";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kryptonhq/analytics",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Krypton Analytics JavaScript SDK — privacy-first analytics tracking",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",