@gurulu/web 1.1.0 → 1.2.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/dist/index.js CHANGED
@@ -1,3 +1,132 @@
1
+ // src/activation.ts
2
+ function fnv1a32(str) {
3
+ let h = 2166136261;
4
+ for (let i = 0;i < str.length; i++) {
5
+ h ^= str.charCodeAt(i);
6
+ h = Math.imul(h, 16777619);
7
+ }
8
+ return h >>> 0;
9
+ }
10
+ function activationBucket(key, uid) {
11
+ return fnv1a32(`${key}:${uid}`) % 1e4 / 1e4;
12
+ }
13
+ var EMPTY = {
14
+ workspace_id: "",
15
+ popups: [],
16
+ tours: [],
17
+ personalizations: [],
18
+ experiments: []
19
+ };
20
+
21
+ class GuruluActivation {
22
+ cfg;
23
+ data = null;
24
+ pending = null;
25
+ exposed = new Set;
26
+ served = new Set;
27
+ constructor(cfg) {
28
+ this.cfg = cfg;
29
+ }
30
+ async refresh(opts) {
31
+ if (this.pending)
32
+ return this.pending;
33
+ const f = this.cfg.fetchImpl ?? (typeof fetch !== "undefined" ? fetch.bind(globalThis) : null);
34
+ if (!f)
35
+ return EMPTY;
36
+ const uid = this.cfg.getUid();
37
+ const sp = new URLSearchParams;
38
+ if (uid)
39
+ sp.set("uid", uid);
40
+ const winHref = typeof window !== "undefined" && window.location ? window.location.href : "";
41
+ const url = opts?.url ?? winHref;
42
+ if (url)
43
+ sp.set("url", url);
44
+ const ua = typeof navigator !== "undefined" && navigator.userAgent ? navigator.userAgent : "";
45
+ const device = opts?.device ?? (/Mobi|Android/i.test(ua) ? "mobile" : "desktop");
46
+ sp.set("device", device);
47
+ this.pending = (async () => {
48
+ try {
49
+ const res = await f(`${this.cfg.endpoint}/v1/activate?${sp.toString()}`, {
50
+ method: "GET",
51
+ headers: { Authorization: `Bearer ${this.cfg.workspaceKey}` },
52
+ credentials: "omit"
53
+ });
54
+ if (!res.ok)
55
+ return this.data ?? EMPTY;
56
+ this.data = await res.json();
57
+ return this.data;
58
+ } catch {
59
+ return this.data ?? EMPTY;
60
+ } finally {
61
+ this.pending = null;
62
+ }
63
+ })();
64
+ return this.pending;
65
+ }
66
+ getPopups() {
67
+ return this.data?.popups ?? [];
68
+ }
69
+ getTours() {
70
+ return this.data?.tours ?? [];
71
+ }
72
+ getContent(slot) {
73
+ const p = (this.data?.personalizations ?? []).find((x) => x.slot_key === slot);
74
+ if (!p)
75
+ return null;
76
+ if (!this.served.has(p.key)) {
77
+ this.served.add(p.key);
78
+ this.cfg.track("personalization_served", {
79
+ personalization_key: p.key,
80
+ variant_key: p.variant_key,
81
+ is_holdout: p.is_holdout
82
+ });
83
+ }
84
+ return p.content;
85
+ }
86
+ getVariant(experimentKey) {
87
+ const e = (this.data?.experiments ?? []).find((x) => x.key === experimentKey);
88
+ if (!e)
89
+ return null;
90
+ const variant = e.assigned_variant ?? assignLocalVariant(experimentKey, this.cfg.getUid(), e.variants);
91
+ if (variant && !this.exposed.has(experimentKey)) {
92
+ this.exposed.add(experimentKey);
93
+ this.cfg.track("experiment_exposed", {
94
+ experiment_key: experimentKey,
95
+ variant_key: variant
96
+ });
97
+ }
98
+ return variant;
99
+ }
100
+ trackPopup(key, action) {
101
+ this.cfg.track(`popup_${action}`, { popup_key: key });
102
+ }
103
+ trackTour(key, action, stepIndex) {
104
+ this.cfg.track(`tour_${action}`, {
105
+ tour_key: key,
106
+ ...stepIndex !== undefined ? { step_index: stepIndex } : {}
107
+ });
108
+ }
109
+ async saveTourProgress(tourKey, body) {}
110
+ snapshot() {
111
+ return this.data ?? EMPTY;
112
+ }
113
+ }
114
+ function assignLocalVariant(key, uid, variants) {
115
+ const valid = variants.filter((v) => v.weight > 0 && v.key.length > 0);
116
+ if (valid.length === 0 || !uid)
117
+ return null;
118
+ const total = valid.reduce((s, v) => s + v.weight, 0);
119
+ if (total <= 0)
120
+ return null;
121
+ const bucket = activationBucket(key, uid);
122
+ let cum = 0;
123
+ for (const v of valid) {
124
+ cum += v.weight / total;
125
+ if (bucket < cum)
126
+ return v.key;
127
+ }
128
+ return valid[valid.length - 1].key;
129
+ }
1
130
  // src/consent.ts
2
131
  var DEFAULT_API_URL = "https://api.gurulu.io";
3
132
  var STORAGE_PREFIX = "gurulu_consent_";
@@ -351,6 +480,44 @@ function startClickAutocapture(track) {
351
480
  };
352
481
  }
353
482
 
483
+ // src/autocapture/error.ts
484
+ var MAX_STACK = 2000;
485
+ var MAX_MESSAGE = 1000;
486
+ function startErrorAutocapture(track) {
487
+ if (typeof window === "undefined")
488
+ return { stop: () => {
489
+ return;
490
+ } };
491
+ const onError = (ev) => {
492
+ const err = ev.error;
493
+ track({
494
+ message: String(ev.message ?? err?.message ?? "Error").slice(0, MAX_MESSAGE),
495
+ error_type: err?.name ?? "Error",
496
+ ...ev.filename ? { source: ev.filename } : {},
497
+ ...typeof ev.lineno === "number" ? { lineno: ev.lineno } : {},
498
+ ...typeof ev.colno === "number" ? { colno: ev.colno } : {},
499
+ ...err?.stack ? { stack: String(err.stack).slice(0, MAX_STACK) } : {}
500
+ });
501
+ };
502
+ const onRejection = (ev) => {
503
+ const reason = ev.reason;
504
+ const isErr = reason instanceof Error;
505
+ track({
506
+ message: String(isErr ? reason.message : reason).slice(0, MAX_MESSAGE),
507
+ error_type: isErr ? reason.name : "UnhandledRejection",
508
+ ...isErr && reason.stack ? { stack: String(reason.stack).slice(0, MAX_STACK) } : {}
509
+ });
510
+ };
511
+ window.addEventListener("error", onError);
512
+ window.addEventListener("unhandledrejection", onRejection);
513
+ return {
514
+ stop() {
515
+ window.removeEventListener("error", onError);
516
+ window.removeEventListener("unhandledrejection", onRejection);
517
+ }
518
+ };
519
+ }
520
+
354
521
  // src/autocapture/form.ts
355
522
  var SENSITIVE_INPUT_TYPES = new Set(["password", "tel"]);
356
523
  function isSensitiveField(el) {
@@ -701,6 +868,8 @@ function startAutocapture(cfg, sinks) {
701
868
  handles.push(startScrollAutocapture(sinks.scrollDepth));
702
869
  if (merged.web_vitals)
703
870
  handles.push(startWebVitalsAutocapture(sinks.webVital));
871
+ if (merged.js_error)
872
+ handles.push(startErrorAutocapture(sinks.jsError));
704
873
  return {
705
874
  stopAll() {
706
875
  for (const h of handles) {
@@ -1173,6 +1342,7 @@ class Gurulu {
1173
1342
  autocaptureHandle = null;
1174
1343
  testMode = false;
1175
1344
  consent;
1345
+ activation;
1176
1346
  init(opts) {
1177
1347
  if (this.initialized) {
1178
1348
  if (opts.debug && typeof console !== "undefined") {
@@ -1193,6 +1363,12 @@ class Gurulu {
1193
1363
  autoBanner: opts.consent_mode === "banner_required"
1194
1364
  });
1195
1365
  this.consent.init();
1366
+ this.activation = new GuruluActivation({
1367
+ endpoint: opts.endpoint ?? DEFAULT_ENDPOINT,
1368
+ workspaceKey: opts.workspaceKey,
1369
+ getUid: () => getPersonId() ?? this.anonymousId ?? "",
1370
+ track: (key, props) => this.track(key, props)
1371
+ });
1196
1372
  const transport = {
1197
1373
  endpoint: opts.endpoint ?? DEFAULT_ENDPOINT,
1198
1374
  workspaceKey: opts.workspaceKey,
@@ -1234,7 +1410,8 @@ class Gurulu {
1234
1410
  formStarted: (p) => this.queueEvent("form_started", "interaction", p),
1235
1411
  formSubmitted: (p) => this.queueEvent("form_submitted", "interaction", p),
1236
1412
  scrollDepth: (p) => this.queueEvent("scroll_depth", "interaction", p),
1237
- webVital: (p) => this.queueEvent("web_vital", "interaction", p)
1413
+ webVital: (p) => this.queueEvent("web_vital", "interaction", p),
1414
+ jsError: (p) => this.queueEvent("js_error", "interaction", p)
1238
1415
  });
1239
1416
  this.initialized = true;
1240
1417
  }
@@ -1380,6 +1557,9 @@ var publicSdk = {
1380
1557
  get consent() {
1381
1558
  return singleton.consent;
1382
1559
  },
1560
+ get activation() {
1561
+ return singleton.activation;
1562
+ },
1383
1563
  VERSION
1384
1564
  };
1385
1565
  function autoBootstrap() {
@@ -1424,6 +1604,7 @@ export {
1424
1604
  NetworkError,
1425
1605
  InitError,
1426
1606
  GuruluConsent,
1607
+ GuruluActivation,
1427
1608
  Gurulu,
1428
1609
  ConsentBlockedError
1429
1610
  };
package/dist/react.js CHANGED
@@ -1,3 +1,132 @@
1
+ // src/activation.ts
2
+ function fnv1a32(str) {
3
+ let h = 2166136261;
4
+ for (let i = 0;i < str.length; i++) {
5
+ h ^= str.charCodeAt(i);
6
+ h = Math.imul(h, 16777619);
7
+ }
8
+ return h >>> 0;
9
+ }
10
+ function activationBucket(key, uid) {
11
+ return fnv1a32(`${key}:${uid}`) % 1e4 / 1e4;
12
+ }
13
+ var EMPTY = {
14
+ workspace_id: "",
15
+ popups: [],
16
+ tours: [],
17
+ personalizations: [],
18
+ experiments: []
19
+ };
20
+
21
+ class GuruluActivation {
22
+ cfg;
23
+ data = null;
24
+ pending = null;
25
+ exposed = new Set;
26
+ served = new Set;
27
+ constructor(cfg) {
28
+ this.cfg = cfg;
29
+ }
30
+ async refresh(opts) {
31
+ if (this.pending)
32
+ return this.pending;
33
+ const f = this.cfg.fetchImpl ?? (typeof fetch !== "undefined" ? fetch.bind(globalThis) : null);
34
+ if (!f)
35
+ return EMPTY;
36
+ const uid = this.cfg.getUid();
37
+ const sp = new URLSearchParams;
38
+ if (uid)
39
+ sp.set("uid", uid);
40
+ const winHref = typeof window !== "undefined" && window.location ? window.location.href : "";
41
+ const url = opts?.url ?? winHref;
42
+ if (url)
43
+ sp.set("url", url);
44
+ const ua = typeof navigator !== "undefined" && navigator.userAgent ? navigator.userAgent : "";
45
+ const device = opts?.device ?? (/Mobi|Android/i.test(ua) ? "mobile" : "desktop");
46
+ sp.set("device", device);
47
+ this.pending = (async () => {
48
+ try {
49
+ const res = await f(`${this.cfg.endpoint}/v1/activate?${sp.toString()}`, {
50
+ method: "GET",
51
+ headers: { Authorization: `Bearer ${this.cfg.workspaceKey}` },
52
+ credentials: "omit"
53
+ });
54
+ if (!res.ok)
55
+ return this.data ?? EMPTY;
56
+ this.data = await res.json();
57
+ return this.data;
58
+ } catch {
59
+ return this.data ?? EMPTY;
60
+ } finally {
61
+ this.pending = null;
62
+ }
63
+ })();
64
+ return this.pending;
65
+ }
66
+ getPopups() {
67
+ return this.data?.popups ?? [];
68
+ }
69
+ getTours() {
70
+ return this.data?.tours ?? [];
71
+ }
72
+ getContent(slot) {
73
+ const p = (this.data?.personalizations ?? []).find((x) => x.slot_key === slot);
74
+ if (!p)
75
+ return null;
76
+ if (!this.served.has(p.key)) {
77
+ this.served.add(p.key);
78
+ this.cfg.track("personalization_served", {
79
+ personalization_key: p.key,
80
+ variant_key: p.variant_key,
81
+ is_holdout: p.is_holdout
82
+ });
83
+ }
84
+ return p.content;
85
+ }
86
+ getVariant(experimentKey) {
87
+ const e = (this.data?.experiments ?? []).find((x) => x.key === experimentKey);
88
+ if (!e)
89
+ return null;
90
+ const variant = e.assigned_variant ?? assignLocalVariant(experimentKey, this.cfg.getUid(), e.variants);
91
+ if (variant && !this.exposed.has(experimentKey)) {
92
+ this.exposed.add(experimentKey);
93
+ this.cfg.track("experiment_exposed", {
94
+ experiment_key: experimentKey,
95
+ variant_key: variant
96
+ });
97
+ }
98
+ return variant;
99
+ }
100
+ trackPopup(key, action) {
101
+ this.cfg.track(`popup_${action}`, { popup_key: key });
102
+ }
103
+ trackTour(key, action, stepIndex) {
104
+ this.cfg.track(`tour_${action}`, {
105
+ tour_key: key,
106
+ ...stepIndex !== undefined ? { step_index: stepIndex } : {}
107
+ });
108
+ }
109
+ async saveTourProgress(tourKey, body) {}
110
+ snapshot() {
111
+ return this.data ?? EMPTY;
112
+ }
113
+ }
114
+ function assignLocalVariant(key, uid, variants) {
115
+ const valid = variants.filter((v) => v.weight > 0 && v.key.length > 0);
116
+ if (valid.length === 0 || !uid)
117
+ return null;
118
+ const total = valid.reduce((s, v) => s + v.weight, 0);
119
+ if (total <= 0)
120
+ return null;
121
+ const bucket = activationBucket(key, uid);
122
+ let cum = 0;
123
+ for (const v of valid) {
124
+ cum += v.weight / total;
125
+ if (bucket < cum)
126
+ return v.key;
127
+ }
128
+ return valid[valid.length - 1].key;
129
+ }
1
130
  // src/consent.ts
2
131
  var DEFAULT_API_URL = "https://api.gurulu.io";
3
132
  var STORAGE_PREFIX = "gurulu_consent_";
@@ -351,6 +480,44 @@ function startClickAutocapture(track) {
351
480
  };
352
481
  }
353
482
 
483
+ // src/autocapture/error.ts
484
+ var MAX_STACK = 2000;
485
+ var MAX_MESSAGE = 1000;
486
+ function startErrorAutocapture(track) {
487
+ if (typeof window === "undefined")
488
+ return { stop: () => {
489
+ return;
490
+ } };
491
+ const onError = (ev) => {
492
+ const err = ev.error;
493
+ track({
494
+ message: String(ev.message ?? err?.message ?? "Error").slice(0, MAX_MESSAGE),
495
+ error_type: err?.name ?? "Error",
496
+ ...ev.filename ? { source: ev.filename } : {},
497
+ ...typeof ev.lineno === "number" ? { lineno: ev.lineno } : {},
498
+ ...typeof ev.colno === "number" ? { colno: ev.colno } : {},
499
+ ...err?.stack ? { stack: String(err.stack).slice(0, MAX_STACK) } : {}
500
+ });
501
+ };
502
+ const onRejection = (ev) => {
503
+ const reason = ev.reason;
504
+ const isErr = reason instanceof Error;
505
+ track({
506
+ message: String(isErr ? reason.message : reason).slice(0, MAX_MESSAGE),
507
+ error_type: isErr ? reason.name : "UnhandledRejection",
508
+ ...isErr && reason.stack ? { stack: String(reason.stack).slice(0, MAX_STACK) } : {}
509
+ });
510
+ };
511
+ window.addEventListener("error", onError);
512
+ window.addEventListener("unhandledrejection", onRejection);
513
+ return {
514
+ stop() {
515
+ window.removeEventListener("error", onError);
516
+ window.removeEventListener("unhandledrejection", onRejection);
517
+ }
518
+ };
519
+ }
520
+
354
521
  // src/autocapture/form.ts
355
522
  var SENSITIVE_INPUT_TYPES = new Set(["password", "tel"]);
356
523
  function isSensitiveField(el) {
@@ -701,6 +868,8 @@ function startAutocapture(cfg, sinks) {
701
868
  handles.push(startScrollAutocapture(sinks.scrollDepth));
702
869
  if (merged.web_vitals)
703
870
  handles.push(startWebVitalsAutocapture(sinks.webVital));
871
+ if (merged.js_error)
872
+ handles.push(startErrorAutocapture(sinks.jsError));
704
873
  return {
705
874
  stopAll() {
706
875
  for (const h of handles) {
@@ -1173,6 +1342,7 @@ class Gurulu {
1173
1342
  autocaptureHandle = null;
1174
1343
  testMode = false;
1175
1344
  consent;
1345
+ activation;
1176
1346
  init(opts) {
1177
1347
  if (this.initialized) {
1178
1348
  if (opts.debug && typeof console !== "undefined") {
@@ -1193,6 +1363,12 @@ class Gurulu {
1193
1363
  autoBanner: opts.consent_mode === "banner_required"
1194
1364
  });
1195
1365
  this.consent.init();
1366
+ this.activation = new GuruluActivation({
1367
+ endpoint: opts.endpoint ?? DEFAULT_ENDPOINT,
1368
+ workspaceKey: opts.workspaceKey,
1369
+ getUid: () => getPersonId() ?? this.anonymousId ?? "",
1370
+ track: (key, props) => this.track(key, props)
1371
+ });
1196
1372
  const transport = {
1197
1373
  endpoint: opts.endpoint ?? DEFAULT_ENDPOINT,
1198
1374
  workspaceKey: opts.workspaceKey,
@@ -1234,7 +1410,8 @@ class Gurulu {
1234
1410
  formStarted: (p) => this.queueEvent("form_started", "interaction", p),
1235
1411
  formSubmitted: (p) => this.queueEvent("form_submitted", "interaction", p),
1236
1412
  scrollDepth: (p) => this.queueEvent("scroll_depth", "interaction", p),
1237
- webVital: (p) => this.queueEvent("web_vital", "interaction", p)
1413
+ webVital: (p) => this.queueEvent("web_vital", "interaction", p),
1414
+ jsError: (p) => this.queueEvent("js_error", "interaction", p)
1238
1415
  });
1239
1416
  this.initialized = true;
1240
1417
  }
@@ -1380,6 +1557,9 @@ var publicSdk = {
1380
1557
  get consent() {
1381
1558
  return singleton.consent;
1382
1559
  },
1560
+ get activation() {
1561
+ return singleton.activation;
1562
+ },
1383
1563
  VERSION
1384
1564
  };
1385
1565
  function autoBootstrap() {
package/dist/t.js CHANGED
@@ -1,10 +1,10 @@
1
- class Q{workspaceId;apiUrl;fetchImpl;storage;autoBanner;locale;anonymousIdValue;bannerConfigCache=null;bannerEl=null;constructor(u){this.workspaceId=u.workspaceId,this.apiUrl=(u.apiUrl??"https://api.gurulu.io").replace(/\/+$/,""),this.fetchImpl=u.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):Xu),this.storage=u.storage??(typeof globalThis<"u"&&"localStorage"in globalThis?globalThis.localStorage:null),this.autoBanner=u.autoBanner??!0,this.locale=u.locale??Vu(),this.anonymousIdValue=u.anonymousId??this.loadOrCreateAnonId()}async init(){if(typeof window>"u")return;try{let m=await this.fetchImpl(`${this.apiUrl}/v1/consent/banner-config?workspace_id=${encodeURIComponent(this.workspaceId)}`,{method:"GET",credentials:"omit"});if(!m.ok)return;this.bannerConfigCache=await m.json()}catch{return}if(!this.getState()&&this.autoBanner&&this.bannerConfigCache?.mode==="banner_required")this.showBanner()}getState(){if(!this.storage)return null;try{let u=this.storage.getItem(this.storageKey());if(!u)return null;let m=JSON.parse(u);if(m.expiresAt&&new Date(m.expiresAt).getTime()<Date.now())return this.storage.removeItem(this.storageKey()),null;return m}catch{return null}}async setState(u){let m=this.getState()?.categories,n={necessary:!0,analytics:u.analytics??m?.analytics??!1,marketing:u.marketing??m?.marketing??!1,functional:u.functional??m?.functional??!1,personalization:u.personalization??m?.personalization??!1},_=new Date,A=this.bannerConfigCache?.renewal_months??13,C=new Date(_);C.setMonth(C.getMonth()+A);let c={workspaceId:this.workspaceId,anonymousId:this.anonymousIdValue,categories:n,grantedAt:_.toISOString(),expiresAt:C.toISOString(),source:"sdk_api"};if(this.storage)try{this.storage.setItem(this.storageKey(),JSON.stringify(c))}catch{}try{await this.fetchImpl(`${this.apiUrl}/v1/consent/state`,{method:"POST",credentials:"omit",headers:{"content-type":"application/json"},body:JSON.stringify({workspace_id:this.workspaceId,anonymous_id:this.anonymousIdValue,necessary:n.necessary,analytics:n.analytics,marketing:n.marketing,functional:n.functional,personalization:n.personalization,source:"sdk_api"})})}catch{}}showBanner(){if(typeof document>"u")return;if(this.bannerEl)return;let u=this.bannerConfigCache?.banner_config??{},m=this.bannerText(),n=u.brand?.primary_color??"#fafafa",_=u.position??"bottom",A=document.createElement("div");A.setAttribute("data-gurulu-consent-banner",""),A.setAttribute("role","dialog"),A.setAttribute("aria-label",m.heading),A.style.cssText=qu(_),A.innerHTML=Eu(m,n);let C=A.querySelector("[data-gurulu-accept]"),c=A.querySelector("[data-gurulu-reject]");C?.addEventListener("click",()=>{this.setState({analytics:!0,marketing:!0,functional:!0,personalization:!0}),this.hideBanner()}),c?.addEventListener("click",()=>{this.setState({analytics:!1,marketing:!1,functional:!1,personalization:!1}),this.hideBanner()}),document.body.appendChild(A),this.bannerEl=A}hideBanner(){if(this.bannerEl?.parentNode)this.bannerEl.parentNode.removeChild(this.bannerEl);this.bannerEl=null}buildIngestHeader(){let u=this.getState();if(!u)return JSON.stringify({necessary:!0});return JSON.stringify(u.categories)}getAnonymousId(){return this.anonymousIdValue}storageKey(){return`gurulu_consent_${this.workspaceId}`}loadOrCreateAnonId(){if(!this.storage)return G();try{let u=this.storage.getItem("gurulu_anon_id");if(u)return u;let m=G();return this.storage.setItem("gurulu_anon_id",m),m}catch{return G()}}bannerText(){let m=this.bannerConfigCache?.banner_config?.text_overrides?.[this.locale];if(this.locale==="tr")return{heading:m?.heading??"Çerezleri tercih et",body:m?.body??"Deneyimini iyileştirmek için analytics + pazarlama çerezleri kullanıyoruz.",accept:m?.accept??"Tümünü kabul et",reject:m?.reject??"Sadece gerekli olanlar"};return{heading:m?.heading??"Manage cookies",body:m?.body??"We use analytics and marketing cookies to improve your experience.",accept:m?.accept??"Accept all",reject:m?.reject??"Necessary only"}}}function qu(u){switch(u){case"top":return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;top:16px;left:50%;transform:translateX(-50%);";case"bottom-left":return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;bottom:16px;left:16px;";case"bottom-right":return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;bottom:16px;right:16px;";case"modal":return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;top:50%;left:50%;transform:translate(-50%,-50%);";default:return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;bottom:16px;left:50%;transform:translateX(-50%);"}}function Eu(u,m){return`
2
- <div style="margin-bottom:12px;font-weight:600;">${M(u.heading)}</div>
3
- <div style="margin-bottom:16px;color:#a3a3a3;">${M(u.body)}</div>
1
+ function Mu(u){let r=2166136261;for(let o=0;o<u.length;o++)r^=u.charCodeAt(o),r=Math.imul(r,16777619);return r>>>0}function zu(u,r){return Mu(`${u}:${r}`)%1e4/1e4}var d={workspace_id:"",popups:[],tours:[],personalizations:[],experiments:[]};class V{cfg;data=null;pending=null;exposed=new Set;served=new Set;constructor(u){this.cfg=u}async refresh(u){if(this.pending)return this.pending;let r=this.cfg.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):null);if(!r)return d;let o=this.cfg.getUid(),n=new URLSearchParams;if(o)n.set("uid",o);let m=typeof window<"u"&&window.location?window.location.href:"",_=u?.url??m;if(_)n.set("url",_);let c=typeof navigator<"u"&&navigator.userAgent?navigator.userAgent:"",A=u?.device??(/Mobi|Android/i.test(c)?"mobile":"desktop");return n.set("device",A),this.pending=(async()=>{try{let E=await r(`${this.cfg.endpoint}/v1/activate?${n.toString()}`,{method:"GET",headers:{Authorization:`Bearer ${this.cfg.workspaceKey}`},credentials:"omit"});if(!E.ok)return this.data??d;return this.data=await E.json(),this.data}catch{return this.data??d}finally{this.pending=null}})(),this.pending}getPopups(){return this.data?.popups??[]}getTours(){return this.data?.tours??[]}getContent(u){let r=(this.data?.personalizations??[]).find((o)=>o.slot_key===u);if(!r)return null;if(!this.served.has(r.key))this.served.add(r.key),this.cfg.track("personalization_served",{personalization_key:r.key,variant_key:r.variant_key,is_holdout:r.is_holdout});return r.content}getVariant(u){let r=(this.data?.experiments??[]).find((n)=>n.key===u);if(!r)return null;let o=r.assigned_variant??Du(u,this.cfg.getUid(),r.variants);if(o&&!this.exposed.has(u))this.exposed.add(u),this.cfg.track("experiment_exposed",{experiment_key:u,variant_key:o});return o}trackPopup(u,r){this.cfg.track(`popup_${r}`,{popup_key:u})}trackTour(u,r,o){this.cfg.track(`tour_${r}`,{tour_key:u,...o!==void 0?{step_index:o}:{}})}async saveTourProgress(u,r){}snapshot(){return this.data??d}}function Du(u,r,o){let n=o.filter((A)=>A.weight>0&&A.key.length>0);if(n.length===0||!r)return null;let m=n.reduce((A,E)=>A+E.weight,0);if(m<=0)return null;let _=zu(u,r),c=0;for(let A of n)if(c+=A.weight/m,_<c)return A.key;return n[n.length-1].key}class h{workspaceId;apiUrl;fetchImpl;storage;autoBanner;locale;anonymousIdValue;bannerConfigCache=null;bannerEl=null;constructor(u){this.workspaceId=u.workspaceId,this.apiUrl=(u.apiUrl??"https://api.gurulu.io").replace(/\/+$/,""),this.fetchImpl=u.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):$u),this.storage=u.storage??(typeof globalThis<"u"&&"localStorage"in globalThis?globalThis.localStorage:null),this.autoBanner=u.autoBanner??!0,this.locale=u.locale??Vu(),this.anonymousIdValue=u.anonymousId??this.loadOrCreateAnonId()}async init(){if(typeof window>"u")return;try{let r=await this.fetchImpl(`${this.apiUrl}/v1/consent/banner-config?workspace_id=${encodeURIComponent(this.workspaceId)}`,{method:"GET",credentials:"omit"});if(!r.ok)return;this.bannerConfigCache=await r.json()}catch{return}if(!this.getState()&&this.autoBanner&&this.bannerConfigCache?.mode==="banner_required")this.showBanner()}getState(){if(!this.storage)return null;try{let u=this.storage.getItem(this.storageKey());if(!u)return null;let r=JSON.parse(u);if(r.expiresAt&&new Date(r.expiresAt).getTime()<Date.now())return this.storage.removeItem(this.storageKey()),null;return r}catch{return null}}async setState(u){let r=this.getState()?.categories,o={necessary:!0,analytics:u.analytics??r?.analytics??!1,marketing:u.marketing??r?.marketing??!1,functional:u.functional??r?.functional??!1,personalization:u.personalization??r?.personalization??!1},n=new Date,m=this.bannerConfigCache?.renewal_months??13,_=new Date(n);_.setMonth(_.getMonth()+m);let c={workspaceId:this.workspaceId,anonymousId:this.anonymousIdValue,categories:o,grantedAt:n.toISOString(),expiresAt:_.toISOString(),source:"sdk_api"};if(this.storage)try{this.storage.setItem(this.storageKey(),JSON.stringify(c))}catch{}try{await this.fetchImpl(`${this.apiUrl}/v1/consent/state`,{method:"POST",credentials:"omit",headers:{"content-type":"application/json"},body:JSON.stringify({workspace_id:this.workspaceId,anonymous_id:this.anonymousIdValue,necessary:o.necessary,analytics:o.analytics,marketing:o.marketing,functional:o.functional,personalization:o.personalization,source:"sdk_api"})})}catch{}}showBanner(){if(typeof document>"u")return;if(this.bannerEl)return;let u=this.bannerConfigCache?.banner_config??{},r=this.bannerText(),o=u.brand?.primary_color??"#fafafa",n=u.position??"bottom",m=document.createElement("div");m.setAttribute("data-gurulu-consent-banner",""),m.setAttribute("role","dialog"),m.setAttribute("aria-label",r.heading),m.style.cssText=Tu(n),m.innerHTML=qu(r,o);let _=m.querySelector("[data-gurulu-accept]"),c=m.querySelector("[data-gurulu-reject]");_?.addEventListener("click",()=>{this.setState({analytics:!0,marketing:!0,functional:!0,personalization:!0}),this.hideBanner()}),c?.addEventListener("click",()=>{this.setState({analytics:!1,marketing:!1,functional:!1,personalization:!1}),this.hideBanner()}),document.body.appendChild(m),this.bannerEl=m}hideBanner(){if(this.bannerEl?.parentNode)this.bannerEl.parentNode.removeChild(this.bannerEl);this.bannerEl=null}buildIngestHeader(){let u=this.getState();if(!u)return JSON.stringify({necessary:!0});return JSON.stringify(u.categories)}getAnonymousId(){return this.anonymousIdValue}storageKey(){return`gurulu_consent_${this.workspaceId}`}loadOrCreateAnonId(){if(!this.storage)return R();try{let u=this.storage.getItem("gurulu_anon_id");if(u)return u;let r=R();return this.storage.setItem("gurulu_anon_id",r),r}catch{return R()}}bannerText(){let r=this.bannerConfigCache?.banner_config?.text_overrides?.[this.locale];if(this.locale==="tr")return{heading:r?.heading??"Çerezleri tercih et",body:r?.body??"Deneyimini iyileştirmek için analytics + pazarlama çerezleri kullanıyoruz.",accept:r?.accept??"Tümünü kabul et",reject:r?.reject??"Sadece gerekli olanlar"};return{heading:r?.heading??"Manage cookies",body:r?.body??"We use analytics and marketing cookies to improve your experience.",accept:r?.accept??"Accept all",reject:r?.reject??"Necessary only"}}}function Tu(u){switch(u){case"top":return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;top:16px;left:50%;transform:translateX(-50%);";case"bottom-left":return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;bottom:16px;left:16px;";case"bottom-right":return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;bottom:16px;right:16px;";case"modal":return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;top:50%;left:50%;transform:translate(-50%,-50%);";default:return"position:fixed;z-index:2147483647;background:#141414;color:#fafafa;border:1px solid #262626;border-radius:8px;padding:16px;font-family:-apple-system,Segoe UI,Roboto,sans-serif;font-size:14px;line-height:1.5;box-shadow:0 4px 24px rgba(0,0,0,0.4);max-width:480px;bottom:16px;left:50%;transform:translateX(-50%);"}}function qu(u,r){return`
2
+ <div style="margin-bottom:12px;font-weight:600;">${$(u.heading)}</div>
3
+ <div style="margin-bottom:16px;color:#a3a3a3;">${$(u.body)}</div>
4
4
  <div style="display:flex;gap:8px;flex-wrap:wrap;">
5
- <button data-gurulu-accept type="button" style="background:${Nu(m)};color:#0a0a0a;border:none;padding:8px 16px;border-radius:6px;font-weight:600;cursor:pointer;">${M(u.accept)}</button>
6
- <button data-gurulu-reject type="button" style="background:transparent;color:#fafafa;border:1px solid #404040;padding:8px 16px;border-radius:6px;cursor:pointer;">${M(u.reject)}</button>
5
+ <button data-gurulu-accept type="button" style="background:${du(r)};color:#0a0a0a;border:none;padding:8px 16px;border-radius:6px;font-weight:600;cursor:pointer;">${$(u.accept)}</button>
6
+ <button data-gurulu-reject type="button" style="background:transparent;color:#fafafa;border:1px solid #404040;padding:8px 16px;border-radius:6px;cursor:pointer;">${$(u.reject)}</button>
7
7
  </div>
8
- `}function M(u){return u.replace(/[&<>"']/g,(m)=>{switch(m){case"&":return"&amp;";case"<":return"&lt;";case">":return"&gt;";case'"':return"&quot;";case"'":return"&#39;";default:return m}})}function Nu(u){return u.replace(/[^a-zA-Z0-9#()_\-., ]/g,"")}function Vu(){if(typeof navigator>"u")return"en";let u=(navigator.language??"").toLowerCase();if(u.startsWith("tr"))return"tr";if(u.startsWith("zh"))return"zh";if(u.startsWith("ar"))return"ar";return"en"}function G(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return`anon_${crypto.randomUUID()}`;return`anon_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`}async function Xu(){throw Error("fetch not available — provide opts.fetchImpl")}var $u=new Set(["A","BUTTON"]),hu=/\.(pdf|zip|dmg|exe|tar|gz|rar|7z|mp3|mp4|csv|xlsx?|docx?|pptx?)(\?|$)/i;function Ju(u){let m=u;while(m){if(m.hasAttribute?.("data-gurulu-no-track"))return!1;m=m.parentElement}return!0}function Mu(u){let m=u;while(m){if(!m.tagName){m=m.parentElement;continue}if($u.has(m.tagName))return m;if(m.getAttribute?.("role")==="button")return m;if(m.tagName==="INPUT"){let n=m.type?.toLowerCase();if(n==="submit"||n==="button")return m}m=m.parentElement}return null}function Qu(u){let m={};if(!u.attributes)return m;for(let n=0;n<u.attributes.length;n+=1){let _=u.attributes.item(n);if(!_)continue;if(_.name.startsWith("data-gurulu-prop-")){let A=_.name.slice(17);m[A]=_.value}}return m}function f(u){if(typeof document>"u")return{stop:()=>{return}};let m=(n)=>{let _=Mu(n.target);if(!_||!Ju(_))return;let A={element_tag:_.tagName.toLowerCase()};if(_.id)A.element_id=_.id;if(_.className&&typeof _.className==="string")A.element_class=_.className.slice(0,256);let C=(_.textContent??"").trim().slice(0,200);if(C)A.element_text=C;if(_.tagName==="A"){let l=_.href;if(l){A.href=l;try{let D=new URL(l).hostname;if(typeof window<"u"&&D!==window.location.hostname)A.is_outbound=!0}catch{}if(hu.test(l))A.is_download=!0}}let c=_.getAttribute?.("data-gurulu-event");if(c)A.custom_event=c,A.custom_props=Qu(_);u(A)};return document.addEventListener("click",m,!0),{stop(){document.removeEventListener("click",m,!0)}}}var Zu=new Set(["password","tel"]);function i(u){if(u.tagName!=="INPUT")return!1;let m=u,n=(m.type??"").toLowerCase();if(Zu.has(n))return!0;if((m.autocomplete??"").toLowerCase().startsWith("cc-"))return!0;return!1}function w(u){let m=u;while(m){if(m.hasAttribute?.("data-gurulu-no-track"))return!1;m=m.parentElement}return!0}function Fu(u){let m=u;while(m){if(m.tagName==="FORM")return m;m=m.parentElement}return null}function d(u){let m={count:u.elements?.length??0};if(u.id)m.id=u.id;if(u.name)m.name=u.name;return m}function o(u){if(typeof document>"u")return{stop:()=>{return}};let m=new WeakSet,n=(A)=>{let C=A.target;if(!C)return;if(i(C))return;if(!w(C))return;let c=Fu(C);if(!c||m.has(c))return;m.add(c);let l=d(c),D={field_count:l.count};if(l.id)D.form_id=l.id;if(l.name)D.form_name=l.name;u.onStart(D)},_=(A)=>{let C=A.target;if(!C||C.tagName!=="FORM")return;if(!w(C))return;let c=d(C),l=[],D=C.elements;for(let z=0;z<D.length;z+=1){let H=D[z];if(!H)continue;if(i(H))continue;if(!("value"in H))continue;if(typeof H.value==="string"&&H.value.length>0&&H.name)l.push(H.name)}let j={field_count:c.count};if(c.id)j.form_id=c.id;if(c.name)j.form_name=c.name;if(l.length>0)j.filled_fields=l;u.onSubmit(j)};return document.addEventListener("focus",n,!0),document.addEventListener("submit",_,!0),{stop(){document.removeEventListener("focus",n,!0),document.removeEventListener("submit",_,!0)}}}function g(u){if(typeof window>"u"||typeof document>"u")return{stop:()=>{return}};let m=window.location.pathname+window.location.search;function n(){let c=window.location.pathname+window.location.search;if(c===m)return;m=c,u(window.location.href,document.title,document.referrer)}u(window.location.href,document.title,document.referrer);let _=()=>n();window.addEventListener("popstate",_);let A=history.pushState.bind(history),C=history.replaceState.bind(history);return history.pushState=function(...l){let D=A(...l);return queueMicrotask(n),D},history.replaceState=function(...l){let D=C(...l);return queueMicrotask(n),D},{stop(){window.removeEventListener("popstate",_),history.pushState=A,history.replaceState=C}}}var Bu=[25,50,75,90];function O(u){if(typeof window>"u"||typeof document>"u")return{stop:()=>{return}};let m=new Set,n=0,_=()=>{n=0;let{documentElement:C,body:c}=document;if(!C||!c)return;let l=window.scrollY??C.scrollTop??0,D=window.innerHeight??C.clientHeight??0,j=Math.max(c.scrollHeight??0,C.scrollHeight??0);if(j<=D)return;let z=(l+D)/j*100;for(let H of Bu)if(z>=H&&!m.has(H))m.add(H),u({depth_percent:H})},A=()=>{if(n!==0)return;n=requestAnimationFrame(_)};return window.addEventListener("scroll",A,{passive:!0}),{stop(){if(window.removeEventListener("scroll",A),n!==0)cancelAnimationFrame(n)}}}var Gu={LCP:[2500,4000],FID:[100,300],INP:[200,500],CLS:[0.1,0.25],TTFB:[800,1800],FCP:[1800,3000]};function V(u,m){let[n,_]=Gu[u];if(m<=n)return"good";if(m<=_)return"needs-improvement";return"poor"}function Z(u,m,n){if(typeof PerformanceObserver>"u")return null;try{let _=new PerformanceObserver((A)=>n(A.getEntries()));return _.observe({type:u,buffered:m}),_}catch{return null}}function k(u){if(typeof window>"u")return{stop:()=>{return}};let m=[];try{let S=performance.getEntriesByType("navigation")[0];if(S&&S.responseStart>0)u({metric:"TTFB",value:S.responseStart,rating:V("TTFB",S.responseStart)});let T=performance.getEntriesByName("first-contentful-paint")[0];if(T)u({metric:"FCP",value:T.startTime,rating:V("FCP",T.startTime)})}catch{}let n=0,_=Z("largest-contentful-paint",!0,(S)=>{let T=S[S.length-1];if(T)n=T.startTime});if(_)m.push(_);let A=Z("first-input",!0,(S)=>{let T=S[0];if(T){let b=T.processingStart-T.startTime;u({metric:"FID",value:b,rating:V("FID",b)})}});if(A)m.push(A);let C=0,c=Z("event",!0,(S)=>{for(let T of S){let b=T.duration;if(b>C)C=b}});if(c)m.push(c);let l=0,D=Z("layout-shift",!0,(S)=>{for(let T of S){let b=T;if(!b.hadRecentInput)l+=b.value}});if(D)m.push(D);let j=()=>{if(n>0)u({metric:"LCP",value:n,rating:V("LCP",n)});if(C>0)u({metric:"INP",value:C,rating:V("INP",C)});if(l>0)u({metric:"CLS",value:l,rating:V("CLS",l)});n=0,C=0,l=0},z=null,H=null;if(typeof document<"u")z=()=>{if(document.visibilityState==="hidden")j()},H=j,document.addEventListener("visibilitychange",z),window.addEventListener("pagehide",H);return{stop(){for(let S of m)try{S.disconnect()}catch{}if(typeof document<"u"&&z)document.removeEventListener("visibilitychange",z);if(typeof window<"u"&&H)window.removeEventListener("pagehide",H)}}}var Ru={page_view:!0,click:!0,form_started:!0,form_submitted:!0,scroll_depth:!0,web_vitals:!0,outbound_link_click:!0,download_click:!0,js_error:!1,console_error:!1,network_error:!1};function y(u,m){if(u===!1)return{stopAll:()=>{return}};let n={...Ru,...u??{}},_=[];if(n.page_view)_.push(g(m.pageView));if(n.click)_.push(f(m.click));if(n.form_started||n.form_submitted)_.push(o({onStart:n.form_started?m.formStarted:()=>{return},onSubmit:n.form_submitted?m.formSubmitted:()=>{return}}));if(n.scroll_depth)_.push(O(m.scrollDepth));if(n.web_vitals)_.push(k(m.webVital));return{stopAll(){for(let A of _)try{A.stop()}catch{}}}}function X(){return typeof window<"u"&&typeof document<"u"}function W(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return crypto.randomUUID();return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}function I(u){if(!X())return null;try{return window.localStorage.getItem(u)}catch{return null}}function F(u,m){if(!X())return;try{window.localStorage.setItem(u,m)}catch{}}function r(u){if(!X())return;try{window.localStorage.removeItem(u)}catch{}}function Wu(u){if(!X())return null;let m=document.cookie??"";for(let n of m.split(";")){let[_,A]=n.trim().split("=");if(_===u&&A!==void 0)return decodeURIComponent(A)}return null}function R(u,m,n=365){if(!X())return;let _=new Date(Date.now()+n*86400000).toUTCString(),A=window.location.hostname,C=A.split("."),c=C.length>=2?`.${C.slice(-2).join(".")}`:A;try{document.cookie=`${u}=${encodeURIComponent(m)}; path=/; domain=${c}; expires=${_}; SameSite=Lax`}catch{}}function v(){let u=I("gurulu_aid")??Wu("gurulu_aid_mirror");if(u)return F("gurulu_aid",u),R("gurulu_aid_mirror",u),u;let m=W();return F("gurulu_aid",m),R("gurulu_aid_mirror",m),m}function p(u){F("gurulu_pid",u)}function a(){return I("gurulu_pid")}function e(){r("gurulu_pid"),r("gurulu_aid");let u=W();return F("gurulu_aid",u),R("gurulu_aid_mirror",u),u}function s(){return W()}class E extends Error{code;constructor(u,m){super(m);this.code=u,this.name="SDKError"}}class uu extends E{constructor(u){super("SDK_INIT",u);this.name="InitError"}}class N extends E{status;constructor(u,m){super("SDK_NETWORK",u);if(this.name="NetworkError",m!==void 0)this.status=m}}class mu extends E{constructor(u){super("SDK_QUEUE_FULL",u);this.name="QueueFullError"}}class _u extends E{constructor(){super("SDK_OPTED_OUT","tracking disabled — gurulu.optOut() in effect");this.name="OptedOutError"}}class nu extends E{constructor(){super("SDK_CONSENT_BLOCKED","event queued — awaiting consent grant");this.name="ConsentBlockedError"}}var tu=65536;function Au(u,m){let n=new Headers({"content-type":"application/json",authorization:`Bearer ${u.workspaceKey}`,"x-gurulu-sdk":`@gurulu/web@${u.sdkVersion}`});if(m)for(let[_,A]of Object.entries(m))n.set(_,A);return n}async function Cu(u,m,n){let _=u.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):null);if(!_)throw new N("fetch unavailable");let A=`${u.endpoint}/v1/ingest/batch`,C=await _(A,{method:"POST",keepalive:!0,credentials:"omit",headers:Au(u,n),body:JSON.stringify(m)});if(!C.ok)throw new N(`ingest ${C.status}`,C.status)}function cu(u,m){if(typeof navigator>"u"||typeof navigator.sendBeacon!=="function")return!1;let n=`${u.endpoint}/v1/ingest/batch?wk=${encodeURIComponent(u.workspaceKey)}&sdk=${encodeURIComponent(u.sdkVersion)}`;try{let _=JSON.stringify(m);if(_.length>=tu)return!1;let A=new Blob([_],{type:"application/json"});return navigator.sendBeacon(n,A)}catch{return!1}}async function lu(u,m){let n=u.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):null);if(!n)throw new N("fetch unavailable");let _=await n(`${u.endpoint}/v1/ingest/identify`,{method:"POST",keepalive:!0,credentials:"omit",headers:Au(u),body:JSON.stringify(m)});if(!_.ok)throw new N(`identify ${_.status}`,_.status)}var Y="gurulu_queue";function L(){return typeof window<"u"}function Yu(){if(!L())return[];try{let u=window.localStorage.getItem(Y);if(!u)return[];let m=JSON.parse(u);return Array.isArray(m)?m:[]}catch{return[]}}function t(u){if(!L())return;try{if(u.length===0)window.localStorage.removeItem(Y);else window.localStorage.setItem(Y,JSON.stringify(u))}catch{}}class P{opts;buffer;timer=null;flushing=!1;constructor(u){if(this.opts=u,this.buffer=Yu(),this.scheduleNext(),this.installUnloadHooks(),this.buffer.length>0)this.scheduleImmediate()}enqueue(u){if(this.buffer.push(u),t(this.buffer),this.buffer.length>=this.opts.maxQueueSize)this.flush();else this.scheduleNext()}size(){return this.buffer.length}async flush(){if(this.flushing||this.buffer.length===0)return;this.flushing=!0;let u=this.buffer.slice(0);try{await this.sendWithRetry(u),this.buffer=this.buffer.slice(u.length),t(this.buffer)}catch(m){if(this.opts.debug&&typeof console<"u")console.warn("[gurulu] flush failed, retain queue",m)}finally{this.flushing=!1}}flushBeacon(){if(this.buffer.length===0)return;if(cu(this.opts.transport,{events:this.buffer}))this.buffer=[],t(this.buffer)}scheduleNext(){if(this.timer!==null)return;this.timer=setTimeout(()=>{this.timer=null,this.flush()},this.opts.flushIntervalMs)}scheduleImmediate(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null;this.timer=setTimeout(()=>{this.timer=null,this.flush()},50)}async sendWithRetry(u){let m=0,n=3;while(m<n)try{await Cu(this.opts.transport,{events:u});return}catch(_){if(m+=1,m>=n)throw _;let A=2**m*1000;await new Promise((C)=>setTimeout(C,A))}}installUnloadHooks(){if(!L()||typeof document>"u")return;let u=()=>{if(document.visibilityState==="hidden")this.flushBeacon()};try{document.addEventListener("visibilitychange",u),window.addEventListener("pagehide",()=>this.flushBeacon())}catch{}}}function Du(){return typeof window<"u"}function Lu(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return crypto.randomUUID();return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}function h(u){if(!Du())return null;try{return window.localStorage.getItem(u)}catch{return null}}function $(u,m){if(!Du())return;try{window.localStorage.setItem(u,m)}catch{}}function B(u=Date.now()){let m=h("gurulu_sid"),n=Number(h("gurulu_session_started_at")??"0"),_=Number(h("gurulu_last_event_at")??"0");if(m&&n&&u-_<1800000)return $("gurulu_last_event_at",String(u)),{session_id:m,session_started_at:n,is_new:!1};let A=Lu();return $("gurulu_sid",A),$("gurulu_session_started_at",String(u)),$("gurulu_last_event_at",String(u)),{session_id:A,session_started_at:u,is_new:!0}}function Hu(u,m){let n={},_={};if(!u)return{utm:n,click_id:_};let A;try{A=new URL(u)}catch{return{utm:n,click_id:_}}let C=A.searchParams,c=C.get("utm_source");if(c)n.source=c;let l=C.get("utm_medium");if(l)n.medium=l;let D=C.get("utm_campaign");if(D)n.campaign=D;let j=C.get("utm_term");if(j)n.term=j;let z=C.get("utm_content");if(z)n.content=z;let H=C.get("gclid");if(H)_.gclid=H;let S=C.get("fbclid");if(S)_.fbclid=S;let T=C.get("ttclid");if(T)_.ttclid=T;let b=C.get("li_fat_id");if(b)_.li_fat_id=b;return{utm:n,click_id:_}}function Su(u){if(h("gurulu_first_source"))return;$("gurulu_first_source",JSON.stringify(u))}function Tu(){let u=h("gurulu_first_source");if(!u)return null;try{return JSON.parse(u)}catch{return null}}var K="0.1.0",ju="https://ingest.gurulu.io",Pu="https://api.gurulu.io",U="gurulu_opt_out";function zu(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(U)==="1"}catch{return!1}}function bu(u){if(typeof window>"u")return;try{if(u)window.localStorage.setItem(U,"1");else window.localStorage.removeItem(U)}catch{}}function Ku(){return new Date().toISOString()}class J{initialized=!1;opts=null;queue=null;session=null;anonymousId=null;autocaptureHandle=null;testMode=!1;consent;init(u){if(this.initialized){if(u.debug&&typeof console<"u")console.warn("[gurulu] init() already called — ignoring");return}if(typeof window>"u")return;this.opts=u,this.testMode=u.test_mode===!0,this.anonymousId=v(),this.session=B(),this.consent=new Q({workspaceId:u.workspaceKey,apiUrl:u.apiUrl??Pu,anonymousId:this.anonymousId,autoBanner:u.consent_mode==="banner_required"}),this.consent.init();let m={endpoint:u.endpoint??ju,workspaceKey:u.workspaceKey,sdkVersion:K};this.queue=new P({transport:m,flushIntervalMs:u.flush_interval_ms??5000,maxQueueSize:u.max_queue_size??50,...u.debug?{debug:!0}:{}});let n=Hu(window.location.href,document.referrer);if(Object.keys(n.utm).length>0||Object.keys(n.click_id).length>0){let _={utm:n.utm,click_id:n.click_id,referrer:document.referrer,landing_url:window.location.href,captured_at:Date.now()};Su(_)}this.autocaptureHandle=y(u.autocapture,{pageView:(_,A,C)=>this.queueEvent("page_view","interaction",{url:_,title:A,referrer:C}),click:(_)=>{let A=_.custom_event??"element_clicked",C={element_tag:_.element_tag,..._.element_id?{element_id:_.element_id}:{},..._.element_class?{element_class:_.element_class}:{},..._.element_text?{element_text:_.element_text}:{},..._.href?{href:_.href}:{},..._.is_outbound?{is_outbound:!0}:{},..._.is_download?{is_download:!0}:{},..._.custom_props??{}};this.queueEvent(A,"interaction",C)},formStarted:(_)=>this.queueEvent("form_started","interaction",_),formSubmitted:(_)=>this.queueEvent("form_submitted","interaction",_),scrollDepth:(_)=>this.queueEvent("scroll_depth","interaction",_),webVital:(_)=>this.queueEvent("web_vital","interaction",_)}),this.initialized=!0}track(u,m){this.queueEvent(u,"interaction",m)}page(u){if(!this.initialized||typeof window>"u")return;let m=u?.url??window.location.href,n=u?.title??document.title,_=u?.referrer??document.referrer;this.queueEvent("page_view","interaction",{url:m,title:n,referrer:_})}async identify(u,m){if(!this.initialized||zu())return;if(p(u),!this.opts)return;try{await lu({endpoint:this.opts.endpoint??ju,workspaceKey:this.opts.workspaceKey,sdkVersion:K},{anonymous_id:this.anonymousId,external_user_id:u,...m?.email?{email:m.email}:{},...m?.phone?{phone:m.phone}:{},...m?{traits:m}:{}})}catch(n){if(this.opts?.debug&&typeof console<"u")console.warn("[gurulu] identify failed",n)}}reset(){if(this.anonymousId=e(),typeof window<"u")try{window.localStorage.removeItem("gurulu_sid"),window.localStorage.removeItem("gurulu_session_started_at"),window.localStorage.removeItem("gurulu_last_event_at"),window.localStorage.removeItem("gurulu_first_source")}catch{}this.session=B()}async flush(){await this.queue?.flush()}optOut(){bu(!0)}optIn(){bu(!1)}queueEvent(u,m,n){if(!this.initialized||!this.queue||zu())return;if(!this.consentAllowsAnalytics()&&this.opts?.consent_mode==="banner_required")return;this.session=B();let _={anonymous_id:this.anonymousId??"anon_unknown",event_id:s(),event_key:u,event_type:m,occurred_at:Ku(),producer:"script",producer_version:K,...this.session?{session_id:this.session.session_id}:{}},A=a();if(A)_.person_id=A;if(n&&Object.keys(n).length>0)_.properties=n;let C=this.buildContext();if(C)_.context=C;let c=this.snapshotConsent();if(c)_.consent_state=c;if(this.testMode)_.test_mode=!0;this.queue.enqueue(_)}snapshotConsent(){let u=this.consent?.getState();if(!u)return;return{necessary:u.categories.necessary,analytics:u.categories.analytics,marketing:u.categories.marketing,functional:u.categories.functional,personalization:u.categories.personalization}}consentAllowsAnalytics(){let u=this.consent?.getState();if(!u)return!1;return u.categories.analytics===!0}buildContext(){if(typeof window>"u")return;let u={url:window.location.href,referrer:document.referrer,page_title:document.title,user_agent:navigator.userAgent,domain:window.location.hostname},m=Tu();if(m?.utm&&Object.keys(m.utm).length>0)u.utm=m.utm;if(m?.click_id&&Object.keys(m.click_id).length>0)u.click_id=m.click_id;return u}}var Uu="0.1.0",q=new J;function Tm(){return new J}var x={init:(u)=>q.init(u),track:(u,m)=>q.track(u,m),identify:(u,m)=>q.identify(u,m),page:(u)=>q.page(u),reset:()=>q.reset(),flush:()=>q.flush(),optOut:()=>q.optOut(),optIn:()=>q.optIn(),get consent(){return q.consent},VERSION:Uu};function xu(){if(typeof document>"u")return;let u=document.currentScript,m=!u?document.querySelector("script[data-workspace]"):u;if(!m)return;let n=m.getAttribute("data-workspace");if(!n)return;let _={workspaceKey:n},A=m.getAttribute("data-endpoint");if(A)_.endpoint=A;let C=m.getAttribute("data-api-url");if(C)_.apiUrl=C;let c=m.getAttribute("data-consent");if(c==="banner_required"||c==="allow_by_default")_.consent_mode=c;let l=m.getAttribute("data-allowlist");if(l)_.cross_domain_allowlist=l.split(",").map((D)=>D.trim());if(x.init(_),typeof window<"u")window.gurulu=x}xu();var Em=x;export{Em as default,Tm as createGurulu,xu as autoBootstrap,Uu as VERSION,E as SDKError,mu as QueueFullError,_u as OptedOutError,N as NetworkError,uu as InitError,Q as GuruluConsent,J as Gurulu,nu as ConsentBlockedError};
8
+ `}function $(u){return u.replace(/[&<>"']/g,(r)=>{switch(r){case"&":return"&amp;";case"<":return"&lt;";case">":return"&gt;";case'"':return"&quot;";case"'":return"&#39;";default:return r}})}function du(u){return u.replace(/[^a-zA-Z0-9#()_\-., ]/g,"")}function Vu(){if(typeof navigator>"u")return"en";let u=(navigator.language??"").toLowerCase();if(u.startsWith("tr"))return"tr";if(u.startsWith("zh"))return"zh";if(u.startsWith("ar"))return"ar";return"en"}function R(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return`anon_${crypto.randomUUID()}`;return`anon_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`}async function $u(){throw Error("fetch not available — provide opts.fetchImpl")}var hu=new Set(["A","BUTTON"]),Nu=/\.(pdf|zip|dmg|exe|tar|gz|rar|7z|mp3|mp4|csv|xlsx?|docx?|pptx?)(\?|$)/i;function Gu(u){let r=u;while(r){if(r.hasAttribute?.("data-gurulu-no-track"))return!1;r=r.parentElement}return!0}function Qu(u){let r=u;while(r){if(!r.tagName){r=r.parentElement;continue}if(hu.has(r.tagName))return r;if(r.getAttribute?.("role")==="button")return r;if(r.tagName==="INPUT"){let o=r.type?.toLowerCase();if(o==="submit"||o==="button")return r}r=r.parentElement}return null}function Ru(u){let r={};if(!u.attributes)return r;for(let o=0;o<u.attributes.length;o+=1){let n=u.attributes.item(o);if(!n)continue;if(n.name.startsWith("data-gurulu-prop-")){let m=n.name.slice(17);r[m]=n.value}}return r}function U(u){if(typeof document>"u")return{stop:()=>{return}};let r=(o)=>{let n=Qu(o.target);if(!n||!Gu(n))return;let m={element_tag:n.tagName.toLowerCase()};if(n.id)m.element_id=n.id;if(n.className&&typeof n.className==="string")m.element_class=n.className.slice(0,256);let _=(n.textContent??"").trim().slice(0,200);if(_)m.element_text=_;if(n.tagName==="A"){let A=n.href;if(A){m.href=A;try{let E=new URL(A).hostname;if(typeof window<"u"&&E!==window.location.hostname)m.is_outbound=!0}catch{}if(Nu.test(A))m.is_download=!0}}let c=n.getAttribute?.("data-gurulu-event");if(c)m.custom_event=c,m.custom_props=Ru(n);u(m)};return document.addEventListener("click",r,!0),{stop(){document.removeEventListener("click",r,!0)}}}function K(u){if(typeof window>"u")return{stop:()=>{return}};let r=(n)=>{let m=n.error;u({message:String(n.message??m?.message??"Error").slice(0,1000),error_type:m?.name??"Error",...n.filename?{source:n.filename}:{},...typeof n.lineno==="number"?{lineno:n.lineno}:{},...typeof n.colno==="number"?{colno:n.colno}:{},...m?.stack?{stack:String(m.stack).slice(0,2000)}:{}})},o=(n)=>{let m=n.reason,_=m instanceof Error;u({message:String(_?m.message:m).slice(0,1000),error_type:_?m.name:"UnhandledRejection",..._&&m.stack?{stack:String(m.stack).slice(0,2000)}:{}})};return window.addEventListener("error",r),window.addEventListener("unhandledrejection",o),{stop(){window.removeEventListener("error",r),window.removeEventListener("unhandledrejection",o)}}}var Zu=new Set(["password","tel"]);function O(u){if(u.tagName!=="INPUT")return!1;let r=u,o=(r.type??"").toLowerCase();if(Zu.has(o))return!0;if((r.autocomplete??"").toLowerCase().startsWith("cc-"))return!0;return!1}function k(u){let r=u;while(r){if(r.hasAttribute?.("data-gurulu-no-track"))return!1;r=r.parentElement}return!0}function iu(u){let r=u;while(r){if(r.tagName==="FORM")return r;r=r.parentElement}return null}function x(u){let r={count:u.elements?.length??0};if(u.id)r.id=u.id;if(u.name)r.name=u.name;return r}function y(u){if(typeof document>"u")return{stop:()=>{return}};let r=new WeakSet,o=(m)=>{let _=m.target;if(!_)return;if(O(_))return;if(!k(_))return;let c=iu(_);if(!c||r.has(c))return;r.add(c);let A=x(c),E={field_count:A.count};if(A.id)E.form_id=A.id;if(A.name)E.form_name=A.name;u.onStart(E)},n=(m)=>{let _=m.target;if(!_||_.tagName!=="FORM")return;if(!k(_))return;let c=x(_),A=[],E=_.elements;for(let t=0;t<E.length;t+=1){let l=E[t];if(!l)continue;if(O(l))continue;if(!("value"in l))continue;if(typeof l.value==="string"&&l.value.length>0&&l.name)A.push(l.name)}let j={field_count:c.count};if(c.id)j.form_id=c.id;if(c.name)j.form_name=c.name;if(A.length>0)j.filled_fields=A;u.onSubmit(j)};return document.addEventListener("focus",o,!0),document.addEventListener("submit",n,!0),{stop(){document.removeEventListener("focus",o,!0),document.removeEventListener("submit",n,!0)}}}function I(u){if(typeof window>"u"||typeof document>"u")return{stop:()=>{return}};let r=window.location.pathname+window.location.search;function o(){let c=window.location.pathname+window.location.search;if(c===r)return;r=c,u(window.location.href,document.title,document.referrer)}u(window.location.href,document.title,document.referrer);let n=()=>o();window.addEventListener("popstate",n);let m=history.pushState.bind(history),_=history.replaceState.bind(history);return history.pushState=function(...A){let E=m(...A);return queueMicrotask(o),E},history.replaceState=function(...A){let E=_(...A);return queueMicrotask(o),E},{stop(){window.removeEventListener("popstate",n),history.pushState=m,history.replaceState=_}}}var fu=[25,50,75,90];function v(u){if(typeof window>"u"||typeof document>"u")return{stop:()=>{return}};let r=new Set,o=0,n=()=>{o=0;let{documentElement:_,body:c}=document;if(!_||!c)return;let A=window.scrollY??_.scrollTop??0,E=window.innerHeight??_.clientHeight??0,j=Math.max(c.scrollHeight??0,_.scrollHeight??0);if(j<=E)return;let t=(A+E)/j*100;for(let l of fu)if(t>=l&&!r.has(l))r.add(l),u({depth_percent:l})},m=()=>{if(o!==0)return;o=requestAnimationFrame(n)};return window.addEventListener("scroll",m,{passive:!0}),{stop(){if(window.removeEventListener("scroll",m),o!==0)cancelAnimationFrame(o)}}}var Fu={LCP:[2500,4000],FID:[100,300],INP:[200,500],CLS:[0.1,0.25],TTFB:[800,1800],FCP:[1800,3000]};function M(u,r){let[o,n]=Fu[u];if(r<=o)return"good";if(r<=n)return"needs-improvement";return"poor"}function N(u,r,o){if(typeof PerformanceObserver>"u")return null;try{let n=new PerformanceObserver((m)=>o(m.getEntries()));return n.observe({type:u,buffered:r}),n}catch{return null}}function a(u){if(typeof window>"u")return{stop:()=>{return}};let r=[];try{let C=performance.getEntriesByType("navigation")[0];if(C&&C.responseStart>0)u({metric:"TTFB",value:C.responseStart,rating:M("TTFB",C.responseStart)});let S=performance.getEntriesByName("first-contentful-paint")[0];if(S)u({metric:"FCP",value:S.startTime,rating:M("FCP",S.startTime)})}catch{}let o=0,n=N("largest-contentful-paint",!0,(C)=>{let S=C[C.length-1];if(S)o=S.startTime});if(n)r.push(n);let m=N("first-input",!0,(C)=>{let S=C[0];if(S){let H=S.processingStart-S.startTime;u({metric:"FID",value:H,rating:M("FID",H)})}});if(m)r.push(m);let _=0,c=N("event",!0,(C)=>{for(let S of C){let H=S.duration;if(H>_)_=H}});if(c)r.push(c);let A=0,E=N("layout-shift",!0,(C)=>{for(let S of C){let H=S;if(!H.hadRecentInput)A+=H.value}});if(E)r.push(E);let j=()=>{if(o>0)u({metric:"LCP",value:o,rating:M("LCP",o)});if(_>0)u({metric:"INP",value:_,rating:M("INP",_)});if(A>0)u({metric:"CLS",value:A,rating:M("CLS",A)});o=0,_=0,A=0},t=null,l=null;if(typeof document<"u")t=()=>{if(document.visibilityState==="hidden")j()},l=j,document.addEventListener("visibilitychange",t),window.addEventListener("pagehide",l);return{stop(){for(let C of r)try{C.disconnect()}catch{}if(typeof document<"u"&&t)document.removeEventListener("visibilitychange",t);if(typeof window<"u"&&l)window.removeEventListener("pagehide",l)}}}var gu={page_view:!0,click:!0,form_started:!0,form_submitted:!0,scroll_depth:!0,web_vitals:!0,outbound_link_click:!0,download_click:!0,js_error:!1,console_error:!1,network_error:!1};function e(u,r){if(u===!1)return{stopAll:()=>{return}};let o={...gu,...u??{}},n=[];if(o.page_view)n.push(I(r.pageView));if(o.click)n.push(U(r.click));if(o.form_started||o.form_submitted)n.push(y({onStart:o.form_started?r.formStarted:()=>{return},onSubmit:o.form_submitted?r.formSubmitted:()=>{return}}));if(o.scroll_depth)n.push(v(r.scrollDepth));if(o.web_vitals)n.push(a(r.webVital));if(o.js_error)n.push(K(r.jsError));return{stopAll(){for(let m of n)try{m.stop()}catch{}}}}function z(){return typeof window<"u"&&typeof document<"u"}function i(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return crypto.randomUUID();return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}function s(u){if(!z())return null;try{return window.localStorage.getItem(u)}catch{return null}}function G(u,r){if(!z())return;try{window.localStorage.setItem(u,r)}catch{}}function p(u){if(!z())return;try{window.localStorage.removeItem(u)}catch{}}function wu(u){if(!z())return null;let r=document.cookie??"";for(let o of r.split(";")){let[n,m]=o.trim().split("=");if(n===u&&m!==void 0)return decodeURIComponent(m)}return null}function Z(u,r,o=365){if(!z())return;let n=new Date(Date.now()+o*86400000).toUTCString(),m=window.location.hostname,_=m.split("."),c=_.length>=2?`.${_.slice(-2).join(".")}`:m;try{document.cookie=`${u}=${encodeURIComponent(r)}; path=/; domain=${c}; expires=${n}; SameSite=Lax`}catch{}}function uu(){let u=s("gurulu_aid")??wu("gurulu_aid_mirror");if(u)return G("gurulu_aid",u),Z("gurulu_aid_mirror",u),u;let r=i();return G("gurulu_aid",r),Z("gurulu_aid_mirror",r),r}function ru(u){G("gurulu_pid",u)}function f(){return s("gurulu_pid")}function nu(){p("gurulu_pid"),p("gurulu_aid");let u=i();return G("gurulu_aid",u),Z("gurulu_aid_mirror",u),u}function ou(){return i()}class J extends Error{code;constructor(u,r){super(r);this.code=u,this.name="SDKError"}}class mu extends J{constructor(u){super("SDK_INIT",u);this.name="InitError"}}class b extends J{status;constructor(u,r){super("SDK_NETWORK",u);if(this.name="NetworkError",r!==void 0)this.status=r}}class _u extends J{constructor(u){super("SDK_QUEUE_FULL",u);this.name="QueueFullError"}}class cu extends J{constructor(){super("SDK_OPTED_OUT","tracking disabled — gurulu.optOut() in effect");this.name="OptedOutError"}}class Au extends J{constructor(){super("SDK_CONSENT_BLOCKED","event queued — awaiting consent grant");this.name="ConsentBlockedError"}}var Wu=65536;function Eu(u,r){let o=new Headers({"content-type":"application/json",authorization:`Bearer ${u.workspaceKey}`,"x-gurulu-sdk":`@gurulu/web@${u.sdkVersion}`});if(r)for(let[n,m]of Object.entries(r))o.set(n,m);return o}async function lu(u,r,o){let n=u.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):null);if(!n)throw new b("fetch unavailable");let m=`${u.endpoint}/v1/ingest/batch`,_=await n(m,{method:"POST",keepalive:!0,credentials:"omit",headers:Eu(u,o),body:JSON.stringify(r)});if(!_.ok)throw new b(`ingest ${_.status}`,_.status)}function Cu(u,r){if(typeof navigator>"u"||typeof navigator.sendBeacon!=="function")return!1;let o=`${u.endpoint}/v1/ingest/batch?wk=${encodeURIComponent(u.workspaceKey)}&sdk=${encodeURIComponent(u.sdkVersion)}`;try{let n=JSON.stringify(r);if(n.length>=Wu)return!1;let m=new Blob([n],{type:"application/json"});return navigator.sendBeacon(o,m)}catch{return!1}}async function Su(u,r){let o=u.fetchImpl??(typeof fetch<"u"?fetch.bind(globalThis):null);if(!o)throw new b("fetch unavailable");let n=await o(`${u.endpoint}/v1/ingest/identify`,{method:"POST",keepalive:!0,credentials:"omit",headers:Eu(u),body:JSON.stringify(r)});if(!n.ok)throw new b(`identify ${n.status}`,n.status)}var g="gurulu_queue";function w(){return typeof window<"u"}function Bu(){if(!w())return[];try{let u=window.localStorage.getItem(g);if(!u)return[];let r=JSON.parse(u);return Array.isArray(r)?r:[]}catch{return[]}}function F(u){if(!w())return;try{if(u.length===0)window.localStorage.removeItem(g);else window.localStorage.setItem(g,JSON.stringify(u))}catch{}}class W{opts;buffer;timer=null;flushing=!1;constructor(u){if(this.opts=u,this.buffer=Bu(),this.scheduleNext(),this.installUnloadHooks(),this.buffer.length>0)this.scheduleImmediate()}enqueue(u){if(this.buffer.push(u),F(this.buffer),this.buffer.length>=this.opts.maxQueueSize)this.flush();else this.scheduleNext()}size(){return this.buffer.length}async flush(){if(this.flushing||this.buffer.length===0)return;this.flushing=!0;let u=this.buffer.slice(0);try{await this.sendWithRetry(u),this.buffer=this.buffer.slice(u.length),F(this.buffer)}catch(r){if(this.opts.debug&&typeof console<"u")console.warn("[gurulu] flush failed, retain queue",r)}finally{this.flushing=!1}}flushBeacon(){if(this.buffer.length===0)return;if(Cu(this.opts.transport,{events:this.buffer}))this.buffer=[],F(this.buffer)}scheduleNext(){if(this.timer!==null)return;this.timer=setTimeout(()=>{this.timer=null,this.flush()},this.opts.flushIntervalMs)}scheduleImmediate(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null;this.timer=setTimeout(()=>{this.timer=null,this.flush()},50)}async sendWithRetry(u){let r=0,o=3;while(r<o)try{await lu(this.opts.transport,{events:u});return}catch(n){if(r+=1,r>=o)throw n;let m=2**r*1000;await new Promise((_)=>setTimeout(_,m))}}installUnloadHooks(){if(!w()||typeof document>"u")return;let u=()=>{if(document.visibilityState==="hidden")this.flushBeacon()};try{document.addEventListener("visibilitychange",u),window.addEventListener("pagehide",()=>this.flushBeacon())}catch{}}}function ju(){return typeof window<"u"}function Lu(){if(typeof crypto<"u"&&typeof crypto.randomUUID==="function")return crypto.randomUUID();return`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}function T(u){if(!ju())return null;try{return window.localStorage.getItem(u)}catch{return null}}function D(u,r){if(!ju())return;try{window.localStorage.setItem(u,r)}catch{}}function Q(u=Date.now()){let r=T("gurulu_sid"),o=Number(T("gurulu_session_started_at")??"0"),n=Number(T("gurulu_last_event_at")??"0");if(r&&o&&u-n<1800000)return D("gurulu_last_event_at",String(u)),{session_id:r,session_started_at:o,is_new:!1};let m=Lu();return D("gurulu_sid",m),D("gurulu_session_started_at",String(u)),D("gurulu_last_event_at",String(u)),{session_id:m,session_started_at:u,is_new:!0}}function tu(u,r){let o={},n={};if(!u)return{utm:o,click_id:n};let m;try{m=new URL(u)}catch{return{utm:o,click_id:n}}let _=m.searchParams,c=_.get("utm_source");if(c)o.source=c;let A=_.get("utm_medium");if(A)o.medium=A;let E=_.get("utm_campaign");if(E)o.campaign=E;let j=_.get("utm_term");if(j)o.term=j;let t=_.get("utm_content");if(t)o.content=t;let l=_.get("gclid");if(l)n.gclid=l;let C=_.get("fbclid");if(C)n.fbclid=C;let S=_.get("ttclid");if(S)n.ttclid=S;let H=_.get("li_fat_id");if(H)n.li_fat_id=H;return{utm:o,click_id:n}}function Hu(u){if(T("gurulu_first_source"))return;D("gurulu_first_source",JSON.stringify(u))}function Xu(){let u=T("gurulu_first_source");if(!u)return null;try{return JSON.parse(u)}catch{return null}}var B="0.1.0",L="https://ingest.gurulu.io",Yu="https://api.gurulu.io",Y="gurulu_opt_out";function Ju(){if(typeof window>"u")return!1;try{return window.localStorage.getItem(Y)==="1"}catch{return!1}}function bu(u){if(typeof window>"u")return;try{if(u)window.localStorage.setItem(Y,"1");else window.localStorage.removeItem(Y)}catch{}}function Pu(){return new Date().toISOString()}class q{initialized=!1;opts=null;queue=null;session=null;anonymousId=null;autocaptureHandle=null;testMode=!1;consent;activation;init(u){if(this.initialized){if(u.debug&&typeof console<"u")console.warn("[gurulu] init() already called — ignoring");return}if(typeof window>"u")return;this.opts=u,this.testMode=u.test_mode===!0,this.anonymousId=uu(),this.session=Q(),this.consent=new h({workspaceId:u.workspaceKey,apiUrl:u.apiUrl??Yu,anonymousId:this.anonymousId,autoBanner:u.consent_mode==="banner_required"}),this.consent.init(),this.activation=new V({endpoint:u.endpoint??L,workspaceKey:u.workspaceKey,getUid:()=>f()??this.anonymousId??"",track:(n,m)=>this.track(n,m)});let r={endpoint:u.endpoint??L,workspaceKey:u.workspaceKey,sdkVersion:B};this.queue=new W({transport:r,flushIntervalMs:u.flush_interval_ms??5000,maxQueueSize:u.max_queue_size??50,...u.debug?{debug:!0}:{}});let o=tu(window.location.href,document.referrer);if(Object.keys(o.utm).length>0||Object.keys(o.click_id).length>0){let n={utm:o.utm,click_id:o.click_id,referrer:document.referrer,landing_url:window.location.href,captured_at:Date.now()};Hu(n)}this.autocaptureHandle=e(u.autocapture,{pageView:(n,m,_)=>this.queueEvent("page_view","interaction",{url:n,title:m,referrer:_}),click:(n)=>{let m=n.custom_event??"element_clicked",_={element_tag:n.element_tag,...n.element_id?{element_id:n.element_id}:{},...n.element_class?{element_class:n.element_class}:{},...n.element_text?{element_text:n.element_text}:{},...n.href?{href:n.href}:{},...n.is_outbound?{is_outbound:!0}:{},...n.is_download?{is_download:!0}:{},...n.custom_props??{}};this.queueEvent(m,"interaction",_)},formStarted:(n)=>this.queueEvent("form_started","interaction",n),formSubmitted:(n)=>this.queueEvent("form_submitted","interaction",n),scrollDepth:(n)=>this.queueEvent("scroll_depth","interaction",n),webVital:(n)=>this.queueEvent("web_vital","interaction",n),jsError:(n)=>this.queueEvent("js_error","interaction",n)}),this.initialized=!0}track(u,r){this.queueEvent(u,"interaction",r)}page(u){if(!this.initialized||typeof window>"u")return;let r=u?.url??window.location.href,o=u?.title??document.title,n=u?.referrer??document.referrer;this.queueEvent("page_view","interaction",{url:r,title:o,referrer:n})}async identify(u,r){if(!this.initialized||Ju())return;if(ru(u),!this.opts)return;try{await Su({endpoint:this.opts.endpoint??L,workspaceKey:this.opts.workspaceKey,sdkVersion:B},{anonymous_id:this.anonymousId,external_user_id:u,...r?.email?{email:r.email}:{},...r?.phone?{phone:r.phone}:{},...r?{traits:r}:{}})}catch(o){if(this.opts?.debug&&typeof console<"u")console.warn("[gurulu] identify failed",o)}}reset(){if(this.anonymousId=nu(),typeof window<"u")try{window.localStorage.removeItem("gurulu_sid"),window.localStorage.removeItem("gurulu_session_started_at"),window.localStorage.removeItem("gurulu_last_event_at"),window.localStorage.removeItem("gurulu_first_source")}catch{}this.session=Q()}async flush(){await this.queue?.flush()}optOut(){bu(!0)}optIn(){bu(!1)}queueEvent(u,r,o){if(!this.initialized||!this.queue||Ju())return;if(!this.consentAllowsAnalytics()&&this.opts?.consent_mode==="banner_required")return;this.session=Q();let n={anonymous_id:this.anonymousId??"anon_unknown",event_id:ou(),event_key:u,event_type:r,occurred_at:Pu(),producer:"script",producer_version:B,...this.session?{session_id:this.session.session_id}:{}},m=f();if(m)n.person_id=m;if(o&&Object.keys(o).length>0)n.properties=o;let _=this.buildContext();if(_)n.context=_;let c=this.snapshotConsent();if(c)n.consent_state=c;if(this.testMode)n.test_mode=!0;this.queue.enqueue(n)}snapshotConsent(){let u=this.consent?.getState();if(!u)return;return{necessary:u.categories.necessary,analytics:u.categories.analytics,marketing:u.categories.marketing,functional:u.categories.functional,personalization:u.categories.personalization}}consentAllowsAnalytics(){let u=this.consent?.getState();if(!u)return!1;return u.categories.analytics===!0}buildContext(){if(typeof window>"u")return;let u={url:window.location.href,referrer:document.referrer,page_title:document.title,user_agent:navigator.userAgent,domain:window.location.hostname},r=Xu();if(r?.utm&&Object.keys(r.utm).length>0)u.utm=r.utm;if(r?.click_id&&Object.keys(r.click_id).length>0)u.click_id=r.click_id;return u}}var Uu="0.1.0",X=new q;function Tr(){return new q}var P={init:(u)=>X.init(u),track:(u,r)=>X.track(u,r),identify:(u,r)=>X.identify(u,r),page:(u)=>X.page(u),reset:()=>X.reset(),flush:()=>X.flush(),optOut:()=>X.optOut(),optIn:()=>X.optIn(),get consent(){return X.consent},get activation(){return X.activation},VERSION:Uu};function Ku(){if(typeof document>"u")return;let u=document.currentScript,r=!u?document.querySelector("script[data-workspace]"):u;if(!r)return;let o=r.getAttribute("data-workspace");if(!o)return;let n={workspaceKey:o},m=r.getAttribute("data-endpoint");if(m)n.endpoint=m;let _=r.getAttribute("data-api-url");if(_)n.apiUrl=_;let c=r.getAttribute("data-consent");if(c==="banner_required"||c==="allow_by_default")n.consent_mode=c;let A=r.getAttribute("data-allowlist");if(A)n.cross_domain_allowlist=A.split(",").map((E)=>E.trim());if(P.init(n),typeof window<"u")window.gurulu=P}Ku();var Nr=P;export{Nr as default,Tr as createGurulu,Ku as autoBootstrap,Uu as VERSION,J as SDKError,_u as QueueFullError,cu as OptedOutError,b as NetworkError,mu as InitError,h as GuruluConsent,V as GuruluActivation,q as Gurulu,Au as ConsentBlockedError};
9
9
 
10
- //# debugId=399296B48A9012C664756E2164756E21
10
+ //# debugId=AF94586E9911F89164756E2164756E21