@drivemetadata-ai/sdk 0.1.1-beta.1 → 0.1.1-beta.2

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.
Files changed (42) hide show
  1. package/README.md +18 -15
  2. package/dist/angular/index.cjs +118 -115
  3. package/dist/angular/index.cjs.map +1 -1
  4. package/dist/angular/index.d.cts +2 -2
  5. package/dist/angular/index.d.ts +2 -2
  6. package/dist/angular/index.js +118 -115
  7. package/dist/angular/index.js.map +1 -1
  8. package/dist/browser/index.cjs +119 -116
  9. package/dist/browser/index.cjs.map +1 -1
  10. package/dist/browser/index.d.cts +5 -68
  11. package/dist/browser/index.d.ts +5 -68
  12. package/dist/browser/index.js +119 -116
  13. package/dist/browser/index.js.map +1 -1
  14. package/dist/next/index.cjs +119 -115
  15. package/dist/next/index.cjs.map +1 -1
  16. package/dist/next/index.d.cts +1 -1
  17. package/dist/next/index.d.ts +1 -1
  18. package/dist/next/index.js +119 -115
  19. package/dist/next/index.js.map +1 -1
  20. package/dist/node/index.cjs +80 -7
  21. package/dist/node/index.cjs.map +1 -1
  22. package/dist/node/index.d.cts +7 -1
  23. package/dist/node/index.d.ts +7 -1
  24. package/dist/node/index.js +80 -7
  25. package/dist/node/index.js.map +1 -1
  26. package/dist/react/index.cjs +119 -115
  27. package/dist/react/index.cjs.map +1 -1
  28. package/dist/react/index.d.cts +2 -2
  29. package/dist/react/index.d.ts +2 -2
  30. package/dist/react/index.js +119 -115
  31. package/dist/react/index.js.map +1 -1
  32. package/dist/{types-BwtS0ZDu.d.cts → types--V8TVIqT.d.cts} +7 -3
  33. package/dist/{types-BwtS0ZDu.d.ts → types--V8TVIqT.d.ts} +7 -3
  34. package/docs/angular-integration.md +6 -6
  35. package/docs/index.md +4 -6
  36. package/docs/integration.md +322 -0
  37. package/docs/node-server-integration.md +16 -7
  38. package/docs/npm-browser-sdk.md +4 -8
  39. package/docs/react-next-integration.md +9 -9
  40. package/docs/security-privacy.md +11 -11
  41. package/package.json +4 -5
  42. package/docs/migration-cdn-to-npm.md +0 -99
@@ -37,53 +37,62 @@ __export(browser_exports, {
37
37
  });
38
38
  module.exports = __toCommonJS(browser_exports);
39
39
 
40
- // src/core/config.ts
41
- function requireString(value, field) {
42
- if (typeof value !== "string" || value.trim() === "") {
43
- throw new Error(`DMD SDK config ${field} is required`);
40
+ // src/core/backend-payload.ts
41
+ function formatUtcTimestamp(value) {
42
+ if (typeof value !== "string") return (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
43
+ const date = new Date(value);
44
+ if (Number.isNaN(date.getTime())) return value;
45
+ return date.toISOString().replace("T", " ").slice(0, 19);
46
+ }
47
+ function cleanObject(value) {
48
+ if (Array.isArray(value)) {
49
+ const cleaned = value.map((item) => cleanObject(item)).filter((item) => item !== null && item !== void 0 && item !== "");
50
+ return cleaned.length > 0 ? cleaned : void 0;
51
+ }
52
+ if (value && typeof value === "object") {
53
+ const cleaned = Object.fromEntries(
54
+ Object.entries(value).map(([key, item]) => [key, cleanObject(item)]).filter(([, item]) => {
55
+ if (item === null || item === void 0 || item === "") return false;
56
+ if (typeof item === "object" && !Array.isArray(item) && Object.keys(item).length === 0) return false;
57
+ return true;
58
+ })
59
+ );
60
+ return Object.keys(cleaned).length > 0 ? cleaned : void 0;
44
61
  }
45
62
  return value;
46
63
  }
47
- function normalizeBrowserConfig(config) {
48
- const writeKey = config.writeKey || config.token;
49
- const legacyConfig = {
50
- client_id: requireString(config.clientId, "clientId"),
51
- workspace_id: requireString(config.workspaceId, "workspaceId"),
52
- app_id: requireString(config.appId, "appId"),
53
- token: requireString(writeKey, "writeKey")
64
+ function createBackendCollectorPayload(input) {
65
+ const eventData = input.eventData && typeof input.eventData === "object" ? input.eventData : {};
66
+ const page2 = eventData.page && typeof eventData.page === "object" ? eventData.page : {};
67
+ const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);
68
+ const normalizedEventData = {
69
+ ...eventData,
70
+ timestamp,
71
+ requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),
72
+ requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)
73
+ };
74
+ const metaData = {
75
+ ...normalizedEventData,
76
+ requestId: input.requestId,
77
+ timestamp,
78
+ eventType: input.eventType,
79
+ requestFrom: input.requestFrom ?? "3",
80
+ clientId: input.clientId,
81
+ workspaceId: input.workspaceId,
82
+ token: input.token,
83
+ anonymousId: eventData.anonymousId ?? input.anonymousId,
84
+ sessionId: eventData.sessionId ?? input.sessionId,
85
+ ua: input.ua,
86
+ appDetails: { app_id: input.appId },
87
+ page: { ...page2, url: page2.url ?? input.pageUrl },
88
+ requestSentAt: normalizedEventData.requestSentAt,
89
+ requestReceivedAt: normalizedEventData.requestReceivedAt
54
90
  };
55
- if (config.apiHost !== void 0) legacyConfig.api_host = config.apiHost;
56
- if (config.uiHost !== void 0) legacyConfig.ui_host = config.uiHost;
57
- if (config.deeplink !== void 0) legacyConfig.deeplink = config.deeplink;
58
- if (config.debug !== void 0) legacyConfig.debug = config.debug;
59
- if (config.consent !== void 0) legacyConfig.consent = config.consent;
60
- if (config.gdprConsent !== void 0) legacyConfig.gdprConsent = config.gdprConsent;
61
- if (config.autocapture !== void 0) legacyConfig.autocapture = config.autocapture;
62
- if (config.capturePageview !== void 0) legacyConfig.capture_pageview = config.capturePageview;
63
- if (config.capturePageleave !== void 0) legacyConfig.capture_pageleave = config.capturePageleave;
64
- if (config.captureDeadClicks !== void 0) legacyConfig.capture_dead_clicks = config.captureDeadClicks;
65
- if (config.crossSubdomainCookie !== void 0) legacyConfig.cross_subdomain_cookie = config.crossSubdomainCookie;
66
- if (config.disablePersistence !== void 0) legacyConfig.disable_persistence = config.disablePersistence;
67
- if (config.disableSurveys !== void 0) legacyConfig.disable_surveys = config.disableSurveys;
68
- if (config.disableSessionRecording !== void 0) legacyConfig.disable_session_recording = config.disableSessionRecording;
69
- if (config.enableHeatmaps !== void 0) legacyConfig.enable_heatmaps = config.enableHeatmaps;
70
- if (config.maskAllText !== void 0) legacyConfig.mask_all_text = config.maskAllText;
71
- if (config.maskAllElementAttributes !== void 0) {
72
- legacyConfig.mask_all_element_attributes = config.maskAllElementAttributes;
73
- }
74
- if (config.persistence !== void 0) legacyConfig.persistence = config.persistence;
75
- if (config.propertyDenylist !== void 0) legacyConfig.property_denylist = config.propertyDenylist;
76
- if (config.sessionIdleTimeoutSeconds !== void 0) {
77
- legacyConfig.session_idle_timeout_seconds = config.sessionIdleTimeoutSeconds;
78
- }
79
- if (config.beforeSend !== void 0) legacyConfig.before_send = config.beforeSend;
80
- return legacyConfig;
91
+ const payload = { metaData };
92
+ return cleanObject(payload);
81
93
  }
82
94
 
83
95
  // src/core/environment.ts
84
- function isBrowserRuntime() {
85
- return typeof window !== "undefined" && typeof document !== "undefined";
86
- }
87
96
  function getBrowserWindow() {
88
97
  return typeof window === "undefined" ? void 0 : window;
89
98
  }
@@ -143,8 +152,9 @@ function stableStringify(value) {
143
152
  );
144
153
  }
145
154
  function createIdempotencyKey(payload, messageId) {
146
- const event = String(payload.event ?? payload.type ?? "event");
147
- const properties = payload.properties;
155
+ const metaData = payload.metaData;
156
+ const event = String(metaData?.eventType ?? payload.event ?? payload.type ?? "event");
157
+ const properties = metaData ?? payload.properties;
148
158
  const orderId = properties?.orderId ?? properties?.order_id ?? properties?.transaction_id;
149
159
  if (orderId !== void 0) return `${event}:${String(orderId)}`;
150
160
  return `${event}:${stableStringify(properties ?? {}) || messageId}`;
@@ -245,7 +255,17 @@ function createDeliveryManager(config) {
245
255
  persistQueue();
246
256
  }
247
257
  function withEnvelope(payload) {
248
- const messageId = String(payload.messageId ?? createId("msg"));
258
+ const metaData = payload.metaData;
259
+ const messageId = String(metaData?.requestId ?? payload.messageId ?? createId("msg"));
260
+ if (metaData) {
261
+ return {
262
+ ...payload,
263
+ metaData: {
264
+ ...metaData,
265
+ requestId: messageId
266
+ }
267
+ };
268
+ }
249
269
  return {
250
270
  ...payload,
251
271
  messageId,
@@ -271,7 +291,7 @@ function createDeliveryManager(config) {
271
291
  const body = withEnvelope(payload);
272
292
  if (payloadByteLength(body) > maxPayloadBytes) {
273
293
  recordDrop({
274
- messageId: String(body.messageId),
294
+ messageId: String(body.metaData?.requestId ?? body.messageId),
275
295
  reason: "payload_too_large",
276
296
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
277
297
  });
@@ -284,7 +304,7 @@ function createDeliveryManager(config) {
284
304
  const deliveryError = error instanceof Error ? error : new Error(String(error));
285
305
  recordError(deliveryError);
286
306
  enqueue({
287
- messageId: String(body.messageId),
307
+ messageId: String(body.metaData?.requestId ?? body.messageId),
288
308
  savedAt: Date.now(),
289
309
  attempts: 1,
290
310
  lastError: deliveryError.message,
@@ -459,6 +479,12 @@ function endpointFromConfig(config) {
459
479
  const host = config.apiHost ?? "https://sdk.drivemetadata.com/v2";
460
480
  return `${host.replace(/\/$/, "")}/data-collector`;
461
481
  }
482
+ function requireConfigString(value, field) {
483
+ if (typeof value !== "string" || value.trim() === "") {
484
+ throw new Error(`DMD SDK config ${field} is required`);
485
+ }
486
+ return value;
487
+ }
462
488
  function getBrowserStorage() {
463
489
  const browserWindow = getBrowserWindow();
464
490
  try {
@@ -473,6 +499,10 @@ var DriveMetaDataSDK = class {
473
499
  this.queue = [];
474
500
  this.offline = false;
475
501
  this.droppedEvents = 0;
502
+ requireConfigString(config.clientId, "clientId");
503
+ requireConfigString(config.workspaceId, "workspaceId");
504
+ requireConfigString(config.appId, "appId");
505
+ requireConfigString(config.writeKey || config.token, "writeKey or token");
476
506
  this.config = config;
477
507
  this.endpoint = endpointFromConfig(config);
478
508
  const storage = getBrowserStorage();
@@ -496,6 +526,7 @@ var DriveMetaDataSDK = class {
496
526
  this.maxRetryDelayMs = config.delivery?.maxRetryDelayMs ?? 3e4;
497
527
  this.writeKey = config.writeKey || config.token || "";
498
528
  this.identity = { anonymousId: createId2("anon") };
529
+ this.sessionId = createId2("session");
499
530
  this.consentState = normalizeConsent(config.gdprConsent ?? config.consent);
500
531
  this.gdprConsent = this.consentState.analytics;
501
532
  if (!config.delivery?.disableLifecycleFlush) {
@@ -641,7 +672,8 @@ var DriveMetaDataSDK = class {
641
672
  workspaceId: this.config.workspaceId,
642
673
  appId: this.config.appId,
643
674
  writeKey: this.writeKey,
644
- consent: this.consentState
675
+ consent: this.consentState,
676
+ sessionId: this.sessionId
645
677
  };
646
678
  if (this.identity.userId !== void 0) prepared.userId = this.identity.userId;
647
679
  if (this.identity.groupId !== void 0) prepared.groupId = this.identity.groupId;
@@ -665,7 +697,31 @@ var DriveMetaDataSDK = class {
665
697
  if (!validation.ok) {
666
698
  this.lastError = `DMD SDK schema warning: ${validation.errors.join(", ")}`;
667
699
  }
668
- this.sendEvent(prepared);
700
+ this.sendEvent(this.toCollectorPayload(prepared));
701
+ }
702
+ toCollectorPayload(prepared) {
703
+ const browserWindow = getBrowserWindow();
704
+ return createBackendCollectorPayload({
705
+ requestId: prepared.messageId,
706
+ timestamp: prepared.timestamp,
707
+ eventType: prepared.event,
708
+ clientId: prepared.clientId,
709
+ workspaceId: prepared.workspaceId,
710
+ token: prepared.writeKey,
711
+ anonymousId: prepared.anonymousId,
712
+ sessionId: prepared.sessionId,
713
+ ua: browserWindow?.navigator?.userAgent,
714
+ appId: prepared.appId,
715
+ pageUrl: browserWindow?.location?.href,
716
+ eventData: {
717
+ ...prepared.properties,
718
+ anonymousId: prepared.anonymousId,
719
+ sessionId: prepared.sessionId,
720
+ timestamp: prepared.timestamp,
721
+ requestSentAt: prepared.timestamp,
722
+ requestReceivedAt: prepared.timestamp
723
+ }
724
+ });
669
725
  }
670
726
  recordDrop(type, reason, event) {
671
727
  this.droppedEvents += 1;
@@ -679,22 +735,6 @@ var DriveMetaDataSDK = class {
679
735
  }
680
736
  };
681
737
 
682
- // src/browser/legacy-loader.ts
683
- function getLegacySdkInstanceFromWindow() {
684
- const browserWindow = getBrowserWindow();
685
- return browserWindow?.__DriveMetaDataSDKInstance;
686
- }
687
- function ensureLegacySdkLoaded() {
688
- if (!isBrowserRuntime()) {
689
- throw new Error("DMD legacy SDK is only available in a browser runtime");
690
- }
691
- const browserWindow = getBrowserWindow();
692
- if (!browserWindow?.DriveMetaDataSDK) {
693
- throw new Error("DMD legacy SDK constructor is missing from window.DriveMetaDataSDK");
694
- }
695
- return browserWindow.DriveMetaDataSDK;
696
- }
697
-
698
738
  // src/browser/client.ts
699
739
  var singleton;
700
740
  var publicSingleton;
@@ -703,56 +743,34 @@ var lastError;
703
743
  var lastDroppedEvent;
704
744
  function createPublicClient(instance) {
705
745
  return {
706
- __legacy: instance,
707
746
  track(event, properties, options) {
708
- if (instance.trackEvent) {
709
- instance.trackEvent(event, properties, options);
710
- return;
711
- }
712
- instance.sendEvent?.({ eventName: event, event, properties, options });
747
+ instance.trackEvent(event, properties, options);
713
748
  },
714
749
  identify(userId, traits, options) {
715
- if (instance.identify) {
716
- instance.identify(userId, traits, options);
717
- return;
718
- }
719
- instance.identifyUser?.(userId, traits);
750
+ instance.identify(userId, traits, options);
720
751
  },
721
752
  page(name, properties, options) {
722
- if (instance.page) {
723
- instance.page(name, properties, options);
724
- return;
725
- }
726
- instance.trackPageview?.();
753
+ instance.page(name, properties, options);
727
754
  },
728
755
  group(groupId, traits, options) {
729
- instance.group?.(groupId, traits, options);
756
+ instance.group(groupId, traits, options);
730
757
  },
731
758
  alias(previousId, userId, options) {
732
- instance.alias?.(previousId, userId, options);
759
+ instance.alias(previousId, userId, options);
733
760
  },
734
761
  async flush() {
735
- await instance.flush?.();
762
+ await instance.flush();
736
763
  },
737
764
  reset() {
738
- instance.reset?.();
765
+ instance.reset();
739
766
  singleton = void 0;
740
767
  publicSingleton = void 0;
741
768
  },
742
769
  setConsent(consent2) {
743
- if (instance.setConsent) {
744
- instance.setConsent(consent2);
745
- return;
746
- }
747
- if (typeof consent2 === "string") {
748
- instance.gdprConsent = consent2;
749
- }
770
+ instance.setConsent(consent2);
750
771
  },
751
772
  getHealth() {
752
- if (instance.getHealth) {
753
- return instance.getHealth();
754
- }
755
- return getDmdHealth();
773
+ return instance.getHealth();
756
774
  }
757
775
  };
758
776
  }
@@ -777,23 +795,8 @@ function initDmdSDK(config) {
777
795
  if (publicSingleton) {
778
796
  return publicSingleton;
779
797
  }
780
- const legacyConfig = normalizeBrowserConfig(config);
781
- const existingInstance = getLegacySdkInstanceFromWindow();
782
- if (existingInstance) {
783
- return setSingleton(existingInstance);
784
- }
785
798
  try {
786
- let instance;
787
- try {
788
- const LegacySdk = ensureLegacySdkLoaded();
789
- instance = new LegacySdk(legacyConfig);
790
- } catch (error) {
791
- if (error instanceof Error && error.message.includes("constructor is missing")) {
792
- instance = new DriveMetaDataSDK(config);
793
- } else {
794
- throw error;
795
- }
796
- }
799
+ const instance = new DriveMetaDataSDK(config);
797
800
  return setSingleton(instance);
798
801
  } catch (error) {
799
802
  lastError = error instanceof Error ? error.message : String(error);
@@ -868,14 +871,14 @@ async function ready() {
868
871
  return getDmdSDK();
869
872
  }
870
873
  function getDmdHealth() {
871
- if (singleton?.getHealth) {
874
+ if (singleton) {
872
875
  return singleton.getHealth();
873
876
  }
874
877
  const health = {
875
- initialized: Boolean(singleton?.initialized ?? singleton),
876
- consent: singleton?.gdprConsent ?? "pending",
877
- queueSize: singleton?.queue?.length ?? 0,
878
- offline: Boolean(singleton?.offline),
878
+ initialized: false,
879
+ consent: "pending",
880
+ queueSize: 0,
881
+ offline: false,
879
882
  droppedEvents
880
883
  };
881
884
  if (lastError !== void 0) {
@@ -887,7 +890,7 @@ function getDmdHealth() {
887
890
  return health;
888
891
  }
889
892
  function resetDmdSDKForTests() {
890
- singleton?.reset?.();
893
+ singleton?.reset();
891
894
  singleton = void 0;
892
895
  publicSingleton = void 0;
893
896
  droppedEvents = 0;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/browser/index.ts","../../src/core/config.ts","../../src/core/environment.ts","../../src/browser/core/consent.ts","../../src/browser/core/delivery.ts","../../src/browser/core/privacy.ts","../../src/browser/core/schema.ts","../../src/browser/core/DriveMetaDataSDK.ts","../../src/browser/legacy-loader.ts","../../src/browser/client.ts"],"sourcesContent":["export {\n alias,\n consent,\n getDmdHealth,\n getDmdSDK,\n flush,\n group,\n identify,\n initDmdSDK,\n page,\n ready,\n reset,\n resetDmdSDKForTests,\n setConsent,\n track\n} from './client';\n\nexport type {\n DmdBrowserClient,\n DmdBrowserConfig,\n DmdConsentInput,\n DmdConsentPurpose,\n DmdConsentState,\n DmdDeliveryDropReason,\n DmdDeliveryEventDiagnostic,\n DmdEventPayload,\n DmdEventOptions,\n DmdHealthStatus\n} from '../core/types';\n\nexport type {\n DmdDroppedEventDiagnostic,\n DmdDroppedEventReason,\n DmdDroppedEventType\n} from '../core/diagnostics';\n","import type { DmdBrowserConfig, DmdLegacyConfig } from './types';\n\nfunction requireString(value: string | undefined, field: string): string {\n if (typeof value !== 'string' || value.trim() === '') {\n throw new Error(`DMD SDK config ${field} is required`);\n }\n return value;\n}\n\nexport function normalizeBrowserConfig(config: DmdBrowserConfig): DmdLegacyConfig {\n const writeKey = config.writeKey || config.token;\n const legacyConfig: DmdLegacyConfig = {\n client_id: requireString(config.clientId, 'clientId'),\n workspace_id: requireString(config.workspaceId, 'workspaceId'),\n app_id: requireString(config.appId, 'appId'),\n token: requireString(writeKey, 'writeKey')\n };\n\n if (config.apiHost !== undefined) legacyConfig.api_host = config.apiHost;\n if (config.uiHost !== undefined) legacyConfig.ui_host = config.uiHost;\n if (config.deeplink !== undefined) legacyConfig.deeplink = config.deeplink;\n if (config.debug !== undefined) legacyConfig.debug = config.debug;\n if (config.consent !== undefined) legacyConfig.consent = config.consent;\n if (config.gdprConsent !== undefined) legacyConfig.gdprConsent = config.gdprConsent;\n if (config.autocapture !== undefined) legacyConfig.autocapture = config.autocapture;\n if (config.capturePageview !== undefined) legacyConfig.capture_pageview = config.capturePageview;\n if (config.capturePageleave !== undefined) legacyConfig.capture_pageleave = config.capturePageleave;\n if (config.captureDeadClicks !== undefined) legacyConfig.capture_dead_clicks = config.captureDeadClicks;\n if (config.crossSubdomainCookie !== undefined) legacyConfig.cross_subdomain_cookie = config.crossSubdomainCookie;\n if (config.disablePersistence !== undefined) legacyConfig.disable_persistence = config.disablePersistence;\n if (config.disableSurveys !== undefined) legacyConfig.disable_surveys = config.disableSurveys;\n if (config.disableSessionRecording !== undefined) legacyConfig.disable_session_recording = config.disableSessionRecording;\n if (config.enableHeatmaps !== undefined) legacyConfig.enable_heatmaps = config.enableHeatmaps;\n if (config.maskAllText !== undefined) legacyConfig.mask_all_text = config.maskAllText;\n if (config.maskAllElementAttributes !== undefined) {\n legacyConfig.mask_all_element_attributes = config.maskAllElementAttributes;\n }\n if (config.persistence !== undefined) legacyConfig.persistence = config.persistence;\n if (config.propertyDenylist !== undefined) legacyConfig.property_denylist = config.propertyDenylist;\n if (config.sessionIdleTimeoutSeconds !== undefined) {\n legacyConfig.session_idle_timeout_seconds = config.sessionIdleTimeoutSeconds;\n }\n if (config.beforeSend !== undefined) legacyConfig.before_send = config.beforeSend;\n\n return legacyConfig;\n}\n","export function isBrowserRuntime(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nexport function getBrowserWindow(): Window | undefined {\n return typeof window === 'undefined' ? undefined : window;\n}\n","import type {\n DmdConsentInput,\n DmdConsentPurpose,\n DmdConsentState,\n DmdPurposeConsent\n} from './types';\n\nexport type DmdResolvedConsent = Record<DmdConsentPurpose, DmdConsentState>;\n\nconst purposes: DmdConsentPurpose[] = [\n 'analytics',\n 'advertising',\n 'personalization',\n 'functional',\n 'saleOfData'\n];\n\nfunction normalizeConsentValue(value: unknown): DmdConsentState {\n if (value === true) return 'granted';\n if (value === false) return 'denied';\n if (value === 'granted' || value === 'denied' || value === 'pending') return value;\n return 'pending';\n}\n\nexport function normalizeConsent(input: DmdConsentInput | undefined): DmdResolvedConsent {\n const defaultValue = normalizeConsentValue(input ?? 'pending');\n const resolved = Object.fromEntries(\n purposes.map(purpose => [purpose, defaultValue])\n ) as DmdResolvedConsent;\n\n if (input && typeof input === 'object') {\n for (const purpose of purposes) {\n const value = input[purpose];\n if (value !== undefined) {\n resolved[purpose] = normalizeConsentValue(value);\n }\n }\n }\n\n return resolved;\n}\n\nexport function mergeConsent(current: DmdResolvedConsent, update: DmdPurposeConsent): DmdResolvedConsent {\n const next = { ...current };\n for (const [purpose, value] of Object.entries(update) as Array<[DmdConsentPurpose, DmdConsentState]>) {\n next[purpose] = normalizeConsentValue(value);\n }\n return next;\n}\n\nexport function canCollectPurpose(consent: DmdResolvedConsent, purpose: DmdConsentPurpose): boolean {\n return consent[purpose] === 'granted';\n}\n","export interface DmdQueuedRecord {\n messageId: string;\n savedAt: number;\n attempts: number;\n lastError?: string;\n payload: Record<string, unknown>;\n}\n\nexport interface DmdDeliveryDiagnostics {\n queued: number;\n inFlight: number;\n dropped: Array<{ messageId?: string; reason: string; timestamp: string }>;\n lastError?: string;\n}\n\nexport interface DmdDeliveryManager {\n send(payload: Record<string, unknown>): Promise<void>;\n flushQueue(): Promise<void>;\n clearQueue(reason: string): void;\n enqueueForTests(record: DmdQueuedRecord): void;\n flushExpired(): void;\n acquireFlushLease(): boolean;\n releaseFlushLease(): void;\n getDiagnostics(): DmdDeliveryDiagnostics;\n}\n\nexport interface DmdDeliveryStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): unknown;\n removeItem(key: string): unknown;\n}\n\nfunction createId(prefix: string): string {\n return `${prefix}_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\nfunction stableStringify(value: unknown): string {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return JSON.stringify(value);\n }\n return JSON.stringify(\n Object.fromEntries(\n Object.entries(value as Record<string, unknown>).sort(([left], [right]) => left.localeCompare(right))\n )\n );\n}\n\nfunction createIdempotencyKey(payload: Record<string, unknown>, messageId: string): string {\n const event = String(payload.event ?? payload.type ?? 'event');\n const properties = payload.properties as Record<string, unknown> | undefined;\n const orderId = properties?.orderId ?? properties?.order_id ?? properties?.transaction_id;\n if (orderId !== undefined) return `${event}:${String(orderId)}`;\n return `${event}:${stableStringify(properties ?? {}) || messageId}`;\n}\n\nexport function createDeliveryManager(config: {\n endpoint: string;\n fetch?: typeof fetch;\n queueTtlMs?: number;\n maxQueueSize?: number;\n storage?: DmdDeliveryStorage;\n queueKey?: string;\n lockKey?: string;\n lockTtlMs?: number;\n tabId?: string;\n retryDelayMs?: number;\n maxRetryDelayMs?: number;\n maxPayloadBytes?: number;\n batchSize?: number;\n onDrop?: (event: { messageId?: string; reason: string; timestamp: string }) => void;\n onError?: (error: Error) => void;\n}): DmdDeliveryManager {\n const queue: DmdQueuedRecord[] = [];\n const diagnostics: DmdDeliveryDiagnostics = { queued: 0, inFlight: 0, dropped: [] };\n const maxQueueSize = config.maxQueueSize ?? 100;\n const queueKey = config.queueKey ?? 'dmd_delivery_queue';\n const lockKey = config.lockKey ?? 'dmd_delivery_flush_lock';\n const lockTtlMs = config.lockTtlMs ?? 5_000;\n const tabId = config.tabId ?? createId('tab');\n const batchSize = config.batchSize ?? 25;\n const maxPayloadBytes = config.maxPayloadBytes ?? 64_000;\n\n function recordDrop(event: { messageId?: string; reason: string; timestamp: string }): void {\n diagnostics.dropped.push(event);\n config.onDrop?.(event);\n }\n\n function recordError(error: Error): void {\n diagnostics.lastError = error.message;\n config.onError?.(error);\n }\n\n function payloadByteLength(payload: Record<string, unknown>): number {\n const serialized = JSON.stringify(payload);\n if (typeof TextEncoder !== 'undefined') {\n return new TextEncoder().encode(serialized).length;\n }\n return serialized.length;\n }\n\n function recordStorageUnavailable(): void {\n recordDrop({\n reason: 'storage_unavailable',\n timestamp: new Date().toISOString()\n });\n }\n\n function safeGetItem(key: string): string | null {\n try {\n return config.storage?.getItem(key) ?? null;\n } catch {\n recordStorageUnavailable();\n return null;\n }\n }\n\n function safeSetItem(key: string, value: string): boolean {\n try {\n config.storage?.setItem(key, value);\n return true;\n } catch {\n recordStorageUnavailable();\n return false;\n }\n }\n\n function safeRemoveItem(key: string): boolean {\n try {\n config.storage?.removeItem(key);\n return true;\n } catch {\n recordStorageUnavailable();\n return false;\n }\n }\n\n function persistQueue(): void {\n if (!config.storage) return;\n if (queue.length === 0) {\n safeRemoveItem(queueKey);\n return;\n }\n safeSetItem(queueKey, JSON.stringify(queue));\n }\n\n function loadQueue(): void {\n if (!config.storage) return;\n const rawQueue = safeGetItem(queueKey);\n if (!rawQueue) return;\n try {\n const records = JSON.parse(rawQueue) as DmdQueuedRecord[];\n queue.splice(0, queue.length, ...records.filter(record => record && typeof record.messageId === 'string'));\n diagnostics.queued = queue.length;\n } catch {\n safeRemoveItem(queueKey);\n recordDrop({\n reason: 'queue_corrupt',\n timestamp: new Date().toISOString()\n });\n }\n }\n\n function enqueue(record: DmdQueuedRecord): void {\n queue.push(record);\n while (queue.length > maxQueueSize) {\n const dropped = queue.shift();\n const diagnostic: { messageId?: string; reason: string; timestamp: string } = {\n reason: 'queue_limit_exceeded',\n timestamp: new Date().toISOString()\n };\n if (dropped?.messageId !== undefined) diagnostic.messageId = dropped.messageId;\n recordDrop(diagnostic);\n }\n diagnostics.queued = queue.length;\n persistQueue();\n }\n\n function withEnvelope(payload: Record<string, unknown>): Record<string, unknown> {\n const messageId = String(payload.messageId ?? createId('msg'));\n return {\n ...payload,\n messageId,\n idempotencyKey: String(payload.idempotencyKey ?? createIdempotencyKey(payload, messageId))\n };\n }\n\n async function deliver(body: Record<string, unknown>): Promise<void> {\n const fetchImpl = config.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== 'function') {\n throw new Error('fetch_unavailable');\n }\n\n const response = await fetchImpl(config.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n keepalive: true\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n }\n\n loadQueue();\n\n return {\n async send(payload: Record<string, unknown>): Promise<void> {\n const body = withEnvelope(payload);\n\n if (payloadByteLength(body) > maxPayloadBytes) {\n recordDrop({\n messageId: String(body.messageId),\n reason: 'payload_too_large',\n timestamp: new Date().toISOString()\n });\n return;\n }\n\n diagnostics.inFlight += 1;\n try {\n await deliver(body);\n } catch (error) {\n const deliveryError = error instanceof Error ? error : new Error(String(error));\n recordError(deliveryError);\n enqueue({\n messageId: String(body.messageId),\n savedAt: Date.now(),\n attempts: 1,\n lastError: deliveryError.message,\n payload: body\n });\n } finally {\n diagnostics.inFlight -= 1;\n diagnostics.queued = queue.length;\n }\n },\n async flushQueue(): Promise<void> {\n this.flushExpired();\n if (queue.length === 0 || !this.acquireFlushLease()) return;\n\n diagnostics.inFlight += 1;\n try {\n let sentInBatch = 0;\n for (let index = 0; index < queue.length && sentInBatch < batchSize;) {\n const record = queue[index];\n if (!record) {\n index += 1;\n continue;\n }\n\n try {\n await deliver(record.payload);\n queue.splice(index, 1);\n sentInBatch += 1;\n persistQueue();\n } catch (error) {\n const deliveryError = error instanceof Error ? error : new Error(String(error));\n record.attempts += 1;\n record.lastError = deliveryError.message;\n recordError(deliveryError);\n index += 1;\n persistQueue();\n break;\n }\n }\n } finally {\n diagnostics.inFlight -= 1;\n diagnostics.queued = queue.length;\n this.releaseFlushLease();\n }\n },\n clearQueue(reason: string): void {\n for (const record of queue) {\n recordDrop({\n messageId: record.messageId,\n reason,\n timestamp: new Date().toISOString()\n });\n }\n queue.splice(0, queue.length);\n diagnostics.queued = 0;\n persistQueue();\n },\n enqueueForTests(record: DmdQueuedRecord): void {\n enqueue(record);\n },\n flushExpired(): void {\n const ttl = config.queueTtlMs ?? 86_400_000;\n const now = Date.now();\n for (let index = queue.length - 1; index >= 0; index -= 1) {\n const record = queue[index];\n if (record && now - record.savedAt > ttl) {\n recordDrop({\n messageId: record.messageId,\n reason: 'queue_ttl_expired',\n timestamp: new Date().toISOString()\n });\n queue.splice(index, 1);\n }\n }\n diagnostics.queued = queue.length;\n persistQueue();\n },\n acquireFlushLease(): boolean {\n if (!config.storage) return true;\n\n const now = Date.now();\n const rawLock = safeGetItem(lockKey);\n let existingLock: { owner?: string; expiresAt?: number } | undefined;\n if (rawLock) {\n try {\n existingLock = JSON.parse(rawLock) as { owner?: string; expiresAt?: number };\n } catch {\n existingLock = undefined;\n }\n }\n\n const lockExpired = !existingLock?.expiresAt || existingLock.expiresAt <= now;\n const lockOwnedByThisTab = existingLock?.owner === tabId;\n if (!existingLock || lockExpired || lockOwnedByThisTab) {\n if (!safeSetItem(lockKey, JSON.stringify({ owner: tabId, expiresAt: now + lockTtlMs }))) {\n return true;\n }\n return true;\n }\n\n return false;\n },\n releaseFlushLease(): void {\n if (!config.storage) return;\n const rawLock = safeGetItem(lockKey);\n if (!rawLock) return;\n\n try {\n const existingLock = JSON.parse(rawLock) as { owner?: string };\n if (existingLock.owner === tabId) {\n safeRemoveItem(lockKey);\n }\n } catch {\n safeRemoveItem(lockKey);\n }\n },\n getDiagnostics(): DmdDeliveryDiagnostics {\n return diagnostics;\n }\n };\n}\n","const sensitiveKeys = new Set([\n 'email',\n 'phone',\n 'mobile',\n 'address',\n 'address1',\n 'address2',\n 'first_name',\n 'last_name',\n 'name',\n 'token',\n 'secret',\n 'password',\n 'session',\n 'cookie'\n]);\n\nexport function redactUrl(\n url: string,\n allowQueryKeys = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']\n): string {\n const parsed = new URL(url, 'https://placeholder.local');\n for (const key of Array.from(parsed.searchParams.keys())) {\n if (!allowQueryKeys.includes(key)) {\n parsed.searchParams.set(key, '[REDACTED]');\n }\n }\n return url.startsWith('http') ? parsed.toString() : `${parsed.pathname}${parsed.search}`;\n}\n\nfunction sanitizeValue(value: unknown, allow: Set<string>): unknown {\n if (Array.isArray(value)) {\n return value.map(item => sanitizeValue(item, allow));\n }\n\n if (value && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .filter(([key]) => !sensitiveKeys.has(key.toLowerCase()) || allow.has(key.toLowerCase()))\n .map(([key, nestedValue]) => [key, sanitizeValue(nestedValue, allow)])\n );\n }\n\n return value;\n}\n\nexport function sanitizeProperties(input: Record<string, unknown>, allowRawKeys: string[] = []): Record<string, unknown> {\n const allow = new Set(allowRawKeys.map(key => key.toLowerCase()));\n return sanitizeValue(input, allow) as Record<string, unknown>;\n}\n\nexport async function sha256LowerTrimmed(value: string): Promise<string> {\n const bytes = new TextEncoder().encode(value.trim().toLowerCase());\n const digest = await crypto.subtle.digest('SHA-256', bytes);\n return Array.from(new Uint8Array(digest)).map(byte => byte.toString(16).padStart(2, '0')).join('');\n}\n","const reservedKeys = new Set(['messageId', 'timestamp', 'type', 'event', 'anonymousId', 'userId', 'context']);\n\nexport interface DmdSchemaValidationResult {\n ok: boolean;\n errors: string[];\n}\n\nexport function validateEventEnvelope(\n envelope: {\n type?: unknown;\n event?: unknown;\n properties?: Record<string, unknown>;\n messageId?: unknown;\n timestamp?: unknown;\n },\n options: { mode?: 'off' | 'warn' | 'strict' } = {}\n): DmdSchemaValidationResult {\n if (options.mode === 'off') return { ok: true, errors: [] };\n const errors: string[] = [];\n if (typeof envelope.type !== 'string') errors.push('type must be a string');\n if (envelope.type === 'track' && typeof envelope.event !== 'string') {\n errors.push('track event must include event name');\n }\n if (typeof envelope.messageId !== 'string') errors.push('messageId must be a string');\n if (typeof envelope.timestamp !== 'string') errors.push('timestamp must be an ISO string');\n for (const key of Object.keys(envelope.properties ?? {})) {\n if (reservedKeys.has(key)) errors.push(`properties.${key} is reserved`);\n }\n return { ok: errors.length === 0, errors };\n}\n","import type { DmdDroppedEventDiagnostic, DmdDroppedEventReason, DmdDroppedEventType } from '../../core/diagnostics';\nimport type { DmdBrowserConfig, DmdConsentInput, DmdEventOptions, DmdHealthStatus } from '../../core/types';\nimport { getBrowserWindow } from '../../core/environment';\nimport { canCollectPurpose, mergeConsent, normalizeConsent, type DmdResolvedConsent } from './consent';\nimport { createDeliveryManager, type DmdDeliveryManager } from './delivery';\nimport { sanitizeProperties } from './privacy';\nimport { validateEventEnvelope } from './schema';\nimport type { DmdIdentityState } from './types';\n\ninterface DmdPreparedEvent {\n type: 'track' | 'page' | 'identify' | 'group' | 'alias';\n event: string;\n properties: Record<string, unknown>;\n messageId: string;\n timestamp: string;\n context: Record<string, unknown>;\n anonymousId: string;\n userId?: string;\n groupId?: string;\n clientId: string;\n workspaceId: string;\n appId: string;\n writeKey: string;\n consent: DmdResolvedConsent;\n}\n\nfunction createId(prefix: string): string {\n return `${prefix}_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\nfunction endpointFromConfig(config: DmdBrowserConfig): string {\n const host = config.apiHost ?? 'https://sdk.drivemetadata.com/v2';\n return `${host.replace(/\\/$/, '')}/data-collector`;\n}\n\nfunction getBrowserStorage() {\n const browserWindow = getBrowserWindow();\n try {\n return browserWindow?.localStorage;\n } catch {\n return undefined;\n }\n}\n\nexport class DriveMetaDataSDK {\n public initialized = true;\n public queue: unknown[] = [];\n public offline = false;\n public gdprConsent: 'granted' | 'denied' | 'pending';\n\n private readonly endpoint: string;\n private readonly config: DmdBrowserConfig;\n private readonly writeKey: string;\n private readonly delivery: DmdDeliveryManager;\n private identity: DmdIdentityState;\n private consentState: DmdResolvedConsent;\n private droppedEvents = 0;\n private lastError: string | undefined;\n private lastDroppedEvent: DmdDroppedEventDiagnostic | undefined;\n private retryTimer: ReturnType<typeof setTimeout> | undefined;\n private retryDelayMs: number;\n private readonly initialRetryDelayMs: number;\n private readonly maxRetryDelayMs: number;\n private lifecycleCleanup: (() => void) | undefined;\n\n constructor(config: DmdBrowserConfig) {\n this.config = config;\n this.endpoint = endpointFromConfig(config);\n const storage = getBrowserStorage();\n const deliveryConfig: Parameters<typeof createDeliveryManager>[0] = {\n endpoint: this.endpoint,\n };\n if (config.delivery?.maxQueueSize !== undefined) deliveryConfig.maxQueueSize = config.delivery.maxQueueSize;\n if (config.delivery?.queueTtlMs !== undefined) deliveryConfig.queueTtlMs = config.delivery.queueTtlMs;\n if (config.delivery?.retryDelayMs !== undefined) deliveryConfig.retryDelayMs = config.delivery.retryDelayMs;\n if (config.delivery?.maxRetryDelayMs !== undefined) deliveryConfig.maxRetryDelayMs = config.delivery.maxRetryDelayMs;\n if (config.delivery?.maxPayloadBytes !== undefined) deliveryConfig.maxPayloadBytes = config.delivery.maxPayloadBytes;\n if (config.delivery?.batchSize !== undefined) deliveryConfig.batchSize = config.delivery.batchSize;\n if (config.onDrop !== undefined) deliveryConfig.onDrop = config.onDrop;\n if (config.onError !== undefined) deliveryConfig.onError = config.onError;\n this.delivery = createDeliveryManager(storage ? {\n ...deliveryConfig,\n storage\n } : deliveryConfig);\n this.initialRetryDelayMs = config.delivery?.retryDelayMs ?? 1_000;\n this.retryDelayMs = this.initialRetryDelayMs;\n this.maxRetryDelayMs = config.delivery?.maxRetryDelayMs ?? 30_000;\n this.writeKey = config.writeKey || config.token || '';\n this.identity = { anonymousId: createId('anon') };\n this.consentState = normalizeConsent(config.gdprConsent ?? config.consent);\n this.gdprConsent = this.consentState.analytics;\n if (!config.delivery?.disableLifecycleFlush) {\n this.installLifecycleFlush();\n }\n }\n\n trackEvent(event: string, properties: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.sendPreparedEvent('track', event, properties, options);\n }\n\n page(name?: string, properties: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.sendPreparedEvent('page', 'page_view', { name, ...properties }, options);\n }\n\n trackPageview(): void {\n this.page();\n }\n\n identify(userId: string, traits: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.identity = { ...this.identity, userId, traits };\n this.sendPreparedEvent('identify', 'identify', { userId, traits }, options);\n }\n\n identifyUser(userId: string, traits: Record<string, unknown> = {}): void {\n this.identify(userId, traits);\n }\n\n group(groupId: string, traits: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.identity = { ...this.identity, groupId };\n this.sendPreparedEvent('group', 'group', { groupId, traits }, options);\n }\n\n alias(previousId: string, userId: string, options: DmdEventOptions = {}): void {\n this.sendPreparedEvent('alias', 'alias', { previousId, userId }, options);\n }\n\n async flush(): Promise<void> {\n await this.delivery.flushQueue();\n const diagnostics = this.delivery.getDiagnostics();\n this.offline = diagnostics.queued > 0;\n this.lastError = diagnostics.lastError;\n if (diagnostics.queued > 0) {\n this.scheduleRetryFlush();\n } else {\n this.retryDelayMs = this.initialRetryDelayMs;\n }\n }\n\n reset(): void {\n this.identity = { anonymousId: createId('anon') };\n this.queue = [];\n this.offline = false;\n if (this.retryTimer !== undefined) {\n clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n this.lifecycleCleanup?.();\n this.lifecycleCleanup = undefined;\n this.delivery.clearQueue('manual_clear');\n }\n\n setConsent(consent: DmdConsentInput): void {\n this.consentState = typeof consent === 'object'\n ? mergeConsent(this.consentState, consent)\n : normalizeConsent(consent);\n this.gdprConsent = this.consentState.analytics;\n if (!canCollectPurpose(this.consentState, 'analytics')) {\n this.queue = [];\n this.delivery.clearQueue('consent_revoked');\n }\n }\n\n getHealth(): DmdHealthStatus {\n const deliveryDiagnostics = this.delivery.getDiagnostics();\n const health: DmdHealthStatus = {\n initialized: this.initialized,\n consent: this.gdprConsent,\n consentPurposes: this.consentState,\n queueSize: deliveryDiagnostics.queued,\n offline: this.offline || deliveryDiagnostics.queued > 0,\n droppedEvents: this.droppedEvents + deliveryDiagnostics.dropped.length,\n delivery: deliveryDiagnostics\n };\n const lastError = this.lastError ?? deliveryDiagnostics.lastError;\n if (lastError !== undefined) health.lastError = lastError;\n if (this.lastDroppedEvent !== undefined) health.lastDroppedEvent = this.lastDroppedEvent;\n return health;\n }\n\n sendEvent(payload: unknown): void {\n void this.delivery.send(payload as Record<string, unknown>).then(() => {\n const diagnostics = this.delivery.getDiagnostics();\n this.offline = diagnostics.queued > 0;\n this.lastError = diagnostics.lastError;\n if (diagnostics.queued > 0) {\n this.scheduleRetryFlush();\n }\n });\n }\n\n private installLifecycleFlush(): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow) return;\n if (typeof browserWindow.addEventListener !== 'function') return;\n if (typeof browserWindow.removeEventListener !== 'function') return;\n\n const flushOnLifecycle = () => {\n void this.flush();\n };\n const flushOnVisibility = () => {\n if (browserWindow.document?.visibilityState === 'hidden') {\n void this.flush();\n }\n };\n\n browserWindow.addEventListener('online', flushOnLifecycle);\n browserWindow.addEventListener('pagehide', flushOnLifecycle);\n if (typeof browserWindow.document?.addEventListener === 'function') {\n browserWindow.document.addEventListener('visibilitychange', flushOnVisibility);\n }\n\n this.lifecycleCleanup = () => {\n browserWindow.removeEventListener('online', flushOnLifecycle);\n browserWindow.removeEventListener('pagehide', flushOnLifecycle);\n if (typeof browserWindow.document?.removeEventListener === 'function') {\n browserWindow.document.removeEventListener('visibilitychange', flushOnVisibility);\n }\n };\n }\n\n private scheduleRetryFlush(): void {\n if (this.retryTimer !== undefined) return;\n\n const delay = Math.min(this.retryDelayMs, this.maxRetryDelayMs);\n this.retryTimer = setTimeout(() => {\n this.retryTimer = undefined;\n void this.flush().then(() => {\n if (this.delivery.getDiagnostics().queued > 0) {\n this.retryDelayMs = Math.min(this.retryDelayMs * 2, this.maxRetryDelayMs);\n this.scheduleRetryFlush();\n }\n });\n }, delay);\n }\n\n private sendPreparedEvent(\n type: DmdPreparedEvent['type'],\n event: string,\n properties: Record<string, unknown>,\n options: DmdEventOptions\n ): void {\n void this.prepareAndSendEvent(type, event, properties, options);\n }\n\n private async prepareAndSendEvent(\n type: DmdPreparedEvent['type'],\n event: string,\n properties: Record<string, unknown>,\n options: DmdEventOptions\n ): Promise<void> {\n if (!canCollectPurpose(this.consentState, 'analytics')) {\n this.recordDrop(type, 'consent_denied', event);\n return;\n }\n\n let prepared: DmdPreparedEvent = {\n type,\n event,\n properties: sanitizeProperties(properties),\n messageId: options.messageId ?? createId('msg'),\n timestamp: options.timestamp ?? new Date().toISOString(),\n context: options.context ?? {},\n anonymousId: this.identity.anonymousId,\n clientId: this.config.clientId,\n workspaceId: this.config.workspaceId,\n appId: this.config.appId,\n writeKey: this.writeKey,\n consent: this.consentState\n };\n\n if (this.identity.userId !== undefined) prepared.userId = this.identity.userId;\n if (this.identity.groupId !== undefined) prepared.groupId = this.identity.groupId;\n\n if (this.config.beforeSend !== undefined) {\n const beforeSendResult = await this.config.beforeSend(prepared);\n if (beforeSendResult === null) {\n this.recordDrop(type, 'before_send_dropped', event);\n return;\n }\n prepared = {\n ...prepared,\n ...beforeSendResult,\n properties: sanitizeProperties(beforeSendResult.properties ?? prepared.properties)\n };\n }\n\n const validation = validateEventEnvelope(prepared, { mode: this.config.schemaValidation ?? 'warn' });\n if (!validation.ok && this.config.schemaValidation === 'strict') {\n this.recordDrop(type, 'invalid_payload', event);\n return;\n }\n if (!validation.ok) {\n this.lastError = `DMD SDK schema warning: ${validation.errors.join(', ')}`;\n }\n\n this.sendEvent(prepared);\n }\n\n private recordDrop(type: DmdDroppedEventType, reason: DmdDroppedEventReason, event?: string): void {\n this.droppedEvents += 1;\n this.lastDroppedEvent = {\n type,\n reason,\n timestamp: new Date().toISOString()\n };\n if (event !== undefined) this.lastDroppedEvent.event = event;\n this.lastError = `DMD SDK ${type} dropped because ${reason}`;\n }\n}\n","import { getBrowserWindow, isBrowserRuntime } from '../core/environment';\n\nexport type LegacySdkConstructor = new (config: unknown) => LegacySdkInstance;\n\nexport interface LegacySdkInstance {\n sendEvent?: (payload: unknown) => void;\n trackEvent?: (event: string, properties?: Record<string, unknown>, options?: unknown) => void;\n identify?: (userId: string, traits?: Record<string, unknown>, options?: unknown) => void;\n identifyUser?: (userId: string, traits?: Record<string, unknown>) => void;\n page?: (name?: string, properties?: Record<string, unknown>, options?: unknown) => void;\n group?: (groupId: string, traits?: Record<string, unknown>, options?: unknown) => void;\n alias?: (previousId: string, userId: string, options?: unknown) => void;\n flush?: () => Promise<void>;\n reset?: () => void;\n setConsent?: (consent: unknown) => void;\n getHealth?: () => unknown;\n trackPageview?: () => void;\n blockTrackingForMe?: () => void;\n gdprConsent?: 'granted' | 'denied' | 'pending';\n initialized?: boolean;\n queue?: unknown[];\n offline?: boolean;\n}\n\ninterface DmdWindow extends Window {\n DriveMetaDataSDK?: LegacySdkConstructor;\n __DriveMetaDataSDKInstance?: LegacySdkInstance;\n}\n\nexport function getLegacySdkInstanceFromWindow(): LegacySdkInstance | undefined {\n const browserWindow = getBrowserWindow() as DmdWindow | undefined;\n return browserWindow?.__DriveMetaDataSDKInstance;\n}\n\nexport function ensureLegacySdkLoaded(): LegacySdkConstructor {\n if (!isBrowserRuntime()) {\n throw new Error('DMD legacy SDK is only available in a browser runtime');\n }\n\n const browserWindow = getBrowserWindow() as DmdWindow | undefined;\n if (!browserWindow?.DriveMetaDataSDK) {\n throw new Error('DMD legacy SDK constructor is missing from window.DriveMetaDataSDK');\n }\n\n return browserWindow.DriveMetaDataSDK;\n}\n","import { normalizeBrowserConfig } from '../core/config';\nimport type { DmdDroppedEventDiagnostic, DmdDroppedEventType } from '../core/diagnostics';\nimport type {\n DmdBrowserClient,\n DmdBrowserConfig,\n DmdConsentInput,\n DmdEventOptions,\n DmdHealthStatus\n} from '../core/types';\nimport { DriveMetaDataSDK } from './core/DriveMetaDataSDK';\nimport {\n ensureLegacySdkLoaded,\n getLegacySdkInstanceFromWindow,\n type LegacySdkInstance\n} from './legacy-loader';\n\ntype DmdRuntimeInstance = LegacySdkInstance | DriveMetaDataSDK;\n\nexport interface DmdBrowserClientWithLegacy extends DmdBrowserClient {\n __legacy: DmdRuntimeInstance;\n}\n\nlet singleton: DmdRuntimeInstance | undefined;\nlet publicSingleton: DmdBrowserClientWithLegacy | undefined;\nlet droppedEvents = 0;\nlet lastError: string | undefined;\nlet lastDroppedEvent: DmdDroppedEventDiagnostic | undefined;\n\nfunction createPublicClient(instance: DmdRuntimeInstance): DmdBrowserClientWithLegacy {\n return {\n __legacy: instance,\n track(event, properties, options) {\n if (instance.trackEvent) {\n instance.trackEvent(event, properties, options);\n return;\n }\n instance.sendEvent?.({ eventName: event, event, properties, options });\n },\n identify(userId, traits, options) {\n if (instance.identify) {\n instance.identify(userId, traits, options);\n return;\n }\n instance.identifyUser?.(userId, traits);\n },\n page(name, properties, options) {\n if (instance.page) {\n instance.page(name, properties, options);\n return;\n }\n instance.trackPageview?.();\n },\n group(groupId, traits, options) {\n instance.group?.(groupId, traits, options);\n },\n alias(previousId, userId, options) {\n instance.alias?.(previousId, userId, options);\n },\n async flush() {\n await instance.flush?.();\n },\n reset() {\n instance.reset?.();\n singleton = undefined;\n publicSingleton = undefined;\n },\n setConsent(consent) {\n if (instance.setConsent) {\n instance.setConsent(consent);\n return;\n }\n if (typeof consent === 'string') {\n instance.gdprConsent = consent;\n }\n },\n getHealth() {\n if (instance.getHealth) {\n return instance.getHealth() as DmdHealthStatus;\n }\n return getDmdHealth();\n }\n };\n}\n\nfunction setSingleton(instance: DmdRuntimeInstance): DmdBrowserClientWithLegacy {\n singleton = instance;\n publicSingleton = createPublicClient(instance);\n return publicSingleton;\n}\n\nfunction recordDroppedEvent(type: DmdDroppedEventType, event?: string): void {\n droppedEvents += 1;\n lastDroppedEvent = {\n type,\n reason: 'not_initialized',\n timestamp: new Date().toISOString()\n };\n if (event !== undefined) {\n lastDroppedEvent.event = event;\n }\n lastError = `DMD SDK ${type} called before initialization`;\n}\n\nexport function initDmdSDK(config: DmdBrowserConfig): DmdBrowserClientWithLegacy {\n if (publicSingleton) {\n return publicSingleton;\n }\n\n const legacyConfig = normalizeBrowserConfig(config);\n const existingInstance = getLegacySdkInstanceFromWindow();\n if (existingInstance) {\n return setSingleton(existingInstance);\n }\n\n try {\n let instance: DmdRuntimeInstance;\n try {\n const LegacySdk = ensureLegacySdkLoaded();\n instance = new LegacySdk(legacyConfig);\n } catch (error) {\n if (error instanceof Error && error.message.includes('constructor is missing')) {\n instance = new DriveMetaDataSDK(config);\n } else {\n throw error;\n }\n }\n return setSingleton(instance);\n } catch (error) {\n lastError = error instanceof Error ? error.message : String(error);\n throw error;\n }\n}\n\nexport function getDmdSDK(): DmdBrowserClientWithLegacy | undefined {\n return publicSingleton;\n}\n\nexport function track(event: string, properties?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('track', event);\n return;\n }\n sdk.track(event, properties, options);\n}\n\nexport function identify(userId: string, traits?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('identify');\n return;\n }\n sdk.identify(userId, traits, options);\n}\n\nexport function page(name?: string, properties?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('page');\n return;\n }\n sdk.page(name, properties, options);\n}\n\nexport function group(groupId: string, traits?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('group');\n return;\n }\n sdk.group(groupId, traits, options);\n}\n\nexport function alias(previousId: string, userId: string, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('alias');\n return;\n }\n sdk.alias(previousId, userId, options);\n}\n\nexport async function flush(): Promise<void> {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('flush');\n return;\n }\n await sdk.flush();\n}\n\nexport function reset(): void {\n singleton?.reset?.();\n singleton = undefined;\n publicSingleton = undefined;\n}\n\nexport function setConsent(consent: DmdConsentInput): void {\n getDmdSDK()?.setConsent(consent);\n}\n\nexport const consent = {\n update(state: DmdConsentInput): void {\n setConsent(state);\n }\n};\n\nexport async function ready(): Promise<DmdBrowserClientWithLegacy | undefined> {\n return getDmdSDK();\n}\n\nexport function getDmdHealth(): DmdHealthStatus {\n if (singleton?.getHealth) {\n return singleton.getHealth() as DmdHealthStatus;\n }\n\n const health: DmdHealthStatus = {\n initialized: Boolean(singleton?.initialized ?? singleton),\n consent: singleton?.gdprConsent ?? 'pending',\n queueSize: singleton?.queue?.length ?? 0,\n offline: Boolean(singleton?.offline),\n droppedEvents\n };\n\n if (lastError !== undefined) {\n health.lastError = lastError;\n }\n if (lastDroppedEvent !== undefined) {\n health.lastDroppedEvent = lastDroppedEvent;\n }\n\n return health;\n}\n\nexport function resetDmdSDKForTests(): void {\n singleton?.reset?.();\n singleton = undefined;\n publicSingleton = undefined;\n droppedEvents = 0;\n lastError = undefined;\n lastDroppedEvent = undefined;\n}\n"],"mappings":"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","names":["consent","createId","consent","lastError","consent"]}
1
+ {"version":3,"sources":["../../src/browser/index.ts","../../src/core/backend-payload.ts","../../src/core/environment.ts","../../src/browser/core/consent.ts","../../src/browser/core/delivery.ts","../../src/browser/core/privacy.ts","../../src/browser/core/schema.ts","../../src/browser/core/DriveMetaDataSDK.ts","../../src/browser/client.ts"],"sourcesContent":["export {\n alias,\n consent,\n getDmdHealth,\n getDmdSDK,\n flush,\n group,\n identify,\n initDmdSDK,\n page,\n ready,\n reset,\n resetDmdSDKForTests,\n setConsent,\n track\n} from './client';\n\nexport type {\n DmdBrowserClient,\n DmdBrowserConfig,\n DmdConsentInput,\n DmdConsentPurpose,\n DmdConsentState,\n DmdDeliveryDropReason,\n DmdDeliveryEventDiagnostic,\n DmdEventPayload,\n DmdEventOptions,\n DmdHealthStatus\n} from '../core/types';\n\nexport type {\n DmdDroppedEventDiagnostic,\n DmdDroppedEventReason,\n DmdDroppedEventType\n} from '../core/diagnostics';\n","function formatUtcTimestamp(value: unknown): string {\n if (typeof value !== 'string') return new Date().toISOString().replace('T', ' ').slice(0, 19);\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n return date.toISOString().replace('T', ' ').slice(0, 19);\n}\n\nfunction cleanObject(value: unknown): unknown {\n if (Array.isArray(value)) {\n const cleaned = value\n .map(item => cleanObject(item))\n .filter(item => item !== null && item !== undefined && item !== '');\n return cleaned.length > 0 ? cleaned : undefined;\n }\n\n if (value && typeof value === 'object') {\n const cleaned = Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .map(([key, item]) => [key, cleanObject(item)])\n .filter(([, item]) => {\n if (item === null || item === undefined || item === '') return false;\n if (typeof item === 'object' && !Array.isArray(item) && Object.keys(item).length === 0) return false;\n return true;\n })\n );\n return Object.keys(cleaned).length > 0 ? cleaned : undefined;\n }\n\n return value;\n}\n\nexport function createBackendCollectorPayload(input: Record<string, unknown>): Record<string, unknown> {\n const eventData = input.eventData && typeof input.eventData === 'object'\n ? input.eventData as Record<string, unknown>\n : {};\n const page = eventData.page && typeof eventData.page === 'object'\n ? eventData.page as Record<string, unknown>\n : {};\n const timestamp = formatUtcTimestamp(eventData.timestamp ?? input.timestamp);\n const normalizedEventData = {\n ...eventData,\n timestamp,\n requestSentAt: formatUtcTimestamp(eventData.requestSentAt ?? input.requestSentAt ?? timestamp),\n requestReceivedAt: formatUtcTimestamp(eventData.requestReceivedAt ?? input.requestReceivedAt ?? timestamp)\n };\n\n const metaData: Record<string, unknown> = {\n ...normalizedEventData,\n requestId: input.requestId,\n timestamp,\n eventType: input.eventType,\n requestFrom: input.requestFrom ?? '3',\n clientId: input.clientId,\n workspaceId: input.workspaceId,\n token: input.token,\n anonymousId: eventData.anonymousId ?? input.anonymousId,\n sessionId: eventData.sessionId ?? input.sessionId,\n ua: input.ua,\n appDetails: { app_id: input.appId },\n page: { ...page, url: page.url ?? input.pageUrl },\n requestSentAt: normalizedEventData.requestSentAt,\n requestReceivedAt: normalizedEventData.requestReceivedAt\n };\n\n const payload = { metaData };\n\n return cleanObject(payload) as Record<string, unknown>;\n}\n","export function isBrowserRuntime(): boolean {\n return typeof window !== 'undefined' && typeof document !== 'undefined';\n}\n\nexport function getBrowserWindow(): Window | undefined {\n return typeof window === 'undefined' ? undefined : window;\n}\n","import type {\n DmdConsentInput,\n DmdConsentPurpose,\n DmdConsentState,\n DmdPurposeConsent\n} from './types';\n\nexport type DmdResolvedConsent = Record<DmdConsentPurpose, DmdConsentState>;\n\nconst purposes: DmdConsentPurpose[] = [\n 'analytics',\n 'advertising',\n 'personalization',\n 'functional',\n 'saleOfData'\n];\n\nfunction normalizeConsentValue(value: unknown): DmdConsentState {\n if (value === true) return 'granted';\n if (value === false) return 'denied';\n if (value === 'granted' || value === 'denied' || value === 'pending') return value;\n return 'pending';\n}\n\nexport function normalizeConsent(input: DmdConsentInput | undefined): DmdResolvedConsent {\n const defaultValue = normalizeConsentValue(input ?? 'pending');\n const resolved = Object.fromEntries(\n purposes.map(purpose => [purpose, defaultValue])\n ) as DmdResolvedConsent;\n\n if (input && typeof input === 'object') {\n for (const purpose of purposes) {\n const value = input[purpose];\n if (value !== undefined) {\n resolved[purpose] = normalizeConsentValue(value);\n }\n }\n }\n\n return resolved;\n}\n\nexport function mergeConsent(current: DmdResolvedConsent, update: DmdPurposeConsent): DmdResolvedConsent {\n const next = { ...current };\n for (const [purpose, value] of Object.entries(update) as Array<[DmdConsentPurpose, DmdConsentState]>) {\n next[purpose] = normalizeConsentValue(value);\n }\n return next;\n}\n\nexport function canCollectPurpose(consent: DmdResolvedConsent, purpose: DmdConsentPurpose): boolean {\n return consent[purpose] === 'granted';\n}\n","export interface DmdQueuedRecord {\n messageId: string;\n savedAt: number;\n attempts: number;\n lastError?: string;\n payload: Record<string, unknown>;\n}\n\nexport interface DmdDeliveryDiagnostics {\n queued: number;\n inFlight: number;\n dropped: Array<{ messageId?: string; reason: string; timestamp: string }>;\n lastError?: string;\n}\n\nexport interface DmdDeliveryManager {\n send(payload: Record<string, unknown>): Promise<void>;\n flushQueue(): Promise<void>;\n clearQueue(reason: string): void;\n enqueueForTests(record: DmdQueuedRecord): void;\n flushExpired(): void;\n acquireFlushLease(): boolean;\n releaseFlushLease(): void;\n getDiagnostics(): DmdDeliveryDiagnostics;\n}\n\nexport interface DmdDeliveryStorage {\n getItem(key: string): string | null;\n setItem(key: string, value: string): unknown;\n removeItem(key: string): unknown;\n}\n\nfunction createId(prefix: string): string {\n return `${prefix}_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\nfunction stableStringify(value: unknown): string {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return JSON.stringify(value);\n }\n return JSON.stringify(\n Object.fromEntries(\n Object.entries(value as Record<string, unknown>).sort(([left], [right]) => left.localeCompare(right))\n )\n );\n}\n\nfunction createIdempotencyKey(payload: Record<string, unknown>, messageId: string): string {\n const metaData = payload.metaData as Record<string, unknown> | undefined;\n const event = String(metaData?.eventType ?? payload.event ?? payload.type ?? 'event');\n const properties = (metaData ?? payload.properties) as Record<string, unknown> | undefined;\n const orderId = properties?.orderId ?? properties?.order_id ?? properties?.transaction_id;\n if (orderId !== undefined) return `${event}:${String(orderId)}`;\n return `${event}:${stableStringify(properties ?? {}) || messageId}`;\n}\n\nexport function createDeliveryManager(config: {\n endpoint: string;\n fetch?: typeof fetch;\n queueTtlMs?: number;\n maxQueueSize?: number;\n storage?: DmdDeliveryStorage;\n queueKey?: string;\n lockKey?: string;\n lockTtlMs?: number;\n tabId?: string;\n retryDelayMs?: number;\n maxRetryDelayMs?: number;\n maxPayloadBytes?: number;\n batchSize?: number;\n onDrop?: (event: { messageId?: string; reason: string; timestamp: string }) => void;\n onError?: (error: Error) => void;\n}): DmdDeliveryManager {\n const queue: DmdQueuedRecord[] = [];\n const diagnostics: DmdDeliveryDiagnostics = { queued: 0, inFlight: 0, dropped: [] };\n const maxQueueSize = config.maxQueueSize ?? 100;\n const queueKey = config.queueKey ?? 'dmd_delivery_queue';\n const lockKey = config.lockKey ?? 'dmd_delivery_flush_lock';\n const lockTtlMs = config.lockTtlMs ?? 5_000;\n const tabId = config.tabId ?? createId('tab');\n const batchSize = config.batchSize ?? 25;\n const maxPayloadBytes = config.maxPayloadBytes ?? 64_000;\n\n function recordDrop(event: { messageId?: string; reason: string; timestamp: string }): void {\n diagnostics.dropped.push(event);\n config.onDrop?.(event);\n }\n\n function recordError(error: Error): void {\n diagnostics.lastError = error.message;\n config.onError?.(error);\n }\n\n function payloadByteLength(payload: Record<string, unknown>): number {\n const serialized = JSON.stringify(payload);\n if (typeof TextEncoder !== 'undefined') {\n return new TextEncoder().encode(serialized).length;\n }\n return serialized.length;\n }\n\n function recordStorageUnavailable(): void {\n recordDrop({\n reason: 'storage_unavailable',\n timestamp: new Date().toISOString()\n });\n }\n\n function safeGetItem(key: string): string | null {\n try {\n return config.storage?.getItem(key) ?? null;\n } catch {\n recordStorageUnavailable();\n return null;\n }\n }\n\n function safeSetItem(key: string, value: string): boolean {\n try {\n config.storage?.setItem(key, value);\n return true;\n } catch {\n recordStorageUnavailable();\n return false;\n }\n }\n\n function safeRemoveItem(key: string): boolean {\n try {\n config.storage?.removeItem(key);\n return true;\n } catch {\n recordStorageUnavailable();\n return false;\n }\n }\n\n function persistQueue(): void {\n if (!config.storage) return;\n if (queue.length === 0) {\n safeRemoveItem(queueKey);\n return;\n }\n safeSetItem(queueKey, JSON.stringify(queue));\n }\n\n function loadQueue(): void {\n if (!config.storage) return;\n const rawQueue = safeGetItem(queueKey);\n if (!rawQueue) return;\n try {\n const records = JSON.parse(rawQueue) as DmdQueuedRecord[];\n queue.splice(0, queue.length, ...records.filter(record => record && typeof record.messageId === 'string'));\n diagnostics.queued = queue.length;\n } catch {\n safeRemoveItem(queueKey);\n recordDrop({\n reason: 'queue_corrupt',\n timestamp: new Date().toISOString()\n });\n }\n }\n\n function enqueue(record: DmdQueuedRecord): void {\n queue.push(record);\n while (queue.length > maxQueueSize) {\n const dropped = queue.shift();\n const diagnostic: { messageId?: string; reason: string; timestamp: string } = {\n reason: 'queue_limit_exceeded',\n timestamp: new Date().toISOString()\n };\n if (dropped?.messageId !== undefined) diagnostic.messageId = dropped.messageId;\n recordDrop(diagnostic);\n }\n diagnostics.queued = queue.length;\n persistQueue();\n }\n\n function withEnvelope(payload: Record<string, unknown>): Record<string, unknown> {\n const metaData = payload.metaData as Record<string, unknown> | undefined;\n const messageId = String(metaData?.requestId ?? payload.messageId ?? createId('msg'));\n if (metaData) {\n return {\n ...payload,\n metaData: {\n ...metaData,\n requestId: messageId\n }\n };\n }\n return {\n ...payload,\n messageId,\n idempotencyKey: String(payload.idempotencyKey ?? createIdempotencyKey(payload, messageId))\n };\n }\n\n async function deliver(body: Record<string, unknown>): Promise<void> {\n const fetchImpl = config.fetch ?? globalThis.fetch;\n if (typeof fetchImpl !== 'function') {\n throw new Error('fetch_unavailable');\n }\n\n const response = await fetchImpl(config.endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n keepalive: true\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n }\n\n loadQueue();\n\n return {\n async send(payload: Record<string, unknown>): Promise<void> {\n const body = withEnvelope(payload);\n\n if (payloadByteLength(body) > maxPayloadBytes) {\n recordDrop({\n messageId: String((body.metaData as Record<string, unknown> | undefined)?.requestId ?? body.messageId),\n reason: 'payload_too_large',\n timestamp: new Date().toISOString()\n });\n return;\n }\n\n diagnostics.inFlight += 1;\n try {\n await deliver(body);\n } catch (error) {\n const deliveryError = error instanceof Error ? error : new Error(String(error));\n recordError(deliveryError);\n enqueue({\n messageId: String((body.metaData as Record<string, unknown> | undefined)?.requestId ?? body.messageId),\n savedAt: Date.now(),\n attempts: 1,\n lastError: deliveryError.message,\n payload: body\n });\n } finally {\n diagnostics.inFlight -= 1;\n diagnostics.queued = queue.length;\n }\n },\n async flushQueue(): Promise<void> {\n this.flushExpired();\n if (queue.length === 0 || !this.acquireFlushLease()) return;\n\n diagnostics.inFlight += 1;\n try {\n let sentInBatch = 0;\n for (let index = 0; index < queue.length && sentInBatch < batchSize;) {\n const record = queue[index];\n if (!record) {\n index += 1;\n continue;\n }\n\n try {\n await deliver(record.payload);\n queue.splice(index, 1);\n sentInBatch += 1;\n persistQueue();\n } catch (error) {\n const deliveryError = error instanceof Error ? error : new Error(String(error));\n record.attempts += 1;\n record.lastError = deliveryError.message;\n recordError(deliveryError);\n index += 1;\n persistQueue();\n break;\n }\n }\n } finally {\n diagnostics.inFlight -= 1;\n diagnostics.queued = queue.length;\n this.releaseFlushLease();\n }\n },\n clearQueue(reason: string): void {\n for (const record of queue) {\n recordDrop({\n messageId: record.messageId,\n reason,\n timestamp: new Date().toISOString()\n });\n }\n queue.splice(0, queue.length);\n diagnostics.queued = 0;\n persistQueue();\n },\n enqueueForTests(record: DmdQueuedRecord): void {\n enqueue(record);\n },\n flushExpired(): void {\n const ttl = config.queueTtlMs ?? 86_400_000;\n const now = Date.now();\n for (let index = queue.length - 1; index >= 0; index -= 1) {\n const record = queue[index];\n if (record && now - record.savedAt > ttl) {\n recordDrop({\n messageId: record.messageId,\n reason: 'queue_ttl_expired',\n timestamp: new Date().toISOString()\n });\n queue.splice(index, 1);\n }\n }\n diagnostics.queued = queue.length;\n persistQueue();\n },\n acquireFlushLease(): boolean {\n if (!config.storage) return true;\n\n const now = Date.now();\n const rawLock = safeGetItem(lockKey);\n let existingLock: { owner?: string; expiresAt?: number } | undefined;\n if (rawLock) {\n try {\n existingLock = JSON.parse(rawLock) as { owner?: string; expiresAt?: number };\n } catch {\n existingLock = undefined;\n }\n }\n\n const lockExpired = !existingLock?.expiresAt || existingLock.expiresAt <= now;\n const lockOwnedByThisTab = existingLock?.owner === tabId;\n if (!existingLock || lockExpired || lockOwnedByThisTab) {\n if (!safeSetItem(lockKey, JSON.stringify({ owner: tabId, expiresAt: now + lockTtlMs }))) {\n return true;\n }\n return true;\n }\n\n return false;\n },\n releaseFlushLease(): void {\n if (!config.storage) return;\n const rawLock = safeGetItem(lockKey);\n if (!rawLock) return;\n\n try {\n const existingLock = JSON.parse(rawLock) as { owner?: string };\n if (existingLock.owner === tabId) {\n safeRemoveItem(lockKey);\n }\n } catch {\n safeRemoveItem(lockKey);\n }\n },\n getDiagnostics(): DmdDeliveryDiagnostics {\n return diagnostics;\n }\n };\n}\n","const sensitiveKeys = new Set([\n 'email',\n 'phone',\n 'mobile',\n 'address',\n 'address1',\n 'address2',\n 'first_name',\n 'last_name',\n 'name',\n 'token',\n 'secret',\n 'password',\n 'session',\n 'cookie'\n]);\n\nexport function redactUrl(\n url: string,\n allowQueryKeys = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']\n): string {\n const parsed = new URL(url, 'https://placeholder.local');\n for (const key of Array.from(parsed.searchParams.keys())) {\n if (!allowQueryKeys.includes(key)) {\n parsed.searchParams.set(key, '[REDACTED]');\n }\n }\n return url.startsWith('http') ? parsed.toString() : `${parsed.pathname}${parsed.search}`;\n}\n\nfunction sanitizeValue(value: unknown, allow: Set<string>): unknown {\n if (Array.isArray(value)) {\n return value.map(item => sanitizeValue(item, allow));\n }\n\n if (value && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>)\n .filter(([key]) => !sensitiveKeys.has(key.toLowerCase()) || allow.has(key.toLowerCase()))\n .map(([key, nestedValue]) => [key, sanitizeValue(nestedValue, allow)])\n );\n }\n\n return value;\n}\n\nexport function sanitizeProperties(input: Record<string, unknown>, allowRawKeys: string[] = []): Record<string, unknown> {\n const allow = new Set(allowRawKeys.map(key => key.toLowerCase()));\n return sanitizeValue(input, allow) as Record<string, unknown>;\n}\n\nexport async function sha256LowerTrimmed(value: string): Promise<string> {\n const bytes = new TextEncoder().encode(value.trim().toLowerCase());\n const digest = await crypto.subtle.digest('SHA-256', bytes);\n return Array.from(new Uint8Array(digest)).map(byte => byte.toString(16).padStart(2, '0')).join('');\n}\n","const reservedKeys = new Set(['messageId', 'timestamp', 'type', 'event', 'anonymousId', 'userId', 'context']);\n\nexport interface DmdSchemaValidationResult {\n ok: boolean;\n errors: string[];\n}\n\nexport function validateEventEnvelope(\n envelope: {\n type?: unknown;\n event?: unknown;\n properties?: Record<string, unknown>;\n messageId?: unknown;\n timestamp?: unknown;\n },\n options: { mode?: 'off' | 'warn' | 'strict' } = {}\n): DmdSchemaValidationResult {\n if (options.mode === 'off') return { ok: true, errors: [] };\n const errors: string[] = [];\n if (typeof envelope.type !== 'string') errors.push('type must be a string');\n if (envelope.type === 'track' && typeof envelope.event !== 'string') {\n errors.push('track event must include event name');\n }\n if (typeof envelope.messageId !== 'string') errors.push('messageId must be a string');\n if (typeof envelope.timestamp !== 'string') errors.push('timestamp must be an ISO string');\n for (const key of Object.keys(envelope.properties ?? {})) {\n if (reservedKeys.has(key)) errors.push(`properties.${key} is reserved`);\n }\n return { ok: errors.length === 0, errors };\n}\n","import type { DmdDroppedEventDiagnostic, DmdDroppedEventReason, DmdDroppedEventType } from '../../core/diagnostics';\nimport type { DmdBrowserConfig, DmdConsentInput, DmdEventOptions, DmdHealthStatus } from '../../core/types';\nimport { createBackendCollectorPayload } from '../../core/backend-payload';\nimport { getBrowserWindow } from '../../core/environment';\nimport { canCollectPurpose, mergeConsent, normalizeConsent, type DmdResolvedConsent } from './consent';\nimport { createDeliveryManager, type DmdDeliveryManager } from './delivery';\nimport { sanitizeProperties } from './privacy';\nimport { validateEventEnvelope } from './schema';\nimport type { DmdIdentityState } from './types';\n\ninterface DmdPreparedEvent {\n type: 'track' | 'page' | 'identify' | 'group' | 'alias';\n event: string;\n properties: Record<string, unknown>;\n messageId: string;\n timestamp: string;\n context: Record<string, unknown>;\n anonymousId: string;\n userId?: string;\n groupId?: string;\n clientId: string;\n workspaceId: string;\n appId: string;\n writeKey: string;\n consent: DmdResolvedConsent;\n sessionId: string;\n}\n\nfunction createId(prefix: string): string {\n return `${prefix}_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\nfunction endpointFromConfig(config: DmdBrowserConfig): string {\n const host = config.apiHost ?? 'https://sdk.drivemetadata.com/v2';\n return `${host.replace(/\\/$/, '')}/data-collector`;\n}\n\nfunction requireConfigString(value: string | undefined, field: string): string {\n if (typeof value !== 'string' || value.trim() === '') {\n throw new Error(`DMD SDK config ${field} is required`);\n }\n return value;\n}\n\nfunction getBrowserStorage() {\n const browserWindow = getBrowserWindow();\n try {\n return browserWindow?.localStorage;\n } catch {\n return undefined;\n }\n}\n\nexport class DriveMetaDataSDK {\n public initialized = true;\n public queue: unknown[] = [];\n public offline = false;\n public gdprConsent: 'granted' | 'denied' | 'pending';\n\n private readonly endpoint: string;\n private readonly config: DmdBrowserConfig;\n private readonly writeKey: string;\n private readonly sessionId: string;\n private readonly delivery: DmdDeliveryManager;\n private identity: DmdIdentityState;\n private consentState: DmdResolvedConsent;\n private droppedEvents = 0;\n private lastError: string | undefined;\n private lastDroppedEvent: DmdDroppedEventDiagnostic | undefined;\n private retryTimer: ReturnType<typeof setTimeout> | undefined;\n private retryDelayMs: number;\n private readonly initialRetryDelayMs: number;\n private readonly maxRetryDelayMs: number;\n private lifecycleCleanup: (() => void) | undefined;\n\n constructor(config: DmdBrowserConfig) {\n requireConfigString(config.clientId, 'clientId');\n requireConfigString(config.workspaceId, 'workspaceId');\n requireConfigString(config.appId, 'appId');\n requireConfigString(config.writeKey || config.token, 'writeKey or token');\n this.config = config;\n this.endpoint = endpointFromConfig(config);\n const storage = getBrowserStorage();\n const deliveryConfig: Parameters<typeof createDeliveryManager>[0] = {\n endpoint: this.endpoint,\n };\n if (config.delivery?.maxQueueSize !== undefined) deliveryConfig.maxQueueSize = config.delivery.maxQueueSize;\n if (config.delivery?.queueTtlMs !== undefined) deliveryConfig.queueTtlMs = config.delivery.queueTtlMs;\n if (config.delivery?.retryDelayMs !== undefined) deliveryConfig.retryDelayMs = config.delivery.retryDelayMs;\n if (config.delivery?.maxRetryDelayMs !== undefined) deliveryConfig.maxRetryDelayMs = config.delivery.maxRetryDelayMs;\n if (config.delivery?.maxPayloadBytes !== undefined) deliveryConfig.maxPayloadBytes = config.delivery.maxPayloadBytes;\n if (config.delivery?.batchSize !== undefined) deliveryConfig.batchSize = config.delivery.batchSize;\n if (config.onDrop !== undefined) deliveryConfig.onDrop = config.onDrop;\n if (config.onError !== undefined) deliveryConfig.onError = config.onError;\n this.delivery = createDeliveryManager(storage ? {\n ...deliveryConfig,\n storage\n } : deliveryConfig);\n this.initialRetryDelayMs = config.delivery?.retryDelayMs ?? 1_000;\n this.retryDelayMs = this.initialRetryDelayMs;\n this.maxRetryDelayMs = config.delivery?.maxRetryDelayMs ?? 30_000;\n this.writeKey = config.writeKey || config.token || '';\n this.identity = { anonymousId: createId('anon') };\n this.sessionId = createId('session');\n this.consentState = normalizeConsent(config.gdprConsent ?? config.consent);\n this.gdprConsent = this.consentState.analytics;\n if (!config.delivery?.disableLifecycleFlush) {\n this.installLifecycleFlush();\n }\n }\n\n trackEvent(event: string, properties: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.sendPreparedEvent('track', event, properties, options);\n }\n\n page(name?: string, properties: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.sendPreparedEvent('page', 'page_view', { name, ...properties }, options);\n }\n\n trackPageview(): void {\n this.page();\n }\n\n identify(userId: string, traits: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.identity = { ...this.identity, userId, traits };\n this.sendPreparedEvent('identify', 'identify', { userId, traits }, options);\n }\n\n identifyUser(userId: string, traits: Record<string, unknown> = {}): void {\n this.identify(userId, traits);\n }\n\n group(groupId: string, traits: Record<string, unknown> = {}, options: DmdEventOptions = {}): void {\n this.identity = { ...this.identity, groupId };\n this.sendPreparedEvent('group', 'group', { groupId, traits }, options);\n }\n\n alias(previousId: string, userId: string, options: DmdEventOptions = {}): void {\n this.sendPreparedEvent('alias', 'alias', { previousId, userId }, options);\n }\n\n async flush(): Promise<void> {\n await this.delivery.flushQueue();\n const diagnostics = this.delivery.getDiagnostics();\n this.offline = diagnostics.queued > 0;\n this.lastError = diagnostics.lastError;\n if (diagnostics.queued > 0) {\n this.scheduleRetryFlush();\n } else {\n this.retryDelayMs = this.initialRetryDelayMs;\n }\n }\n\n reset(): void {\n this.identity = { anonymousId: createId('anon') };\n this.queue = [];\n this.offline = false;\n if (this.retryTimer !== undefined) {\n clearTimeout(this.retryTimer);\n this.retryTimer = undefined;\n }\n this.lifecycleCleanup?.();\n this.lifecycleCleanup = undefined;\n this.delivery.clearQueue('manual_clear');\n }\n\n setConsent(consent: DmdConsentInput): void {\n this.consentState = typeof consent === 'object'\n ? mergeConsent(this.consentState, consent)\n : normalizeConsent(consent);\n this.gdprConsent = this.consentState.analytics;\n if (!canCollectPurpose(this.consentState, 'analytics')) {\n this.queue = [];\n this.delivery.clearQueue('consent_revoked');\n }\n }\n\n getHealth(): DmdHealthStatus {\n const deliveryDiagnostics = this.delivery.getDiagnostics();\n const health: DmdHealthStatus = {\n initialized: this.initialized,\n consent: this.gdprConsent,\n consentPurposes: this.consentState,\n queueSize: deliveryDiagnostics.queued,\n offline: this.offline || deliveryDiagnostics.queued > 0,\n droppedEvents: this.droppedEvents + deliveryDiagnostics.dropped.length,\n delivery: deliveryDiagnostics\n };\n const lastError = this.lastError ?? deliveryDiagnostics.lastError;\n if (lastError !== undefined) health.lastError = lastError;\n if (this.lastDroppedEvent !== undefined) health.lastDroppedEvent = this.lastDroppedEvent;\n return health;\n }\n\n sendEvent(payload: unknown): void {\n void this.delivery.send(payload as Record<string, unknown>).then(() => {\n const diagnostics = this.delivery.getDiagnostics();\n this.offline = diagnostics.queued > 0;\n this.lastError = diagnostics.lastError;\n if (diagnostics.queued > 0) {\n this.scheduleRetryFlush();\n }\n });\n }\n\n private installLifecycleFlush(): void {\n const browserWindow = getBrowserWindow();\n if (!browserWindow) return;\n if (typeof browserWindow.addEventListener !== 'function') return;\n if (typeof browserWindow.removeEventListener !== 'function') return;\n\n const flushOnLifecycle = () => {\n void this.flush();\n };\n const flushOnVisibility = () => {\n if (browserWindow.document?.visibilityState === 'hidden') {\n void this.flush();\n }\n };\n\n browserWindow.addEventListener('online', flushOnLifecycle);\n browserWindow.addEventListener('pagehide', flushOnLifecycle);\n if (typeof browserWindow.document?.addEventListener === 'function') {\n browserWindow.document.addEventListener('visibilitychange', flushOnVisibility);\n }\n\n this.lifecycleCleanup = () => {\n browserWindow.removeEventListener('online', flushOnLifecycle);\n browserWindow.removeEventListener('pagehide', flushOnLifecycle);\n if (typeof browserWindow.document?.removeEventListener === 'function') {\n browserWindow.document.removeEventListener('visibilitychange', flushOnVisibility);\n }\n };\n }\n\n private scheduleRetryFlush(): void {\n if (this.retryTimer !== undefined) return;\n\n const delay = Math.min(this.retryDelayMs, this.maxRetryDelayMs);\n this.retryTimer = setTimeout(() => {\n this.retryTimer = undefined;\n void this.flush().then(() => {\n if (this.delivery.getDiagnostics().queued > 0) {\n this.retryDelayMs = Math.min(this.retryDelayMs * 2, this.maxRetryDelayMs);\n this.scheduleRetryFlush();\n }\n });\n }, delay);\n }\n\n private sendPreparedEvent(\n type: DmdPreparedEvent['type'],\n event: string,\n properties: Record<string, unknown>,\n options: DmdEventOptions\n ): void {\n void this.prepareAndSendEvent(type, event, properties, options);\n }\n\n private async prepareAndSendEvent(\n type: DmdPreparedEvent['type'],\n event: string,\n properties: Record<string, unknown>,\n options: DmdEventOptions\n ): Promise<void> {\n if (!canCollectPurpose(this.consentState, 'analytics')) {\n this.recordDrop(type, 'consent_denied', event);\n return;\n }\n\n let prepared: DmdPreparedEvent = {\n type,\n event,\n properties: sanitizeProperties(properties),\n messageId: options.messageId ?? createId('msg'),\n timestamp: options.timestamp ?? new Date().toISOString(),\n context: options.context ?? {},\n anonymousId: this.identity.anonymousId,\n clientId: this.config.clientId,\n workspaceId: this.config.workspaceId,\n appId: this.config.appId,\n writeKey: this.writeKey,\n consent: this.consentState,\n sessionId: this.sessionId\n };\n\n if (this.identity.userId !== undefined) prepared.userId = this.identity.userId;\n if (this.identity.groupId !== undefined) prepared.groupId = this.identity.groupId;\n\n if (this.config.beforeSend !== undefined) {\n const beforeSendResult = await this.config.beforeSend(prepared);\n if (beforeSendResult === null) {\n this.recordDrop(type, 'before_send_dropped', event);\n return;\n }\n prepared = {\n ...prepared,\n ...beforeSendResult,\n properties: sanitizeProperties(beforeSendResult.properties ?? prepared.properties)\n };\n }\n\n const validation = validateEventEnvelope(prepared, { mode: this.config.schemaValidation ?? 'warn' });\n if (!validation.ok && this.config.schemaValidation === 'strict') {\n this.recordDrop(type, 'invalid_payload', event);\n return;\n }\n if (!validation.ok) {\n this.lastError = `DMD SDK schema warning: ${validation.errors.join(', ')}`;\n }\n\n this.sendEvent(this.toCollectorPayload(prepared));\n }\n\n private toCollectorPayload(prepared: DmdPreparedEvent): Record<string, unknown> {\n const browserWindow = getBrowserWindow();\n return createBackendCollectorPayload({\n requestId: prepared.messageId,\n timestamp: prepared.timestamp,\n eventType: prepared.event,\n clientId: prepared.clientId,\n workspaceId: prepared.workspaceId,\n token: prepared.writeKey,\n anonymousId: prepared.anonymousId,\n sessionId: prepared.sessionId,\n ua: browserWindow?.navigator?.userAgent,\n appId: prepared.appId,\n pageUrl: browserWindow?.location?.href,\n eventData: {\n ...prepared.properties,\n anonymousId: prepared.anonymousId,\n sessionId: prepared.sessionId,\n timestamp: prepared.timestamp,\n requestSentAt: prepared.timestamp,\n requestReceivedAt: prepared.timestamp\n }\n });\n }\n\n private recordDrop(type: DmdDroppedEventType, reason: DmdDroppedEventReason, event?: string): void {\n this.droppedEvents += 1;\n this.lastDroppedEvent = {\n type,\n reason,\n timestamp: new Date().toISOString()\n };\n if (event !== undefined) this.lastDroppedEvent.event = event;\n this.lastError = `DMD SDK ${type} dropped because ${reason}`;\n }\n}\n","import type { DmdDroppedEventDiagnostic, DmdDroppedEventType } from '../core/diagnostics';\nimport type {\n DmdBrowserClient,\n DmdBrowserConfig,\n DmdConsentInput,\n DmdEventOptions,\n DmdHealthStatus\n} from '../core/types';\nimport { DriveMetaDataSDK } from './core/DriveMetaDataSDK';\n\nlet singleton: DriveMetaDataSDK | undefined;\nlet publicSingleton: DmdBrowserClient | undefined;\nlet droppedEvents = 0;\nlet lastError: string | undefined;\nlet lastDroppedEvent: DmdDroppedEventDiagnostic | undefined;\n\nfunction createPublicClient(instance: DriveMetaDataSDK): DmdBrowserClient {\n return {\n track(event, properties, options) {\n instance.trackEvent(event, properties, options);\n },\n identify(userId, traits, options) {\n instance.identify(userId, traits, options);\n },\n page(name, properties, options) {\n instance.page(name, properties, options);\n },\n group(groupId, traits, options) {\n instance.group(groupId, traits, options);\n },\n alias(previousId, userId, options) {\n instance.alias(previousId, userId, options);\n },\n async flush() {\n await instance.flush();\n },\n reset() {\n instance.reset();\n singleton = undefined;\n publicSingleton = undefined;\n },\n setConsent(consent) {\n instance.setConsent(consent);\n },\n getHealth() {\n return instance.getHealth();\n }\n };\n}\n\nfunction setSingleton(instance: DriveMetaDataSDK): DmdBrowserClient {\n singleton = instance;\n publicSingleton = createPublicClient(instance);\n return publicSingleton;\n}\n\nfunction recordDroppedEvent(type: DmdDroppedEventType, event?: string): void {\n droppedEvents += 1;\n lastDroppedEvent = {\n type,\n reason: 'not_initialized',\n timestamp: new Date().toISOString()\n };\n if (event !== undefined) {\n lastDroppedEvent.event = event;\n }\n lastError = `DMD SDK ${type} called before initialization`;\n}\n\nexport function initDmdSDK(config: DmdBrowserConfig): DmdBrowserClient {\n if (publicSingleton) {\n return publicSingleton;\n }\n\n try {\n const instance = new DriveMetaDataSDK(config);\n return setSingleton(instance);\n } catch (error) {\n lastError = error instanceof Error ? error.message : String(error);\n throw error;\n }\n}\n\nexport function getDmdSDK(): DmdBrowserClient | undefined {\n return publicSingleton;\n}\n\nexport function track(event: string, properties?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('track', event);\n return;\n }\n sdk.track(event, properties, options);\n}\n\nexport function identify(userId: string, traits?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('identify');\n return;\n }\n sdk.identify(userId, traits, options);\n}\n\nexport function page(name?: string, properties?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('page');\n return;\n }\n sdk.page(name, properties, options);\n}\n\nexport function group(groupId: string, traits?: Record<string, unknown>, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('group');\n return;\n }\n sdk.group(groupId, traits, options);\n}\n\nexport function alias(previousId: string, userId: string, options?: DmdEventOptions): void {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('alias');\n return;\n }\n sdk.alias(previousId, userId, options);\n}\n\nexport async function flush(): Promise<void> {\n const sdk = getDmdSDK();\n if (!sdk) {\n recordDroppedEvent('flush');\n return;\n }\n await sdk.flush();\n}\n\nexport function reset(): void {\n singleton?.reset?.();\n singleton = undefined;\n publicSingleton = undefined;\n}\n\nexport function setConsent(consent: DmdConsentInput): void {\n getDmdSDK()?.setConsent(consent);\n}\n\nexport const consent = {\n update(state: DmdConsentInput): void {\n setConsent(state);\n }\n};\n\nexport async function ready(): Promise<DmdBrowserClient | undefined> {\n return getDmdSDK();\n}\n\nexport function getDmdHealth(): DmdHealthStatus {\n if (singleton) {\n return singleton.getHealth();\n }\n\n const health: DmdHealthStatus = {\n initialized: false,\n consent: 'pending',\n queueSize: 0,\n offline: false,\n droppedEvents\n };\n\n if (lastError !== undefined) {\n health.lastError = lastError;\n }\n if (lastDroppedEvent !== undefined) {\n health.lastDroppedEvent = lastDroppedEvent;\n }\n\n return health;\n}\n\nexport function resetDmdSDKForTests(): void {\n singleton?.reset();\n singleton = undefined;\n publicSingleton = undefined;\n droppedEvents = 0;\n lastError = undefined;\n lastDroppedEvent = undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,SAAS,mBAAmB,OAAwB;AAClD,MAAI,OAAO,UAAU,SAAU,SAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE;AAC5F,QAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,EAAG,QAAO;AACzC,SAAO,KAAK,YAAY,EAAE,QAAQ,KAAK,GAAG,EAAE,MAAM,GAAG,EAAE;AACzD;AAEA,SAAS,YAAY,OAAyB;AAC5C,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,UAAM,UAAU,MACb,IAAI,UAAQ,YAAY,IAAI,CAAC,EAC7B,OAAO,UAAQ,SAAS,QAAQ,SAAS,UAAa,SAAS,EAAE;AACpE,WAAO,QAAQ,SAAS,IAAI,UAAU;AAAA,EACxC;AAEA,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,UAAM,UAAU,OAAO;AAAA,MACrB,OAAO,QAAQ,KAAgC,EAC5C,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,YAAY,IAAI,CAAC,CAAC,EAC7C,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM;AACpB,YAAI,SAAS,QAAQ,SAAS,UAAa,SAAS,GAAI,QAAO;AAC/D,YAAI,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,KAAK,OAAO,KAAK,IAAI,EAAE,WAAW,EAAG,QAAO;AAC/F,eAAO;AAAA,MACT,CAAC;AAAA,IACL;AACA,WAAO,OAAO,KAAK,OAAO,EAAE,SAAS,IAAI,UAAU;AAAA,EACrD;AAEA,SAAO;AACT;AAEO,SAAS,8BAA8B,OAAyD;AACrG,QAAM,YAAY,MAAM,aAAa,OAAO,MAAM,cAAc,WAC5D,MAAM,YACN,CAAC;AACL,QAAMA,QAAO,UAAU,QAAQ,OAAO,UAAU,SAAS,WACrD,UAAU,OACV,CAAC;AACL,QAAM,YAAY,mBAAmB,UAAU,aAAa,MAAM,SAAS;AAC3E,QAAM,sBAAsB;AAAA,IAC1B,GAAG;AAAA,IACH;AAAA,IACA,eAAe,mBAAmB,UAAU,iBAAiB,MAAM,iBAAiB,SAAS;AAAA,IAC7F,mBAAmB,mBAAmB,UAAU,qBAAqB,MAAM,qBAAqB,SAAS;AAAA,EAC3G;AAEA,QAAM,WAAoC;AAAA,IACxC,GAAG;AAAA,IACH,WAAW,MAAM;AAAA,IACjB;AAAA,IACA,WAAW,MAAM;AAAA,IACjB,aAAa,MAAM,eAAe;AAAA,IAClC,UAAU,MAAM;AAAA,IAChB,aAAa,MAAM;AAAA,IACnB,OAAO,MAAM;AAAA,IACb,aAAa,UAAU,eAAe,MAAM;AAAA,IAC5C,WAAW,UAAU,aAAa,MAAM;AAAA,IACxC,IAAI,MAAM;AAAA,IACV,YAAY,EAAE,QAAQ,MAAM,MAAM;AAAA,IAClC,MAAM,EAAE,GAAGA,OAAM,KAAKA,MAAK,OAAO,MAAM,QAAQ;AAAA,IAChD,eAAe,oBAAoB;AAAA,IACnC,mBAAmB,oBAAoB;AAAA,EACzC;AAEA,QAAM,UAAU,EAAE,SAAS;AAE3B,SAAO,YAAY,OAAO;AAC5B;;;AC/DO,SAAS,mBAAuC;AACrD,SAAO,OAAO,WAAW,cAAc,SAAY;AACrD;;;ACGA,IAAM,WAAgC;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,sBAAsB,OAAiC;AAC9D,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,UAAU,MAAO,QAAO;AAC5B,MAAI,UAAU,aAAa,UAAU,YAAY,UAAU,UAAW,QAAO;AAC7E,SAAO;AACT;AAEO,SAAS,iBAAiB,OAAwD;AACvF,QAAM,eAAe,sBAAsB,SAAS,SAAS;AAC7D,QAAM,WAAW,OAAO;AAAA,IACtB,SAAS,IAAI,aAAW,CAAC,SAAS,YAAY,CAAC;AAAA,EACjD;AAEA,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,eAAW,WAAW,UAAU;AAC9B,YAAM,QAAQ,MAAM,OAAO;AAC3B,UAAI,UAAU,QAAW;AACvB,iBAAS,OAAO,IAAI,sBAAsB,KAAK;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,aAAa,SAA6B,QAA+C;AACvG,QAAM,OAAO,EAAE,GAAG,QAAQ;AAC1B,aAAW,CAAC,SAAS,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAkD;AACpG,SAAK,OAAO,IAAI,sBAAsB,KAAK;AAAA,EAC7C;AACA,SAAO;AACT;AAEO,SAAS,kBAAkBC,UAA6B,SAAqC;AAClG,SAAOA,SAAQ,OAAO,MAAM;AAC9B;;;ACpBA,SAAS,SAAS,QAAwB;AACxC,SAAO,GAAG,MAAM,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC,GAAG,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC;AACnF;AAEA,SAAS,gBAAgB,OAAwB;AAC/C,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D,WAAO,KAAK,UAAU,KAAK;AAAA,EAC7B;AACA,SAAO,KAAK;AAAA,IACV,OAAO;AAAA,MACL,OAAO,QAAQ,KAAgC,EAAE,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MAAM,KAAK,cAAc,KAAK,CAAC;AAAA,IACtG;AAAA,EACF;AACF;AAEA,SAAS,qBAAqB,SAAkC,WAA2B;AACzF,QAAM,WAAW,QAAQ;AACzB,QAAM,QAAQ,OAAO,UAAU,aAAa,QAAQ,SAAS,QAAQ,QAAQ,OAAO;AACpF,QAAM,aAAc,YAAY,QAAQ;AACxC,QAAM,UAAU,YAAY,WAAW,YAAY,YAAY,YAAY;AAC3E,MAAI,YAAY,OAAW,QAAO,GAAG,KAAK,IAAI,OAAO,OAAO,CAAC;AAC7D,SAAO,GAAG,KAAK,IAAI,gBAAgB,cAAc,CAAC,CAAC,KAAK,SAAS;AACnE;AAEO,SAAS,sBAAsB,QAgBf;AACrB,QAAM,QAA2B,CAAC;AAClC,QAAM,cAAsC,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC,EAAE;AAClF,QAAM,eAAe,OAAO,gBAAgB;AAC5C,QAAM,WAAW,OAAO,YAAY;AACpC,QAAM,UAAU,OAAO,WAAW;AAClC,QAAM,YAAY,OAAO,aAAa;AACtC,QAAM,QAAQ,OAAO,SAAS,SAAS,KAAK;AAC5C,QAAM,YAAY,OAAO,aAAa;AACtC,QAAM,kBAAkB,OAAO,mBAAmB;AAElD,WAAS,WAAW,OAAwE;AAC1F,gBAAY,QAAQ,KAAK,KAAK;AAC9B,WAAO,SAAS,KAAK;AAAA,EACvB;AAEA,WAAS,YAAY,OAAoB;AACvC,gBAAY,YAAY,MAAM;AAC9B,WAAO,UAAU,KAAK;AAAA,EACxB;AAEA,WAAS,kBAAkB,SAA0C;AACnE,UAAM,aAAa,KAAK,UAAU,OAAO;AACzC,QAAI,OAAO,gBAAgB,aAAa;AACtC,aAAO,IAAI,YAAY,EAAE,OAAO,UAAU,EAAE;AAAA,IAC9C;AACA,WAAO,WAAW;AAAA,EACpB;AAEA,WAAS,2BAAiC;AACxC,eAAW;AAAA,MACT,QAAQ;AAAA,MACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,CAAC;AAAA,EACH;AAEA,WAAS,YAAY,KAA4B;AAC/C,QAAI;AACF,aAAO,OAAO,SAAS,QAAQ,GAAG,KAAK;AAAA,IACzC,QAAQ;AACN,+BAAyB;AACzB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,WAAS,YAAY,KAAa,OAAwB;AACxD,QAAI;AACF,aAAO,SAAS,QAAQ,KAAK,KAAK;AAClC,aAAO;AAAA,IACT,QAAQ;AACN,+BAAyB;AACzB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,WAAS,eAAe,KAAsB;AAC5C,QAAI;AACF,aAAO,SAAS,WAAW,GAAG;AAC9B,aAAO;AAAA,IACT,QAAQ;AACN,+BAAyB;AACzB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,WAAS,eAAqB;AAC5B,QAAI,CAAC,OAAO,QAAS;AACrB,QAAI,MAAM,WAAW,GAAG;AACtB,qBAAe,QAAQ;AACvB;AAAA,IACF;AACA,gBAAY,UAAU,KAAK,UAAU,KAAK,CAAC;AAAA,EAC7C;AAEA,WAAS,YAAkB;AACzB,QAAI,CAAC,OAAO,QAAS;AACrB,UAAM,WAAW,YAAY,QAAQ;AACrC,QAAI,CAAC,SAAU;AACf,QAAI;AACF,YAAM,UAAU,KAAK,MAAM,QAAQ;AACnC,YAAM,OAAO,GAAG,MAAM,QAAQ,GAAG,QAAQ,OAAO,YAAU,UAAU,OAAO,OAAO,cAAc,QAAQ,CAAC;AACzG,kBAAY,SAAS,MAAM;AAAA,IAC7B,QAAQ;AACN,qBAAe,QAAQ;AACvB,iBAAW;AAAA,QACT,QAAQ;AAAA,QACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC,CAAC;AAAA,IACH;AAAA,EACF;AAEA,WAAS,QAAQ,QAA+B;AAC9C,UAAM,KAAK,MAAM;AACjB,WAAO,MAAM,SAAS,cAAc;AAClC,YAAM,UAAU,MAAM,MAAM;AAC5B,YAAM,aAAwE;AAAA,QAC5E,QAAQ;AAAA,QACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MACpC;AACA,UAAI,SAAS,cAAc,OAAW,YAAW,YAAY,QAAQ;AACrE,iBAAW,UAAU;AAAA,IACvB;AACA,gBAAY,SAAS,MAAM;AAC3B,iBAAa;AAAA,EACf;AAEA,WAAS,aAAa,SAA2D;AAC/E,UAAM,WAAW,QAAQ;AACzB,UAAM,YAAY,OAAO,UAAU,aAAa,QAAQ,aAAa,SAAS,KAAK,CAAC;AACpF,QAAI,UAAU;AACZ,aAAO;AAAA,QACL,GAAG;AAAA,QACH,UAAU;AAAA,UACR,GAAG;AAAA,UACH,WAAW;AAAA,QACb;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL,GAAG;AAAA,MACH;AAAA,MACA,gBAAgB,OAAO,QAAQ,kBAAkB,qBAAqB,SAAS,SAAS,CAAC;AAAA,IAC3F;AAAA,EACF;AAEA,iBAAe,QAAQ,MAA8C;AACnE,UAAM,YAAY,OAAO,SAAS,WAAW;AAC7C,QAAI,OAAO,cAAc,YAAY;AACnC,YAAM,IAAI,MAAM,mBAAmB;AAAA,IACrC;AAEA,UAAM,WAAW,MAAM,UAAU,OAAO,UAAU;AAAA,MAChD,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,MACzB,WAAW;AAAA,IACb,CAAC;AACD,QAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,EAAE;AAAA,EAC7D;AAEA,YAAU;AAEV,SAAO;AAAA,IACL,MAAM,KAAK,SAAiD;AAC1D,YAAM,OAAO,aAAa,OAAO;AAEjC,UAAI,kBAAkB,IAAI,IAAI,iBAAiB;AAC7C,mBAAW;AAAA,UACT,WAAW,OAAQ,KAAK,UAAkD,aAAa,KAAK,SAAS;AAAA,UACrG,QAAQ;AAAA,UACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC,CAAC;AACD;AAAA,MACF;AAEA,kBAAY,YAAY;AACxB,UAAI;AACF,cAAM,QAAQ,IAAI;AAAA,MACpB,SAAS,OAAO;AACd,cAAM,gBAAgB,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAC9E,oBAAY,aAAa;AACzB,gBAAQ;AAAA,UACN,WAAW,OAAQ,KAAK,UAAkD,aAAa,KAAK,SAAS;AAAA,UACrG,SAAS,KAAK,IAAI;AAAA,UAClB,UAAU;AAAA,UACV,WAAW,cAAc;AAAA,UACzB,SAAS;AAAA,QACX,CAAC;AAAA,MACH,UAAE;AACA,oBAAY,YAAY;AACxB,oBAAY,SAAS,MAAM;AAAA,MAC7B;AAAA,IACF;AAAA,IACA,MAAM,aAA4B;AAChC,WAAK,aAAa;AAClB,UAAI,MAAM,WAAW,KAAK,CAAC,KAAK,kBAAkB,EAAG;AAErD,kBAAY,YAAY;AACxB,UAAI;AACF,YAAI,cAAc;AAClB,iBAAS,QAAQ,GAAG,QAAQ,MAAM,UAAU,cAAc,aAAY;AACpE,gBAAM,SAAS,MAAM,KAAK;AAC1B,cAAI,CAAC,QAAQ;AACX,qBAAS;AACT;AAAA,UACF;AAEA,cAAI;AACF,kBAAM,QAAQ,OAAO,OAAO;AAC5B,kBAAM,OAAO,OAAO,CAAC;AACrB,2BAAe;AACf,yBAAa;AAAA,UACf,SAAS,OAAO;AACd,kBAAM,gBAAgB,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAC9E,mBAAO,YAAY;AACnB,mBAAO,YAAY,cAAc;AACjC,wBAAY,aAAa;AACzB,qBAAS;AACT,yBAAa;AACb;AAAA,UACF;AAAA,QACF;AAAA,MACF,UAAE;AACA,oBAAY,YAAY;AACxB,oBAAY,SAAS,MAAM;AAC3B,aAAK,kBAAkB;AAAA,MACzB;AAAA,IACF;AAAA,IACA,WAAW,QAAsB;AAC/B,iBAAW,UAAU,OAAO;AAC1B,mBAAW;AAAA,UACT,WAAW,OAAO;AAAA,UAClB;AAAA,UACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC,CAAC;AAAA,MACH;AACA,YAAM,OAAO,GAAG,MAAM,MAAM;AAC5B,kBAAY,SAAS;AACrB,mBAAa;AAAA,IACf;AAAA,IACA,gBAAgB,QAA+B;AAC7C,cAAQ,MAAM;AAAA,IAChB;AAAA,IACA,eAAqB;AACnB,YAAM,MAAM,OAAO,cAAc;AACjC,YAAM,MAAM,KAAK,IAAI;AACrB,eAAS,QAAQ,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;AACzD,cAAM,SAAS,MAAM,KAAK;AAC1B,YAAI,UAAU,MAAM,OAAO,UAAU,KAAK;AACxC,qBAAW;AAAA,YACT,WAAW,OAAO;AAAA,YAClB,QAAQ;AAAA,YACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,UACpC,CAAC;AACD,gBAAM,OAAO,OAAO,CAAC;AAAA,QACvB;AAAA,MACF;AACA,kBAAY,SAAS,MAAM;AAC3B,mBAAa;AAAA,IACf;AAAA,IACA,oBAA6B;AAC3B,UAAI,CAAC,OAAO,QAAS,QAAO;AAE5B,YAAM,MAAM,KAAK,IAAI;AACrB,YAAM,UAAU,YAAY,OAAO;AACnC,UAAI;AACJ,UAAI,SAAS;AACX,YAAI;AACF,yBAAe,KAAK,MAAM,OAAO;AAAA,QACnC,QAAQ;AACN,yBAAe;AAAA,QACjB;AAAA,MACF;AAEA,YAAM,cAAc,CAAC,cAAc,aAAa,aAAa,aAAa;AAC1E,YAAM,qBAAqB,cAAc,UAAU;AACnD,UAAI,CAAC,gBAAgB,eAAe,oBAAoB;AACtD,YAAI,CAAC,YAAY,SAAS,KAAK,UAAU,EAAE,OAAO,OAAO,WAAW,MAAM,UAAU,CAAC,CAAC,GAAG;AACvF,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT;AAAA,IACA,oBAA0B;AACxB,UAAI,CAAC,OAAO,QAAS;AACrB,YAAM,UAAU,YAAY,OAAO;AACnC,UAAI,CAAC,QAAS;AAEd,UAAI;AACF,cAAM,eAAe,KAAK,MAAM,OAAO;AACvC,YAAI,aAAa,UAAU,OAAO;AAChC,yBAAe,OAAO;AAAA,QACxB;AAAA,MACF,QAAQ;AACN,uBAAe,OAAO;AAAA,MACxB;AAAA,IACF;AAAA,IACA,iBAAyC;AACvC,aAAO;AAAA,IACT;AAAA,EACF;AACF;;;ACnWA,IAAM,gBAAgB,oBAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAeD,SAAS,cAAc,OAAgB,OAA6B;AAClE,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,UAAQ,cAAc,MAAM,KAAK,CAAC;AAAA,EACrD;AAEA,MAAI,SAAS,OAAO,UAAU,UAAU;AACtC,WAAO,OAAO;AAAA,MACZ,OAAO,QAAQ,KAAgC,EAC5C,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,cAAc,IAAI,IAAI,YAAY,CAAC,KAAK,MAAM,IAAI,IAAI,YAAY,CAAC,CAAC,EACvF,IAAI,CAAC,CAAC,KAAK,WAAW,MAAM,CAAC,KAAK,cAAc,aAAa,KAAK,CAAC,CAAC;AAAA,IACzE;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,mBAAmB,OAAgC,eAAyB,CAAC,GAA4B;AACvH,QAAM,QAAQ,IAAI,IAAI,aAAa,IAAI,SAAO,IAAI,YAAY,CAAC,CAAC;AAChE,SAAO,cAAc,OAAO,KAAK;AACnC;;;ACjDA,IAAM,eAAe,oBAAI,IAAI,CAAC,aAAa,aAAa,QAAQ,SAAS,eAAe,UAAU,SAAS,CAAC;AAOrG,SAAS,sBACd,UAOA,UAAgD,CAAC,GACtB;AAC3B,MAAI,QAAQ,SAAS,MAAO,QAAO,EAAE,IAAI,MAAM,QAAQ,CAAC,EAAE;AAC1D,QAAM,SAAmB,CAAC;AAC1B,MAAI,OAAO,SAAS,SAAS,SAAU,QAAO,KAAK,uBAAuB;AAC1E,MAAI,SAAS,SAAS,WAAW,OAAO,SAAS,UAAU,UAAU;AACnE,WAAO,KAAK,qCAAqC;AAAA,EACnD;AACA,MAAI,OAAO,SAAS,cAAc,SAAU,QAAO,KAAK,4BAA4B;AACpF,MAAI,OAAO,SAAS,cAAc,SAAU,QAAO,KAAK,iCAAiC;AACzF,aAAW,OAAO,OAAO,KAAK,SAAS,cAAc,CAAC,CAAC,GAAG;AACxD,QAAI,aAAa,IAAI,GAAG,EAAG,QAAO,KAAK,cAAc,GAAG,cAAc;AAAA,EACxE;AACA,SAAO,EAAE,IAAI,OAAO,WAAW,GAAG,OAAO;AAC3C;;;ACDA,SAASC,UAAS,QAAwB;AACxC,SAAO,GAAG,MAAM,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC,GAAG,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC;AACnF;AAEA,SAAS,mBAAmB,QAAkC;AAC5D,QAAM,OAAO,OAAO,WAAW;AAC/B,SAAO,GAAG,KAAK,QAAQ,OAAO,EAAE,CAAC;AACnC;AAEA,SAAS,oBAAoB,OAA2B,OAAuB;AAC7E,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,IAAI;AACpD,UAAM,IAAI,MAAM,kBAAkB,KAAK,cAAc;AAAA,EACvD;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB;AAC3B,QAAM,gBAAgB,iBAAiB;AACvC,MAAI;AACF,WAAO,eAAe;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,IAAM,mBAAN,MAAuB;AAAA,EAsB5B,YAAY,QAA0B;AArBtC,SAAO,cAAc;AACrB,SAAO,QAAmB,CAAC;AAC3B,SAAO,UAAU;AAUjB,SAAQ,gBAAgB;AAUtB,wBAAoB,OAAO,UAAU,UAAU;AAC/C,wBAAoB,OAAO,aAAa,aAAa;AACrD,wBAAoB,OAAO,OAAO,OAAO;AACzC,wBAAoB,OAAO,YAAY,OAAO,OAAO,mBAAmB;AACxE,SAAK,SAAS;AACd,SAAK,WAAW,mBAAmB,MAAM;AACzC,UAAM,UAAU,kBAAkB;AAClC,UAAM,iBAA8D;AAAA,MAClE,UAAU,KAAK;AAAA,IACjB;AACA,QAAI,OAAO,UAAU,iBAAiB,OAAW,gBAAe,eAAe,OAAO,SAAS;AAC/F,QAAI,OAAO,UAAU,eAAe,OAAW,gBAAe,aAAa,OAAO,SAAS;AAC3F,QAAI,OAAO,UAAU,iBAAiB,OAAW,gBAAe,eAAe,OAAO,SAAS;AAC/F,QAAI,OAAO,UAAU,oBAAoB,OAAW,gBAAe,kBAAkB,OAAO,SAAS;AACrG,QAAI,OAAO,UAAU,oBAAoB,OAAW,gBAAe,kBAAkB,OAAO,SAAS;AACrG,QAAI,OAAO,UAAU,cAAc,OAAW,gBAAe,YAAY,OAAO,SAAS;AACzF,QAAI,OAAO,WAAW,OAAW,gBAAe,SAAS,OAAO;AAChE,QAAI,OAAO,YAAY,OAAW,gBAAe,UAAU,OAAO;AAClE,SAAK,WAAW,sBAAsB,UAAU;AAAA,MAC9C,GAAG;AAAA,MACH;AAAA,IACF,IAAI,cAAc;AAClB,SAAK,sBAAsB,OAAO,UAAU,gBAAgB;AAC5D,SAAK,eAAe,KAAK;AACzB,SAAK,kBAAkB,OAAO,UAAU,mBAAmB;AAC3D,SAAK,WAAW,OAAO,YAAY,OAAO,SAAS;AACnD,SAAK,WAAW,EAAE,aAAaA,UAAS,MAAM,EAAE;AAChD,SAAK,YAAYA,UAAS,SAAS;AACnC,SAAK,eAAe,iBAAiB,OAAO,eAAe,OAAO,OAAO;AACzE,SAAK,cAAc,KAAK,aAAa;AACrC,QAAI,CAAC,OAAO,UAAU,uBAAuB;AAC3C,WAAK,sBAAsB;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,WAAW,OAAe,aAAsC,CAAC,GAAG,UAA2B,CAAC,GAAS;AACvG,SAAK,kBAAkB,SAAS,OAAO,YAAY,OAAO;AAAA,EAC5D;AAAA,EAEA,KAAK,MAAe,aAAsC,CAAC,GAAG,UAA2B,CAAC,GAAS;AACjG,SAAK,kBAAkB,QAAQ,aAAa,EAAE,MAAM,GAAG,WAAW,GAAG,OAAO;AAAA,EAC9E;AAAA,EAEA,gBAAsB;AACpB,SAAK,KAAK;AAAA,EACZ;AAAA,EAEA,SAAS,QAAgB,SAAkC,CAAC,GAAG,UAA2B,CAAC,GAAS;AAClG,SAAK,WAAW,EAAE,GAAG,KAAK,UAAU,QAAQ,OAAO;AACnD,SAAK,kBAAkB,YAAY,YAAY,EAAE,QAAQ,OAAO,GAAG,OAAO;AAAA,EAC5E;AAAA,EAEA,aAAa,QAAgB,SAAkC,CAAC,GAAS;AACvE,SAAK,SAAS,QAAQ,MAAM;AAAA,EAC9B;AAAA,EAEA,MAAM,SAAiB,SAAkC,CAAC,GAAG,UAA2B,CAAC,GAAS;AAChG,SAAK,WAAW,EAAE,GAAG,KAAK,UAAU,QAAQ;AAC5C,SAAK,kBAAkB,SAAS,SAAS,EAAE,SAAS,OAAO,GAAG,OAAO;AAAA,EACvE;AAAA,EAEA,MAAM,YAAoB,QAAgB,UAA2B,CAAC,GAAS;AAC7E,SAAK,kBAAkB,SAAS,SAAS,EAAE,YAAY,OAAO,GAAG,OAAO;AAAA,EAC1E;AAAA,EAEA,MAAM,QAAuB;AAC3B,UAAM,KAAK,SAAS,WAAW;AAC/B,UAAM,cAAc,KAAK,SAAS,eAAe;AACjD,SAAK,UAAU,YAAY,SAAS;AACpC,SAAK,YAAY,YAAY;AAC7B,QAAI,YAAY,SAAS,GAAG;AAC1B,WAAK,mBAAmB;AAAA,IAC1B,OAAO;AACL,WAAK,eAAe,KAAK;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,SAAK,WAAW,EAAE,aAAaA,UAAS,MAAM,EAAE;AAChD,SAAK,QAAQ,CAAC;AACd,SAAK,UAAU;AACf,QAAI,KAAK,eAAe,QAAW;AACjC,mBAAa,KAAK,UAAU;AAC5B,WAAK,aAAa;AAAA,IACpB;AACA,SAAK,mBAAmB;AACxB,SAAK,mBAAmB;AACxB,SAAK,SAAS,WAAW,cAAc;AAAA,EACzC;AAAA,EAEA,WAAWC,UAAgC;AACzC,SAAK,eAAe,OAAOA,aAAY,WACnC,aAAa,KAAK,cAAcA,QAAO,IACvC,iBAAiBA,QAAO;AAC5B,SAAK,cAAc,KAAK,aAAa;AACrC,QAAI,CAAC,kBAAkB,KAAK,cAAc,WAAW,GAAG;AACtD,WAAK,QAAQ,CAAC;AACd,WAAK,SAAS,WAAW,iBAAiB;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,YAA6B;AAC3B,UAAM,sBAAsB,KAAK,SAAS,eAAe;AACzD,UAAM,SAA0B;AAAA,MAC9B,aAAa,KAAK;AAAA,MAClB,SAAS,KAAK;AAAA,MACd,iBAAiB,KAAK;AAAA,MACtB,WAAW,oBAAoB;AAAA,MAC/B,SAAS,KAAK,WAAW,oBAAoB,SAAS;AAAA,MACtD,eAAe,KAAK,gBAAgB,oBAAoB,QAAQ;AAAA,MAChE,UAAU;AAAA,IACZ;AACA,UAAMC,aAAY,KAAK,aAAa,oBAAoB;AACxD,QAAIA,eAAc,OAAW,QAAO,YAAYA;AAChD,QAAI,KAAK,qBAAqB,OAAW,QAAO,mBAAmB,KAAK;AACxE,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,SAAwB;AAChC,SAAK,KAAK,SAAS,KAAK,OAAkC,EAAE,KAAK,MAAM;AACrE,YAAM,cAAc,KAAK,SAAS,eAAe;AACjD,WAAK,UAAU,YAAY,SAAS;AACpC,WAAK,YAAY,YAAY;AAC7B,UAAI,YAAY,SAAS,GAAG;AAC1B,aAAK,mBAAmB;AAAA,MAC1B;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,wBAA8B;AACpC,UAAM,gBAAgB,iBAAiB;AACvC,QAAI,CAAC,cAAe;AACpB,QAAI,OAAO,cAAc,qBAAqB,WAAY;AAC1D,QAAI,OAAO,cAAc,wBAAwB,WAAY;AAE7D,UAAM,mBAAmB,MAAM;AAC7B,WAAK,KAAK,MAAM;AAAA,IAClB;AACA,UAAM,oBAAoB,MAAM;AAC9B,UAAI,cAAc,UAAU,oBAAoB,UAAU;AACxD,aAAK,KAAK,MAAM;AAAA,MAClB;AAAA,IACF;AAEA,kBAAc,iBAAiB,UAAU,gBAAgB;AACzD,kBAAc,iBAAiB,YAAY,gBAAgB;AAC3D,QAAI,OAAO,cAAc,UAAU,qBAAqB,YAAY;AAClE,oBAAc,SAAS,iBAAiB,oBAAoB,iBAAiB;AAAA,IAC/E;AAEA,SAAK,mBAAmB,MAAM;AAC5B,oBAAc,oBAAoB,UAAU,gBAAgB;AAC5D,oBAAc,oBAAoB,YAAY,gBAAgB;AAC9D,UAAI,OAAO,cAAc,UAAU,wBAAwB,YAAY;AACrE,sBAAc,SAAS,oBAAoB,oBAAoB,iBAAiB;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,qBAA2B;AACjC,QAAI,KAAK,eAAe,OAAW;AAEnC,UAAM,QAAQ,KAAK,IAAI,KAAK,cAAc,KAAK,eAAe;AAC9D,SAAK,aAAa,WAAW,MAAM;AACjC,WAAK,aAAa;AAClB,WAAK,KAAK,MAAM,EAAE,KAAK,MAAM;AAC3B,YAAI,KAAK,SAAS,eAAe,EAAE,SAAS,GAAG;AAC7C,eAAK,eAAe,KAAK,IAAI,KAAK,eAAe,GAAG,KAAK,eAAe;AACxE,eAAK,mBAAmB;AAAA,QAC1B;AAAA,MACF,CAAC;AAAA,IACH,GAAG,KAAK;AAAA,EACV;AAAA,EAEQ,kBACN,MACA,OACA,YACA,SACM;AACN,SAAK,KAAK,oBAAoB,MAAM,OAAO,YAAY,OAAO;AAAA,EAChE;AAAA,EAEA,MAAc,oBACZ,MACA,OACA,YACA,SACe;AACf,QAAI,CAAC,kBAAkB,KAAK,cAAc,WAAW,GAAG;AACtD,WAAK,WAAW,MAAM,kBAAkB,KAAK;AAC7C;AAAA,IACF;AAEA,QAAI,WAA6B;AAAA,MAC/B;AAAA,MACA;AAAA,MACA,YAAY,mBAAmB,UAAU;AAAA,MACzC,WAAW,QAAQ,aAAaF,UAAS,KAAK;AAAA,MAC9C,WAAW,QAAQ,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,MACvD,SAAS,QAAQ,WAAW,CAAC;AAAA,MAC7B,aAAa,KAAK,SAAS;AAAA,MAC3B,UAAU,KAAK,OAAO;AAAA,MACtB,aAAa,KAAK,OAAO;AAAA,MACzB,OAAO,KAAK,OAAO;AAAA,MACnB,UAAU,KAAK;AAAA,MACf,SAAS,KAAK;AAAA,MACd,WAAW,KAAK;AAAA,IAClB;AAEA,QAAI,KAAK,SAAS,WAAW,OAAW,UAAS,SAAS,KAAK,SAAS;AACxE,QAAI,KAAK,SAAS,YAAY,OAAW,UAAS,UAAU,KAAK,SAAS;AAE1E,QAAI,KAAK,OAAO,eAAe,QAAW;AACxC,YAAM,mBAAmB,MAAM,KAAK,OAAO,WAAW,QAAQ;AAC9D,UAAI,qBAAqB,MAAM;AAC7B,aAAK,WAAW,MAAM,uBAAuB,KAAK;AAClD;AAAA,MACF;AACA,iBAAW;AAAA,QACT,GAAG;AAAA,QACH,GAAG;AAAA,QACH,YAAY,mBAAmB,iBAAiB,cAAc,SAAS,UAAU;AAAA,MACnF;AAAA,IACF;AAEA,UAAM,aAAa,sBAAsB,UAAU,EAAE,MAAM,KAAK,OAAO,oBAAoB,OAAO,CAAC;AACnG,QAAI,CAAC,WAAW,MAAM,KAAK,OAAO,qBAAqB,UAAU;AAC/D,WAAK,WAAW,MAAM,mBAAmB,KAAK;AAC9C;AAAA,IACF;AACA,QAAI,CAAC,WAAW,IAAI;AAClB,WAAK,YAAY,2BAA2B,WAAW,OAAO,KAAK,IAAI,CAAC;AAAA,IAC1E;AAEA,SAAK,UAAU,KAAK,mBAAmB,QAAQ,CAAC;AAAA,EAClD;AAAA,EAEQ,mBAAmB,UAAqD;AAC9E,UAAM,gBAAgB,iBAAiB;AACvC,WAAO,8BAA8B;AAAA,MACnC,WAAW,SAAS;AAAA,MACpB,WAAW,SAAS;AAAA,MACpB,WAAW,SAAS;AAAA,MACpB,UAAU,SAAS;AAAA,MACnB,aAAa,SAAS;AAAA,MACtB,OAAO,SAAS;AAAA,MAChB,aAAa,SAAS;AAAA,MACtB,WAAW,SAAS;AAAA,MACpB,IAAI,eAAe,WAAW;AAAA,MAC9B,OAAO,SAAS;AAAA,MAChB,SAAS,eAAe,UAAU;AAAA,MAClC,WAAW;AAAA,QACT,GAAG,SAAS;AAAA,QACZ,aAAa,SAAS;AAAA,QACtB,WAAW,SAAS;AAAA,QACpB,WAAW,SAAS;AAAA,QACpB,eAAe,SAAS;AAAA,QACxB,mBAAmB,SAAS;AAAA,MAC9B;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,WAAW,MAA2B,QAA+B,OAAsB;AACjG,SAAK,iBAAiB;AACtB,SAAK,mBAAmB;AAAA,MACtB;AAAA,MACA;AAAA,MACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC;AACA,QAAI,UAAU,OAAW,MAAK,iBAAiB,QAAQ;AACvD,SAAK,YAAY,WAAW,IAAI,oBAAoB,MAAM;AAAA,EAC5D;AACF;;;ACnVA,IAAI;AACJ,IAAI;AACJ,IAAI,gBAAgB;AACpB,IAAI;AACJ,IAAI;AAEJ,SAAS,mBAAmB,UAA8C;AACxE,SAAO;AAAA,IACL,MAAM,OAAO,YAAY,SAAS;AAChC,eAAS,WAAW,OAAO,YAAY,OAAO;AAAA,IAChD;AAAA,IACA,SAAS,QAAQ,QAAQ,SAAS;AAChC,eAAS,SAAS,QAAQ,QAAQ,OAAO;AAAA,IAC3C;AAAA,IACA,KAAK,MAAM,YAAY,SAAS;AAC9B,eAAS,KAAK,MAAM,YAAY,OAAO;AAAA,IACzC;AAAA,IACA,MAAM,SAAS,QAAQ,SAAS;AAC9B,eAAS,MAAM,SAAS,QAAQ,OAAO;AAAA,IACzC;AAAA,IACA,MAAM,YAAY,QAAQ,SAAS;AACjC,eAAS,MAAM,YAAY,QAAQ,OAAO;AAAA,IAC5C;AAAA,IACA,MAAM,QAAQ;AACZ,YAAM,SAAS,MAAM;AAAA,IACvB;AAAA,IACA,QAAQ;AACN,eAAS,MAAM;AACf,kBAAY;AACZ,wBAAkB;AAAA,IACpB;AAAA,IACA,WAAWG,UAAS;AAClB,eAAS,WAAWA,QAAO;AAAA,IAC7B;AAAA,IACA,YAAY;AACV,aAAO,SAAS,UAAU;AAAA,IAC5B;AAAA,EACF;AACF;AAEA,SAAS,aAAa,UAA8C;AAClE,cAAY;AACZ,oBAAkB,mBAAmB,QAAQ;AAC7C,SAAO;AACT;AAEA,SAAS,mBAAmB,MAA2B,OAAsB;AAC3E,mBAAiB;AACjB,qBAAmB;AAAA,IACjB;AAAA,IACA,QAAQ;AAAA,IACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AACA,MAAI,UAAU,QAAW;AACvB,qBAAiB,QAAQ;AAAA,EAC3B;AACA,cAAY,WAAW,IAAI;AAC7B;AAEO,SAAS,WAAW,QAA4C;AACrE,MAAI,iBAAiB;AACnB,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,WAAW,IAAI,iBAAiB,MAAM;AAC5C,WAAO,aAAa,QAAQ;AAAA,EAC9B,SAAS,OAAO;AACd,gBAAY,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,UAAM;AAAA,EACR;AACF;AAEO,SAAS,YAA0C;AACxD,SAAO;AACT;AAEO,SAAS,MAAM,OAAe,YAAsC,SAAiC;AAC1G,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,KAAK;AACR,uBAAmB,SAAS,KAAK;AACjC;AAAA,EACF;AACA,MAAI,MAAM,OAAO,YAAY,OAAO;AACtC;AAEO,SAAS,SAAS,QAAgB,QAAkC,SAAiC;AAC1G,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,KAAK;AACR,uBAAmB,UAAU;AAC7B;AAAA,EACF;AACA,MAAI,SAAS,QAAQ,QAAQ,OAAO;AACtC;AAEO,SAAS,KAAK,MAAe,YAAsC,SAAiC;AACzG,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,KAAK;AACR,uBAAmB,MAAM;AACzB;AAAA,EACF;AACA,MAAI,KAAK,MAAM,YAAY,OAAO;AACpC;AAEO,SAAS,MAAM,SAAiB,QAAkC,SAAiC;AACxG,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,KAAK;AACR,uBAAmB,OAAO;AAC1B;AAAA,EACF;AACA,MAAI,MAAM,SAAS,QAAQ,OAAO;AACpC;AAEO,SAAS,MAAM,YAAoB,QAAgB,SAAiC;AACzF,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,KAAK;AACR,uBAAmB,OAAO;AAC1B;AAAA,EACF;AACA,MAAI,MAAM,YAAY,QAAQ,OAAO;AACvC;AAEA,eAAsB,QAAuB;AAC3C,QAAM,MAAM,UAAU;AACtB,MAAI,CAAC,KAAK;AACR,uBAAmB,OAAO;AAC1B;AAAA,EACF;AACA,QAAM,IAAI,MAAM;AAClB;AAEO,SAAS,QAAc;AAC5B,aAAW,QAAQ;AACnB,cAAY;AACZ,oBAAkB;AACpB;AAEO,SAAS,WAAWA,UAAgC;AACzD,YAAU,GAAG,WAAWA,QAAO;AACjC;AAEO,IAAM,UAAU;AAAA,EACrB,OAAO,OAA8B;AACnC,eAAW,KAAK;AAAA,EAClB;AACF;AAEA,eAAsB,QAA+C;AACnE,SAAO,UAAU;AACnB;AAEO,SAAS,eAAgC;AAC9C,MAAI,WAAW;AACb,WAAO,UAAU,UAAU;AAAA,EAC7B;AAEA,QAAM,SAA0B;AAAA,IAC9B,aAAa;AAAA,IACb,SAAS;AAAA,IACT,WAAW;AAAA,IACX,SAAS;AAAA,IACT;AAAA,EACF;AAEA,MAAI,cAAc,QAAW;AAC3B,WAAO,YAAY;AAAA,EACrB;AACA,MAAI,qBAAqB,QAAW;AAClC,WAAO,mBAAmB;AAAA,EAC5B;AAEA,SAAO;AACT;AAEO,SAAS,sBAA4B;AAC1C,aAAW,MAAM;AACjB,cAAY;AACZ,oBAAkB;AAClB,kBAAgB;AAChB,cAAY;AACZ,qBAAmB;AACrB;","names":["page","consent","createId","consent","lastError","consent"]}