@usermaven/sdk-js 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,164 @@
1
+ # Usermaven SDK
2
+
3
+ Usermaven SDK is a powerful and flexible JavaScript/TypeScript library for tracking user behavior and events in web applications. It supports both client-side and server-side usage, with a focus on privacy, configurability, and robustness.
4
+
5
+ ## Features
6
+
7
+ - Cross-platform compatibility (browser and server-side)
8
+ - Flexible event tracking with custom payloads
9
+ - Automatic tracking of page views, form submissions, and user interactions
10
+ - Privacy-focused with configurable data sanitization
11
+ - Robust error handling and retry mechanisms
12
+ - Extensible architecture for custom tracking features
13
+ - Performance optimizations including event batching and debouncing
14
+
15
+ ## Installation
16
+
17
+ ### NPM or Yarn
18
+
19
+ You can install the Usermaven SDK using npm:
20
+
21
+ ```bash
22
+ npm install @usermaven/sdk-js
23
+ ```
24
+
25
+ Or using yarn:
26
+
27
+ ```bash
28
+ yarn add @usermaven/sdk-js
29
+ ```
30
+
31
+ ### UMD (Universal Module Definition)
32
+
33
+ For quick integration without a module bundler, you can include the SDK directly in your HTML using a script tag:
34
+
35
+ ```html
36
+ <script src="https://cdn.usermaven.com/sdk/v1/lib.js"
37
+ data-key="your-api-key"
38
+ data-tracking-host="https://events.yourdomain.com"
39
+ data-log-level="debug"
40
+ data-autocapture="true"
41
+ data-form-tracking="true"
42
+ data-auto-pageview="true"></script>
43
+ ```
44
+
45
+ Replace `https://cdn.usermaven.com/sdk/v1/lib.js` with the actual URL where the Usermaven SDK is hosted.
46
+
47
+ ## Basic Usage
48
+
49
+ ### Using as a module
50
+
51
+ ```javascript
52
+ import { usermavenClient } from '@usermaven/sdk-js';
53
+
54
+ const client = usermavenClient({
55
+ apiKey: 'your-api-key',
56
+ trackingHost: 'https://events.yourdomain.com',
57
+ // Add other configuration options as needed
58
+ });
59
+
60
+ // Track an event
61
+ client.track('button_click', {
62
+ buttonId: 'submit-form',
63
+ pageUrl: window.location.href
64
+ });
65
+
66
+ // Identify a user
67
+ client.id({
68
+ id: 'user123',
69
+ email: 'user@example.com',
70
+ name: 'John Doe'
71
+ });
72
+
73
+ // Track a page view
74
+ client.pageview();
75
+ ```
76
+
77
+ ### Using via UMD
78
+
79
+ When you include the SDK via a script tag, it automatically initializes with the configuration provided in the data attributes. You can then use the global `usermaven` function to interact with the SDK:
80
+
81
+ ```html
82
+ <script>
83
+ // Track an event
84
+ usermaven('track', 'button_click', {
85
+ buttonId: 'submit-form',
86
+ pageUrl: window.location.href
87
+ });
88
+
89
+ // Identify a user
90
+ usermaven('id', {
91
+ id: 'user123',
92
+ email: 'user@example.com',
93
+ name: 'John Doe'
94
+ });
95
+
96
+ // Track a page view (if not set to automatic in the script tag)
97
+ usermaven('pageview');
98
+ </script>
99
+ ```
100
+
101
+ ## Advanced Configuration
102
+
103
+ The SDK supports various configuration options to customize its behavior. When using as a module:
104
+
105
+ ```javascript
106
+ const client = usermavenClient({
107
+ apiKey: 'your-api-key',
108
+ trackingHost: 'https://events.yourdomain.com',
109
+ cookieDomain: '.yourdomain.com',
110
+ logLevel: 'DEBUG',
111
+ useBeaconApi: true,
112
+ autocapture: true,
113
+ formTracking: 'all',
114
+ autoPageview: true,
115
+ // ... other options
116
+ });
117
+ ```
118
+
119
+ When using via UMD, you can set these options using data attributes on the script tag:
120
+
121
+ ```html
122
+ <script src="https://cdn.usermaven.com/sdk/v1/lib.js"
123
+ data-key="your-api-key"
124
+ data-tracking-host="https://events.yourdomain.com"
125
+ data-log-level="debug"
126
+ data-autocapture="true"
127
+ data-form-tracking="all"
128
+ data-auto-pageview="true"
129
+ data-use-beacon-api="true"
130
+ data-cookie-domain=".yourdomain.com"></script>
131
+ ```
132
+
133
+ Refer to the `Config` interface in `src/core/config.ts` for a full list of configuration options.
134
+
135
+ ## Server-Side Usage
136
+
137
+ The SDK can also be used in server-side environments:
138
+
139
+ ```javascript
140
+ const { usermavenClient } = require('@usermaven/sdk-js');
141
+
142
+ const client = usermavenClient({
143
+ apiKey: 'your-api-key',
144
+ trackingHost: 'https://events.yourdomain.com'
145
+ });
146
+
147
+ client.track('server_event', {
148
+ userId: 'user123',
149
+ action: 'item_purchased'
150
+ });
151
+ ```
152
+
153
+ ## Development
154
+
155
+ To set up the project for development:
156
+
157
+ 1. Clone the repository
158
+ 2. Install dependencies: `npm install`
159
+ 3. Run tests: `npm test`
160
+ 4. Build the project: `npm run build`
161
+
162
+ ## Contributing
163
+
164
+ Contributions are welcome! Please read our contributing guidelines and code of conduct before submitting pull requests.
@@ -0,0 +1,57 @@
1
+ import { Config } from './config';
2
+ import { CompanyProps, EventPayload, UserProps } from './types';
3
+ import { Logger } from '../utils/logger';
4
+ export declare class UsermavenClient {
5
+ private config;
6
+ private logger;
7
+ private cookieManager?;
8
+ private transport;
9
+ private persistence;
10
+ private autoCapture?;
11
+ private formTracking?;
12
+ private pageviewTracking?;
13
+ private retryQueue;
14
+ private anonymousId;
15
+ private namespace;
16
+ private rageClick?;
17
+ constructor(config: Config);
18
+ private initializeBrowserFeatures;
19
+ /**
20
+ * Recursively merge the provided configuration with the existing defaultConfig
21
+ * @param config
22
+ * @param defaultConfig
23
+ */
24
+ mergeConfig(config: Partial<Config>, defaultConfig: Partial<Config>): Config;
25
+ init(config: Config): void;
26
+ private manageCrossDomainLinking;
27
+ private findClosestLink;
28
+ private initializeTransport;
29
+ private initializePersistence;
30
+ private getOrCreateAnonymousId;
31
+ private generateFingerprint;
32
+ private hashString;
33
+ id(userData: UserProps, doNotSendEvent?: boolean): Promise<void>;
34
+ track(typeName: string, payload?: EventPayload, directSend?: boolean): void;
35
+ private trackInternal;
36
+ rawTrack(payload: any): void;
37
+ group(props: CompanyProps, doNotSendEvent?: boolean): Promise<void>;
38
+ private createEventPayload;
39
+ private processAutocaptureAttributes;
40
+ getCookie(name: string): string | null;
41
+ private getThirdPartyIds;
42
+ private getUtmParams;
43
+ pageview(): void;
44
+ private setupPageLeaveTracking;
45
+ getConfig(): Config;
46
+ getLogger(): Logger;
47
+ reset(resetAnonId?: boolean): Promise<void>;
48
+ set(properties: Record<string, any>, opts?: {
49
+ eventType?: string;
50
+ persist?: boolean;
51
+ }): void;
52
+ setUserId(userId: string): void;
53
+ unset(propertyName: string, options?: {
54
+ eventType?: string;
55
+ persist?: boolean;
56
+ }): void;
57
+ }
@@ -0,0 +1,37 @@
1
+ import { LogLevel } from '../utils/logger';
2
+ export type Policy = 'strict' | 'keep' | 'comply';
3
+ export interface Config {
4
+ key: string;
5
+ trackingHost: string;
6
+ cookieDomain?: string;
7
+ cookieName?: string;
8
+ logLevel?: LogLevel;
9
+ useBeaconApi?: boolean;
10
+ forceUseFetch?: boolean;
11
+ autocapture?: boolean;
12
+ rageClick?: boolean;
13
+ formTracking?: boolean | 'all' | 'tagged' | 'none';
14
+ autoPageview?: boolean;
15
+ disableEventPersistence?: boolean;
16
+ gaHook?: boolean;
17
+ segmentHook?: boolean;
18
+ randomizeUrl?: boolean;
19
+ capture3rdPartyCookies?: string[] | false;
20
+ idMethod?: 'cookie' | 'localStorage';
21
+ privacyPolicy?: 'strict';
22
+ ipPolicy?: Policy;
23
+ cookiePolicy?: Policy;
24
+ customHeaders?: Record<string, string> | (() => Record<string, string>);
25
+ minSendTimeout?: number;
26
+ maxSendTimeout?: number;
27
+ maxSendAttempts?: number;
28
+ propertiesStringMaxLength?: number | null;
29
+ propertyBlacklist?: string[];
30
+ exclude?: string;
31
+ namespace?: string;
32
+ crossDomainLinking?: boolean;
33
+ domains?: string;
34
+ maskAllText?: boolean;
35
+ maskAllElementAttributes?: boolean;
36
+ }
37
+ export declare const defaultConfig: Partial<Config>;
@@ -0,0 +1,38 @@
1
+ export interface EventPayload {
2
+ [key: string]: any;
3
+ }
4
+ export interface UserProps extends EventPayload {
5
+ id?: string;
6
+ email?: string;
7
+ }
8
+ export interface Transport {
9
+ send(payload: any): Promise<void>;
10
+ }
11
+ export interface UserProps {
12
+ id?: string;
13
+ email?: string;
14
+ [key: string]: any;
15
+ }
16
+ export type Policy = 'strict' | 'keep' | 'comply';
17
+ export interface CompanyProps {
18
+ id: string;
19
+ name: string;
20
+ created_at: string;
21
+ [key: string]: any;
22
+ }
23
+ /**
24
+ * Environment where the event have happened.
25
+ */
26
+ export type ClientProperties = {
27
+ screen_resolution: string;
28
+ user_agent: string;
29
+ referer: string;
30
+ url: string;
31
+ page_title: string;
32
+ doc_path: string;
33
+ doc_host: string;
34
+ doc_search: string;
35
+ vp_size: string;
36
+ user_language: string;
37
+ doc_encoding: string;
38
+ };
@@ -0,0 +1,15 @@
1
+ import { UsermavenClient } from '../core/client';
2
+ export declare class RageClick {
3
+ private client;
4
+ private clicks;
5
+ private threshold;
6
+ private timeWindow;
7
+ private distanceThreshold;
8
+ constructor(client: UsermavenClient);
9
+ private initializeEventListener;
10
+ private handleClick;
11
+ private shouldCaptureElement;
12
+ click(x: number, y: number, timestamp: number): void;
13
+ private checkRageClick;
14
+ private sendRageClickEvent;
15
+ }
@@ -0,0 +1,19 @@
1
+ import { UsermavenClient } from '../core/client';
2
+ export declare class ScrollDepth {
3
+ private client;
4
+ private maxScrollDepth;
5
+ private milestones;
6
+ private lastScrollDepth;
7
+ private documentElement;
8
+ private debouncedHandleScroll;
9
+ constructor(client: UsermavenClient);
10
+ private initializeEventListener;
11
+ track(): void;
12
+ send(eventType?: string): void;
13
+ private handleScroll;
14
+ private getScrollDepth;
15
+ private getWindowHeight;
16
+ private getDocumentHeight;
17
+ private getScrollDistance;
18
+ private checkMilestones;
19
+ }
@@ -0,0 +1,6 @@
1
+ import { UsermavenClient } from './core/client';
2
+ import { Config } from './core/config';
3
+ import { LogLevel } from './utils/logger';
4
+ import { UserProps, EventPayload, ClientProperties } from './core/types';
5
+ declare function usermavenClient(config: Partial<Config>): UsermavenClient;
6
+ export { usermavenClient, UsermavenClient, Config as UsermavenOptions, UserProps, EventPayload, LogLevel, ClientProperties };
package/dist/lib.js ADDED
@@ -0,0 +1,2 @@
1
+ (function(f,g){typeof exports=="object"&&typeof module<"u"?g(exports):typeof define=="function"&&define.amd?define(["exports"],g):(f=typeof globalThis<"u"?globalThis:f||self,g(f.Usermaven={}))})(this,function(f){"use strict";var g=(s=>(s[s.DEBUG=0]="DEBUG",s[s.INFO=1]="INFO",s[s.WARN=2]="WARN",s[s.ERROR=3]="ERROR",s))(g||{});class X{constructor(e){this.level=e}debug(e,...t){this.level<=0&&console.debug("[Usermaven Debug]:",e,...t)}info(e,...t){this.level<=1&&console.info("[Usermaven Info]:",e,...t)}warn(e,...t){this.level<=2&&console.warn("[Usermaven Warning]:",e,...t)}error(e,...t){this.level<=3&&console.error("[Usermaven Error]:",e,...t)}}function h(s=0){return new X(s)}const N={logLevel:g.ERROR,useBeaconApi:!1,forceUseFetch:!1,trackingHost:"t.usermaven.com",autocapture:!1,rageClick:!1,formTracking:!1,autoPageview:!1,disableEventPersistence:!1,gaHook:!1,segmentHook:!1,randomizeUrl:!1,capture3rdPartyCookies:["_ga","_fbp","_ym_uid","ajs_user_id","ajs_anonymous_id"],idMethod:"cookie",ipPolicy:"keep",cookiePolicy:"keep",minSendTimeout:0,maxSendTimeout:2e3,maxSendAttempts:4,propertiesStringMaxLength:null,propertyBlacklist:[],crossDomainLinking:!0,maskAllText:!1,maskAllElementAttributes:!1};class K{constructor(e){this.domain=e,this.cookieDomain=this.getCookieDomain(),console.log(this.cookieDomain)}set(e,t,i=365,n=!0,r=!1){console.log("Setting cookie",e,t,i,n,r);const o=new Date;o.setTime(o.getTime()+i*24*60*60*1e3);const c=`expires=${o.toUTCString()}`,l=n?"; Secure":"",a=r?"; HttpOnly":"";document.cookie=`${e}=${t};${c};path=/;domain=${this.cookieDomain}${l}${a}`}get(e){const t=e+"=",i=document.cookie.split(";");for(let n=0;n<i.length;n++){let r=i[n].trim();if(r.indexOf(t)===0)return decodeURIComponent(r.substring(t.length))}return null}delete(e,t="/"){document.cookie=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${t};domain=${this.cookieDomain}`}getCookieDomain(){return typeof window>"u"||this.domain?this.domain||"":this.extractRoot(window.location.hostname)}extractRoot(e){if(this.isIpAddress(e)||e==="localhost")return e;let t=this.extractTopLevelDomain(e);return t||(t=this.extractRootDomain(e)),"."+t}isIpAddress(e){const t=e.split(".");return t.length===4&&t.every(i=>!isNaN(Number(i)))}extractHostname(e){let t;return e.indexOf("//")>-1?t=e.split("/")[2]:t=e.split("/")[0],t=t.split(":")[0],t=t.split("?")[0],t}extractRootDomain(e){let t=this.extractHostname(e);const i=t.split("."),n=i.length;return n>2&&(i[n-1].length==2?(t=i[n-2]+"."+i[n-1],i[n-2].length==2&&(t=i[n-3]+"."+t)):t=i[n-2]+"."+i[n-1]),t}extractTopLevelDomain(e){const t=/[a-z0-9][a-z0-9-]+\.[a-z.]{2,6}$/i,i=e.match(t);return i?i[0]:""}}const Z=Object.prototype.hasOwnProperty,b=Array.prototype.forEach,$={};function G(s,e,t){if(Array.isArray(s)){if(b&&s.forEach===b)s.forEach(e,t);else if("length"in s&&s.length===+s.length){for(let i=0,n=s.length;i<n;i++)if(i in s&&e.call(t,s[i],i)===$)return}}}const T=function(s){return s.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")},Y=function(s){for(const e in s)typeof s[e]=="function"&&(s[e]=s[e].bind(s))};function A(s,e,t){if(s!=null){if(b&&Array.isArray(s)&&s.forEach===b)s.forEach(e,t);else if("length"in s&&s.length===+s.length){for(let i=0,n=s.length;i<n;i++)if(i in s&&e.call(t,s[i],i)===$)return}else for(const i in s)if(Z.call(s,i)&&e.call(t,s[i],i)===$)return}}const j=function(s,...e){return G(e,function(t){for(const i in t)t[i]!==void 0&&(s[i]=t[i])}),s};function E(s,e){return s.indexOf(e)!==-1}const O=function(s){try{return/^\s*\bfunction\b/.test(s)}catch{return!1}},ee=function(s){return s===void 0},y=function(){const s=function(i,n,r,o,c){if(!i){h().error("No valid element provided to register_event");return}if(i.addEventListener&&!o)i.addEventListener(n,r,!!c);else{const l="on"+n,a=i[l];i[l]=e(i,r,a)}};function e(i,n,r){return function(o){if(o=o||t(window.event),!o)return;let c=!0,l;O(r)&&(l=r(o));const a=n.call(i,o);return(l===!1||a===!1)&&(c=!1),c}}function t(i){return i&&(i.preventDefault=t.preventDefault,i.stopPropagation=t.stopPropagation),i}return t.preventDefault=function(){this.returnValue=!1},t.stopPropagation=function(){this.cancelBubble=!0},s}(),te=function(s){return function(...e){try{return s.apply(this,e)}catch(t){h().error("Implementation error. Please turn on debug and contact support@usermaven.com.",t)}}},L=function(s){for(const e in s)typeof s[e]=="function"&&(s[e]=te(s[e]))};function U(s){for(let e in s)(s[e]===""||s[e]===null||s[e]===void 0||typeof s[e]=="object"&&Object.keys(s[e]).length===0)&&delete s[e];return s}function u(){try{return typeof window<"u"&&window.document!==void 0&&window.document.createElement!==void 0}catch{return h().warn("window is not available"),!1}}function m(s=5){const e=new Uint8Array(s);return crypto.getRandomValues(e),Array.from(e,t=>t.toString(36).padStart(2,"0")).join("").slice(0,s)}function ie(s){return s.replace(/([-_][a-z])/g,e=>e.toUpperCase().replace("-","").replace("_",""))}function S(s){return typeof s!="object"||s===null?s:Array.isArray(s)?s.map(S):Object.keys(s).reduce((e,t)=>{const i=ie(t);return e[i]=S(s[t]),e},{})}function P(s){switch(typeof s.className){case"string":return s.className;case"object":return("baseVal"in s.className?s.className.baseVal:null)||s.getAttribute("class")||"";default:return""}}function I(s){let e="";return z(s)&&!M(s)&&s.childNodes&&s.childNodes.length&&A(s.childNodes,function(t){D(t)&&t.textContent&&(e+=T(t.textContent).split(/(\s+)/).filter(H).join("").replace(/[\r\n]/g," ").replace(/[ ]+/g," ").substring(0,255))}),T(e)}function C(s){return!!s&&s.nodeType===1}function p(s,e){return!!s&&!!s.tagName&&s.tagName.toLowerCase()===e.toLowerCase()}function D(s){return!!s&&s.nodeType===3}function F(s){return!!s&&s.nodeType===11}const x=["a","button","form","input","select","textarea","label"];function se(s,e){if(!s||p(s,"html")||!C(s)||s.classList&&s.classList.contains("um-no-capture"))return!1;let t=!1;const i=[s];let n=!0,r=s;for(;r.parentNode&&!p(r,"body");){if(F(r.parentNode)){i.push(r.parentNode.host),r=r.parentNode.host;continue}if(n=r.parentNode||!1,!n)break;if(x.indexOf(n.tagName.toLowerCase())>-1)t=!0;else{const l=window.getComputedStyle(n);l&&l.getPropertyValue("cursor")==="pointer"&&(t=!0)}i.push(n),r=n}const o=window.getComputedStyle(s);if(o&&o.getPropertyValue("cursor")==="pointer"&&e.type==="click")return!0;const c=s.tagName.toLowerCase();switch(c){case"html":return!1;case"form":return e.type==="submit";case"input":return e.type==="change"||e.type==="click";case"select":case"textarea":return e.type==="change"||e.type==="click";default:return t?e.type==="click":e.type==="click"&&(x.indexOf(c)>-1||s.getAttribute("contenteditable")==="true")}}function z(s){if(!s||!C(s))return!1;if(typeof s.hasAttribute=="function"){if(s.hasAttribute(w.FORCE_CAPTURE_ATTR))return!0;if(s.hasAttribute(w.PREVENT_CAPTURE_ATTR))return!1}let e=s;for(;e&&e.parentElement&&!p(e,"body");){const n=P(e).split(" ");if(E(n,"ph-sensitive")||E(n,"ph-no-capture"))return!1;e=e.parentElement}if(E(P(s).split(" "),"ph-include"))return!0;const t=s.type;if(typeof t=="string")switch(t.toLowerCase()){case"hidden":case"password":return!1}const i=s.name||s.id||"";return!(typeof i=="string"&&/^cc|cardnum|ccnum|creditcard|csc|cvc|cvv|exp|pass|pwd|routing|seccode|securitycode|securitynum|socialsec|socsec|ssn/i.test(i.replace(/[^a-zA-Z0-9]/g,"")))}function M(s){const e=["button","checkbox","submit","reset"];return!!(p(s,"input")&&!e.includes(s.type)||p(s,"select")||p(s,"textarea")||s.getAttribute("contenteditable")==="true")}function H(s){return!(s===null||ee(s)||typeof s=="string"&&(s=T(s),/^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/.test((s||"").replace(/[- ]/g,""))||/(^\d{3}-?\d{2}-?\d{4}$)/.test(s)))}function ne(s){return typeof s=="string"?s.substring(0,10)==="_ngcontent"||s.substring(0,7)==="_nghost":!1}function R(){return m(10)}function re(s){return/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(String(s).toLowerCase())}function oe(s,e){let t;return function(...i){const n=()=>{clearTimeout(t),s(...i)};clearTimeout(t),t=setTimeout(n,e)}}function ae(s){const e={},t=s.replace(/^\?/,"").split("&");for(let i=0;i<t.length;i++){const n=t[i].split("=");n[0]!==""&&(e[decodeURIComponent(n[0])]=decodeURIComponent(n[1]||""))}return e}function B(s){return typeof s=="string"||s instanceof String}function _(s){return s!==null&&typeof s=="object"&&s.constructor===Object}function ce(s){if(s===null)return g.ERROR;const e=s.toUpperCase(),t=g[e];return t||t===0?t:g.ERROR}class le{constructor(e){this.maxScrollDepth=0,this.milestones=[25,50,75,90],this.lastScrollDepth=0,this.client=e,this.documentElement=document.documentElement,this.debouncedHandleScroll=oe(this.handleScroll.bind(this),250),this.initializeEventListener()}initializeEventListener(){window.addEventListener("scroll",this.debouncedHandleScroll)}track(){const e=this.getScrollDepth();e>this.lastScrollDepth&&(this.lastScrollDepth=e,this.checkMilestones(e))}send(e="$scroll"){const t={percent:this.lastScrollDepth,window_height:this.getWindowHeight(),document_height:this.getDocumentHeight(),scroll_distance:this.getScrollDistance()};this.client.track(e,t)}handleScroll(){this.track()}getScrollDepth(){const e=this.getWindowHeight(),t=this.getDocumentHeight(),i=this.getScrollDistance(),n=t-e;return Math.min(100,Math.floor(i/n*100))}getWindowHeight(){return window.innerHeight||this.documentElement.clientHeight||document.body.clientHeight||0}getDocumentHeight(){return Math.max(document.body.scrollHeight||0,this.documentElement.scrollHeight||0,document.body.offsetHeight||0,this.documentElement.offsetHeight||0,document.body.clientHeight||0,this.documentElement.clientHeight||0)}getScrollDistance(){return window.pageYOffset||this.documentElement.scrollTop||document.body.scrollTop||0}checkMilestones(e){this.milestones.filter(i=>e>=i).forEach(i=>{this.send(),this.milestones=this.milestones.filter(n=>n!==i)})}}const v=class v{constructor(e,t,i=h()){this.logger=i,this.scrollDepth=null,this.client=e,this.options=t,this.scrollDepth=new le(e),Y(this),L(this)}init(){if(!(document&&document.body)){this.logger.debug("Document not ready yet, trying again in 500 milliseconds..."),setTimeout(()=>this.init(),500);return}this.addDomEventHandlers()}addDomEventHandlers(){const e=t=>{t=t||window.event,this.captureEvent(t)};y(document,"submit",e,!1,!0),y(document,"change",e,!1,!0),y(document,"click",e,!1,!0),y(document,"visibilitychange",e,!1,!0),y(document,"scroll",e,!1,!0),y(window,"popstate",e,!1,!0)}isPageRefresh(){if("PerformanceNavigationTiming"in window){const e=performance.getEntriesByType("navigation");if(e.length>0)return e[0].type==="reload"}return performance.navigation&&performance.navigation.type===1}captureEvent(e){var i,n;let t=this.getEventTarget(e);if(D(t)&&(t=t.parentNode||null),e.type==="scroll")return(i=this.scrollDepth)==null||i.track(),!0;if(e.type==="visibilitychange"&&document.visibilityState==="hidden"||e.type==="popstate")return this.isPageRefresh()||(n=this.scrollDepth)==null||n.send(),!0;if(t&&this.shouldCaptureElement(t,e)){const r=this.getElementList(t),o=this.getElementsJson(r,e),c=j(this.getDefaultProperties(e.type),{$elements:o});return this.client.track("$autocapture",c),!0}}shouldCaptureElement(e,t){return!e||typeof e.hasAttribute!="function"?!1:e.hasAttribute(v.FORCE_CAPTURE_ATTR)?!0:e.hasAttribute(v.PREVENT_CAPTURE_ATTR)?!1:se(e,t)}getEventTarget(e){var t;return typeof e.target>"u"?e.srcElement||null:(t=e.target)!=null&&t.shadowRoot?e.composedPath()[0]||null:e.target||null}getElementList(e){const t=[e];let i=e;for(;i.parentNode&&!p(i,"body");)F(i.parentNode)?(t.push(i.parentNode.host),i=i.parentNode.host):(t.push(i.parentNode),i=i.parentNode);return t}getElementsJson(e,t){const i=[];let n=null,r=!1;return A(e,o=>{if(p(o,"a")){const l=o.getAttribute("href");l!==null&&z(o)&&H(l)&&(n=l)}const c=P(o).split(" ");E(c,"ph-no-capture")&&(r=!0),i.push(this.getPropertiesFromElement(o))}),this.options.maskAllText||(i[0].$el_text=this.sanitizeText(I(e[0]))),n!==null&&(i[0].attr__href=n),r?[]:i}getPropertiesFromElement(e){const t={tag_name:e.tagName.toLowerCase()};x.indexOf(t.tag_name)>-1&&!this.options.maskAllText&&(t.$el_text=this.sanitizeText(I(e)));const i=P(e);i.length>0&&(t.classes=i.split(" ").filter(c=>c!=="")),A(e.attributes,c=>{M(e)&&["name","id","class"].indexOf(c.name)===-1||!this.options.maskAllElementAttributes&&H(c.value)&&!ne(c.name)&&(t["attr__"+c.name]=this.sanitizeAttributeValue(c.name,c.value))});let n=1,r=1,o=e;for(;o=this.previousElementSibling(o);)n++,o.tagName===e.tagName&&r++;return t.nth_child=n,t.nth_of_type=r,t}previousElementSibling(e){if(e.previousElementSibling)return e.previousElementSibling;do e=e.previousSibling;while(e&&!C(e));return e}getDefaultProperties(e){return{$event_type:e,$ce_version:1}}sanitizeText(e){e=e.replace(/<[^>]*?>/g,""),e=this.encodeHtml(e);const t=this.options.propertiesStringMaxLength||255;return e.length>t&&(e=e.substring(0,t)+"..."),e}sanitizeUrl(e){if(!e)return"";try{const t=new URL(e,window.location.href);return t.protocol!=="http:"&&t.protocol!=="https:"?"":encodeURI(t.toString())}catch{return this.encodeHtml(e)}}sanitizeAttributeValue(e,t){switch(e.toLowerCase()){case"href":case"src":return this.sanitizeUrl(t);default:return this.encodeHtml(t)}}encodeHtml(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}static enabledForProject(e,t=10,i=10){if(!e)return!1;let n=0;for(let r=0;r<e.length;r++)n+=e.charCodeAt(r);return n%t<i}static isBrowserSupported(){return O(document.querySelectorAll)}};v.FORCE_CAPTURE_ATTR="data-um-force-capture",v.PREVENT_CAPTURE_ATTR="data-um-no-capture";let w=v;class ue{constructor(e){this.client=e,this.lastPageUrl=window.location.href,this.trackInitialPageview(),this.initializePageviewTracking()}trackInitialPageview(){this.trackPageview()}initializePageviewTracking(){window.addEventListener("popstate",this.handlePageview.bind(this));const e=history.pushState;history.pushState=(...t)=>{e.apply(history,t),this.handlePageview()},window.addEventListener("hashchange",this.handlePageview.bind(this)),setInterval(this.checkForUrlChange.bind(this),1e3)}handlePageview(){this.trackPageview()}checkForUrlChange(){window.location.href!==this.lastPageUrl&&this.trackPageview()}trackPageview(){const e=window.location.href;e!==this.lastPageUrl&&(this.lastPageUrl=e,this.client.track("pageview",{url:e,referrer:document.referrer,title:document.title}))}}class he{constructor(e,t,i=h()){this.trackingHost=e,this.logger=i,this.config=t}async send(e){const t=this.config.key,i=this.constructUrl(t),n=new Blob([JSON.stringify(e)],{type:"application/json"});if(navigator.sendBeacon(i,n))this.logger.debug(`Successfully queued ${e.length} event(s) via Beacon API`);else throw new Error("Failed to queue events via Beacon API")}constructUrl(e){const t=this.config.cookiePolicy!=="keep"?`&cookie_policy=${this.config.cookiePolicy}`:"",i=this.config.ipPolicy!=="keep"?`&ip_policy=${this.config.ipPolicy}`:"",n=u()?"/api/v1/event":"/api/v1/s2s/event";return this.config.randomizeUrl?`${this.trackingHost}/api.${m()}?p_${m()}=${e}${t}${i}`:`${this.trackingHost}${n}?token=${e}${t}${i}`}}class q{constructor(e,t,i=h()){this.trackingHost=e,this.logger=i,this.config=t}async send(e){const t=this.config.key,i=this.constructUrl(t),n=JSON.stringify(e),r={"Content-Type":"application/json",...this.getCustomHeaders()},o=await fetch(i,{method:"POST",headers:r,body:n});if(!o.ok)throw new Error(`HTTP error! status: ${o.status}`);this.logger.debug(`Successfully sent ${e.length} event(s)`),this.postHandle(o.status,await o.text())}constructUrl(e){const t=this.config.cookiePolicy!=="keep"?`&cookie_policy=${this.config.cookiePolicy}`:"",i=this.config.ipPolicy!=="keep"?`&ip_policy=${this.config.ipPolicy}`:"",n=u()?"/api/v1/event":"/api/v1/s2s/event";return this.config.randomizeUrl?`${this.trackingHost}/api.${m()}?p_${m()}=${e}${t}${i}`:`${this.trackingHost}${n}?token=${e}${t}${i}`}getCustomHeaders(){return typeof this.config.customHeaders=="function"?this.config.customHeaders():this.config.customHeaders?this.config.customHeaders:{}}postHandle(e,t){this.logger.debug(`Response received. Status: ${e}, Body: ${t}`)}}class ge{constructor(e,t,i=h()){this.trackingHost=e,this.logger=i,this.config=t}send(e){return new Promise((t,i)=>{const n=new XMLHttpRequest,r=this.config.key,o=this.constructUrl(r);n.open("POST",o,!0),n.setRequestHeader("Content-Type","application/json");const c=this.getCustomHeaders();Object.keys(c).forEach(l=>{n.setRequestHeader(l,c[l])}),n.onload=()=>{n.status>=200&&n.status<300?(this.logger.debug(`Successfully sent ${e.length} event(s)`),t()):i(new Error(`HTTP error! status: ${n.status}`))},n.onerror=()=>{i(new Error("Network error"))},n.send(JSON.stringify(e))})}constructUrl(e){const t=this.config.cookiePolicy!=="keep"?`&cookie_policy=${this.config.cookiePolicy}`:"",i=this.config.ipPolicy!=="keep"?`&ip_policy=${this.config.ipPolicy}`:"",n=u()?"/api/v1/event":"/api/v1/s2s/event";return this.config.randomizeUrl?`${this.trackingHost}/api.${m()}?p_${m()}=${e}${t}${i}`:`${this.trackingHost}${n}?token=${e}${t}${i}`}getCustomHeaders(){return typeof this.config.customHeaders=="function"?this.config.customHeaders():this.config.customHeaders?this.config.customHeaders:{}}postHandle(e,t){this.logger.debug(`Response received. Status: ${e}, Body: ${t}`)}}class V{constructor(e,t){this.storage={},this.prefix=`usermaven_${e}_`,this.load(),this.logger=t||h()}set(e,t){this.storage[e]=t,this.save()}get(e){return this.storage[e]}remove(e){delete this.storage[e],this.save()}clear(){this.storage={},this.save()}save(){if(!u()){this.logger.warn("localStorage is not available in this environment");return}try{localStorage.setItem(this.prefix+"data",JSON.stringify(this.storage))}catch(e){this.logger.error("Error saving to localStorage:",e)}}load(){if(!u()){this.logger.warn("localStorage is not available in this environment");return}try{const e=localStorage.getItem(this.prefix+"data");e&&(this.storage=JSON.parse(e))}catch(e){this.logger.error("Error loading from localStorage:",e)}}}class de{constructor(){this.storage={}}set(e,t){this.storage[e]=t}get(e){return this.storage[e]}remove(e){delete this.storage[e]}save(){}clear(){this.storage={}}}class J{constructor(e,t=3,i=1e3,n=10,r=1e3,o=h()){this.transport=e,this.maxRetries=t,this.retryInterval=i,this.batchSize=n,this.batchInterval=r,this.logger=o,this.queue=[],this.processing=!1,this.batchTimeoutId=null,this.isOnline=!0,this.persistence=new V("offline_queue"),u()&&(this.isOnline=navigator.onLine,this.loadQueueFromStorage(),this.initNetworkListeners(),this.scheduleBatch())}add(e){const t={payload:e,retries:0,timestamp:Date.now()};this.queue.push(t),u()?this.saveQueueToStorage():this.processBatch()}initNetworkListeners(){u()&&(window.addEventListener("online",()=>{this.isOnline=!0,this.processBatch()}),window.addEventListener("offline",()=>{this.isOnline=!1}))}scheduleBatch(){u()&&(this.batchTimeoutId!==null&&clearTimeout(this.batchTimeoutId),this.batchTimeoutId=window.setTimeout(()=>this.processBatch(),this.batchInterval))}async processBatch(){if((!u()||this.isOnline)&&!this.processing&&this.queue.length>0){this.processing=!0;const e=this.queue.splice(0,this.batchSize),t=e.map(i=>i.payload);try{await this.transport.send(t),this.logger.debug(`Successfully sent batch of ${e.length} payloads`),u()&&this.saveQueueToStorage()}catch(i){this.logger.error("Failed to send batch",i),await this.handleBatchFailure(e)}this.processing=!1}u()&&this.scheduleBatch()}async handleBatchFailure(e){for(const t of e)t.retries<this.maxRetries?(t.retries++,this.queue.unshift(t),this.logger.warn(`Retry attempt ${t.retries} for payload`)):this.logger.error("Max retries reached, discarding payload",t.payload);u()&&(this.saveQueueToStorage(),await new Promise(t=>setTimeout(t,this.retryInterval)))}loadQueueFromStorage(){if(u()){const e=this.persistence.get("queue");e&&(this.queue=JSON.parse(e))}}saveQueueToStorage(){u()&&this.persistence.set("queue",JSON.stringify(this.queue))}}class fe{constructor(e){this.clicks=[],this.threshold=3,this.timeWindow=2e3,this.distanceThreshold=30,this.client=e,this.initializeEventListener(),L(this)}initializeEventListener(){document.addEventListener("click",this.handleClick.bind(this))}handleClick(e){const t=e.target;this.shouldCaptureElement(t)&&this.click(e.clientX,e.clientY,Date.now())}shouldCaptureElement(e){return!e.closest(".um-no-capture")}click(e,t,i){const n={x:e,y:t,timestamp:i};this.clicks.push(n),this.clicks=this.clicks.filter(r=>i-r.timestamp<this.timeWindow),this.clicks.length>=this.threshold&&this.checkRageClick()}checkRageClick(){const e=this.clicks[0],i=(this.clicks[this.clicks.length-1].timestamp-e.timestamp)/1e3;this.clicks.every((r,o)=>{if(o===0)return!0;const c=this.clicks[o-1];return Math.sqrt(Math.pow(r.x-c.x,2)+Math.pow(r.y-c.y,2))<this.distanceThreshold})&&this.sendRageClickEvent(i)}sendRageClickEvent(e){const t=this.clicks[this.clicks.length-1];document.elementFromPoint(t.x,t.y)&&this.client.track("$rage_click",{no_of_clicks:this.clicks.length,time:e.toFixed(2)}),this.clicks=[]}}class pe{constructor(e,t,i=h()){this.trackingHost=e,this.logger=i,this.config=t}async send(e){const t=this.config.key,i=new(void 0)(this.constructUrl(t)),n={hostname:i.hostname,port:443,path:`${i.pathname}${i.search}`,method:"POST",headers:{"Content-Type":"application/json",...this.getCustomHeaders()}};return new Promise((r,o)=>{const c=(void 0)(n,l=>{l.on("data",a=>{}),l.on("end",()=>{const a=l.statusCode||0;a>=200&&a<300?(this.logger.debug(`Successfully sent ${e.length} event(s)`),r()):o(new Error(`HTTP error! status: ${a}`))})});c.on("error",l=>{o(l)}),c.write(JSON.stringify(e)),c.end()})}constructUrl(e){const t=this.config.cookiePolicy!=="keep"?`&cookie_policy=${this.config.cookiePolicy}`:"",i=this.config.ipPolicy!=="keep"?`&ip_policy=${this.config.ipPolicy}`:"";return`${this.trackingHost}/api/v1/s2s/event?token=${e}${t}${i}`}getCustomHeaders(){return typeof this.config.customHeaders=="function"?this.config.customHeaders():this.config.customHeaders?this.config.customHeaders:{}}}class k{constructor(e,t="all",i={}){this.instance=e,this.trackingType=t,this.options=i,document.readyState==="loading"?document.addEventListener("DOMContentLoaded",this.initialize.bind(this)):this.initialize()}initialize(){this.trackingType!=="none"&&this.setupFormTracking()}setupFormTracking(){var e;this.formElements=this.trackingType==="tagged"?document.querySelectorAll("form[data-um-form]"):document.querySelectorAll("form"),(e=this.formElements)==null||e.forEach(t=>{t.addEventListener("submit",this.handleFormSubmit.bind(this))})}handleFormSubmit(e){const t=e.target,i=this._getFormDetails(t);this.instance.track("$form",U(i)),this.options.trackFieldChanges&&this.trackFieldChanges(t)}trackFieldChanges(e){e.querySelectorAll("input, select, textarea").forEach(i=>{i.addEventListener("change",n=>{const r=this._getFieldProps(n.target,0);this.instance.track("$form_field_change",U(r))})})}static getInstance(e,t="all",i={}){return k.instance||(k.instance=new k(e,t,i)),k.instance}_getFormDetails(e){const t={form_id:e.id,form_name:e.name||"",form_action:e.action,form_method:e.method,form_class:e.className,form_attributes:this._getElementAttributes(e)},i=e.querySelectorAll("input, select, textarea");return Array.from(i).filter(r=>!r.classList.contains("um-no-capture")).forEach((r,o)=>{const c=this._getFieldProps(r,o);Object.assign(t,c)}),t}_getFieldProps(e,t){const i=Object.keys(e.dataset).length?JSON.stringify(e.dataset):void 0,n=this.getSafeText(e);return{[`field_${t+1}_tag`]:e.tagName.toLowerCase(),[`field_${t+1}_type`]:e instanceof HTMLInputElement?e.type:void 0,[`field_${t+1}_data_attributes`]:i,[`field_${t+1}_id`]:e.id,[`field_${t+1}_value`]:n,[`field_${t+1}_class`]:e.className,[`field_${t+1}_name`]:e.name,[`field_${t+1}_attributes`]:this._getElementAttributes(e)}}_getElementAttributes(e){const t={};for(let i=0;i<e.attributes.length;i++){const n=e.attributes[i];n.name!=="value"&&!n.name.startsWith("data-")&&(t[n.name]=n.value)}return t}getSafeText(e){let t="";return"value"in e&&e.type!=="password"?t=e.value:e.hasChildNodes()?t=Array.from(e.childNodes).filter(n=>n.nodeType===Node.TEXT_NODE).map(n=>n.textContent).join(""):t=e.textContent||"",this._scrubPotentiallySensitiveValues(t)}_scrubPotentiallySensitiveValues(e){return this._shouldCaptureValue(e)?e:"<redacted>"}_shouldCaptureValue(e){return!(this._isNullish(e)||this._isString(e)&&(e=this._trim(e),/^(?:(4[0-9]{12}(?:[0-9]{3})?)|(5[1-5][0-9]{14})|(6(?:011|5[0-9]{2})[0-9]{12})|(3[47][0-9]{13})|(3(?:0[0-5]|[68][0-9])[0-9]{11})|((?:2131|1800|35[0-9]{3})[0-9]{11}))$/.test((e||"").replace(/[- ]/g,""))||/(^\d{3}-?\d{2}-?\d{4}$)/.test(e)))}_isNullish(e){return e==null}_isString(e){return typeof e=="string"||e instanceof String}_trim(e){if(typeof String.prototype.trim=="function")return e.trim();let t=0,i=e.length-1;const n=[" ",`
2
+ `,"\r"," ","\f","\v"," "," "," "," "," "," "," "," "," "," "," "," "," ","\u2028","\u2029"," "," "," "].join("");for(;t<=i&&n.indexOf(e[t])>-1;)t++;for(;i>=t&&n.indexOf(e[i])>-1;)i--;return e.slice(t,i+1)}}class Q{constructor(e){this.config=this.mergeConfig(e,N),this.logger=h(this.config.logLevel),this.namespace=e.namespace||"usermaven",this.transport=this.initializeTransport(this.config),this.persistence=this.initializePersistence(),this.retryQueue=new J(this.transport,this.config.maxSendAttempts||3,this.config.minSendTimeout||1e3,10,200,this.logger),u()&&this.initializeBrowserFeatures(),this.anonymousId=this.getOrCreateAnonymousId(),this.logger.info(`Usermaven client initialized for namespace: ${this.namespace}`)}initializeBrowserFeatures(){if(this.cookieManager=new K(this.config.cookieDomain),this.config.autocapture&&w.enabledForProject(this.config.key)&&(this.autoCapture=new w(this,this.config,this.logger),this.autoCapture.init()),this.config.formTracking){const e=this.config.formTracking===!0?"all":this.config.formTracking;this.formTracking=k.getInstance(this,e||"none",{trackFieldChanges:!1})}this.config.autoPageview&&(this.pageviewTracking=new ue(this)),this.config.crossDomainLinking&&this.manageCrossDomainLinking(),this.config.rageClick&&(this.rageClick=new fe(this)),this.setupPageLeaveTracking()}mergeConfig(e,t){const i=JSON.parse(JSON.stringify(e));let n={...t,...i};return Object.keys(t).forEach(r=>{_(t[r])&&(n[r]=this.mergeConfig(e[r],t[r]))}),n}init(e){this.config={...this.config,...e},this.logger=h(this.config.logLevel),this.namespace=e.namespace||this.namespace,this.transport=this.initializeTransport(e),this.persistence=this.initializePersistence(),this.retryQueue=new J(this.transport,this.config.maxSendAttempts||3,this.config.minSendTimeout||1e3,10,250,this.logger),u()&&this.initializeBrowserFeatures(),this.anonymousId=this.getOrCreateAnonymousId(),this.logger.info(`Usermaven client reinitialized for namespace: ${this.namespace}`)}manageCrossDomainLinking(){if(!this.config.crossDomainLinking||!this.config.domains)return;const e=this.config.domains.split(",").map(i=>i.trim()),t=this.config.cookieName||`${this.namespace}_id_${this.config.key}`;document.addEventListener("click",i=>{var c;const n=this.findClosestLink(i.target);if(!n)return;const r=n.getAttribute("href");if(!r||!r.startsWith("http"))return;const o=new URL(r);if(o.hostname!==window.location.hostname&&e.includes(o.hostname)){const l=(c=this.cookieManager)==null?void 0:c.get(t);l&&(o.searchParams.append("_um",l),n.setAttribute("href",o.toString()))}}),this.logger.debug("Cross-domain linking initialized")}findClosestLink(e){for(;e&&e.tagName!=="A";)e=e.parentElement;return e}initializeTransport(e){if(!u())return new pe(e.trackingHost,e);const t="XMLHttpRequest"in window,i=typeof fetch<"u",n=typeof navigator<"u"&&"sendBeacon"in navigator;if(e.useBeaconApi&&n)return new he(e.trackingHost,e,this.logger);if(e.forceUseFetch&&i)return new q(e.trackingHost,e,this.logger);if(t)return new ge(e.trackingHost,e,this.logger);if(i)return new q(e.trackingHost,e,this.logger);throw new Error("No suitable transport method available")}initializePersistence(){return this.config.disableEventPersistence||!u()?new de:new V(`${this.namespace}_${this.config.key}`,this.logger)}getOrCreateAnonymousId(){var i,n;if(!u())return R();if(this.config.privacyPolicy==="strict"||this.config.cookiePolicy==="strict")return this.generateFingerprint();const e=this.config.cookieName||`${this.namespace}_id_${this.config.key}`;let t=(i=this.cookieManager)==null?void 0:i.get(e);if(!t){if(this.config.crossDomainLinking){const c=new URLSearchParams(window.location.search).get("_um"),a=window.location.hash.substring(1).split("~"),d=a.length>1?a[1]:void 0;t=c||d||R()}t||(t=R());const r=365*10;(n=this.cookieManager)==null||n.set(e,t,r,document.location.protocol!=="http:",!1)}return t}generateFingerprint(){const e=navigator.userAgent,t=`${screen.width}x${screen.height}`,i=screen.colorDepth,n=Intl.DateTimeFormat().resolvedOptions().timeZone,r=`${e}|${t}|${i}|${n}`;return this.hashString(r)}hashString(e){let t=0;for(let i=0;i<e.length;i++){const n=e.charCodeAt(i);t=(t<<5)-t+n,t=t&t}return t.toString(36)}async id(e,t=!1){if(!_(e))throw new Error("User data must be an object");if(e.email&&!re(e.email))throw new Error("Invalid email provided");if(!e.id||!B(e.id))throw new Error("User ID must be a string");const i=e.id;if(this.persistence.set("userId",i),this.persistence.set("userProps",e),!t){const n={...e,anonymous_id:this.anonymousId};await this.track("user_identify",n)}this.logger.info("User identified:",e)}track(e,t,i=!1){this.trackInternal(e,t,i)}trackInternal(e,t,i=!1){if(!B(e))throw new Error("Event name must be a string");if(t!==void 0&&(typeof t!="object"||t===null||Array.isArray(t)))throw new Error("Event payload must be a non-null object and not an array");const n=this.createEventPayload(e,t);try{if(i){this.transport.send(n),this.logger.debug(`Event sent: ${e}`,[n]);return}this.retryQueue.add(n),this.logger.debug(`Event tracked: ${e}`,[n])}catch(r){throw this.logger.error(`Failed to track event: ${e}`,r),new Error(`Failed to track event: ${e}`)}}rawTrack(e){if(!_(e))throw new Error("Event payload must be an object");this.track("raw",e)}async group(e,t=!1){if(!_(e))throw new Error("Company properties must be an object");if(!e.id||!e.name||!e.created_at)throw new Error("Company properties must include id, name, and created_at");this.persistence.set("companyProps",e),t||await this.track("group",e),this.logger.info("Company identified:",e)}createEventPayload(e,t){const i=this.persistence.get("userProps")||{},n=this.persistence.get("companyProps")||void 0,r=this.persistence.get("userId"),o=this.persistence.get("global_props")||{},c=this.persistence.get(`props_${e}`)||{};let l=t||{};const a={event_id:"",user:{anonymous_id:this.anonymousId,id:r,...i},...n&&{company:n},ids:this.getThirdPartyIds(),utc_time:new Date().toISOString(),local_tz_offset:new Date().getTimezoneOffset(),api_key:this.config.key,src:"usermaven",event_type:e,namespace:this.namespace,...o,...c};if(e==="$autocapture"){const d=this.processAutocaptureAttributes(t||{});a.autocapture_attributes=d}else Array.isArray(this.config.propertyBlacklist)&&this.config.propertyBlacklist.forEach(d=>{delete l[d]}),a.event_attributes=l;return u()&&(a.referer=document.referrer,a.url=window.location.href,a.page_title=document.title,a.doc_path=window.location.pathname,a.doc_host=window.location.hostname,a.doc_search=window.location.search,a.screen_resolution=`${window.screen.width}x${window.screen.height}`,a.vp_size=`${window.innerWidth}x${window.innerHeight}`,a.user_agent=navigator.userAgent,a.user_language=navigator.language,a.doc_encoding=document.characterSet,a.utm=this.getUtmParams()),a}processAutocaptureAttributes(e){let t={};const i=e.$elements||[];return i.length&&(t={...i[0]}),t.el_text=t.$el_text||"",t.event_type=e.$event_type||"",["$ce_version","$event_type","$initial_referrer","$initial_referring_domain","$referrer","$referring_domain","$elements"].forEach(n=>{delete t[n]}),delete t.$el_text,delete t.nth_child,delete t.nth_of_type,t}getCookie(e){var t;return((t=this.cookieManager)==null?void 0:t.get(e))||null}getThirdPartyIds(){const e={};if(u()){const t=this.getCookie("_fbp");t&&(e.fbp=t)}return e}getUtmParams(){const e={},t=ae(window.location.search);return["utm_source","utm_medium","utm_campaign","utm_term","utm_content"].forEach(n=>{t[n]&&(e[n.replace("utm_","")]=t[n])}),e}pageview(){u()?this.track("pageview",{url:window.location.href,referrer:document.referrer,title:document.title},!0):this.logger.warn("Pageview tracking is not available in server-side environments")}setupPageLeaveTracking(){if(!u())return;let e=!1,t=!1;const i=()=>{!e&&!t&&(e=!0,this.track("$pageleave",{url:window.location.href,referrer:document.referrer,title:document.title}))};window.addEventListener("beforeunload",r=>{t=!0,setTimeout(()=>{t=!1},100)}),document.addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&!t&&i()});const n=history.pushState;history.pushState=function(){return i(),n.apply(this,arguments)},window.addEventListener("popstate",i)}getConfig(){return this.config}getLogger(){return this.logger}async reset(e=!1){if(this.persistence.clear(),e&&this.cookieManager){const t=this.config.cookieName||`${this.namespace}_id_${this.config.key}`;this.cookieManager.delete(t),this.anonymousId=this.getOrCreateAnonymousId()}this.logger.info("core state reset",{resetAnonId:e,namespace:this.namespace})}set(e,t){if(!_(e))throw new Error("Properties must be an object");const i=t==null?void 0:t.eventType,n=(t==null?void 0:t.persist)??!0;if(i){let r=this.persistence.get(`props_${i}`)||{};r={...r,...e},this.persistence.set(`props_${i}`,r)}else{let r=this.persistence.get("global_props")||{};r={...r,...e},this.persistence.set("global_props",r)}n&&this.persistence.save(),this.logger.debug("Properties set",{properties:e,eventType:i||"global",persist:n})}setUserId(e){this.persistence.set("userId",e);let t=this.persistence.get("userProps")||{};t.id=e,this.persistence.set("userProps",t),this.persistence.save()}unset(e,t){const i=t==null?void 0:t.eventType,n=(t==null?void 0:t.persist)??!0;if(i){let r=this.persistence.get(`props_${i}`)||{};delete r[e],this.persistence.set(`props_${i}`,r)}else{let r=this.persistence.get("global_props")||{};delete r[e],this.persistence.set("global_props",r)}n&&this.persistence.save(),this.logger.debug(`Property unset: ${e}`,`Event type: ${i||"global"}`)}}function W(s){const e=JSON.parse(JSON.stringify(s)),t=S(e),i={...N,...t};if(!i.key)throw new Error("API key is required!");if(!i.trackingHost)throw new Error("Tracking host is required!");return new Q(i)}function me(s){var n;const e={key:s.getAttribute("data-key")||void 0,trackingHost:s.getAttribute("data-tracking-host")||"https://events.usermaven.com",logLevel:ce(s.getAttribute("data-log-level")),autocapture:s.getAttribute("data-autocapture")==="true",formTracking:s.getAttribute("data-form-tracking")==="true"?"all":!1,autoPageview:s.getAttribute("data-auto-pageview")==="true",useBeaconApi:s.getAttribute("data-use-beacon-api")==="true",forceUseFetch:s.getAttribute("data-force-use-fetch")==="true",gaHook:s.getAttribute("data-ga-hook")==="true",segmentHook:s.getAttribute("data-segment-hook")==="true",randomizeUrl:s.getAttribute("data-randomize-url")==="true",capture3rdPartyCookies:s.getAttribute("data-capture-3rd-party-cookies")==="false"?!1:void 0,idMethod:s.getAttribute("data-id-method")||void 0,privacyPolicy:s.getAttribute("data-privacy-policy")==="strict"?"strict":void 0,ipPolicy:s.getAttribute("data-ip-policy")||void 0,cookiePolicy:s.getAttribute("data-cookie-policy")||void 0,minSendTimeout:parseInt(s.getAttribute("data-min-send-timeout")||"",10)||void 0,maxSendTimeout:parseInt(s.getAttribute("data-max-send-timeout")||"",10)||void 0,maxSendAttempts:parseInt(s.getAttribute("data-max-send-attempts")||"",10)||void 0,propertiesStringMaxLength:parseInt(s.getAttribute("data-properties-string-max-length")||"",10)||null,propertyBlacklist:((n=s.getAttribute("data-property-blacklist"))==null?void 0:n.split(","))||void 0,exclude:s.getAttribute("data-exclude")||void 0,namespace:s.getAttribute("data-namespace")||void 0,crossDomainLinking:s.getAttribute("data-cross-domain-linking")!=="false",domains:s.getAttribute("data-domains")||void 0,maskAllText:s.getAttribute("data-mask-all-text")==="true",maskAllElementAttributes:s.getAttribute("data-mask-all-element-attributes")==="true"},t=W(e),i=e.namespace||"usermaven";u()&&t.pageview(),ye(i,t)}function ye(s,e){let t=!1;const i=[],n=[];function r(){for(;i.length>0;){const a=i.shift();a&&window[s].apply(null,a)}}function o(){n.forEach(a=>a()),n.length=0}window[s]=function(...a){const d=a[0];if(d==="onLoad"){typeof a[1]=="function"&&(t?a[1]():n.push(a[1]));return}if(!t){i.push(a);return}if(typeof e[d]=="function")return e[d].apply(e,a.slice(1));console.error(`Method ${d} not found on UsermavenClient`)};const c=`${s}Q`,l=window[c]||[];for(window[c]=l,l.push=function(...a){return window[s].apply(null,a),Array.prototype.push.apply(this,a)},setTimeout(()=>{t=!0,r(),o(),console.log(`Usermaven client for namespace ${s} is ready`)},0);l.length>0;){const a=l.shift();a&&i.push(a)}}u()&&function(s,e){const t=s.currentScript;function i(){t&&t.src.includes("lib.js")&&me(t)}typeof e<"u"&&(s.readyState==="loading"?s.addEventListener("DOMContentLoaded",i):i())}(document,window),f.LogLevel=g,f.UsermavenClient=Q,f.usermavenClient=W,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,13 @@
1
+ import { Logger } from '../utils/logger';
2
+ export declare class LocalStoragePersistence {
3
+ private storage;
4
+ private prefix;
5
+ private logger;
6
+ constructor(apiKey: string, logger?: Logger);
7
+ set(key: string, value: any): void;
8
+ get(key: string): any;
9
+ remove(key: string): void;
10
+ clear(): void;
11
+ save(): void;
12
+ private load;
13
+ }
@@ -0,0 +1,8 @@
1
+ export declare class MemoryPersistence {
2
+ private storage;
3
+ set(key: string, value: any): void;
4
+ get(key: string): any;
5
+ remove(key: string): void;
6
+ save(): void;
7
+ clear(): void;
8
+ }
@@ -0,0 +1,29 @@
1
+ import { UsermavenClient } from '../core/client';
2
+ import { Config } from '../core/config';
3
+ declare class AutoCapture {
4
+ private logger;
5
+ private client;
6
+ private options;
7
+ private scrollDepth;
8
+ static readonly FORCE_CAPTURE_ATTR = "data-um-force-capture";
9
+ static readonly PREVENT_CAPTURE_ATTR = "data-um-no-capture";
10
+ constructor(client: UsermavenClient, options: Config, logger?: import('../utils/logger').Logger);
11
+ init(): void;
12
+ private addDomEventHandlers;
13
+ private isPageRefresh;
14
+ private captureEvent;
15
+ private shouldCaptureElement;
16
+ private getEventTarget;
17
+ private getElementList;
18
+ private getElementsJson;
19
+ private getPropertiesFromElement;
20
+ private previousElementSibling;
21
+ private getDefaultProperties;
22
+ private sanitizeText;
23
+ private sanitizeUrl;
24
+ private sanitizeAttributeValue;
25
+ private encodeHtml;
26
+ static enabledForProject(token: string, numBuckets?: number, numEnabledBuckets?: number): boolean;
27
+ static isBrowserSupported(): boolean;
28
+ }
29
+ export default AutoCapture;
@@ -0,0 +1,27 @@
1
+ import { UsermavenClient } from '../core/client';
2
+ export default class FormTracking {
3
+ private instance;
4
+ private formElements?;
5
+ private trackingType;
6
+ private options;
7
+ private static instance;
8
+ private constructor();
9
+ private initialize;
10
+ private setupFormTracking;
11
+ private handleFormSubmit;
12
+ private trackFieldChanges;
13
+ static getInstance(instance: UsermavenClient, trackingType?: 'all' | 'tagged' | 'none', options?: FormTrackingOptions): FormTracking;
14
+ private _getFormDetails;
15
+ private _getFieldProps;
16
+ private _getElementAttributes;
17
+ private getSafeText;
18
+ private _scrubPotentiallySensitiveValues;
19
+ private _shouldCaptureValue;
20
+ private _isNullish;
21
+ private _isString;
22
+ private _trim;
23
+ }
24
+ interface FormTrackingOptions {
25
+ trackFieldChanges?: boolean;
26
+ }
27
+ export {};
@@ -0,0 +1,11 @@
1
+ import { UsermavenClient } from '../core/client';
2
+ export declare class PageviewTracking {
3
+ private client;
4
+ private lastPageUrl;
5
+ constructor(client: UsermavenClient);
6
+ private trackInitialPageview;
7
+ private initializePageviewTracking;
8
+ private handlePageview;
9
+ private checkForUrlChange;
10
+ private trackPageview;
11
+ }
@@ -0,0 +1,10 @@
1
+ import { Transport } from '../core/types';
2
+ import { Config } from '../core/config';
3
+ export declare class BeaconTransport implements Transport {
4
+ private trackingHost;
5
+ private logger;
6
+ private config;
7
+ constructor(trackingHost: string, config: Config, logger?: import('../utils/logger').Logger);
8
+ send(payloads: any[]): Promise<void>;
9
+ private constructUrl;
10
+ }
@@ -0,0 +1,13 @@
1
+ import { Transport } from '../core/types';
2
+ import { Logger } from '../utils/logger';
3
+ import { Config } from '../core/config';
4
+ export declare class FetchTransport implements Transport {
5
+ private trackingHost;
6
+ private logger;
7
+ private config;
8
+ constructor(trackingHost: string, config: Config, logger?: Logger);
9
+ send(payloads: any[]): Promise<void>;
10
+ private constructUrl;
11
+ private getCustomHeaders;
12
+ private postHandle;
13
+ }
@@ -0,0 +1,11 @@
1
+ import { Transport } from '../core/types';
2
+ import { Config } from '../core/config';
3
+ export declare class HttpsTransport implements Transport {
4
+ private trackingHost;
5
+ private logger;
6
+ private config;
7
+ constructor(trackingHost: string, config: Config, logger?: import('../utils/logger').Logger);
8
+ send(payloads: any[]): Promise<void>;
9
+ private constructUrl;
10
+ private getCustomHeaders;
11
+ }
@@ -0,0 +1,3 @@
1
+ export interface Transport {
2
+ send(payload: any | any[]): Promise<void>;
3
+ }
@@ -0,0 +1,12 @@
1
+ import { Transport } from '../core/types';
2
+ import { Config } from '../core/config';
3
+ export declare class XhrTransport implements Transport {
4
+ private trackingHost;
5
+ private logger;
6
+ private config;
7
+ constructor(trackingHost: string, config: Config, logger?: import('../utils/logger').Logger);
8
+ send(payloads: any[]): Promise<void>;
9
+ private constructUrl;
10
+ private getCustomHeaders;
11
+ private postHandle;
12
+ }