@grainql/analytics-web 3.0.3 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/heatmap-tracking.d.ts.map +1 -1
- package/dist/cjs/heatmap-tracking.js +14 -21
- package/dist/cjs/heatmap-tracking.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/interaction-tracking.d.ts.map +1 -1
- package/dist/cjs/interaction-tracking.js +4 -4
- package/dist/cjs/interaction-tracking.js.map +1 -1
- package/dist/cjs/section-tracking.d.ts.map +1 -1
- package/dist/cjs/section-tracking.js +2 -4
- package/dist/cjs/section-tracking.js.map +1 -1
- package/dist/esm/heatmap-tracking.d.ts.map +1 -1
- package/dist/esm/heatmap-tracking.js +14 -21
- package/dist/esm/heatmap-tracking.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/interaction-tracking.d.ts.map +1 -1
- package/dist/esm/interaction-tracking.js +4 -4
- package/dist/esm/interaction-tracking.js.map +1 -1
- package/dist/esm/section-tracking.d.ts.map +1 -1
- package/dist/esm/section-tracking.js +2 -4
- package/dist/esm/section-tracking.js.map +1 -1
- package/dist/heatmap-tracking.d.ts.map +1 -1
- package/dist/heatmap-tracking.js +14 -21
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.global.dev.js +11 -30
- package/dist/index.global.dev.js.map +2 -2
- package/dist/index.global.js +8 -8
- package/dist/index.global.js.map +3 -3
- package/dist/index.js +13 -0
- package/dist/index.mjs +13 -0
- package/dist/interaction-tracking.d.ts.map +1 -1
- package/dist/interaction-tracking.js +4 -4
- package/dist/section-tracking.d.ts.map +1 -1
- package/dist/section-tracking.js +2 -4
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/attention-quality.ts", "../src/text-utils.ts", "../src/heatmap-tracking.ts", "../src/interaction-tracking.ts", "../src/section-tracking.ts", "../src/debug-agent.ts", "../src/index.ts", "../src/consent.ts", "../src/cookies.ts", "../src/activity.ts", "../src/heartbeat.ts", "../src/attribution.ts", "../src/countries.ts", "../src/page-tracking.ts", "../src/id-manager.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Attention Quality Manager for Grain Analytics\n * Enforces policies to ensure tracked data represents genuine user attention\n * \n * Policies:\n * 1. Page Visibility: Stop tracking when tab is hidden/backgrounded\n * 2. User Activity: Stop tracking when user is idle (no mouse/keyboard/touch)\n * 3. Section Duration Cap: Max attention per section before requiring transition\n * 4. Scroll Distance: Minimum scroll distance to count as meaningful engagement\n * \n * See: ATTENTION_QUALITY_POLICY.md for detailed policy documentation\n */\n\nimport type { ActivityDetector } from './activity';\n\nexport interface AttentionQualityOptions {\n /**\n * Maximum continuous attention duration per section (ms)\n * Default: 9000 (9 seconds)\n */\n maxSectionDuration?: number;\n\n /**\n * Minimum scroll distance to reset attention timer (px)\n * Default: 100\n */\n minScrollDistance?: number;\n\n /**\n * Idle threshold - stop tracking after this period of inactivity (ms)\n * Default: 30000 (30 seconds)\n */\n idleThreshold?: number;\n\n /**\n * Enable debug logging\n */\n debug?: boolean;\n}\n\ninterface SectionAttentionState {\n sectionName: string;\n currentDuration: number; // Cumulative duration in current attention block\n lastScrollPosition: number;\n lastResetTime: number;\n}\n\nconst DEFAULT_OPTIONS: Required<Omit<AttentionQualityOptions, 'debug'>> = {\n maxSectionDuration: 9000, // 9 seconds\n minScrollDistance: 100, // 100 pixels\n idleThreshold: 30000, // 30 seconds\n};\n\nexport class AttentionQualityManager {\n private options: Required<Omit<AttentionQualityOptions, 'debug'>> & { debug: boolean };\n private activityDetector: ActivityDetector;\n private isDestroyed = false;\n\n // Page visibility tracking\n private isPageVisible = true;\n private visibilityChangeHandler: (() => void) | null = null;\n\n // Section attention state\n private sectionStates = new Map<string, SectionAttentionState>();\n\n // Policies applied reasons (for debugging/traceability)\n private lastFilterReason: string | null = null;\n\n constructor(activityDetector: ActivityDetector, options: AttentionQualityOptions = {}) {\n this.activityDetector = activityDetector;\n this.options = {\n ...DEFAULT_OPTIONS,\n ...options,\n debug: options.debug ?? false,\n };\n\n this.setupPageVisibilityTracking();\n }\n\n /**\n * Setup page visibility tracking\n */\n private setupPageVisibilityTracking(): void {\n if (typeof document === 'undefined') return;\n\n this.isPageVisible = document.visibilityState === 'visible';\n\n this.visibilityChangeHandler = () => {\n const wasVisible = this.isPageVisible;\n this.isPageVisible = document.visibilityState === 'visible';\n\n if (!this.isPageVisible && wasVisible) {\n this.log('Page hidden - tracking paused');\n } else if (this.isPageVisible && !wasVisible) {\n this.log('Page visible - tracking resumed');\n // Reset all section states when page becomes visible again\n this.resetAllSections();\n }\n };\n\n document.addEventListener('visibilitychange', this.visibilityChangeHandler);\n }\n\n /**\n * Check if tracking should be allowed (global check)\n * Returns true if tracking is allowed, false if it should be paused\n */\n shouldTrack(): boolean {\n // Policy 1: Page Visibility\n if (!this.isPageVisible) {\n this.lastFilterReason = 'page_hidden';\n return false;\n }\n\n // Policy 2: User Activity\n if (!this.activityDetector.isActive(this.options.idleThreshold)) {\n this.lastFilterReason = 'user_idle';\n return false;\n }\n\n this.lastFilterReason = null;\n return true;\n }\n\n /**\n * Check if section view tracking should be allowed for a specific section\n * @param sectionName - Section identifier\n * @param currentScrollY - Current scroll position\n * @returns Object with shouldTrack boolean and optional reason\n */\n shouldTrackSection(sectionName: string, currentScrollY: number): {\n shouldTrack: boolean;\n reason?: string;\n resetAttention?: boolean;\n } {\n // First check global tracking state\n if (!this.shouldTrack()) {\n return {\n shouldTrack: false,\n reason: this.lastFilterReason || 'global_policy',\n };\n }\n\n // Get or create section state\n let state = this.sectionStates.get(sectionName);\n if (!state) {\n state = {\n sectionName,\n currentDuration: 0,\n lastScrollPosition: currentScrollY,\n lastResetTime: Date.now(),\n };\n this.sectionStates.set(sectionName, state);\n }\n\n // Policy 4: Scroll Distance - Check if user has scrolled enough to reset attention\n const scrollDistance = Math.abs(currentScrollY - state.lastScrollPosition);\n const hasScrolledEnough = scrollDistance >= this.options.minScrollDistance;\n\n if (hasScrolledEnough) {\n // Reset attention timer due to meaningful scroll\n this.log(`Section \"${sectionName}\": Attention reset due to ${Math.round(scrollDistance)}px scroll`);\n state.currentDuration = 0;\n state.lastScrollPosition = currentScrollY;\n state.lastResetTime = Date.now();\n return {\n shouldTrack: true,\n resetAttention: true,\n };\n }\n\n // Policy 3: Section Duration Cap\n if (state.currentDuration >= this.options.maxSectionDuration) {\n return {\n shouldTrack: false,\n reason: 'max_duration_reached',\n };\n }\n\n return {\n shouldTrack: true,\n };\n }\n\n /**\n * Update section duration (call this when tracking a section view event)\n * @param sectionName - Section identifier\n * @param durationMs - Duration to add to current attention block\n */\n updateSectionDuration(sectionName: string, durationMs: number): void {\n const state = this.sectionStates.get(sectionName);\n if (state) {\n state.currentDuration += durationMs;\n \n if (state.currentDuration >= this.options.maxSectionDuration) {\n this.log(`Section \"${sectionName}\": Max duration cap reached (${state.currentDuration}ms)`);\n }\n }\n }\n\n /**\n * Reset attention for a specific section (call when user navigates to different section)\n * @param sectionName - Section identifier\n */\n resetSection(sectionName: string): void {\n const state = this.sectionStates.get(sectionName);\n if (state) {\n this.log(`Section \"${sectionName}\": Attention reset (section exit)`);\n state.currentDuration = 0;\n state.lastResetTime = Date.now();\n }\n }\n\n /**\n * Reset all section attention states\n */\n resetAllSections(): void {\n this.log('Resetting all section attention states');\n for (const state of this.sectionStates.values()) {\n state.currentDuration = 0;\n state.lastResetTime = Date.now();\n }\n }\n\n /**\n * Get current attention state for a section (for debugging/monitoring)\n */\n getSectionState(sectionName: string): SectionAttentionState | undefined {\n return this.sectionStates.get(sectionName);\n }\n\n /**\n * Get reason why last tracking attempt was filtered\n */\n getLastFilterReason(): string | null {\n return this.lastFilterReason;\n }\n\n /**\n * Check if scroll tracking should be allowed\n * Similar to shouldTrack() but also checks scroll-specific conditions\n */\n shouldTrackScroll(previousScrollY: number, currentScrollY: number): {\n shouldTrack: boolean;\n reason?: string;\n } {\n // First check global tracking state\n if (!this.shouldTrack()) {\n return {\n shouldTrack: false,\n reason: this.lastFilterReason || 'global_policy',\n };\n }\n\n // Check if scroll is meaningful\n const scrollDistance = Math.abs(currentScrollY - previousScrollY);\n if (scrollDistance < 10) { // Minimum 10px to count as scroll\n return {\n shouldTrack: false,\n reason: 'scroll_too_small',\n };\n }\n\n return {\n shouldTrack: true,\n };\n }\n\n /**\n * Get all active policies as object (for monitoring/debugging)\n */\n getPolicies(): {\n maxSectionDuration: number;\n minScrollDistance: number;\n idleThreshold: number;\n } {\n return {\n maxSectionDuration: this.options.maxSectionDuration,\n minScrollDistance: this.options.minScrollDistance,\n idleThreshold: this.options.idleThreshold,\n };\n }\n\n /**\n * Get current tracking state (for monitoring/debugging)\n */\n getTrackingState(): {\n isPageVisible: boolean;\n isUserActive: boolean;\n timeSinceLastActivity: number;\n activeSections: number;\n } {\n return {\n isPageVisible: this.isPageVisible,\n isUserActive: this.activityDetector.isActive(this.options.idleThreshold),\n timeSinceLastActivity: this.activityDetector.getTimeSinceLastActivity(),\n activeSections: this.sectionStates.size,\n };\n }\n\n /**\n * Log debug messages\n */\n private log(...args: unknown[]): void {\n if (this.options.debug) {\n console.log('[AttentionQuality]', ...args);\n }\n }\n\n /**\n * Destroy and cleanup\n */\n destroy(): void {\n if (this.isDestroyed) return;\n\n this.isDestroyed = true;\n\n // Remove visibility change listener\n if (this.visibilityChangeHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.visibilityChangeHandler);\n this.visibilityChangeHandler = null;\n }\n\n // Clear section states\n this.sectionStates.clear();\n }\n}\n\n", "/**\n * Text utility functions for cleaning and processing text content\n */\n\n/**\n * Remove emojis and other Unicode symbols from text\n * This regex matches emoji ranges and other Unicode symbols\n */\nexport function removeEmojis(text: string | null | undefined): string | undefined {\n if (!text) return undefined;\n \n // Remove emojis and other Unicode symbols\n // This regex covers:\n // - Emoticons (\uD83D\uDE00-\uD83D\uDE4F)\n // - Miscellaneous Symbols and Pictographs (\uD83C\uDC00-\uD83F\uDFFF)\n // - Supplemental Symbols and Pictographs (\uD83C\uDE00-\uD83C\uDE3F)\n // - Transport and Map Symbols (\uD83D\uDE80-\uD83D\uDEFF)\n // - Enclosed characters (\u24C2-\u24FF)\n // - Regional indicator symbols (\uD83C\uDDE6-\uD83C\uDDFF)\n // - Other Unicode symbol ranges\n return text\n .replace(/[\\u{1F300}-\\u{1F9FF}]/gu, '') // Miscellaneous Symbols and Pictographs\n .replace(/[\\u{1F600}-\\u{1F64F}]/gu, '') // Emoticons\n .replace(/[\\u{1F680}-\\u{1F6FF}]/gu, '') // Transport and Map Symbols\n .replace(/[\\u{2600}-\\u{26FF}]/gu, '') // Miscellaneous Symbols\n .replace(/[\\u{2700}-\\u{27BF}]/gu, '') // Dingbats\n .replace(/[\\u{1F900}-\\u{1F9FF}]/gu, '') // Supplemental Symbols and Pictographs\n .replace(/[\\u{1F1E0}-\\u{1F1FF}]/gu, '') // Regional Indicator Symbols (flags)\n .replace(/[\\u{200D}]/gu, '') // Zero Width Joiner\n .replace(/[\\u{FE0F}]/gu, '') // Variation Selector-16\n .replace(/[\\u{20E3}]/gu, '') // Combining Enclosing Keycap\n .trim();\n}\n\n/**\n * Clean and truncate text content for event tracking\n * Removes emojis, trims whitespace, and limits length\n */\nexport function cleanElementText(text: string | null | undefined, maxLength: number = 100): string | undefined {\n if (!text) return undefined;\n \n const cleaned = removeEmojis(text);\n if (!cleaned) return undefined;\n \n return cleaned.substring(0, maxLength) || undefined;\n}\n", "/**\n * Heatmap Tracking Manager for Grain Analytics\n * Tracks click interactions and scroll depth across all pages\n */\n\nimport type {\n HeatmapClickData,\n HeatmapScrollData,\n HeatmapTrackingOptions,\n HeatmapScrollState,\n} from './types/heatmap-tracking';\nimport { AttentionQualityManager } from './attention-quality';\nimport type { ActivityDetector } from './activity';\nimport { cleanElementText } from './text-utils';\n\nexport interface SendEventOptions {\n flush?: boolean;\n}\n\nexport interface HeatmapTracker {\n trackSystemEvent(eventName: string, properties?: Record<string, unknown>, options?: SendEventOptions): void | Promise<void>;\n hasConsent(category: 'analytics' | 'marketing' | 'functional'): boolean;\n getActivityDetector(): ActivityDetector;\n log(...args: unknown[]): void;\n}\n\nconst DEFAULT_OPTIONS: HeatmapTrackingOptions = {\n scrollDebounceDelay: 100,\n batchDelay: 2000,\n maxBatchSize: 20,\n debug: false,\n};\n\nexport class HeatmapTrackingManager {\n private tracker: HeatmapTracker;\n private options: HeatmapTrackingOptions;\n private isDestroyed = false;\n\n // Tracking state\n private currentScrollState: HeatmapScrollState | null = null;\n private pendingClicks: HeatmapClickData[] = [];\n private pendingScrolls: HeatmapScrollData[] = [];\n\n // Timers\n private scrollDebounceTimer: number | null = null;\n private batchTimer: number | null = null;\n private scrollTrackingTimer: number | null = null;\n private periodicScrollTimer: number | null = null;\n\n // Scroll tracking\n private lastScrollPosition = 0;\n private lastScrollTime = Date.now();\n private readonly SPLIT_DURATION = 3000; // 3 seconds - same as section tracking\n\n // Attention quality management\n private attentionQuality: AttentionQualityManager;\n\n constructor(\n tracker: HeatmapTracker,\n options: Partial<HeatmapTrackingOptions> = {}\n ) {\n this.tracker = tracker;\n this.options = { ...DEFAULT_OPTIONS, ...options };\n\n // Initialize attention quality manager\n this.attentionQuality = new AttentionQualityManager(\n tracker.getActivityDetector(),\n {\n maxSectionDuration: 9000, // 9 seconds per viewport section\n minScrollDistance: 100, // 100 pixels\n idleThreshold: 30000, // 30 seconds\n debug: this.options.debug,\n }\n );\n\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Initialize after DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => this.initialize());\n } else {\n setTimeout(() => this.initialize(), 0);\n }\n }\n }\n\n /**\n * Initialize heatmap tracking\n */\n private initialize(): void {\n if (this.isDestroyed) return;\n\n this.log('Initializing heatmap tracking');\n\n // Setup click tracking\n this.setupClickTracking();\n\n // Setup scroll tracking\n this.setupScrollTracking();\n\n // Start periodic scroll state tracking\n this.startScrollTracking();\n\n // Setup page unload handler for beaconing\n this.setupUnloadHandler();\n }\n\n /**\n * Setup click event tracking\n */\n private setupClickTracking(): void {\n if (typeof document === 'undefined') return;\n\n const clickHandler = (event: MouseEvent) => {\n if (this.isDestroyed) return;\n if (!this.tracker.hasConsent('analytics')) return;\n\n this.handleClick(event);\n };\n\n document.addEventListener('click', clickHandler, { passive: true, capture: true });\n }\n\n /**\n * Setup scroll event tracking\n */\n private setupScrollTracking(): void {\n if (typeof window === 'undefined') return;\n\n const scrollHandler = () => {\n if (this.scrollDebounceTimer !== null) {\n clearTimeout(this.scrollDebounceTimer);\n }\n\n this.scrollDebounceTimer = window.setTimeout(() => {\n this.handleScroll();\n this.scrollDebounceTimer = null;\n }, this.options.scrollDebounceDelay);\n };\n\n window.addEventListener('scroll', scrollHandler, { passive: true });\n }\n\n /**\n * Start periodic scroll state tracking\n */\n private startScrollTracking(): void {\n if (typeof window === 'undefined') return;\n\n // Track initial scroll position\n this.updateScrollState();\n\n // Update scroll state every 500ms (for detecting section changes)\n this.scrollTrackingTimer = window.setInterval(() => {\n if (this.isDestroyed) return;\n this.updateScrollState();\n }, 500);\n\n // Start periodic 3-second scroll duration tracking\n this.startPeriodicScrollTracking();\n }\n\n /**\n * Start periodic scroll tracking (sends events every 3 seconds)\n */\n private startPeriodicScrollTracking(): void {\n if (typeof window === 'undefined') return;\n\n this.periodicScrollTimer = window.setInterval(() => {\n if (this.isDestroyed || !this.currentScrollState) return;\n if (!this.tracker.hasConsent('analytics')) return;\n\n // Check attention quality policies\n if (!this.attentionQuality.shouldTrack()) {\n this.log('Scroll tracking paused:', this.attentionQuality.getLastFilterReason());\n return;\n }\n\n const currentTime = Date.now();\n const duration = currentTime - this.currentScrollState.entryTime;\n\n // Only send if meaningful duration (> 1 second)\n if (duration > 1000) {\n const scrollY = window.scrollY || window.pageYOffset;\n const viewportHeight = window.innerHeight;\n const pageHeight = document.documentElement.scrollHeight;\n\n // Check section-specific attention quality\n const sectionKey = `viewport_section_${this.currentScrollState.viewportSection}`;\n const attentionCheck = this.attentionQuality.shouldTrackSection(sectionKey, scrollY);\n\n // If attention was reset due to scroll, reset our entry time\n if (attentionCheck.resetAttention) {\n this.log(`Viewport section ${this.currentScrollState.viewportSection}: Attention reset`);\n this.currentScrollState.entryTime = currentTime;\n return;\n }\n\n // If max duration reached for this viewport section\n if (!attentionCheck.shouldTrack) {\n this.log(`Viewport section ${this.currentScrollState.viewportSection}: ${attentionCheck.reason}`);\n return;\n }\n\n const scrollData: HeatmapScrollData = {\n pageUrl: window.location.href,\n viewportSection: this.currentScrollState.viewportSection,\n scrollDepthPx: scrollY,\n durationMs: duration,\n entryTimestamp: this.currentScrollState.entryTime,\n exitTimestamp: currentTime,\n pageHeight,\n viewportHeight,\n };\n\n // Send immediately using beacon to ensure delivery\n this.tracker.trackSystemEvent('_grain_heatmap_scroll', {\n page_url: scrollData.pageUrl,\n viewport_section: scrollData.viewportSection,\n scroll_depth_px: scrollData.scrollDepthPx,\n duration_ms: scrollData.durationMs,\n entry_timestamp: scrollData.entryTimestamp,\n exit_timestamp: scrollData.exitTimestamp,\n page_height: scrollData.pageHeight,\n viewport_height: scrollData.viewportHeight,\n is_split: true, // Flag to indicate periodic tracking, not final exit\n }, { flush: true });\n\n // Update attention quality duration tracker\n this.attentionQuality.updateSectionDuration(sectionKey, duration);\n\n // Reset entry time for next period\n this.currentScrollState.entryTime = currentTime;\n }\n }, this.SPLIT_DURATION);\n }\n\n /**\n * Setup page unload handler to beacon remaining data\n */\n private setupUnloadHandler(): void {\n if (typeof window === 'undefined') return;\n\n const unloadHandler = () => {\n // Finalize current scroll state\n if (this.currentScrollState) {\n const currentTime = Date.now();\n const duration = currentTime - this.currentScrollState.entryTime;\n\n if (duration > 100) {\n const scrollData: HeatmapScrollData = {\n pageUrl: window.location.href,\n viewportSection: this.currentScrollState.viewportSection,\n scrollDepthPx: this.currentScrollState.scrollDepthPx,\n durationMs: duration,\n entryTimestamp: this.currentScrollState.entryTime,\n exitTimestamp: currentTime,\n pageHeight: document.documentElement.scrollHeight,\n viewportHeight: window.innerHeight,\n };\n\n this.pendingScrolls.push(scrollData);\n }\n }\n\n // Flush all pending events with beacon\n this.flushPendingEventsWithBeacon();\n };\n\n // Use both events for better compatibility\n window.addEventListener('beforeunload', unloadHandler);\n window.addEventListener('pagehide', unloadHandler);\n }\n\n /**\n * Handle click event\n */\n private handleClick(event: MouseEvent): void {\n if (!this.tracker.hasConsent('analytics')) return;\n\n const element = event.target as HTMLElement;\n if (!element) return;\n\n const pageUrl = window.location.href;\n const xpath = this.generateXPath(element);\n \n // Get viewport coordinates\n const viewportX = Math.round(event.clientX);\n const viewportY = Math.round(event.clientY);\n \n // Get page coordinates (including scroll offset)\n const pageX = Math.round(event.pageX);\n const pageY = Math.round(event.pageY);\n \n const elementTag = element.tagName?.toLowerCase() || 'unknown';\n const elementText = cleanElementText(element.textContent);\n\n const clickData: HeatmapClickData = {\n pageUrl,\n xpath,\n viewportX,\n viewportY,\n pageX,\n pageY,\n elementTag,\n elementText: elementText || undefined,\n timestamp: Date.now(),\n };\n\n // Check if this is a navigation link\n const isNavigationLink = element instanceof HTMLAnchorElement && element.href;\n\n // Send immediately with beacon for navigation links to ensure delivery\n if (isNavigationLink) {\n this.tracker.trackSystemEvent('_grain_heatmap_click', {\n page_url: clickData.pageUrl,\n xpath: clickData.xpath,\n viewport_x: clickData.viewportX,\n viewport_y: clickData.viewportY,\n page_x: clickData.pageX,\n page_y: clickData.pageY,\n element_tag: clickData.elementTag,\n element_text: clickData.elementText,\n timestamp: clickData.timestamp,\n }, { flush: true });\n } else {\n this.pendingClicks.push(clickData);\n\n // Check if we should flush\n this.considerBatchFlush();\n }\n }\n\n /**\n * Handle scroll event\n */\n private handleScroll(): void {\n if (!this.tracker.hasConsent('analytics')) return;\n this.updateScrollState();\n }\n\n /**\n * Update current scroll state\n */\n private updateScrollState(): void {\n if (typeof window === 'undefined') return;\n if (!this.tracker.hasConsent('analytics')) return;\n\n const currentTime = Date.now();\n const scrollY = window.scrollY || window.pageYOffset;\n const viewportHeight = window.innerHeight;\n const pageHeight = document.documentElement.scrollHeight;\n \n // Calculate which viewport section we're in\n const viewportSection = Math.floor(scrollY / viewportHeight);\n\n // If we're in a new section, record the previous one\n if (this.currentScrollState && this.currentScrollState.viewportSection !== viewportSection) {\n const duration = currentTime - this.currentScrollState.entryTime;\n \n // Only record if duration is meaningful (> 100ms)\n if (duration > 100) {\n const scrollData: HeatmapScrollData = {\n pageUrl: window.location.href,\n viewportSection: this.currentScrollState.viewportSection,\n scrollDepthPx: this.currentScrollState.scrollDepthPx,\n durationMs: duration,\n entryTimestamp: this.currentScrollState.entryTime,\n exitTimestamp: currentTime,\n pageHeight,\n viewportHeight,\n };\n\n this.pendingScrolls.push(scrollData);\n }\n\n // Reset attention for previous viewport section\n const prevSectionKey = `viewport_section_${this.currentScrollState.viewportSection}`;\n this.attentionQuality.resetSection(prevSectionKey);\n }\n\n // Update current state\n if (!this.currentScrollState || this.currentScrollState.viewportSection !== viewportSection) {\n this.currentScrollState = {\n viewportSection,\n entryTime: currentTime,\n scrollDepthPx: scrollY,\n };\n }\n\n this.lastScrollPosition = scrollY;\n this.lastScrollTime = currentTime;\n\n // Check if we should flush\n this.considerBatchFlush();\n }\n\n /**\n * Generate XPath for an element\n */\n private generateXPath(element: HTMLElement): string {\n if (!element) return '';\n\n // If element has an ID, use that for simpler XPath\n if (element.id) {\n return `//*[@id=\"${element.id}\"]`;\n }\n\n const paths: string[] = [];\n let currentElement: HTMLElement | null = element;\n\n while (currentElement && currentElement.nodeType === Node.ELEMENT_NODE) {\n let index = 0;\n let sibling: Element | null = currentElement;\n\n // Count preceding siblings of the same tag\n while (sibling) {\n sibling = sibling.previousElementSibling;\n if (sibling && sibling.nodeName === currentElement.nodeName) {\n index++;\n }\n }\n\n const tagName = currentElement.nodeName.toLowerCase();\n const pathIndex = index > 0 ? `[${index + 1}]` : '';\n paths.unshift(`${tagName}${pathIndex}`);\n\n currentElement = currentElement.parentElement;\n }\n\n return paths.length ? `/${paths.join('/')}` : '';\n }\n\n /**\n * Consider flushing batched events\n */\n private considerBatchFlush(): void {\n const totalEvents = this.pendingClicks.length + this.pendingScrolls.length;\n\n // Flush if we've hit the batch size\n if (totalEvents >= this.options.maxBatchSize) {\n this.flushPendingEvents();\n return;\n }\n\n // Otherwise, schedule a batch flush\n if (this.batchTimer === null && totalEvents > 0) {\n this.batchTimer = window.setTimeout(() => {\n this.flushPendingEvents();\n this.batchTimer = null;\n }, this.options.batchDelay);\n }\n }\n\n /**\n * Flush pending events\n */\n private flushPendingEvents(): void {\n if (this.isDestroyed) return;\n if (!this.tracker.hasConsent('analytics')) {\n // Clear pending events if consent is revoked\n this.pendingClicks = [];\n this.pendingScrolls = [];\n return;\n }\n\n // Send click events\n if (this.pendingClicks.length > 0) {\n for (const clickData of this.pendingClicks) {\n this.tracker.trackSystemEvent('_grain_heatmap_click', {\n page_url: clickData.pageUrl,\n xpath: clickData.xpath,\n viewport_x: clickData.viewportX,\n viewport_y: clickData.viewportY,\n page_x: clickData.pageX,\n page_y: clickData.pageY,\n element_tag: clickData.elementTag,\n element_text: clickData.elementText,\n timestamp: clickData.timestamp,\n });\n }\n\n this.pendingClicks = [];\n }\n\n // Send scroll events\n if (this.pendingScrolls.length > 0) {\n for (const scrollData of this.pendingScrolls) {\n this.tracker.trackSystemEvent('_grain_heatmap_scroll', {\n page_url: scrollData.pageUrl,\n viewport_section: scrollData.viewportSection,\n scroll_depth_px: scrollData.scrollDepthPx,\n duration_ms: scrollData.durationMs,\n entry_timestamp: scrollData.entryTimestamp,\n exit_timestamp: scrollData.exitTimestamp,\n page_height: scrollData.pageHeight,\n viewport_height: scrollData.viewportHeight,\n });\n }\n\n this.pendingScrolls = [];\n }\n\n // Clear batch timer\n if (this.batchTimer !== null) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n }\n\n /**\n * Flush pending events with beacon (for page unload)\n */\n private flushPendingEventsWithBeacon(): void {\n if (!this.tracker.hasConsent('analytics')) {\n this.pendingClicks = [];\n this.pendingScrolls = [];\n return;\n }\n\n // Send click events with beacon\n if (this.pendingClicks.length > 0) {\n for (const clickData of this.pendingClicks) {\n this.tracker.trackSystemEvent('_grain_heatmap_click', {\n page_url: clickData.pageUrl,\n xpath: clickData.xpath,\n viewport_x: clickData.viewportX,\n viewport_y: clickData.viewportY,\n page_x: clickData.pageX,\n page_y: clickData.pageY,\n element_tag: clickData.elementTag,\n element_text: clickData.elementText,\n timestamp: clickData.timestamp,\n }, { flush: true });\n }\n\n this.pendingClicks = [];\n }\n\n // Send scroll events with beacon\n if (this.pendingScrolls.length > 0) {\n for (const scrollData of this.pendingScrolls) {\n this.tracker.trackSystemEvent('_grain_heatmap_scroll', {\n page_url: scrollData.pageUrl,\n viewport_section: scrollData.viewportSection,\n scroll_depth_px: scrollData.scrollDepthPx,\n duration_ms: scrollData.durationMs,\n entry_timestamp: scrollData.entryTimestamp,\n exit_timestamp: scrollData.exitTimestamp,\n page_height: scrollData.pageHeight,\n viewport_height: scrollData.viewportHeight,\n }, { flush: true });\n }\n\n this.pendingScrolls = [];\n }\n }\n\n /**\n * Log debug message\n */\n private log(...args: unknown[]): void {\n if (this.options.debug) {\n this.tracker.log('[Heatmap Tracking]', ...args);\n }\n }\n\n /**\n * Destroy the tracking manager\n */\n destroy(): void {\n this.isDestroyed = true;\n\n // Clear timers\n if (this.scrollDebounceTimer !== null) {\n clearTimeout(this.scrollDebounceTimer);\n this.scrollDebounceTimer = null;\n }\n\n if (this.batchTimer !== null) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n\n if (this.scrollTrackingTimer !== null) {\n clearInterval(this.scrollTrackingTimer);\n this.scrollTrackingTimer = null;\n }\n\n if (this.periodicScrollTimer !== null) {\n clearInterval(this.periodicScrollTimer);\n this.periodicScrollTimer = null;\n }\n\n // Destroy attention quality manager\n this.attentionQuality.destroy();\n\n // Flush any remaining events\n this.flushPendingEvents();\n }\n}\n\n", "/**\n * Interaction Tracking Manager for Grain Analytics\n * Automatically attaches click and focus listeners to detected interactive elements\n */\n\nimport type { InteractionConfig } from './types/auto-tracking';\nimport { cleanElementText } from './text-utils';\n\nexport interface SendEventOptions {\n flush?: boolean;\n}\n\nexport interface InteractionTracker {\n track(eventName: string, properties?: Record<string, unknown>, options?: SendEventOptions): void | Promise<void>;\n hasConsent(category: 'analytics' | 'marketing' | 'functional'): boolean;\n log(...args: unknown[]): void;\n}\n\nexport interface InteractionTrackingConfig {\n debug?: boolean;\n enableMutationObserver?: boolean;\n mutationDebounceDelay?: number;\n tenantId?: string;\n apiUrl?: string;\n}\n\nexport class InteractionTrackingManager {\n private tracker: InteractionTracker;\n private interactions: InteractionConfig[];\n private config: InteractionTrackingConfig;\n private isDestroyed = false;\n private attachedListeners: Map<Element, Array<{ event: string; handler: EventListener }>> = new Map();\n private xpathCache: Map<string, Element | null> = new Map();\n private mutationObserver: MutationObserver | null = null;\n private mutationDebounceTimer: number | null = null;\n\n constructor(\n tracker: InteractionTracker,\n interactions: InteractionConfig[],\n config: InteractionTrackingConfig = {}\n ) {\n this.tracker = tracker;\n this.interactions = interactions;\n this.config = {\n debug: config.debug ?? false,\n enableMutationObserver: config.enableMutationObserver ?? true,\n mutationDebounceDelay: config.mutationDebounceDelay ?? 500,\n tenantId: config.tenantId,\n apiUrl: config.apiUrl,\n };\n\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Fetch and merge trackers if configured\n if (this.config.tenantId && this.config.apiUrl) {\n this.fetchAndMergeTrackers().then(() => {\n this.attachAllListeners();\n });\n } else {\n // Attach listeners after DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => this.attachAllListeners());\n } else {\n // DOM already loaded\n setTimeout(() => this.attachAllListeners(), 0);\n }\n }\n\n // Setup mutation observer for dynamic content\n if (this.config.enableMutationObserver) {\n this.setupMutationObserver();\n }\n }\n }\n \n /**\n * Fetch trackers from API and merge with existing interactions\n */\n private async fetchAndMergeTrackers(): Promise<void> {\n if (!this.config.tenantId || !this.config.apiUrl) return;\n \n try {\n const currentUrl = typeof window !== 'undefined' ? window.location.href : '';\n const url = `${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/trackers?url=${encodeURIComponent(currentUrl)}`;\n \n this.log('Fetching trackers from:', url);\n \n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n \n if (!response.ok) {\n this.log('Failed to fetch trackers:', response.status);\n return;\n }\n \n const result = await response.json();\n \n if (result.trackers && Array.isArray(result.trackers)) {\n this.log('Fetched', result.trackers.length, 'trackers');\n \n // Convert trackers to InteractionConfig format\n const trackerInteractions: InteractionConfig[] = result.trackers.map((tracker: any) => ({\n eventName: tracker.eventName,\n selector: tracker.selector,\n priority: 5, // High priority for manually created trackers\n label: tracker.eventName,\n description: `Tracker: ${tracker.eventName}`,\n }));\n \n // Merge with existing interactions (trackers take precedence)\n this.interactions = [...trackerInteractions, ...this.interactions];\n \n this.log('Merged trackers, total interactions:', this.interactions.length);\n }\n } catch (error) {\n this.log('Error fetching trackers:', error);\n }\n }\n\n /**\n * Attach listeners to all configured interactions\n */\n private attachAllListeners(): void {\n if (this.isDestroyed) return;\n\n this.log('Attaching interaction listeners');\n\n for (const interaction of this.interactions) {\n this.attachInteractionListener(interaction);\n }\n }\n\n /**\n * Attach listener to a specific interaction\n */\n private attachInteractionListener(interaction: InteractionConfig): void {\n if (this.isDestroyed) return;\n\n const element = this.findElementByXPath(interaction.selector);\n \n if (!element) {\n this.log('Element not found for interaction:', interaction.eventName, 'selector:', interaction.selector);\n return;\n }\n\n // Check if we already attached listeners to this element for this interaction\n if (this.attachedListeners.has(element)) {\n this.log('Listeners already attached for element:', element);\n return;\n }\n\n const handlers: Array<{ event: string; handler: EventListener }> = [];\n\n // Click handler\n const clickHandler = (event: Event) => this.handleInteractionClick(interaction, event);\n element.addEventListener('click', clickHandler, { passive: true });\n handlers.push({ event: 'click', handler: clickHandler });\n\n // Focus handler (for form inputs)\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) {\n const focusHandler = (event: Event) => this.handleInteractionFocus(interaction, event);\n element.addEventListener('focus', focusHandler, { passive: true });\n handlers.push({ event: 'focus', handler: focusHandler });\n }\n\n this.attachedListeners.set(element, handlers);\n }\n\n /**\n * Handle click event on interaction\n */\n private handleInteractionClick(interaction: InteractionConfig, event: Event): void {\n if (this.isDestroyed) return;\n if (!this.tracker.hasConsent('analytics')) return;\n\n const element = event.target as HTMLElement;\n \n // Check if this is a navigation link (has href attribute)\n const isNavigationLink = element instanceof HTMLAnchorElement && element.href;\n \n const eventProperties = {\n interaction_type: 'click',\n interaction_label: interaction.label,\n interaction_description: interaction.description,\n interaction_priority: interaction.priority,\n element_tag: element.tagName?.toLowerCase(),\n element_text: cleanElementText(element.textContent),\n element_id: element.id || undefined,\n element_class: element.className || undefined,\n ...(isNavigationLink && { href: element.href }),\n timestamp: Date.now(),\n };\n \n // Always use flush for auto-tracked clicks to ensure delivery\n // This is especially important for navigation links and quick interactions\n const result = this.tracker.track(interaction.eventName, eventProperties, { flush: true });\n if (result instanceof Promise) {\n result.catch((error: unknown) => {\n // Log error but don't block interaction\n this.log('Failed to track click:', error);\n });\n }\n }\n\n /**\n * Handle focus event on interaction (for form fields)\n */\n private handleInteractionFocus(interaction: InteractionConfig, event: Event): void {\n if (this.isDestroyed) return;\n if (!this.tracker.hasConsent('analytics')) return;\n\n const element = event.target as HTMLElement;\n \n this.tracker.track(interaction.eventName, {\n interaction_type: 'focus',\n interaction_label: interaction.label,\n interaction_description: interaction.description,\n interaction_priority: interaction.priority,\n element_tag: element.tagName?.toLowerCase(),\n element_id: element.id || undefined,\n element_class: element.className || undefined,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Find element by XPath selector\n */\n private findElementByXPath(xpath: string): Element | null {\n // Check cache first\n if (this.xpathCache.has(xpath)) {\n const cached = this.xpathCache.get(xpath);\n // Verify element is still in DOM\n if (cached && document.contains(cached)) {\n return cached;\n }\n // Clear invalid cache entry\n this.xpathCache.delete(xpath);\n }\n\n try {\n // Strip the xpath= prefix if present (from Stagehand selectors)\n let cleanXpath = xpath;\n if (xpath.startsWith('xpath=')) {\n cleanXpath = xpath.substring(6); // Remove 'xpath=' prefix\n }\n\n const result = document.evaluate(\n cleanXpath,\n document,\n null,\n XPathResult.FIRST_ORDERED_NODE_TYPE,\n null\n );\n \n const element = result.singleNodeValue as Element | null;\n \n // Cache the result (use original xpath as key)\n if (element) {\n this.xpathCache.set(xpath, element);\n }\n \n return element;\n } catch (error) {\n this.log('Error evaluating XPath:', xpath, error);\n return null;\n }\n }\n\n /**\n * Setup mutation observer to handle dynamic content\n */\n private setupMutationObserver(): void {\n if (typeof MutationObserver === 'undefined') {\n this.log('MutationObserver not supported');\n return;\n }\n\n this.mutationObserver = new MutationObserver((mutations) => {\n // Debounce the re-attachment\n if (this.mutationDebounceTimer !== null) {\n clearTimeout(this.mutationDebounceTimer);\n }\n\n this.mutationDebounceTimer = window.setTimeout(() => {\n this.handleMutations(mutations);\n this.mutationDebounceTimer = null;\n }, this.config.mutationDebounceDelay);\n });\n\n this.mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n });\n\n this.log('Mutation observer setup');\n }\n\n /**\n * Handle DOM mutations\n */\n private handleMutations(mutations: MutationRecord[]): void {\n if (this.isDestroyed) return;\n\n // Clear XPath cache on mutations\n this.xpathCache.clear();\n\n // Check if any of our tracked elements were removed\n const removedElements = new Set<Element>();\n for (const mutation of mutations) {\n mutation.removedNodes.forEach((node) => {\n if (node instanceof Element) {\n removedElements.add(node);\n // Also check for child elements we were tracking\n this.attachedListeners.forEach((handlers, element) => {\n if (node.contains(element)) {\n removedElements.add(element);\n }\n });\n }\n });\n }\n\n // Clean up removed elements\n removedElements.forEach((element) => {\n this.detachListeners(element);\n });\n\n // Try to re-attach listeners for any interactions that might now be available\n this.attachAllListeners();\n }\n\n /**\n * Detach listeners from an element\n */\n private detachListeners(element: Element): void {\n const handlers = this.attachedListeners.get(element);\n if (!handlers) return;\n\n handlers.forEach(({ event, handler }) => {\n element.removeEventListener(event, handler);\n });\n\n this.attachedListeners.delete(element);\n }\n\n /**\n * Log debug messages\n */\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[InteractionTracking]', ...args);\n }\n }\n\n /**\n * Update interactions configuration\n */\n updateInteractions(interactions: InteractionConfig[]): void {\n if (this.isDestroyed) return;\n\n this.log('Updating interactions configuration');\n \n // Detach all existing listeners\n this.attachedListeners.forEach((handlers, element) => {\n this.detachListeners(element);\n });\n\n // Clear cache\n this.xpathCache.clear();\n\n // Update configuration\n this.interactions = interactions;\n\n // Reattach listeners\n this.attachAllListeners();\n }\n\n /**\n * Cleanup and destroy\n */\n destroy(): void {\n if (this.isDestroyed) return;\n\n this.log('Destroying interaction tracking manager');\n \n this.isDestroyed = true;\n\n // Clear debounce timer\n if (this.mutationDebounceTimer !== null) {\n clearTimeout(this.mutationDebounceTimer);\n this.mutationDebounceTimer = null;\n }\n\n // Disconnect mutation observer\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n\n // Detach all listeners\n this.attachedListeners.forEach((handlers, element) => {\n this.detachListeners(element);\n });\n\n // Clear caches\n this.attachedListeners.clear();\n this.xpathCache.clear();\n }\n}\n\n", "/**\n * Section Tracking Manager for Grain Analytics\n * Intelligent scroll tracking with viewport metrics, visible sections, and engagement analysis\n */\n\nimport type { SectionConfig, SectionViewData, SectionTrackingOptions, SectionTrackingState } from './types/auto-tracking';\nimport { AttentionQualityManager } from './attention-quality';\nimport type { ActivityDetector } from './activity';\n\nexport interface SectionTracker {\n trackSystemEvent(eventName: string, properties: Record<string, unknown>): void;\n hasConsent(category: 'analytics' | 'marketing' | 'functional'): boolean;\n getActivityDetector(): ActivityDetector;\n log(...args: unknown[]): void;\n}\n\nconst DEFAULT_OPTIONS: SectionTrackingOptions = {\n minDwellTime: 1000, // 1 second minimum\n scrollVelocityThreshold: 500, // 500px/s\n intersectionThreshold: 0.1, // 10% visible\n debounceDelay: 100,\n batchDelay: 2000, // 2 seconds\n debug: false,\n};\n\nexport class SectionTrackingManager {\n private tracker: SectionTracker;\n private sections: SectionConfig[];\n private options: SectionTrackingOptions;\n private isDestroyed = false;\n \n // Tracking state\n private sectionStates: Map<string, SectionTrackingState> = new Map();\n private intersectionObserver: IntersectionObserver | null = null;\n private xpathCache: Map<string, Element | null> = new Map();\n \n // Scroll tracking\n private lastScrollPosition = 0;\n private lastScrollTime = Date.now();\n private scrollVelocity = 0;\n private scrollDebounceTimer: number | null = null;\n \n // Event batching\n private pendingEvents: SectionViewData[] = [];\n private batchTimer: number | null = null;\n\n // Periodic tracking for long-duration views\n private sectionTimers: Map<string, number> = new Map(); // sectionName -> timer ID\n private readonly SPLIT_DURATION = 3000; // 3 seconds\n\n // Attention quality management\n private attentionQuality: AttentionQualityManager;\n\n constructor(\n tracker: SectionTracker,\n sections: SectionConfig[],\n options: Partial<SectionTrackingOptions> = {}\n ) {\n this.tracker = tracker;\n this.sections = sections;\n this.options = { ...DEFAULT_OPTIONS, ...options };\n\n // Initialize attention quality manager\n this.attentionQuality = new AttentionQualityManager(\n tracker.getActivityDetector(),\n {\n maxSectionDuration: 9000, // 9 seconds\n minScrollDistance: 100, // 100 pixels\n idleThreshold: 30000, // 30 seconds\n debug: this.options.debug,\n }\n );\n\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Initialize after DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => this.initialize());\n } else {\n setTimeout(() => this.initialize(), 0);\n }\n }\n }\n\n /**\n * Initialize section tracking\n */\n private initialize(): void {\n if (this.isDestroyed) return;\n\n this.log('Initializing section tracking');\n\n // Setup intersection observer\n this.setupIntersectionObserver();\n\n // Setup scroll listener for velocity tracking\n this.setupScrollListener();\n\n // Initialize sections\n this.initializeSections();\n }\n\n /**\n * Setup IntersectionObserver for section visibility\n */\n private setupIntersectionObserver(): void {\n if (typeof IntersectionObserver === 'undefined') {\n this.log('IntersectionObserver not supported');\n return;\n }\n\n this.intersectionObserver = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n this.handleIntersection(entry);\n });\n },\n {\n threshold: [0, 0.1, 0.25, 0.5, 0.75, 1.0],\n rootMargin: '0px',\n }\n );\n\n this.log('IntersectionObserver created');\n }\n\n /**\n * Setup scroll listener for velocity calculation\n */\n private setupScrollListener(): void {\n if (typeof window === 'undefined') return;\n\n const scrollHandler = () => {\n if (this.scrollDebounceTimer !== null) {\n clearTimeout(this.scrollDebounceTimer);\n }\n\n this.scrollDebounceTimer = window.setTimeout(() => {\n this.updateScrollVelocity();\n this.scrollDebounceTimer = null;\n }, this.options.debounceDelay);\n };\n\n window.addEventListener('scroll', scrollHandler, { passive: true });\n this.log('Scroll listener attached');\n }\n\n /**\n * Initialize sections and start observing\n */\n private initializeSections(): void {\n for (const section of this.sections) {\n const element = this.findElementByXPath(section.selector);\n \n if (!element) {\n this.log('Section element not found:', section.sectionName, 'selector:', section.selector);\n continue;\n }\n\n // Initialize state\n const state: SectionTrackingState = {\n element,\n config: section,\n entryTime: null,\n exitTime: null,\n isVisible: false,\n lastScrollPosition: window.scrollY,\n lastScrollTime: Date.now(),\n entryScrollSpeed: 0,\n exitScrollSpeed: 0,\n maxVisibleArea: 0,\n };\n\n this.sectionStates.set(section.sectionName, state);\n\n // Start observing\n if (this.intersectionObserver) {\n this.intersectionObserver.observe(element);\n }\n }\n }\n\n /**\n * Handle intersection observer entry\n */\n private handleIntersection(entry: IntersectionObserverEntry): void {\n if (this.isDestroyed) return;\n\n // Find which section this element belongs to\n const state = Array.from(this.sectionStates.values()).find(\n (s) => s.element === entry.target\n );\n\n if (!state) return;\n\n const isVisible = entry.isIntersecting && entry.intersectionRatio >= this.options.intersectionThreshold;\n const visibleArea = entry.intersectionRatio;\n\n // Update max visible area\n if (visibleArea > state.maxVisibleArea) {\n state.maxVisibleArea = visibleArea;\n }\n\n // Handle visibility change\n if (isVisible && !state.isVisible) {\n // Section became visible\n this.handleSectionEntry(state);\n } else if (!isVisible && state.isVisible) {\n // Section became invisible\n this.handleSectionExit(state);\n }\n\n state.isVisible = isVisible;\n }\n\n /**\n * Handle section entry (became visible)\n */\n private handleSectionEntry(state: SectionTrackingState): void {\n state.entryTime = Date.now();\n state.entryScrollSpeed = this.scrollVelocity;\n state.lastScrollPosition = window.scrollY;\n state.lastScrollTime = Date.now();\n state.maxVisibleArea = 0;\n \n // Start periodic tracking timer (3 second intervals)\n this.startPeriodicTracking(state);\n }\n \n /**\n * Start periodic tracking for a section (sends events every 3 seconds)\n */\n private startPeriodicTracking(state: SectionTrackingState): void {\n // Clear any existing timer for this section\n this.stopPeriodicTracking(state.config.sectionName);\n \n const timerId = window.setInterval(() => {\n if (this.isDestroyed || !state.isVisible || state.entryTime === null) {\n this.stopPeriodicTracking(state.config.sectionName);\n return;\n }\n \n const now = Date.now();\n const duration = now - state.entryTime;\n \n // Only track if minimum dwell time has passed\n if (duration >= this.options.minDwellTime) {\n // Check attention quality policies\n const currentScrollY = window.scrollY;\n const attentionCheck = this.attentionQuality.shouldTrackSection(\n state.config.sectionName,\n currentScrollY\n );\n\n // If attention was reset due to scroll, reset our entry time\n if (attentionCheck.resetAttention) {\n this.log(`Section \"${state.config.sectionName}\": Attention reset, restarting timer`);\n state.entryTime = now;\n state.entryScrollSpeed = this.scrollVelocity;\n return;\n }\n\n // If tracking is not allowed (page hidden, idle, or max duration reached)\n if (!attentionCheck.shouldTrack) {\n this.log(`Section \"${state.config.sectionName}\": Tracking paused - ${attentionCheck.reason}`);\n return;\n }\n\n // Create partial section view data\n const viewData: SectionViewData = {\n sectionName: state.config.sectionName,\n sectionType: state.config.sectionType,\n entryTime: state.entryTime,\n exitTime: now, // Current time as \"exit\" for this split\n duration,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n scrollDepth: this.calculateScrollDepth(),\n visibleAreaPercentage: Math.round(state.maxVisibleArea * 100),\n scrollSpeedAtEntry: state.entryScrollSpeed,\n scrollSpeedAtExit: this.scrollVelocity,\n };\n \n // Track this split immediately (don't queue for batching)\n if (this.shouldTrackSection(viewData)) {\n this.tracker.trackSystemEvent('_grain_section_view', {\n section_name: viewData.sectionName,\n section_type: viewData.sectionType,\n duration_ms: viewData.duration,\n viewport_width: viewData.viewportWidth,\n viewport_height: viewData.viewportHeight,\n scroll_depth_percent: viewData.scrollDepth,\n visible_area_percent: viewData.visibleAreaPercentage,\n scroll_speed_entry: Math.round(viewData.scrollSpeedAtEntry || 0),\n scroll_speed_exit: Math.round(viewData.scrollSpeedAtExit || 0),\n entry_timestamp: viewData.entryTime,\n exit_timestamp: viewData.exitTime,\n is_split: true, // Flag to indicate this is a periodic split, not final exit\n });\n \n // Update attention quality duration tracker\n this.attentionQuality.updateSectionDuration(state.config.sectionName, duration);\n \n // Reset entry time for next split (but keep tracking)\n state.entryTime = now;\n state.entryScrollSpeed = this.scrollVelocity;\n }\n }\n }, this.SPLIT_DURATION);\n \n this.sectionTimers.set(state.config.sectionName, timerId);\n }\n \n /**\n * Stop periodic tracking for a section\n */\n private stopPeriodicTracking(sectionName: string): void {\n const timerId = this.sectionTimers.get(sectionName);\n if (timerId !== undefined) {\n clearInterval(timerId);\n this.sectionTimers.delete(sectionName);\n }\n }\n\n /**\n * Handle section exit (became invisible)\n */\n private handleSectionExit(state: SectionTrackingState): void {\n // Stop periodic tracking\n this.stopPeriodicTracking(state.config.sectionName);\n \n // Reset attention for this section\n this.attentionQuality.resetSection(state.config.sectionName);\n \n if (state.entryTime === null) return;\n\n state.exitTime = Date.now();\n state.exitScrollSpeed = this.scrollVelocity;\n\n const duration = state.exitTime - state.entryTime;\n\n // Create section view data\n const viewData: SectionViewData = {\n sectionName: state.config.sectionName,\n sectionType: state.config.sectionType,\n entryTime: state.entryTime,\n exitTime: state.exitTime,\n duration,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n scrollDepth: this.calculateScrollDepth(),\n visibleAreaPercentage: Math.round(state.maxVisibleArea * 100),\n scrollSpeedAtEntry: state.entryScrollSpeed,\n scrollSpeedAtExit: state.exitScrollSpeed,\n };\n\n // Apply sanitization and track if valid\n if (this.shouldTrackSection(viewData)) {\n this.queueSectionView(viewData);\n } else {\n this.log('Section view filtered out:', state.config.sectionName, 'duration:', duration);\n }\n\n // Reset entry time\n state.entryTime = null;\n }\n\n /**\n * Update scroll velocity\n */\n private updateScrollVelocity(): void {\n const now = Date.now();\n const currentPosition = window.scrollY;\n \n const timeDelta = now - this.lastScrollTime;\n const positionDelta = Math.abs(currentPosition - this.lastScrollPosition);\n \n if (timeDelta > 0) {\n this.scrollVelocity = (positionDelta / timeDelta) * 1000; // pixels per second\n }\n \n this.lastScrollPosition = currentPosition;\n this.lastScrollTime = now;\n }\n\n /**\n * Calculate current scroll depth as percentage\n */\n private calculateScrollDepth(): number {\n if (typeof window === 'undefined' || typeof document === 'undefined') return 0;\n\n const windowHeight = window.innerHeight;\n const documentHeight = Math.max(\n document.body.scrollHeight,\n document.body.offsetHeight,\n document.documentElement.clientHeight,\n document.documentElement.scrollHeight,\n document.documentElement.offsetHeight\n );\n \n const scrollTop = window.scrollY;\n const scrollableHeight = documentHeight - windowHeight;\n \n if (scrollableHeight <= 0) return 100;\n \n return Math.round((scrollTop / scrollableHeight) * 100);\n }\n\n /**\n * Determine if section view should be tracked (sanitization)\n */\n private shouldTrackSection(viewData: SectionViewData): boolean {\n // Minimum dwell time check\n if (viewData.duration < this.options.minDwellTime) {\n return false;\n }\n\n // Check if user was rapidly scrolling through\n const avgScrollSpeed = (viewData.scrollSpeedAtEntry! + viewData.scrollSpeedAtExit!) / 2;\n if (avgScrollSpeed > this.options.scrollVelocityThreshold * 2) {\n // Very fast scroll - likely not engaged\n return false;\n }\n\n // Must have had some meaningful visible area\n if (viewData.visibleAreaPercentage < 10) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Queue section view for batching\n */\n private queueSectionView(viewData: SectionViewData): void {\n this.pendingEvents.push(viewData);\n\n // Setup batch timer if not already set\n if (this.batchTimer === null) {\n this.batchTimer = window.setTimeout(() => {\n this.flushPendingEvents();\n }, this.options.batchDelay);\n }\n }\n\n /**\n * Flush pending section view events\n */\n private flushPendingEvents(): void {\n if (this.isDestroyed || this.pendingEvents.length === 0) return;\n if (!this.tracker.hasConsent('analytics')) {\n this.pendingEvents = [];\n return;\n }\n\n // Track each section view\n for (const viewData of this.pendingEvents) {\n this.tracker.trackSystemEvent('_grain_section_view', {\n section_name: viewData.sectionName,\n section_type: viewData.sectionType,\n duration_ms: viewData.duration,\n viewport_width: viewData.viewportWidth,\n viewport_height: viewData.viewportHeight,\n scroll_depth_percent: viewData.scrollDepth,\n visible_area_percent: viewData.visibleAreaPercentage,\n scroll_speed_entry: Math.round(viewData.scrollSpeedAtEntry || 0),\n scroll_speed_exit: Math.round(viewData.scrollSpeedAtExit || 0),\n entry_timestamp: viewData.entryTime,\n exit_timestamp: viewData.exitTime,\n });\n }\n\n // Clear pending events\n this.pendingEvents = [];\n this.batchTimer = null;\n }\n\n /**\n * Find element by XPath selector\n */\n private findElementByXPath(xpath: string): Element | null {\n // Check cache first\n if (this.xpathCache.has(xpath)) {\n const cached = this.xpathCache.get(xpath);\n if (cached && document.contains(cached)) {\n return cached;\n }\n this.xpathCache.delete(xpath);\n }\n\n try {\n // Strip the xpath= prefix if present (from Stagehand selectors)\n let cleanXpath = xpath;\n if (xpath.startsWith('xpath=')) {\n cleanXpath = xpath.substring(6); // Remove 'xpath=' prefix\n }\n\n const result = document.evaluate(\n cleanXpath,\n document,\n null,\n XPathResult.FIRST_ORDERED_NODE_TYPE,\n null\n );\n \n const element = result.singleNodeValue as Element | null;\n \n // Cache the result (use original xpath as key)\n if (element) {\n this.xpathCache.set(xpath, element);\n }\n \n return element;\n } catch (error) {\n this.log('Error evaluating XPath:', xpath, error);\n return null;\n }\n }\n\n /**\n * Log debug messages\n */\n private log(...args: unknown[]): void {\n if (this.options.debug) {\n console.log('[SectionTracking]', ...args);\n }\n }\n\n /**\n * Update sections configuration\n */\n updateSections(sections: SectionConfig[]): void {\n if (this.isDestroyed) return;\n\n this.log('Updating sections configuration');\n \n // Disconnect observer\n if (this.intersectionObserver) {\n this.intersectionObserver.disconnect();\n }\n\n // Clear state\n this.sectionStates.clear();\n this.xpathCache.clear();\n\n // Update configuration\n this.sections = sections;\n\n // Reinitialize\n this.setupIntersectionObserver();\n this.initializeSections();\n }\n\n /**\n * Cleanup and destroy\n */\n destroy(): void {\n if (this.isDestroyed) return;\n\n this.log('Destroying section tracking manager');\n \n this.isDestroyed = true;\n\n // Stop all periodic tracking timers\n this.sectionTimers.forEach((timerId) => {\n clearInterval(timerId);\n });\n this.sectionTimers.clear();\n\n // Flush any pending events\n this.flushPendingEvents();\n\n // Clear timers\n if (this.scrollDebounceTimer !== null) {\n clearTimeout(this.scrollDebounceTimer);\n this.scrollDebounceTimer = null;\n }\n\n if (this.batchTimer !== null) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n\n // Disconnect intersection observer\n if (this.intersectionObserver) {\n this.intersectionObserver.disconnect();\n this.intersectionObserver = null;\n }\n\n // Destroy attention quality manager\n this.attentionQuality.destroy();\n\n // Clear state\n this.sectionStates.clear();\n this.xpathCache.clear();\n this.pendingEvents = [];\n }\n}\n\n", "/**\n * Debug Agent for Visual Event Tracking\n * Provides a toolbar and element inspection mode for creating event trackers\n */\n\nexport interface DebugAgentConfig {\n debug?: boolean;\n}\n\nexport interface Tracker {\n track(eventName: string, properties?: Record<string, unknown>): void | Promise<void>;\n log(...args: unknown[]): void;\n}\n\nexport interface ExistingTracker {\n trackerId: string;\n name: string;\n type: string;\n selector: string;\n urlScope: string;\n urlPattern?: string;\n isEnabled: boolean;\n}\n\nexport class DebugAgent {\n private tracker: Tracker;\n private sessionId: string;\n private tenantId: string;\n private apiUrl: string;\n private config: DebugAgentConfig;\n private isDestroyed = false;\n \n // UI state\n private isInspectMode = false;\n private showTrackers = false;\n private selectedElement: Element | null = null;\n private toolbarElement: HTMLElement | null = null;\n private panelElement: HTMLElement | null = null;\n private highlightElement: HTMLElement | null = null;\n private existingTrackers: ExistingTracker[] = [];\n private trackerHighlights: HTMLElement[] = [];\n \n // Dragging state\n private isDragging = false;\n private dragStartX = 0;\n private dragStartY = 0;\n private toolbarStartX = 0;\n private toolbarStartY = 0;\n \n // Event listeners\n private mouseMoveListener: ((e: MouseEvent) => void) | null = null;\n private clickListener: ((e: MouseEvent) => void) | null = null;\n private dragMoveListener: ((e: MouseEvent) => void) | null = null;\n private dragEndListener: ((e: MouseEvent) => void) | null = null;\n\n constructor(\n tracker: Tracker,\n sessionId: string,\n tenantId: string,\n apiUrl: string,\n config: DebugAgentConfig = {}\n ) {\n this.tracker = tracker;\n this.sessionId = sessionId;\n this.tenantId = tenantId;\n this.apiUrl = apiUrl;\n this.config = {\n debug: config.debug ?? false,\n };\n\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n this.initialize();\n }\n }\n\n /**\n * Initialize the debug agent\n */\n private async initialize(): Promise<void> {\n this.log('Initializing debug agent');\n await this.loadExistingTrackers();\n this.showToolbar();\n this.createHighlightElement();\n \n // Show trackers by default\n this.showTrackers = true;\n this.showTrackerHighlights();\n this.showTrackersList();\n }\n\n /**\n * Load existing trackers from API\n */\n private async loadExistingTrackers(): Promise<void> {\n try {\n const url = `${this.apiUrl}/v1/tenant/${encodeURIComponent(this.tenantId)}/trackers`;\n const response = await fetch(url);\n\n if (response.ok) {\n this.existingTrackers = await response.json();\n this.log('Loaded trackers:', this.existingTrackers);\n }\n } catch (error) {\n this.log('Failed to load trackers:', error);\n this.existingTrackers = [];\n }\n }\n\n /**\n * Show the debug toolbar\n */\n private showToolbar(): void {\n if (this.toolbarElement) return;\n\n const toolbar = document.createElement('div');\n toolbar.id = 'grain-debug-toolbar';\n toolbar.innerHTML = `\n <style>\n #grain-debug-toolbar {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: repeating-linear-gradient(\n 45deg,\n #fbbf24,\n #fbbf24 10px,\n #1e293b 10px,\n #1e293b 20px\n );\n border: 2px solid #1e293b;\n border-radius: 12px;\n padding: 6px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2), 0 2px 8px rgba(0, 0, 0, 0.1);\n z-index: 999999;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n }\n \n .grain-toolbar-inner {\n display: flex;\n align-items: center;\n gap: 12px;\n background: white;\n border-radius: 6px;\n padding: 8px 12px;\n }\n \n #grain-debug-toolbar.dragging {\n cursor: move;\n user-select: none;\n }\n \n .grain-toolbar-header {\n display: flex;\n align-items: center;\n cursor: move;\n user-select: none;\n padding: 6px 10px;\n background: #1e293b;\n border-radius: 4px;\n margin-right: 4px;\n }\n \n .grain-toolbar-title {\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 1.2px;\n text-transform: uppercase;\n color: #fbbf24;\n }\n \n .grain-toolbar-body {\n display: flex;\n align-items: center;\n gap: 10px;\n flex: 1;\n }\n \n .grain-toolbar-stats {\n display: flex;\n gap: 12px;\n padding: 6px 10px;\n background: #f8fafc;\n border-radius: 4px;\n margin-right: 4px;\n }\n \n .grain-stat {\n display: flex;\n align-items: baseline;\n gap: 6px;\n }\n \n .grain-stat-value {\n font-size: 18px;\n font-weight: 700;\n color: #1e293b;\n }\n \n .grain-stat-label {\n font-size: 11px;\n color: #64748b;\n font-weight: 500;\n }\n \n .grain-toolbar-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n }\n \n #grain-debug-toolbar button {\n background: white;\n border: 1.5px solid #e2e8f0;\n color: #475569;\n padding: 8px 14px;\n border-radius: 8px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n white-space: nowrap;\n }\n \n #grain-debug-toolbar button:hover {\n background: #f8fafc;\n border-color: #cbd5e1;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n }\n \n #grain-debug-toolbar button.active {\n background: #fbbf24;\n color: #1e293b;\n border-color: #fbbf24;\n box-shadow: 0 2px 8px rgba(251, 191, 36, 0.3);\n }\n \n #grain-debug-toolbar button.danger {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n border-color: #ef4444;\n color: white;\n }\n \n #grain-debug-toolbar button.danger:hover {\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(239, 68, 68, 0.25);\n }\n \n .grain-debug-highlight {\n position: absolute;\n pointer-events: none;\n border: 2px solid #10b981;\n background: rgba(16, 185, 129, 0.1);\n z-index: 999998;\n transition: all 0.1s;\n }\n \n .grain-tracker-highlight {\n position: absolute;\n pointer-events: none;\n border: 2px solid #6366f1;\n background: rgba(99, 102, 241, 0.08);\n z-index: 999997;\n transition: opacity 0.2s;\n }\n \n .grain-tracker-label {\n position: absolute;\n top: -28px;\n left: 0;\n background: #6366f1;\n color: white;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n pointer-events: none;\n }\n \n .grain-tracker-label::after {\n content: '';\n position: absolute;\n bottom: -4px;\n left: 10px;\n width: 0;\n height: 0;\n border-left: 4px solid transparent;\n border-right: 4px solid transparent;\n border-top: 4px solid #6366f1;\n }\n \n .grain-trackers-list {\n position: fixed;\n bottom: 80px;\n right: 20px;\n background: white;\n border: 1.5px solid #e2e8f0;\n border-radius: 10px;\n padding: 12px;\n max-height: 400px;\n width: 320px;\n overflow-y: auto;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1), 0 2px 8px rgba(0, 0, 0, 0.06);\n z-index: 999998;\n }\n \n .grain-tracker-item {\n padding: 10px;\n background: #f8fafc;\n border-radius: 8px;\n margin-bottom: 8px;\n cursor: pointer;\n transition: all 0.2s;\n }\n \n .grain-tracker-item:hover {\n background: #f1f5f9;\n transform: translateX(4px);\n }\n \n .grain-tracker-item:last-child {\n margin-bottom: 0;\n }\n \n .grain-tracker-name {\n font-weight: 600;\n color: #1e293b;\n font-size: 13px;\n margin-bottom: 4px;\n }\n \n .grain-tracker-details {\n font-size: 11px;\n color: #64748b;\n display: flex;\n gap: 8px;\n align-items: center;\n }\n \n .grain-tracker-type {\n background: #dbeafe;\n color: #1e40af;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n font-size: 9px;\n letter-spacing: 0.5px;\n }\n </style>\n <div class=\"grain-toolbar-inner\">\n <div class=\"grain-toolbar-header\" id=\"grain-toolbar-handle\">\n <div class=\"grain-toolbar-title\">Grain Debug</div>\n </div>\n <div class=\"grain-toolbar-body\">\n <div class=\"grain-toolbar-stats\">\n <div class=\"grain-stat\">\n <div class=\"grain-stat-value\">${this.existingTrackers.length}</div>\n <div class=\"grain-stat-label\">trackers</div>\n </div>\n <div class=\"grain-stat\">\n <div class=\"grain-stat-value\">${this.existingTrackers.filter(t => t.isEnabled).length}</div>\n <div class=\"grain-stat-label\">active</div>\n </div>\n </div>\n <div class=\"grain-toolbar-actions\">\n <button id=\"grain-debug-inspect\" type=\"button\">\n + New\n </button>\n <button id=\"grain-debug-trackers\" class=\"active\" type=\"button\">\n Hide\n </button>\n <button id=\"grain-debug-end\" class=\"danger\" type=\"button\">\n End Session\n </button>\n </div>\n </div>\n </div>\n <div id=\"grain-trackers-list-container\"></div>\n `;\n\n document.body.appendChild(toolbar);\n this.toolbarElement = toolbar;\n\n // Setup dragging\n const handle = toolbar.querySelector('#grain-toolbar-handle') as HTMLElement;\n if (handle) {\n handle.addEventListener('mousedown', (e) => this.startDrag(e));\n }\n\n // Add event listeners\n const inspectBtn = toolbar.querySelector('#grain-debug-inspect');\n const trackersBtn = toolbar.querySelector('#grain-debug-trackers');\n const endBtn = toolbar.querySelector('#grain-debug-end');\n\n if (inspectBtn) {\n inspectBtn.addEventListener('click', () => this.toggleInspectMode());\n }\n\n if (trackersBtn) {\n trackersBtn.addEventListener('click', () => this.toggleTrackerView());\n }\n\n if (endBtn) {\n endBtn.addEventListener('click', () => this.endDebug());\n }\n\n this.log('Toolbar shown');\n }\n\n /**\n * Create highlight element for hovering\n */\n private createHighlightElement(): void {\n if (this.highlightElement) return;\n\n const highlight = document.createElement('div');\n highlight.className = 'grain-debug-highlight';\n highlight.style.display = 'none';\n document.body.appendChild(highlight);\n this.highlightElement = highlight;\n }\n\n /**\n * Start dragging the toolbar\n */\n private startDrag(e: MouseEvent): void {\n if (!this.toolbarElement) return;\n \n this.isDragging = true;\n this.dragStartX = e.clientX;\n this.dragStartY = e.clientY;\n \n const rect = this.toolbarElement.getBoundingClientRect();\n this.toolbarStartX = rect.left;\n this.toolbarStartY = rect.top;\n \n this.toolbarElement.classList.add('dragging');\n \n this.dragMoveListener = (e: MouseEvent) => this.onDrag(e);\n this.dragEndListener = () => this.endDrag();\n \n document.addEventListener('mousemove', this.dragMoveListener);\n document.addEventListener('mouseup', this.dragEndListener);\n }\n\n /**\n * Handle drag movement\n */\n private onDrag(e: MouseEvent): void {\n if (!this.isDragging || !this.toolbarElement) return;\n \n const deltaX = e.clientX - this.dragStartX;\n const deltaY = e.clientY - this.dragStartY;\n \n const newX = this.toolbarStartX + deltaX;\n const newY = this.toolbarStartY + deltaY;\n \n // Keep toolbar within viewport\n const maxX = window.innerWidth - this.toolbarElement.offsetWidth;\n const maxY = window.innerHeight - this.toolbarElement.offsetHeight;\n \n const clampedX = Math.max(0, Math.min(newX, maxX));\n const clampedY = Math.max(0, Math.min(newY, maxY));\n \n this.toolbarElement.style.left = `${clampedX}px`;\n this.toolbarElement.style.top = `${clampedY}px`;\n this.toolbarElement.style.right = 'auto';\n this.toolbarElement.style.bottom = 'auto';\n }\n\n /**\n * End dragging\n */\n private endDrag(): void {\n if (!this.isDragging) return;\n \n this.isDragging = false;\n \n if (this.toolbarElement) {\n this.toolbarElement.classList.remove('dragging');\n }\n \n if (this.dragMoveListener) {\n document.removeEventListener('mousemove', this.dragMoveListener);\n this.dragMoveListener = null;\n }\n \n if (this.dragEndListener) {\n document.removeEventListener('mouseup', this.dragEndListener);\n this.dragEndListener = null;\n }\n }\n\n /**\n * Toggle tracker view\n */\n private toggleTrackerView(): void {\n this.showTrackers = !this.showTrackers;\n \n const trackersBtn = document.querySelector('#grain-debug-trackers');\n if (trackersBtn) {\n trackersBtn.textContent = this.showTrackers ? 'Hide' : 'View';\n trackersBtn.classList.toggle('active', this.showTrackers);\n }\n \n if (this.showTrackers) {\n this.showTrackerHighlights();\n this.showTrackersList();\n } else {\n this.hideTrackerHighlights();\n this.hideTrackersList();\n }\n }\n\n /**\n * Show tracker highlights on page\n */\n private showTrackerHighlights(): void {\n this.hideTrackerHighlights();\n \n for (const tracker of this.existingTrackers) {\n if (!tracker.isEnabled) continue;\n \n try {\n const element = this.findElementBySelector(tracker.selector);\n if (!element) continue;\n \n const rect = element.getBoundingClientRect();\n const highlight = document.createElement('div');\n highlight.className = 'grain-tracker-highlight';\n \n const label = document.createElement('div');\n label.className = 'grain-tracker-label';\n label.textContent = tracker.name;\n \n highlight.style.top = `${rect.top + window.scrollY}px`;\n highlight.style.left = `${rect.left + window.scrollX}px`;\n highlight.style.width = `${rect.width}px`;\n highlight.style.height = `${rect.height}px`;\n \n highlight.appendChild(label);\n document.body.appendChild(highlight);\n this.trackerHighlights.push(highlight);\n } catch (error) {\n this.log('Failed to highlight tracker:', tracker.name, error);\n }\n }\n }\n\n /**\n * Hide tracker highlights\n */\n private hideTrackerHighlights(): void {\n for (const highlight of this.trackerHighlights) {\n highlight.remove();\n }\n this.trackerHighlights = [];\n }\n\n /**\n * Show trackers list\n */\n private showTrackersList(): void {\n // Check if list already exists\n let list = document.querySelector('.grain-trackers-list') as HTMLElement;\n \n if (this.existingTrackers.length === 0) {\n if (list) list.remove();\n return;\n }\n \n if (!list) {\n list = document.createElement('div');\n list.className = 'grain-trackers-list';\n document.body.appendChild(list);\n }\n \n list.innerHTML = `\n ${this.existingTrackers.map(tracker => `\n <div class=\"grain-tracker-item\" data-tracker-id=\"${tracker.trackerId}\">\n <div class=\"grain-tracker-name\">${tracker.name}</div>\n <div class=\"grain-tracker-details\">\n <span class=\"grain-tracker-type\">${tracker.type}</span>\n <span>${tracker.urlScope}</span>\n ${!tracker.isEnabled ? '<span style=\"color: #ef4444;\">\u2022 Disabled</span>' : ''}\n </div>\n </div>\n `).join('')}\n `;\n \n // Add click handlers to scroll to elements\n list.querySelectorAll('.grain-tracker-item').forEach(item => {\n item.addEventListener('click', () => {\n const trackerId = item.getAttribute('data-tracker-id');\n const tracker = this.existingTrackers.find(t => t.trackerId === trackerId);\n if (tracker) {\n this.scrollToTracker(tracker);\n }\n });\n });\n }\n\n /**\n * Hide trackers list\n */\n private hideTrackersList(): void {\n const list = document.querySelector('.grain-trackers-list');\n if (list) {\n list.remove();\n }\n }\n\n /**\n * Scroll to and highlight a tracker element\n */\n private scrollToTracker(tracker: ExistingTracker): void {\n try {\n const element = this.findElementBySelector(tracker.selector);\n if (element) {\n element.scrollIntoView({ behavior: 'smooth', block: 'center' });\n \n // Flash the highlight\n const highlight = this.trackerHighlights.find(h => {\n const rect = element.getBoundingClientRect();\n const hRect = h.getBoundingClientRect();\n return Math.abs(hRect.top - rect.top) < 5;\n });\n \n if (highlight) {\n highlight.style.opacity = '0';\n setTimeout(() => {\n highlight.style.opacity = '1';\n }, 100);\n setTimeout(() => {\n highlight.style.opacity = '0';\n }, 300);\n setTimeout(() => {\n highlight.style.opacity = '1';\n }, 500);\n }\n }\n } catch (error) {\n this.log('Failed to scroll to tracker:', error);\n }\n }\n\n /**\n * Find element by XPath selector\n */\n private findElementBySelector(selector: string): Element | null {\n try {\n const result = document.evaluate(\n selector,\n document,\n null,\n XPathResult.FIRST_ORDERED_NODE_TYPE,\n null\n );\n return result.singleNodeValue as Element | null;\n } catch (error) {\n this.log('Failed to find element:', error);\n return null;\n }\n }\n\n /**\n * Toggle inspect mode\n */\n private toggleInspectMode(): void {\n if (this.isInspectMode) {\n this.disableInspectMode();\n } else {\n this.enableInspectMode();\n }\n }\n\n /**\n * Enable element inspection mode\n */\n private enableInspectMode(): void {\n if (this.isInspectMode) return;\n\n this.log('Enabling inspect mode');\n this.isInspectMode = true;\n\n // Update button state\n const inspectBtn = document.querySelector('#grain-debug-inspect');\n if (inspectBtn) {\n inspectBtn.classList.add('active');\n inspectBtn.textContent = 'Click Element';\n }\n\n // Add event listeners\n this.mouseMoveListener = (e: MouseEvent) => this.handleMouseMove(e);\n this.clickListener = (e: MouseEvent) => this.handleElementClick(e);\n\n document.addEventListener('mousemove', this.mouseMoveListener, true);\n document.addEventListener('click', this.clickListener, true);\n \n // Add ESC key listener to exit inspect mode\n document.addEventListener('keydown', this.handleEscapeKey);\n }\n\n /**\n * Handle ESC key to exit inspect mode\n */\n private handleEscapeKey = (e: KeyboardEvent): void => {\n if (e.key === 'Escape' && this.isInspectMode) {\n this.disableInspectMode();\n }\n };\n\n /**\n * Disable element inspection mode\n */\n private disableInspectMode(): void {\n if (!this.isInspectMode) return;\n\n this.log('Disabling inspect mode');\n this.isInspectMode = false;\n\n // Update button state\n const inspectBtn = document.querySelector('#grain-debug-inspect');\n if (inspectBtn) {\n inspectBtn.classList.remove('active');\n inspectBtn.textContent = '+ New';\n }\n\n // Remove event listeners\n if (this.mouseMoveListener) {\n document.removeEventListener('mousemove', this.mouseMoveListener, true);\n this.mouseMoveListener = null;\n }\n\n if (this.clickListener) {\n document.removeEventListener('click', this.clickListener, true);\n this.clickListener = null;\n }\n\n document.removeEventListener('keydown', this.handleEscapeKey);\n\n // Hide highlight\n if (this.highlightElement) {\n this.highlightElement.style.display = 'none';\n }\n }\n\n /**\n * Handle mouse move to highlight hovered element\n */\n private handleMouseMove(e: MouseEvent): void {\n if (!this.isInspectMode || !this.highlightElement) return;\n\n // Ignore if hovering over toolbar, panel, or tracker list\n const target = e.target as HTMLElement;\n if (target.closest('#grain-debug-toolbar') || \n target.closest('#grain-debug-panel') ||\n target.closest('.grain-trackers-list')) {\n this.highlightElement.style.display = 'none';\n return;\n }\n\n // Get element rect\n const element = e.target as HTMLElement;\n const rect = element.getBoundingClientRect();\n\n // Position highlight\n this.highlightElement.style.display = 'block';\n this.highlightElement.style.top = `${rect.top + window.scrollY}px`;\n this.highlightElement.style.left = `${rect.left + window.scrollX}px`;\n this.highlightElement.style.width = `${rect.width}px`;\n this.highlightElement.style.height = `${rect.height}px`;\n }\n\n /**\n * Handle element click to show creation panel\n */\n private handleElementClick(e: MouseEvent): void {\n if (!this.isInspectMode) return;\n\n const target = e.target as HTMLElement;\n \n // If clicking toolbar or tracker list, exit inspect mode and allow normal click\n if (target.closest('#grain-debug-toolbar') || target.closest('.grain-trackers-list')) {\n this.disableInspectMode();\n return;\n }\n\n // If clicking panel, prevent default but don't do anything\n if (target.closest('#grain-debug-panel')) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n\n // Otherwise, select the element\n e.preventDefault();\n e.stopPropagation();\n\n this.selectedElement = target;\n this.disableInspectMode();\n this.showCreationPanel(target);\n }\n\n /**\n * Show tracker creation panel\n */\n private showCreationPanel(element: Element): void {\n // Remove existing panel if any\n if (this.panelElement) {\n this.panelElement.remove();\n }\n\n const panel = document.createElement('div');\n panel.id = 'grain-debug-panel';\n \n // Extract element info\n const tagName = element.tagName.toLowerCase();\n const elementId = element.id;\n const elementText = element.textContent?.trim().substring(0, 50) || '';\n const xpath = this.getXPathForElement(element);\n \n panel.innerHTML = `\n <style>\n #grain-debug-panel {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: repeating-linear-gradient(\n 45deg,\n #fbbf24,\n #fbbf24 10px,\n #1e293b 10px,\n #1e293b 20px\n );\n border: 2px solid #1e293b;\n border-radius: 16px;\n padding: 6px;\n width: 420px;\n max-width: 90vw;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25), 0 8px 24px rgba(0, 0, 0, 0.15);\n z-index: 1000000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n }\n \n .grain-panel-inner {\n background: white;\n border-radius: 10px;\n overflow: hidden;\n }\n \n .grain-panel-header {\n background: #1e293b;\n padding: 14px 18px;\n color: white;\n }\n \n .grain-panel-header h3 {\n margin: 0 0 4px 0;\n font-size: 16px;\n font-weight: 700;\n letter-spacing: 0.5px;\n color: #fbbf24;\n text-transform: uppercase;\n }\n \n .grain-panel-header p {\n margin: 0;\n font-size: 12px;\n opacity: 0.85;\n color: white;\n }\n \n .grain-panel-body {\n padding: 18px;\n }\n \n #grain-debug-panel .element-preview {\n background: #f8fafc;\n border: 1.5px solid #e2e8f0;\n border-radius: 8px;\n padding: 10px 12px;\n margin-bottom: 16px;\n font-size: 11px;\n color: #475569;\n }\n \n #grain-debug-panel .element-preview div {\n margin-bottom: 4px;\n }\n \n #grain-debug-panel .element-preview div:last-child {\n margin-bottom: 0;\n }\n \n #grain-debug-panel .element-preview strong {\n color: #1e293b;\n font-weight: 600;\n }\n \n #grain-debug-panel label {\n display: block;\n color: #1e293b;\n font-size: 12px;\n font-weight: 600;\n margin-bottom: 6px;\n }\n \n #grain-debug-panel input,\n #grain-debug-panel select {\n width: 100%;\n background: white;\n border: 1.5px solid #e2e8f0;\n border-radius: 8px;\n padding: 9px 12px;\n color: #1e293b;\n font-size: 13px;\n margin-bottom: 14px;\n box-sizing: border-box;\n transition: all 0.2s;\n }\n \n #grain-debug-panel input:focus,\n #grain-debug-panel select:focus {\n outline: none;\n border-color: #fbbf24;\n box-shadow: 0 0 0 3px rgba(251, 191, 36, 0.1);\n }\n \n #grain-debug-panel .button-group {\n display: flex;\n gap: 8px;\n margin-top: 18px;\n }\n \n #grain-debug-panel button {\n flex: 1;\n padding: 10px 16px;\n border: none;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s;\n }\n \n #grain-debug-panel button.primary {\n background: #fbbf24;\n color: #1e293b;\n box-shadow: 0 2px 8px rgba(251, 191, 36, 0.3);\n }\n \n #grain-debug-panel button.primary:hover {\n background: #f59e0b;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(251, 191, 36, 0.4);\n }\n \n #grain-debug-panel button.secondary {\n background: white;\n border: 1.5px solid #e2e8f0;\n color: #475569;\n }\n \n #grain-debug-panel button.secondary:hover {\n background: #f8fafc;\n border-color: #cbd5e1;\n }\n \n #grain-debug-panel .url-pattern-input {\n display: none;\n }\n \n #grain-debug-panel .url-pattern-input.visible {\n display: block;\n }\n </style>\n <div class=\"grain-panel-inner\">\n <div class=\"grain-panel-header\">\n <h3>Create Tracker</h3>\n <p>Set up automatic tracking for this element</p>\n </div>\n <div class=\"grain-panel-body\">\n <div class=\"element-preview\">\n <div><strong>Element:</strong> ${tagName}${elementId ? `#${elementId}` : ''}</div>\n ${elementText ? `<div><strong>Text:</strong> ${elementText}</div>` : ''}\n </div>\n <div>\n <label>Event Name</label>\n <input type=\"text\" id=\"grain-event-name\" placeholder=\"e.g., signup_button_click\" value=\"\" />\n </div>\n <div>\n <label>Type</label>\n <select id=\"grain-event-type\">\n <option value=\"metric\">Metric</option>\n <option value=\"conversion\">Conversion</option>\n </select>\n </div>\n <div>\n <label>URL Scope</label>\n <select id=\"grain-url-scope\">\n <option value=\"all\">All Pages</option>\n <option value=\"contains\" selected>This Page</option>\n <option value=\"equals\">Exact URL</option>\n </select>\n </div>\n <div class=\"url-pattern-input visible\" id=\"grain-url-pattern-container\">\n <label>URL Pattern</label>\n <input type=\"text\" id=\"grain-url-pattern\" placeholder=\"e.g., /pricing\" value=\"${window.location.pathname}\" />\n </div>\n <div class=\"button-group\">\n <button type=\"button\" class=\"secondary\" id=\"grain-cancel\">Cancel</button>\n <button type=\"button\" class=\"primary\" id=\"grain-create\">\u2713 Create</button>\n </div>\n </div>\n </div>\n `;\n\n document.body.appendChild(panel);\n this.panelElement = panel;\n\n // Auto-generate event name suggestion\n const eventNameInput = panel.querySelector('#grain-event-name') as HTMLInputElement;\n if (eventNameInput) {\n const suggestedName = this.generateEventName(element);\n eventNameInput.value = suggestedName;\n eventNameInput.select();\n }\n\n // Handle URL scope change\n const urlScopeSelect = panel.querySelector('#grain-url-scope') as HTMLSelectElement;\n const urlPatternContainer = panel.querySelector('#grain-url-pattern-container');\n const urlPatternInput = panel.querySelector('#grain-url-pattern') as HTMLInputElement;\n \n if (urlScopeSelect && urlPatternContainer) {\n urlScopeSelect.addEventListener('change', () => {\n if (urlScopeSelect.value === 'all') {\n urlPatternContainer.classList.remove('visible');\n } else {\n urlPatternContainer.classList.add('visible');\n if (urlPatternInput && !urlPatternInput.value) {\n urlPatternInput.value = window.location.pathname;\n }\n }\n });\n }\n\n // Handle buttons\n const cancelBtn = panel.querySelector('#grain-cancel');\n const createBtn = panel.querySelector('#grain-create');\n\n if (cancelBtn) {\n cancelBtn.addEventListener('click', () => this.hideCreationPanel());\n }\n\n if (createBtn) {\n createBtn.addEventListener('click', () => this.handleCreateTracker(xpath));\n }\n }\n\n /**\n * Generate suggested event name from element\n */\n private generateEventName(element: Element): string {\n const tagName = element.tagName.toLowerCase();\n const elementId = element.id;\n const elementText = element.textContent?.trim().toLowerCase().replace(/\\s+/g, '_').substring(0, 30) || '';\n \n // Try to generate meaningful name\n if (elementId) {\n return `${elementId}_click`;\n } else if (elementText) {\n return `${elementText}_click`;\n } else if (tagName === 'button') {\n return 'button_click';\n } else if (tagName === 'a') {\n return 'link_click';\n } else {\n return `${tagName}_click`;\n }\n }\n\n /**\n * Handle tracker creation\n */\n private async handleCreateTracker(selector: string): Promise<void> {\n if (!this.panelElement) return;\n\n const eventNameInput = this.panelElement.querySelector('#grain-event-name') as HTMLInputElement;\n const eventTypeSelect = this.panelElement.querySelector('#grain-event-type') as HTMLSelectElement;\n const urlScopeSelect = this.panelElement.querySelector('#grain-url-scope') as HTMLSelectElement;\n const urlPatternInput = this.panelElement.querySelector('#grain-url-pattern') as HTMLInputElement;\n\n if (!eventNameInput || !eventTypeSelect || !urlScopeSelect) return;\n\n const eventName = eventNameInput.value.trim();\n const eventType = eventTypeSelect.value;\n const urlScope = urlScopeSelect.value;\n const urlPattern = urlPatternInput?.value.trim() || undefined;\n\n // Validate\n if (!eventName) {\n alert('Please enter an event name');\n return;\n }\n\n if (!eventName.match(/^[a-zA-Z0-9_-]+$/)) {\n alert('Event name can only contain letters, numbers, underscores, and hyphens');\n return;\n }\n\n if ((urlScope === 'contains' || urlScope === 'equals') && !urlPattern) {\n alert('Please enter a URL pattern');\n return;\n }\n\n try {\n // Show loading state\n const createBtn = this.panelElement.querySelector('#grain-create') as HTMLButtonElement;\n if (createBtn) {\n createBtn.textContent = 'Creating...';\n createBtn.disabled = true;\n }\n\n // Create tracker\n await this.createTracker(eventName, eventType, selector, urlScope, urlPattern);\n\n // Success\n this.hideCreationPanel();\n this.showSuccessMessage(`Tracker \"${eventName}\" created successfully!`);\n \n // Reload trackers and update UI\n await this.loadExistingTrackers();\n this.updateToolbarStats();\n if (this.showTrackers) {\n this.showTrackerHighlights();\n this.showTrackersList();\n }\n \n this.log('Tracker created:', eventName);\n } catch (error) {\n alert('Failed to create tracker. Please try again.');\n this.log('Failed to create tracker:', error);\n \n // Reset button\n const createBtn = this.panelElement.querySelector('#grain-create') as HTMLButtonElement;\n if (createBtn) {\n createBtn.textContent = 'Create Tracker';\n createBtn.disabled = false;\n }\n }\n }\n\n /**\n * Create tracker via API\n */\n private async createTracker(\n name: string,\n type: string,\n selector: string,\n urlScope: string,\n urlPattern?: string\n ): Promise<void> {\n const url = `${this.apiUrl}/v1/tenant/${encodeURIComponent(this.tenantId)}/debug-sessions/${this.sessionId}/trackers`;\n \n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n name,\n type,\n selector,\n urlScope,\n urlPattern,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create tracker: ${response.status}`);\n }\n }\n\n /**\n * Hide creation panel\n */\n private hideCreationPanel(): void {\n if (this.panelElement) {\n this.panelElement.remove();\n this.panelElement = null;\n }\n this.selectedElement = null;\n }\n\n /**\n * Show success message\n */\n private showSuccessMessage(message: string): void {\n const toast = document.createElement('div');\n toast.style.cssText = `\n position: fixed;\n top: 20px;\n left: 50%;\n transform: translateX(-50%) translateY(-20px);\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n color: white;\n padding: 14px 24px;\n border-radius: 12px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n font-weight: 600;\n box-shadow: 0 12px 32px rgba(16, 185, 129, 0.3), 0 4px 12px rgba(0, 0, 0, 0.15);\n z-index: 1000000;\n display: flex;\n align-items: center;\n gap: 10px;\n animation: slideDown 0.3s ease-out forwards;\n `;\n toast.innerHTML = `\n <style>\n @keyframes slideDown {\n to {\n transform: translateX(-50%) translateY(0);\n }\n }\n </style>\n <span style=\"font-size: 18px;\">\u2713</span>\n <span>${message}</span>\n `;\n\n document.body.appendChild(toast);\n\n setTimeout(() => {\n toast.style.animation = 'slideDown 0.3s ease-in reverse';\n setTimeout(() => {\n toast.remove();\n }, 300);\n }, 2700);\n }\n\n /**\n * End debug session\n */\n private async endDebug(): Promise<void> {\n try {\n // Call end session API\n const url = `${this.apiUrl}/v1/tenant/${encodeURIComponent(this.tenantId)}/debug-sessions/${this.sessionId}/end`;\n \n await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n } catch (error) {\n this.log('Failed to end debug session:', error);\n }\n\n // Clean up and reload page\n this.destroy();\n \n // Remove debug params from URL and reload\n const url = new URL(window.location.href);\n url.searchParams.delete('grain_debug');\n url.searchParams.delete('grain_session');\n window.location.href = url.toString();\n }\n\n /**\n * Get XPath for element\n */\n private getXPathForElement(element: Element): string {\n if (element.id) {\n return `//*[@id=\"${element.id}\"]`;\n }\n\n const parts: string[] = [];\n let current: Element | null = element;\n\n while (current && current.nodeType === Node.ELEMENT_NODE) {\n let index = 0;\n let sibling: Element | null = current;\n\n while (sibling) {\n if (sibling.nodeType === Node.ELEMENT_NODE && sibling.tagName === current.tagName) {\n index++;\n }\n sibling = sibling.previousElementSibling;\n }\n\n const tagName = current.tagName.toLowerCase();\n const pathIndex = index > 1 ? `[${index}]` : '';\n parts.unshift(`${tagName}${pathIndex}`);\n\n current = current.parentElement;\n }\n\n return parts.length ? `/${parts.join('/')}` : '';\n }\n\n /**\n * Log debug messages\n */\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[DebugAgent]', ...args);\n }\n }\n\n /**\n * Update toolbar stats\n */\n private updateToolbarStats(): void {\n if (!this.toolbarElement) return;\n \n const totalStat = this.toolbarElement.querySelector('.grain-stat:nth-child(1) .grain-stat-value');\n const activeStat = this.toolbarElement.querySelector('.grain-stat:nth-child(2) .grain-stat-value');\n \n if (totalStat) {\n totalStat.textContent = String(this.existingTrackers.length);\n }\n if (activeStat) {\n activeStat.textContent = String(this.existingTrackers.filter(t => t.isEnabled).length);\n }\n }\n\n /**\n * Destroy the debug agent\n */\n destroy(): void {\n if (this.isDestroyed) return;\n\n this.log('Destroying debug agent');\n this.isDestroyed = true;\n\n this.disableInspectMode();\n this.hideTrackerHighlights();\n this.endDrag();\n\n if (this.toolbarElement) {\n this.toolbarElement.remove();\n this.toolbarElement = null;\n }\n\n if (this.panelElement) {\n this.panelElement.remove();\n this.panelElement = null;\n }\n\n if (this.highlightElement) {\n this.highlightElement.remove();\n this.highlightElement = null;\n }\n }\n}\n", "/**\n * Grain Analytics Web SDK\n * A lightweight, dependency-free TypeScript SDK for sending analytics events to Grain's REST API\n */\n\nimport { ConsentManager, ConsentState, ConsentMode } from './consent';\nimport { setCookie, getCookie, deleteCookie, areCookiesEnabled, CookieConfig } from './cookies';\nimport { ActivityDetector } from './activity';\nimport { HeartbeatManager, type HeartbeatTracker } from './heartbeat';\nimport { PageTrackingManager, type PageTracker } from './page-tracking';\nimport { IdManager, type IdMode } from './id-manager';\nimport {\n categorizeReferrer,\n parseUTMParameters,\n getOrCreateFirstTouchAttribution,\n getSessionUTMParameters,\n getFirstTouchAttribution,\n type ReferrerCategory,\n type UTMParameters,\n type FirstTouchAttribution,\n} from './attribution';\n\n// Re-export attribution types and functions\nexport type { ReferrerCategory, UTMParameters, FirstTouchAttribution };\nexport { categorizeReferrer, parseUTMParameters };\n\n// Re-export timezone-country utilities\nexport { getCountry, getCountryCodeFromTimezone, getState } from './countries';\n\n// Re-export auto-tracking types\nexport type {\n InteractionConfig,\n SectionConfig,\n AutoTrackingConfig,\n SectionViewData,\n SectionTrackingOptions,\n} from './types/auto-tracking';\n\nexport interface GrainEvent {\n eventName: string;\n userId?: string;\n properties?: Record<string, unknown>;\n timestamp?: Date;\n}\n\nexport interface EventPayload {\n eventName: string;\n userId: string;\n properties: Record<string, unknown>;\n}\n\nexport type AuthStrategy = 'NONE' | 'SERVER_SIDE' | 'JWT';\n\nexport interface AuthProvider {\n getToken(): Promise<string> | string;\n}\n\n// Re-export privacy types\nexport type { ConsentState, ConsentMode, CookieConfig };\n\nexport interface GrainConfig {\n tenantId: string;\n apiUrl?: string;\n authStrategy?: AuthStrategy;\n secretKey?: string; // For SERVER_SIDE auth\n authProvider?: AuthProvider; // For JWT auth\n userId?: string; // Global user ID for all events\n batchSize?: number;\n flushInterval?: number; // milliseconds\n retryAttempts?: number;\n retryDelay?: number; // milliseconds\n maxEventsPerRequest?: number; // Maximum events to send in a single API request\n debug?: boolean;\n // Remote Config options\n defaultConfigurations?: Record<string, string>; // Default values for configurations\n configCacheKey?: string; // Custom cache key for configurations\n configRefreshInterval?: number; // Auto-refresh interval in milliseconds (default: 5 minutes)\n enableConfigCache?: boolean; // Enable/disable configuration caching (default: true)\n // Privacy & Consent options (v2.0)\n consentMode?: ConsentMode; // 'cookieless' | 'gdpr-strict' | 'gdpr-opt-out' (default: 'cookieless')\n waitForConsent?: boolean; // Queue events until consent is granted (default: false, only for gdpr-strict)\n // Deprecated: enableCookies - cookies no longer used for user identification\n // Deprecated: anonymizeIP - IP addresses never stored (GeoIP used instead)\n disableAutoProperties?: boolean; // Disable automatic property collection (default: false)\n allowedProperties?: string[]; // Whitelist of allowed event properties (default: all)\n // Automatic Tracking options\n enableHeartbeat?: boolean; // Enable heartbeat tracking (default: true)\n heartbeatActiveInterval?: number; // Active interval in ms (default: 120000 - 2 min)\n heartbeatInactiveInterval?: number; // Inactive interval in ms (default: 300000 - 5 min)\n enableAutoPageView?: boolean; // Enable automatic page view tracking (default: true)\n stripQueryParams?: boolean; // Strip query params from URLs (default: true)\n stripHash?: boolean; // Strip hash from URLs (default: false)\n // Heatmap Tracking options\n enableHeatmapTracking?: boolean; // Enable heatmap tracking (default: true)\n}\n\nexport interface SendEventOptions {\n flush?: boolean; // Force immediate send\n}\n\nexport interface SetPropertyOptions {\n userId?: string; // Override global userId\n}\n\nexport interface LoginOptions {\n userId?: string; // User ID to set\n authToken?: string; // Auth token to set for JWT auth\n authStrategy?: AuthStrategy; // Override auth strategy\n}\n\nexport interface PropertyPayload {\n userId: string;\n [key: string]: string; // All property values must be strings\n}\n\n// Remote Config interfaces\nexport interface RemoteConfigRequest {\n userId: string;\n immediateKeys: string[];\n properties?: Record<string, string>;\n currentUrl?: string; // Optional current URL for page-specific configs\n}\n\nexport interface RemoteConfigResponse {\n userId: string;\n snapshotId: string;\n configurations: Record<string, string>;\n isFinal: boolean;\n qualifiedSegments: string[];\n qualifiedRuleSets: string[];\n timestamp: string;\n isFromCache: boolean;\n autoTrackingConfig?: {\n interactions: Array<{\n eventName: string;\n description: string;\n selector: string;\n priority: number;\n label: string;\n }>;\n sections: Array<{\n sectionName: string;\n description: string;\n sectionType: string;\n selector: string;\n importance: number;\n }>;\n };\n}\n\nexport interface RemoteConfigOptions {\n immediateKeys?: string[];\n properties?: Record<string, string>;\n userId?: string; // Override global userId\n forceRefresh?: boolean; // Force fetch from API, bypass cache\n}\n\nexport interface RemoteConfigCache {\n configurations: Record<string, string>;\n snapshotId: string;\n timestamp: string;\n userId: string;\n}\n\nexport type ConfigChangeListener = (configurations: Record<string, string>) => void;\n\n// Template event interfaces\nexport interface LoginEventProperties extends Record<string, unknown> {\n method?: string; // 'email', 'google', 'facebook', etc.\n success?: boolean;\n errorMessage?: string;\n loginAttempt?: number;\n rememberMe?: boolean;\n twoFactorEnabled?: boolean;\n}\n\nexport interface SignupEventProperties extends Record<string, unknown> {\n method?: string; // 'email', 'google', 'facebook', etc.\n source?: string; // 'landing_page', 'referral', 'ad', etc.\n plan?: string; // 'free', 'pro', 'enterprise', etc.\n success?: boolean;\n errorMessage?: string;\n}\n\nexport interface CheckoutEventProperties extends Record<string, unknown> {\n orderId?: string;\n total?: number;\n currency?: string;\n items?: Array<{\n id: string;\n name: string;\n price: number;\n quantity: number;\n }>;\n paymentMethod?: string; // 'credit_card', 'paypal', 'stripe', etc.\n success?: boolean;\n errorMessage?: string;\n couponCode?: string;\n discount?: number;\n}\n\nexport interface PageViewEventProperties extends Record<string, unknown> {\n page?: string;\n title?: string;\n referrer?: string;\n url?: string;\n userAgent?: string;\n screenResolution?: string;\n viewportSize?: string;\n}\n\nexport interface PurchaseEventProperties extends Record<string, unknown> {\n orderId?: string;\n total?: number;\n currency?: string;\n items?: Array<{\n id: string;\n name: string;\n price: number;\n quantity: number;\n category?: string;\n }>;\n paymentMethod?: string;\n shippingMethod?: string;\n tax?: number;\n shipping?: number;\n discount?: number;\n couponCode?: string;\n}\n\nexport interface SearchEventProperties extends Record<string, unknown> {\n query?: string;\n results?: number;\n filters?: Record<string, unknown>;\n sortBy?: string;\n category?: string;\n success?: boolean;\n}\n\nexport interface AddToCartEventProperties extends Record<string, unknown> {\n itemId?: string;\n itemName?: string;\n price?: number;\n quantity?: number;\n currency?: string;\n category?: string;\n variant?: string;\n}\n\nexport interface RemoveFromCartEventProperties extends Record<string, unknown> {\n itemId?: string;\n itemName?: string;\n price?: number;\n quantity?: number;\n currency?: string;\n category?: string;\n variant?: string;\n}\n\n// Error handling interfaces\nexport interface ErrorDigest {\n eventCount: number;\n totalProperties: number;\n totalSize: number;\n eventNames: string[];\n userIds: string[];\n}\n\nexport interface FormattedError {\n code: string;\n message: string;\n digest: ErrorDigest;\n timestamp: string;\n context: string;\n originalError?: unknown;\n}\n\n/**\n * Main Grain Analytics client\n * \n * Features:\n * - Automatic UUIDv4 generation for anonymous users\n * - Login/logout functionality for dynamic auth token injection\n * - Persistent anonymous user ID across sessions (when consent is granted)\n * - Support for multiple auth strategies (NONE, SERVER_SIDE, JWT)\n * - GDPR-compliant consent management with strict opt-in mode\n * - Optional cookie support for cross-session tracking\n * \n * GDPR Compliance (Opt-in Mode):\n * - Without consent: Only ephemeral session IDs (memory-only) are used\n * - No cookies or localStorage identifiers until consent is granted\n * - Exceptions: User explicitly identified via identify()/login() or JWT auth\n * - Remote config cache and consent preferences use localStorage (functional/necessary)\n */\ntype RequiredConfig = Required<Omit<GrainConfig, 'secretKey' | 'authProvider' | 'userId' | 'cookieOptions' | 'allowedProperties'>> & {\n secretKey?: string;\n authProvider?: AuthProvider;\n userId?: string;\n cookieOptions?: CookieConfig;\n allowedProperties?: string[];\n};\n\nexport class GrainAnalytics implements HeartbeatTracker, PageTracker {\n private config: RequiredConfig;\n private eventQueue: EventPayload[] = [];\n private waitingForConsentQueue: EventPayload[] = [];\n private flushTimer: number | null = null;\n private isDestroyed = false;\n private globalUserId: string | null = null;\n private persistentAnonymousUserId: string | null = null; // Deprecated: use idManager instead\n // Remote Config properties\n private configCache: RemoteConfigCache | null = null;\n private configRefreshTimer: number | null = null;\n private configChangeListeners: ConfigChangeListener[] = [];\n private configFetchPromise: Promise<RemoteConfigResponse> | null = null;\n // Privacy & Consent properties (v2.0)\n private consentManager: ConsentManager;\n private idManager: IdManager;\n private cookiesEnabled: boolean = false; // Deprecated: cookies no longer used for IDs\n // Automatic Tracking properties\n private activityDetector: ActivityDetector | null = null;\n private heartbeatManager: HeartbeatManager | null = null;\n private pageTrackingManager: PageTrackingManager | null = null;\n private ephemeralSessionId: string | null = null;\n private eventCountSinceLastHeartbeat: number = 0;\n // Auto-tracking properties\n private interactionTrackingManager: any | null = null;\n private sectionTrackingManager: any | null = null;\n private heatmapTrackingManager: any | null = null;\n // Session tracking\n private sessionStartTime: number = Date.now();\n private sessionEventCount: number = 0;\n // Debug mode properties\n private debugAgent: any | null = null;\n private isDebugMode: boolean = false;\n\n constructor(config: GrainConfig) {\n this.config = {\n apiUrl: 'https://api.grainql.com',\n authStrategy: 'NONE',\n batchSize: 50,\n flushInterval: 5000, // 5 seconds\n retryAttempts: 3,\n retryDelay: 1000, // 1 second\n maxEventsPerRequest: 160, // Maximum events per API request\n debug: false,\n // Remote Config defaults\n defaultConfigurations: {},\n configCacheKey: 'grain_config',\n configRefreshInterval: 300000, // 5 minutes\n enableConfigCache: true,\n // Privacy defaults (v2.0)\n consentMode: 'COOKIELESS', // Default: privacy-first, no permanent tracking\n waitForConsent: false,\n disableAutoProperties: false,\n // Automatic Tracking defaults\n enableHeartbeat: true,\n heartbeatActiveInterval: 120000, // 2 minutes\n heartbeatInactiveInterval: 300000, // 5 minutes\n enableAutoPageView: true,\n stripQueryParams: true, // Privacy-first: strip by default\n stripHash: false,\n // Heatmap Tracking defaults\n enableHeatmapTracking: true,\n ...config,\n tenantId: config.tenantId,\n };\n\n // Initialize consent manager (v2.0)\n this.consentManager = new ConsentManager(this.config.tenantId, this.config.consentMode);\n\n // Initialize ID manager (v2.0)\n const idMode: IdMode = this.consentManager.getIdMode();\n this.idManager = new IdManager({\n mode: idMode,\n tenantId: this.config.tenantId,\n useLocalStorage: true, // For permanent IDs when consented\n });\n\n // Set global userId if provided in config\n if (config.userId) {\n this.globalUserId = config.userId;\n }\n\n this.validateConfig();\n // Deprecated: initializePersistentAnonymousUserId() - now handled by IdManager\n this.setupBeforeUnload();\n this.startFlushTimer();\n this.initializeConfigCache();\n\n // Initialize ephemeral session ID (memory-only, not persisted)\n this.ephemeralSessionId = this.generateUUID();\n\n // Initialize automatic tracking (browser only)\n if (typeof window !== 'undefined') {\n // Check for debug mode before initializing tracking\n this.checkAndInitializeDebugMode();\n \n this.initializeAutomaticTracking();\n // Track session start\n this.trackSessionStart();\n // Initialize heatmap tracking if enabled\n if (this.config.enableHeatmapTracking) {\n this.initializeHeatmapTracking();\n }\n }\n\n // Set up consent change listener to sync IdManager and flush waiting events (v2.0)\n this.consentManager.addListener((state) => {\n // Sync IdManager with consent state\n const idMode = this.consentManager.getIdMode();\n this.idManager.setMode(idMode);\n \n if (state.granted) {\n this.handleConsentGranted();\n }\n });\n }\n\n private validateConfig(): void {\n if (!this.config.tenantId) {\n throw new Error('Grain Analytics: tenantId is required');\n }\n\n if (this.config.authStrategy === 'SERVER_SIDE' && !this.config.secretKey) {\n throw new Error('Grain Analytics: secretKey is required for SERVER_SIDE auth strategy');\n }\n\n if (this.config.authStrategy === 'JWT' && !this.config.authProvider) {\n throw new Error('Grain Analytics: authProvider is required for JWT auth strategy');\n }\n }\n\n /**\n * Generate a UUID v4 string\n */\n private generateUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n \n // Fallback for environments without crypto.randomUUID\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n const r = Math.random() * 16 | 0;\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n }\n\n /**\n * Check if we should allow persistent storage (GDPR compliance)\n * \n * Returns true if:\n * - Consent has been granted, OR\n * - Not in opt-in mode, OR\n * - User has been explicitly identified by the site (login/identify), OR\n * - Using JWT auth strategy (functional/essential purpose)\n */\n private shouldAllowPersistentStorage(): boolean {\n const hasConsent = this.consentManager.hasConsent('analytics');\n const isCookieless = this.config.consentMode === 'COOKIELESS';\n const userExplicitlyIdentified = !!this.globalUserId;\n const isJWTAuth = this.config.authStrategy === 'JWT';\n \n // Never allow persistent storage in cookieless mode\n if (isCookieless) return false;\n \n // Allow persistent storage if any of these conditions are met\n return hasConsent || userExplicitlyIdentified || isJWTAuth;\n }\n\n /**\n * Generate a proper UUIDv4 identifier for anonymous user ID\n */\n private generateAnonymousUserId(): string {\n return this.generateUUID();\n }\n\n /**\n * Initialize persistent anonymous user ID from cookies or localStorage\n * Priority: Cookie \u2192 localStorage \u2192 generate new\n * \n * GDPR Compliance: In opt-in mode without consent, we skip loading/saving\n * persistent IDs unless the user has been explicitly identified by the site\n * or when using JWT auth (functional/essential purpose)\n */\n private initializePersistentAnonymousUserId(): void {\n if (typeof window === 'undefined') return;\n\n // Check if we should avoid persistent storage (GDPR compliance)\n if (!this.shouldAllowPersistentStorage()) {\n this.log('Opt-in mode without consent: skipping persistent ID initialization (GDPR compliance)');\n return; // Don't load or create persistent ID\n }\n\n const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;\n const cookieName = '_grain_uid';\n \n try {\n // Try to load from cookie first if enabled\n if (this.cookiesEnabled) {\n const cookieValue = getCookie(cookieName);\n if (cookieValue) {\n this.persistentAnonymousUserId = cookieValue;\n this.log('Loaded persistent anonymous user ID from cookie:', this.persistentAnonymousUserId);\n return;\n }\n }\n\n // Fallback to localStorage\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n this.persistentAnonymousUserId = stored;\n this.log('Loaded persistent anonymous user ID from localStorage:', this.persistentAnonymousUserId);\n \n // Migrate to cookie if enabled\n if (this.cookiesEnabled) {\n this.savePersistentAnonymousUserId(stored);\n }\n } else {\n // Generate new UUIDv4 anonymous user ID\n this.persistentAnonymousUserId = this.generateAnonymousUserId();\n this.savePersistentAnonymousUserId(this.persistentAnonymousUserId);\n this.log('Generated new persistent anonymous user ID:', this.persistentAnonymousUserId);\n }\n } catch (error) {\n this.log('Failed to initialize persistent anonymous user ID:', error);\n // Fallback: generate temporary ID without persistence\n this.persistentAnonymousUserId = this.generateAnonymousUserId();\n }\n }\n\n /**\n * Save persistent anonymous user ID to cookie and/or localStorage\n * \n * GDPR Compliance: In opt-in mode without consent, we don't persist IDs\n * unless the user has been explicitly identified or using JWT auth\n */\n private savePersistentAnonymousUserId(userId: string): void {\n if (typeof window === 'undefined') return;\n\n // Check if we should avoid persistent storage (GDPR compliance)\n if (!this.shouldAllowPersistentStorage()) {\n this.log('Opt-in mode without consent: skipping persistent ID save (GDPR compliance)');\n return; // Don't save persistent ID\n }\n\n const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;\n const cookieName = '_grain_uid';\n\n try {\n // Save to cookie if enabled\n if (this.cookiesEnabled) {\n const cookieOptions: CookieConfig = {\n maxAge: 365 * 24 * 60 * 60, // 365 days\n sameSite: 'lax',\n secure: typeof window !== 'undefined' && window.location.protocol === 'https:',\n ...this.config.cookieOptions,\n };\n setCookie(cookieName, userId, cookieOptions);\n }\n\n // Always save to localStorage as fallback\n localStorage.setItem(storageKey, userId);\n } catch (error) {\n this.log('Failed to save persistent anonymous user ID:', error);\n }\n }\n\n /**\n * Get the effective user ID (v2.0)\n * \n * Privacy-first implementation:\n * - Returns global userId if explicitly set (via identify/login)\n * - Otherwise uses IdManager to generate:\n * - Daily rotating ID (cookieless mode)\n * - Permanent ID (with consent)\n */\n private getEffectiveUserIdInternal(): string {\n // Explicit user identification always takes precedence\n if (this.globalUserId) {\n return this.globalUserId;\n }\n \n // Use IdManager to generate appropriate ID based on consent\n return this.idManager.getCurrentUserId();\n }\n\n log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[Grain Analytics]', ...args);\n }\n }\n\n /**\n * Create error digest from events\n */\n private createErrorDigest(events: EventPayload[]): ErrorDigest {\n const eventNames = [...new Set(events.map(e => e.eventName))];\n const userIds = [...new Set(events.map(e => e.userId))];\n \n let totalProperties = 0;\n let totalSize = 0;\n \n events.forEach(event => {\n const properties = event.properties || {};\n totalProperties += Object.keys(properties).length;\n totalSize += JSON.stringify(event).length;\n });\n\n return {\n eventCount: events.length,\n totalProperties,\n totalSize,\n eventNames,\n userIds,\n };\n }\n\n /**\n * Format error with beautiful structure\n */\n private formatError(\n error: unknown,\n context: string,\n events?: EventPayload[]\n ): FormattedError {\n const digest = events ? this.createErrorDigest(events) : {\n eventCount: 0,\n totalProperties: 0,\n totalSize: 0,\n eventNames: [],\n userIds: [],\n };\n\n let code = 'UNKNOWN_ERROR';\n let message = 'An unknown error occurred';\n\n if (error instanceof Error) {\n message = error.message;\n \n // Determine error code based on error type and message\n if (message.includes('fetch failed') || message.includes('network error')) {\n code = 'NETWORK_ERROR';\n } else if (message.includes('timeout')) {\n code = 'TIMEOUT_ERROR';\n } else if (message.includes('HTTP 4')) {\n code = 'CLIENT_ERROR';\n } else if (message.includes('HTTP 5')) {\n code = 'SERVER_ERROR';\n } else if (message.includes('JSON')) {\n code = 'PARSE_ERROR';\n } else if (message.includes('auth') || message.includes('unauthorized')) {\n code = 'AUTH_ERROR';\n } else if (message.includes('rate limit') || message.includes('429')) {\n code = 'RATE_LIMIT_ERROR';\n } else {\n code = 'GENERAL_ERROR';\n }\n } else if (typeof error === 'string') {\n message = error;\n code = 'STRING_ERROR';\n } else if (error && typeof error === 'object' && 'status' in error) {\n const status = (error as { status: number }).status;\n code = `HTTP_${status}`;\n message = `HTTP ${status} error`;\n }\n\n return {\n code,\n message,\n digest,\n timestamp: new Date().toISOString(),\n context,\n originalError: error,\n };\n }\n\n /**\n * Log formatted error gracefully\n */\n private logError(formattedError: FormattedError): void {\n // Only log errors in debug mode to reduce noise in production\n if (!this.config.debug) return;\n \n const { code, message, digest, timestamp, context } = formattedError;\n \n const errorOutput = {\n '\uD83D\uDEA8 Grain Analytics Error': {\n 'Error Code': code,\n 'Message': message,\n 'Context': context,\n 'Timestamp': timestamp,\n 'Event Digest': {\n 'Events': digest.eventCount,\n 'Properties': digest.totalProperties,\n 'Size (bytes)': digest.totalSize,\n 'Event Names': digest.eventNames.length > 0 ? digest.eventNames.join(', ') : 'None',\n 'User IDs': digest.userIds.length > 0 ? digest.userIds.slice(0, 3).join(', ') + (digest.userIds.length > 3 ? '...' : '') : 'None',\n }\n }\n };\n\n console.error('\uD83D\uDEA8 Grain Analytics Error:', errorOutput);\n console.error(`[Grain Analytics] ${code}: ${message} (${context}) - Events: ${digest.eventCount}, Props: ${digest.totalProperties}, Size: ${digest.totalSize}B`);\n }\n\n /**\n * Safely execute a function with error handling\n */\n private async safeExecute<T>(\n fn: () => Promise<T>,\n context: string,\n events?: EventPayload[]\n ): Promise<T | null> {\n try {\n return await fn();\n } catch (error) {\n const formattedError = this.formatError(error, context, events);\n this.logError(formattedError);\n return null;\n }\n }\n\n private formatEvent(event: GrainEvent): EventPayload {\n const properties = event.properties || {};\n \n // Auto-enrich events with session-level attribution properties\n // This ensures UTM parameters and attribution data are available on ALL events, not just page_view\n if (!this.config.disableAutoProperties && typeof window !== 'undefined') {\n const hasConsent = this.consentManager.hasConsent('analytics');\n \n // Only enrich if not a system event (they handle their own properties)\n const isSystemEvent = event.eventName.startsWith('_grain_');\n \n if (!isSystemEvent && hasConsent) {\n // Get session UTM parameters\n const sessionUTMs = getSessionUTMParameters();\n if (sessionUTMs) {\n if (sessionUTMs.utm_source) properties.utm_source = sessionUTMs.utm_source;\n if (sessionUTMs.utm_medium) properties.utm_medium = sessionUTMs.utm_medium;\n if (sessionUTMs.utm_campaign) properties.utm_campaign = sessionUTMs.utm_campaign;\n if (sessionUTMs.utm_term) properties.utm_term = sessionUTMs.utm_term;\n if (sessionUTMs.utm_content) properties.utm_content = sessionUTMs.utm_content;\n }\n \n // Get first-touch attribution\n const firstTouch = getFirstTouchAttribution(this.config.tenantId);\n if (firstTouch) {\n properties.first_touch_source = firstTouch.source;\n properties.first_touch_medium = firstTouch.medium;\n properties.first_touch_campaign = firstTouch.campaign;\n properties.first_touch_referrer_category = firstTouch.referrer_category;\n }\n \n // Add session ID if not already present\n if (!properties.session_id) {\n properties.session_id = this.getSessionId();\n }\n }\n }\n \n return {\n eventName: event.eventName,\n userId: event.userId || this.getEffectiveUserIdInternal(),\n properties,\n };\n }\n\n private async getAuthHeaders(): Promise<Record<string, string>> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n switch (this.config.authStrategy) {\n case 'NONE':\n break;\n case 'SERVER_SIDE':\n headers['Authorization'] = `Chase ${this.config.secretKey}`;\n break;\n case 'JWT':\n if (this.config.authProvider) {\n const token = await this.config.authProvider.getToken();\n headers['Authorization'] = `Bearer ${token}`;\n }\n break;\n }\n\n return headers;\n }\n\n private async delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n private isRetriableError(error: unknown): boolean {\n if (error instanceof Error) {\n // Check for specific network or fetch errors\n const message = error.message.toLowerCase();\n if (message.includes('fetch failed')) return true;\n if (message === 'network error') return true; // Exact match to avoid \"Non-network error\"\n if (message.includes('timeout')) return true;\n if (message.includes('connection')) return true;\n }\n \n // Check for HTTP status codes that are retriable\n if (typeof error === 'object' && error !== null && 'status' in error) {\n const status = (error as { status: number }).status;\n return status >= 500 || status === 429; // Server errors or rate limiting\n }\n \n return false;\n }\n\n private async sendEvents(events: EventPayload[]): Promise<void> {\n if (events.length === 0) return;\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= this.config.retryAttempts; attempt++) {\n try {\n const headers = await this.getAuthHeaders();\n const url = `${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(events),\n });\n\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}`;\n try {\n const errorBody = await response.json();\n if (errorBody?.message) {\n errorMessage = errorBody.message;\n }\n } catch {\n const errorText = await response.text();\n if (errorText) {\n errorMessage = errorText;\n }\n }\n \n const error = new Error(`Failed to send events: ${errorMessage}`) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n this.log(`Successfully sent ${events.length} events`);\n return; // Success, exit retry loop\n \n } catch (error) {\n lastError = error;\n \n if (attempt === this.config.retryAttempts) {\n // Last attempt, don't retry - log error gracefully\n const formattedError = this.formatError(error, `sendEvents (attempt ${attempt + 1}/${this.config.retryAttempts + 1})`, events);\n this.logError(formattedError);\n return; // Don't throw, just return gracefully\n }\n \n if (!this.isRetriableError(error)) {\n // Non-retriable error, don't retry - log error gracefully\n const formattedError = this.formatError(error, `sendEvents (non-retriable error)`, events);\n this.logError(formattedError);\n return; // Don't throw, just return gracefully\n }\n \n const delayMs = this.config.retryDelay * Math.pow(2, attempt); // Exponential backoff\n this.log(`Retrying in ${delayMs}ms after error:`, error);\n await this.delay(delayMs);\n }\n }\n }\n\n private async sendEventsWithBeacon(events: EventPayload[]): Promise<void> {\n if (events.length === 0) return;\n\n try {\n const headers = await this.getAuthHeaders();\n const url = `${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`;\n\n // Send events array directly (not wrapped in object) to match API expectation\n const body = JSON.stringify(events);\n\n // Beacon API doesn't support custom headers, so only use it for unauthenticated requests\n const needsAuth = this.config.authStrategy !== 'NONE';\n\n // Try beacon API first (more reliable for page unload, but only if no auth needed)\n if (!needsAuth && typeof navigator !== 'undefined' && 'sendBeacon' in navigator) {\n const blob = new Blob([body], { type: 'application/json' });\n const success = navigator.sendBeacon(url, blob);\n \n if (success) {\n this.log(`Successfully sent ${events.length} events via beacon`);\n return;\n }\n }\n\n // Use fetch with keepalive (supports headers and works during page unload)\n await fetch(url, {\n method: 'POST',\n headers,\n body,\n keepalive: true,\n });\n } catch (error) {\n // Log error gracefully for beacon failures (page unload scenarios)\n const formattedError = this.formatError(error, 'sendEventsWithBeacon', events);\n this.logError(formattedError);\n }\n }\n\n private startFlushTimer(): void {\n if (typeof window === 'undefined') return;\n \n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n }\n\n this.flushTimer = window.setInterval(() => {\n if (this.eventQueue.length > 0) {\n this.flush().catch((error) => {\n const formattedError = this.formatError(error, 'auto-flush');\n this.logError(formattedError);\n });\n }\n }, this.config.flushInterval);\n }\n\n private setupBeforeUnload(): void {\n if (typeof window === 'undefined') return;\n\n const handleBeforeUnload = () => {\n // Track session end\n this.trackSessionEnd();\n \n if (this.eventQueue.length > 0) {\n // Use beacon API for reliable delivery during page unload\n const eventsToSend = [...this.eventQueue];\n this.eventQueue = [];\n \n const chunks = this.chunkEvents(eventsToSend, this.config.maxEventsPerRequest);\n \n // Send first chunk with beacon (most important for page unload)\n if (chunks.length > 0) {\n this.sendEventsWithBeacon(chunks[0]).catch(() => {\n // Silently fail - page is unloading\n });\n }\n }\n };\n\n // Handle page unload\n window.addEventListener('beforeunload', handleBeforeUnload);\n window.addEventListener('pagehide', handleBeforeUnload);\n \n // Handle visibility change (page hidden)\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden' && this.eventQueue.length > 0) {\n const eventsToSend = [...this.eventQueue];\n this.eventQueue = [];\n \n const chunks = this.chunkEvents(eventsToSend, this.config.maxEventsPerRequest);\n \n // Send first chunk with beacon (most important for page hidden)\n if (chunks.length > 0) {\n this.sendEventsWithBeacon(chunks[0]).catch(() => {\n // Silently fail\n });\n }\n }\n });\n }\n\n /**\n * Initialize automatic tracking (heartbeat and page views)\n */\n private initializeAutomaticTracking(): void {\n if (this.config.enableHeartbeat) {\n try {\n this.activityDetector = new ActivityDetector();\n this.heartbeatManager = new HeartbeatManager(\n this,\n this.activityDetector,\n {\n activeInterval: this.config.heartbeatActiveInterval,\n inactiveInterval: this.config.heartbeatInactiveInterval,\n debug: this.config.debug,\n }\n );\n } catch (error) {\n this.log('Failed to initialize heartbeat tracking:', error);\n }\n }\n\n if (this.config.enableAutoPageView) {\n try {\n this.pageTrackingManager = new PageTrackingManager(\n this,\n {\n stripQueryParams: this.config.stripQueryParams,\n stripHash: this.config.stripHash,\n debug: this.config.debug,\n tenantId: this.config.tenantId,\n }\n );\n } catch (error) {\n this.log('Failed to initialize page view tracking:', error);\n }\n }\n\n // Initialize auto-tracking when config is available\n this.initializeAutoTracking();\n }\n\n /**\n * Initialize heatmap tracking\n */\n private initializeHeatmapTracking(): void {\n if (typeof window === 'undefined') return;\n \n try {\n this.log('Initializing heatmap tracking');\n \n import('./heatmap-tracking').then(({ HeatmapTrackingManager }) => {\n try {\n this.heatmapTrackingManager = new HeatmapTrackingManager(\n this,\n {\n scrollDebounceDelay: 100,\n batchDelay: 2000,\n maxBatchSize: 20,\n debug: this.config.debug,\n }\n );\n this.log('Heatmap tracking initialized');\n } catch (error) {\n this.log('Failed to initialize heatmap tracking:', error);\n }\n }).catch((error) => {\n this.log('Failed to load heatmap tracking module:', error);\n });\n } catch (error) {\n this.log('Failed to initialize heatmap tracking:', error);\n }\n }\n\n /**\n * Initialize auto-tracking (interactions and sections)\n */\n private async initializeAutoTracking(): Promise<void> {\n try {\n this.log('Initializing auto-tracking');\n \n // Fetch remote config to get auto-tracking configuration\n const userId = this.globalUserId || this.persistentAnonymousUserId || this.generateUUID();\n const currentUrl = typeof window !== 'undefined' ? window.location.href : '';\n \n // Fetch config with currentUrl\n const request: RemoteConfigRequest = {\n userId,\n immediateKeys: [],\n properties: {},\n currentUrl, // Add current URL to request\n };\n\n const headers = await this.getAuthHeaders();\n const url = `${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n this.log('Failed to fetch auto-tracking config:', response.status);\n return;\n }\n\n const configResponse: RemoteConfigResponse = await response.json();\n \n if (configResponse.autoTrackingConfig) {\n this.log('Auto-tracking config loaded');\n this.setupAutoTrackingManagers(configResponse.autoTrackingConfig);\n }\n } catch (error) {\n this.log('Failed to initialize auto-tracking:', error);\n // Fail silently - auto-tracking is optional\n }\n }\n\n /**\n * Setup auto-tracking managers\n */\n private setupAutoTrackingManagers(config: NonNullable<RemoteConfigResponse['autoTrackingConfig']>): void {\n this.log('Setting up auto-tracking managers');\n \n // Lazy load the managers to avoid bundling them if not needed\n if (config.interactions && config.interactions.length > 0) {\n this.log('Loading interaction tracking:', config.interactions.length, 'interactions');\n import('./interaction-tracking').then(({ InteractionTrackingManager }) => {\n try {\n this.interactionTrackingManager = new InteractionTrackingManager(\n this,\n config.interactions,\n {\n debug: this.config.debug,\n enableMutationObserver: true,\n mutationDebounceDelay: 500,\n tenantId: this.config.tenantId,\n apiUrl: this.config.apiUrl,\n }\n );\n this.log('Interaction tracking initialized');\n } catch (error) {\n this.log('Failed to initialize interaction tracking:', error);\n }\n }).catch((error) => {\n this.log('Failed to load interaction tracking module:', error);\n });\n }\n\n if (config.sections && config.sections.length > 0) {\n this.log('Loading section tracking:', config.sections.length, 'sections');\n import('./section-tracking').then(({ SectionTrackingManager }) => {\n try {\n this.sectionTrackingManager = new SectionTrackingManager(\n this,\n config.sections,\n {\n minDwellTime: 1000,\n scrollVelocityThreshold: 500,\n intersectionThreshold: 0.1,\n debounceDelay: 100,\n batchDelay: 2000,\n debug: this.config.debug,\n }\n );\n this.log('Section tracking initialized');\n } catch (error) {\n this.log('Failed to initialize section tracking:', error);\n }\n }).catch((error) => {\n this.log('Failed to load section tracking module:', error);\n });\n }\n }\n\n /**\n * Track session start event\n */\n private trackSessionStart(): void {\n if (typeof window === 'undefined') return;\n\n const hasConsent = this.consentManager.hasConsent('analytics');\n \n const properties: Record<string, unknown> = {\n session_id: this.getSessionId(),\n timestamp: this.sessionStartTime,\n };\n\n if (hasConsent) {\n const referrer = document.referrer || '';\n const currentUrl = window.location.href;\n \n // Parse UTM parameters\n const utmParams = parseUTMParameters(currentUrl);\n const sessionUTMs = getSessionUTMParameters() || utmParams;\n \n // Get first-touch attribution\n const firstTouch = getOrCreateFirstTouchAttribution(\n this.config.tenantId,\n referrer,\n currentUrl,\n sessionUTMs\n );\n\n // Landing page\n properties.landing_page = window.location.pathname;\n \n // Referrer info\n if (referrer) {\n properties.referrer = referrer;\n properties.referrer_domain = new URL(referrer).hostname;\n properties.referrer_category = categorizeReferrer(referrer, currentUrl);\n } else {\n properties.referrer_category = 'direct';\n }\n\n // UTM parameters\n if (sessionUTMs.utm_source) properties.utm_source = sessionUTMs.utm_source;\n if (sessionUTMs.utm_medium) properties.utm_medium = sessionUTMs.utm_medium;\n if (sessionUTMs.utm_campaign) properties.utm_campaign = sessionUTMs.utm_campaign;\n if (sessionUTMs.utm_term) properties.utm_term = sessionUTMs.utm_term;\n if (sessionUTMs.utm_content) properties.utm_content = sessionUTMs.utm_content;\n\n // First-touch attribution\n properties.first_touch_source = firstTouch.source;\n properties.first_touch_medium = firstTouch.medium;\n properties.first_touch_campaign = firstTouch.campaign;\n properties.first_touch_referrer_category = firstTouch.referrer_category;\n\n // Device and browser info\n properties.device = this.getDeviceType();\n properties.screen_resolution = `${screen.width}x${screen.height}`;\n properties.viewport = `${window.innerWidth}x${window.innerHeight}`;\n properties.browser = this.getBrowser();\n properties.os = this.getOS();\n properties.language = navigator.language || '';\n properties.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n }\n\n this.trackSystemEvent('_grain_session_start', properties);\n this.log('Session started');\n }\n\n /**\n * Track session end event\n */\n private trackSessionEnd(): void {\n if (typeof window === 'undefined') return;\n\n const hasConsent = this.consentManager.hasConsent('analytics');\n const sessionDuration = Date.now() - this.sessionStartTime;\n \n const properties: Record<string, unknown> = {\n session_id: this.getSessionId(),\n session_duration: Math.floor(sessionDuration / 1000), // In seconds for easier querying\n duration: sessionDuration, // Keep for backward compatibility\n event_count: this.sessionEventCount,\n timestamp: Date.now(),\n };\n\n if (hasConsent && this.pageTrackingManager) {\n const pageCount = this.pageTrackingManager.getPageViewCount();\n properties.pages_per_session = pageCount;\n properties.page_count = pageCount; // Keep for backward compatibility\n }\n\n this.trackSystemEvent('_grain_session_end', properties);\n this.log('Session ended');\n }\n\n /**\n * Detect browser name\n */\n private getBrowser(): string {\n if (typeof navigator === 'undefined') return 'Unknown';\n const ua = navigator.userAgent;\n if (ua.includes('Firefox/')) return 'Firefox';\n if (ua.includes('Edg/')) return 'Edge';\n if (ua.includes('Chrome/')) return 'Chrome';\n if (ua.includes('Safari/') && !ua.includes('Chrome/')) return 'Safari';\n if (ua.includes('Opera/') || ua.includes('OPR/')) return 'Opera';\n return 'Unknown';\n }\n\n /**\n * Detect operating system\n */\n private getOS(): string {\n if (typeof navigator === 'undefined') return 'Unknown';\n const ua = navigator.userAgent;\n if (ua.includes('Win')) return 'Windows';\n if (ua.includes('Mac')) return 'macOS';\n if (ua.includes('Linux')) return 'Linux';\n if (ua.includes('Android')) return 'Android';\n if (ua.includes('iOS') || ua.includes('iPhone') || ua.includes('iPad')) return 'iOS';\n return 'Unknown';\n }\n\n /**\n * Detect device type (Mobile, Tablet, Desktop)\n */\n private getDeviceType(): string {\n if (typeof window === 'undefined' || typeof navigator === 'undefined') return 'Unknown';\n \n const ua = navigator.userAgent;\n const width = window.innerWidth;\n \n // Check for tablet-specific indicators\n if (ua.includes('iPad') || (ua.includes('Android') && !ua.includes('Mobile'))) {\n return 'Tablet';\n }\n \n // Check for mobile indicators\n if (ua.includes('Mobile') || ua.includes('iPhone') || ua.includes('Android')) {\n return 'Mobile';\n }\n \n // Fallback to screen width detection\n if (width < 768) {\n return 'Mobile';\n } else if (width >= 768 && width < 1024) {\n return 'Tablet';\n }\n \n return 'Desktop';\n }\n\n /**\n * Handle consent granted - upgrade ephemeral session to persistent user\n */\n private handleConsentGranted(): void {\n this.flushWaitingForConsentQueue();\n\n // Initialize persistent ID now that consent is granted (if not already initialized)\n if (!this.persistentAnonymousUserId) {\n this.initializePersistentAnonymousUserId();\n this.log('Initialized persistent ID after consent grant');\n }\n\n // Track consent granted event with mapping from ephemeral to persistent ID\n if (this.ephemeralSessionId) {\n this.trackSystemEvent('_grain_consent_granted', {\n previous_session_id: this.ephemeralSessionId,\n new_user_id: this.getEffectiveUserId(),\n timestamp: Date.now(),\n });\n }\n }\n\n /**\n * Track system events that bypass consent checks (for necessary/functional tracking)\n */\n trackSystemEvent(eventName: string, properties: Record<string, unknown>): void {\n if (this.isDestroyed) return;\n\n const hasConsent = this.consentManager.hasConsent('analytics');\n\n // Create event with appropriate user ID\n // v2.0: Always use IdManager which returns daily rotating ID or permanent ID based on consent\n const event: EventPayload = {\n eventName,\n userId: this.getEffectiveUserId(), // IdManager handles daily vs permanent based on consent\n properties: {\n ...properties,\n _minimal: !hasConsent, // Flag to indicate minimal tracking (daily rotating ID)\n _consent_status: hasConsent ? 'granted' : 'pending',\n },\n };\n\n // Bypass consent check for necessary system events\n this.eventQueue.push(event);\n this.eventCountSinceLastHeartbeat++;\n\n this.log(`Queued system event: ${eventName}`);\n\n // Consider flushing\n if (this.eventQueue.length >= this.config.batchSize) {\n this.flush().catch((error) => {\n const formattedError = this.formatError(error, 'flush system event');\n this.logError(formattedError);\n });\n }\n }\n\n /**\n * Get ephemeral session ID (memory-only, not persisted)\n */\n getEphemeralSessionId(): string {\n if (!this.ephemeralSessionId) {\n this.ephemeralSessionId = this.generateUUID();\n }\n return this.ephemeralSessionId;\n }\n\n /**\n * Get the current page path from page tracker\n */\n getCurrentPage(): string | null {\n return this.pageTrackingManager?.getCurrentPage() || null;\n }\n\n /**\n * Get event count since last heartbeat\n */\n getEventCountSinceLastHeartbeat(): number {\n return this.eventCountSinceLastHeartbeat;\n }\n\n /**\n * Reset event count since last heartbeat\n */\n resetEventCountSinceLastHeartbeat(): void {\n this.eventCountSinceLastHeartbeat = 0;\n }\n\n /**\n * Get the activity detector (for internal use by tracking managers)\n */\n getActivityDetector(): ActivityDetector {\n if (!this.activityDetector) {\n throw new Error('Activity detector not initialized');\n }\n return this.activityDetector;\n }\n\n /**\n * Get the effective user ID (public method)\n */\n getEffectiveUserId(): string {\n return this.getEffectiveUserIdInternal();\n }\n\n /**\n * Get the session ID (ephemeral or persistent based on consent)\n */\n getSessionId(): string {\n const hasConsent = this.consentManager.hasConsent('analytics');\n return hasConsent ? this.getEffectiveUserId() : this.getEphemeralSessionId();\n }\n\n /**\n * Track an analytics event\n */\n async track(eventName: string, properties?: Record<string, unknown>, options?: SendEventOptions): Promise<void>;\n async track(event: GrainEvent, options?: SendEventOptions): Promise<void>;\n async track(\n eventOrName: string | GrainEvent,\n propertiesOrOptions?: Record<string, unknown> | SendEventOptions,\n options?: SendEventOptions\n ): Promise<void> {\n try {\n if (this.isDestroyed) {\n const error = new Error('Grain Analytics: Client has been destroyed');\n const formattedError = this.formatError(error, 'track (client destroyed)');\n this.logError(formattedError);\n return;\n }\n\n let event: GrainEvent;\n let opts: SendEventOptions = {};\n\n if (typeof eventOrName === 'string') {\n event = {\n eventName: eventOrName,\n properties: propertiesOrOptions as Record<string, unknown>,\n };\n opts = options || {};\n } else {\n event = eventOrName;\n opts = propertiesOrOptions as SendEventOptions || {};\n }\n\n // Filter properties if whitelist is enabled\n if (this.config.allowedProperties && event.properties) {\n const filtered: Record<string, unknown> = {};\n for (const key of this.config.allowedProperties) {\n if (key in event.properties) {\n filtered[key] = event.properties[key];\n }\n }\n event.properties = filtered;\n }\n\n const formattedEvent = this.formatEvent(event);\n\n // Check if we should wait for consent (only if explicitly configured)\n if (this.consentManager.shouldWaitForConsent() && this.config.waitForConsent) {\n // Queue event until consent is granted\n this.waitingForConsentQueue.push(formattedEvent);\n this.log(`Event waiting for consent: ${event.eventName}`, event.properties);\n return;\n }\n\n // v2.0: GDPR Strict falls back to cookieless mode (daily rotating IDs)\n // Events are never blocked - IdManager already provides correct ID (daily or permanent)\n const hasConsent = this.consentManager.hasConsent('analytics');\n \n // Add tracking flags to indicate consent status\n formattedEvent.properties = {\n ...formattedEvent.properties,\n _minimal: !hasConsent, // Flag: true = daily rotating ID, false = permanent ID\n _consent_status: hasConsent ? 'granted' : 'pending',\n };\n\n this.eventQueue.push(formattedEvent);\n this.eventCountSinceLastHeartbeat++;\n this.sessionEventCount++;\n this.log(`Queued event: ${event.eventName}`);\n\n // Check if we should flush immediately\n if (opts.flush || this.eventQueue.length >= this.config.batchSize) {\n await this.flush();\n }\n } catch (error) {\n const formattedError = this.formatError(error, 'track');\n this.logError(formattedError);\n }\n }\n\n /**\n * Flush events that were waiting for consent\n */\n private flushWaitingForConsentQueue(): void {\n if (this.waitingForConsentQueue.length === 0) return;\n\n this.log(`Flushing ${this.waitingForConsentQueue.length} events waiting for consent`);\n \n // Move waiting events to main queue\n this.eventQueue.push(...this.waitingForConsentQueue);\n this.waitingForConsentQueue = [];\n\n // Flush immediately\n this.flush().catch((error) => {\n const formattedError = this.formatError(error, 'flush waiting for consent queue');\n this.logError(formattedError);\n });\n }\n\n /**\n * Identify a user (sets userId for subsequent events)\n */\n identify(userId: string): void {\n this.log(`Identified user: ${userId}`);\n this.globalUserId = userId;\n // Clear persistent anonymous user ID since we now have a real user ID\n this.persistentAnonymousUserId = null;\n }\n\n /**\n * Set global user ID for all subsequent events\n */\n setUserId(userId: string | null): void {\n this.log(`Set global user ID: ${userId}`);\n this.globalUserId = userId;\n \n if (userId) {\n // Clear persistent anonymous user ID if setting a real user ID\n this.persistentAnonymousUserId = null;\n } else {\n // If clearing user ID, ensure we have an identifier\n if (!this.persistentAnonymousUserId) {\n this.persistentAnonymousUserId = this.generateAnonymousUserId();\n \n // Try to persist the new anonymous ID (respects GDPR opt-in mode)\n this.savePersistentAnonymousUserId(this.persistentAnonymousUserId);\n }\n }\n }\n\n /**\n * Get current global user ID\n */\n getUserId(): string | null {\n return this.globalUserId;\n }\n\n /**\n * Get current effective user ID (global userId or persistent anonymous ID)\n */\n getEffectiveUserIdPublic(): string {\n return this.getEffectiveUserIdInternal();\n }\n\n /**\n * Login with auth token or userId on the fly\n * \n * @example\n * // Login with userId only\n * client.login({ userId: 'user123' });\n * \n * // Login with auth token (automatically sets authStrategy to JWT)\n * client.login({ authToken: 'jwt-token-here' });\n * \n * // Login with both userId and auth token\n * client.login({ userId: 'user123', authToken: 'jwt-token-here' });\n * \n * // Override auth strategy\n * client.login({ userId: 'user123', authStrategy: 'SERVER_SIDE' });\n */\n login(options: LoginOptions): void {\n try {\n if (this.isDestroyed) {\n const error = new Error('Grain Analytics: Client has been destroyed');\n const formattedError = this.formatError(error, 'login (client destroyed)');\n this.logError(formattedError);\n return;\n }\n\n // Set userId if provided\n if (options.userId) {\n this.log(`Login: Setting user ID to ${options.userId}`);\n this.globalUserId = options.userId;\n // Clear persistent anonymous user ID since we now have a real user ID\n this.persistentAnonymousUserId = null;\n }\n\n // Handle auth token if provided\n if (options.authToken) {\n this.log('Login: Setting auth token');\n // Update auth strategy to JWT if not already set\n if (this.config.authStrategy === 'NONE') {\n this.config.authStrategy = 'JWT';\n }\n \n // Create a simple auth provider that returns the provided token\n this.config.authProvider = {\n getToken: () => options.authToken!\n };\n }\n\n // Override auth strategy if provided\n if (options.authStrategy) {\n this.log(`Login: Setting auth strategy to ${options.authStrategy}`);\n this.config.authStrategy = options.authStrategy;\n }\n\n this.log(`Login successful. Effective user ID: ${this.getEffectiveUserIdInternal()}`);\n } catch (error) {\n const formattedError = this.formatError(error, 'login');\n this.logError(formattedError);\n }\n }\n\n /**\n * Logout and clear user session, fall back to UUIDv4 identifier\n * \n * @example\n * // Logout user and return to anonymous mode\n * client.logout();\n * \n * // After logout, events will use the persistent UUIDv4 identifier\n * client.track('page_view', { page: 'home' });\n */\n logout(): void {\n try {\n if (this.isDestroyed) {\n const error = new Error('Grain Analytics: Client has been destroyed');\n const formattedError = this.formatError(error, 'logout (client destroyed)');\n this.logError(formattedError);\n return;\n }\n\n this.log('Logout: Clearing user session');\n \n // Clear global user ID\n this.globalUserId = null;\n \n // Reset auth strategy to NONE\n this.config.authStrategy = 'NONE';\n this.config.authProvider = undefined;\n \n // Generate new UUIDv4 identifier if we don't have one\n if (!this.persistentAnonymousUserId) {\n this.persistentAnonymousUserId = this.generateAnonymousUserId();\n \n // Try to persist the new anonymous ID\n if (typeof window !== 'undefined') {\n try {\n const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;\n localStorage.setItem(storageKey, this.persistentAnonymousUserId);\n } catch (error) {\n this.log('Failed to persist new anonymous user ID after logout:', error);\n }\n }\n }\n \n this.log(`Logout successful. Effective user ID: ${this.getEffectiveUserIdInternal()}`);\n } catch (error) {\n const formattedError = this.formatError(error, 'logout');\n this.logError(formattedError);\n }\n }\n\n /**\n * Set user properties\n */\n async setProperty(properties: Record<string, unknown>, options?: SetPropertyOptions): Promise<void> {\n try {\n if (this.isDestroyed) {\n const error = new Error('Grain Analytics: Client has been destroyed');\n const formattedError = this.formatError(error, 'setProperty (client destroyed)');\n this.logError(formattedError);\n return;\n }\n\n const userId = options?.userId || this.getEffectiveUserIdInternal();\n \n // Validate property count (max 4 properties)\n const propertyKeys = Object.keys(properties);\n if (propertyKeys.length > 4) {\n const error = new Error('Grain Analytics: Maximum 4 properties allowed per request');\n const formattedError = this.formatError(error, 'setProperty (validation)');\n this.logError(formattedError);\n return;\n }\n\n if (propertyKeys.length === 0) {\n const error = new Error('Grain Analytics: At least one property is required');\n const formattedError = this.formatError(error, 'setProperty (validation)');\n this.logError(formattedError);\n return;\n }\n\n // Serialize all values to strings\n const serializedProperties: Record<string, string> = {};\n for (const [key, value] of Object.entries(properties)) {\n if (value === null || value === undefined) {\n serializedProperties[key] = '';\n } else if (typeof value === 'string') {\n serializedProperties[key] = value;\n } else {\n serializedProperties[key] = JSON.stringify(value);\n }\n }\n\n const payload: PropertyPayload = {\n userId,\n ...serializedProperties,\n };\n\n await this.sendProperties(payload);\n } catch (error) {\n const formattedError = this.formatError(error, 'setProperty');\n this.logError(formattedError);\n }\n }\n\n /**\n * Send properties to the API\n */\n private async sendProperties(payload: PropertyPayload): Promise<void> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= this.config.retryAttempts; attempt++) {\n try {\n const headers = await this.getAuthHeaders();\n const url = `${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/properties`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}`;\n try {\n const errorBody = await response.json();\n if (errorBody?.message) {\n errorMessage = errorBody.message;\n }\n } catch {\n const errorText = await response.text();\n if (errorText) {\n errorMessage = errorText;\n }\n }\n \n const error = new Error(`Failed to set properties: ${errorMessage}`) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n this.log(`Successfully set properties for user ${payload.userId}`);\n return; // Success, exit retry loop\n \n } catch (error) {\n lastError = error;\n \n if (attempt === this.config.retryAttempts) {\n // Last attempt, don't retry - log error gracefully\n const formattedError = this.formatError(error, `sendProperties (attempt ${attempt + 1}/${this.config.retryAttempts + 1})`);\n this.logError(formattedError);\n return; // Don't throw, just return gracefully\n }\n \n if (!this.isRetriableError(error)) {\n // Non-retriable error, don't retry - log error gracefully\n const formattedError = this.formatError(error, 'sendProperties (non-retriable error)');\n this.logError(formattedError);\n return; // Don't throw, just return gracefully\n }\n \n const delayMs = this.config.retryDelay * Math.pow(2, attempt); // Exponential backoff\n this.log(`Retrying in ${delayMs}ms after error:`, error);\n await this.delay(delayMs);\n }\n }\n }\n\n // Template event methods\n\n /**\n * Track user login event\n */\n async trackLogin(properties?: LoginEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('login', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackLogin');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track user signup event\n */\n async trackSignup(properties?: SignupEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('signup', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackSignup');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track checkout event\n */\n async trackCheckout(properties?: CheckoutEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('checkout', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackCheckout');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track page view event\n */\n async trackPageView(properties?: PageViewEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('page_view', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackPageView');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track purchase event\n */\n async trackPurchase(properties?: PurchaseEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('purchase', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackPurchase');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track search event\n */\n async trackSearch(properties?: SearchEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('search', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackSearch');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track add to cart event\n */\n async trackAddToCart(properties?: AddToCartEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('add_to_cart', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackAddToCart');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track remove from cart event\n */\n async trackRemoveFromCart(properties?: RemoveFromCartEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('remove_from_cart', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackRemoveFromCart');\n this.logError(formattedError);\n }\n }\n\n /**\n * Manually flush all queued events\n */\n async flush(): Promise<void> {\n try {\n if (this.eventQueue.length === 0) return;\n\n const eventsToSend = [...this.eventQueue];\n this.eventQueue = [];\n\n // Split events into chunks to respect maxEventsPerRequest limit\n const chunks = this.chunkEvents(eventsToSend, this.config.maxEventsPerRequest);\n \n // Send all chunks sequentially to maintain order\n for (const chunk of chunks) {\n await this.sendEvents(chunk);\n }\n } catch (error) {\n const formattedError = this.formatError(error, 'flush');\n this.logError(formattedError);\n }\n }\n\n // Remote Config Methods\n\n /**\n * Initialize configuration cache from localStorage\n */\n private initializeConfigCache(): void {\n if (!this.config.enableConfigCache || typeof window === 'undefined') return;\n\n try {\n const cached = localStorage.getItem(this.config.configCacheKey);\n if (cached) {\n this.configCache = JSON.parse(cached);\n this.log('Loaded configuration from cache:', this.configCache);\n }\n } catch (error) {\n this.log('Failed to load configuration cache:', error);\n }\n }\n\n /**\n * Save configuration cache to localStorage\n */\n private saveConfigCache(cache: RemoteConfigCache): void {\n if (!this.config.enableConfigCache || typeof window === 'undefined') return;\n\n try {\n localStorage.setItem(this.config.configCacheKey, JSON.stringify(cache));\n this.log('Saved configuration to cache:', cache);\n } catch (error) {\n this.log('Failed to save configuration cache:', error);\n }\n }\n\n /**\n * Get configuration value with fallback to defaults\n */\n getConfig(key: string): string | undefined {\n // First check cache\n if (this.configCache?.configurations?.[key]) {\n return this.configCache.configurations[key];\n }\n\n // Then check defaults\n if (this.config.defaultConfigurations?.[key]) {\n return this.config.defaultConfigurations[key];\n }\n\n return undefined;\n }\n\n /**\n * Get all configurations with fallback to defaults\n */\n getAllConfigs(): Record<string, string> {\n const configs = { ...this.config.defaultConfigurations };\n \n if (this.configCache?.configurations) {\n Object.assign(configs, this.configCache.configurations);\n }\n\n return configs;\n }\n\n /**\n * Fetch configurations from API\n */\n async fetchConfig(options: RemoteConfigOptions = {}): Promise<RemoteConfigResponse | null> {\n try {\n if (this.isDestroyed) {\n const error = new Error('Grain Analytics: Client has been destroyed');\n const formattedError = this.formatError(error, 'fetchConfig (client destroyed)');\n this.logError(formattedError);\n return null;\n }\n\n const userId = options.userId || this.getEffectiveUserIdInternal();\n const immediateKeys = options.immediateKeys || [];\n const properties = options.properties || {};\n\n const request: RemoteConfigRequest = {\n userId,\n immediateKeys,\n properties,\n };\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= this.config.retryAttempts; attempt++) {\n try {\n const headers = await this.getAuthHeaders();\n const url = `${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}`;\n try {\n const errorBody = await response.json();\n if (errorBody?.message) {\n errorMessage = errorBody.message;\n }\n } catch {\n const errorText = await response.text();\n if (errorText) {\n errorMessage = errorText;\n }\n }\n \n const error = new Error(`Failed to fetch configurations: ${errorMessage}`) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n const configResponse: RemoteConfigResponse = await response.json();\n \n // Update cache if successful\n if (configResponse.configurations) {\n this.updateConfigCache(configResponse, userId);\n }\n\n this.log('Successfully fetched configurations');\n return configResponse;\n \n } catch (error) {\n lastError = error;\n \n if (attempt === this.config.retryAttempts) {\n // Last attempt, don't retry - log error gracefully\n const formattedError = this.formatError(error, `fetchConfig (attempt ${attempt + 1}/${this.config.retryAttempts + 1})`);\n this.logError(formattedError);\n return null;\n }\n \n if (!this.isRetriableError(error)) {\n // Non-retriable error, don't retry - log error gracefully\n const formattedError = this.formatError(error, 'fetchConfig (non-retriable error)');\n this.logError(formattedError);\n return null;\n }\n \n const delayMs = this.config.retryDelay * Math.pow(2, attempt);\n this.log(`Retrying config fetch in ${delayMs}ms after error:`, error);\n await this.delay(delayMs);\n }\n }\n\n return null;\n } catch (error) {\n const formattedError = this.formatError(error, 'fetchConfig');\n this.logError(formattedError);\n return null;\n }\n }\n\n /**\n * Get configuration asynchronously (cache-first with fallback to API)\n */\n async getConfigAsync(key: string, options: RemoteConfigOptions = {}): Promise<string | undefined> {\n try {\n // Return immediately if we have it in cache and not forcing refresh\n if (!options.forceRefresh && this.configCache?.configurations?.[key]) {\n return this.configCache.configurations[key];\n }\n\n // Return default if available and not forcing refresh\n if (!options.forceRefresh && this.config.defaultConfigurations?.[key]) {\n return this.config.defaultConfigurations[key];\n }\n\n // Fetch from API\n const response = await this.fetchConfig(options);\n if (response) {\n return response.configurations[key];\n }\n \n // Return default as fallback\n return this.config.defaultConfigurations?.[key];\n } catch (error) {\n const formattedError = this.formatError(error, 'getConfigAsync');\n this.logError(formattedError);\n // Return default as fallback\n return this.config.defaultConfigurations?.[key];\n }\n }\n\n /**\n * Get all configurations asynchronously (cache-first with fallback to API)\n */\n async getAllConfigsAsync(options: RemoteConfigOptions = {}): Promise<Record<string, string>> {\n try {\n // Return cache if available and not forcing refresh\n if (!options.forceRefresh && this.configCache?.configurations) {\n return { ...this.config.defaultConfigurations, ...this.configCache.configurations };\n }\n\n // Fetch from API\n const response = await this.fetchConfig(options);\n if (response) {\n return { ...this.config.defaultConfigurations, ...response.configurations };\n }\n \n // Return defaults as fallback\n return { ...this.config.defaultConfigurations };\n } catch (error) {\n const formattedError = this.formatError(error, 'getAllConfigsAsync');\n this.logError(formattedError);\n // Return defaults as fallback\n return { ...this.config.defaultConfigurations };\n }\n }\n\n /**\n * Update configuration cache and notify listeners\n */\n private updateConfigCache(response: RemoteConfigResponse, userId: string): void {\n const newCache: RemoteConfigCache = {\n configurations: response.configurations,\n snapshotId: response.snapshotId,\n timestamp: response.timestamp,\n userId,\n };\n\n const oldConfigs = this.configCache?.configurations || {};\n this.configCache = newCache;\n this.saveConfigCache(newCache);\n\n // Notify listeners if configurations changed\n if (JSON.stringify(oldConfigs) !== JSON.stringify(response.configurations)) {\n this.notifyConfigChangeListeners(response.configurations);\n }\n }\n\n /**\n * Add configuration change listener\n */\n addConfigChangeListener(listener: ConfigChangeListener): void {\n this.configChangeListeners.push(listener);\n }\n\n /**\n * Remove configuration change listener\n */\n removeConfigChangeListener(listener: ConfigChangeListener): void {\n const index = this.configChangeListeners.indexOf(listener);\n if (index > -1) {\n this.configChangeListeners.splice(index, 1);\n }\n }\n\n /**\n * Notify all configuration change listeners\n */\n private notifyConfigChangeListeners(configurations: Record<string, string>): void {\n this.configChangeListeners.forEach(listener => {\n try {\n listener(configurations);\n } catch (error) {\n console.error('[Grain Analytics] Config change listener error:', error);\n }\n });\n }\n\n /**\n * Start automatic configuration refresh timer\n */\n private startConfigRefreshTimer(): void {\n if (typeof window === 'undefined') return;\n \n if (this.configRefreshTimer) {\n clearInterval(this.configRefreshTimer);\n }\n\n this.configRefreshTimer = window.setInterval(() => {\n if (!this.isDestroyed) {\n // Use effective userId (will be generated if not set)\n this.fetchConfig().catch((error) => {\n const formattedError = this.formatError(error, 'auto-config refresh');\n this.logError(formattedError);\n });\n }\n }, this.config.configRefreshInterval);\n }\n\n /**\n * Stop automatic configuration refresh timer\n */\n private stopConfigRefreshTimer(): void {\n if (this.configRefreshTimer) {\n clearInterval(this.configRefreshTimer);\n this.configRefreshTimer = null;\n }\n }\n\n /**\n * Preload configurations for immediate access\n */\n async preloadConfig(immediateKeys: string[] = [], properties?: Record<string, string>): Promise<void> {\n try {\n // Use effective userId (will be generated if not set)\n const effectiveUserId = this.getEffectiveUserIdInternal();\n this.log(`Preloading config for user: ${effectiveUserId}`);\n\n const response = await this.fetchConfig({ immediateKeys, properties });\n if (response) {\n this.startConfigRefreshTimer();\n }\n } catch (error) {\n const formattedError = this.formatError(error, 'preloadConfig');\n this.logError(formattedError);\n }\n }\n\n /**\n * Split events array into chunks of specified size\n */\n private chunkEvents(events: EventPayload[], chunkSize: number): EventPayload[][] {\n const chunks: EventPayload[][] = [];\n for (let i = 0; i < events.length; i += chunkSize) {\n chunks.push(events.slice(i, i + chunkSize));\n }\n return chunks;\n }\n\n // Privacy & Consent Methods\n\n /**\n * Grant consent for tracking (v2.0)\n * Switches from cookieless mode to permanent IDs\n * @param categories - Optional array of consent categories (e.g., ['analytics', 'functional'])\n */\n grantConsent(categories?: string[]): void {\n try {\n this.consentManager.grantConsent(categories);\n \n // Sync ID manager with consent state\n const idMode = this.consentManager.getIdMode();\n this.idManager.setMode(idMode);\n \n this.log('Consent granted, switched to permanent IDs', categories);\n \n // Process any queued events waiting for consent\n if (this.waitingForConsentQueue.length > 0) {\n this.log(`Processing ${this.waitingForConsentQueue.length} queued events`);\n this.eventQueue.push(...this.waitingForConsentQueue);\n this.waitingForConsentQueue = [];\n this.flush();\n }\n } catch (error) {\n const formattedError = this.formatError(error, 'grantConsent');\n this.logError(formattedError);\n }\n }\n\n /**\n * Revoke consent for tracking (v2.0)\n * Switches from permanent IDs to cookieless mode\n * @param categories - Optional array of categories to revoke (if not provided, revokes all)\n */\n revokeConsent(categories?: string[]): void {\n try {\n this.consentManager.revokeConsent(categories);\n \n // Sync ID manager with consent state\n const idMode = this.consentManager.getIdMode();\n this.idManager.setMode(idMode);\n \n this.log('Consent revoked, switched to cookieless mode', categories);\n \n // Clear queued events when consent is fully revoked\n if (!this.consentManager.hasConsent()) {\n this.eventQueue = [];\n this.waitingForConsentQueue = [];\n }\n } catch (error) {\n const formattedError = this.formatError(error, 'revokeConsent');\n this.logError(formattedError);\n }\n }\n\n /**\n * Get current consent state\n */\n getConsentState(): ConsentState | null {\n return this.consentManager.getConsentState();\n }\n\n /**\n * Check if user has granted consent\n * @param category - Optional category to check (if not provided, checks general consent)\n */\n hasConsent(category?: string): boolean {\n return this.consentManager.hasConsent(category);\n }\n\n /**\n * Add listener for consent state changes\n */\n onConsentChange(listener: (state: ConsentState) => void): void {\n this.consentManager.addListener(listener);\n }\n\n /**\n * Remove consent change listener\n */\n offConsentChange(listener: (state: ConsentState) => void): void {\n this.consentManager.removeListener(listener);\n }\n\n /**\n * Check for debug mode parameters and initialize debug agent if valid\n */\n private checkAndInitializeDebugMode(): void {\n if (typeof window === 'undefined') return;\n \n try {\n const urlParams = new URLSearchParams(window.location.search);\n const isDebug = urlParams.get('grain_debug') === '1';\n const sessionId = urlParams.get('grain_session');\n \n if (!isDebug || !sessionId) {\n return;\n }\n \n this.log('Debug mode detected, verifying session:', sessionId);\n \n // Verify session with API\n this.verifyDebugSession(sessionId, window.location.hostname)\n .then((valid) => {\n if (valid) {\n this.log('Debug session verified, initializing debug agent');\n this.isDebugMode = true;\n this.initializeDebugAgent(sessionId);\n } else {\n this.log('Debug session verification failed');\n }\n })\n .catch((error) => {\n this.log('Failed to verify debug session:', error);\n });\n } catch (error) {\n this.log('Error checking debug mode:', error);\n }\n }\n \n /**\n * Verify debug session with API\n */\n private async verifyDebugSession(sessionId: string, domain: string): Promise<boolean> {\n try {\n const url = `${this.config.apiUrl}/v1/tenant/${encodeURIComponent(this.config.tenantId)}/debug-sessions/verify`;\n \n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n sessionId,\n domain,\n }),\n });\n \n if (!response.ok) {\n return false;\n }\n \n const result = await response.json();\n return result.valid === true;\n } catch (error) {\n this.log('Debug session verification error:', error);\n return false;\n }\n }\n \n /**\n * Initialize debug agent\n */\n private initializeDebugAgent(sessionId: string): void {\n if (typeof window === 'undefined') return;\n \n try {\n this.log('Loading debug agent module');\n \n import('./debug-agent').then(({ DebugAgent }) => {\n try {\n this.debugAgent = new DebugAgent(\n this,\n sessionId,\n this.config.tenantId,\n this.config.apiUrl,\n {\n debug: this.config.debug,\n }\n );\n this.log('Debug agent initialized');\n } catch (error) {\n this.log('Failed to initialize debug agent:', error);\n }\n }).catch((error) => {\n this.log('Failed to load debug agent module:', error);\n });\n } catch (error) {\n this.log('Error initializing debug agent:', error);\n }\n }\n\n /**\n * Destroy the client and clean up resources\n */\n destroy(): void {\n this.isDestroyed = true;\n \n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n\n // Stop config refresh timer\n this.stopConfigRefreshTimer();\n\n // Clear config change listeners\n this.configChangeListeners = [];\n\n // Destroy automatic tracking managers\n if (this.heartbeatManager) {\n this.heartbeatManager.destroy();\n this.heartbeatManager = null;\n }\n\n if (this.pageTrackingManager) {\n this.pageTrackingManager.destroy();\n this.pageTrackingManager = null;\n }\n\n if (this.activityDetector) {\n this.activityDetector.destroy();\n this.activityDetector = null;\n }\n\n // Destroy auto-tracking managers\n if (this.interactionTrackingManager) {\n this.interactionTrackingManager.destroy();\n this.interactionTrackingManager = null;\n }\n\n if (this.sectionTrackingManager) {\n this.sectionTrackingManager.destroy();\n this.sectionTrackingManager = null;\n }\n\n if (this.heatmapTrackingManager) {\n this.heatmapTrackingManager.destroy();\n this.heatmapTrackingManager = null;\n }\n \n // Destroy debug agent\n if (this.debugAgent) {\n this.debugAgent.destroy();\n this.debugAgent = null;\n }\n\n // Send any remaining events (in chunks if necessary)\n if (this.eventQueue.length > 0) {\n const eventsToSend = [...this.eventQueue];\n this.eventQueue = [];\n \n const chunks = this.chunkEvents(eventsToSend, this.config.maxEventsPerRequest);\n \n // Send first chunk with beacon (most important for page unload)\n if (chunks.length > 0) {\n this.sendEventsWithBeacon(chunks[0]).catch(() => {\n // Silently fail during cleanup\n });\n \n // If there are more chunks, try to send them with regular fetch\n for (let i = 1; i < chunks.length; i++) {\n this.sendEventsWithBeacon(chunks[i]).catch(() => {\n // Silently fail during cleanup\n });\n }\n }\n }\n }\n}\n\n/**\n * Create a new Grain Analytics client\n */\nexport function createGrainAnalytics(config: GrainConfig): GrainAnalytics {\n return new GrainAnalytics(config);\n}\n\n// Default export for convenience\nexport default GrainAnalytics;\n\n// Global interface for IIFE build\ndeclare global {\n interface Window {\n Grain?: {\n GrainAnalytics: typeof GrainAnalytics;\n createGrainAnalytics: typeof createGrainAnalytics;\n };\n }\n}\n\n// Auto-setup for IIFE build\nif (typeof window !== 'undefined') {\n window.Grain = {\n GrainAnalytics,\n createGrainAnalytics,\n };\n}", "/**\n * Consent management for Grain Analytics v2.0\n * Privacy-first, cookieless by default\n * \n * Consent Modes:\n * - cookieless: Default mode, daily rotating IDs, no consent needed\n * - gdpr-strict: Requires explicit consent, falls back to cookieless\n * - gdpr-opt-out: Permanent IDs by default, cookieless on opt-out\n */\n\nexport type ConsentMode = 'COOKIELESS' | 'GDPR_STRICT' | 'GDPR_OPT_OUT';\n\nexport interface ConsentState {\n granted: boolean;\n categories: string[];\n timestamp: Date;\n version: string;\n}\n\nexport const DEFAULT_CONSENT_CATEGORIES = ['necessary', 'analytics', 'functional'];\nexport const CONSENT_VERSION = '1.0.0';\n\n/**\n * Consent manager for handling user consent state\n * v2.0: Cookieless by default, privacy-first approach\n */\nexport class ConsentManager {\n private consentState: ConsentState | null = null;\n private consentMode: ConsentMode;\n private storageKey: string;\n private listeners: Array<(state: ConsentState) => void> = [];\n\n constructor(tenantId: string, consentMode: ConsentMode = 'COOKIELESS') {\n this.consentMode = consentMode;\n this.storageKey = `grain_consent_${tenantId}`;\n this.loadConsentState();\n }\n\n /**\n * Load consent state from localStorage\n * \n * GDPR Compliance: localStorage only used for storing consent preferences\n * (not for tracking), which is a legitimate interest for compliance.\n */\n private loadConsentState(): void {\n if (typeof window === 'undefined') return;\n\n try {\n const stored = localStorage.getItem(this.storageKey);\n if (stored) {\n const parsed = JSON.parse(stored);\n this.consentState = {\n ...parsed,\n timestamp: new Date(parsed.timestamp),\n };\n } else if (this.consentMode === 'GDPR_OPT_OUT') {\n // Auto-grant consent for opt-out mode (user hasn't opted out yet)\n this.consentState = {\n granted: true,\n categories: DEFAULT_CONSENT_CATEGORIES,\n timestamp: new Date(),\n version: CONSENT_VERSION,\n };\n this.saveConsentState();\n }\n // Note: cookieless and gdpr-strict modes without stored consent \u2192 no permanent tracking\n } catch (error) {\n // Silent failure - will use cookieless mode by default\n }\n }\n\n /**\n * Save consent state to localStorage\n */\n private saveConsentState(): void {\n if (typeof window === 'undefined' || !this.consentState) return;\n\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(this.consentState));\n } catch (error) {\n // Silent failure - consent state won't persist\n }\n }\n\n /**\n * Grant consent with optional categories\n */\n grantConsent(categories?: string[]): void {\n const grantedCategories = categories || DEFAULT_CONSENT_CATEGORIES;\n \n this.consentState = {\n granted: true,\n categories: grantedCategories,\n timestamp: new Date(),\n version: CONSENT_VERSION,\n };\n\n this.saveConsentState();\n this.notifyListeners();\n }\n\n /**\n * Revoke consent (opt-out)\n */\n revokeConsent(categories?: string[]): void {\n if (!this.consentState) {\n this.consentState = {\n granted: false,\n categories: [],\n timestamp: new Date(),\n version: CONSENT_VERSION,\n };\n } else if (categories) {\n // Remove specific categories\n this.consentState = {\n ...this.consentState,\n categories: this.consentState.categories.filter(cat => !categories.includes(cat)),\n granted: this.consentState.categories.length > 0,\n timestamp: new Date(),\n };\n } else {\n // Revoke all consent\n this.consentState = {\n granted: false,\n categories: [],\n timestamp: new Date(),\n version: CONSENT_VERSION,\n };\n }\n\n this.saveConsentState();\n this.notifyListeners();\n }\n\n /**\n * Get current consent state\n */\n getConsentState(): ConsentState | null {\n return this.consentState ? { ...this.consentState } : null;\n }\n\n /**\n * Check if user has granted consent for permanent IDs\n */\n hasConsent(category?: string): boolean {\n // Cookieless mode: no consent needed (no permanent tracking)\n if (this.consentMode === 'COOKIELESS') {\n return false; // No permanent IDs\n }\n\n // GDPR Strict: requires explicit consent\n if (this.consentMode === 'GDPR_STRICT') {\n if (!this.consentState?.granted) {\n return false;\n }\n }\n\n // GDPR Opt-out: consent by default unless explicitly revoked\n if (this.consentMode === 'GDPR_OPT_OUT') {\n // If no state, assume consent (opt-out model)\n if (!this.consentState) {\n return true;\n }\n // Check if consent was revoked\n if (!this.consentState.granted) {\n return false;\n }\n }\n\n // Check specific category if provided\n if (category && this.consentState) {\n return this.consentState.categories.includes(category);\n }\n\n return this.consentState?.granted ?? (this.consentMode === 'GDPR_OPT_OUT');\n }\n\n /**\n * Check if permanent IDs are allowed\n */\n shouldUsePermanentId(): boolean {\n return this.hasConsent();\n }\n\n /**\n * Check if we should strip query parameters from URLs\n * Query params stripped unless:\n * - Mode is gdpr-opt-out, OR\n * - Mode is gdpr-strict AND consent given\n */\n shouldStripQueryParams(): boolean {\n if (this.consentMode === 'COOKIELESS') {\n return true; // Always strip in cookieless mode\n }\n \n if (this.consentMode === 'GDPR_STRICT') {\n return !this.hasConsent(); // Strip unless consented\n }\n \n if (this.consentMode === 'GDPR_OPT_OUT') {\n return false; // Don't strip in opt-out mode\n }\n \n return true; // Default: strip\n }\n\n /**\n * Check if we can track events (always true in v2.0)\n * Even cookieless mode allows basic analytics with daily IDs\n */\n canTrack(): boolean {\n return true; // All modes allow some form of tracking\n }\n\n /**\n * Check if we should wait for consent before tracking\n * Only relevant for GDPR Strict mode\n */\n shouldWaitForConsent(): boolean {\n return this.consentMode === 'GDPR_STRICT' && !this.consentState?.granted;\n }\n\n /**\n * Add consent change listener\n */\n addListener(listener: (state: ConsentState) => void): void {\n this.listeners.push(listener);\n }\n\n /**\n * Remove consent change listener\n */\n removeListener(listener: (state: ConsentState) => void): void {\n const index = this.listeners.indexOf(listener);\n if (index > -1) {\n this.listeners.splice(index, 1);\n }\n }\n\n /**\n * Notify all listeners of consent state change\n */\n private notifyListeners(): void {\n if (!this.consentState) return;\n\n this.listeners.forEach(listener => {\n try {\n listener(this.consentState!);\n } catch (error) {\n // Silent failure - listener threw an error\n }\n });\n }\n\n /**\n * Clear all consent data\n */\n clearConsent(): void {\n if (typeof window === 'undefined') return;\n\n try {\n localStorage.removeItem(this.storageKey);\n this.consentState = null;\n } catch (error) {\n // Silent failure - consent state may not be fully cleared\n }\n }\n\n /**\n * Get current consent mode\n */\n getConsentMode(): ConsentMode {\n return this.consentMode;\n }\n\n /**\n * Get ID mode based on consent state\n * Returns 'cookieless' or 'permanent' for IdManager\n */\n getIdMode(): 'cookieless' | 'permanent' {\n return this.shouldUsePermanentId() ? 'permanent' : 'cookieless';\n }\n}\n\n", "/**\n * Cookie utilities for Grain Analytics\n * Provides GDPR-compliant cookie management with configurable options\n */\n\nexport interface CookieConfig {\n domain?: string;\n path?: string;\n sameSite?: 'strict' | 'lax' | 'none';\n secure?: boolean;\n maxAge?: number; // seconds\n}\n\n/**\n * Set a cookie with configurable options\n */\nexport function setCookie(name: string, value: string, config?: CookieConfig): void {\n if (typeof document === 'undefined') return;\n\n const parts = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`];\n \n if (config?.maxAge !== undefined) {\n parts.push(`max-age=${config.maxAge}`);\n }\n \n if (config?.domain) {\n parts.push(`domain=${config.domain}`);\n }\n \n if (config?.path) {\n parts.push(`path=${config.path}`);\n } else {\n parts.push('path=/');\n }\n \n if (config?.sameSite) {\n parts.push(`samesite=${config.sameSite}`);\n }\n \n if (config?.secure) {\n parts.push('secure');\n }\n \n document.cookie = parts.join('; ');\n}\n\n/**\n * Get a cookie value by name\n */\nexport function getCookie(name: string): string | null {\n if (typeof document === 'undefined') return null;\n\n const nameEQ = encodeURIComponent(name) + '=';\n const cookies = document.cookie.split(';');\n \n for (let i = 0; i < cookies.length; i++) {\n let cookie = cookies[i];\n while (cookie.charAt(0) === ' ') {\n cookie = cookie.substring(1);\n }\n if (cookie.indexOf(nameEQ) === 0) {\n return decodeURIComponent(cookie.substring(nameEQ.length));\n }\n }\n \n return null;\n}\n\n/**\n * Delete a cookie by name\n */\nexport function deleteCookie(name: string, config?: Pick<CookieConfig, 'domain' | 'path'>): void {\n if (typeof document === 'undefined') return;\n\n const parts = [\n `${encodeURIComponent(name)}=`,\n 'max-age=0',\n ];\n \n if (config?.domain) {\n parts.push(`domain=${config.domain}`);\n }\n \n if (config?.path) {\n parts.push(`path=${config.path}`);\n } else {\n parts.push('path=/');\n }\n \n document.cookie = parts.join('; ');\n}\n\n/**\n * Check if cookies are available and working\n */\nexport function areCookiesEnabled(): boolean {\n if (typeof document === 'undefined') return false;\n\n try {\n const testCookie = '_grain_cookie_test';\n setCookie(testCookie, 'test', { maxAge: 1 });\n const result = getCookie(testCookie) === 'test';\n deleteCookie(testCookie);\n return result;\n } catch {\n return false;\n }\n}\n\n", "/**\n * Activity Detection for Grain Analytics\n * Tracks user activity (mouse, keyboard, touch, scroll) to determine if user is active\n */\n\nexport class ActivityDetector {\n private lastActivityTime: number;\n private activityThreshold: number = 30000; // 30 seconds\n private listeners: Array<() => void> = [];\n private boundActivityHandler: () => void;\n private isDestroyed = false;\n\n // Events that indicate user activity\n private readonly activityEvents = [\n 'mousemove',\n 'mousedown',\n 'keydown',\n 'scroll',\n 'touchstart',\n 'click',\n ] as const;\n\n constructor() {\n this.lastActivityTime = Date.now();\n this.boundActivityHandler = this.debounce(this.handleActivity.bind(this), 500);\n this.setupListeners();\n }\n\n /**\n * Setup event listeners for activity detection\n */\n private setupListeners(): void {\n if (typeof window === 'undefined') return;\n\n for (const event of this.activityEvents) {\n window.addEventListener(event, this.boundActivityHandler, { passive: true });\n }\n }\n\n /**\n * Handle activity event\n */\n private handleActivity(): void {\n if (this.isDestroyed) return;\n this.lastActivityTime = Date.now();\n this.notifyListeners();\n }\n\n /**\n * Debounce function to limit how often activity handler is called\n */\n private debounce(func: () => void, wait: number): () => void {\n let timeout: number | null = null;\n \n return () => {\n if (timeout !== null) {\n clearTimeout(timeout);\n }\n \n timeout = window.setTimeout(() => {\n func();\n timeout = null;\n }, wait);\n };\n }\n\n /**\n * Check if user is currently active\n * @param threshold Time in ms to consider user inactive (default: 30s)\n */\n isActive(threshold?: number): boolean {\n const thresholdToUse = threshold ?? this.activityThreshold;\n const now = Date.now();\n return (now - this.lastActivityTime) < thresholdToUse;\n }\n\n /**\n * Get time since last activity in milliseconds\n */\n getTimeSinceLastActivity(): number {\n return Date.now() - this.lastActivityTime;\n }\n\n /**\n * Get last activity timestamp\n */\n getLastActivityTime(): number {\n return this.lastActivityTime;\n }\n\n /**\n * Set activity threshold\n */\n setActivityThreshold(threshold: number): void {\n this.activityThreshold = threshold;\n }\n\n /**\n * Add listener for activity changes\n */\n addListener(listener: () => void): void {\n this.listeners.push(listener);\n }\n\n /**\n * Remove listener\n */\n removeListener(listener: () => void): void {\n const index = this.listeners.indexOf(listener);\n if (index > -1) {\n this.listeners.splice(index, 1);\n }\n }\n\n /**\n * Notify all listeners\n */\n private notifyListeners(): void {\n for (const listener of this.listeners) {\n try {\n listener();\n } catch (error) {\n // Silent failure - listener threw an error\n }\n }\n }\n\n /**\n * Cleanup and remove listeners\n */\n destroy(): void {\n if (this.isDestroyed) return;\n \n if (typeof window !== 'undefined') {\n for (const event of this.activityEvents) {\n window.removeEventListener(event, this.boundActivityHandler);\n }\n }\n \n this.listeners = [];\n this.isDestroyed = true;\n }\n}\n\n", "/**\n * Heartbeat Manager for Grain Analytics\n * Tracks session activity with consent-aware behavior\n */\n\nimport type { ActivityDetector } from './activity';\n\nexport interface HeartbeatConfig {\n activeInterval: number; // Interval when user is active (ms)\n inactiveInterval: number; // Interval when user is inactive (ms)\n debug?: boolean;\n}\n\nexport interface HeartbeatTracker {\n trackSystemEvent(eventName: string, properties: Record<string, unknown>): void;\n hasConsent(category?: string): boolean;\n getEffectiveUserId(): string;\n getEphemeralSessionId(): string;\n getSessionId(): string;\n getCurrentPage(): string | null;\n getEventCountSinceLastHeartbeat(): number;\n resetEventCountSinceLastHeartbeat(): void;\n}\n\nexport class HeartbeatManager {\n private config: HeartbeatConfig;\n private tracker: HeartbeatTracker;\n private activityDetector: ActivityDetector;\n private heartbeatTimer: number | null = null;\n private isDestroyed = false;\n private lastHeartbeatTime: number;\n private currentInterval: number;\n private hasSentPageLoadHeartbeat = false;\n\n constructor(\n tracker: HeartbeatTracker,\n activityDetector: ActivityDetector,\n config: HeartbeatConfig\n ) {\n this.tracker = tracker;\n this.activityDetector = activityDetector;\n this.config = config;\n this.lastHeartbeatTime = Date.now();\n this.currentInterval = config.activeInterval;\n\n // Send initial heartbeat when page loads (if allowed by consent)\n this.sendPageLoadHeartbeat();\n \n // Start periodic heartbeat tracking\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Send initial heartbeat when page loads\n */\n private sendPageLoadHeartbeat(): void {\n if (this.isDestroyed || this.hasSentPageLoadHeartbeat) return;\n\n // Wait for page to be fully loaded\n if (typeof window !== 'undefined' && document.readyState !== 'complete') {\n const handleLoad = () => {\n this.sendHeartbeat('page_load');\n this.hasSentPageLoadHeartbeat = true;\n window.removeEventListener('load', handleLoad);\n };\n window.addEventListener('load', handleLoad);\n } else {\n // Page is already loaded or we're in a non-browser environment\n this.sendHeartbeat('page_load');\n this.hasSentPageLoadHeartbeat = true;\n }\n }\n\n /**\n * Schedule the next heartbeat based on current activity\n */\n private scheduleNextHeartbeat(): void {\n if (this.isDestroyed) return;\n\n // Clear existing timer\n if (this.heartbeatTimer !== null) {\n clearTimeout(this.heartbeatTimer);\n }\n\n // Determine interval based on activity\n const isActive = this.activityDetector.isActive(60000); // 1 minute threshold\n this.currentInterval = isActive ? this.config.activeInterval : this.config.inactiveInterval;\n\n // Schedule next heartbeat\n this.heartbeatTimer = window.setTimeout(() => {\n this.sendHeartbeat('periodic');\n this.scheduleNextHeartbeat();\n }, this.currentInterval);\n\n if (this.config.debug) {\n console.log(\n `[Heartbeat] Scheduled next heartbeat in ${this.currentInterval / 1000}s (${isActive ? 'active' : 'inactive'})`\n );\n }\n }\n\n /**\n * Send heartbeat event\n */\n private sendHeartbeat(heartbeatType: 'periodic' | 'page_load' = 'periodic'): void {\n if (this.isDestroyed) return;\n\n const now = Date.now();\n const isActive = this.activityDetector.isActive(60000); // 1 minute threshold\n const hasConsent = this.tracker.hasConsent('analytics');\n\n // Base properties (always included)\n const properties: Record<string, unknown> = {\n heartbeat_type: heartbeatType,\n status: isActive ? 'active' : 'inactive',\n timestamp: now,\n };\n\n // Enhanced properties when consent is granted\n if (hasConsent) {\n const page = this.tracker.getCurrentPage();\n if (page) {\n properties.page = page;\n }\n \n properties.session_id = this.tracker.getSessionId();\n \n // Only include duration and event count for periodic heartbeats\n if (heartbeatType === 'periodic') {\n properties.duration = now - this.lastHeartbeatTime;\n properties.event_count = this.tracker.getEventCountSinceLastHeartbeat();\n \n // Reset event count\n this.tracker.resetEventCountSinceLastHeartbeat();\n }\n }\n\n // Track the heartbeat event\n this.tracker.trackSystemEvent('_grain_heartbeat', properties);\n\n this.lastHeartbeatTime = now;\n }\n\n /**\n * Destroy the heartbeat manager\n */\n destroy(): void {\n if (this.isDestroyed) return;\n\n if (this.heartbeatTimer !== null) {\n clearTimeout(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n\n this.isDestroyed = true;\n }\n}\n\n", "/**\n * Attribution and Referral Tracking for Grain Analytics\n * Handles referral categorization and first-touch attribution\n */\n\nexport type ReferrerCategory = 'organic' | 'paid' | 'social' | 'direct' | 'email' | 'referral';\n\nexport interface UTMParameters {\n utm_source?: string;\n utm_medium?: string;\n utm_campaign?: string;\n utm_term?: string;\n utm_content?: string;\n}\n\nexport interface FirstTouchAttribution {\n source: string;\n medium: string;\n campaign: string;\n referrer: string;\n referrer_category: ReferrerCategory;\n timestamp: number;\n}\n\n/**\n * Known paid search parameters\n */\nconst PAID_SEARCH_PARAMS = [\n 'gclid', // Google Ads\n 'msclkid', // Microsoft Ads\n 'fbclid', // Facebook Ads\n 'ttclid', // TikTok Ads\n 'li_fat_id', // LinkedIn Ads\n 'twclid', // Twitter Ads\n 'ScCid', // Snapchat Ads\n];\n\n/**\n * Known social media domains\n */\nconst SOCIAL_DOMAINS = [\n 'facebook.com',\n 'twitter.com',\n 'x.com',\n 'linkedin.com',\n 'instagram.com',\n 'pinterest.com',\n 'reddit.com',\n 'tiktok.com',\n 'youtube.com',\n 'snapchat.com',\n 't.co', // Twitter short links\n 'fb.me', // Facebook short links\n 'lnkd.in', // LinkedIn short links\n];\n\n/**\n * Known organic search engines\n */\nconst SEARCH_ENGINES = [\n 'google.',\n 'bing.com',\n 'yahoo.com',\n 'duckduckgo.com',\n 'baidu.com',\n 'yandex.com',\n 'ecosia.org',\n 'ask.com',\n];\n\n/**\n * Email client domains\n */\nconst EMAIL_DOMAINS = [\n 'mail.google.com',\n 'outlook.live.com',\n 'mail.yahoo.com',\n 'mail.aol.com',\n];\n\n/**\n * Extract domain from URL\n */\nfunction extractDomain(url: string): string {\n try {\n const urlObj = new URL(url);\n return urlObj.hostname.toLowerCase();\n } catch {\n return '';\n }\n}\n\n/**\n * Check if URL contains paid search parameters\n */\nfunction hasPaidSearchParams(url: string): boolean {\n try {\n const urlObj = new URL(url);\n return PAID_SEARCH_PARAMS.some(param => urlObj.searchParams.has(param));\n } catch {\n return false;\n }\n}\n\n/**\n * Categorize referrer based on domain and parameters\n */\nexport function categorizeReferrer(referrer: string, currentUrl: string = ''): ReferrerCategory {\n // Direct traffic (no referrer)\n if (!referrer || referrer.trim() === '') {\n return 'direct';\n }\n\n const domain = extractDomain(referrer);\n \n // Same domain = direct\n if (currentUrl) {\n const currentDomain = extractDomain(currentUrl);\n if (domain === currentDomain) {\n return 'direct';\n }\n }\n\n // Check for paid search parameters\n if (hasPaidSearchParams(referrer) || hasPaidSearchParams(currentUrl)) {\n return 'paid';\n }\n\n // Email clients\n if (EMAIL_DOMAINS.some(emailDomain => domain.includes(emailDomain))) {\n return 'email';\n }\n\n // Social media\n if (SOCIAL_DOMAINS.some(socialDomain => domain.includes(socialDomain))) {\n return 'social';\n }\n\n // Organic search engines\n if (SEARCH_ENGINES.some(searchEngine => domain.includes(searchEngine))) {\n return 'organic';\n }\n\n // Everything else is referral\n return 'referral';\n}\n\n/**\n * Parse UTM parameters from URL\n */\nexport function parseUTMParameters(url: string): UTMParameters {\n try {\n const urlObj = new URL(url);\n const params: UTMParameters = {};\n\n const utmSource = urlObj.searchParams.get('utm_source');\n const utmMedium = urlObj.searchParams.get('utm_medium');\n const utmCampaign = urlObj.searchParams.get('utm_campaign');\n const utmTerm = urlObj.searchParams.get('utm_term');\n const utmContent = urlObj.searchParams.get('utm_content');\n\n if (utmSource) params.utm_source = utmSource;\n if (utmMedium) params.utm_medium = utmMedium;\n if (utmCampaign) params.utm_campaign = utmCampaign;\n if (utmTerm) params.utm_term = utmTerm;\n if (utmContent) params.utm_content = utmContent;\n\n return params;\n } catch {\n return {};\n }\n}\n\n/**\n * Get first-touch attribution from localStorage\n */\nexport function getFirstTouchAttribution(tenantId: string): FirstTouchAttribution | null {\n if (typeof window === 'undefined' || typeof localStorage === 'undefined') {\n return null;\n }\n\n try {\n const key = `_grain_first_touch_${tenantId}`;\n const stored = localStorage.getItem(key);\n if (stored) {\n return JSON.parse(stored) as FirstTouchAttribution;\n }\n } catch (error) {\n console.warn('[Grain Attribution] Failed to retrieve first-touch attribution:', error);\n }\n\n return null;\n}\n\n/**\n * Set first-touch attribution in localStorage\n */\nexport function setFirstTouchAttribution(\n tenantId: string,\n attribution: FirstTouchAttribution\n): void {\n if (typeof window === 'undefined' || typeof localStorage === 'undefined') {\n return;\n }\n\n try {\n const key = `_grain_first_touch_${tenantId}`;\n localStorage.setItem(key, JSON.stringify(attribution));\n } catch (error) {\n console.warn('[Grain Attribution] Failed to store first-touch attribution:', error);\n }\n}\n\n/**\n * Get or create first-touch attribution\n */\nexport function getOrCreateFirstTouchAttribution(\n tenantId: string,\n referrer: string,\n currentUrl: string,\n utmParams: UTMParameters\n): FirstTouchAttribution {\n // Try to get existing first-touch\n const existing = getFirstTouchAttribution(tenantId);\n if (existing) {\n return existing;\n }\n\n // Create new first-touch attribution\n const referrerCategory = categorizeReferrer(referrer, currentUrl);\n const referrerDomain = extractDomain(referrer);\n\n const firstTouch: FirstTouchAttribution = {\n source: utmParams.utm_source || referrerDomain || 'direct',\n medium: utmParams.utm_medium || referrerCategory,\n campaign: utmParams.utm_campaign || 'none',\n referrer: referrer || 'direct',\n referrer_category: referrerCategory,\n timestamp: Date.now(),\n };\n\n // Store it\n setFirstTouchAttribution(tenantId, firstTouch);\n\n return firstTouch;\n}\n\n/**\n * Get session UTM parameters (memory-only, not persisted across page loads)\n */\nlet sessionUTMParams: UTMParameters | null = null;\n\nexport function getSessionUTMParameters(): UTMParameters | null {\n return sessionUTMParams;\n}\n\nexport function setSessionUTMParameters(params: UTMParameters): void {\n sessionUTMParams = params;\n}\n\n/**\n * Clear session UTM parameters\n */\nexport function clearSessionUTMParameters(): void {\n sessionUTMParams = null;\n}\n\n", "const countries = {\n\t\tAD: \"Andorra\",\n\t\tAE: \"United Arab Emirates\",\n\t\tAF: \"Afghanistan\",\n\t\tAG: \"Antigua and Barbuda\",\n\t\tAI: \"Anguilla\",\n\t\tAL: \"Albania\",\n\t\tAM: \"Armenia\",\n\t\tAO: \"Angola\",\n\t\tAQ: \"Antarctica\",\n\t\tAR: \"Argentina\",\n\t\tAS: \"American Samoa\",\n\t\tAT: \"Austria\",\n\t\tAU: \"Australia\",\n\t\tAW: \"Aruba\",\n\t\tAX: \"\u00C5land Islands\",\n\t\tAZ: \"Azerbaijan\",\n\t\tBA: \"Bosnia and Herzegovina\",\n\t\tBB: \"Barbados\",\n\t\tBD: \"Bangladesh\",\n\t\tBE: \"Belgium\",\n\t\tBF: \"Burkina Faso\",\n\t\tBG: \"Bulgaria\",\n\t\tBH: \"Bahrain\",\n\t\tBI: \"Burundi\",\n\t\tBJ: \"Benin\",\n\t\tBL: \"Saint Barth\u00E9lemy\",\n\t\tBM: \"Bermuda\",\n\t\tBN: \"Brunei\",\n\t\tBO: \"Bolivia\",\n\t\tBQ: \"Caribbean Netherlands\",\n\t\tBR: \"Brazil\",\n\t\tBS: \"Bahamas\",\n\t\tBT: \"Bhutan\",\n\t\tBV: \"Bouvet Island\",\n\t\tBW: \"Botswana\",\n\t\tBY: \"Belarus\",\n\t\tBZ: \"Belize\",\n\t\tCA: \"Canada\",\n\t\tCC: \"Cocos Islands\",\n\t\tCD: \"Democratic Republic of the Congo\",\n\t\tCF: \"Central African Republic\",\n\t\tCG: \"Republic of the Congo\",\n\t\tCH: \"Switzerland\",\n\t\tCI: \"Ivory Coast\",\n\t\tCK: \"Cook Islands\",\n\t\tCL: \"Chile\",\n\t\tCM: \"Cameroon\",\n\t\tCN: \"China\",\n\t\tCO: \"Colombia\",\n\t\tCR: \"Costa Rica\",\n\t\tCU: \"Cuba\",\n\t\tCV: \"Cabo Verde\",\n\t\tCW: \"Cura\u00E7ao\",\n\t\tCX: \"Christmas Island\",\n\t\tCY: \"Cyprus\",\n\t\tCZ: \"Czechia\",\n\t\tDE: \"Germany\",\n\t\tDJ: \"Djibouti\",\n\t\tDK: \"Denmark\",\n\t\tDM: \"Dominica\",\n\t\tDO: \"Dominican Republic\",\n\t\tDZ: \"Algeria\",\n\t\tEC: \"Ecuador\",\n\t\tEE: \"Estonia\",\n\t\tEG: \"Egypt\",\n\t\tEH: \"Western Sahara\",\n\t\tER: \"Eritrea\",\n\t\tES: \"Spain\",\n\t\tET: \"Ethiopia\",\n\t\tFI: \"Finland\",\n\t\tFJ: \"Fiji\",\n\t\tFK: \"Falkland Islands\",\n\t\tFM: \"Micronesia\",\n\t\tFO: \"Faroe Islands\",\n\t\tFR: \"France\",\n\t\tGA: \"Gabon\",\n\t\tGB: \"United Kingdom\",\n\t\tGD: \"Grenada\",\n\t\tGE: \"Georgia\",\n\t\tGF: \"French Guiana\",\n\t\tGG: \"Guernsey\",\n\t\tGH: \"Ghana\",\n\t\tGI: \"Gibraltar\",\n\t\tGL: \"Greenland\",\n\t\tGM: \"Gambia\",\n\t\tGN: \"Guinea\",\n\t\tGP: \"Guadeloupe\",\n\t\tGQ: \"Equatorial Guinea\",\n\t\tGR: \"Greece\",\n\t\tGS: \"South Georgia and the South Sandwich Islands\",\n\t\tGT: \"Guatemala\",\n\t\tGU: \"Guam\",\n\t\tGW: \"Guinea-Bissau\",\n\t\tGY: \"Guyana\",\n\t\tHK: \"Hong Kong\",\n\t\tHM: \"Heard Island and McDonald Islands\",\n\t\tHN: \"Honduras\",\n\t\tHR: \"Croatia\",\n\t\tHT: \"Haiti\",\n\t\tHU: \"Hungary\",\n\t\tID: \"Indonesia\",\n\t\tIE: \"Ireland\",\n\t\tIL: \"Israel\",\n\t\tIM: \"Isle of Man\",\n\t\tIN: \"India\",\n\t\tIO: \"British Indian Ocean Territory\",\n\t\tIQ: \"Iraq\",\n\t\tIR: \"Iran\",\n\t\tIS: \"Iceland\",\n\t\tIT: \"Italy\",\n\t\tJE: \"Jersey\",\n\t\tJM: \"Jamaica\",\n\t\tJO: \"Jordan\",\n\t\tJP: \"Japan\",\n\t\tKE: \"Kenya\",\n\t\tKG: \"Kyrgyzstan\",\n\t\tKH: \"Cambodia\",\n\t\tKI: \"Kiribati\",\n\t\tKM: \"Comoros\",\n\t\tKN: \"Saint Kitts and Nevis\",\n\t\tKP: \"North Korea\",\n\t\tKR: \"South Korea\",\n\t\tKW: \"Kuwait\",\n\t\tKY: \"Cayman Islands\",\n\t\tKZ: \"Kazakhstan\",\n\t\tLA: \"Laos\",\n\t\tLB: \"Lebanon\",\n\t\tLC: \"Saint Lucia\",\n\t\tLI: \"Liechtenstein\",\n\t\tLK: \"Sri Lanka\",\n\t\tLR: \"Liberia\",\n\t\tLS: \"Lesotho\",\n\t\tLT: \"Lithuania\",\n\t\tLU: \"Luxembourg\",\n\t\tLV: \"Latvia\",\n\t\tLY: \"Libya\",\n\t\tMA: \"Morocco\",\n\t\tMC: \"Monaco\",\n\t\tMD: \"Moldova\",\n\t\tME: \"Montenegro\",\n\t\tMF: \"Saint Martin\",\n\t\tMG: \"Madagascar\",\n\t\tMH: \"Marshall Islands\",\n\t\tMK: \"North Macedonia\",\n\t\tML: \"Mali\",\n\t\tMM: \"Myanmar\",\n\t\tMN: \"Mongolia\",\n\t\tMO: \"Macao\",\n\t\tMP: \"Northern Mariana Islands\",\n\t\tMQ: \"Martinique\",\n\t\tMR: \"Mauritania\",\n\t\tMS: \"Montserrat\",\n\t\tMT: \"Malta\",\n\t\tMU: \"Mauritius\",\n\t\tMV: \"Maldives\",\n\t\tMW: \"Malawi\",\n\t\tMX: \"Mexico\",\n\t\tMY: \"Malaysia\",\n\t\tMZ: \"Mozambique\",\n\t\tNA: \"Namibia\",\n\t\tNC: \"New Caledonia\",\n\t\tNE: \"Niger\",\n\t\tNF: \"Norfolk Island\",\n\t\tNG: \"Nigeria\",\n\t\tNI: \"Nicaragua\",\n\t\tNL: \"Netherlands\",\n\t\tNO: \"Norway\",\n\t\tNP: \"Nepal\",\n\t\tNR: \"Nauru\",\n\t\tNU: \"Niue\",\n\t\tNZ: \"New Zealand\",\n\t\tOM: \"Oman\",\n\t\tPA: \"Panama\",\n\t\tPE: \"Peru\",\n\t\tPF: \"French Polynesia\",\n\t\tPG: \"Papua New Guinea\",\n\t\tPH: \"Philippines\",\n\t\tPK: \"Pakistan\",\n\t\tPL: \"Poland\",\n\t\tPM: \"Saint Pierre and Miquelon\",\n\t\tPN: \"Pitcairn\",\n\t\tPR: \"Puerto Rico\",\n\t\tPS: \"Palestine\",\n\t\tPT: \"Portugal\",\n\t\tPW: \"Palau\",\n\t\tPY: \"Paraguay\",\n\t\tQA: \"Qatar\",\n\t\tRE: \"R\u00E9union\",\n\t\tRO: \"Romania\",\n\t\tRS: \"Serbia\",\n\t\tRU: \"Russia\",\n\t\tRW: \"Rwanda\",\n\t\tSA: \"Saudi Arabia\",\n\t\tSB: \"Solomon Islands\",\n\t\tSC: \"Seychelles\",\n\t\tSD: \"Sudan\",\n\t\tSE: \"Sweden\",\n\t\tSG: \"Singapore\",\n\t\tSH: \"Saint Helena, Ascension and Tristan da Cunha\",\n\t\tSI: \"Slovenia\",\n\t\tSJ: \"Svalbard and Jan Mayen\",\n\t\tSK: \"Slovakia\",\n\t\tSL: \"Sierra Leone\",\n\t\tSM: \"San Marino\",\n\t\tSN: \"Senegal\",\n\t\tSO: \"Somalia\",\n\t\tSR: \"Suriname\",\n\t\tSS: \"South Sudan\",\n\t\tST: \"Sao Tome and Principe\",\n\t\tSV: \"El Salvador\",\n\t\tSX: \"Sint Maarten\",\n\t\tSY: \"Syria\",\n\t\tSZ: \"Eswatini\",\n\t\tTC: \"Turks and Caicos Islands\",\n\t\tTD: \"Chad\",\n\t\tTF: \"French Southern Territories\",\n\t\tTG: \"Togo\",\n\t\tTH: \"Thailand\",\n\t\tTJ: \"Tajikistan\",\n\t\tTK: \"Tokelau\",\n\t\tTL: \"Timor-Leste\",\n\t\tTM: \"Turkmenistan\",\n\t\tTN: \"Tunisia\",\n\t\tTO: \"Tonga\",\n\t\tTR: \"Turkey\",\n\t\tTT: \"Trinidad and Tobago\",\n\t\tTV: \"Tuvalu\",\n\t\tTW: \"Taiwan\",\n\t\tTZ: \"Tanzania\",\n\t\tUA: \"Ukraine\",\n\t\tUG: \"Uganda\",\n\t\tUM: \"United States Minor Outlying Islands\",\n\t\tUS: \"United States of America\",\n\t\tUY: \"Uruguay\",\n\t\tUZ: \"Uzbekistan\",\n\t\tVA: \"Holy See\",\n\t\tVC: \"Saint Vincent and the Grenadines\",\n\t\tVE: \"Venezuela\",\n\t\tVG: \"Virgin Islands (UK)\",\n\t\tVI: \"Virgin Islands (US)\",\n\t\tVN: \"Vietnam\",\n\t\tVU: \"Vanuatu\",\n\t\tWF: \"Wallis and Futuna\",\n\t\tWS: \"Samoa\",\n\t\tYE: \"Yemen\",\n\t\tYT: \"Mayotte\",\n\t\tZA: \"South Africa\",\n\t\tZM: \"Zambia\",\n\t\tZW: \"Zimbabwe\"\n};\n\nconst timezones: Record<string, any> = {\n\t\t\"Africa/Abidjan\": {\n\t\t\tu: 0,\n\t\t\tc: [\"CI\", \"BF\", \"GH\", \"GM\", \"GN\", \"ML\", \"MR\", \"SH\", \"SL\", \"SN\", \"TG\"]\n\t\t},\n\t\t\"Africa/Accra\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"GH\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Addis_Ababa\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"ET\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Algiers\": {\n\t\t\tu: 60,\n\t\t\tc: [\"DZ\"]\n\t\t},\n\t\t\"Africa/Asmara\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"ER\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Asmera\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"ER\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Bamako\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"ML\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Bangui\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"CF\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Banjul\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"GM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Bissau\": {\n\t\t\tu: 0,\n\t\t\tc: [\"GW\"]\n\t\t},\n\t\t\"Africa/Blantyre\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"MW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Brazzaville\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"CG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Bujumbura\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"BI\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Cairo\": {\n\t\t\tu: 120,\n\t\t\tc: [\"EG\"]\n\t\t},\n\t\t\"Africa/Casablanca\": {\n\t\t\tu: 60,\n\t\t\td: 0,\n\t\t\tc: [\"MA\"]\n\t\t},\n\t\t\"Africa/Ceuta\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"ES\"]\n\t\t},\n\t\t\"Africa/Conakry\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"GN\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Dakar\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"SN\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Dar_es_Salaam\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"TZ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Djibouti\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"DJ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Douala\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"CM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/El_Aaiun\": {\n\t\t\tu: 60,\n\t\t\td: 0,\n\t\t\tc: [\"EH\"]\n\t\t},\n\t\t\"Africa/Freetown\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"SL\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Gaborone\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"BW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Harare\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"ZW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Johannesburg\": {\n\t\t\tu: 120,\n\t\t\tc: [\"ZA\", \"LS\", \"SZ\"]\n\t\t},\n\t\t\"Africa/Juba\": {\n\t\t\tu: 120,\n\t\t\tc: [\"SS\"]\n\t\t},\n\t\t\"Africa/Kampala\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"UG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Khartoum\": {\n\t\t\tu: 120,\n\t\t\tc: [\"SD\"]\n\t\t},\n\t\t\"Africa/Kigali\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"RW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Kinshasa\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"CD\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Lagos\": {\n\t\t\tu: 60,\n\t\t\tc: [\"NG\", \"AO\", \"BJ\", \"CD\", \"CF\", \"CG\", \"CM\", \"GA\", \"GQ\", \"NE\"]\n\t\t},\n\t\t\"Africa/Libreville\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"GA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Lome\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"TG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Luanda\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"AO\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Lubumbashi\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"CD\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Lusaka\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"ZM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Malabo\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"GQ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Maputo\": {\n\t\t\tu: 120,\n\t\t\tc: [\"MZ\", \"BI\", \"BW\", \"CD\", \"MW\", \"RW\", \"ZM\", \"ZW\"]\n\t\t},\n\t\t\"Africa/Maseru\": {\n\t\t\ta: \"Africa/Johannesburg\",\n\t\t\tc: [\"LS\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Mbabane\": {\n\t\t\ta: \"Africa/Johannesburg\",\n\t\t\tc: [\"SZ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Mogadishu\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"SO\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Monrovia\": {\n\t\t\tu: 0,\n\t\t\tc: [\"LR\"]\n\t\t},\n\t\t\"Africa/Nairobi\": {\n\t\t\tu: 180,\n\t\t\tc: [\"KE\", \"DJ\", \"ER\", \"ET\", \"KM\", \"MG\", \"SO\", \"TZ\", \"UG\", \"YT\"]\n\t\t},\n\t\t\"Africa/Ndjamena\": {\n\t\t\tu: 60,\n\t\t\tc: [\"TD\"]\n\t\t},\n\t\t\"Africa/Niamey\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"NE\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Nouakchott\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"MR\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Ouagadougou\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"BF\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Porto-Novo\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"BJ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Sao_Tome\": {\n\t\t\tu: 0,\n\t\t\tc: [\"ST\"]\n\t\t},\n\t\t\"Africa/Timbuktu\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"ML\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Tripoli\": {\n\t\t\tu: 120,\n\t\t\tc: [\"LY\"]\n\t\t},\n\t\t\"Africa/Tunis\": {\n\t\t\tu: 60,\n\t\t\tc: [\"TN\"]\n\t\t},\n\t\t\"Africa/Windhoek\": {\n\t\t\tu: 120,\n\t\t\tc: [\"NA\"]\n\t\t},\n\t\t\"America/Adak\": {\n\t\t\tu: -600,\n\t\t\td: -540,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Anchorage\": {\n\t\t\tu: -540,\n\t\t\td: -480,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Anguilla\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"AI\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Antigua\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"AG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Araguaina\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Argentina/Buenos_Aires\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Catamarca\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/ComodRivadavia\": {\n\t\t\ta: \"America/Argentina/Catamarca\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Argentina/Cordoba\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Jujuy\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/La_Rioja\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Mendoza\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Rio_Gallegos\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Salta\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/San_Juan\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/San_Luis\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Tucuman\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Ushuaia\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Aruba\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"AW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Asuncion\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"PY\"]\n\t\t},\n\t\t\"America/Atikokan\": {\n\t\t\ta: \"America/Panama\",\n\t\t\tc: [\"CA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Atka\": {\n\t\t\ta: \"America/Adak\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Bahia\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Bahia_Banderas\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Barbados\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BB\"]\n\t\t},\n\t\t\"America/Belem\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Belize\": {\n\t\t\tu: -360,\n\t\t\tc: [\"BZ\"]\n\t\t},\n\t\t\"America/Blanc-Sablon\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"CA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Boa_Vista\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Bogota\": {\n\t\t\tu: -300,\n\t\t\tc: [\"CO\"]\n\t\t},\n\t\t\"America/Boise\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Buenos_Aires\": {\n\t\t\ta: \"America/Argentina/Buenos_Aires\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Cambridge_Bay\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Campo_Grande\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Cancun\": {\n\t\t\tu: -300,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Caracas\": {\n\t\t\tu: -240,\n\t\t\tc: [\"VE\"]\n\t\t},\n\t\t\"America/Catamarca\": {\n\t\t\ta: \"America/Argentina/Catamarca\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Cayenne\": {\n\t\t\tu: -180,\n\t\t\tc: [\"GF\"]\n\t\t},\n\t\t\"America/Cayman\": {\n\t\t\ta: \"America/Panama\",\n\t\t\tc: [\"KY\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Chicago\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Chihuahua\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Coral_Harbour\": {\n\t\t\ta: \"America/Panama\",\n\t\t\tc: [\"CA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Cordoba\": {\n\t\t\ta: \"America/Argentina/Cordoba\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Costa_Rica\": {\n\t\t\tu: -360,\n\t\t\tc: [\"CR\"]\n\t\t},\n\t\t\"America/Creston\": {\n\t\t\ta: \"America/Phoenix\",\n\t\t\tc: [\"CA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Cuiaba\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Curacao\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"CW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Danmarkshavn\": {\n\t\t\tu: 0,\n\t\t\tc: [\"GL\"]\n\t\t},\n\t\t\"America/Dawson\": {\n\t\t\tu: -420,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Dawson_Creek\": {\n\t\t\tu: -420,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Denver\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Detroit\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Dominica\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"DM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Edmonton\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Eirunepe\": {\n\t\t\tu: -300,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/El_Salvador\": {\n\t\t\tu: -360,\n\t\t\tc: [\"SV\"]\n\t\t},\n\t\t\"America/Ensenada\": {\n\t\t\ta: \"America/Tijuana\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Fort_Nelson\": {\n\t\t\tu: -420,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Fort_Wayne\": {\n\t\t\ta: \"America/Indiana/Indianapolis\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Fortaleza\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Glace_Bay\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Godthab\": {\n\t\t\ta: \"America/Nuuk\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Goose_Bay\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Grand_Turk\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"TC\"]\n\t\t},\n\t\t\"America/Grenada\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"GD\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Guadeloupe\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"GP\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Guatemala\": {\n\t\t\tu: -360,\n\t\t\tc: [\"GT\"]\n\t\t},\n\t\t\"America/Guayaquil\": {\n\t\t\tu: -300,\n\t\t\tc: [\"EC\"]\n\t\t},\n\t\t\"America/Guyana\": {\n\t\t\tu: -240,\n\t\t\tc: [\"GY\"]\n\t\t},\n\t\t\"America/Halifax\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Havana\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"CU\"]\n\t\t},\n\t\t\"America/Hermosillo\": {\n\t\t\tu: -420,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Indiana/Indianapolis\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Knox\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Marengo\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Petersburg\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Tell_City\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Vevay\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Vincennes\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Winamac\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indianapolis\": {\n\t\t\ta: \"America/Indiana/Indianapolis\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Inuvik\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Iqaluit\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Jamaica\": {\n\t\t\tu: -300,\n\t\t\tc: [\"JM\"]\n\t\t},\n\t\t\"America/Jujuy\": {\n\t\t\ta: \"America/Argentina/Jujuy\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Juneau\": {\n\t\t\tu: -540,\n\t\t\td: -480,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Kentucky/Louisville\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Kentucky/Monticello\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Knox_IN\": {\n\t\t\ta: \"America/Indiana/Knox\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Kralendijk\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"BQ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/La_Paz\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BO\"]\n\t\t},\n\t\t\"America/Lima\": {\n\t\t\tu: -300,\n\t\t\tc: [\"PE\"]\n\t\t},\n\t\t\"America/Los_Angeles\": {\n\t\t\tu: -480,\n\t\t\td: -420,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Louisville\": {\n\t\t\ta: \"America/Kentucky/Louisville\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Lower_Princes\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"SX\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Maceio\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Managua\": {\n\t\t\tu: -360,\n\t\t\tc: [\"NI\"]\n\t\t},\n\t\t\"America/Manaus\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Marigot\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"MF\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Martinique\": {\n\t\t\tu: -240,\n\t\t\tc: [\"MQ\"]\n\t\t},\n\t\t\"America/Matamoros\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Mazatlan\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Mendoza\": {\n\t\t\ta: \"America/Argentina/Mendoza\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Menominee\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Merida\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Metlakatla\": {\n\t\t\tu: -540,\n\t\t\td: -480,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Mexico_City\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Miquelon\": {\n\t\t\tu: -180,\n\t\t\td: -120,\n\t\t\tc: [\"PM\"]\n\t\t},\n\t\t\"America/Moncton\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Monterrey\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Montevideo\": {\n\t\t\tu: -180,\n\t\t\tc: [\"UY\"]\n\t\t},\n\t\t\"America/Montreal\": {\n\t\t\ta: \"America/Toronto\",\n\t\t\tc: [\"CA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Montserrat\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"MS\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Nassau\": {\n\t\t\ta: \"America/Toronto\",\n\t\t\tc: [\"BS\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/New_York\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Nipigon\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Nome\": {\n\t\t\tu: -540,\n\t\t\td: -480,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Noronha\": {\n\t\t\tu: -120,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/North_Dakota/Beulah\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/North_Dakota/Center\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/North_Dakota/New_Salem\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Nuuk\": {\n\t\t\tu: -180,\n\t\t\td: -120,\n\t\t\tc: [\"GL\"]\n\t\t},\n\t\t\"America/Ojinaga\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Panama\": {\n\t\t\tu: -300,\n\t\t\tc: [\"PA\", \"CA\", \"KY\"]\n\t\t},\n\t\t\"America/Pangnirtung\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Paramaribo\": {\n\t\t\tu: -180,\n\t\t\tc: [\"SR\"]\n\t\t},\n\t\t\"America/Phoenix\": {\n\t\t\tu: -420,\n\t\t\tc: [\"US\", \"CA\"]\n\t\t},\n\t\t\"America/Port-au-Prince\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"HT\"]\n\t\t},\n\t\t\"America/Port_of_Spain\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"TT\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Porto_Acre\": {\n\t\t\ta: \"America/Rio_Branco\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Porto_Velho\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Puerto_Rico\": {\n\t\t\tu: -240,\n\t\t\tc: [\n\t\t\t\t\"PR\",\n\t\t\t\t\"AG\",\n\t\t\t\t\"CA\",\n\t\t\t\t\"AI\",\n\t\t\t\t\"AW\",\n\t\t\t\t\"BL\",\n\t\t\t\t\"BQ\",\n\t\t\t\t\"CW\",\n\t\t\t\t\"DM\",\n\t\t\t\t\"GD\",\n\t\t\t\t\"GP\",\n\t\t\t\t\"KN\",\n\t\t\t\t\"LC\",\n\t\t\t\t\"MF\",\n\t\t\t\t\"MS\",\n\t\t\t\t\"SX\",\n\t\t\t\t\"TT\",\n\t\t\t\t\"VC\",\n\t\t\t\t\"VG\",\n\t\t\t\t\"VI\"\n\t\t\t]\n\t\t},\n\t\t\"America/Punta_Arenas\": {\n\t\t\tu: -180,\n\t\t\tc: [\"CL\"]\n\t\t},\n\t\t\"America/Rainy_River\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Rankin_Inlet\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Recife\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Regina\": {\n\t\t\tu: -360,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Resolute\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Rio_Branco\": {\n\t\t\tu: -300,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Rosario\": {\n\t\t\ta: \"America/Argentina/Cordoba\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Santa_Isabel\": {\n\t\t\ta: \"America/Tijuana\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Santarem\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Santiago\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"CL\"]\n\t\t},\n\t\t\"America/Santo_Domingo\": {\n\t\t\tu: -240,\n\t\t\tc: [\"DO\"]\n\t\t},\n\t\t\"America/Sao_Paulo\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Scoresbysund\": {\n\t\t\tu: -60,\n\t\t\td: 0,\n\t\t\tc: [\"GL\"]\n\t\t},\n\t\t\"America/Shiprock\": {\n\t\t\ta: \"America/Denver\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Sitka\": {\n\t\t\tu: -540,\n\t\t\td: -480,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/St_Barthelemy\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"BL\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/St_Johns\": {\n\t\t\tu: -150,\n\t\t\td: -90,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/St_Kitts\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"KN\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/St_Lucia\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"LC\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/St_Thomas\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"VI\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/St_Vincent\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"VC\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Swift_Current\": {\n\t\t\tu: -360,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Tegucigalpa\": {\n\t\t\tu: -360,\n\t\t\tc: [\"HN\"]\n\t\t},\n\t\t\"America/Thule\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"GL\"]\n\t\t},\n\t\t\"America/Thunder_Bay\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Tijuana\": {\n\t\t\tu: -480,\n\t\t\td: -420,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Toronto\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"CA\", \"BS\"]\n\t\t},\n\t\t\"America/Tortola\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"VG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Vancouver\": {\n\t\t\tu: -480,\n\t\t\td: -420,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Virgin\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"VI\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Whitehorse\": {\n\t\t\tu: -420,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Winnipeg\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Yakutat\": {\n\t\t\tu: -540,\n\t\t\td: -480,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Yellowknife\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"Antarctica/Casey\": {\n\t\t\tu: 660,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Antarctica/Davis\": {\n\t\t\tu: 420,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Antarctica/DumontDUrville\": {\n\t\t\ta: \"Pacific/Port_Moresby\",\n\t\t\tc: [\"AQ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Antarctica/Macquarie\": {\n\t\t\tu: 600,\n\t\t\td: 660,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Antarctica/Mawson\": {\n\t\t\tu: 300,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Antarctica/McMurdo\": {\n\t\t\ta: \"Pacific/Auckland\",\n\t\t\tc: [\"AQ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Antarctica/Palmer\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Antarctica/Rothera\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Antarctica/South_Pole\": {\n\t\t\ta: \"Pacific/Auckland\",\n\t\t\tc: [\"AQ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Antarctica/Syowa\": {\n\t\t\ta: \"Asia/Riyadh\",\n\t\t\tc: [\"AQ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Antarctica/Troll\": {\n\t\t\tu: 0,\n\t\t\td: 120,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Antarctica/Vostok\": {\n\t\t\tu: 360,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Arctic/Longyearbyen\": {\n\t\t\ta: \"Europe/Oslo\",\n\t\t\tc: [\"SJ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Aden\": {\n\t\t\ta: \"Asia/Riyadh\",\n\t\t\tc: [\"YE\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Almaty\": {\n\t\t\tu: 360,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Amman\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"JO\"]\n\t\t},\n\t\t\"Asia/Anadyr\": {\n\t\t\tu: 720,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Aqtau\": {\n\t\t\tu: 300,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Aqtobe\": {\n\t\t\tu: 300,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Ashgabat\": {\n\t\t\tu: 300,\n\t\t\tc: [\"TM\"]\n\t\t},\n\t\t\"Asia/Ashkhabad\": {\n\t\t\ta: \"Asia/Ashgabat\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Atyrau\": {\n\t\t\tu: 300,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Baghdad\": {\n\t\t\tu: 180,\n\t\t\tc: [\"IQ\"]\n\t\t},\n\t\t\"Asia/Bahrain\": {\n\t\t\ta: \"Asia/Qatar\",\n\t\t\tc: [\"BH\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Baku\": {\n\t\t\tu: 240,\n\t\t\tc: [\"AZ\"]\n\t\t},\n\t\t\"Asia/Bangkok\": {\n\t\t\tu: 420,\n\t\t\tc: [\"TH\", \"KH\", \"LA\", \"VN\"]\n\t\t},\n\t\t\"Asia/Barnaul\": {\n\t\t\tu: 420,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Beirut\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"LB\"]\n\t\t},\n\t\t\"Asia/Bishkek\": {\n\t\t\tu: 360,\n\t\t\tc: [\"KG\"]\n\t\t},\n\t\t\"Asia/Brunei\": {\n\t\t\tu: 480,\n\t\t\tc: [\"BN\"]\n\t\t},\n\t\t\"Asia/Calcutta\": {\n\t\t\ta: \"Asia/Kolkata\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Chita\": {\n\t\t\tu: 540,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Choibalsan\": {\n\t\t\tu: 480,\n\t\t\tc: [\"MN\"]\n\t\t},\n\t\t\"Asia/Chongqing\": {\n\t\t\ta: \"Asia/Shanghai\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Chungking\": {\n\t\t\ta: \"Asia/Shanghai\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Colombo\": {\n\t\t\tu: 330,\n\t\t\tc: [\"LK\"]\n\t\t},\n\t\t\"Asia/Dacca\": {\n\t\t\ta: \"Asia/Dhaka\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Damascus\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"SY\"]\n\t\t},\n\t\t\"Asia/Dhaka\": {\n\t\t\tu: 360,\n\t\t\tc: [\"BD\"]\n\t\t},\n\t\t\"Asia/Dili\": {\n\t\t\tu: 540,\n\t\t\tc: [\"TL\"]\n\t\t},\n\t\t\"Asia/Dubai\": {\n\t\t\tu: 240,\n\t\t\tc: [\"AE\", \"OM\"]\n\t\t},\n\t\t\"Asia/Dushanbe\": {\n\t\t\tu: 300,\n\t\t\tc: [\"TJ\"]\n\t\t},\n\t\t\"Asia/Famagusta\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"CY\"]\n\t\t},\n\t\t\"Asia/Gaza\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"PS\"]\n\t\t},\n\t\t\"Asia/Harbin\": {\n\t\t\ta: \"Asia/Shanghai\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Hebron\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"PS\"]\n\t\t},\n\t\t\"Asia/Ho_Chi_Minh\": {\n\t\t\tu: 420,\n\t\t\tc: [\"VN\"]\n\t\t},\n\t\t\"Asia/Hong_Kong\": {\n\t\t\tu: 480,\n\t\t\tc: [\"HK\"]\n\t\t},\n\t\t\"Asia/Hovd\": {\n\t\t\tu: 420,\n\t\t\tc: [\"MN\"]\n\t\t},\n\t\t\"Asia/Irkutsk\": {\n\t\t\tu: 480,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Istanbul\": {\n\t\t\ta: \"Europe/Istanbul\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Jakarta\": {\n\t\t\tu: 420,\n\t\t\tc: [\"ID\"]\n\t\t},\n\t\t\"Asia/Jayapura\": {\n\t\t\tu: 540,\n\t\t\tc: [\"ID\"]\n\t\t},\n\t\t\"Asia/Jerusalem\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"IL\"]\n\t\t},\n\t\t\"Asia/Kabul\": {\n\t\t\tu: 270,\n\t\t\tc: [\"AF\"]\n\t\t},\n\t\t\"Asia/Kamchatka\": {\n\t\t\tu: 720,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Karachi\": {\n\t\t\tu: 300,\n\t\t\tc: [\"PK\"]\n\t\t},\n\t\t\"Asia/Kashgar\": {\n\t\t\ta: \"Asia/Urumqi\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Kathmandu\": {\n\t\t\tu: 345,\n\t\t\tc: [\"NP\"]\n\t\t},\n\t\t\"Asia/Katmandu\": {\n\t\t\ta: \"Asia/Kathmandu\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Khandyga\": {\n\t\t\tu: 540,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Kolkata\": {\n\t\t\tu: 330,\n\t\t\tc: [\"IN\"]\n\t\t},\n\t\t\"Asia/Krasnoyarsk\": {\n\t\t\tu: 420,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Kuala_Lumpur\": {\n\t\t\tu: 480,\n\t\t\tc: [\"MY\"]\n\t\t},\n\t\t\"Asia/Kuching\": {\n\t\t\tu: 480,\n\t\t\tc: [\"MY\"]\n\t\t},\n\t\t\"Asia/Kuwait\": {\n\t\t\ta: \"Asia/Riyadh\",\n\t\t\tc: [\"KW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Macao\": {\n\t\t\ta: \"Asia/Macau\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Macau\": {\n\t\t\tu: 480,\n\t\t\tc: [\"MO\"]\n\t\t},\n\t\t\"Asia/Magadan\": {\n\t\t\tu: 660,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Makassar\": {\n\t\t\tu: 480,\n\t\t\tc: [\"ID\"]\n\t\t},\n\t\t\"Asia/Manila\": {\n\t\t\tu: 480,\n\t\t\tc: [\"PH\"]\n\t\t},\n\t\t\"Asia/Muscat\": {\n\t\t\ta: \"Asia/Dubai\",\n\t\t\tc: [\"OM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Nicosia\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"CY\"]\n\t\t},\n\t\t\"Asia/Novokuznetsk\": {\n\t\t\tu: 420,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Novosibirsk\": {\n\t\t\tu: 420,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Omsk\": {\n\t\t\tu: 360,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Oral\": {\n\t\t\tu: 300,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Phnom_Penh\": {\n\t\t\ta: \"Asia/Bangkok\",\n\t\t\tc: [\"KH\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Pontianak\": {\n\t\t\tu: 420,\n\t\t\tc: [\"ID\"]\n\t\t},\n\t\t\"Asia/Pyongyang\": {\n\t\t\tu: 540,\n\t\t\tc: [\"KP\"]\n\t\t},\n\t\t\"Asia/Qatar\": {\n\t\t\tu: 180,\n\t\t\tc: [\"QA\", \"BH\"]\n\t\t},\n\t\t\"Asia/Qostanay\": {\n\t\t\tu: 360,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Qyzylorda\": {\n\t\t\tu: 300,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Rangoon\": {\n\t\t\ta: \"Asia/Yangon\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Riyadh\": {\n\t\t\tu: 180,\n\t\t\tc: [\"SA\", \"AQ\", \"KW\", \"YE\"]\n\t\t},\n\t\t\"Asia/Saigon\": {\n\t\t\ta: \"Asia/Ho_Chi_Minh\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Sakhalin\": {\n\t\t\tu: 660,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Samarkand\": {\n\t\t\tu: 300,\n\t\t\tc: [\"UZ\"]\n\t\t},\n\t\t\"Asia/Seoul\": {\n\t\t\tu: 540,\n\t\t\tc: [\"KR\"]\n\t\t},\n\t\t\"Asia/Shanghai\": {\n\t\t\tu: 480,\n\t\t\tc: [\"CN\"]\n\t\t},\n\t\t\"Asia/Singapore\": {\n\t\t\tu: 480,\n\t\t\tc: [\"SG\", \"MY\"]\n\t\t},\n\t\t\"Asia/Srednekolymsk\": {\n\t\t\tu: 660,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Taipei\": {\n\t\t\tu: 480,\n\t\t\tc: [\"TW\"]\n\t\t},\n\t\t\"Asia/Tashkent\": {\n\t\t\tu: 300,\n\t\t\tc: [\"UZ\"]\n\t\t},\n\t\t\"Asia/Tbilisi\": {\n\t\t\tu: 240,\n\t\t\tc: [\"GE\"]\n\t\t},\n\t\t\"Asia/Tehran\": {\n\t\t\tu: 210,\n\t\t\td: 270,\n\t\t\tc: [\"IR\"]\n\t\t},\n\t\t\"Asia/Tel_Aviv\": {\n\t\t\ta: \"Asia/Jerusalem\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Thimbu\": {\n\t\t\ta: \"Asia/Thimphu\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Thimphu\": {\n\t\t\tu: 360,\n\t\t\tc: [\"BT\"]\n\t\t},\n\t\t\"Asia/Tokyo\": {\n\t\t\tu: 540,\n\t\t\tc: [\"JP\"]\n\t\t},\n\t\t\"Asia/Tomsk\": {\n\t\t\tu: 420,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Ujung_Pandang\": {\n\t\t\ta: \"Asia/Makassar\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Ulaanbaatar\": {\n\t\t\tu: 480,\n\t\t\tc: [\"MN\"]\n\t\t},\n\t\t\"Asia/Ulan_Bator\": {\n\t\t\ta: \"Asia/Ulaanbaatar\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Urumqi\": {\n\t\t\tu: 360,\n\t\t\tc: [\"CN\"]\n\t\t},\n\t\t\"Asia/Ust-Nera\": {\n\t\t\tu: 600,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Vientiane\": {\n\t\t\ta: \"Asia/Bangkok\",\n\t\t\tc: [\"LA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Vladivostok\": {\n\t\t\tu: 600,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Yakutsk\": {\n\t\t\tu: 540,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Yangon\": {\n\t\t\tu: 390,\n\t\t\tc: [\"MM\"]\n\t\t},\n\t\t\"Asia/Yekaterinburg\": {\n\t\t\tu: 300,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Yerevan\": {\n\t\t\tu: 240,\n\t\t\tc: [\"AM\"]\n\t\t},\n\t\t\"Atlantic/Azores\": {\n\t\t\tu: -60,\n\t\t\td: 0,\n\t\t\tc: [\"PT\"]\n\t\t},\n\t\t\"Atlantic/Bermuda\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"BM\"]\n\t\t},\n\t\t\"Atlantic/Canary\": {\n\t\t\tu: 0,\n\t\t\td: 60,\n\t\t\tc: [\"ES\"]\n\t\t},\n\t\t\"Atlantic/Cape_Verde\": {\n\t\t\tu: -60,\n\t\t\tc: [\"CV\"]\n\t\t},\n\t\t\"Atlantic/Faeroe\": {\n\t\t\ta: \"Atlantic/Faroe\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Atlantic/Faroe\": {\n\t\t\tu: 0,\n\t\t\td: 60,\n\t\t\tc: [\"FO\"]\n\t\t},\n\t\t\"Atlantic/Jan_Mayen\": {\n\t\t\ta: \"Europe/Oslo\",\n\t\t\tc: [\"SJ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Atlantic/Madeira\": {\n\t\t\tu: 0,\n\t\t\td: 60,\n\t\t\tc: [\"PT\"]\n\t\t},\n\t\t\"Atlantic/Reykjavik\": {\n\t\t\tu: 0,\n\t\t\tc: [\"IS\"]\n\t\t},\n\t\t\"Atlantic/South_Georgia\": {\n\t\t\tu: -120,\n\t\t\tc: [\"GS\"]\n\t\t},\n\t\t\"Atlantic/St_Helena\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"SH\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Atlantic/Stanley\": {\n\t\t\tu: -180,\n\t\t\tc: [\"FK\"]\n\t\t},\n\t\t\"Australia/ACT\": {\n\t\t\ta: \"Australia/Sydney\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Adelaide\": {\n\t\t\tu: 570,\n\t\t\td: 630,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Brisbane\": {\n\t\t\tu: 600,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Broken_Hill\": {\n\t\t\tu: 570,\n\t\t\td: 630,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Canberra\": {\n\t\t\ta: \"Australia/Sydney\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Currie\": {\n\t\t\ta: \"Australia/Hobart\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Darwin\": {\n\t\t\tu: 570,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Eucla\": {\n\t\t\tu: 525,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Hobart\": {\n\t\t\tu: 600,\n\t\t\td: 660,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/LHI\": {\n\t\t\ta: \"Australia/Lord_Howe\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Lindeman\": {\n\t\t\tu: 600,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Lord_Howe\": {\n\t\t\tu: 630,\n\t\t\td: 660,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Melbourne\": {\n\t\t\tu: 600,\n\t\t\td: 660,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/NSW\": {\n\t\t\ta: \"Australia/Sydney\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/North\": {\n\t\t\ta: \"Australia/Darwin\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Perth\": {\n\t\t\tu: 480,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Queensland\": {\n\t\t\ta: \"Australia/Brisbane\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/South\": {\n\t\t\ta: \"Australia/Adelaide\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Sydney\": {\n\t\t\tu: 600,\n\t\t\td: 660,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Tasmania\": {\n\t\t\ta: \"Australia/Hobart\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Victoria\": {\n\t\t\ta: \"Australia/Melbourne\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/West\": {\n\t\t\ta: \"Australia/Perth\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Yancowinna\": {\n\t\t\ta: \"Australia/Broken_Hill\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Brazil/Acre\": {\n\t\t\ta: \"America/Rio_Branco\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Brazil/DeNoronha\": {\n\t\t\ta: \"America/Noronha\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Brazil/East\": {\n\t\t\ta: \"America/Sao_Paulo\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Brazil/West\": {\n\t\t\ta: \"America/Manaus\",\n\t\t\tr: 1\n\t\t},\n\t\tCET: {\n\t\t\tu: 60,\n\t\t\td: 120\n\t\t},\n\t\tCST6CDT: {\n\t\t\tu: -360,\n\t\t\td: -300\n\t\t},\n\t\t\"Canada/Atlantic\": {\n\t\t\ta: \"America/Halifax\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Central\": {\n\t\t\ta: \"America/Winnipeg\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Eastern\": {\n\t\t\ta: \"America/Toronto\",\n\t\t\tc: [\"CA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Mountain\": {\n\t\t\ta: \"America/Edmonton\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Newfoundland\": {\n\t\t\ta: \"America/St_Johns\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Pacific\": {\n\t\t\ta: \"America/Vancouver\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Saskatchewan\": {\n\t\t\ta: \"America/Regina\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Yukon\": {\n\t\t\ta: \"America/Whitehorse\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Chile/Continental\": {\n\t\t\ta: \"America/Santiago\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Chile/EasterIsland\": {\n\t\t\ta: \"Pacific/Easter\",\n\t\t\tr: 1\n\t\t},\n\t\tCuba: {\n\t\t\ta: \"America/Havana\",\n\t\t\tr: 1\n\t\t},\n\t\tEET: {\n\t\t\tu: 120,\n\t\t\td: 180\n\t\t},\n\t\tEST: {\n\t\t\tu: -300\n\t\t},\n\t\tEST5EDT: {\n\t\t\tu: -300,\n\t\t\td: -240\n\t\t},\n\t\tEgypt: {\n\t\t\ta: \"Africa/Cairo\",\n\t\t\tr: 1\n\t\t},\n\t\tEire: {\n\t\t\ta: \"Europe/Dublin\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/GMT\": {\n\t\t\tu: 0\n\t\t},\n\t\t\"Etc/GMT+0\": {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/GMT+1\": {\n\t\t\tu: -60\n\t\t},\n\t\t\"Etc/GMT+10\": {\n\t\t\tu: -600\n\t\t},\n\t\t\"Etc/GMT+11\": {\n\t\t\tu: -660\n\t\t},\n\t\t\"Etc/GMT+12\": {\n\t\t\tu: -720\n\t\t},\n\t\t\"Etc/GMT+2\": {\n\t\t\tu: -120\n\t\t},\n\t\t\"Etc/GMT+3\": {\n\t\t\tu: -180\n\t\t},\n\t\t\"Etc/GMT+4\": {\n\t\t\tu: -240\n\t\t},\n\t\t\"Etc/GMT+5\": {\n\t\t\tu: -300\n\t\t},\n\t\t\"Etc/GMT+6\": {\n\t\t\tu: -360\n\t\t},\n\t\t\"Etc/GMT+7\": {\n\t\t\tu: -420\n\t\t},\n\t\t\"Etc/GMT+8\": {\n\t\t\tu: -480\n\t\t},\n\t\t\"Etc/GMT+9\": {\n\t\t\tu: -540\n\t\t},\n\t\t\"Etc/GMT-0\": {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/GMT-1\": {\n\t\t\tu: 60\n\t\t},\n\t\t\"Etc/GMT-10\": {\n\t\t\tu: 600\n\t\t},\n\t\t\"Etc/GMT-11\": {\n\t\t\tu: 660\n\t\t},\n\t\t\"Etc/GMT-12\": {\n\t\t\tu: 720\n\t\t},\n\t\t\"Etc/GMT-13\": {\n\t\t\tu: 780\n\t\t},\n\t\t\"Etc/GMT-14\": {\n\t\t\tu: 840\n\t\t},\n\t\t\"Etc/GMT-2\": {\n\t\t\tu: 120\n\t\t},\n\t\t\"Etc/GMT-3\": {\n\t\t\tu: 180\n\t\t},\n\t\t\"Etc/GMT-4\": {\n\t\t\tu: 240\n\t\t},\n\t\t\"Etc/GMT-5\": {\n\t\t\tu: 300\n\t\t},\n\t\t\"Etc/GMT-6\": {\n\t\t\tu: 360\n\t\t},\n\t\t\"Etc/GMT-7\": {\n\t\t\tu: 420\n\t\t},\n\t\t\"Etc/GMT-8\": {\n\t\t\tu: 480\n\t\t},\n\t\t\"Etc/GMT-9\": {\n\t\t\tu: 540\n\t\t},\n\t\t\"Etc/GMT0\": {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/Greenwich\": {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/UCT\": {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/UTC\": {\n\t\t\tu: 0\n\t\t},\n\t\t\"Etc/Universal\": {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/Zulu\": {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Amsterdam\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"NL\"]\n\t\t},\n\t\t\"Europe/Andorra\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"AD\"]\n\t\t},\n\t\t\"Europe/Astrakhan\": {\n\t\t\tu: 240,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Athens\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"GR\"]\n\t\t},\n\t\t\"Europe/Belfast\": {\n\t\t\ta: \"Europe/London\",\n\t\t\tc: [\"GB\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Belgrade\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"RS\", \"BA\", \"HR\", \"ME\", \"MK\", \"SI\"]\n\t\t},\n\t\t\"Europe/Berlin\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"DE\"]\n\t\t},\n\t\t\"Europe/Bratislava\": {\n\t\t\ta: \"Europe/Prague\",\n\t\t\tc: [\"SK\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Brussels\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"BE\"]\n\t\t},\n\t\t\"Europe/Bucharest\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"RO\"]\n\t\t},\n\t\t\"Europe/Budapest\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"HU\"]\n\t\t},\n\t\t\"Europe/Busingen\": {\n\t\t\ta: \"Europe/Zurich\",\n\t\t\tc: [\"DE\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Chisinau\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"MD\"]\n\t\t},\n\t\t\"Europe/Copenhagen\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"DK\"]\n\t\t},\n\t\t\"Europe/Dublin\": {\n\t\t\tu: 60,\n\t\t\td: 0,\n\t\t\tc: [\"IE\"]\n\t\t},\n\t\t\"Europe/Gibraltar\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"GI\"]\n\t\t},\n\t\t\"Europe/Guernsey\": {\n\t\t\ta: \"Europe/London\",\n\t\t\tc: [\"GG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Helsinki\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"FI\", \"AX\"]\n\t\t},\n\t\t\"Europe/Isle_of_Man\": {\n\t\t\ta: \"Europe/London\",\n\t\t\tc: [\"IM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Istanbul\": {\n\t\t\tu: 180,\n\t\t\tc: [\"TR\"]\n\t\t},\n\t\t\"Europe/Jersey\": {\n\t\t\ta: \"Europe/London\",\n\t\t\tc: [\"JE\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Kaliningrad\": {\n\t\t\tu: 120,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Kiev\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"UA\"]\n\t\t},\n\t\t\"Europe/Kirov\": {\n\t\t\tu: 180,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Lisbon\": {\n\t\t\tu: 0,\n\t\t\td: 60,\n\t\t\tc: [\"PT\"]\n\t\t},\n\t\t\"Europe/Ljubljana\": {\n\t\t\ta: \"Europe/Belgrade\",\n\t\t\tc: [\"SI\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/London\": {\n\t\t\tu: 0,\n\t\t\td: 60,\n\t\t\tc: [\"GB\", \"GG\", \"IM\", \"JE\"]\n\t\t},\n\t\t\"Europe/Luxembourg\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"LU\"]\n\t\t},\n\t\t\"Europe/Madrid\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"ES\"]\n\t\t},\n\t\t\"Europe/Malta\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"MT\"]\n\t\t},\n\t\t\"Europe/Mariehamn\": {\n\t\t\ta: \"Europe/Helsinki\",\n\t\t\tc: [\"AX\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Minsk\": {\n\t\t\tu: 180,\n\t\t\tc: [\"BY\"]\n\t\t},\n\t\t\"Europe/Monaco\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"MC\"]\n\t\t},\n\t\t\"Europe/Moscow\": {\n\t\t\tu: 180,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Nicosia\": {\n\t\t\ta: \"Asia/Nicosia\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Oslo\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"NO\", \"SJ\", \"BV\"]\n\t\t},\n\t\t\"Europe/Paris\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"FR\"]\n\t\t},\n\t\t\"Europe/Podgorica\": {\n\t\t\ta: \"Europe/Belgrade\",\n\t\t\tc: [\"ME\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Prague\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"CZ\", \"SK\"]\n\t\t},\n\t\t\"Europe/Riga\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"LV\"]\n\t\t},\n\t\t\"Europe/Rome\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"IT\", \"SM\", \"VA\"]\n\t\t},\n\t\t\"Europe/Samara\": {\n\t\t\tu: 240,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/San_Marino\": {\n\t\t\ta: \"Europe/Rome\",\n\t\t\tc: [\"SM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Sarajevo\": {\n\t\t\ta: \"Europe/Belgrade\",\n\t\t\tc: [\"BA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Saratov\": {\n\t\t\tu: 240,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Simferopol\": {\n\t\t\tu: 180,\n\t\t\tc: [\"RU\", \"UA\"]\n\t\t},\n\t\t\"Europe/Skopje\": {\n\t\t\ta: \"Europe/Belgrade\",\n\t\t\tc: [\"MK\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Sofia\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"BG\"]\n\t\t},\n\t\t\"Europe/Stockholm\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"SE\"]\n\t\t},\n\t\t\"Europe/Tallinn\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"EE\"]\n\t\t},\n\t\t\"Europe/Tirane\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"AL\"]\n\t\t},\n\t\t\"Europe/Tiraspol\": {\n\t\t\ta: \"Europe/Chisinau\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Ulyanovsk\": {\n\t\t\tu: 240,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Uzhgorod\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"UA\"]\n\t\t},\n\t\t\"Europe/Vaduz\": {\n\t\t\ta: \"Europe/Zurich\",\n\t\t\tc: [\"LI\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Vatican\": {\n\t\t\ta: \"Europe/Rome\",\n\t\t\tc: [\"VA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Vienna\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"AT\"]\n\t\t},\n\t\t\"Europe/Vilnius\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"LT\"]\n\t\t},\n\t\t\"Europe/Volgograd\": {\n\t\t\tu: 180,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Warsaw\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"PL\"]\n\t\t},\n\t\t\"Europe/Zagreb\": {\n\t\t\ta: \"Europe/Belgrade\",\n\t\t\tc: [\"HR\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Zaporozhye\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"UA\"]\n\t\t},\n\t\t\"Europe/Zurich\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"CH\", \"DE\", \"LI\"]\n\t\t},\n\t\tFactory: {\n\t\t\tu: 0\n\t\t},\n\t\tGB: {\n\t\t\ta: \"Europe/London\",\n\t\t\tc: [\"GB\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"GB-Eire\": {\n\t\t\ta: \"Europe/London\",\n\t\t\tc: [\"GB\"],\n\t\t\tr: 1\n\t\t},\n\t\tGMT: {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\t\"GMT+0\": {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\t\"GMT-0\": {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\tGMT0: {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\tGreenwich: {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\tHST: {\n\t\t\tu: -600\n\t\t},\n\t\tHongkong: {\n\t\t\ta: \"Asia/Hong_Kong\",\n\t\t\tr: 1\n\t\t},\n\t\tIceland: {\n\t\t\ta: \"Atlantic/Reykjavik\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Indian/Antananarivo\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"MG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Indian/Chagos\": {\n\t\t\tu: 360,\n\t\t\tc: [\"IO\"]\n\t\t},\n\t\t\"Indian/Christmas\": {\n\t\t\tu: 420,\n\t\t\tc: [\"CX\"]\n\t\t},\n\t\t\"Indian/Cocos\": {\n\t\t\tu: 390,\n\t\t\tc: [\"CC\"]\n\t\t},\n\t\t\"Indian/Comoro\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"KM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Indian/Kerguelen\": {\n\t\t\tu: 300,\n\t\t\tc: [\"TF\", \"HM\"]\n\t\t},\n\t\t\"Indian/Mahe\": {\n\t\t\tu: 240,\n\t\t\tc: [\"SC\"]\n\t\t},\n\t\t\"Indian/Maldives\": {\n\t\t\tu: 300,\n\t\t\tc: [\"MV\"]\n\t\t},\n\t\t\"Indian/Mauritius\": {\n\t\t\tu: 240,\n\t\t\tc: [\"MU\"]\n\t\t},\n\t\t\"Indian/Mayotte\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"YT\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Indian/Reunion\": {\n\t\t\tu: 240,\n\t\t\tc: [\"RE\", \"TF\"]\n\t\t},\n\t\tIran: {\n\t\t\ta: \"Asia/Tehran\",\n\t\t\tr: 1\n\t\t},\n\t\tIsrael: {\n\t\t\ta: \"Asia/Jerusalem\",\n\t\t\tr: 1\n\t\t},\n\t\tJamaica: {\n\t\t\ta: \"America/Jamaica\",\n\t\t\tr: 1\n\t\t},\n\t\tJapan: {\n\t\t\ta: \"Asia/Tokyo\",\n\t\t\tr: 1\n\t\t},\n\t\tKwajalein: {\n\t\t\ta: \"Pacific/Kwajalein\",\n\t\t\tr: 1\n\t\t},\n\t\tLibya: {\n\t\t\ta: \"Africa/Tripoli\",\n\t\t\tr: 1\n\t\t},\n\t\tMET: {\n\t\t\tu: 60,\n\t\t\td: 120\n\t\t},\n\t\tMST: {\n\t\t\tu: -420\n\t\t},\n\t\tMST7MDT: {\n\t\t\tu: -420,\n\t\t\td: -360\n\t\t},\n\t\t\"Mexico/BajaNorte\": {\n\t\t\ta: \"America/Tijuana\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Mexico/BajaSur\": {\n\t\t\ta: \"America/Mazatlan\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Mexico/General\": {\n\t\t\ta: \"America/Mexico_City\",\n\t\t\tr: 1\n\t\t},\n\t\tNZ: {\n\t\t\ta: \"Pacific/Auckland\",\n\t\t\tc: [\"NZ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"NZ-CHAT\": {\n\t\t\ta: \"Pacific/Chatham\",\n\t\t\tr: 1\n\t\t},\n\t\tNavajo: {\n\t\t\ta: \"America/Denver\",\n\t\t\tr: 1\n\t\t},\n\t\tPRC: {\n\t\t\ta: \"Asia/Shanghai\",\n\t\t\tr: 1\n\t\t},\n\t\tPST8PDT: {\n\t\t\tu: -480,\n\t\t\td: -420\n\t\t},\n\t\t\"Pacific/Apia\": {\n\t\t\tu: 780,\n\t\t\tc: [\"WS\"]\n\t\t},\n\t\t\"Pacific/Auckland\": {\n\t\t\tu: 720,\n\t\t\td: 780,\n\t\t\tc: [\"NZ\", \"AQ\"]\n\t\t},\n\t\t\"Pacific/Bougainville\": {\n\t\t\tu: 660,\n\t\t\tc: [\"PG\"]\n\t\t},\n\t\t\"Pacific/Chatham\": {\n\t\t\tu: 765,\n\t\t\td: 825,\n\t\t\tc: [\"NZ\"]\n\t\t},\n\t\t\"Pacific/Chuuk\": {\n\t\t\tu: 600,\n\t\t\tc: [\"FM\"]\n\t\t},\n\t\t\"Pacific/Easter\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"CL\"]\n\t\t},\n\t\t\"Pacific/Efate\": {\n\t\t\tu: 660,\n\t\t\tc: [\"VU\"]\n\t\t},\n\t\t\"Pacific/Enderbury\": {\n\t\t\ta: \"Pacific/Kanton\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Fakaofo\": {\n\t\t\tu: 780,\n\t\t\tc: [\"TK\"]\n\t\t},\n\t\t\"Pacific/Fiji\": {\n\t\t\tu: 720,\n\t\t\td: 780,\n\t\t\tc: [\"FJ\"]\n\t\t},\n\t\t\"Pacific/Funafuti\": {\n\t\t\tu: 720,\n\t\t\tc: [\"TV\"]\n\t\t},\n\t\t\"Pacific/Galapagos\": {\n\t\t\tu: -360,\n\t\t\tc: [\"EC\"]\n\t\t},\n\t\t\"Pacific/Gambier\": {\n\t\t\tu: -540,\n\t\t\tc: [\"PF\"]\n\t\t},\n\t\t\"Pacific/Guadalcanal\": {\n\t\t\tu: 660,\n\t\t\tc: [\"SB\"]\n\t\t},\n\t\t\"Pacific/Guam\": {\n\t\t\tu: 600,\n\t\t\tc: [\"GU\", \"MP\"]\n\t\t},\n\t\t\"Pacific/Honolulu\": {\n\t\t\tu: -600,\n\t\t\tc: [\"US\", \"UM\"]\n\t\t},\n\t\t\"Pacific/Johnston\": {\n\t\t\ta: \"Pacific/Honolulu\",\n\t\t\tc: [\"UM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Kanton\": {\n\t\t\tu: 780,\n\t\t\tc: [\"KI\"]\n\t\t},\n\t\t\"Pacific/Kiritimati\": {\n\t\t\tu: 840,\n\t\t\tc: [\"KI\"]\n\t\t},\n\t\t\"Pacific/Kosrae\": {\n\t\t\tu: 660,\n\t\t\tc: [\"FM\"]\n\t\t},\n\t\t\"Pacific/Kwajalein\": {\n\t\t\tu: 720,\n\t\t\tc: [\"MH\"]\n\t\t},\n\t\t\"Pacific/Majuro\": {\n\t\t\tu: 720,\n\t\t\tc: [\"MH\"]\n\t\t},\n\t\t\"Pacific/Marquesas\": {\n\t\t\tu: -510,\n\t\t\tc: [\"PF\"]\n\t\t},\n\t\t\"Pacific/Midway\": {\n\t\t\ta: \"Pacific/Pago_Pago\",\n\t\t\tc: [\"UM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Nauru\": {\n\t\t\tu: 720,\n\t\t\tc: [\"NR\"]\n\t\t},\n\t\t\"Pacific/Niue\": {\n\t\t\tu: -660,\n\t\t\tc: [\"NU\"]\n\t\t},\n\t\t\"Pacific/Norfolk\": {\n\t\t\tu: 660,\n\t\t\td: 720,\n\t\t\tc: [\"NF\"]\n\t\t},\n\t\t\"Pacific/Noumea\": {\n\t\t\tu: 660,\n\t\t\tc: [\"NC\"]\n\t\t},\n\t\t\"Pacific/Pago_Pago\": {\n\t\t\tu: -660,\n\t\t\tc: [\"AS\", \"UM\"]\n\t\t},\n\t\t\"Pacific/Palau\": {\n\t\t\tu: 540,\n\t\t\tc: [\"PW\"]\n\t\t},\n\t\t\"Pacific/Pitcairn\": {\n\t\t\tu: -480,\n\t\t\tc: [\"PN\"]\n\t\t},\n\t\t\"Pacific/Pohnpei\": {\n\t\t\tu: 660,\n\t\t\tc: [\"FM\"]\n\t\t},\n\t\t\"Pacific/Ponape\": {\n\t\t\ta: \"Pacific/Pohnpei\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Port_Moresby\": {\n\t\t\tu: 600,\n\t\t\tc: [\"PG\", \"AQ\"]\n\t\t},\n\t\t\"Pacific/Rarotonga\": {\n\t\t\tu: -600,\n\t\t\tc: [\"CK\"]\n\t\t},\n\t\t\"Pacific/Saipan\": {\n\t\t\ta: \"Pacific/Guam\",\n\t\t\tc: [\"MP\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Samoa\": {\n\t\t\ta: \"Pacific/Pago_Pago\",\n\t\t\tc: [\"WS\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Tahiti\": {\n\t\t\tu: -600,\n\t\t\tc: [\"PF\"]\n\t\t},\n\t\t\"Pacific/Tarawa\": {\n\t\t\tu: 720,\n\t\t\tc: [\"KI\"]\n\t\t},\n\t\t\"Pacific/Tongatapu\": {\n\t\t\tu: 780,\n\t\t\tc: [\"TO\"]\n\t\t},\n\t\t\"Pacific/Truk\": {\n\t\t\ta: \"Pacific/Chuuk\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Wake\": {\n\t\t\tu: 720,\n\t\t\tc: [\"UM\"]\n\t\t},\n\t\t\"Pacific/Wallis\": {\n\t\t\tu: 720,\n\t\t\tc: [\"WF\"]\n\t\t},\n\t\t\"Pacific/Yap\": {\n\t\t\ta: \"Pacific/Chuuk\",\n\t\t\tr: 1\n\t\t},\n\t\tPoland: {\n\t\t\ta: \"Europe/Warsaw\",\n\t\t\tr: 1\n\t\t},\n\t\tPortugal: {\n\t\t\ta: \"Europe/Lisbon\",\n\t\t\tr: 1\n\t\t},\n\t\tROC: {\n\t\t\ta: \"Asia/Taipei\",\n\t\t\tr: 1\n\t\t},\n\t\tROK: {\n\t\t\ta: \"Asia/Seoul\",\n\t\t\tr: 1\n\t\t},\n\t\tSingapore: {\n\t\t\ta: \"Asia/Singapore\",\n\t\t\tc: [\"SG\"],\n\t\t\tr: 1\n\t\t},\n\t\tTurkey: {\n\t\t\ta: \"Europe/Istanbul\",\n\t\t\tr: 1\n\t\t},\n\t\tUCT: {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Alaska\": {\n\t\t\ta: \"America/Anchorage\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Aleutian\": {\n\t\t\ta: \"America/Adak\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Arizona\": {\n\t\t\ta: \"America/Phoenix\",\n\t\t\tc: [\"US\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Central\": {\n\t\t\ta: \"America/Chicago\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/East-Indiana\": {\n\t\t\ta: \"America/Indiana/Indianapolis\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Eastern\": {\n\t\t\ta: \"America/New_York\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Hawaii\": {\n\t\t\ta: \"Pacific/Honolulu\",\n\t\t\tc: [\"US\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Indiana-Starke\": {\n\t\t\ta: \"America/Indiana/Knox\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Michigan\": {\n\t\t\ta: \"America/Detroit\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Mountain\": {\n\t\t\ta: \"America/Denver\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Pacific\": {\n\t\t\ta: \"America/Los_Angeles\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Samoa\": {\n\t\t\ta: \"Pacific/Pago_Pago\",\n\t\t\tc: [\"WS\"],\n\t\t\tr: 1\n\t\t},\n\t\tUTC: {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t},\n\t\tUniversal: {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t},\n\t\t\"W-SU\": {\n\t\t\ta: \"Europe/Moscow\",\n\t\t\tr: 1\n\t\t},\n\t\tWET: {\n\t\t\tu: 0,\n\t\t\td: 60\n\t\t},\n\t\tZulu: {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t}\n};\n\n/**\n * Get full country name from user's timezone\n * @returns Full country name or null if timezone is unavailable\n */\nexport function getCountry(): string | null {\n\tconst timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n\tif (timezone === \"\" || !timezone) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst _country = timezones[timezone]?.c?.[0];\n\t\tif (!_country) return null;\n\t\tconst country = (countries as Record<string, string>)[_country];\n\t\treturn country || null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Get country code (ISO 3166-1 alpha-2) from user's timezone\n * Privacy-friendly alternative to IP geolocation\n * @returns ISO 3166-1 alpha-2 country code (e.g., \"US\", \"GB\") or \"Unknown\"\n */\nexport function getCountryCodeFromTimezone(): string {\n\tconst timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n\tif (timezone === \"\" || !timezone) {\n\t\treturn \"Unknown\";\n\t}\n\n\ttry {\n\t\tconst countryCode = timezones[timezone]?.c?.[0];\n\t\treturn countryCode || \"Unknown\";\n\t} catch {\n\t\treturn \"Unknown\";\n\t}\n}\n\nexport function getState(): string | null {\n\tconst timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n\tif (timezone === \"\" || !timezone) {\n\t\treturn null;\n\t}\n\t\n\tconst state = timezone.split(\"/\")[1]?.replace(\"_\", \" \");\n\t\n\treturn state || null;\n}\n", "/**\n * Page Tracking for Grain Analytics\n * Automatically tracks page views with consent-aware behavior\n */\n\nimport {\n categorizeReferrer,\n parseUTMParameters,\n getOrCreateFirstTouchAttribution,\n getSessionUTMParameters,\n setSessionUTMParameters,\n type UTMParameters,\n type FirstTouchAttribution,\n} from './attribution';\nimport { getCountryCodeFromTimezone } from './countries';\n\nexport interface PageTrackingConfig {\n stripQueryParams: boolean; // Default: true for privacy\n stripHash?: boolean; // Default: false\n debug?: boolean;\n tenantId: string;\n}\n\nexport interface PageTracker {\n trackSystemEvent(eventName: string, properties: Record<string, unknown>): void;\n hasConsent(category?: string): boolean;\n getEffectiveUserId(): string;\n getEphemeralSessionId(): string;\n getSessionId(): string;\n}\n\nexport class PageTrackingManager {\n private config: PageTrackingConfig;\n private tracker: PageTracker;\n private isDestroyed = false;\n private currentPath: string | null = null;\n private originalPushState: typeof history.pushState | null = null;\n private originalReplaceState: typeof history.replaceState | null = null;\n private previousPage: string | null = null;\n private landingPage: string | null = null;\n private pageViewCount = 0;\n\n constructor(tracker: PageTracker, config: PageTrackingConfig) {\n this.tracker = tracker;\n this.config = config;\n \n // Track initial page load (this is the landing page)\n this.trackCurrentPage(true);\n \n // Setup listeners\n this.setupHistoryListeners();\n this.setupHashChangeListener();\n }\n\n /**\n * Setup History API listeners (pushState, replaceState, popstate)\n */\n private setupHistoryListeners(): void {\n if (typeof window === 'undefined' || typeof history === 'undefined') return;\n\n // Wrap pushState\n this.originalPushState = history.pushState;\n history.pushState = (state: any, title: string, url?: string | URL | null) => {\n this.originalPushState?.call(history, state, title, url);\n this.trackCurrentPage();\n };\n\n // Wrap replaceState\n this.originalReplaceState = history.replaceState;\n history.replaceState = (state: any, title: string, url?: string | URL | null) => {\n this.originalReplaceState?.call(history, state, title, url);\n this.trackCurrentPage();\n };\n\n // Listen to popstate (back/forward buttons)\n window.addEventListener('popstate', this.handlePopState);\n }\n\n /**\n * Setup hash change listener\n */\n private setupHashChangeListener(): void {\n if (typeof window === 'undefined') return;\n window.addEventListener('hashchange', this.handleHashChange);\n }\n\n /**\n * Handle popstate event (back/forward navigation)\n */\n private handlePopState = (): void => {\n if (this.isDestroyed) return;\n this.trackCurrentPage();\n };\n\n /**\n * Handle hash change event\n */\n private handleHashChange = (): void => {\n if (this.isDestroyed) return;\n this.trackCurrentPage();\n };\n\n /**\n * Track the current page\n */\n private trackCurrentPage(isLanding: boolean = false): void {\n if (this.isDestroyed || typeof window === 'undefined') return;\n\n const page = this.extractPath(window.location.href);\n \n // Don't track if it's the same page (unless it's the landing page)\n if (!isLanding && page === this.currentPath) {\n return;\n }\n\n // Store previous page before updating\n if (this.currentPath) {\n this.previousPage = this.currentPath;\n }\n\n this.currentPath = page;\n this.pageViewCount++;\n\n // Set landing page on first view\n if (isLanding) {\n this.landingPage = page;\n }\n\n const hasConsent = this.tracker.hasConsent('analytics');\n const currentUrl = window.location.href;\n const referrer = document.referrer || '';\n\n // Parse UTM parameters from current URL\n const utmParams = parseUTMParameters(currentUrl);\n \n // Store session UTM if they exist (first time only or if new UTMs appear)\n if (Object.keys(utmParams).length > 0) {\n const existing = getSessionUTMParameters();\n if (!existing || isLanding) {\n setSessionUTMParameters(utmParams);\n }\n }\n\n // Get or create first-touch attribution\n const sessionUTMs = getSessionUTMParameters() || {};\n const firstTouch = getOrCreateFirstTouchAttribution(\n this.config.tenantId,\n referrer,\n currentUrl,\n sessionUTMs\n );\n\n // Base properties (always included)\n const properties: Record<string, unknown> = {\n page,\n timestamp: Date.now(),\n };\n\n // Enhanced properties when consent is granted\n if (hasConsent) {\n properties.title = document.title || '';\n properties.full_url = this.cleanUrl(currentUrl); // Clean URL based on privacy settings\n properties.session_id = this.tracker.getSessionId();\n\n // Add referrer info\n if (referrer) {\n properties.referrer = referrer;\n properties.referrer_domain = this.extractDomain(referrer);\n properties.referrer_category = categorizeReferrer(referrer, currentUrl);\n }\n\n // Add landing page if this is not the first view\n if (this.landingPage && !isLanding) {\n properties.landing_page = this.landingPage;\n }\n\n // Add previous page if available\n if (this.previousPage) {\n properties.previous_page = this.previousPage;\n }\n\n // Add UTM parameters if present (from session)\n if (sessionUTMs.utm_source) properties.utm_source = sessionUTMs.utm_source;\n if (sessionUTMs.utm_medium) properties.utm_medium = sessionUTMs.utm_medium;\n if (sessionUTMs.utm_campaign) properties.utm_campaign = sessionUTMs.utm_campaign;\n if (sessionUTMs.utm_term) properties.utm_term = sessionUTMs.utm_term;\n if (sessionUTMs.utm_content) properties.utm_content = sessionUTMs.utm_content;\n\n // Add first-touch attribution\n properties.first_touch_source = firstTouch.source;\n properties.first_touch_medium = firstTouch.medium;\n properties.first_touch_campaign = firstTouch.campaign;\n properties.first_touch_referrer_category = firstTouch.referrer_category;\n\n // Browser and device info\n properties.device = this.getDeviceType();\n properties.browser = this.getBrowser();\n properties.os = this.getOS();\n properties.language = navigator.language || '';\n \n // Timezone and country (privacy-friendly: derived from timezone, no IP tracking)\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n properties.timezone = timezone;\n properties.country = getCountryCodeFromTimezone();\n \n properties.screen_resolution = `${screen.width}x${screen.height}`;\n properties.viewport = `${window.innerWidth}x${window.innerHeight}`;\n }\n\n // Track the page view event\n this.tracker.trackSystemEvent('page_view', properties);\n }\n\n /**\n * Extract domain from URL\n */\n private extractDomain(url: string): string {\n try {\n const urlObj = new URL(url);\n return urlObj.hostname;\n } catch {\n return '';\n }\n }\n\n /**\n * Detect browser name\n */\n private getBrowser(): string {\n const ua = navigator.userAgent;\n if (ua.includes('Firefox/')) return 'Firefox';\n if (ua.includes('Edg/')) return 'Edge';\n if (ua.includes('Chrome/')) return 'Chrome';\n if (ua.includes('Safari/') && !ua.includes('Chrome/')) return 'Safari';\n if (ua.includes('Opera/') || ua.includes('OPR/')) return 'Opera';\n return 'Unknown';\n }\n\n /**\n * Detect operating system\n */\n private getOS(): string {\n const ua = navigator.userAgent;\n if (ua.includes('Win')) return 'Windows';\n if (ua.includes('Mac')) return 'macOS';\n if (ua.includes('Linux')) return 'Linux';\n if (ua.includes('Android')) return 'Android';\n if (ua.includes('iOS') || ua.includes('iPhone') || ua.includes('iPad')) return 'iOS';\n return 'Unknown';\n }\n\n /**\n * Detect device type (Mobile, Tablet, Desktop)\n */\n private getDeviceType(): string {\n const ua = navigator.userAgent;\n const width = window.innerWidth;\n \n // Check for tablet-specific indicators\n if (ua.includes('iPad') || (ua.includes('Android') && !ua.includes('Mobile'))) {\n return 'Tablet';\n }\n \n // Check for mobile indicators\n if (ua.includes('Mobile') || ua.includes('iPhone') || ua.includes('Android')) {\n return 'Mobile';\n }\n \n // Fallback to screen width detection\n if (width < 768) {\n return 'Mobile';\n } else if (width >= 768 && width < 1024) {\n return 'Tablet';\n }\n \n return 'Desktop';\n }\n\n /**\n * Extract path from URL, optionally stripping query parameters\n * Privacy-first: strips query params by default\n */\n private extractPath(url: string): string {\n try {\n const urlObj = new URL(url);\n let path = urlObj.pathname;\n \n // Include query params only if not stripping\n if (!this.config.stripQueryParams && urlObj.search) {\n path += urlObj.search;\n }\n \n // Include hash only if not stripping\n if (!this.config.stripHash && urlObj.hash) {\n path += urlObj.hash;\n }\n \n return path;\n } catch (error) {\n // If URL parsing fails, return the raw string\n if (this.config.debug) {\n console.warn('[Page Tracking] Failed to parse URL:', url, error);\n }\n return url;\n }\n }\n\n /**\n * Clean URL for privacy (strip query params based on config)\n */\n private cleanUrl(url: string): string {\n if (!this.config.stripQueryParams) {\n return url;\n }\n \n try {\n const urlObj = new URL(url);\n return `${urlObj.origin}${urlObj.pathname}${this.config.stripHash ? '' : urlObj.hash}`;\n } catch (error) {\n return url;\n }\n }\n\n /**\n * Get the current page path\n */\n getCurrentPage(): string | null {\n return this.currentPath;\n }\n\n /**\n * Manually track a page view (for custom navigation)\n */\n trackPage(page: string, properties?: Record<string, unknown>): void {\n if (this.isDestroyed) return;\n\n const hasConsent = this.tracker.hasConsent('analytics');\n\n // Base properties\n const baseProperties: Record<string, unknown> = {\n page,\n timestamp: Date.now(),\n ...properties,\n };\n\n // Enhanced properties when consent is granted\n if (hasConsent && typeof document !== 'undefined' && typeof window !== 'undefined') {\n if (!baseProperties.referrer) {\n baseProperties.referrer = document.referrer || '';\n }\n if (!baseProperties.title) {\n baseProperties.title = document.title || '';\n }\n if (!baseProperties.full_url) {\n baseProperties.full_url = window.location.href;\n }\n if (!baseProperties.session_id) {\n baseProperties.session_id = this.tracker.getSessionId();\n }\n if (!baseProperties.browser) {\n baseProperties.browser = this.getBrowser();\n }\n if (!baseProperties.os) {\n baseProperties.os = this.getOS();\n }\n }\n\n this.tracker.trackSystemEvent('page_view', baseProperties);\n }\n\n /**\n * Get page view count for current session\n */\n getPageViewCount(): number {\n return this.pageViewCount;\n }\n\n /**\n * Destroy the page tracker\n */\n destroy(): void {\n if (this.isDestroyed) return;\n\n // Restore original history methods\n if (typeof history !== 'undefined') {\n if (this.originalPushState) {\n history.pushState = this.originalPushState;\n }\n if (this.originalReplaceState) {\n history.replaceState = this.originalReplaceState;\n }\n }\n\n // Remove event listeners\n if (typeof window !== 'undefined') {\n window.removeEventListener('popstate', this.handlePopState);\n window.removeEventListener('hashchange', this.handleHashChange);\n }\n\n this.isDestroyed = true;\n }\n}\n\n", "/**\n * ID Manager for Grain Analytics\n * Generates and manages user IDs based on consent mode\n * \n * Privacy-first implementation:\n * - Cookieless mode: Daily rotating IDs (no persistence)\n * - GDPR Strict: Permanent IDs only with consent\n * - GDPR Opt-out: Permanent IDs by default\n */\n\nexport type IdMode = 'cookieless' | 'permanent';\n\nexport interface IdConfig {\n mode: IdMode;\n tenantId: string;\n useLocalStorage?: boolean; // For permanent IDs only\n}\n\n/**\n * Generate a simple hash from a string\n */\nfunction simpleHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return Math.abs(hash).toString(36);\n}\n\n/**\n * Generate a UUID v4\n */\nfunction generateUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n \n // Fallback for older browsers\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = Math.random() * 16 | 0;\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\n\n/**\n * Get minimal browser fingerprint for daily ID generation\n * NOT for tracking, just for same-day continuity\n */\nfunction getBrowserFingerprint(): string {\n if (typeof window === 'undefined') return 'server';\n \n const components: string[] = [\n screen.width?.toString() || '',\n screen.height?.toString() || '',\n navigator.language || '',\n Intl.DateTimeFormat().resolvedOptions().timeZone || ''\n ];\n \n return simpleHash(components.join('|'));\n}\n\n/**\n * Get current date string in local timezone (YYYY-MM-DD)\n */\nfunction getLocalDateString(): string {\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const day = String(now.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n}\n\n/**\n * ID Manager class\n * Handles both daily rotating IDs and permanent IDs\n */\nexport class IdManager {\n private config: IdConfig;\n private cachedDailyId: string | null = null;\n private dailyIdDate: string | null = null;\n private permanentId: string | null = null;\n \n constructor(config: IdConfig) {\n this.config = config;\n \n // Load permanent ID from localStorage if in permanent mode\n if (config.mode === 'permanent' && config.useLocalStorage) {\n this.loadPermanentId();\n }\n }\n \n /**\n * Generate a daily rotating ID\n * Rotates at midnight in user's local timezone\n * Provides same-day continuity without persistent tracking\n */\n generateDailyRotatingId(): string {\n const currentDate = getLocalDateString();\n \n // Return cached ID if still the same day\n if (this.cachedDailyId && this.dailyIdDate === currentDate) {\n return this.cachedDailyId;\n }\n \n // Generate new daily ID\n const fingerprint = getBrowserFingerprint();\n const seed = `${this.config.tenantId}|${currentDate}|${fingerprint}`;\n const dailyId = `daily_${simpleHash(seed)}_${simpleHash(Date.now().toString())}`;\n \n // Cache for same-day requests\n this.cachedDailyId = dailyId;\n this.dailyIdDate = currentDate;\n \n return dailyId;\n }\n \n /**\n * Generate or retrieve permanent user ID\n * Only used when consent is given\n */\n generatePermanentId(): string {\n if (this.permanentId) {\n return this.permanentId;\n }\n \n // Try to load from localStorage\n if (this.config.useLocalStorage) {\n const stored = this.loadPermanentId();\n if (stored) {\n return stored;\n }\n }\n \n // Generate new permanent ID\n const newId = generateUUID();\n this.permanentId = newId;\n \n // Store in localStorage if enabled\n if (this.config.useLocalStorage) {\n this.savePermanentId(newId);\n }\n \n return newId;\n }\n \n /**\n * Get the current user ID based on mode\n */\n getCurrentUserId(): string {\n if (this.config.mode === 'cookieless') {\n return this.generateDailyRotatingId();\n } else {\n return this.generatePermanentId();\n }\n }\n \n /**\n * Switch ID mode (e.g., when consent is granted/revoked)\n */\n setMode(mode: IdMode): void {\n this.config.mode = mode;\n \n // Clear cached daily ID when switching to permanent\n if (mode === 'permanent') {\n this.cachedDailyId = null;\n this.dailyIdDate = null;\n }\n \n // Clear permanent ID when switching to cookieless\n if (mode === 'cookieless') {\n this.permanentId = null;\n if (this.config.useLocalStorage) {\n this.clearPermanentId();\n }\n }\n }\n \n /**\n * Load permanent ID from localStorage\n */\n private loadPermanentId(): string | null {\n if (typeof window === 'undefined') return null;\n \n try {\n const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n this.permanentId = stored;\n return stored;\n }\n } catch (error) {\n // Silent failure - localStorage might be disabled\n }\n \n return null;\n }\n \n /**\n * Save permanent ID to localStorage\n */\n private savePermanentId(id: string): void {\n if (typeof window === 'undefined') return;\n \n try {\n const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;\n localStorage.setItem(storageKey, id);\n } catch (error) {\n // Silent failure - localStorage might be disabled\n }\n }\n \n /**\n * Clear permanent ID from localStorage\n */\n private clearPermanentId(): void {\n if (typeof window === 'undefined') return;\n \n try {\n const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;\n localStorage.removeItem(storageKey);\n } catch (error) {\n // Silent failure\n }\n }\n \n /**\n * Get info about current ID for debugging\n */\n getIdInfo(): { mode: IdMode; id: string; isDailyRotating: boolean } {\n const id = this.getCurrentUserId();\n return {\n mode: this.config.mode,\n id: id,\n isDailyRotating: id.startsWith('daily_')\n };\n }\n}\n"],
|
|
5
|
-
"mappings": "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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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I;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAA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",
|
|
4
|
+
"sourcesContent": ["/**\n * Attention Quality Manager for Grain Analytics\n * Enforces policies to ensure tracked data represents genuine user attention\n * \n * Policies:\n * 1. Page Visibility: Stop tracking when tab is hidden/backgrounded\n * 2. User Activity: Stop tracking when user is idle (no mouse/keyboard/touch)\n * 3. Section Duration Cap: Max attention per section before requiring transition\n * 4. Scroll Distance: Minimum scroll distance to count as meaningful engagement\n * \n * See: ATTENTION_QUALITY_POLICY.md for detailed policy documentation\n */\n\nimport type { ActivityDetector } from './activity';\n\nexport interface AttentionQualityOptions {\n /**\n * Maximum continuous attention duration per section (ms)\n * Default: 9000 (9 seconds)\n */\n maxSectionDuration?: number;\n\n /**\n * Minimum scroll distance to reset attention timer (px)\n * Default: 100\n */\n minScrollDistance?: number;\n\n /**\n * Idle threshold - stop tracking after this period of inactivity (ms)\n * Default: 30000 (30 seconds)\n */\n idleThreshold?: number;\n\n /**\n * Enable debug logging\n */\n debug?: boolean;\n}\n\ninterface SectionAttentionState {\n sectionName: string;\n currentDuration: number; // Cumulative duration in current attention block\n lastScrollPosition: number;\n lastResetTime: number;\n}\n\nconst DEFAULT_OPTIONS: Required<Omit<AttentionQualityOptions, 'debug'>> = {\n maxSectionDuration: 9000, // 9 seconds\n minScrollDistance: 100, // 100 pixels\n idleThreshold: 30000, // 30 seconds\n};\n\nexport class AttentionQualityManager {\n private options: Required<Omit<AttentionQualityOptions, 'debug'>> & { debug: boolean };\n private activityDetector: ActivityDetector;\n private isDestroyed = false;\n\n // Page visibility tracking\n private isPageVisible = true;\n private visibilityChangeHandler: (() => void) | null = null;\n\n // Section attention state\n private sectionStates = new Map<string, SectionAttentionState>();\n\n // Policies applied reasons (for debugging/traceability)\n private lastFilterReason: string | null = null;\n\n constructor(activityDetector: ActivityDetector, options: AttentionQualityOptions = {}) {\n this.activityDetector = activityDetector;\n this.options = {\n ...DEFAULT_OPTIONS,\n ...options,\n debug: options.debug ?? false,\n };\n\n this.setupPageVisibilityTracking();\n }\n\n /**\n * Setup page visibility tracking\n */\n private setupPageVisibilityTracking(): void {\n if (typeof document === 'undefined') return;\n\n this.isPageVisible = document.visibilityState === 'visible';\n\n this.visibilityChangeHandler = () => {\n const wasVisible = this.isPageVisible;\n this.isPageVisible = document.visibilityState === 'visible';\n\n if (!this.isPageVisible && wasVisible) {\n this.log('Page hidden - tracking paused');\n } else if (this.isPageVisible && !wasVisible) {\n this.log('Page visible - tracking resumed');\n // Reset all section states when page becomes visible again\n this.resetAllSections();\n }\n };\n\n document.addEventListener('visibilitychange', this.visibilityChangeHandler);\n }\n\n /**\n * Check if tracking should be allowed (global check)\n * Returns true if tracking is allowed, false if it should be paused\n */\n shouldTrack(): boolean {\n // Policy 1: Page Visibility\n if (!this.isPageVisible) {\n this.lastFilterReason = 'page_hidden';\n return false;\n }\n\n // Policy 2: User Activity\n if (!this.activityDetector.isActive(this.options.idleThreshold)) {\n this.lastFilterReason = 'user_idle';\n return false;\n }\n\n this.lastFilterReason = null;\n return true;\n }\n\n /**\n * Check if section view tracking should be allowed for a specific section\n * @param sectionName - Section identifier\n * @param currentScrollY - Current scroll position\n * @returns Object with shouldTrack boolean and optional reason\n */\n shouldTrackSection(sectionName: string, currentScrollY: number): {\n shouldTrack: boolean;\n reason?: string;\n resetAttention?: boolean;\n } {\n // First check global tracking state\n if (!this.shouldTrack()) {\n return {\n shouldTrack: false,\n reason: this.lastFilterReason || 'global_policy',\n };\n }\n\n // Get or create section state\n let state = this.sectionStates.get(sectionName);\n if (!state) {\n state = {\n sectionName,\n currentDuration: 0,\n lastScrollPosition: currentScrollY,\n lastResetTime: Date.now(),\n };\n this.sectionStates.set(sectionName, state);\n }\n\n // Policy 4: Scroll Distance - Check if user has scrolled enough to reset attention\n const scrollDistance = Math.abs(currentScrollY - state.lastScrollPosition);\n const hasScrolledEnough = scrollDistance >= this.options.minScrollDistance;\n\n if (hasScrolledEnough) {\n // Reset attention timer due to meaningful scroll\n this.log(`Section \"${sectionName}\": Attention reset due to ${Math.round(scrollDistance)}px scroll`);\n state.currentDuration = 0;\n state.lastScrollPosition = currentScrollY;\n state.lastResetTime = Date.now();\n return {\n shouldTrack: true,\n resetAttention: true,\n };\n }\n\n // Policy 3: Section Duration Cap\n if (state.currentDuration >= this.options.maxSectionDuration) {\n return {\n shouldTrack: false,\n reason: 'max_duration_reached',\n };\n }\n\n return {\n shouldTrack: true,\n };\n }\n\n /**\n * Update section duration (call this when tracking a section view event)\n * @param sectionName - Section identifier\n * @param durationMs - Duration to add to current attention block\n */\n updateSectionDuration(sectionName: string, durationMs: number): void {\n const state = this.sectionStates.get(sectionName);\n if (state) {\n state.currentDuration += durationMs;\n \n if (state.currentDuration >= this.options.maxSectionDuration) {\n this.log(`Section \"${sectionName}\": Max duration cap reached (${state.currentDuration}ms)`);\n }\n }\n }\n\n /**\n * Reset attention for a specific section (call when user navigates to different section)\n * @param sectionName - Section identifier\n */\n resetSection(sectionName: string): void {\n const state = this.sectionStates.get(sectionName);\n if (state) {\n this.log(`Section \"${sectionName}\": Attention reset (section exit)`);\n state.currentDuration = 0;\n state.lastResetTime = Date.now();\n }\n }\n\n /**\n * Reset all section attention states\n */\n resetAllSections(): void {\n this.log('Resetting all section attention states');\n for (const state of this.sectionStates.values()) {\n state.currentDuration = 0;\n state.lastResetTime = Date.now();\n }\n }\n\n /**\n * Get current attention state for a section (for debugging/monitoring)\n */\n getSectionState(sectionName: string): SectionAttentionState | undefined {\n return this.sectionStates.get(sectionName);\n }\n\n /**\n * Get reason why last tracking attempt was filtered\n */\n getLastFilterReason(): string | null {\n return this.lastFilterReason;\n }\n\n /**\n * Check if scroll tracking should be allowed\n * Similar to shouldTrack() but also checks scroll-specific conditions\n */\n shouldTrackScroll(previousScrollY: number, currentScrollY: number): {\n shouldTrack: boolean;\n reason?: string;\n } {\n // First check global tracking state\n if (!this.shouldTrack()) {\n return {\n shouldTrack: false,\n reason: this.lastFilterReason || 'global_policy',\n };\n }\n\n // Check if scroll is meaningful\n const scrollDistance = Math.abs(currentScrollY - previousScrollY);\n if (scrollDistance < 10) { // Minimum 10px to count as scroll\n return {\n shouldTrack: false,\n reason: 'scroll_too_small',\n };\n }\n\n return {\n shouldTrack: true,\n };\n }\n\n /**\n * Get all active policies as object (for monitoring/debugging)\n */\n getPolicies(): {\n maxSectionDuration: number;\n minScrollDistance: number;\n idleThreshold: number;\n } {\n return {\n maxSectionDuration: this.options.maxSectionDuration,\n minScrollDistance: this.options.minScrollDistance,\n idleThreshold: this.options.idleThreshold,\n };\n }\n\n /**\n * Get current tracking state (for monitoring/debugging)\n */\n getTrackingState(): {\n isPageVisible: boolean;\n isUserActive: boolean;\n timeSinceLastActivity: number;\n activeSections: number;\n } {\n return {\n isPageVisible: this.isPageVisible,\n isUserActive: this.activityDetector.isActive(this.options.idleThreshold),\n timeSinceLastActivity: this.activityDetector.getTimeSinceLastActivity(),\n activeSections: this.sectionStates.size,\n };\n }\n\n /**\n * Log debug messages\n */\n private log(...args: unknown[]): void {\n if (this.options.debug) {\n console.log('[AttentionQuality]', ...args);\n }\n }\n\n /**\n * Destroy and cleanup\n */\n destroy(): void {\n if (this.isDestroyed) return;\n\n this.isDestroyed = true;\n\n // Remove visibility change listener\n if (this.visibilityChangeHandler && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this.visibilityChangeHandler);\n this.visibilityChangeHandler = null;\n }\n\n // Clear section states\n this.sectionStates.clear();\n }\n}\n\n", "/**\n * Text utility functions for cleaning and processing text content\n */\n\n/**\n * Remove emojis and other Unicode symbols from text\n * This regex matches emoji ranges and other Unicode symbols\n */\nexport function removeEmojis(text: string | null | undefined): string | undefined {\n if (!text) return undefined;\n \n // Remove emojis and other Unicode symbols\n // This regex covers:\n // - Emoticons (\uD83D\uDE00-\uD83D\uDE4F)\n // - Miscellaneous Symbols and Pictographs (\uD83C\uDC00-\uD83F\uDFFF)\n // - Supplemental Symbols and Pictographs (\uD83C\uDE00-\uD83C\uDE3F)\n // - Transport and Map Symbols (\uD83D\uDE80-\uD83D\uDEFF)\n // - Enclosed characters (\u24C2-\u24FF)\n // - Regional indicator symbols (\uD83C\uDDE6-\uD83C\uDDFF)\n // - Other Unicode symbol ranges\n return text\n .replace(/[\\u{1F300}-\\u{1F9FF}]/gu, '') // Miscellaneous Symbols and Pictographs\n .replace(/[\\u{1F600}-\\u{1F64F}]/gu, '') // Emoticons\n .replace(/[\\u{1F680}-\\u{1F6FF}]/gu, '') // Transport and Map Symbols\n .replace(/[\\u{2600}-\\u{26FF}]/gu, '') // Miscellaneous Symbols\n .replace(/[\\u{2700}-\\u{27BF}]/gu, '') // Dingbats\n .replace(/[\\u{1F900}-\\u{1F9FF}]/gu, '') // Supplemental Symbols and Pictographs\n .replace(/[\\u{1F1E0}-\\u{1F1FF}]/gu, '') // Regional Indicator Symbols (flags)\n .replace(/[\\u{200D}]/gu, '') // Zero Width Joiner\n .replace(/[\\u{FE0F}]/gu, '') // Variation Selector-16\n .replace(/[\\u{20E3}]/gu, '') // Combining Enclosing Keycap\n .trim();\n}\n\n/**\n * Clean and truncate text content for event tracking\n * Removes emojis, trims whitespace, and limits length\n */\nexport function cleanElementText(text: string | null | undefined, maxLength: number = 100): string | undefined {\n if (!text) return undefined;\n \n const cleaned = removeEmojis(text);\n if (!cleaned) return undefined;\n \n return cleaned.substring(0, maxLength) || undefined;\n}\n", "/**\n * Heatmap Tracking Manager for Grain Analytics\n * Tracks click interactions and scroll depth across all pages\n */\n\nimport type {\n HeatmapClickData,\n HeatmapScrollData,\n HeatmapTrackingOptions,\n HeatmapScrollState,\n} from './types/heatmap-tracking';\nimport { AttentionQualityManager } from './attention-quality';\nimport type { ActivityDetector } from './activity';\nimport { cleanElementText } from './text-utils';\n\nexport interface SendEventOptions {\n flush?: boolean;\n}\n\nexport interface HeatmapTracker {\n trackSystemEvent(eventName: string, properties?: Record<string, unknown>, options?: SendEventOptions): void | Promise<void>;\n hasConsent(category: 'analytics' | 'marketing' | 'functional'): boolean;\n getActivityDetector(): ActivityDetector;\n log(...args: unknown[]): void;\n}\n\nconst DEFAULT_OPTIONS: HeatmapTrackingOptions = {\n scrollDebounceDelay: 100,\n batchDelay: 2000,\n maxBatchSize: 20,\n debug: false,\n};\n\nexport class HeatmapTrackingManager {\n private tracker: HeatmapTracker;\n private options: HeatmapTrackingOptions;\n private isDestroyed = false;\n\n // Tracking state\n private currentScrollState: HeatmapScrollState | null = null;\n private pendingClicks: HeatmapClickData[] = [];\n private pendingScrolls: HeatmapScrollData[] = [];\n\n // Timers\n private scrollDebounceTimer: number | null = null;\n private batchTimer: number | null = null;\n private scrollTrackingTimer: number | null = null;\n private periodicScrollTimer: number | null = null;\n\n // Scroll tracking\n private lastScrollPosition = 0;\n private lastScrollTime = Date.now();\n private readonly SPLIT_DURATION = 3000; // 3 seconds - same as section tracking\n\n // Attention quality management\n private attentionQuality: AttentionQualityManager;\n\n constructor(\n tracker: HeatmapTracker,\n options: Partial<HeatmapTrackingOptions> = {}\n ) {\n this.tracker = tracker;\n this.options = { ...DEFAULT_OPTIONS, ...options };\n\n // Initialize attention quality manager\n this.attentionQuality = new AttentionQualityManager(\n tracker.getActivityDetector(),\n {\n maxSectionDuration: 9000, // 9 seconds per viewport section\n minScrollDistance: 100, // 100 pixels\n idleThreshold: 30000, // 30 seconds\n debug: this.options.debug,\n }\n );\n\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Initialize after DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => this.initialize());\n } else {\n setTimeout(() => this.initialize(), 0);\n }\n }\n }\n\n /**\n * Initialize heatmap tracking\n */\n private initialize(): void {\n if (this.isDestroyed) return;\n\n this.log('Initializing heatmap tracking');\n\n // Setup click tracking\n this.setupClickTracking();\n\n // Setup scroll tracking\n this.setupScrollTracking();\n\n // Start periodic scroll state tracking\n this.startScrollTracking();\n\n // Setup page unload handler for beaconing\n this.setupUnloadHandler();\n }\n\n /**\n * Setup click event tracking\n */\n private setupClickTracking(): void {\n if (typeof document === 'undefined') return;\n\n const clickHandler = (event: MouseEvent) => {\n if (this.isDestroyed) return;\n // v3: Always track events - consent only affects ID type (daily vs permanent)\n // Removed: if (!this.tracker.hasConsent('analytics')) return;\n\n this.handleClick(event);\n };\n\n document.addEventListener('click', clickHandler, { passive: true, capture: true });\n }\n\n /**\n * Setup scroll event tracking\n */\n private setupScrollTracking(): void {\n if (typeof window === 'undefined') return;\n\n const scrollHandler = () => {\n if (this.scrollDebounceTimer !== null) {\n clearTimeout(this.scrollDebounceTimer);\n }\n\n this.scrollDebounceTimer = window.setTimeout(() => {\n this.handleScroll();\n this.scrollDebounceTimer = null;\n }, this.options.scrollDebounceDelay);\n };\n\n window.addEventListener('scroll', scrollHandler, { passive: true });\n }\n\n /**\n * Start periodic scroll state tracking\n */\n private startScrollTracking(): void {\n if (typeof window === 'undefined') return;\n\n // Track initial scroll position\n this.updateScrollState();\n\n // Update scroll state every 500ms (for detecting section changes)\n this.scrollTrackingTimer = window.setInterval(() => {\n if (this.isDestroyed) return;\n this.updateScrollState();\n }, 500);\n\n // Start periodic 3-second scroll duration tracking\n this.startPeriodicScrollTracking();\n }\n\n /**\n * Start periodic scroll tracking (sends events every 3 seconds)\n */\n private startPeriodicScrollTracking(): void {\n if (typeof window === 'undefined') return;\n\n this.periodicScrollTimer = window.setInterval(() => {\n if (this.isDestroyed || !this.currentScrollState) return;\n // v3: Always track events - consent only affects ID type (daily vs permanent)\n // Removed: if (!this.tracker.hasConsent('analytics')) return;\n\n // Check attention quality policies\n if (!this.attentionQuality.shouldTrack()) {\n this.log('Scroll tracking paused:', this.attentionQuality.getLastFilterReason());\n return;\n }\n\n const currentTime = Date.now();\n const duration = currentTime - this.currentScrollState.entryTime;\n\n // Only send if meaningful duration (> 1 second)\n if (duration > 1000) {\n const scrollY = window.scrollY || window.pageYOffset;\n const viewportHeight = window.innerHeight;\n const pageHeight = document.documentElement.scrollHeight;\n\n // Check section-specific attention quality\n const sectionKey = `viewport_section_${this.currentScrollState.viewportSection}`;\n const attentionCheck = this.attentionQuality.shouldTrackSection(sectionKey, scrollY);\n\n // If attention was reset due to scroll, reset our entry time\n if (attentionCheck.resetAttention) {\n this.log(`Viewport section ${this.currentScrollState.viewportSection}: Attention reset`);\n this.currentScrollState.entryTime = currentTime;\n return;\n }\n\n // If max duration reached for this viewport section\n if (!attentionCheck.shouldTrack) {\n this.log(`Viewport section ${this.currentScrollState.viewportSection}: ${attentionCheck.reason}`);\n return;\n }\n\n const scrollData: HeatmapScrollData = {\n pageUrl: window.location.href,\n viewportSection: this.currentScrollState.viewportSection,\n scrollDepthPx: scrollY,\n durationMs: duration,\n entryTimestamp: this.currentScrollState.entryTime,\n exitTimestamp: currentTime,\n pageHeight,\n viewportHeight,\n };\n\n // Send immediately using beacon to ensure delivery\n this.tracker.trackSystemEvent('_grain_heatmap_scroll', {\n page_url: scrollData.pageUrl,\n viewport_section: scrollData.viewportSection,\n scroll_depth_px: scrollData.scrollDepthPx,\n duration_ms: scrollData.durationMs,\n entry_timestamp: scrollData.entryTimestamp,\n exit_timestamp: scrollData.exitTimestamp,\n page_height: scrollData.pageHeight,\n viewport_height: scrollData.viewportHeight,\n is_split: true, // Flag to indicate periodic tracking, not final exit\n }, { flush: true });\n\n // Update attention quality duration tracker\n this.attentionQuality.updateSectionDuration(sectionKey, duration);\n\n // Reset entry time for next period\n this.currentScrollState.entryTime = currentTime;\n }\n }, this.SPLIT_DURATION);\n }\n\n /**\n * Setup page unload handler to beacon remaining data\n */\n private setupUnloadHandler(): void {\n if (typeof window === 'undefined') return;\n\n const unloadHandler = () => {\n // Finalize current scroll state\n if (this.currentScrollState) {\n const currentTime = Date.now();\n const duration = currentTime - this.currentScrollState.entryTime;\n\n if (duration > 100) {\n const scrollData: HeatmapScrollData = {\n pageUrl: window.location.href,\n viewportSection: this.currentScrollState.viewportSection,\n scrollDepthPx: this.currentScrollState.scrollDepthPx,\n durationMs: duration,\n entryTimestamp: this.currentScrollState.entryTime,\n exitTimestamp: currentTime,\n pageHeight: document.documentElement.scrollHeight,\n viewportHeight: window.innerHeight,\n };\n\n this.pendingScrolls.push(scrollData);\n }\n }\n\n // Flush all pending events with beacon\n this.flushPendingEventsWithBeacon();\n };\n\n // Use both events for better compatibility\n window.addEventListener('beforeunload', unloadHandler);\n window.addEventListener('pagehide', unloadHandler);\n }\n\n /**\n * Handle click event\n */\n private handleClick(event: MouseEvent): void {\n // v3: Always track events - consent only affects ID type (daily vs permanent)\n // Removed: if (!this.tracker.hasConsent('analytics')) return;\n\n const element = event.target as HTMLElement;\n if (!element) return;\n\n const pageUrl = window.location.href;\n const xpath = this.generateXPath(element);\n \n // Get viewport coordinates\n const viewportX = Math.round(event.clientX);\n const viewportY = Math.round(event.clientY);\n \n // Get page coordinates (including scroll offset)\n const pageX = Math.round(event.pageX);\n const pageY = Math.round(event.pageY);\n \n const elementTag = element.tagName?.toLowerCase() || 'unknown';\n const elementText = cleanElementText(element.textContent);\n\n const clickData: HeatmapClickData = {\n pageUrl,\n xpath,\n viewportX,\n viewportY,\n pageX,\n pageY,\n elementTag,\n elementText: elementText || undefined,\n timestamp: Date.now(),\n };\n\n // Check if this is a navigation link\n const isNavigationLink = element instanceof HTMLAnchorElement && element.href;\n\n // Send immediately with beacon for navigation links to ensure delivery\n if (isNavigationLink) {\n this.tracker.trackSystemEvent('_grain_heatmap_click', {\n page_url: clickData.pageUrl,\n xpath: clickData.xpath,\n viewport_x: clickData.viewportX,\n viewport_y: clickData.viewportY,\n page_x: clickData.pageX,\n page_y: clickData.pageY,\n element_tag: clickData.elementTag,\n element_text: clickData.elementText,\n timestamp: clickData.timestamp,\n }, { flush: true });\n } else {\n this.pendingClicks.push(clickData);\n\n // Check if we should flush\n this.considerBatchFlush();\n }\n }\n\n /**\n * Handle scroll event\n */\n private handleScroll(): void {\n // v3: Always track events - consent only affects ID type (daily vs permanent)\n // Removed: if (!this.tracker.hasConsent('analytics')) return;\n this.updateScrollState();\n }\n\n /**\n * Update current scroll state\n */\n private updateScrollState(): void {\n if (typeof window === 'undefined') return;\n // v3: Always track events - consent only affects ID type (daily vs permanent)\n // Removed: if (!this.tracker.hasConsent('analytics')) return;\n\n const currentTime = Date.now();\n const scrollY = window.scrollY || window.pageYOffset;\n const viewportHeight = window.innerHeight;\n const pageHeight = document.documentElement.scrollHeight;\n \n // Calculate which viewport section we're in\n const viewportSection = Math.floor(scrollY / viewportHeight);\n\n // If we're in a new section, record the previous one\n if (this.currentScrollState && this.currentScrollState.viewportSection !== viewportSection) {\n const duration = currentTime - this.currentScrollState.entryTime;\n \n // Only record if duration is meaningful (> 100ms)\n if (duration > 100) {\n const scrollData: HeatmapScrollData = {\n pageUrl: window.location.href,\n viewportSection: this.currentScrollState.viewportSection,\n scrollDepthPx: this.currentScrollState.scrollDepthPx,\n durationMs: duration,\n entryTimestamp: this.currentScrollState.entryTime,\n exitTimestamp: currentTime,\n pageHeight,\n viewportHeight,\n };\n\n this.pendingScrolls.push(scrollData);\n }\n\n // Reset attention for previous viewport section\n const prevSectionKey = `viewport_section_${this.currentScrollState.viewportSection}`;\n this.attentionQuality.resetSection(prevSectionKey);\n }\n\n // Update current state\n if (!this.currentScrollState || this.currentScrollState.viewportSection !== viewportSection) {\n this.currentScrollState = {\n viewportSection,\n entryTime: currentTime,\n scrollDepthPx: scrollY,\n };\n }\n\n this.lastScrollPosition = scrollY;\n this.lastScrollTime = currentTime;\n\n // Check if we should flush\n this.considerBatchFlush();\n }\n\n /**\n * Generate XPath for an element\n */\n private generateXPath(element: HTMLElement): string {\n if (!element) return '';\n\n // If element has an ID, use that for simpler XPath\n if (element.id) {\n return `//*[@id=\"${element.id}\"]`;\n }\n\n const paths: string[] = [];\n let currentElement: HTMLElement | null = element;\n\n while (currentElement && currentElement.nodeType === Node.ELEMENT_NODE) {\n let index = 0;\n let sibling: Element | null = currentElement;\n\n // Count preceding siblings of the same tag\n while (sibling) {\n sibling = sibling.previousElementSibling;\n if (sibling && sibling.nodeName === currentElement.nodeName) {\n index++;\n }\n }\n\n const tagName = currentElement.nodeName.toLowerCase();\n const pathIndex = index > 0 ? `[${index + 1}]` : '';\n paths.unshift(`${tagName}${pathIndex}`);\n\n currentElement = currentElement.parentElement;\n }\n\n return paths.length ? `/${paths.join('/')}` : '';\n }\n\n /**\n * Consider flushing batched events\n */\n private considerBatchFlush(): void {\n const totalEvents = this.pendingClicks.length + this.pendingScrolls.length;\n\n // Flush if we've hit the batch size\n if (totalEvents >= this.options.maxBatchSize) {\n this.flushPendingEvents();\n return;\n }\n\n // Otherwise, schedule a batch flush\n if (this.batchTimer === null && totalEvents > 0) {\n this.batchTimer = window.setTimeout(() => {\n this.flushPendingEvents();\n this.batchTimer = null;\n }, this.options.batchDelay);\n }\n }\n\n /**\n * Flush pending events\n */\n private flushPendingEvents(): void {\n if (this.isDestroyed) return;\n // v3: Always track events - consent only affects ID type (daily vs permanent)\n // Removed consent check that was blocking events in cookieless mode\n\n // Send click events\n if (this.pendingClicks.length > 0) {\n for (const clickData of this.pendingClicks) {\n this.tracker.trackSystemEvent('_grain_heatmap_click', {\n page_url: clickData.pageUrl,\n xpath: clickData.xpath,\n viewport_x: clickData.viewportX,\n viewport_y: clickData.viewportY,\n page_x: clickData.pageX,\n page_y: clickData.pageY,\n element_tag: clickData.elementTag,\n element_text: clickData.elementText,\n timestamp: clickData.timestamp,\n });\n }\n\n this.pendingClicks = [];\n }\n\n // Send scroll events\n if (this.pendingScrolls.length > 0) {\n for (const scrollData of this.pendingScrolls) {\n this.tracker.trackSystemEvent('_grain_heatmap_scroll', {\n page_url: scrollData.pageUrl,\n viewport_section: scrollData.viewportSection,\n scroll_depth_px: scrollData.scrollDepthPx,\n duration_ms: scrollData.durationMs,\n entry_timestamp: scrollData.entryTimestamp,\n exit_timestamp: scrollData.exitTimestamp,\n page_height: scrollData.pageHeight,\n viewport_height: scrollData.viewportHeight,\n });\n }\n\n this.pendingScrolls = [];\n }\n\n // Clear batch timer\n if (this.batchTimer !== null) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n }\n\n /**\n * Flush pending events with beacon (for page unload)\n */\n private flushPendingEventsWithBeacon(): void {\n // v3: Always track events - consent only affects ID type (daily vs permanent)\n // Removed consent check that was blocking events in cookieless mode\n\n // Send click events with beacon\n if (this.pendingClicks.length > 0) {\n for (const clickData of this.pendingClicks) {\n this.tracker.trackSystemEvent('_grain_heatmap_click', {\n page_url: clickData.pageUrl,\n xpath: clickData.xpath,\n viewport_x: clickData.viewportX,\n viewport_y: clickData.viewportY,\n page_x: clickData.pageX,\n page_y: clickData.pageY,\n element_tag: clickData.elementTag,\n element_text: clickData.elementText,\n timestamp: clickData.timestamp,\n }, { flush: true });\n }\n\n this.pendingClicks = [];\n }\n\n // Send scroll events with beacon\n if (this.pendingScrolls.length > 0) {\n for (const scrollData of this.pendingScrolls) {\n this.tracker.trackSystemEvent('_grain_heatmap_scroll', {\n page_url: scrollData.pageUrl,\n viewport_section: scrollData.viewportSection,\n scroll_depth_px: scrollData.scrollDepthPx,\n duration_ms: scrollData.durationMs,\n entry_timestamp: scrollData.entryTimestamp,\n exit_timestamp: scrollData.exitTimestamp,\n page_height: scrollData.pageHeight,\n viewport_height: scrollData.viewportHeight,\n }, { flush: true });\n }\n\n this.pendingScrolls = [];\n }\n }\n\n /**\n * Log debug message\n */\n private log(...args: unknown[]): void {\n if (this.options.debug) {\n this.tracker.log('[Heatmap Tracking]', ...args);\n }\n }\n\n /**\n * Destroy the tracking manager\n */\n destroy(): void {\n this.isDestroyed = true;\n\n // Clear timers\n if (this.scrollDebounceTimer !== null) {\n clearTimeout(this.scrollDebounceTimer);\n this.scrollDebounceTimer = null;\n }\n\n if (this.batchTimer !== null) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n\n if (this.scrollTrackingTimer !== null) {\n clearInterval(this.scrollTrackingTimer);\n this.scrollTrackingTimer = null;\n }\n\n if (this.periodicScrollTimer !== null) {\n clearInterval(this.periodicScrollTimer);\n this.periodicScrollTimer = null;\n }\n\n // Destroy attention quality manager\n this.attentionQuality.destroy();\n\n // Flush any remaining events\n this.flushPendingEvents();\n }\n}\n\n", "/**\n * Interaction Tracking Manager for Grain Analytics\n * Automatically attaches click and focus listeners to detected interactive elements\n */\n\nimport type { InteractionConfig } from './types/auto-tracking';\nimport { cleanElementText } from './text-utils';\n\nexport interface SendEventOptions {\n flush?: boolean;\n}\n\nexport interface InteractionTracker {\n track(eventName: string, properties?: Record<string, unknown>, options?: SendEventOptions): void | Promise<void>;\n hasConsent(category: 'analytics' | 'marketing' | 'functional'): boolean;\n log(...args: unknown[]): void;\n}\n\nexport interface InteractionTrackingConfig {\n debug?: boolean;\n enableMutationObserver?: boolean;\n mutationDebounceDelay?: number;\n tenantId?: string;\n apiUrl?: string;\n}\n\nexport class InteractionTrackingManager {\n private tracker: InteractionTracker;\n private interactions: InteractionConfig[];\n private config: InteractionTrackingConfig;\n private isDestroyed = false;\n private attachedListeners: Map<Element, Array<{ event: string; handler: EventListener }>> = new Map();\n private xpathCache: Map<string, Element | null> = new Map();\n private mutationObserver: MutationObserver | null = null;\n private mutationDebounceTimer: number | null = null;\n\n constructor(\n tracker: InteractionTracker,\n interactions: InteractionConfig[],\n config: InteractionTrackingConfig = {}\n ) {\n this.tracker = tracker;\n this.interactions = interactions;\n this.config = {\n debug: config.debug ?? false,\n enableMutationObserver: config.enableMutationObserver ?? true,\n mutationDebounceDelay: config.mutationDebounceDelay ?? 500,\n tenantId: config.tenantId,\n apiUrl: config.apiUrl,\n };\n\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Fetch and merge trackers if configured\n if (this.config.tenantId && this.config.apiUrl) {\n this.fetchAndMergeTrackers().then(() => {\n this.attachAllListeners();\n });\n } else {\n // Attach listeners after DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => this.attachAllListeners());\n } else {\n // DOM already loaded\n setTimeout(() => this.attachAllListeners(), 0);\n }\n }\n\n // Setup mutation observer for dynamic content\n if (this.config.enableMutationObserver) {\n this.setupMutationObserver();\n }\n }\n }\n \n /**\n * Fetch trackers from API and merge with existing interactions\n */\n private async fetchAndMergeTrackers(): Promise<void> {\n if (!this.config.tenantId || !this.config.apiUrl) return;\n \n try {\n const currentUrl = typeof window !== 'undefined' ? window.location.href : '';\n const url = `${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/trackers?url=${encodeURIComponent(currentUrl)}`;\n \n this.log('Fetching trackers from:', url);\n \n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n \n if (!response.ok) {\n this.log('Failed to fetch trackers:', response.status);\n return;\n }\n \n const result = await response.json();\n \n if (result.trackers && Array.isArray(result.trackers)) {\n this.log('Fetched', result.trackers.length, 'trackers');\n \n // Convert trackers to InteractionConfig format\n const trackerInteractions: InteractionConfig[] = result.trackers.map((tracker: any) => ({\n eventName: tracker.eventName,\n selector: tracker.selector,\n priority: 5, // High priority for manually created trackers\n label: tracker.eventName,\n description: `Tracker: ${tracker.eventName}`,\n }));\n \n // Merge with existing interactions (trackers take precedence)\n this.interactions = [...trackerInteractions, ...this.interactions];\n \n this.log('Merged trackers, total interactions:', this.interactions.length);\n }\n } catch (error) {\n this.log('Error fetching trackers:', error);\n }\n }\n\n /**\n * Attach listeners to all configured interactions\n */\n private attachAllListeners(): void {\n if (this.isDestroyed) return;\n\n this.log('Attaching interaction listeners');\n\n for (const interaction of this.interactions) {\n this.attachInteractionListener(interaction);\n }\n }\n\n /**\n * Attach listener to a specific interaction\n */\n private attachInteractionListener(interaction: InteractionConfig): void {\n if (this.isDestroyed) return;\n\n const element = this.findElementByXPath(interaction.selector);\n \n if (!element) {\n this.log('Element not found for interaction:', interaction.eventName, 'selector:', interaction.selector);\n return;\n }\n\n // Check if we already attached listeners to this element for this interaction\n if (this.attachedListeners.has(element)) {\n this.log('Listeners already attached for element:', element);\n return;\n }\n\n const handlers: Array<{ event: string; handler: EventListener }> = [];\n\n // Click handler\n const clickHandler = (event: Event) => this.handleInteractionClick(interaction, event);\n element.addEventListener('click', clickHandler, { passive: true });\n handlers.push({ event: 'click', handler: clickHandler });\n\n // Focus handler (for form inputs)\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) {\n const focusHandler = (event: Event) => this.handleInteractionFocus(interaction, event);\n element.addEventListener('focus', focusHandler, { passive: true });\n handlers.push({ event: 'focus', handler: focusHandler });\n }\n\n this.attachedListeners.set(element, handlers);\n }\n\n /**\n * Handle click event on interaction\n */\n private handleInteractionClick(interaction: InteractionConfig, event: Event): void {\n if (this.isDestroyed) return;\n // v3: Always track events - consent only affects ID type (daily vs permanent)\n // Removed: if (!this.tracker.hasConsent('analytics')) return;\n\n const element = event.target as HTMLElement;\n \n // Check if this is a navigation link (has href attribute)\n const isNavigationLink = element instanceof HTMLAnchorElement && element.href;\n \n const eventProperties = {\n interaction_type: 'click',\n interaction_label: interaction.label,\n interaction_description: interaction.description,\n interaction_priority: interaction.priority,\n element_tag: element.tagName?.toLowerCase(),\n element_text: cleanElementText(element.textContent),\n element_id: element.id || undefined,\n element_class: element.className || undefined,\n ...(isNavigationLink && { href: element.href }),\n timestamp: Date.now(),\n };\n \n // Always use flush for auto-tracked clicks to ensure delivery\n // This is especially important for navigation links and quick interactions\n const result = this.tracker.track(interaction.eventName, eventProperties, { flush: true });\n if (result instanceof Promise) {\n result.catch((error: unknown) => {\n // Log error but don't block interaction\n this.log('Failed to track click:', error);\n });\n }\n }\n\n /**\n * Handle focus event on interaction (for form fields)\n */\n private handleInteractionFocus(interaction: InteractionConfig, event: Event): void {\n if (this.isDestroyed) return;\n // v3: Always track events - consent only affects ID type (daily vs permanent)\n // Removed: if (!this.tracker.hasConsent('analytics')) return;\n\n const element = event.target as HTMLElement;\n \n this.tracker.track(interaction.eventName, {\n interaction_type: 'focus',\n interaction_label: interaction.label,\n interaction_description: interaction.description,\n interaction_priority: interaction.priority,\n element_tag: element.tagName?.toLowerCase(),\n element_id: element.id || undefined,\n element_class: element.className || undefined,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Find element by XPath selector\n */\n private findElementByXPath(xpath: string): Element | null {\n // Check cache first\n if (this.xpathCache.has(xpath)) {\n const cached = this.xpathCache.get(xpath);\n // Verify element is still in DOM\n if (cached && document.contains(cached)) {\n return cached;\n }\n // Clear invalid cache entry\n this.xpathCache.delete(xpath);\n }\n\n try {\n // Strip the xpath= prefix if present (from Stagehand selectors)\n let cleanXpath = xpath;\n if (xpath.startsWith('xpath=')) {\n cleanXpath = xpath.substring(6); // Remove 'xpath=' prefix\n }\n\n const result = document.evaluate(\n cleanXpath,\n document,\n null,\n XPathResult.FIRST_ORDERED_NODE_TYPE,\n null\n );\n \n const element = result.singleNodeValue as Element | null;\n \n // Cache the result (use original xpath as key)\n if (element) {\n this.xpathCache.set(xpath, element);\n }\n \n return element;\n } catch (error) {\n this.log('Error evaluating XPath:', xpath, error);\n return null;\n }\n }\n\n /**\n * Setup mutation observer to handle dynamic content\n */\n private setupMutationObserver(): void {\n if (typeof MutationObserver === 'undefined') {\n this.log('MutationObserver not supported');\n return;\n }\n\n this.mutationObserver = new MutationObserver((mutations) => {\n // Debounce the re-attachment\n if (this.mutationDebounceTimer !== null) {\n clearTimeout(this.mutationDebounceTimer);\n }\n\n this.mutationDebounceTimer = window.setTimeout(() => {\n this.handleMutations(mutations);\n this.mutationDebounceTimer = null;\n }, this.config.mutationDebounceDelay);\n });\n\n this.mutationObserver.observe(document.body, {\n childList: true,\n subtree: true,\n });\n\n this.log('Mutation observer setup');\n }\n\n /**\n * Handle DOM mutations\n */\n private handleMutations(mutations: MutationRecord[]): void {\n if (this.isDestroyed) return;\n\n // Clear XPath cache on mutations\n this.xpathCache.clear();\n\n // Check if any of our tracked elements were removed\n const removedElements = new Set<Element>();\n for (const mutation of mutations) {\n mutation.removedNodes.forEach((node) => {\n if (node instanceof Element) {\n removedElements.add(node);\n // Also check for child elements we were tracking\n this.attachedListeners.forEach((handlers, element) => {\n if (node.contains(element)) {\n removedElements.add(element);\n }\n });\n }\n });\n }\n\n // Clean up removed elements\n removedElements.forEach((element) => {\n this.detachListeners(element);\n });\n\n // Try to re-attach listeners for any interactions that might now be available\n this.attachAllListeners();\n }\n\n /**\n * Detach listeners from an element\n */\n private detachListeners(element: Element): void {\n const handlers = this.attachedListeners.get(element);\n if (!handlers) return;\n\n handlers.forEach(({ event, handler }) => {\n element.removeEventListener(event, handler);\n });\n\n this.attachedListeners.delete(element);\n }\n\n /**\n * Log debug messages\n */\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[InteractionTracking]', ...args);\n }\n }\n\n /**\n * Update interactions configuration\n */\n updateInteractions(interactions: InteractionConfig[]): void {\n if (this.isDestroyed) return;\n\n this.log('Updating interactions configuration');\n \n // Detach all existing listeners\n this.attachedListeners.forEach((handlers, element) => {\n this.detachListeners(element);\n });\n\n // Clear cache\n this.xpathCache.clear();\n\n // Update configuration\n this.interactions = interactions;\n\n // Reattach listeners\n this.attachAllListeners();\n }\n\n /**\n * Cleanup and destroy\n */\n destroy(): void {\n if (this.isDestroyed) return;\n\n this.log('Destroying interaction tracking manager');\n \n this.isDestroyed = true;\n\n // Clear debounce timer\n if (this.mutationDebounceTimer !== null) {\n clearTimeout(this.mutationDebounceTimer);\n this.mutationDebounceTimer = null;\n }\n\n // Disconnect mutation observer\n if (this.mutationObserver) {\n this.mutationObserver.disconnect();\n this.mutationObserver = null;\n }\n\n // Detach all listeners\n this.attachedListeners.forEach((handlers, element) => {\n this.detachListeners(element);\n });\n\n // Clear caches\n this.attachedListeners.clear();\n this.xpathCache.clear();\n }\n}\n\n", "/**\n * Section Tracking Manager for Grain Analytics\n * Intelligent scroll tracking with viewport metrics, visible sections, and engagement analysis\n */\n\nimport type { SectionConfig, SectionViewData, SectionTrackingOptions, SectionTrackingState } from './types/auto-tracking';\nimport { AttentionQualityManager } from './attention-quality';\nimport type { ActivityDetector } from './activity';\n\nexport interface SectionTracker {\n trackSystemEvent(eventName: string, properties: Record<string, unknown>): void;\n hasConsent(category: 'analytics' | 'marketing' | 'functional'): boolean;\n getActivityDetector(): ActivityDetector;\n log(...args: unknown[]): void;\n}\n\nconst DEFAULT_OPTIONS: SectionTrackingOptions = {\n minDwellTime: 1000, // 1 second minimum\n scrollVelocityThreshold: 500, // 500px/s\n intersectionThreshold: 0.1, // 10% visible\n debounceDelay: 100,\n batchDelay: 2000, // 2 seconds\n debug: false,\n};\n\nexport class SectionTrackingManager {\n private tracker: SectionTracker;\n private sections: SectionConfig[];\n private options: SectionTrackingOptions;\n private isDestroyed = false;\n \n // Tracking state\n private sectionStates: Map<string, SectionTrackingState> = new Map();\n private intersectionObserver: IntersectionObserver | null = null;\n private xpathCache: Map<string, Element | null> = new Map();\n \n // Scroll tracking\n private lastScrollPosition = 0;\n private lastScrollTime = Date.now();\n private scrollVelocity = 0;\n private scrollDebounceTimer: number | null = null;\n \n // Event batching\n private pendingEvents: SectionViewData[] = [];\n private batchTimer: number | null = null;\n\n // Periodic tracking for long-duration views\n private sectionTimers: Map<string, number> = new Map(); // sectionName -> timer ID\n private readonly SPLIT_DURATION = 3000; // 3 seconds\n\n // Attention quality management\n private attentionQuality: AttentionQualityManager;\n\n constructor(\n tracker: SectionTracker,\n sections: SectionConfig[],\n options: Partial<SectionTrackingOptions> = {}\n ) {\n this.tracker = tracker;\n this.sections = sections;\n this.options = { ...DEFAULT_OPTIONS, ...options };\n\n // Initialize attention quality manager\n this.attentionQuality = new AttentionQualityManager(\n tracker.getActivityDetector(),\n {\n maxSectionDuration: 9000, // 9 seconds\n minScrollDistance: 100, // 100 pixels\n idleThreshold: 30000, // 30 seconds\n debug: this.options.debug,\n }\n );\n\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Initialize after DOM is ready\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', () => this.initialize());\n } else {\n setTimeout(() => this.initialize(), 0);\n }\n }\n }\n\n /**\n * Initialize section tracking\n */\n private initialize(): void {\n if (this.isDestroyed) return;\n\n this.log('Initializing section tracking');\n\n // Setup intersection observer\n this.setupIntersectionObserver();\n\n // Setup scroll listener for velocity tracking\n this.setupScrollListener();\n\n // Initialize sections\n this.initializeSections();\n }\n\n /**\n * Setup IntersectionObserver for section visibility\n */\n private setupIntersectionObserver(): void {\n if (typeof IntersectionObserver === 'undefined') {\n this.log('IntersectionObserver not supported');\n return;\n }\n\n this.intersectionObserver = new IntersectionObserver(\n (entries) => {\n entries.forEach((entry) => {\n this.handleIntersection(entry);\n });\n },\n {\n threshold: [0, 0.1, 0.25, 0.5, 0.75, 1.0],\n rootMargin: '0px',\n }\n );\n\n this.log('IntersectionObserver created');\n }\n\n /**\n * Setup scroll listener for velocity calculation\n */\n private setupScrollListener(): void {\n if (typeof window === 'undefined') return;\n\n const scrollHandler = () => {\n if (this.scrollDebounceTimer !== null) {\n clearTimeout(this.scrollDebounceTimer);\n }\n\n this.scrollDebounceTimer = window.setTimeout(() => {\n this.updateScrollVelocity();\n this.scrollDebounceTimer = null;\n }, this.options.debounceDelay);\n };\n\n window.addEventListener('scroll', scrollHandler, { passive: true });\n this.log('Scroll listener attached');\n }\n\n /**\n * Initialize sections and start observing\n */\n private initializeSections(): void {\n for (const section of this.sections) {\n const element = this.findElementByXPath(section.selector);\n \n if (!element) {\n this.log('Section element not found:', section.sectionName, 'selector:', section.selector);\n continue;\n }\n\n // Initialize state\n const state: SectionTrackingState = {\n element,\n config: section,\n entryTime: null,\n exitTime: null,\n isVisible: false,\n lastScrollPosition: window.scrollY,\n lastScrollTime: Date.now(),\n entryScrollSpeed: 0,\n exitScrollSpeed: 0,\n maxVisibleArea: 0,\n };\n\n this.sectionStates.set(section.sectionName, state);\n\n // Start observing\n if (this.intersectionObserver) {\n this.intersectionObserver.observe(element);\n }\n }\n }\n\n /**\n * Handle intersection observer entry\n */\n private handleIntersection(entry: IntersectionObserverEntry): void {\n if (this.isDestroyed) return;\n\n // Find which section this element belongs to\n const state = Array.from(this.sectionStates.values()).find(\n (s) => s.element === entry.target\n );\n\n if (!state) return;\n\n const isVisible = entry.isIntersecting && entry.intersectionRatio >= this.options.intersectionThreshold;\n const visibleArea = entry.intersectionRatio;\n\n // Update max visible area\n if (visibleArea > state.maxVisibleArea) {\n state.maxVisibleArea = visibleArea;\n }\n\n // Handle visibility change\n if (isVisible && !state.isVisible) {\n // Section became visible\n this.handleSectionEntry(state);\n } else if (!isVisible && state.isVisible) {\n // Section became invisible\n this.handleSectionExit(state);\n }\n\n state.isVisible = isVisible;\n }\n\n /**\n * Handle section entry (became visible)\n */\n private handleSectionEntry(state: SectionTrackingState): void {\n state.entryTime = Date.now();\n state.entryScrollSpeed = this.scrollVelocity;\n state.lastScrollPosition = window.scrollY;\n state.lastScrollTime = Date.now();\n state.maxVisibleArea = 0;\n \n // Start periodic tracking timer (3 second intervals)\n this.startPeriodicTracking(state);\n }\n \n /**\n * Start periodic tracking for a section (sends events every 3 seconds)\n */\n private startPeriodicTracking(state: SectionTrackingState): void {\n // Clear any existing timer for this section\n this.stopPeriodicTracking(state.config.sectionName);\n \n const timerId = window.setInterval(() => {\n if (this.isDestroyed || !state.isVisible || state.entryTime === null) {\n this.stopPeriodicTracking(state.config.sectionName);\n return;\n }\n \n const now = Date.now();\n const duration = now - state.entryTime;\n \n // Only track if minimum dwell time has passed\n if (duration >= this.options.minDwellTime) {\n // Check attention quality policies\n const currentScrollY = window.scrollY;\n const attentionCheck = this.attentionQuality.shouldTrackSection(\n state.config.sectionName,\n currentScrollY\n );\n\n // If attention was reset due to scroll, reset our entry time\n if (attentionCheck.resetAttention) {\n this.log(`Section \"${state.config.sectionName}\": Attention reset, restarting timer`);\n state.entryTime = now;\n state.entryScrollSpeed = this.scrollVelocity;\n return;\n }\n\n // If tracking is not allowed (page hidden, idle, or max duration reached)\n if (!attentionCheck.shouldTrack) {\n this.log(`Section \"${state.config.sectionName}\": Tracking paused - ${attentionCheck.reason}`);\n return;\n }\n\n // Create partial section view data\n const viewData: SectionViewData = {\n sectionName: state.config.sectionName,\n sectionType: state.config.sectionType,\n entryTime: state.entryTime,\n exitTime: now, // Current time as \"exit\" for this split\n duration,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n scrollDepth: this.calculateScrollDepth(),\n visibleAreaPercentage: Math.round(state.maxVisibleArea * 100),\n scrollSpeedAtEntry: state.entryScrollSpeed,\n scrollSpeedAtExit: this.scrollVelocity,\n };\n \n // Track this split immediately (don't queue for batching)\n if (this.shouldTrackSection(viewData)) {\n this.tracker.trackSystemEvent('_grain_section_view', {\n section_name: viewData.sectionName,\n section_type: viewData.sectionType,\n duration_ms: viewData.duration,\n viewport_width: viewData.viewportWidth,\n viewport_height: viewData.viewportHeight,\n scroll_depth_percent: viewData.scrollDepth,\n visible_area_percent: viewData.visibleAreaPercentage,\n scroll_speed_entry: Math.round(viewData.scrollSpeedAtEntry || 0),\n scroll_speed_exit: Math.round(viewData.scrollSpeedAtExit || 0),\n entry_timestamp: viewData.entryTime,\n exit_timestamp: viewData.exitTime,\n is_split: true, // Flag to indicate this is a periodic split, not final exit\n });\n \n // Update attention quality duration tracker\n this.attentionQuality.updateSectionDuration(state.config.sectionName, duration);\n \n // Reset entry time for next split (but keep tracking)\n state.entryTime = now;\n state.entryScrollSpeed = this.scrollVelocity;\n }\n }\n }, this.SPLIT_DURATION);\n \n this.sectionTimers.set(state.config.sectionName, timerId);\n }\n \n /**\n * Stop periodic tracking for a section\n */\n private stopPeriodicTracking(sectionName: string): void {\n const timerId = this.sectionTimers.get(sectionName);\n if (timerId !== undefined) {\n clearInterval(timerId);\n this.sectionTimers.delete(sectionName);\n }\n }\n\n /**\n * Handle section exit (became invisible)\n */\n private handleSectionExit(state: SectionTrackingState): void {\n // Stop periodic tracking\n this.stopPeriodicTracking(state.config.sectionName);\n \n // Reset attention for this section\n this.attentionQuality.resetSection(state.config.sectionName);\n \n if (state.entryTime === null) return;\n\n state.exitTime = Date.now();\n state.exitScrollSpeed = this.scrollVelocity;\n\n const duration = state.exitTime - state.entryTime;\n\n // Create section view data\n const viewData: SectionViewData = {\n sectionName: state.config.sectionName,\n sectionType: state.config.sectionType,\n entryTime: state.entryTime,\n exitTime: state.exitTime,\n duration,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n scrollDepth: this.calculateScrollDepth(),\n visibleAreaPercentage: Math.round(state.maxVisibleArea * 100),\n scrollSpeedAtEntry: state.entryScrollSpeed,\n scrollSpeedAtExit: state.exitScrollSpeed,\n };\n\n // Apply sanitization and track if valid\n if (this.shouldTrackSection(viewData)) {\n this.queueSectionView(viewData);\n } else {\n this.log('Section view filtered out:', state.config.sectionName, 'duration:', duration);\n }\n\n // Reset entry time\n state.entryTime = null;\n }\n\n /**\n * Update scroll velocity\n */\n private updateScrollVelocity(): void {\n const now = Date.now();\n const currentPosition = window.scrollY;\n \n const timeDelta = now - this.lastScrollTime;\n const positionDelta = Math.abs(currentPosition - this.lastScrollPosition);\n \n if (timeDelta > 0) {\n this.scrollVelocity = (positionDelta / timeDelta) * 1000; // pixels per second\n }\n \n this.lastScrollPosition = currentPosition;\n this.lastScrollTime = now;\n }\n\n /**\n * Calculate current scroll depth as percentage\n */\n private calculateScrollDepth(): number {\n if (typeof window === 'undefined' || typeof document === 'undefined') return 0;\n\n const windowHeight = window.innerHeight;\n const documentHeight = Math.max(\n document.body.scrollHeight,\n document.body.offsetHeight,\n document.documentElement.clientHeight,\n document.documentElement.scrollHeight,\n document.documentElement.offsetHeight\n );\n \n const scrollTop = window.scrollY;\n const scrollableHeight = documentHeight - windowHeight;\n \n if (scrollableHeight <= 0) return 100;\n \n return Math.round((scrollTop / scrollableHeight) * 100);\n }\n\n /**\n * Determine if section view should be tracked (sanitization)\n */\n private shouldTrackSection(viewData: SectionViewData): boolean {\n // Minimum dwell time check\n if (viewData.duration < this.options.minDwellTime) {\n return false;\n }\n\n // Check if user was rapidly scrolling through\n const avgScrollSpeed = (viewData.scrollSpeedAtEntry! + viewData.scrollSpeedAtExit!) / 2;\n if (avgScrollSpeed > this.options.scrollVelocityThreshold * 2) {\n // Very fast scroll - likely not engaged\n return false;\n }\n\n // Must have had some meaningful visible area\n if (viewData.visibleAreaPercentage < 10) {\n return false;\n }\n\n return true;\n }\n\n /**\n * Queue section view for batching\n */\n private queueSectionView(viewData: SectionViewData): void {\n this.pendingEvents.push(viewData);\n\n // Setup batch timer if not already set\n if (this.batchTimer === null) {\n this.batchTimer = window.setTimeout(() => {\n this.flushPendingEvents();\n }, this.options.batchDelay);\n }\n }\n\n /**\n * Flush pending section view events\n */\n private flushPendingEvents(): void {\n if (this.isDestroyed || this.pendingEvents.length === 0) return;\n // v3: Always track events - consent only affects ID type (daily vs permanent)\n // Removed consent check that was blocking events in cookieless mode\n\n // Track each section view\n for (const viewData of this.pendingEvents) {\n this.tracker.trackSystemEvent('_grain_section_view', {\n section_name: viewData.sectionName,\n section_type: viewData.sectionType,\n duration_ms: viewData.duration,\n viewport_width: viewData.viewportWidth,\n viewport_height: viewData.viewportHeight,\n scroll_depth_percent: viewData.scrollDepth,\n visible_area_percent: viewData.visibleAreaPercentage,\n scroll_speed_entry: Math.round(viewData.scrollSpeedAtEntry || 0),\n scroll_speed_exit: Math.round(viewData.scrollSpeedAtExit || 0),\n entry_timestamp: viewData.entryTime,\n exit_timestamp: viewData.exitTime,\n });\n }\n\n // Clear pending events\n this.pendingEvents = [];\n this.batchTimer = null;\n }\n\n /**\n * Find element by XPath selector\n */\n private findElementByXPath(xpath: string): Element | null {\n // Check cache first\n if (this.xpathCache.has(xpath)) {\n const cached = this.xpathCache.get(xpath);\n if (cached && document.contains(cached)) {\n return cached;\n }\n this.xpathCache.delete(xpath);\n }\n\n try {\n // Strip the xpath= prefix if present (from Stagehand selectors)\n let cleanXpath = xpath;\n if (xpath.startsWith('xpath=')) {\n cleanXpath = xpath.substring(6); // Remove 'xpath=' prefix\n }\n\n const result = document.evaluate(\n cleanXpath,\n document,\n null,\n XPathResult.FIRST_ORDERED_NODE_TYPE,\n null\n );\n \n const element = result.singleNodeValue as Element | null;\n \n // Cache the result (use original xpath as key)\n if (element) {\n this.xpathCache.set(xpath, element);\n }\n \n return element;\n } catch (error) {\n this.log('Error evaluating XPath:', xpath, error);\n return null;\n }\n }\n\n /**\n * Log debug messages\n */\n private log(...args: unknown[]): void {\n if (this.options.debug) {\n console.log('[SectionTracking]', ...args);\n }\n }\n\n /**\n * Update sections configuration\n */\n updateSections(sections: SectionConfig[]): void {\n if (this.isDestroyed) return;\n\n this.log('Updating sections configuration');\n \n // Disconnect observer\n if (this.intersectionObserver) {\n this.intersectionObserver.disconnect();\n }\n\n // Clear state\n this.sectionStates.clear();\n this.xpathCache.clear();\n\n // Update configuration\n this.sections = sections;\n\n // Reinitialize\n this.setupIntersectionObserver();\n this.initializeSections();\n }\n\n /**\n * Cleanup and destroy\n */\n destroy(): void {\n if (this.isDestroyed) return;\n\n this.log('Destroying section tracking manager');\n \n this.isDestroyed = true;\n\n // Stop all periodic tracking timers\n this.sectionTimers.forEach((timerId) => {\n clearInterval(timerId);\n });\n this.sectionTimers.clear();\n\n // Flush any pending events\n this.flushPendingEvents();\n\n // Clear timers\n if (this.scrollDebounceTimer !== null) {\n clearTimeout(this.scrollDebounceTimer);\n this.scrollDebounceTimer = null;\n }\n\n if (this.batchTimer !== null) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n\n // Disconnect intersection observer\n if (this.intersectionObserver) {\n this.intersectionObserver.disconnect();\n this.intersectionObserver = null;\n }\n\n // Destroy attention quality manager\n this.attentionQuality.destroy();\n\n // Clear state\n this.sectionStates.clear();\n this.xpathCache.clear();\n this.pendingEvents = [];\n }\n}\n\n", "/**\n * Debug Agent for Visual Event Tracking\n * Provides a toolbar and element inspection mode for creating event trackers\n */\n\nexport interface DebugAgentConfig {\n debug?: boolean;\n}\n\nexport interface Tracker {\n track(eventName: string, properties?: Record<string, unknown>): void | Promise<void>;\n log(...args: unknown[]): void;\n}\n\nexport interface ExistingTracker {\n trackerId: string;\n name: string;\n type: string;\n selector: string;\n urlScope: string;\n urlPattern?: string;\n isEnabled: boolean;\n}\n\nexport class DebugAgent {\n private tracker: Tracker;\n private sessionId: string;\n private tenantId: string;\n private apiUrl: string;\n private config: DebugAgentConfig;\n private isDestroyed = false;\n \n // UI state\n private isInspectMode = false;\n private showTrackers = false;\n private selectedElement: Element | null = null;\n private toolbarElement: HTMLElement | null = null;\n private panelElement: HTMLElement | null = null;\n private highlightElement: HTMLElement | null = null;\n private existingTrackers: ExistingTracker[] = [];\n private trackerHighlights: HTMLElement[] = [];\n \n // Dragging state\n private isDragging = false;\n private dragStartX = 0;\n private dragStartY = 0;\n private toolbarStartX = 0;\n private toolbarStartY = 0;\n \n // Event listeners\n private mouseMoveListener: ((e: MouseEvent) => void) | null = null;\n private clickListener: ((e: MouseEvent) => void) | null = null;\n private dragMoveListener: ((e: MouseEvent) => void) | null = null;\n private dragEndListener: ((e: MouseEvent) => void) | null = null;\n\n constructor(\n tracker: Tracker,\n sessionId: string,\n tenantId: string,\n apiUrl: string,\n config: DebugAgentConfig = {}\n ) {\n this.tracker = tracker;\n this.sessionId = sessionId;\n this.tenantId = tenantId;\n this.apiUrl = apiUrl;\n this.config = {\n debug: config.debug ?? false,\n };\n\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n this.initialize();\n }\n }\n\n /**\n * Initialize the debug agent\n */\n private async initialize(): Promise<void> {\n this.log('Initializing debug agent');\n await this.loadExistingTrackers();\n this.showToolbar();\n this.createHighlightElement();\n \n // Show trackers by default\n this.showTrackers = true;\n this.showTrackerHighlights();\n this.showTrackersList();\n }\n\n /**\n * Load existing trackers from API\n */\n private async loadExistingTrackers(): Promise<void> {\n try {\n const url = `${this.apiUrl}/v1/tenant/${encodeURIComponent(this.tenantId)}/trackers`;\n const response = await fetch(url);\n\n if (response.ok) {\n this.existingTrackers = await response.json();\n this.log('Loaded trackers:', this.existingTrackers);\n }\n } catch (error) {\n this.log('Failed to load trackers:', error);\n this.existingTrackers = [];\n }\n }\n\n /**\n * Show the debug toolbar\n */\n private showToolbar(): void {\n if (this.toolbarElement) return;\n\n const toolbar = document.createElement('div');\n toolbar.id = 'grain-debug-toolbar';\n toolbar.innerHTML = `\n <style>\n #grain-debug-toolbar {\n position: fixed;\n bottom: 20px;\n right: 20px;\n background: repeating-linear-gradient(\n 45deg,\n #fbbf24,\n #fbbf24 10px,\n #1e293b 10px,\n #1e293b 20px\n );\n border: 2px solid #1e293b;\n border-radius: 12px;\n padding: 6px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2), 0 2px 8px rgba(0, 0, 0, 0.1);\n z-index: 999999;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n }\n \n .grain-toolbar-inner {\n display: flex;\n align-items: center;\n gap: 12px;\n background: white;\n border-radius: 6px;\n padding: 8px 12px;\n }\n \n #grain-debug-toolbar.dragging {\n cursor: move;\n user-select: none;\n }\n \n .grain-toolbar-header {\n display: flex;\n align-items: center;\n cursor: move;\n user-select: none;\n padding: 6px 10px;\n background: #1e293b;\n border-radius: 4px;\n margin-right: 4px;\n }\n \n .grain-toolbar-title {\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 1.2px;\n text-transform: uppercase;\n color: #fbbf24;\n }\n \n .grain-toolbar-body {\n display: flex;\n align-items: center;\n gap: 10px;\n flex: 1;\n }\n \n .grain-toolbar-stats {\n display: flex;\n gap: 12px;\n padding: 6px 10px;\n background: #f8fafc;\n border-radius: 4px;\n margin-right: 4px;\n }\n \n .grain-stat {\n display: flex;\n align-items: baseline;\n gap: 6px;\n }\n \n .grain-stat-value {\n font-size: 18px;\n font-weight: 700;\n color: #1e293b;\n }\n \n .grain-stat-label {\n font-size: 11px;\n color: #64748b;\n font-weight: 500;\n }\n \n .grain-toolbar-actions {\n display: flex;\n gap: 8px;\n align-items: center;\n }\n \n #grain-debug-toolbar button {\n background: white;\n border: 1.5px solid #e2e8f0;\n color: #475569;\n padding: 8px 14px;\n border-radius: 8px;\n cursor: pointer;\n font-size: 12px;\n font-weight: 600;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n white-space: nowrap;\n }\n \n #grain-debug-toolbar button:hover {\n background: #f8fafc;\n border-color: #cbd5e1;\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);\n }\n \n #grain-debug-toolbar button.active {\n background: #fbbf24;\n color: #1e293b;\n border-color: #fbbf24;\n box-shadow: 0 2px 8px rgba(251, 191, 36, 0.3);\n }\n \n #grain-debug-toolbar button.danger {\n background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);\n border-color: #ef4444;\n color: white;\n }\n \n #grain-debug-toolbar button.danger:hover {\n transform: translateY(-1px);\n box-shadow: 0 2px 8px rgba(239, 68, 68, 0.25);\n }\n \n .grain-debug-highlight {\n position: absolute;\n pointer-events: none;\n border: 2px solid #10b981;\n background: rgba(16, 185, 129, 0.1);\n z-index: 999998;\n transition: all 0.1s;\n }\n \n .grain-tracker-highlight {\n position: absolute;\n pointer-events: none;\n border: 2px solid #6366f1;\n background: rgba(99, 102, 241, 0.08);\n z-index: 999997;\n transition: opacity 0.2s;\n }\n \n .grain-tracker-label {\n position: absolute;\n top: -28px;\n left: 0;\n background: #6366f1;\n color: white;\n padding: 4px 10px;\n border-radius: 6px;\n font-size: 11px;\n font-weight: 600;\n white-space: nowrap;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n pointer-events: none;\n }\n \n .grain-tracker-label::after {\n content: '';\n position: absolute;\n bottom: -4px;\n left: 10px;\n width: 0;\n height: 0;\n border-left: 4px solid transparent;\n border-right: 4px solid transparent;\n border-top: 4px solid #6366f1;\n }\n \n .grain-trackers-list {\n position: fixed;\n bottom: 80px;\n right: 20px;\n background: white;\n border: 1.5px solid #e2e8f0;\n border-radius: 10px;\n padding: 12px;\n max-height: 400px;\n width: 320px;\n overflow-y: auto;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1), 0 2px 8px rgba(0, 0, 0, 0.06);\n z-index: 999998;\n }\n \n .grain-tracker-item {\n padding: 10px;\n background: #f8fafc;\n border-radius: 8px;\n margin-bottom: 8px;\n cursor: pointer;\n transition: all 0.2s;\n }\n \n .grain-tracker-item:hover {\n background: #f1f5f9;\n transform: translateX(4px);\n }\n \n .grain-tracker-item:last-child {\n margin-bottom: 0;\n }\n \n .grain-tracker-name {\n font-weight: 600;\n color: #1e293b;\n font-size: 13px;\n margin-bottom: 4px;\n }\n \n .grain-tracker-details {\n font-size: 11px;\n color: #64748b;\n display: flex;\n gap: 8px;\n align-items: center;\n }\n \n .grain-tracker-type {\n background: #dbeafe;\n color: #1e40af;\n padding: 2px 6px;\n border-radius: 4px;\n font-weight: 600;\n text-transform: uppercase;\n font-size: 9px;\n letter-spacing: 0.5px;\n }\n </style>\n <div class=\"grain-toolbar-inner\">\n <div class=\"grain-toolbar-header\" id=\"grain-toolbar-handle\">\n <div class=\"grain-toolbar-title\">Grain Debug</div>\n </div>\n <div class=\"grain-toolbar-body\">\n <div class=\"grain-toolbar-stats\">\n <div class=\"grain-stat\">\n <div class=\"grain-stat-value\">${this.existingTrackers.length}</div>\n <div class=\"grain-stat-label\">trackers</div>\n </div>\n <div class=\"grain-stat\">\n <div class=\"grain-stat-value\">${this.existingTrackers.filter(t => t.isEnabled).length}</div>\n <div class=\"grain-stat-label\">active</div>\n </div>\n </div>\n <div class=\"grain-toolbar-actions\">\n <button id=\"grain-debug-inspect\" type=\"button\">\n + New\n </button>\n <button id=\"grain-debug-trackers\" class=\"active\" type=\"button\">\n Hide\n </button>\n <button id=\"grain-debug-end\" class=\"danger\" type=\"button\">\n End Session\n </button>\n </div>\n </div>\n </div>\n <div id=\"grain-trackers-list-container\"></div>\n `;\n\n document.body.appendChild(toolbar);\n this.toolbarElement = toolbar;\n\n // Setup dragging\n const handle = toolbar.querySelector('#grain-toolbar-handle') as HTMLElement;\n if (handle) {\n handle.addEventListener('mousedown', (e) => this.startDrag(e));\n }\n\n // Add event listeners\n const inspectBtn = toolbar.querySelector('#grain-debug-inspect');\n const trackersBtn = toolbar.querySelector('#grain-debug-trackers');\n const endBtn = toolbar.querySelector('#grain-debug-end');\n\n if (inspectBtn) {\n inspectBtn.addEventListener('click', () => this.toggleInspectMode());\n }\n\n if (trackersBtn) {\n trackersBtn.addEventListener('click', () => this.toggleTrackerView());\n }\n\n if (endBtn) {\n endBtn.addEventListener('click', () => this.endDebug());\n }\n\n this.log('Toolbar shown');\n }\n\n /**\n * Create highlight element for hovering\n */\n private createHighlightElement(): void {\n if (this.highlightElement) return;\n\n const highlight = document.createElement('div');\n highlight.className = 'grain-debug-highlight';\n highlight.style.display = 'none';\n document.body.appendChild(highlight);\n this.highlightElement = highlight;\n }\n\n /**\n * Start dragging the toolbar\n */\n private startDrag(e: MouseEvent): void {\n if (!this.toolbarElement) return;\n \n this.isDragging = true;\n this.dragStartX = e.clientX;\n this.dragStartY = e.clientY;\n \n const rect = this.toolbarElement.getBoundingClientRect();\n this.toolbarStartX = rect.left;\n this.toolbarStartY = rect.top;\n \n this.toolbarElement.classList.add('dragging');\n \n this.dragMoveListener = (e: MouseEvent) => this.onDrag(e);\n this.dragEndListener = () => this.endDrag();\n \n document.addEventListener('mousemove', this.dragMoveListener);\n document.addEventListener('mouseup', this.dragEndListener);\n }\n\n /**\n * Handle drag movement\n */\n private onDrag(e: MouseEvent): void {\n if (!this.isDragging || !this.toolbarElement) return;\n \n const deltaX = e.clientX - this.dragStartX;\n const deltaY = e.clientY - this.dragStartY;\n \n const newX = this.toolbarStartX + deltaX;\n const newY = this.toolbarStartY + deltaY;\n \n // Keep toolbar within viewport\n const maxX = window.innerWidth - this.toolbarElement.offsetWidth;\n const maxY = window.innerHeight - this.toolbarElement.offsetHeight;\n \n const clampedX = Math.max(0, Math.min(newX, maxX));\n const clampedY = Math.max(0, Math.min(newY, maxY));\n \n this.toolbarElement.style.left = `${clampedX}px`;\n this.toolbarElement.style.top = `${clampedY}px`;\n this.toolbarElement.style.right = 'auto';\n this.toolbarElement.style.bottom = 'auto';\n }\n\n /**\n * End dragging\n */\n private endDrag(): void {\n if (!this.isDragging) return;\n \n this.isDragging = false;\n \n if (this.toolbarElement) {\n this.toolbarElement.classList.remove('dragging');\n }\n \n if (this.dragMoveListener) {\n document.removeEventListener('mousemove', this.dragMoveListener);\n this.dragMoveListener = null;\n }\n \n if (this.dragEndListener) {\n document.removeEventListener('mouseup', this.dragEndListener);\n this.dragEndListener = null;\n }\n }\n\n /**\n * Toggle tracker view\n */\n private toggleTrackerView(): void {\n this.showTrackers = !this.showTrackers;\n \n const trackersBtn = document.querySelector('#grain-debug-trackers');\n if (trackersBtn) {\n trackersBtn.textContent = this.showTrackers ? 'Hide' : 'View';\n trackersBtn.classList.toggle('active', this.showTrackers);\n }\n \n if (this.showTrackers) {\n this.showTrackerHighlights();\n this.showTrackersList();\n } else {\n this.hideTrackerHighlights();\n this.hideTrackersList();\n }\n }\n\n /**\n * Show tracker highlights on page\n */\n private showTrackerHighlights(): void {\n this.hideTrackerHighlights();\n \n for (const tracker of this.existingTrackers) {\n if (!tracker.isEnabled) continue;\n \n try {\n const element = this.findElementBySelector(tracker.selector);\n if (!element) continue;\n \n const rect = element.getBoundingClientRect();\n const highlight = document.createElement('div');\n highlight.className = 'grain-tracker-highlight';\n \n const label = document.createElement('div');\n label.className = 'grain-tracker-label';\n label.textContent = tracker.name;\n \n highlight.style.top = `${rect.top + window.scrollY}px`;\n highlight.style.left = `${rect.left + window.scrollX}px`;\n highlight.style.width = `${rect.width}px`;\n highlight.style.height = `${rect.height}px`;\n \n highlight.appendChild(label);\n document.body.appendChild(highlight);\n this.trackerHighlights.push(highlight);\n } catch (error) {\n this.log('Failed to highlight tracker:', tracker.name, error);\n }\n }\n }\n\n /**\n * Hide tracker highlights\n */\n private hideTrackerHighlights(): void {\n for (const highlight of this.trackerHighlights) {\n highlight.remove();\n }\n this.trackerHighlights = [];\n }\n\n /**\n * Show trackers list\n */\n private showTrackersList(): void {\n // Check if list already exists\n let list = document.querySelector('.grain-trackers-list') as HTMLElement;\n \n if (this.existingTrackers.length === 0) {\n if (list) list.remove();\n return;\n }\n \n if (!list) {\n list = document.createElement('div');\n list.className = 'grain-trackers-list';\n document.body.appendChild(list);\n }\n \n list.innerHTML = `\n ${this.existingTrackers.map(tracker => `\n <div class=\"grain-tracker-item\" data-tracker-id=\"${tracker.trackerId}\">\n <div class=\"grain-tracker-name\">${tracker.name}</div>\n <div class=\"grain-tracker-details\">\n <span class=\"grain-tracker-type\">${tracker.type}</span>\n <span>${tracker.urlScope}</span>\n ${!tracker.isEnabled ? '<span style=\"color: #ef4444;\">\u2022 Disabled</span>' : ''}\n </div>\n </div>\n `).join('')}\n `;\n \n // Add click handlers to scroll to elements\n list.querySelectorAll('.grain-tracker-item').forEach(item => {\n item.addEventListener('click', () => {\n const trackerId = item.getAttribute('data-tracker-id');\n const tracker = this.existingTrackers.find(t => t.trackerId === trackerId);\n if (tracker) {\n this.scrollToTracker(tracker);\n }\n });\n });\n }\n\n /**\n * Hide trackers list\n */\n private hideTrackersList(): void {\n const list = document.querySelector('.grain-trackers-list');\n if (list) {\n list.remove();\n }\n }\n\n /**\n * Scroll to and highlight a tracker element\n */\n private scrollToTracker(tracker: ExistingTracker): void {\n try {\n const element = this.findElementBySelector(tracker.selector);\n if (element) {\n element.scrollIntoView({ behavior: 'smooth', block: 'center' });\n \n // Flash the highlight\n const highlight = this.trackerHighlights.find(h => {\n const rect = element.getBoundingClientRect();\n const hRect = h.getBoundingClientRect();\n return Math.abs(hRect.top - rect.top) < 5;\n });\n \n if (highlight) {\n highlight.style.opacity = '0';\n setTimeout(() => {\n highlight.style.opacity = '1';\n }, 100);\n setTimeout(() => {\n highlight.style.opacity = '0';\n }, 300);\n setTimeout(() => {\n highlight.style.opacity = '1';\n }, 500);\n }\n }\n } catch (error) {\n this.log('Failed to scroll to tracker:', error);\n }\n }\n\n /**\n * Find element by XPath selector\n */\n private findElementBySelector(selector: string): Element | null {\n try {\n const result = document.evaluate(\n selector,\n document,\n null,\n XPathResult.FIRST_ORDERED_NODE_TYPE,\n null\n );\n return result.singleNodeValue as Element | null;\n } catch (error) {\n this.log('Failed to find element:', error);\n return null;\n }\n }\n\n /**\n * Toggle inspect mode\n */\n private toggleInspectMode(): void {\n if (this.isInspectMode) {\n this.disableInspectMode();\n } else {\n this.enableInspectMode();\n }\n }\n\n /**\n * Enable element inspection mode\n */\n private enableInspectMode(): void {\n if (this.isInspectMode) return;\n\n this.log('Enabling inspect mode');\n this.isInspectMode = true;\n\n // Update button state\n const inspectBtn = document.querySelector('#grain-debug-inspect');\n if (inspectBtn) {\n inspectBtn.classList.add('active');\n inspectBtn.textContent = 'Click Element';\n }\n\n // Add event listeners\n this.mouseMoveListener = (e: MouseEvent) => this.handleMouseMove(e);\n this.clickListener = (e: MouseEvent) => this.handleElementClick(e);\n\n document.addEventListener('mousemove', this.mouseMoveListener, true);\n document.addEventListener('click', this.clickListener, true);\n \n // Add ESC key listener to exit inspect mode\n document.addEventListener('keydown', this.handleEscapeKey);\n }\n\n /**\n * Handle ESC key to exit inspect mode\n */\n private handleEscapeKey = (e: KeyboardEvent): void => {\n if (e.key === 'Escape' && this.isInspectMode) {\n this.disableInspectMode();\n }\n };\n\n /**\n * Disable element inspection mode\n */\n private disableInspectMode(): void {\n if (!this.isInspectMode) return;\n\n this.log('Disabling inspect mode');\n this.isInspectMode = false;\n\n // Update button state\n const inspectBtn = document.querySelector('#grain-debug-inspect');\n if (inspectBtn) {\n inspectBtn.classList.remove('active');\n inspectBtn.textContent = '+ New';\n }\n\n // Remove event listeners\n if (this.mouseMoveListener) {\n document.removeEventListener('mousemove', this.mouseMoveListener, true);\n this.mouseMoveListener = null;\n }\n\n if (this.clickListener) {\n document.removeEventListener('click', this.clickListener, true);\n this.clickListener = null;\n }\n\n document.removeEventListener('keydown', this.handleEscapeKey);\n\n // Hide highlight\n if (this.highlightElement) {\n this.highlightElement.style.display = 'none';\n }\n }\n\n /**\n * Handle mouse move to highlight hovered element\n */\n private handleMouseMove(e: MouseEvent): void {\n if (!this.isInspectMode || !this.highlightElement) return;\n\n // Ignore if hovering over toolbar, panel, or tracker list\n const target = e.target as HTMLElement;\n if (target.closest('#grain-debug-toolbar') || \n target.closest('#grain-debug-panel') ||\n target.closest('.grain-trackers-list')) {\n this.highlightElement.style.display = 'none';\n return;\n }\n\n // Get element rect\n const element = e.target as HTMLElement;\n const rect = element.getBoundingClientRect();\n\n // Position highlight\n this.highlightElement.style.display = 'block';\n this.highlightElement.style.top = `${rect.top + window.scrollY}px`;\n this.highlightElement.style.left = `${rect.left + window.scrollX}px`;\n this.highlightElement.style.width = `${rect.width}px`;\n this.highlightElement.style.height = `${rect.height}px`;\n }\n\n /**\n * Handle element click to show creation panel\n */\n private handleElementClick(e: MouseEvent): void {\n if (!this.isInspectMode) return;\n\n const target = e.target as HTMLElement;\n \n // If clicking toolbar or tracker list, exit inspect mode and allow normal click\n if (target.closest('#grain-debug-toolbar') || target.closest('.grain-trackers-list')) {\n this.disableInspectMode();\n return;\n }\n\n // If clicking panel, prevent default but don't do anything\n if (target.closest('#grain-debug-panel')) {\n e.preventDefault();\n e.stopPropagation();\n return;\n }\n\n // Otherwise, select the element\n e.preventDefault();\n e.stopPropagation();\n\n this.selectedElement = target;\n this.disableInspectMode();\n this.showCreationPanel(target);\n }\n\n /**\n * Show tracker creation panel\n */\n private showCreationPanel(element: Element): void {\n // Remove existing panel if any\n if (this.panelElement) {\n this.panelElement.remove();\n }\n\n const panel = document.createElement('div');\n panel.id = 'grain-debug-panel';\n \n // Extract element info\n const tagName = element.tagName.toLowerCase();\n const elementId = element.id;\n const elementText = element.textContent?.trim().substring(0, 50) || '';\n const xpath = this.getXPathForElement(element);\n \n panel.innerHTML = `\n <style>\n #grain-debug-panel {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n background: repeating-linear-gradient(\n 45deg,\n #fbbf24,\n #fbbf24 10px,\n #1e293b 10px,\n #1e293b 20px\n );\n border: 2px solid #1e293b;\n border-radius: 16px;\n padding: 6px;\n width: 420px;\n max-width: 90vw;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25), 0 8px 24px rgba(0, 0, 0, 0.15);\n z-index: 1000000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n }\n \n .grain-panel-inner {\n background: white;\n border-radius: 10px;\n overflow: hidden;\n }\n \n .grain-panel-header {\n background: #1e293b;\n padding: 14px 18px;\n color: white;\n }\n \n .grain-panel-header h3 {\n margin: 0 0 4px 0;\n font-size: 16px;\n font-weight: 700;\n letter-spacing: 0.5px;\n color: #fbbf24;\n text-transform: uppercase;\n }\n \n .grain-panel-header p {\n margin: 0;\n font-size: 12px;\n opacity: 0.85;\n color: white;\n }\n \n .grain-panel-body {\n padding: 18px;\n }\n \n #grain-debug-panel .element-preview {\n background: #f8fafc;\n border: 1.5px solid #e2e8f0;\n border-radius: 8px;\n padding: 10px 12px;\n margin-bottom: 16px;\n font-size: 11px;\n color: #475569;\n }\n \n #grain-debug-panel .element-preview div {\n margin-bottom: 4px;\n }\n \n #grain-debug-panel .element-preview div:last-child {\n margin-bottom: 0;\n }\n \n #grain-debug-panel .element-preview strong {\n color: #1e293b;\n font-weight: 600;\n }\n \n #grain-debug-panel label {\n display: block;\n color: #1e293b;\n font-size: 12px;\n font-weight: 600;\n margin-bottom: 6px;\n }\n \n #grain-debug-panel input,\n #grain-debug-panel select {\n width: 100%;\n background: white;\n border: 1.5px solid #e2e8f0;\n border-radius: 8px;\n padding: 9px 12px;\n color: #1e293b;\n font-size: 13px;\n margin-bottom: 14px;\n box-sizing: border-box;\n transition: all 0.2s;\n }\n \n #grain-debug-panel input:focus,\n #grain-debug-panel select:focus {\n outline: none;\n border-color: #fbbf24;\n box-shadow: 0 0 0 3px rgba(251, 191, 36, 0.1);\n }\n \n #grain-debug-panel .button-group {\n display: flex;\n gap: 8px;\n margin-top: 18px;\n }\n \n #grain-debug-panel button {\n flex: 1;\n padding: 10px 16px;\n border: none;\n border-radius: 8px;\n font-size: 13px;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s;\n }\n \n #grain-debug-panel button.primary {\n background: #fbbf24;\n color: #1e293b;\n box-shadow: 0 2px 8px rgba(251, 191, 36, 0.3);\n }\n \n #grain-debug-panel button.primary:hover {\n background: #f59e0b;\n transform: translateY(-1px);\n box-shadow: 0 4px 12px rgba(251, 191, 36, 0.4);\n }\n \n #grain-debug-panel button.secondary {\n background: white;\n border: 1.5px solid #e2e8f0;\n color: #475569;\n }\n \n #grain-debug-panel button.secondary:hover {\n background: #f8fafc;\n border-color: #cbd5e1;\n }\n \n #grain-debug-panel .url-pattern-input {\n display: none;\n }\n \n #grain-debug-panel .url-pattern-input.visible {\n display: block;\n }\n </style>\n <div class=\"grain-panel-inner\">\n <div class=\"grain-panel-header\">\n <h3>Create Tracker</h3>\n <p>Set up automatic tracking for this element</p>\n </div>\n <div class=\"grain-panel-body\">\n <div class=\"element-preview\">\n <div><strong>Element:</strong> ${tagName}${elementId ? `#${elementId}` : ''}</div>\n ${elementText ? `<div><strong>Text:</strong> ${elementText}</div>` : ''}\n </div>\n <div>\n <label>Event Name</label>\n <input type=\"text\" id=\"grain-event-name\" placeholder=\"e.g., signup_button_click\" value=\"\" />\n </div>\n <div>\n <label>Type</label>\n <select id=\"grain-event-type\">\n <option value=\"metric\">Metric</option>\n <option value=\"conversion\">Conversion</option>\n </select>\n </div>\n <div>\n <label>URL Scope</label>\n <select id=\"grain-url-scope\">\n <option value=\"all\">All Pages</option>\n <option value=\"contains\" selected>This Page</option>\n <option value=\"equals\">Exact URL</option>\n </select>\n </div>\n <div class=\"url-pattern-input visible\" id=\"grain-url-pattern-container\">\n <label>URL Pattern</label>\n <input type=\"text\" id=\"grain-url-pattern\" placeholder=\"e.g., /pricing\" value=\"${window.location.pathname}\" />\n </div>\n <div class=\"button-group\">\n <button type=\"button\" class=\"secondary\" id=\"grain-cancel\">Cancel</button>\n <button type=\"button\" class=\"primary\" id=\"grain-create\">\u2713 Create</button>\n </div>\n </div>\n </div>\n `;\n\n document.body.appendChild(panel);\n this.panelElement = panel;\n\n // Auto-generate event name suggestion\n const eventNameInput = panel.querySelector('#grain-event-name') as HTMLInputElement;\n if (eventNameInput) {\n const suggestedName = this.generateEventName(element);\n eventNameInput.value = suggestedName;\n eventNameInput.select();\n }\n\n // Handle URL scope change\n const urlScopeSelect = panel.querySelector('#grain-url-scope') as HTMLSelectElement;\n const urlPatternContainer = panel.querySelector('#grain-url-pattern-container');\n const urlPatternInput = panel.querySelector('#grain-url-pattern') as HTMLInputElement;\n \n if (urlScopeSelect && urlPatternContainer) {\n urlScopeSelect.addEventListener('change', () => {\n if (urlScopeSelect.value === 'all') {\n urlPatternContainer.classList.remove('visible');\n } else {\n urlPatternContainer.classList.add('visible');\n if (urlPatternInput && !urlPatternInput.value) {\n urlPatternInput.value = window.location.pathname;\n }\n }\n });\n }\n\n // Handle buttons\n const cancelBtn = panel.querySelector('#grain-cancel');\n const createBtn = panel.querySelector('#grain-create');\n\n if (cancelBtn) {\n cancelBtn.addEventListener('click', () => this.hideCreationPanel());\n }\n\n if (createBtn) {\n createBtn.addEventListener('click', () => this.handleCreateTracker(xpath));\n }\n }\n\n /**\n * Generate suggested event name from element\n */\n private generateEventName(element: Element): string {\n const tagName = element.tagName.toLowerCase();\n const elementId = element.id;\n const elementText = element.textContent?.trim().toLowerCase().replace(/\\s+/g, '_').substring(0, 30) || '';\n \n // Try to generate meaningful name\n if (elementId) {\n return `${elementId}_click`;\n } else if (elementText) {\n return `${elementText}_click`;\n } else if (tagName === 'button') {\n return 'button_click';\n } else if (tagName === 'a') {\n return 'link_click';\n } else {\n return `${tagName}_click`;\n }\n }\n\n /**\n * Handle tracker creation\n */\n private async handleCreateTracker(selector: string): Promise<void> {\n if (!this.panelElement) return;\n\n const eventNameInput = this.panelElement.querySelector('#grain-event-name') as HTMLInputElement;\n const eventTypeSelect = this.panelElement.querySelector('#grain-event-type') as HTMLSelectElement;\n const urlScopeSelect = this.panelElement.querySelector('#grain-url-scope') as HTMLSelectElement;\n const urlPatternInput = this.panelElement.querySelector('#grain-url-pattern') as HTMLInputElement;\n\n if (!eventNameInput || !eventTypeSelect || !urlScopeSelect) return;\n\n const eventName = eventNameInput.value.trim();\n const eventType = eventTypeSelect.value;\n const urlScope = urlScopeSelect.value;\n const urlPattern = urlPatternInput?.value.trim() || undefined;\n\n // Validate\n if (!eventName) {\n alert('Please enter an event name');\n return;\n }\n\n if (!eventName.match(/^[a-zA-Z0-9_-]+$/)) {\n alert('Event name can only contain letters, numbers, underscores, and hyphens');\n return;\n }\n\n if ((urlScope === 'contains' || urlScope === 'equals') && !urlPattern) {\n alert('Please enter a URL pattern');\n return;\n }\n\n try {\n // Show loading state\n const createBtn = this.panelElement.querySelector('#grain-create') as HTMLButtonElement;\n if (createBtn) {\n createBtn.textContent = 'Creating...';\n createBtn.disabled = true;\n }\n\n // Create tracker\n await this.createTracker(eventName, eventType, selector, urlScope, urlPattern);\n\n // Success\n this.hideCreationPanel();\n this.showSuccessMessage(`Tracker \"${eventName}\" created successfully!`);\n \n // Reload trackers and update UI\n await this.loadExistingTrackers();\n this.updateToolbarStats();\n if (this.showTrackers) {\n this.showTrackerHighlights();\n this.showTrackersList();\n }\n \n this.log('Tracker created:', eventName);\n } catch (error) {\n alert('Failed to create tracker. Please try again.');\n this.log('Failed to create tracker:', error);\n \n // Reset button\n const createBtn = this.panelElement.querySelector('#grain-create') as HTMLButtonElement;\n if (createBtn) {\n createBtn.textContent = 'Create Tracker';\n createBtn.disabled = false;\n }\n }\n }\n\n /**\n * Create tracker via API\n */\n private async createTracker(\n name: string,\n type: string,\n selector: string,\n urlScope: string,\n urlPattern?: string\n ): Promise<void> {\n const url = `${this.apiUrl}/v1/tenant/${encodeURIComponent(this.tenantId)}/debug-sessions/${this.sessionId}/trackers`;\n \n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n name,\n type,\n selector,\n urlScope,\n urlPattern,\n }),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to create tracker: ${response.status}`);\n }\n }\n\n /**\n * Hide creation panel\n */\n private hideCreationPanel(): void {\n if (this.panelElement) {\n this.panelElement.remove();\n this.panelElement = null;\n }\n this.selectedElement = null;\n }\n\n /**\n * Show success message\n */\n private showSuccessMessage(message: string): void {\n const toast = document.createElement('div');\n toast.style.cssText = `\n position: fixed;\n top: 20px;\n left: 50%;\n transform: translateX(-50%) translateY(-20px);\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n color: white;\n padding: 14px 24px;\n border-radius: 12px;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 14px;\n font-weight: 600;\n box-shadow: 0 12px 32px rgba(16, 185, 129, 0.3), 0 4px 12px rgba(0, 0, 0, 0.15);\n z-index: 1000000;\n display: flex;\n align-items: center;\n gap: 10px;\n animation: slideDown 0.3s ease-out forwards;\n `;\n toast.innerHTML = `\n <style>\n @keyframes slideDown {\n to {\n transform: translateX(-50%) translateY(0);\n }\n }\n </style>\n <span style=\"font-size: 18px;\">\u2713</span>\n <span>${message}</span>\n `;\n\n document.body.appendChild(toast);\n\n setTimeout(() => {\n toast.style.animation = 'slideDown 0.3s ease-in reverse';\n setTimeout(() => {\n toast.remove();\n }, 300);\n }, 2700);\n }\n\n /**\n * End debug session\n */\n private async endDebug(): Promise<void> {\n try {\n // Call end session API\n const url = `${this.apiUrl}/v1/tenant/${encodeURIComponent(this.tenantId)}/debug-sessions/${this.sessionId}/end`;\n \n await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n } catch (error) {\n this.log('Failed to end debug session:', error);\n }\n\n // Clean up and reload page\n this.destroy();\n \n // Remove debug params from URL and reload\n const url = new URL(window.location.href);\n url.searchParams.delete('grain_debug');\n url.searchParams.delete('grain_session');\n window.location.href = url.toString();\n }\n\n /**\n * Get XPath for element\n */\n private getXPathForElement(element: Element): string {\n if (element.id) {\n return `//*[@id=\"${element.id}\"]`;\n }\n\n const parts: string[] = [];\n let current: Element | null = element;\n\n while (current && current.nodeType === Node.ELEMENT_NODE) {\n let index = 0;\n let sibling: Element | null = current;\n\n while (sibling) {\n if (sibling.nodeType === Node.ELEMENT_NODE && sibling.tagName === current.tagName) {\n index++;\n }\n sibling = sibling.previousElementSibling;\n }\n\n const tagName = current.tagName.toLowerCase();\n const pathIndex = index > 1 ? `[${index}]` : '';\n parts.unshift(`${tagName}${pathIndex}`);\n\n current = current.parentElement;\n }\n\n return parts.length ? `/${parts.join('/')}` : '';\n }\n\n /**\n * Log debug messages\n */\n private log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[DebugAgent]', ...args);\n }\n }\n\n /**\n * Update toolbar stats\n */\n private updateToolbarStats(): void {\n if (!this.toolbarElement) return;\n \n const totalStat = this.toolbarElement.querySelector('.grain-stat:nth-child(1) .grain-stat-value');\n const activeStat = this.toolbarElement.querySelector('.grain-stat:nth-child(2) .grain-stat-value');\n \n if (totalStat) {\n totalStat.textContent = String(this.existingTrackers.length);\n }\n if (activeStat) {\n activeStat.textContent = String(this.existingTrackers.filter(t => t.isEnabled).length);\n }\n }\n\n /**\n * Destroy the debug agent\n */\n destroy(): void {\n if (this.isDestroyed) return;\n\n this.log('Destroying debug agent');\n this.isDestroyed = true;\n\n this.disableInspectMode();\n this.hideTrackerHighlights();\n this.endDrag();\n\n if (this.toolbarElement) {\n this.toolbarElement.remove();\n this.toolbarElement = null;\n }\n\n if (this.panelElement) {\n this.panelElement.remove();\n this.panelElement = null;\n }\n\n if (this.highlightElement) {\n this.highlightElement.remove();\n this.highlightElement = null;\n }\n }\n}\n", "/**\n * Grain Analytics Web SDK\n * A lightweight, dependency-free TypeScript SDK for sending analytics events to Grain's REST API\n */\n\nimport { ConsentManager, ConsentState, ConsentMode } from './consent';\nimport { setCookie, getCookie, deleteCookie, areCookiesEnabled, CookieConfig } from './cookies';\nimport { ActivityDetector } from './activity';\nimport { HeartbeatManager, type HeartbeatTracker } from './heartbeat';\nimport { PageTrackingManager, type PageTracker } from './page-tracking';\nimport { IdManager, type IdMode } from './id-manager';\nimport {\n categorizeReferrer,\n parseUTMParameters,\n getOrCreateFirstTouchAttribution,\n getSessionUTMParameters,\n getFirstTouchAttribution,\n type ReferrerCategory,\n type UTMParameters,\n type FirstTouchAttribution,\n} from './attribution';\n\n// Re-export attribution types and functions\nexport type { ReferrerCategory, UTMParameters, FirstTouchAttribution };\nexport { categorizeReferrer, parseUTMParameters };\n\n// Re-export timezone-country utilities\nexport { getCountry, getCountryCodeFromTimezone, getState } from './countries';\n\n// Re-export auto-tracking types\nexport type {\n InteractionConfig,\n SectionConfig,\n AutoTrackingConfig,\n SectionViewData,\n SectionTrackingOptions,\n} from './types/auto-tracking';\n\nexport interface GrainEvent {\n eventName: string;\n userId?: string;\n properties?: Record<string, unknown>;\n timestamp?: Date;\n}\n\nexport interface EventPayload {\n eventName: string;\n userId: string;\n properties: Record<string, unknown>;\n}\n\nexport type AuthStrategy = 'NONE' | 'SERVER_SIDE' | 'JWT';\n\nexport interface AuthProvider {\n getToken(): Promise<string> | string;\n}\n\n// Re-export privacy types\nexport type { ConsentState, ConsentMode, CookieConfig };\n\nexport interface GrainConfig {\n tenantId: string;\n apiUrl?: string;\n authStrategy?: AuthStrategy;\n secretKey?: string; // For SERVER_SIDE auth\n authProvider?: AuthProvider; // For JWT auth\n userId?: string; // Global user ID for all events\n batchSize?: number;\n flushInterval?: number; // milliseconds\n retryAttempts?: number;\n retryDelay?: number; // milliseconds\n maxEventsPerRequest?: number; // Maximum events to send in a single API request\n debug?: boolean;\n // Remote Config options\n defaultConfigurations?: Record<string, string>; // Default values for configurations\n configCacheKey?: string; // Custom cache key for configurations\n configRefreshInterval?: number; // Auto-refresh interval in milliseconds (default: 5 minutes)\n enableConfigCache?: boolean; // Enable/disable configuration caching (default: true)\n // Privacy & Consent options (v2.0)\n consentMode?: ConsentMode; // 'cookieless' | 'gdpr-strict' | 'gdpr-opt-out' (default: 'cookieless')\n waitForConsent?: boolean; // Queue events until consent is granted (default: false, only for gdpr-strict)\n // Deprecated: enableCookies - cookies no longer used for user identification\n // Deprecated: anonymizeIP - IP addresses never stored (GeoIP used instead)\n disableAutoProperties?: boolean; // Disable automatic property collection (default: false)\n allowedProperties?: string[]; // Whitelist of allowed event properties (default: all)\n // Automatic Tracking options\n enableHeartbeat?: boolean; // Enable heartbeat tracking (default: true)\n heartbeatActiveInterval?: number; // Active interval in ms (default: 120000 - 2 min)\n heartbeatInactiveInterval?: number; // Inactive interval in ms (default: 300000 - 5 min)\n enableAutoPageView?: boolean; // Enable automatic page view tracking (default: true)\n stripQueryParams?: boolean; // Strip query params from URLs (default: true)\n stripHash?: boolean; // Strip hash from URLs (default: false)\n // Heatmap Tracking options\n enableHeatmapTracking?: boolean; // Enable heatmap tracking (default: true)\n}\n\nexport interface SendEventOptions {\n flush?: boolean; // Force immediate send\n}\n\nexport interface SetPropertyOptions {\n userId?: string; // Override global userId\n}\n\nexport interface LoginOptions {\n userId?: string; // User ID to set\n authToken?: string; // Auth token to set for JWT auth\n authStrategy?: AuthStrategy; // Override auth strategy\n}\n\nexport interface PropertyPayload {\n userId: string;\n [key: string]: string; // All property values must be strings\n}\n\n// Remote Config interfaces\nexport interface RemoteConfigRequest {\n userId: string;\n immediateKeys: string[];\n properties?: Record<string, string>;\n currentUrl?: string; // Optional current URL for page-specific configs\n}\n\nexport interface RemoteConfigResponse {\n userId: string;\n snapshotId: string;\n configurations: Record<string, string>;\n isFinal: boolean;\n qualifiedSegments: string[];\n qualifiedRuleSets: string[];\n timestamp: string;\n isFromCache: boolean;\n autoTrackingConfig?: {\n interactions: Array<{\n eventName: string;\n description: string;\n selector: string;\n priority: number;\n label: string;\n }>;\n sections: Array<{\n sectionName: string;\n description: string;\n sectionType: string;\n selector: string;\n importance: number;\n }>;\n };\n}\n\nexport interface RemoteConfigOptions {\n immediateKeys?: string[];\n properties?: Record<string, string>;\n userId?: string; // Override global userId\n forceRefresh?: boolean; // Force fetch from API, bypass cache\n currentUrl?: string; // Optional current URL for page-specific configs (auto-tracking)\n}\n\nexport interface RemoteConfigCache {\n configurations: Record<string, string>;\n snapshotId: string;\n timestamp: string;\n userId: string;\n}\n\nexport type ConfigChangeListener = (configurations: Record<string, string>) => void;\n\n// Template event interfaces\nexport interface LoginEventProperties extends Record<string, unknown> {\n method?: string; // 'email', 'google', 'facebook', etc.\n success?: boolean;\n errorMessage?: string;\n loginAttempt?: number;\n rememberMe?: boolean;\n twoFactorEnabled?: boolean;\n}\n\nexport interface SignupEventProperties extends Record<string, unknown> {\n method?: string; // 'email', 'google', 'facebook', etc.\n source?: string; // 'landing_page', 'referral', 'ad', etc.\n plan?: string; // 'free', 'pro', 'enterprise', etc.\n success?: boolean;\n errorMessage?: string;\n}\n\nexport interface CheckoutEventProperties extends Record<string, unknown> {\n orderId?: string;\n total?: number;\n currency?: string;\n items?: Array<{\n id: string;\n name: string;\n price: number;\n quantity: number;\n }>;\n paymentMethod?: string; // 'credit_card', 'paypal', 'stripe', etc.\n success?: boolean;\n errorMessage?: string;\n couponCode?: string;\n discount?: number;\n}\n\nexport interface PageViewEventProperties extends Record<string, unknown> {\n page?: string;\n title?: string;\n referrer?: string;\n url?: string;\n userAgent?: string;\n screenResolution?: string;\n viewportSize?: string;\n}\n\nexport interface PurchaseEventProperties extends Record<string, unknown> {\n orderId?: string;\n total?: number;\n currency?: string;\n items?: Array<{\n id: string;\n name: string;\n price: number;\n quantity: number;\n category?: string;\n }>;\n paymentMethod?: string;\n shippingMethod?: string;\n tax?: number;\n shipping?: number;\n discount?: number;\n couponCode?: string;\n}\n\nexport interface SearchEventProperties extends Record<string, unknown> {\n query?: string;\n results?: number;\n filters?: Record<string, unknown>;\n sortBy?: string;\n category?: string;\n success?: boolean;\n}\n\nexport interface AddToCartEventProperties extends Record<string, unknown> {\n itemId?: string;\n itemName?: string;\n price?: number;\n quantity?: number;\n currency?: string;\n category?: string;\n variant?: string;\n}\n\nexport interface RemoveFromCartEventProperties extends Record<string, unknown> {\n itemId?: string;\n itemName?: string;\n price?: number;\n quantity?: number;\n currency?: string;\n category?: string;\n variant?: string;\n}\n\n// Error handling interfaces\nexport interface ErrorDigest {\n eventCount: number;\n totalProperties: number;\n totalSize: number;\n eventNames: string[];\n userIds: string[];\n}\n\nexport interface FormattedError {\n code: string;\n message: string;\n digest: ErrorDigest;\n timestamp: string;\n context: string;\n originalError?: unknown;\n}\n\n/**\n * Main Grain Analytics client\n * \n * Features:\n * - Automatic UUIDv4 generation for anonymous users\n * - Login/logout functionality for dynamic auth token injection\n * - Persistent anonymous user ID across sessions (when consent is granted)\n * - Support for multiple auth strategies (NONE, SERVER_SIDE, JWT)\n * - GDPR-compliant consent management with strict opt-in mode\n * - Optional cookie support for cross-session tracking\n * \n * GDPR Compliance (Opt-in Mode):\n * - Without consent: Only ephemeral session IDs (memory-only) are used\n * - No cookies or localStorage identifiers until consent is granted\n * - Exceptions: User explicitly identified via identify()/login() or JWT auth\n * - Remote config cache and consent preferences use localStorage (functional/necessary)\n */\ntype RequiredConfig = Required<Omit<GrainConfig, 'secretKey' | 'authProvider' | 'userId' | 'cookieOptions' | 'allowedProperties'>> & {\n secretKey?: string;\n authProvider?: AuthProvider;\n userId?: string;\n cookieOptions?: CookieConfig;\n allowedProperties?: string[];\n};\n\nexport class GrainAnalytics implements HeartbeatTracker, PageTracker {\n private config: RequiredConfig;\n private eventQueue: EventPayload[] = [];\n private waitingForConsentQueue: EventPayload[] = [];\n private flushTimer: number | null = null;\n private isDestroyed = false;\n private globalUserId: string | null = null;\n private persistentAnonymousUserId: string | null = null; // Deprecated: use idManager instead\n // Remote Config properties\n private configCache: RemoteConfigCache | null = null;\n private configRefreshTimer: number | null = null;\n private configChangeListeners: ConfigChangeListener[] = [];\n private configFetchPromise: Promise<RemoteConfigResponse> | null = null;\n // Privacy & Consent properties (v2.0)\n private consentManager: ConsentManager;\n private idManager: IdManager;\n private cookiesEnabled: boolean = false; // Deprecated: cookies no longer used for IDs\n // Automatic Tracking properties\n private activityDetector: ActivityDetector | null = null;\n private heartbeatManager: HeartbeatManager | null = null;\n private pageTrackingManager: PageTrackingManager | null = null;\n private ephemeralSessionId: string | null = null;\n private eventCountSinceLastHeartbeat: number = 0;\n // Auto-tracking properties\n private interactionTrackingManager: any | null = null;\n private sectionTrackingManager: any | null = null;\n private heatmapTrackingManager: any | null = null;\n // Session tracking\n private sessionStartTime: number = Date.now();\n private sessionEventCount: number = 0;\n // Debug mode properties\n private debugAgent: any | null = null;\n private isDebugMode: boolean = false;\n\n constructor(config: GrainConfig) {\n this.config = {\n apiUrl: 'https://api.grainql.com',\n authStrategy: 'NONE',\n batchSize: 50,\n flushInterval: 5000, // 5 seconds\n retryAttempts: 3,\n retryDelay: 1000, // 1 second\n maxEventsPerRequest: 160, // Maximum events per API request\n debug: false,\n // Remote Config defaults\n defaultConfigurations: {},\n configCacheKey: 'grain_config',\n configRefreshInterval: 300000, // 5 minutes\n enableConfigCache: true,\n // Privacy defaults (v2.0)\n consentMode: 'COOKIELESS', // Default: privacy-first, no permanent tracking\n waitForConsent: false,\n disableAutoProperties: false,\n // Automatic Tracking defaults\n enableHeartbeat: true,\n heartbeatActiveInterval: 120000, // 2 minutes\n heartbeatInactiveInterval: 300000, // 5 minutes\n enableAutoPageView: true,\n stripQueryParams: true, // Privacy-first: strip by default\n stripHash: false,\n // Heatmap Tracking defaults\n enableHeatmapTracking: true,\n ...config,\n tenantId: config.tenantId,\n };\n\n // Initialize consent manager (v2.0)\n this.consentManager = new ConsentManager(this.config.tenantId, this.config.consentMode);\n\n // Initialize ID manager (v2.0)\n const idMode: IdMode = this.consentManager.getIdMode();\n this.idManager = new IdManager({\n mode: idMode,\n tenantId: this.config.tenantId,\n useLocalStorage: true, // For permanent IDs when consented\n });\n\n // Set global userId if provided in config\n if (config.userId) {\n this.globalUserId = config.userId;\n }\n\n this.validateConfig();\n // Deprecated: initializePersistentAnonymousUserId() - now handled by IdManager\n this.setupBeforeUnload();\n this.startFlushTimer();\n this.initializeConfigCache();\n\n // Initialize ephemeral session ID (memory-only, not persisted)\n this.ephemeralSessionId = this.generateUUID();\n\n // Initialize automatic tracking (browser only)\n if (typeof window !== 'undefined') {\n // Check for debug mode before initializing tracking\n this.checkAndInitializeDebugMode();\n \n this.initializeAutomaticTracking();\n // Track session start\n this.trackSessionStart();\n // Initialize heatmap tracking if enabled\n if (this.config.enableHeatmapTracking) {\n this.initializeHeatmapTracking();\n }\n }\n\n // Set up consent change listener to sync IdManager and flush waiting events (v2.0)\n this.consentManager.addListener((state) => {\n // Sync IdManager with consent state\n const idMode = this.consentManager.getIdMode();\n this.idManager.setMode(idMode);\n \n if (state.granted) {\n this.handleConsentGranted();\n }\n });\n }\n\n private validateConfig(): void {\n if (!this.config.tenantId) {\n throw new Error('Grain Analytics: tenantId is required');\n }\n\n if (this.config.authStrategy === 'SERVER_SIDE' && !this.config.secretKey) {\n throw new Error('Grain Analytics: secretKey is required for SERVER_SIDE auth strategy');\n }\n\n if (this.config.authStrategy === 'JWT' && !this.config.authProvider) {\n throw new Error('Grain Analytics: authProvider is required for JWT auth strategy');\n }\n }\n\n /**\n * Generate a UUID v4 string\n */\n private generateUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n \n // Fallback for environments without crypto.randomUUID\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n const r = Math.random() * 16 | 0;\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n }\n\n /**\n * Check if we should allow persistent storage (GDPR compliance)\n * \n * Returns true if:\n * - Consent has been granted, OR\n * - Not in opt-in mode, OR\n * - User has been explicitly identified by the site (login/identify), OR\n * - Using JWT auth strategy (functional/essential purpose)\n */\n private shouldAllowPersistentStorage(): boolean {\n const hasConsent = this.consentManager.hasConsent('analytics');\n const isCookieless = this.config.consentMode === 'COOKIELESS';\n const userExplicitlyIdentified = !!this.globalUserId;\n const isJWTAuth = this.config.authStrategy === 'JWT';\n \n // Never allow persistent storage in cookieless mode\n if (isCookieless) return false;\n \n // Allow persistent storage if any of these conditions are met\n return hasConsent || userExplicitlyIdentified || isJWTAuth;\n }\n\n /**\n * Generate a proper UUIDv4 identifier for anonymous user ID\n */\n private generateAnonymousUserId(): string {\n return this.generateUUID();\n }\n\n /**\n * Initialize persistent anonymous user ID from cookies or localStorage\n * Priority: Cookie \u2192 localStorage \u2192 generate new\n * \n * GDPR Compliance: In opt-in mode without consent, we skip loading/saving\n * persistent IDs unless the user has been explicitly identified by the site\n * or when using JWT auth (functional/essential purpose)\n */\n private initializePersistentAnonymousUserId(): void {\n if (typeof window === 'undefined') return;\n\n // Check if we should avoid persistent storage (GDPR compliance)\n if (!this.shouldAllowPersistentStorage()) {\n this.log('Opt-in mode without consent: skipping persistent ID initialization (GDPR compliance)');\n return; // Don't load or create persistent ID\n }\n\n const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;\n const cookieName = '_grain_uid';\n \n try {\n // Try to load from cookie first if enabled\n if (this.cookiesEnabled) {\n const cookieValue = getCookie(cookieName);\n if (cookieValue) {\n this.persistentAnonymousUserId = cookieValue;\n this.log('Loaded persistent anonymous user ID from cookie:', this.persistentAnonymousUserId);\n return;\n }\n }\n\n // Fallback to localStorage\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n this.persistentAnonymousUserId = stored;\n this.log('Loaded persistent anonymous user ID from localStorage:', this.persistentAnonymousUserId);\n \n // Migrate to cookie if enabled\n if (this.cookiesEnabled) {\n this.savePersistentAnonymousUserId(stored);\n }\n } else {\n // Generate new UUIDv4 anonymous user ID\n this.persistentAnonymousUserId = this.generateAnonymousUserId();\n this.savePersistentAnonymousUserId(this.persistentAnonymousUserId);\n this.log('Generated new persistent anonymous user ID:', this.persistentAnonymousUserId);\n }\n } catch (error) {\n this.log('Failed to initialize persistent anonymous user ID:', error);\n // Fallback: generate temporary ID without persistence\n this.persistentAnonymousUserId = this.generateAnonymousUserId();\n }\n }\n\n /**\n * Save persistent anonymous user ID to cookie and/or localStorage\n * \n * GDPR Compliance: In opt-in mode without consent, we don't persist IDs\n * unless the user has been explicitly identified or using JWT auth\n */\n private savePersistentAnonymousUserId(userId: string): void {\n if (typeof window === 'undefined') return;\n\n // Check if we should avoid persistent storage (GDPR compliance)\n if (!this.shouldAllowPersistentStorage()) {\n this.log('Opt-in mode without consent: skipping persistent ID save (GDPR compliance)');\n return; // Don't save persistent ID\n }\n\n const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;\n const cookieName = '_grain_uid';\n\n try {\n // Save to cookie if enabled\n if (this.cookiesEnabled) {\n const cookieOptions: CookieConfig = {\n maxAge: 365 * 24 * 60 * 60, // 365 days\n sameSite: 'lax',\n secure: typeof window !== 'undefined' && window.location.protocol === 'https:',\n ...this.config.cookieOptions,\n };\n setCookie(cookieName, userId, cookieOptions);\n }\n\n // Always save to localStorage as fallback\n localStorage.setItem(storageKey, userId);\n } catch (error) {\n this.log('Failed to save persistent anonymous user ID:', error);\n }\n }\n\n /**\n * Get the effective user ID (v2.0)\n * \n * Privacy-first implementation:\n * - Returns global userId if explicitly set (via identify/login)\n * - Otherwise uses IdManager to generate:\n * - Daily rotating ID (cookieless mode)\n * - Permanent ID (with consent)\n */\n private getEffectiveUserIdInternal(): string {\n // Explicit user identification always takes precedence\n if (this.globalUserId) {\n return this.globalUserId;\n }\n \n // Use IdManager to generate appropriate ID based on consent\n return this.idManager.getCurrentUserId();\n }\n\n log(...args: unknown[]): void {\n if (this.config.debug) {\n console.log('[Grain Analytics]', ...args);\n }\n }\n\n /**\n * Create error digest from events\n */\n private createErrorDigest(events: EventPayload[]): ErrorDigest {\n const eventNames = [...new Set(events.map(e => e.eventName))];\n const userIds = [...new Set(events.map(e => e.userId))];\n \n let totalProperties = 0;\n let totalSize = 0;\n \n events.forEach(event => {\n const properties = event.properties || {};\n totalProperties += Object.keys(properties).length;\n totalSize += JSON.stringify(event).length;\n });\n\n return {\n eventCount: events.length,\n totalProperties,\n totalSize,\n eventNames,\n userIds,\n };\n }\n\n /**\n * Format error with beautiful structure\n */\n private formatError(\n error: unknown,\n context: string,\n events?: EventPayload[]\n ): FormattedError {\n const digest = events ? this.createErrorDigest(events) : {\n eventCount: 0,\n totalProperties: 0,\n totalSize: 0,\n eventNames: [],\n userIds: [],\n };\n\n let code = 'UNKNOWN_ERROR';\n let message = 'An unknown error occurred';\n\n if (error instanceof Error) {\n message = error.message;\n \n // Determine error code based on error type and message\n if (message.includes('fetch failed') || message.includes('network error')) {\n code = 'NETWORK_ERROR';\n } else if (message.includes('timeout')) {\n code = 'TIMEOUT_ERROR';\n } else if (message.includes('HTTP 4')) {\n code = 'CLIENT_ERROR';\n } else if (message.includes('HTTP 5')) {\n code = 'SERVER_ERROR';\n } else if (message.includes('JSON')) {\n code = 'PARSE_ERROR';\n } else if (message.includes('auth') || message.includes('unauthorized')) {\n code = 'AUTH_ERROR';\n } else if (message.includes('rate limit') || message.includes('429')) {\n code = 'RATE_LIMIT_ERROR';\n } else {\n code = 'GENERAL_ERROR';\n }\n } else if (typeof error === 'string') {\n message = error;\n code = 'STRING_ERROR';\n } else if (error && typeof error === 'object' && 'status' in error) {\n const status = (error as { status: number }).status;\n code = `HTTP_${status}`;\n message = `HTTP ${status} error`;\n }\n\n return {\n code,\n message,\n digest,\n timestamp: new Date().toISOString(),\n context,\n originalError: error,\n };\n }\n\n /**\n * Log formatted error gracefully\n */\n private logError(formattedError: FormattedError): void {\n // Only log errors in debug mode to reduce noise in production\n if (!this.config.debug) return;\n \n const { code, message, digest, timestamp, context } = formattedError;\n \n const errorOutput = {\n '\uD83D\uDEA8 Grain Analytics Error': {\n 'Error Code': code,\n 'Message': message,\n 'Context': context,\n 'Timestamp': timestamp,\n 'Event Digest': {\n 'Events': digest.eventCount,\n 'Properties': digest.totalProperties,\n 'Size (bytes)': digest.totalSize,\n 'Event Names': digest.eventNames.length > 0 ? digest.eventNames.join(', ') : 'None',\n 'User IDs': digest.userIds.length > 0 ? digest.userIds.slice(0, 3).join(', ') + (digest.userIds.length > 3 ? '...' : '') : 'None',\n }\n }\n };\n\n console.error('\uD83D\uDEA8 Grain Analytics Error:', errorOutput);\n console.error(`[Grain Analytics] ${code}: ${message} (${context}) - Events: ${digest.eventCount}, Props: ${digest.totalProperties}, Size: ${digest.totalSize}B`);\n }\n\n /**\n * Safely execute a function with error handling\n */\n private async safeExecute<T>(\n fn: () => Promise<T>,\n context: string,\n events?: EventPayload[]\n ): Promise<T | null> {\n try {\n return await fn();\n } catch (error) {\n const formattedError = this.formatError(error, context, events);\n this.logError(formattedError);\n return null;\n }\n }\n\n private formatEvent(event: GrainEvent): EventPayload {\n const properties = event.properties || {};\n \n // Auto-enrich events with session-level attribution properties\n // This ensures UTM parameters and attribution data are available on ALL events, not just page_view\n if (!this.config.disableAutoProperties && typeof window !== 'undefined') {\n const hasConsent = this.consentManager.hasConsent('analytics');\n \n // Only enrich if not a system event (they handle their own properties)\n const isSystemEvent = event.eventName.startsWith('_grain_');\n \n if (!isSystemEvent && hasConsent) {\n // Get session UTM parameters\n const sessionUTMs = getSessionUTMParameters();\n if (sessionUTMs) {\n if (sessionUTMs.utm_source) properties.utm_source = sessionUTMs.utm_source;\n if (sessionUTMs.utm_medium) properties.utm_medium = sessionUTMs.utm_medium;\n if (sessionUTMs.utm_campaign) properties.utm_campaign = sessionUTMs.utm_campaign;\n if (sessionUTMs.utm_term) properties.utm_term = sessionUTMs.utm_term;\n if (sessionUTMs.utm_content) properties.utm_content = sessionUTMs.utm_content;\n }\n \n // Get first-touch attribution\n const firstTouch = getFirstTouchAttribution(this.config.tenantId);\n if (firstTouch) {\n properties.first_touch_source = firstTouch.source;\n properties.first_touch_medium = firstTouch.medium;\n properties.first_touch_campaign = firstTouch.campaign;\n properties.first_touch_referrer_category = firstTouch.referrer_category;\n }\n \n // Add session ID if not already present\n if (!properties.session_id) {\n properties.session_id = this.getSessionId();\n }\n }\n }\n \n return {\n eventName: event.eventName,\n userId: event.userId || this.getEffectiveUserIdInternal(),\n properties,\n };\n }\n\n private async getAuthHeaders(): Promise<Record<string, string>> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n\n switch (this.config.authStrategy) {\n case 'NONE':\n break;\n case 'SERVER_SIDE':\n headers['Authorization'] = `Chase ${this.config.secretKey}`;\n break;\n case 'JWT':\n if (this.config.authProvider) {\n const token = await this.config.authProvider.getToken();\n headers['Authorization'] = `Bearer ${token}`;\n }\n break;\n }\n\n return headers;\n }\n\n private async delay(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n private isRetriableError(error: unknown): boolean {\n if (error instanceof Error) {\n // Check for specific network or fetch errors\n const message = error.message.toLowerCase();\n if (message.includes('fetch failed')) return true;\n if (message === 'network error') return true; // Exact match to avoid \"Non-network error\"\n if (message.includes('timeout')) return true;\n if (message.includes('connection')) return true;\n }\n \n // Check for HTTP status codes that are retriable\n if (typeof error === 'object' && error !== null && 'status' in error) {\n const status = (error as { status: number }).status;\n return status >= 500 || status === 429; // Server errors or rate limiting\n }\n \n return false;\n }\n\n private async sendEvents(events: EventPayload[]): Promise<void> {\n if (events.length === 0) return;\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= this.config.retryAttempts; attempt++) {\n try {\n const headers = await this.getAuthHeaders();\n const url = `${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(events),\n });\n\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}`;\n try {\n const errorBody = await response.json();\n if (errorBody?.message) {\n errorMessage = errorBody.message;\n }\n } catch {\n const errorText = await response.text();\n if (errorText) {\n errorMessage = errorText;\n }\n }\n \n const error = new Error(`Failed to send events: ${errorMessage}`) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n this.log(`Successfully sent ${events.length} events`);\n return; // Success, exit retry loop\n \n } catch (error) {\n lastError = error;\n \n if (attempt === this.config.retryAttempts) {\n // Last attempt, don't retry - log error gracefully\n const formattedError = this.formatError(error, `sendEvents (attempt ${attempt + 1}/${this.config.retryAttempts + 1})`, events);\n this.logError(formattedError);\n return; // Don't throw, just return gracefully\n }\n \n if (!this.isRetriableError(error)) {\n // Non-retriable error, don't retry - log error gracefully\n const formattedError = this.formatError(error, `sendEvents (non-retriable error)`, events);\n this.logError(formattedError);\n return; // Don't throw, just return gracefully\n }\n \n const delayMs = this.config.retryDelay * Math.pow(2, attempt); // Exponential backoff\n this.log(`Retrying in ${delayMs}ms after error:`, error);\n await this.delay(delayMs);\n }\n }\n }\n\n private async sendEventsWithBeacon(events: EventPayload[]): Promise<void> {\n if (events.length === 0) return;\n\n try {\n const headers = await this.getAuthHeaders();\n const url = `${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`;\n\n // Send events array directly (not wrapped in object) to match API expectation\n const body = JSON.stringify(events);\n\n // Beacon API doesn't support custom headers, so only use it for unauthenticated requests\n const needsAuth = this.config.authStrategy !== 'NONE';\n\n // Try beacon API first (more reliable for page unload, but only if no auth needed)\n if (!needsAuth && typeof navigator !== 'undefined' && 'sendBeacon' in navigator) {\n const blob = new Blob([body], { type: 'application/json' });\n const success = navigator.sendBeacon(url, blob);\n \n if (success) {\n this.log(`Successfully sent ${events.length} events via beacon`);\n return;\n }\n }\n\n // Use fetch with keepalive (supports headers and works during page unload)\n await fetch(url, {\n method: 'POST',\n headers,\n body,\n keepalive: true,\n });\n } catch (error) {\n // Log error gracefully for beacon failures (page unload scenarios)\n const formattedError = this.formatError(error, 'sendEventsWithBeacon', events);\n this.logError(formattedError);\n }\n }\n\n private startFlushTimer(): void {\n if (typeof window === 'undefined') return;\n \n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n }\n\n this.flushTimer = window.setInterval(() => {\n if (this.eventQueue.length > 0) {\n this.flush().catch((error) => {\n const formattedError = this.formatError(error, 'auto-flush');\n this.logError(formattedError);\n });\n }\n }, this.config.flushInterval);\n }\n\n private setupBeforeUnload(): void {\n if (typeof window === 'undefined') return;\n\n const handleBeforeUnload = () => {\n // Track session end\n this.trackSessionEnd();\n \n if (this.eventQueue.length > 0) {\n // Use beacon API for reliable delivery during page unload\n const eventsToSend = [...this.eventQueue];\n this.eventQueue = [];\n \n const chunks = this.chunkEvents(eventsToSend, this.config.maxEventsPerRequest);\n \n // Send first chunk with beacon (most important for page unload)\n if (chunks.length > 0) {\n this.sendEventsWithBeacon(chunks[0]).catch(() => {\n // Silently fail - page is unloading\n });\n }\n }\n };\n\n // Handle page unload\n window.addEventListener('beforeunload', handleBeforeUnload);\n window.addEventListener('pagehide', handleBeforeUnload);\n \n // Handle visibility change (page hidden)\n document.addEventListener('visibilitychange', () => {\n if (document.visibilityState === 'hidden' && this.eventQueue.length > 0) {\n const eventsToSend = [...this.eventQueue];\n this.eventQueue = [];\n \n const chunks = this.chunkEvents(eventsToSend, this.config.maxEventsPerRequest);\n \n // Send first chunk with beacon (most important for page hidden)\n if (chunks.length > 0) {\n this.sendEventsWithBeacon(chunks[0]).catch(() => {\n // Silently fail\n });\n }\n }\n });\n }\n\n /**\n * Initialize automatic tracking (heartbeat and page views)\n */\n private initializeAutomaticTracking(): void {\n if (this.config.enableHeartbeat) {\n try {\n this.activityDetector = new ActivityDetector();\n this.heartbeatManager = new HeartbeatManager(\n this,\n this.activityDetector,\n {\n activeInterval: this.config.heartbeatActiveInterval,\n inactiveInterval: this.config.heartbeatInactiveInterval,\n debug: this.config.debug,\n }\n );\n } catch (error) {\n this.log('Failed to initialize heartbeat tracking:', error);\n }\n }\n\n if (this.config.enableAutoPageView) {\n try {\n this.pageTrackingManager = new PageTrackingManager(\n this,\n {\n stripQueryParams: this.config.stripQueryParams,\n stripHash: this.config.stripHash,\n debug: this.config.debug,\n tenantId: this.config.tenantId,\n }\n );\n } catch (error) {\n this.log('Failed to initialize page view tracking:', error);\n }\n }\n\n // Initialize auto-tracking when config is available\n this.initializeAutoTracking();\n }\n\n /**\n * Initialize heatmap tracking\n */\n private initializeHeatmapTracking(): void {\n if (typeof window === 'undefined') return;\n \n try {\n this.log('Initializing heatmap tracking');\n \n import('./heatmap-tracking').then(({ HeatmapTrackingManager }) => {\n try {\n this.heatmapTrackingManager = new HeatmapTrackingManager(\n this,\n {\n scrollDebounceDelay: 100,\n batchDelay: 2000,\n maxBatchSize: 20,\n debug: this.config.debug,\n }\n );\n this.log('Heatmap tracking initialized');\n } catch (error) {\n this.log('Failed to initialize heatmap tracking:', error);\n }\n }).catch((error) => {\n this.log('Failed to load heatmap tracking module:', error);\n });\n } catch (error) {\n this.log('Failed to initialize heatmap tracking:', error);\n }\n }\n\n /**\n * Initialize auto-tracking (interactions and sections)\n */\n private async initializeAutoTracking(): Promise<void> {\n try {\n this.log('Initializing auto-tracking');\n \n // Fetch remote config to get auto-tracking configuration\n const userId = this.globalUserId || this.persistentAnonymousUserId || this.generateUUID();\n const currentUrl = typeof window !== 'undefined' ? window.location.href : '';\n \n // Fetch config with currentUrl\n const request: RemoteConfigRequest = {\n userId,\n immediateKeys: [],\n properties: {},\n currentUrl, // Add current URL to request\n };\n\n const headers = await this.getAuthHeaders();\n const url = `${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n this.log('Failed to fetch auto-tracking config:', response.status);\n return;\n }\n\n const configResponse: RemoteConfigResponse = await response.json();\n \n if (configResponse.autoTrackingConfig) {\n this.log('Auto-tracking config loaded');\n this.setupAutoTrackingManagers(configResponse.autoTrackingConfig);\n }\n } catch (error) {\n this.log('Failed to initialize auto-tracking:', error);\n // Fail silently - auto-tracking is optional\n }\n }\n\n /**\n * Setup auto-tracking managers\n */\n private setupAutoTrackingManagers(config: NonNullable<RemoteConfigResponse['autoTrackingConfig']>): void {\n this.log('Setting up auto-tracking managers');\n \n // Lazy load the managers to avoid bundling them if not needed\n if (config.interactions && config.interactions.length > 0) {\n this.log('Loading interaction tracking:', config.interactions.length, 'interactions');\n import('./interaction-tracking').then(({ InteractionTrackingManager }) => {\n try {\n this.interactionTrackingManager = new InteractionTrackingManager(\n this,\n config.interactions,\n {\n debug: this.config.debug,\n enableMutationObserver: true,\n mutationDebounceDelay: 500,\n tenantId: this.config.tenantId,\n apiUrl: this.config.apiUrl,\n }\n );\n this.log('Interaction tracking initialized');\n } catch (error) {\n this.log('Failed to initialize interaction tracking:', error);\n }\n }).catch((error) => {\n this.log('Failed to load interaction tracking module:', error);\n });\n }\n\n if (config.sections && config.sections.length > 0) {\n this.log('Loading section tracking:', config.sections.length, 'sections');\n import('./section-tracking').then(({ SectionTrackingManager }) => {\n try {\n this.sectionTrackingManager = new SectionTrackingManager(\n this,\n config.sections,\n {\n minDwellTime: 1000,\n scrollVelocityThreshold: 500,\n intersectionThreshold: 0.1,\n debounceDelay: 100,\n batchDelay: 2000,\n debug: this.config.debug,\n }\n );\n this.log('Section tracking initialized');\n } catch (error) {\n this.log('Failed to initialize section tracking:', error);\n }\n }).catch((error) => {\n this.log('Failed to load section tracking module:', error);\n });\n }\n }\n\n /**\n * Track session start event\n */\n private trackSessionStart(): void {\n if (typeof window === 'undefined') return;\n\n const hasConsent = this.consentManager.hasConsent('analytics');\n \n const properties: Record<string, unknown> = {\n session_id: this.getSessionId(),\n timestamp: this.sessionStartTime,\n };\n\n if (hasConsent) {\n const referrer = document.referrer || '';\n const currentUrl = window.location.href;\n \n // Parse UTM parameters\n const utmParams = parseUTMParameters(currentUrl);\n const sessionUTMs = getSessionUTMParameters() || utmParams;\n \n // Get first-touch attribution\n const firstTouch = getOrCreateFirstTouchAttribution(\n this.config.tenantId,\n referrer,\n currentUrl,\n sessionUTMs\n );\n\n // Landing page\n properties.landing_page = window.location.pathname;\n \n // Referrer info\n if (referrer) {\n properties.referrer = referrer;\n properties.referrer_domain = new URL(referrer).hostname;\n properties.referrer_category = categorizeReferrer(referrer, currentUrl);\n } else {\n properties.referrer_category = 'direct';\n }\n\n // UTM parameters\n if (sessionUTMs.utm_source) properties.utm_source = sessionUTMs.utm_source;\n if (sessionUTMs.utm_medium) properties.utm_medium = sessionUTMs.utm_medium;\n if (sessionUTMs.utm_campaign) properties.utm_campaign = sessionUTMs.utm_campaign;\n if (sessionUTMs.utm_term) properties.utm_term = sessionUTMs.utm_term;\n if (sessionUTMs.utm_content) properties.utm_content = sessionUTMs.utm_content;\n\n // First-touch attribution\n properties.first_touch_source = firstTouch.source;\n properties.first_touch_medium = firstTouch.medium;\n properties.first_touch_campaign = firstTouch.campaign;\n properties.first_touch_referrer_category = firstTouch.referrer_category;\n\n // Device and browser info\n properties.device = this.getDeviceType();\n properties.screen_resolution = `${screen.width}x${screen.height}`;\n properties.viewport = `${window.innerWidth}x${window.innerHeight}`;\n properties.browser = this.getBrowser();\n properties.os = this.getOS();\n properties.language = navigator.language || '';\n properties.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n }\n\n this.trackSystemEvent('_grain_session_start', properties);\n this.log('Session started');\n }\n\n /**\n * Track session end event\n */\n private trackSessionEnd(): void {\n if (typeof window === 'undefined') return;\n\n const hasConsent = this.consentManager.hasConsent('analytics');\n const sessionDuration = Date.now() - this.sessionStartTime;\n \n const properties: Record<string, unknown> = {\n session_id: this.getSessionId(),\n session_duration: Math.floor(sessionDuration / 1000), // In seconds for easier querying\n duration: sessionDuration, // Keep for backward compatibility\n event_count: this.sessionEventCount,\n timestamp: Date.now(),\n };\n\n if (hasConsent && this.pageTrackingManager) {\n const pageCount = this.pageTrackingManager.getPageViewCount();\n properties.pages_per_session = pageCount;\n properties.page_count = pageCount; // Keep for backward compatibility\n }\n\n this.trackSystemEvent('_grain_session_end', properties);\n this.log('Session ended');\n }\n\n /**\n * Detect browser name\n */\n private getBrowser(): string {\n if (typeof navigator === 'undefined') return 'Unknown';\n const ua = navigator.userAgent;\n if (ua.includes('Firefox/')) return 'Firefox';\n if (ua.includes('Edg/')) return 'Edge';\n if (ua.includes('Chrome/')) return 'Chrome';\n if (ua.includes('Safari/') && !ua.includes('Chrome/')) return 'Safari';\n if (ua.includes('Opera/') || ua.includes('OPR/')) return 'Opera';\n return 'Unknown';\n }\n\n /**\n * Detect operating system\n */\n private getOS(): string {\n if (typeof navigator === 'undefined') return 'Unknown';\n const ua = navigator.userAgent;\n if (ua.includes('Win')) return 'Windows';\n if (ua.includes('Mac')) return 'macOS';\n if (ua.includes('Linux')) return 'Linux';\n if (ua.includes('Android')) return 'Android';\n if (ua.includes('iOS') || ua.includes('iPhone') || ua.includes('iPad')) return 'iOS';\n return 'Unknown';\n }\n\n /**\n * Detect device type (Mobile, Tablet, Desktop)\n */\n private getDeviceType(): string {\n if (typeof window === 'undefined' || typeof navigator === 'undefined') return 'Unknown';\n \n const ua = navigator.userAgent;\n const width = window.innerWidth;\n \n // Check for tablet-specific indicators\n if (ua.includes('iPad') || (ua.includes('Android') && !ua.includes('Mobile'))) {\n return 'Tablet';\n }\n \n // Check for mobile indicators\n if (ua.includes('Mobile') || ua.includes('iPhone') || ua.includes('Android')) {\n return 'Mobile';\n }\n \n // Fallback to screen width detection\n if (width < 768) {\n return 'Mobile';\n } else if (width >= 768 && width < 1024) {\n return 'Tablet';\n }\n \n return 'Desktop';\n }\n\n /**\n * Handle consent granted - upgrade ephemeral session to persistent user\n */\n private handleConsentGranted(): void {\n this.flushWaitingForConsentQueue();\n\n // Initialize persistent ID now that consent is granted (if not already initialized)\n if (!this.persistentAnonymousUserId) {\n this.initializePersistentAnonymousUserId();\n this.log('Initialized persistent ID after consent grant');\n }\n\n // Track consent granted event with mapping from ephemeral to persistent ID\n if (this.ephemeralSessionId) {\n this.trackSystemEvent('_grain_consent_granted', {\n previous_session_id: this.ephemeralSessionId,\n new_user_id: this.getEffectiveUserId(),\n timestamp: Date.now(),\n });\n }\n }\n\n /**\n * Track system events that bypass consent checks (for necessary/functional tracking)\n */\n trackSystemEvent(eventName: string, properties: Record<string, unknown>): void {\n if (this.isDestroyed) return;\n\n const hasConsent = this.consentManager.hasConsent('analytics');\n\n // Create event with appropriate user ID\n // v2.0: Always use IdManager which returns daily rotating ID or permanent ID based on consent\n const event: EventPayload = {\n eventName,\n userId: this.getEffectiveUserId(), // IdManager handles daily vs permanent based on consent\n properties: {\n ...properties,\n _minimal: !hasConsent, // Flag to indicate minimal tracking (daily rotating ID)\n _consent_status: hasConsent ? 'granted' : 'pending',\n },\n };\n\n // Bypass consent check for necessary system events\n this.eventQueue.push(event);\n this.eventCountSinceLastHeartbeat++;\n\n this.log(`Queued system event: ${eventName}`);\n\n // Consider flushing\n if (this.eventQueue.length >= this.config.batchSize) {\n this.flush().catch((error) => {\n const formattedError = this.formatError(error, 'flush system event');\n this.logError(formattedError);\n });\n }\n }\n\n /**\n * Get ephemeral session ID (memory-only, not persisted)\n */\n getEphemeralSessionId(): string {\n if (!this.ephemeralSessionId) {\n this.ephemeralSessionId = this.generateUUID();\n }\n return this.ephemeralSessionId;\n }\n\n /**\n * Get the current page path from page tracker\n */\n getCurrentPage(): string | null {\n return this.pageTrackingManager?.getCurrentPage() || null;\n }\n\n /**\n * Get event count since last heartbeat\n */\n getEventCountSinceLastHeartbeat(): number {\n return this.eventCountSinceLastHeartbeat;\n }\n\n /**\n * Reset event count since last heartbeat\n */\n resetEventCountSinceLastHeartbeat(): void {\n this.eventCountSinceLastHeartbeat = 0;\n }\n\n /**\n * Get the activity detector (for internal use by tracking managers)\n */\n getActivityDetector(): ActivityDetector {\n if (!this.activityDetector) {\n throw new Error('Activity detector not initialized');\n }\n return this.activityDetector;\n }\n\n /**\n * Get the effective user ID (public method)\n */\n getEffectiveUserId(): string {\n return this.getEffectiveUserIdInternal();\n }\n\n /**\n * Get the session ID (ephemeral or persistent based on consent)\n */\n getSessionId(): string {\n const hasConsent = this.consentManager.hasConsent('analytics');\n return hasConsent ? this.getEffectiveUserId() : this.getEphemeralSessionId();\n }\n\n /**\n * Track an analytics event\n */\n async track(eventName: string, properties?: Record<string, unknown>, options?: SendEventOptions): Promise<void>;\n async track(event: GrainEvent, options?: SendEventOptions): Promise<void>;\n async track(\n eventOrName: string | GrainEvent,\n propertiesOrOptions?: Record<string, unknown> | SendEventOptions,\n options?: SendEventOptions\n ): Promise<void> {\n try {\n if (this.isDestroyed) {\n const error = new Error('Grain Analytics: Client has been destroyed');\n const formattedError = this.formatError(error, 'track (client destroyed)');\n this.logError(formattedError);\n return;\n }\n\n let event: GrainEvent;\n let opts: SendEventOptions = {};\n\n if (typeof eventOrName === 'string') {\n event = {\n eventName: eventOrName,\n properties: propertiesOrOptions as Record<string, unknown>,\n };\n opts = options || {};\n } else {\n event = eventOrName;\n opts = propertiesOrOptions as SendEventOptions || {};\n }\n\n // Filter properties if whitelist is enabled\n if (this.config.allowedProperties && event.properties) {\n const filtered: Record<string, unknown> = {};\n for (const key of this.config.allowedProperties) {\n if (key in event.properties) {\n filtered[key] = event.properties[key];\n }\n }\n event.properties = filtered;\n }\n\n const formattedEvent = this.formatEvent(event);\n\n // Check if we should wait for consent (only if explicitly configured)\n if (this.consentManager.shouldWaitForConsent() && this.config.waitForConsent) {\n // Queue event until consent is granted\n this.waitingForConsentQueue.push(formattedEvent);\n this.log(`Event waiting for consent: ${event.eventName}`, event.properties);\n return;\n }\n\n // v2.0: GDPR Strict falls back to cookieless mode (daily rotating IDs)\n // Events are never blocked - IdManager already provides correct ID (daily or permanent)\n const hasConsent = this.consentManager.hasConsent('analytics');\n \n // Add tracking flags to indicate consent status\n formattedEvent.properties = {\n ...formattedEvent.properties,\n _minimal: !hasConsent, // Flag: true = daily rotating ID, false = permanent ID\n _consent_status: hasConsent ? 'granted' : 'pending',\n };\n\n this.eventQueue.push(formattedEvent);\n this.eventCountSinceLastHeartbeat++;\n this.sessionEventCount++;\n this.log(`Queued event: ${event.eventName}`);\n\n // Check if we should flush immediately\n if (opts.flush || this.eventQueue.length >= this.config.batchSize) {\n await this.flush();\n }\n } catch (error) {\n const formattedError = this.formatError(error, 'track');\n this.logError(formattedError);\n }\n }\n\n /**\n * Flush events that were waiting for consent\n */\n private flushWaitingForConsentQueue(): void {\n if (this.waitingForConsentQueue.length === 0) return;\n\n this.log(`Flushing ${this.waitingForConsentQueue.length} events waiting for consent`);\n \n // Move waiting events to main queue\n this.eventQueue.push(...this.waitingForConsentQueue);\n this.waitingForConsentQueue = [];\n\n // Flush immediately\n this.flush().catch((error) => {\n const formattedError = this.formatError(error, 'flush waiting for consent queue');\n this.logError(formattedError);\n });\n }\n\n /**\n * Identify a user (sets userId for subsequent events)\n */\n identify(userId: string): void {\n this.log(`Identified user: ${userId}`);\n this.globalUserId = userId;\n // Clear persistent anonymous user ID since we now have a real user ID\n this.persistentAnonymousUserId = null;\n }\n\n /**\n * Set global user ID for all subsequent events\n */\n setUserId(userId: string | null): void {\n this.log(`Set global user ID: ${userId}`);\n this.globalUserId = userId;\n \n if (userId) {\n // Clear persistent anonymous user ID if setting a real user ID\n this.persistentAnonymousUserId = null;\n } else {\n // If clearing user ID, ensure we have an identifier\n if (!this.persistentAnonymousUserId) {\n this.persistentAnonymousUserId = this.generateAnonymousUserId();\n \n // Try to persist the new anonymous ID (respects GDPR opt-in mode)\n this.savePersistentAnonymousUserId(this.persistentAnonymousUserId);\n }\n }\n }\n\n /**\n * Get current global user ID\n */\n getUserId(): string | null {\n return this.globalUserId;\n }\n\n /**\n * Get current effective user ID (global userId or persistent anonymous ID)\n */\n getEffectiveUserIdPublic(): string {\n return this.getEffectiveUserIdInternal();\n }\n\n /**\n * Login with auth token or userId on the fly\n * \n * @example\n * // Login with userId only\n * client.login({ userId: 'user123' });\n * \n * // Login with auth token (automatically sets authStrategy to JWT)\n * client.login({ authToken: 'jwt-token-here' });\n * \n * // Login with both userId and auth token\n * client.login({ userId: 'user123', authToken: 'jwt-token-here' });\n * \n * // Override auth strategy\n * client.login({ userId: 'user123', authStrategy: 'SERVER_SIDE' });\n */\n login(options: LoginOptions): void {\n try {\n if (this.isDestroyed) {\n const error = new Error('Grain Analytics: Client has been destroyed');\n const formattedError = this.formatError(error, 'login (client destroyed)');\n this.logError(formattedError);\n return;\n }\n\n // Set userId if provided\n if (options.userId) {\n this.log(`Login: Setting user ID to ${options.userId}`);\n this.globalUserId = options.userId;\n // Clear persistent anonymous user ID since we now have a real user ID\n this.persistentAnonymousUserId = null;\n }\n\n // Handle auth token if provided\n if (options.authToken) {\n this.log('Login: Setting auth token');\n // Update auth strategy to JWT if not already set\n if (this.config.authStrategy === 'NONE') {\n this.config.authStrategy = 'JWT';\n }\n \n // Create a simple auth provider that returns the provided token\n this.config.authProvider = {\n getToken: () => options.authToken!\n };\n }\n\n // Override auth strategy if provided\n if (options.authStrategy) {\n this.log(`Login: Setting auth strategy to ${options.authStrategy}`);\n this.config.authStrategy = options.authStrategy;\n }\n\n this.log(`Login successful. Effective user ID: ${this.getEffectiveUserIdInternal()}`);\n } catch (error) {\n const formattedError = this.formatError(error, 'login');\n this.logError(formattedError);\n }\n }\n\n /**\n * Logout and clear user session, fall back to UUIDv4 identifier\n * \n * @example\n * // Logout user and return to anonymous mode\n * client.logout();\n * \n * // After logout, events will use the persistent UUIDv4 identifier\n * client.track('page_view', { page: 'home' });\n */\n logout(): void {\n try {\n if (this.isDestroyed) {\n const error = new Error('Grain Analytics: Client has been destroyed');\n const formattedError = this.formatError(error, 'logout (client destroyed)');\n this.logError(formattedError);\n return;\n }\n\n this.log('Logout: Clearing user session');\n \n // Clear global user ID\n this.globalUserId = null;\n \n // Reset auth strategy to NONE\n this.config.authStrategy = 'NONE';\n this.config.authProvider = undefined;\n \n // Generate new UUIDv4 identifier if we don't have one\n if (!this.persistentAnonymousUserId) {\n this.persistentAnonymousUserId = this.generateAnonymousUserId();\n \n // Try to persist the new anonymous ID\n if (typeof window !== 'undefined') {\n try {\n const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;\n localStorage.setItem(storageKey, this.persistentAnonymousUserId);\n } catch (error) {\n this.log('Failed to persist new anonymous user ID after logout:', error);\n }\n }\n }\n \n this.log(`Logout successful. Effective user ID: ${this.getEffectiveUserIdInternal()}`);\n } catch (error) {\n const formattedError = this.formatError(error, 'logout');\n this.logError(formattedError);\n }\n }\n\n /**\n * Set user properties\n */\n async setProperty(properties: Record<string, unknown>, options?: SetPropertyOptions): Promise<void> {\n try {\n if (this.isDestroyed) {\n const error = new Error('Grain Analytics: Client has been destroyed');\n const formattedError = this.formatError(error, 'setProperty (client destroyed)');\n this.logError(formattedError);\n return;\n }\n\n const userId = options?.userId || this.getEffectiveUserIdInternal();\n \n // Validate property count (max 4 properties)\n const propertyKeys = Object.keys(properties);\n if (propertyKeys.length > 4) {\n const error = new Error('Grain Analytics: Maximum 4 properties allowed per request');\n const formattedError = this.formatError(error, 'setProperty (validation)');\n this.logError(formattedError);\n return;\n }\n\n if (propertyKeys.length === 0) {\n const error = new Error('Grain Analytics: At least one property is required');\n const formattedError = this.formatError(error, 'setProperty (validation)');\n this.logError(formattedError);\n return;\n }\n\n // Serialize all values to strings\n const serializedProperties: Record<string, string> = {};\n for (const [key, value] of Object.entries(properties)) {\n if (value === null || value === undefined) {\n serializedProperties[key] = '';\n } else if (typeof value === 'string') {\n serializedProperties[key] = value;\n } else {\n serializedProperties[key] = JSON.stringify(value);\n }\n }\n\n const payload: PropertyPayload = {\n userId,\n ...serializedProperties,\n };\n\n await this.sendProperties(payload);\n } catch (error) {\n const formattedError = this.formatError(error, 'setProperty');\n this.logError(formattedError);\n }\n }\n\n /**\n * Send properties to the API\n */\n private async sendProperties(payload: PropertyPayload): Promise<void> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= this.config.retryAttempts; attempt++) {\n try {\n const headers = await this.getAuthHeaders();\n const url = `${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/properties`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}`;\n try {\n const errorBody = await response.json();\n if (errorBody?.message) {\n errorMessage = errorBody.message;\n }\n } catch {\n const errorText = await response.text();\n if (errorText) {\n errorMessage = errorText;\n }\n }\n \n const error = new Error(`Failed to set properties: ${errorMessage}`) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n this.log(`Successfully set properties for user ${payload.userId}`);\n return; // Success, exit retry loop\n \n } catch (error) {\n lastError = error;\n \n if (attempt === this.config.retryAttempts) {\n // Last attempt, don't retry - log error gracefully\n const formattedError = this.formatError(error, `sendProperties (attempt ${attempt + 1}/${this.config.retryAttempts + 1})`);\n this.logError(formattedError);\n return; // Don't throw, just return gracefully\n }\n \n if (!this.isRetriableError(error)) {\n // Non-retriable error, don't retry - log error gracefully\n const formattedError = this.formatError(error, 'sendProperties (non-retriable error)');\n this.logError(formattedError);\n return; // Don't throw, just return gracefully\n }\n \n const delayMs = this.config.retryDelay * Math.pow(2, attempt); // Exponential backoff\n this.log(`Retrying in ${delayMs}ms after error:`, error);\n await this.delay(delayMs);\n }\n }\n }\n\n // Template event methods\n\n /**\n * Track user login event\n */\n async trackLogin(properties?: LoginEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('login', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackLogin');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track user signup event\n */\n async trackSignup(properties?: SignupEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('signup', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackSignup');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track checkout event\n */\n async trackCheckout(properties?: CheckoutEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('checkout', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackCheckout');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track page view event\n */\n async trackPageView(properties?: PageViewEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('page_view', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackPageView');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track purchase event\n */\n async trackPurchase(properties?: PurchaseEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('purchase', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackPurchase');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track search event\n */\n async trackSearch(properties?: SearchEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('search', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackSearch');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track add to cart event\n */\n async trackAddToCart(properties?: AddToCartEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('add_to_cart', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackAddToCart');\n this.logError(formattedError);\n }\n }\n\n /**\n * Track remove from cart event\n */\n async trackRemoveFromCart(properties?: RemoveFromCartEventProperties, options?: SendEventOptions): Promise<void> {\n try {\n return await this.track('remove_from_cart', properties, options);\n } catch (error) {\n const formattedError = this.formatError(error, 'trackRemoveFromCart');\n this.logError(formattedError);\n }\n }\n\n /**\n * Manually flush all queued events\n */\n async flush(): Promise<void> {\n try {\n if (this.eventQueue.length === 0) return;\n\n const eventsToSend = [...this.eventQueue];\n this.eventQueue = [];\n\n // Split events into chunks to respect maxEventsPerRequest limit\n const chunks = this.chunkEvents(eventsToSend, this.config.maxEventsPerRequest);\n \n // Send all chunks sequentially to maintain order\n for (const chunk of chunks) {\n await this.sendEvents(chunk);\n }\n } catch (error) {\n const formattedError = this.formatError(error, 'flush');\n this.logError(formattedError);\n }\n }\n\n // Remote Config Methods\n\n /**\n * Initialize configuration cache from localStorage\n */\n private initializeConfigCache(): void {\n if (!this.config.enableConfigCache || typeof window === 'undefined') return;\n\n try {\n const cached = localStorage.getItem(this.config.configCacheKey);\n if (cached) {\n this.configCache = JSON.parse(cached);\n this.log('Loaded configuration from cache:', this.configCache);\n }\n } catch (error) {\n this.log('Failed to load configuration cache:', error);\n }\n }\n\n /**\n * Save configuration cache to localStorage\n */\n private saveConfigCache(cache: RemoteConfigCache): void {\n if (!this.config.enableConfigCache || typeof window === 'undefined') return;\n\n try {\n localStorage.setItem(this.config.configCacheKey, JSON.stringify(cache));\n this.log('Saved configuration to cache:', cache);\n } catch (error) {\n this.log('Failed to save configuration cache:', error);\n }\n }\n\n /**\n * Get configuration value with fallback to defaults\n */\n getConfig(key: string): string | undefined {\n // First check cache\n if (this.configCache?.configurations?.[key]) {\n return this.configCache.configurations[key];\n }\n\n // Then check defaults\n if (this.config.defaultConfigurations?.[key]) {\n return this.config.defaultConfigurations[key];\n }\n\n return undefined;\n }\n\n /**\n * Get all configurations with fallback to defaults\n */\n getAllConfigs(): Record<string, string> {\n const configs = { ...this.config.defaultConfigurations };\n \n if (this.configCache?.configurations) {\n Object.assign(configs, this.configCache.configurations);\n }\n\n return configs;\n }\n\n /**\n * Fetch configurations from API\n */\n async fetchConfig(options: RemoteConfigOptions = {}): Promise<RemoteConfigResponse | null> {\n try {\n if (this.isDestroyed) {\n const error = new Error('Grain Analytics: Client has been destroyed');\n const formattedError = this.formatError(error, 'fetchConfig (client destroyed)');\n this.logError(formattedError);\n return null;\n }\n\n const userId = options.userId || this.getEffectiveUserIdInternal();\n const immediateKeys = options.immediateKeys || [];\n const properties = options.properties || {};\n // Include currentUrl from options, or automatically get it from window.location if available\n // Strip query parameters and hash to match backend normalization\n let currentUrl = options.currentUrl ?? (typeof window !== 'undefined' ? window.location.href : undefined);\n if (currentUrl) {\n try {\n const urlObj = new URL(currentUrl);\n currentUrl = `${urlObj.protocol}//${urlObj.host}${urlObj.pathname}`;\n } catch {\n // If URL parsing fails, use as-is\n }\n }\n\n const request: RemoteConfigRequest = {\n userId,\n immediateKeys,\n properties,\n currentUrl,\n };\n\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= this.config.retryAttempts; attempt++) {\n try {\n const headers = await this.getAuthHeaders();\n const url = `${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`;\n\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n let errorMessage = `HTTP ${response.status}`;\n try {\n const errorBody = await response.json();\n if (errorBody?.message) {\n errorMessage = errorBody.message;\n }\n } catch {\n const errorText = await response.text();\n if (errorText) {\n errorMessage = errorText;\n }\n }\n \n const error = new Error(`Failed to fetch configurations: ${errorMessage}`) as Error & { status?: number };\n error.status = response.status;\n throw error;\n }\n\n const configResponse: RemoteConfigResponse = await response.json();\n \n // Update cache if successful\n if (configResponse.configurations) {\n this.updateConfigCache(configResponse, userId);\n }\n\n this.log('Successfully fetched configurations');\n return configResponse;\n \n } catch (error) {\n lastError = error;\n \n if (attempt === this.config.retryAttempts) {\n // Last attempt, don't retry - log error gracefully\n const formattedError = this.formatError(error, `fetchConfig (attempt ${attempt + 1}/${this.config.retryAttempts + 1})`);\n this.logError(formattedError);\n return null;\n }\n \n if (!this.isRetriableError(error)) {\n // Non-retriable error, don't retry - log error gracefully\n const formattedError = this.formatError(error, 'fetchConfig (non-retriable error)');\n this.logError(formattedError);\n return null;\n }\n \n const delayMs = this.config.retryDelay * Math.pow(2, attempt);\n this.log(`Retrying config fetch in ${delayMs}ms after error:`, error);\n await this.delay(delayMs);\n }\n }\n\n return null;\n } catch (error) {\n const formattedError = this.formatError(error, 'fetchConfig');\n this.logError(formattedError);\n return null;\n }\n }\n\n /**\n * Get configuration asynchronously (cache-first with fallback to API)\n */\n async getConfigAsync(key: string, options: RemoteConfigOptions = {}): Promise<string | undefined> {\n try {\n // Return immediately if we have it in cache and not forcing refresh\n if (!options.forceRefresh && this.configCache?.configurations?.[key]) {\n return this.configCache.configurations[key];\n }\n\n // Return default if available and not forcing refresh\n if (!options.forceRefresh && this.config.defaultConfigurations?.[key]) {\n return this.config.defaultConfigurations[key];\n }\n\n // Fetch from API\n const response = await this.fetchConfig(options);\n if (response) {\n return response.configurations[key];\n }\n \n // Return default as fallback\n return this.config.defaultConfigurations?.[key];\n } catch (error) {\n const formattedError = this.formatError(error, 'getConfigAsync');\n this.logError(formattedError);\n // Return default as fallback\n return this.config.defaultConfigurations?.[key];\n }\n }\n\n /**\n * Get all configurations asynchronously (cache-first with fallback to API)\n */\n async getAllConfigsAsync(options: RemoteConfigOptions = {}): Promise<Record<string, string>> {\n try {\n // Return cache if available and not forcing refresh\n if (!options.forceRefresh && this.configCache?.configurations) {\n return { ...this.config.defaultConfigurations, ...this.configCache.configurations };\n }\n\n // Fetch from API\n const response = await this.fetchConfig(options);\n if (response) {\n return { ...this.config.defaultConfigurations, ...response.configurations };\n }\n \n // Return defaults as fallback\n return { ...this.config.defaultConfigurations };\n } catch (error) {\n const formattedError = this.formatError(error, 'getAllConfigsAsync');\n this.logError(formattedError);\n // Return defaults as fallback\n return { ...this.config.defaultConfigurations };\n }\n }\n\n /**\n * Update configuration cache and notify listeners\n */\n private updateConfigCache(response: RemoteConfigResponse, userId: string): void {\n const newCache: RemoteConfigCache = {\n configurations: response.configurations,\n snapshotId: response.snapshotId,\n timestamp: response.timestamp,\n userId,\n };\n\n const oldConfigs = this.configCache?.configurations || {};\n this.configCache = newCache;\n this.saveConfigCache(newCache);\n\n // Notify listeners if configurations changed\n if (JSON.stringify(oldConfigs) !== JSON.stringify(response.configurations)) {\n this.notifyConfigChangeListeners(response.configurations);\n }\n }\n\n /**\n * Add configuration change listener\n */\n addConfigChangeListener(listener: ConfigChangeListener): void {\n this.configChangeListeners.push(listener);\n }\n\n /**\n * Remove configuration change listener\n */\n removeConfigChangeListener(listener: ConfigChangeListener): void {\n const index = this.configChangeListeners.indexOf(listener);\n if (index > -1) {\n this.configChangeListeners.splice(index, 1);\n }\n }\n\n /**\n * Notify all configuration change listeners\n */\n private notifyConfigChangeListeners(configurations: Record<string, string>): void {\n this.configChangeListeners.forEach(listener => {\n try {\n listener(configurations);\n } catch (error) {\n console.error('[Grain Analytics] Config change listener error:', error);\n }\n });\n }\n\n /**\n * Start automatic configuration refresh timer\n */\n private startConfigRefreshTimer(): void {\n if (typeof window === 'undefined') return;\n \n if (this.configRefreshTimer) {\n clearInterval(this.configRefreshTimer);\n }\n\n this.configRefreshTimer = window.setInterval(() => {\n if (!this.isDestroyed) {\n // Use effective userId (will be generated if not set)\n this.fetchConfig().catch((error) => {\n const formattedError = this.formatError(error, 'auto-config refresh');\n this.logError(formattedError);\n });\n }\n }, this.config.configRefreshInterval);\n }\n\n /**\n * Stop automatic configuration refresh timer\n */\n private stopConfigRefreshTimer(): void {\n if (this.configRefreshTimer) {\n clearInterval(this.configRefreshTimer);\n this.configRefreshTimer = null;\n }\n }\n\n /**\n * Preload configurations for immediate access\n */\n async preloadConfig(immediateKeys: string[] = [], properties?: Record<string, string>): Promise<void> {\n try {\n // Use effective userId (will be generated if not set)\n const effectiveUserId = this.getEffectiveUserIdInternal();\n this.log(`Preloading config for user: ${effectiveUserId}`);\n\n const response = await this.fetchConfig({ immediateKeys, properties });\n if (response) {\n this.startConfigRefreshTimer();\n }\n } catch (error) {\n const formattedError = this.formatError(error, 'preloadConfig');\n this.logError(formattedError);\n }\n }\n\n /**\n * Split events array into chunks of specified size\n */\n private chunkEvents(events: EventPayload[], chunkSize: number): EventPayload[][] {\n const chunks: EventPayload[][] = [];\n for (let i = 0; i < events.length; i += chunkSize) {\n chunks.push(events.slice(i, i + chunkSize));\n }\n return chunks;\n }\n\n // Privacy & Consent Methods\n\n /**\n * Grant consent for tracking (v2.0)\n * Switches from cookieless mode to permanent IDs\n * @param categories - Optional array of consent categories (e.g., ['analytics', 'functional'])\n */\n grantConsent(categories?: string[]): void {\n try {\n this.consentManager.grantConsent(categories);\n \n // Sync ID manager with consent state\n const idMode = this.consentManager.getIdMode();\n this.idManager.setMode(idMode);\n \n this.log('Consent granted, switched to permanent IDs', categories);\n \n // Process any queued events waiting for consent\n if (this.waitingForConsentQueue.length > 0) {\n this.log(`Processing ${this.waitingForConsentQueue.length} queued events`);\n this.eventQueue.push(...this.waitingForConsentQueue);\n this.waitingForConsentQueue = [];\n this.flush();\n }\n } catch (error) {\n const formattedError = this.formatError(error, 'grantConsent');\n this.logError(formattedError);\n }\n }\n\n /**\n * Revoke consent for tracking (v2.0)\n * Switches from permanent IDs to cookieless mode\n * @param categories - Optional array of categories to revoke (if not provided, revokes all)\n */\n revokeConsent(categories?: string[]): void {\n try {\n this.consentManager.revokeConsent(categories);\n \n // Sync ID manager with consent state\n const idMode = this.consentManager.getIdMode();\n this.idManager.setMode(idMode);\n \n this.log('Consent revoked, switched to cookieless mode', categories);\n \n // Clear queued events when consent is fully revoked\n if (!this.consentManager.hasConsent()) {\n this.eventQueue = [];\n this.waitingForConsentQueue = [];\n }\n } catch (error) {\n const formattedError = this.formatError(error, 'revokeConsent');\n this.logError(formattedError);\n }\n }\n\n /**\n * Get current consent state\n */\n getConsentState(): ConsentState | null {\n return this.consentManager.getConsentState();\n }\n\n /**\n * Check if user has granted consent\n * @param category - Optional category to check (if not provided, checks general consent)\n */\n hasConsent(category?: string): boolean {\n return this.consentManager.hasConsent(category);\n }\n\n /**\n * Add listener for consent state changes\n */\n onConsentChange(listener: (state: ConsentState) => void): void {\n this.consentManager.addListener(listener);\n }\n\n /**\n * Remove consent change listener\n */\n offConsentChange(listener: (state: ConsentState) => void): void {\n this.consentManager.removeListener(listener);\n }\n\n /**\n * Check for debug mode parameters and initialize debug agent if valid\n */\n private checkAndInitializeDebugMode(): void {\n if (typeof window === 'undefined') return;\n \n try {\n const urlParams = new URLSearchParams(window.location.search);\n const isDebug = urlParams.get('grain_debug') === '1';\n const sessionId = urlParams.get('grain_session');\n \n if (!isDebug || !sessionId) {\n return;\n }\n \n this.log('Debug mode detected, verifying session:', sessionId);\n \n // Verify session with API\n this.verifyDebugSession(sessionId, window.location.hostname)\n .then((valid) => {\n if (valid) {\n this.log('Debug session verified, initializing debug agent');\n this.isDebugMode = true;\n this.initializeDebugAgent(sessionId);\n } else {\n this.log('Debug session verification failed');\n }\n })\n .catch((error) => {\n this.log('Failed to verify debug session:', error);\n });\n } catch (error) {\n this.log('Error checking debug mode:', error);\n }\n }\n \n /**\n * Verify debug session with API\n */\n private async verifyDebugSession(sessionId: string, domain: string): Promise<boolean> {\n try {\n const url = `${this.config.apiUrl}/v1/tenant/${encodeURIComponent(this.config.tenantId)}/debug-sessions/verify`;\n \n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n sessionId,\n domain,\n }),\n });\n \n if (!response.ok) {\n return false;\n }\n \n const result = await response.json();\n return result.valid === true;\n } catch (error) {\n this.log('Debug session verification error:', error);\n return false;\n }\n }\n \n /**\n * Initialize debug agent\n */\n private initializeDebugAgent(sessionId: string): void {\n if (typeof window === 'undefined') return;\n \n try {\n this.log('Loading debug agent module');\n \n import('./debug-agent').then(({ DebugAgent }) => {\n try {\n this.debugAgent = new DebugAgent(\n this,\n sessionId,\n this.config.tenantId,\n this.config.apiUrl,\n {\n debug: this.config.debug,\n }\n );\n this.log('Debug agent initialized');\n } catch (error) {\n this.log('Failed to initialize debug agent:', error);\n }\n }).catch((error) => {\n this.log('Failed to load debug agent module:', error);\n });\n } catch (error) {\n this.log('Error initializing debug agent:', error);\n }\n }\n\n /**\n * Destroy the client and clean up resources\n */\n destroy(): void {\n this.isDestroyed = true;\n \n if (this.flushTimer) {\n clearInterval(this.flushTimer);\n this.flushTimer = null;\n }\n\n // Stop config refresh timer\n this.stopConfigRefreshTimer();\n\n // Clear config change listeners\n this.configChangeListeners = [];\n\n // Destroy automatic tracking managers\n if (this.heartbeatManager) {\n this.heartbeatManager.destroy();\n this.heartbeatManager = null;\n }\n\n if (this.pageTrackingManager) {\n this.pageTrackingManager.destroy();\n this.pageTrackingManager = null;\n }\n\n if (this.activityDetector) {\n this.activityDetector.destroy();\n this.activityDetector = null;\n }\n\n // Destroy auto-tracking managers\n if (this.interactionTrackingManager) {\n this.interactionTrackingManager.destroy();\n this.interactionTrackingManager = null;\n }\n\n if (this.sectionTrackingManager) {\n this.sectionTrackingManager.destroy();\n this.sectionTrackingManager = null;\n }\n\n if (this.heatmapTrackingManager) {\n this.heatmapTrackingManager.destroy();\n this.heatmapTrackingManager = null;\n }\n \n // Destroy debug agent\n if (this.debugAgent) {\n this.debugAgent.destroy();\n this.debugAgent = null;\n }\n\n // Send any remaining events (in chunks if necessary)\n if (this.eventQueue.length > 0) {\n const eventsToSend = [...this.eventQueue];\n this.eventQueue = [];\n \n const chunks = this.chunkEvents(eventsToSend, this.config.maxEventsPerRequest);\n \n // Send first chunk with beacon (most important for page unload)\n if (chunks.length > 0) {\n this.sendEventsWithBeacon(chunks[0]).catch(() => {\n // Silently fail during cleanup\n });\n \n // If there are more chunks, try to send them with regular fetch\n for (let i = 1; i < chunks.length; i++) {\n this.sendEventsWithBeacon(chunks[i]).catch(() => {\n // Silently fail during cleanup\n });\n }\n }\n }\n }\n}\n\n/**\n * Create a new Grain Analytics client\n */\nexport function createGrainAnalytics(config: GrainConfig): GrainAnalytics {\n return new GrainAnalytics(config);\n}\n\n// Default export for convenience\nexport default GrainAnalytics;\n\n// Global interface for IIFE build\ndeclare global {\n interface Window {\n Grain?: {\n GrainAnalytics: typeof GrainAnalytics;\n createGrainAnalytics: typeof createGrainAnalytics;\n };\n }\n}\n\n// Auto-setup for IIFE build\nif (typeof window !== 'undefined') {\n window.Grain = {\n GrainAnalytics,\n createGrainAnalytics,\n };\n}", "/**\n * Consent management for Grain Analytics v2.0\n * Privacy-first, cookieless by default\n * \n * Consent Modes:\n * - cookieless: Default mode, daily rotating IDs, no consent needed\n * - gdpr-strict: Requires explicit consent, falls back to cookieless\n * - gdpr-opt-out: Permanent IDs by default, cookieless on opt-out\n */\n\nexport type ConsentMode = 'COOKIELESS' | 'GDPR_STRICT' | 'GDPR_OPT_OUT';\n\nexport interface ConsentState {\n granted: boolean;\n categories: string[];\n timestamp: Date;\n version: string;\n}\n\nexport const DEFAULT_CONSENT_CATEGORIES = ['necessary', 'analytics', 'functional'];\nexport const CONSENT_VERSION = '1.0.0';\n\n/**\n * Consent manager for handling user consent state\n * v2.0: Cookieless by default, privacy-first approach\n */\nexport class ConsentManager {\n private consentState: ConsentState | null = null;\n private consentMode: ConsentMode;\n private storageKey: string;\n private listeners: Array<(state: ConsentState) => void> = [];\n\n constructor(tenantId: string, consentMode: ConsentMode = 'COOKIELESS') {\n this.consentMode = consentMode;\n this.storageKey = `grain_consent_${tenantId}`;\n this.loadConsentState();\n }\n\n /**\n * Load consent state from localStorage\n * \n * GDPR Compliance: localStorage only used for storing consent preferences\n * (not for tracking), which is a legitimate interest for compliance.\n */\n private loadConsentState(): void {\n if (typeof window === 'undefined') return;\n\n try {\n const stored = localStorage.getItem(this.storageKey);\n if (stored) {\n const parsed = JSON.parse(stored);\n this.consentState = {\n ...parsed,\n timestamp: new Date(parsed.timestamp),\n };\n } else if (this.consentMode === 'GDPR_OPT_OUT') {\n // Auto-grant consent for opt-out mode (user hasn't opted out yet)\n this.consentState = {\n granted: true,\n categories: DEFAULT_CONSENT_CATEGORIES,\n timestamp: new Date(),\n version: CONSENT_VERSION,\n };\n this.saveConsentState();\n }\n // Note: cookieless and gdpr-strict modes without stored consent \u2192 no permanent tracking\n } catch (error) {\n // Silent failure - will use cookieless mode by default\n }\n }\n\n /**\n * Save consent state to localStorage\n */\n private saveConsentState(): void {\n if (typeof window === 'undefined' || !this.consentState) return;\n\n try {\n localStorage.setItem(this.storageKey, JSON.stringify(this.consentState));\n } catch (error) {\n // Silent failure - consent state won't persist\n }\n }\n\n /**\n * Grant consent with optional categories\n */\n grantConsent(categories?: string[]): void {\n const grantedCategories = categories || DEFAULT_CONSENT_CATEGORIES;\n \n this.consentState = {\n granted: true,\n categories: grantedCategories,\n timestamp: new Date(),\n version: CONSENT_VERSION,\n };\n\n this.saveConsentState();\n this.notifyListeners();\n }\n\n /**\n * Revoke consent (opt-out)\n */\n revokeConsent(categories?: string[]): void {\n if (!this.consentState) {\n this.consentState = {\n granted: false,\n categories: [],\n timestamp: new Date(),\n version: CONSENT_VERSION,\n };\n } else if (categories) {\n // Remove specific categories\n this.consentState = {\n ...this.consentState,\n categories: this.consentState.categories.filter(cat => !categories.includes(cat)),\n granted: this.consentState.categories.length > 0,\n timestamp: new Date(),\n };\n } else {\n // Revoke all consent\n this.consentState = {\n granted: false,\n categories: [],\n timestamp: new Date(),\n version: CONSENT_VERSION,\n };\n }\n\n this.saveConsentState();\n this.notifyListeners();\n }\n\n /**\n * Get current consent state\n */\n getConsentState(): ConsentState | null {\n return this.consentState ? { ...this.consentState } : null;\n }\n\n /**\n * Check if user has granted consent for permanent IDs\n */\n hasConsent(category?: string): boolean {\n // Cookieless mode: no consent needed (no permanent tracking)\n if (this.consentMode === 'COOKIELESS') {\n return false; // No permanent IDs\n }\n\n // GDPR Strict: requires explicit consent\n if (this.consentMode === 'GDPR_STRICT') {\n if (!this.consentState?.granted) {\n return false;\n }\n }\n\n // GDPR Opt-out: consent by default unless explicitly revoked\n if (this.consentMode === 'GDPR_OPT_OUT') {\n // If no state, assume consent (opt-out model)\n if (!this.consentState) {\n return true;\n }\n // Check if consent was revoked\n if (!this.consentState.granted) {\n return false;\n }\n }\n\n // Check specific category if provided\n if (category && this.consentState) {\n return this.consentState.categories.includes(category);\n }\n\n return this.consentState?.granted ?? (this.consentMode === 'GDPR_OPT_OUT');\n }\n\n /**\n * Check if permanent IDs are allowed\n */\n shouldUsePermanentId(): boolean {\n return this.hasConsent();\n }\n\n /**\n * Check if we should strip query parameters from URLs\n * Query params stripped unless:\n * - Mode is gdpr-opt-out, OR\n * - Mode is gdpr-strict AND consent given\n */\n shouldStripQueryParams(): boolean {\n if (this.consentMode === 'COOKIELESS') {\n return true; // Always strip in cookieless mode\n }\n \n if (this.consentMode === 'GDPR_STRICT') {\n return !this.hasConsent(); // Strip unless consented\n }\n \n if (this.consentMode === 'GDPR_OPT_OUT') {\n return false; // Don't strip in opt-out mode\n }\n \n return true; // Default: strip\n }\n\n /**\n * Check if we can track events (always true in v2.0)\n * Even cookieless mode allows basic analytics with daily IDs\n */\n canTrack(): boolean {\n return true; // All modes allow some form of tracking\n }\n\n /**\n * Check if we should wait for consent before tracking\n * Only relevant for GDPR Strict mode\n */\n shouldWaitForConsent(): boolean {\n return this.consentMode === 'GDPR_STRICT' && !this.consentState?.granted;\n }\n\n /**\n * Add consent change listener\n */\n addListener(listener: (state: ConsentState) => void): void {\n this.listeners.push(listener);\n }\n\n /**\n * Remove consent change listener\n */\n removeListener(listener: (state: ConsentState) => void): void {\n const index = this.listeners.indexOf(listener);\n if (index > -1) {\n this.listeners.splice(index, 1);\n }\n }\n\n /**\n * Notify all listeners of consent state change\n */\n private notifyListeners(): void {\n if (!this.consentState) return;\n\n this.listeners.forEach(listener => {\n try {\n listener(this.consentState!);\n } catch (error) {\n // Silent failure - listener threw an error\n }\n });\n }\n\n /**\n * Clear all consent data\n */\n clearConsent(): void {\n if (typeof window === 'undefined') return;\n\n try {\n localStorage.removeItem(this.storageKey);\n this.consentState = null;\n } catch (error) {\n // Silent failure - consent state may not be fully cleared\n }\n }\n\n /**\n * Get current consent mode\n */\n getConsentMode(): ConsentMode {\n return this.consentMode;\n }\n\n /**\n * Get ID mode based on consent state\n * Returns 'cookieless' or 'permanent' for IdManager\n */\n getIdMode(): 'cookieless' | 'permanent' {\n return this.shouldUsePermanentId() ? 'permanent' : 'cookieless';\n }\n}\n\n", "/**\n * Cookie utilities for Grain Analytics\n * Provides GDPR-compliant cookie management with configurable options\n */\n\nexport interface CookieConfig {\n domain?: string;\n path?: string;\n sameSite?: 'strict' | 'lax' | 'none';\n secure?: boolean;\n maxAge?: number; // seconds\n}\n\n/**\n * Set a cookie with configurable options\n */\nexport function setCookie(name: string, value: string, config?: CookieConfig): void {\n if (typeof document === 'undefined') return;\n\n const parts = [`${encodeURIComponent(name)}=${encodeURIComponent(value)}`];\n \n if (config?.maxAge !== undefined) {\n parts.push(`max-age=${config.maxAge}`);\n }\n \n if (config?.domain) {\n parts.push(`domain=${config.domain}`);\n }\n \n if (config?.path) {\n parts.push(`path=${config.path}`);\n } else {\n parts.push('path=/');\n }\n \n if (config?.sameSite) {\n parts.push(`samesite=${config.sameSite}`);\n }\n \n if (config?.secure) {\n parts.push('secure');\n }\n \n document.cookie = parts.join('; ');\n}\n\n/**\n * Get a cookie value by name\n */\nexport function getCookie(name: string): string | null {\n if (typeof document === 'undefined') return null;\n\n const nameEQ = encodeURIComponent(name) + '=';\n const cookies = document.cookie.split(';');\n \n for (let i = 0; i < cookies.length; i++) {\n let cookie = cookies[i];\n while (cookie.charAt(0) === ' ') {\n cookie = cookie.substring(1);\n }\n if (cookie.indexOf(nameEQ) === 0) {\n return decodeURIComponent(cookie.substring(nameEQ.length));\n }\n }\n \n return null;\n}\n\n/**\n * Delete a cookie by name\n */\nexport function deleteCookie(name: string, config?: Pick<CookieConfig, 'domain' | 'path'>): void {\n if (typeof document === 'undefined') return;\n\n const parts = [\n `${encodeURIComponent(name)}=`,\n 'max-age=0',\n ];\n \n if (config?.domain) {\n parts.push(`domain=${config.domain}`);\n }\n \n if (config?.path) {\n parts.push(`path=${config.path}`);\n } else {\n parts.push('path=/');\n }\n \n document.cookie = parts.join('; ');\n}\n\n/**\n * Check if cookies are available and working\n */\nexport function areCookiesEnabled(): boolean {\n if (typeof document === 'undefined') return false;\n\n try {\n const testCookie = '_grain_cookie_test';\n setCookie(testCookie, 'test', { maxAge: 1 });\n const result = getCookie(testCookie) === 'test';\n deleteCookie(testCookie);\n return result;\n } catch {\n return false;\n }\n}\n\n", "/**\n * Activity Detection for Grain Analytics\n * Tracks user activity (mouse, keyboard, touch, scroll) to determine if user is active\n */\n\nexport class ActivityDetector {\n private lastActivityTime: number;\n private activityThreshold: number = 30000; // 30 seconds\n private listeners: Array<() => void> = [];\n private boundActivityHandler: () => void;\n private isDestroyed = false;\n\n // Events that indicate user activity\n private readonly activityEvents = [\n 'mousemove',\n 'mousedown',\n 'keydown',\n 'scroll',\n 'touchstart',\n 'click',\n ] as const;\n\n constructor() {\n this.lastActivityTime = Date.now();\n this.boundActivityHandler = this.debounce(this.handleActivity.bind(this), 500);\n this.setupListeners();\n }\n\n /**\n * Setup event listeners for activity detection\n */\n private setupListeners(): void {\n if (typeof window === 'undefined') return;\n\n for (const event of this.activityEvents) {\n window.addEventListener(event, this.boundActivityHandler, { passive: true });\n }\n }\n\n /**\n * Handle activity event\n */\n private handleActivity(): void {\n if (this.isDestroyed) return;\n this.lastActivityTime = Date.now();\n this.notifyListeners();\n }\n\n /**\n * Debounce function to limit how often activity handler is called\n */\n private debounce(func: () => void, wait: number): () => void {\n let timeout: number | null = null;\n \n return () => {\n if (timeout !== null) {\n clearTimeout(timeout);\n }\n \n timeout = window.setTimeout(() => {\n func();\n timeout = null;\n }, wait);\n };\n }\n\n /**\n * Check if user is currently active\n * @param threshold Time in ms to consider user inactive (default: 30s)\n */\n isActive(threshold?: number): boolean {\n const thresholdToUse = threshold ?? this.activityThreshold;\n const now = Date.now();\n return (now - this.lastActivityTime) < thresholdToUse;\n }\n\n /**\n * Get time since last activity in milliseconds\n */\n getTimeSinceLastActivity(): number {\n return Date.now() - this.lastActivityTime;\n }\n\n /**\n * Get last activity timestamp\n */\n getLastActivityTime(): number {\n return this.lastActivityTime;\n }\n\n /**\n * Set activity threshold\n */\n setActivityThreshold(threshold: number): void {\n this.activityThreshold = threshold;\n }\n\n /**\n * Add listener for activity changes\n */\n addListener(listener: () => void): void {\n this.listeners.push(listener);\n }\n\n /**\n * Remove listener\n */\n removeListener(listener: () => void): void {\n const index = this.listeners.indexOf(listener);\n if (index > -1) {\n this.listeners.splice(index, 1);\n }\n }\n\n /**\n * Notify all listeners\n */\n private notifyListeners(): void {\n for (const listener of this.listeners) {\n try {\n listener();\n } catch (error) {\n // Silent failure - listener threw an error\n }\n }\n }\n\n /**\n * Cleanup and remove listeners\n */\n destroy(): void {\n if (this.isDestroyed) return;\n \n if (typeof window !== 'undefined') {\n for (const event of this.activityEvents) {\n window.removeEventListener(event, this.boundActivityHandler);\n }\n }\n \n this.listeners = [];\n this.isDestroyed = true;\n }\n}\n\n", "/**\n * Heartbeat Manager for Grain Analytics\n * Tracks session activity with consent-aware behavior\n */\n\nimport type { ActivityDetector } from './activity';\n\nexport interface HeartbeatConfig {\n activeInterval: number; // Interval when user is active (ms)\n inactiveInterval: number; // Interval when user is inactive (ms)\n debug?: boolean;\n}\n\nexport interface HeartbeatTracker {\n trackSystemEvent(eventName: string, properties: Record<string, unknown>): void;\n hasConsent(category?: string): boolean;\n getEffectiveUserId(): string;\n getEphemeralSessionId(): string;\n getSessionId(): string;\n getCurrentPage(): string | null;\n getEventCountSinceLastHeartbeat(): number;\n resetEventCountSinceLastHeartbeat(): void;\n}\n\nexport class HeartbeatManager {\n private config: HeartbeatConfig;\n private tracker: HeartbeatTracker;\n private activityDetector: ActivityDetector;\n private heartbeatTimer: number | null = null;\n private isDestroyed = false;\n private lastHeartbeatTime: number;\n private currentInterval: number;\n private hasSentPageLoadHeartbeat = false;\n\n constructor(\n tracker: HeartbeatTracker,\n activityDetector: ActivityDetector,\n config: HeartbeatConfig\n ) {\n this.tracker = tracker;\n this.activityDetector = activityDetector;\n this.config = config;\n this.lastHeartbeatTime = Date.now();\n this.currentInterval = config.activeInterval;\n\n // Send initial heartbeat when page loads (if allowed by consent)\n this.sendPageLoadHeartbeat();\n \n // Start periodic heartbeat tracking\n this.scheduleNextHeartbeat();\n }\n\n /**\n * Send initial heartbeat when page loads\n */\n private sendPageLoadHeartbeat(): void {\n if (this.isDestroyed || this.hasSentPageLoadHeartbeat) return;\n\n // Wait for page to be fully loaded\n if (typeof window !== 'undefined' && document.readyState !== 'complete') {\n const handleLoad = () => {\n this.sendHeartbeat('page_load');\n this.hasSentPageLoadHeartbeat = true;\n window.removeEventListener('load', handleLoad);\n };\n window.addEventListener('load', handleLoad);\n } else {\n // Page is already loaded or we're in a non-browser environment\n this.sendHeartbeat('page_load');\n this.hasSentPageLoadHeartbeat = true;\n }\n }\n\n /**\n * Schedule the next heartbeat based on current activity\n */\n private scheduleNextHeartbeat(): void {\n if (this.isDestroyed) return;\n\n // Clear existing timer\n if (this.heartbeatTimer !== null) {\n clearTimeout(this.heartbeatTimer);\n }\n\n // Determine interval based on activity\n const isActive = this.activityDetector.isActive(60000); // 1 minute threshold\n this.currentInterval = isActive ? this.config.activeInterval : this.config.inactiveInterval;\n\n // Schedule next heartbeat\n this.heartbeatTimer = window.setTimeout(() => {\n this.sendHeartbeat('periodic');\n this.scheduleNextHeartbeat();\n }, this.currentInterval);\n\n if (this.config.debug) {\n console.log(\n `[Heartbeat] Scheduled next heartbeat in ${this.currentInterval / 1000}s (${isActive ? 'active' : 'inactive'})`\n );\n }\n }\n\n /**\n * Send heartbeat event\n */\n private sendHeartbeat(heartbeatType: 'periodic' | 'page_load' = 'periodic'): void {\n if (this.isDestroyed) return;\n\n const now = Date.now();\n const isActive = this.activityDetector.isActive(60000); // 1 minute threshold\n const hasConsent = this.tracker.hasConsent('analytics');\n\n // Base properties (always included)\n const properties: Record<string, unknown> = {\n heartbeat_type: heartbeatType,\n status: isActive ? 'active' : 'inactive',\n timestamp: now,\n };\n\n // Enhanced properties when consent is granted\n if (hasConsent) {\n const page = this.tracker.getCurrentPage();\n if (page) {\n properties.page = page;\n }\n \n properties.session_id = this.tracker.getSessionId();\n \n // Only include duration and event count for periodic heartbeats\n if (heartbeatType === 'periodic') {\n properties.duration = now - this.lastHeartbeatTime;\n properties.event_count = this.tracker.getEventCountSinceLastHeartbeat();\n \n // Reset event count\n this.tracker.resetEventCountSinceLastHeartbeat();\n }\n }\n\n // Track the heartbeat event\n this.tracker.trackSystemEvent('_grain_heartbeat', properties);\n\n this.lastHeartbeatTime = now;\n }\n\n /**\n * Destroy the heartbeat manager\n */\n destroy(): void {\n if (this.isDestroyed) return;\n\n if (this.heartbeatTimer !== null) {\n clearTimeout(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n\n this.isDestroyed = true;\n }\n}\n\n", "/**\n * Attribution and Referral Tracking for Grain Analytics\n * Handles referral categorization and first-touch attribution\n */\n\nexport type ReferrerCategory = 'organic' | 'paid' | 'social' | 'direct' | 'email' | 'referral';\n\nexport interface UTMParameters {\n utm_source?: string;\n utm_medium?: string;\n utm_campaign?: string;\n utm_term?: string;\n utm_content?: string;\n}\n\nexport interface FirstTouchAttribution {\n source: string;\n medium: string;\n campaign: string;\n referrer: string;\n referrer_category: ReferrerCategory;\n timestamp: number;\n}\n\n/**\n * Known paid search parameters\n */\nconst PAID_SEARCH_PARAMS = [\n 'gclid', // Google Ads\n 'msclkid', // Microsoft Ads\n 'fbclid', // Facebook Ads\n 'ttclid', // TikTok Ads\n 'li_fat_id', // LinkedIn Ads\n 'twclid', // Twitter Ads\n 'ScCid', // Snapchat Ads\n];\n\n/**\n * Known social media domains\n */\nconst SOCIAL_DOMAINS = [\n 'facebook.com',\n 'twitter.com',\n 'x.com',\n 'linkedin.com',\n 'instagram.com',\n 'pinterest.com',\n 'reddit.com',\n 'tiktok.com',\n 'youtube.com',\n 'snapchat.com',\n 't.co', // Twitter short links\n 'fb.me', // Facebook short links\n 'lnkd.in', // LinkedIn short links\n];\n\n/**\n * Known organic search engines\n */\nconst SEARCH_ENGINES = [\n 'google.',\n 'bing.com',\n 'yahoo.com',\n 'duckduckgo.com',\n 'baidu.com',\n 'yandex.com',\n 'ecosia.org',\n 'ask.com',\n];\n\n/**\n * Email client domains\n */\nconst EMAIL_DOMAINS = [\n 'mail.google.com',\n 'outlook.live.com',\n 'mail.yahoo.com',\n 'mail.aol.com',\n];\n\n/**\n * Extract domain from URL\n */\nfunction extractDomain(url: string): string {\n try {\n const urlObj = new URL(url);\n return urlObj.hostname.toLowerCase();\n } catch {\n return '';\n }\n}\n\n/**\n * Check if URL contains paid search parameters\n */\nfunction hasPaidSearchParams(url: string): boolean {\n try {\n const urlObj = new URL(url);\n return PAID_SEARCH_PARAMS.some(param => urlObj.searchParams.has(param));\n } catch {\n return false;\n }\n}\n\n/**\n * Categorize referrer based on domain and parameters\n */\nexport function categorizeReferrer(referrer: string, currentUrl: string = ''): ReferrerCategory {\n // Direct traffic (no referrer)\n if (!referrer || referrer.trim() === '') {\n return 'direct';\n }\n\n const domain = extractDomain(referrer);\n \n // Same domain = direct\n if (currentUrl) {\n const currentDomain = extractDomain(currentUrl);\n if (domain === currentDomain) {\n return 'direct';\n }\n }\n\n // Check for paid search parameters\n if (hasPaidSearchParams(referrer) || hasPaidSearchParams(currentUrl)) {\n return 'paid';\n }\n\n // Email clients\n if (EMAIL_DOMAINS.some(emailDomain => domain.includes(emailDomain))) {\n return 'email';\n }\n\n // Social media\n if (SOCIAL_DOMAINS.some(socialDomain => domain.includes(socialDomain))) {\n return 'social';\n }\n\n // Organic search engines\n if (SEARCH_ENGINES.some(searchEngine => domain.includes(searchEngine))) {\n return 'organic';\n }\n\n // Everything else is referral\n return 'referral';\n}\n\n/**\n * Parse UTM parameters from URL\n */\nexport function parseUTMParameters(url: string): UTMParameters {\n try {\n const urlObj = new URL(url);\n const params: UTMParameters = {};\n\n const utmSource = urlObj.searchParams.get('utm_source');\n const utmMedium = urlObj.searchParams.get('utm_medium');\n const utmCampaign = urlObj.searchParams.get('utm_campaign');\n const utmTerm = urlObj.searchParams.get('utm_term');\n const utmContent = urlObj.searchParams.get('utm_content');\n\n if (utmSource) params.utm_source = utmSource;\n if (utmMedium) params.utm_medium = utmMedium;\n if (utmCampaign) params.utm_campaign = utmCampaign;\n if (utmTerm) params.utm_term = utmTerm;\n if (utmContent) params.utm_content = utmContent;\n\n return params;\n } catch {\n return {};\n }\n}\n\n/**\n * Get first-touch attribution from localStorage\n */\nexport function getFirstTouchAttribution(tenantId: string): FirstTouchAttribution | null {\n if (typeof window === 'undefined' || typeof localStorage === 'undefined') {\n return null;\n }\n\n try {\n const key = `_grain_first_touch_${tenantId}`;\n const stored = localStorage.getItem(key);\n if (stored) {\n return JSON.parse(stored) as FirstTouchAttribution;\n }\n } catch (error) {\n console.warn('[Grain Attribution] Failed to retrieve first-touch attribution:', error);\n }\n\n return null;\n}\n\n/**\n * Set first-touch attribution in localStorage\n */\nexport function setFirstTouchAttribution(\n tenantId: string,\n attribution: FirstTouchAttribution\n): void {\n if (typeof window === 'undefined' || typeof localStorage === 'undefined') {\n return;\n }\n\n try {\n const key = `_grain_first_touch_${tenantId}`;\n localStorage.setItem(key, JSON.stringify(attribution));\n } catch (error) {\n console.warn('[Grain Attribution] Failed to store first-touch attribution:', error);\n }\n}\n\n/**\n * Get or create first-touch attribution\n */\nexport function getOrCreateFirstTouchAttribution(\n tenantId: string,\n referrer: string,\n currentUrl: string,\n utmParams: UTMParameters\n): FirstTouchAttribution {\n // Try to get existing first-touch\n const existing = getFirstTouchAttribution(tenantId);\n if (existing) {\n return existing;\n }\n\n // Create new first-touch attribution\n const referrerCategory = categorizeReferrer(referrer, currentUrl);\n const referrerDomain = extractDomain(referrer);\n\n const firstTouch: FirstTouchAttribution = {\n source: utmParams.utm_source || referrerDomain || 'direct',\n medium: utmParams.utm_medium || referrerCategory,\n campaign: utmParams.utm_campaign || 'none',\n referrer: referrer || 'direct',\n referrer_category: referrerCategory,\n timestamp: Date.now(),\n };\n\n // Store it\n setFirstTouchAttribution(tenantId, firstTouch);\n\n return firstTouch;\n}\n\n/**\n * Get session UTM parameters (memory-only, not persisted across page loads)\n */\nlet sessionUTMParams: UTMParameters | null = null;\n\nexport function getSessionUTMParameters(): UTMParameters | null {\n return sessionUTMParams;\n}\n\nexport function setSessionUTMParameters(params: UTMParameters): void {\n sessionUTMParams = params;\n}\n\n/**\n * Clear session UTM parameters\n */\nexport function clearSessionUTMParameters(): void {\n sessionUTMParams = null;\n}\n\n", "const countries = {\n\t\tAD: \"Andorra\",\n\t\tAE: \"United Arab Emirates\",\n\t\tAF: \"Afghanistan\",\n\t\tAG: \"Antigua and Barbuda\",\n\t\tAI: \"Anguilla\",\n\t\tAL: \"Albania\",\n\t\tAM: \"Armenia\",\n\t\tAO: \"Angola\",\n\t\tAQ: \"Antarctica\",\n\t\tAR: \"Argentina\",\n\t\tAS: \"American Samoa\",\n\t\tAT: \"Austria\",\n\t\tAU: \"Australia\",\n\t\tAW: \"Aruba\",\n\t\tAX: \"\u00C5land Islands\",\n\t\tAZ: \"Azerbaijan\",\n\t\tBA: \"Bosnia and Herzegovina\",\n\t\tBB: \"Barbados\",\n\t\tBD: \"Bangladesh\",\n\t\tBE: \"Belgium\",\n\t\tBF: \"Burkina Faso\",\n\t\tBG: \"Bulgaria\",\n\t\tBH: \"Bahrain\",\n\t\tBI: \"Burundi\",\n\t\tBJ: \"Benin\",\n\t\tBL: \"Saint Barth\u00E9lemy\",\n\t\tBM: \"Bermuda\",\n\t\tBN: \"Brunei\",\n\t\tBO: \"Bolivia\",\n\t\tBQ: \"Caribbean Netherlands\",\n\t\tBR: \"Brazil\",\n\t\tBS: \"Bahamas\",\n\t\tBT: \"Bhutan\",\n\t\tBV: \"Bouvet Island\",\n\t\tBW: \"Botswana\",\n\t\tBY: \"Belarus\",\n\t\tBZ: \"Belize\",\n\t\tCA: \"Canada\",\n\t\tCC: \"Cocos Islands\",\n\t\tCD: \"Democratic Republic of the Congo\",\n\t\tCF: \"Central African Republic\",\n\t\tCG: \"Republic of the Congo\",\n\t\tCH: \"Switzerland\",\n\t\tCI: \"Ivory Coast\",\n\t\tCK: \"Cook Islands\",\n\t\tCL: \"Chile\",\n\t\tCM: \"Cameroon\",\n\t\tCN: \"China\",\n\t\tCO: \"Colombia\",\n\t\tCR: \"Costa Rica\",\n\t\tCU: \"Cuba\",\n\t\tCV: \"Cabo Verde\",\n\t\tCW: \"Cura\u00E7ao\",\n\t\tCX: \"Christmas Island\",\n\t\tCY: \"Cyprus\",\n\t\tCZ: \"Czechia\",\n\t\tDE: \"Germany\",\n\t\tDJ: \"Djibouti\",\n\t\tDK: \"Denmark\",\n\t\tDM: \"Dominica\",\n\t\tDO: \"Dominican Republic\",\n\t\tDZ: \"Algeria\",\n\t\tEC: \"Ecuador\",\n\t\tEE: \"Estonia\",\n\t\tEG: \"Egypt\",\n\t\tEH: \"Western Sahara\",\n\t\tER: \"Eritrea\",\n\t\tES: \"Spain\",\n\t\tET: \"Ethiopia\",\n\t\tFI: \"Finland\",\n\t\tFJ: \"Fiji\",\n\t\tFK: \"Falkland Islands\",\n\t\tFM: \"Micronesia\",\n\t\tFO: \"Faroe Islands\",\n\t\tFR: \"France\",\n\t\tGA: \"Gabon\",\n\t\tGB: \"United Kingdom\",\n\t\tGD: \"Grenada\",\n\t\tGE: \"Georgia\",\n\t\tGF: \"French Guiana\",\n\t\tGG: \"Guernsey\",\n\t\tGH: \"Ghana\",\n\t\tGI: \"Gibraltar\",\n\t\tGL: \"Greenland\",\n\t\tGM: \"Gambia\",\n\t\tGN: \"Guinea\",\n\t\tGP: \"Guadeloupe\",\n\t\tGQ: \"Equatorial Guinea\",\n\t\tGR: \"Greece\",\n\t\tGS: \"South Georgia and the South Sandwich Islands\",\n\t\tGT: \"Guatemala\",\n\t\tGU: \"Guam\",\n\t\tGW: \"Guinea-Bissau\",\n\t\tGY: \"Guyana\",\n\t\tHK: \"Hong Kong\",\n\t\tHM: \"Heard Island and McDonald Islands\",\n\t\tHN: \"Honduras\",\n\t\tHR: \"Croatia\",\n\t\tHT: \"Haiti\",\n\t\tHU: \"Hungary\",\n\t\tID: \"Indonesia\",\n\t\tIE: \"Ireland\",\n\t\tIL: \"Israel\",\n\t\tIM: \"Isle of Man\",\n\t\tIN: \"India\",\n\t\tIO: \"British Indian Ocean Territory\",\n\t\tIQ: \"Iraq\",\n\t\tIR: \"Iran\",\n\t\tIS: \"Iceland\",\n\t\tIT: \"Italy\",\n\t\tJE: \"Jersey\",\n\t\tJM: \"Jamaica\",\n\t\tJO: \"Jordan\",\n\t\tJP: \"Japan\",\n\t\tKE: \"Kenya\",\n\t\tKG: \"Kyrgyzstan\",\n\t\tKH: \"Cambodia\",\n\t\tKI: \"Kiribati\",\n\t\tKM: \"Comoros\",\n\t\tKN: \"Saint Kitts and Nevis\",\n\t\tKP: \"North Korea\",\n\t\tKR: \"South Korea\",\n\t\tKW: \"Kuwait\",\n\t\tKY: \"Cayman Islands\",\n\t\tKZ: \"Kazakhstan\",\n\t\tLA: \"Laos\",\n\t\tLB: \"Lebanon\",\n\t\tLC: \"Saint Lucia\",\n\t\tLI: \"Liechtenstein\",\n\t\tLK: \"Sri Lanka\",\n\t\tLR: \"Liberia\",\n\t\tLS: \"Lesotho\",\n\t\tLT: \"Lithuania\",\n\t\tLU: \"Luxembourg\",\n\t\tLV: \"Latvia\",\n\t\tLY: \"Libya\",\n\t\tMA: \"Morocco\",\n\t\tMC: \"Monaco\",\n\t\tMD: \"Moldova\",\n\t\tME: \"Montenegro\",\n\t\tMF: \"Saint Martin\",\n\t\tMG: \"Madagascar\",\n\t\tMH: \"Marshall Islands\",\n\t\tMK: \"North Macedonia\",\n\t\tML: \"Mali\",\n\t\tMM: \"Myanmar\",\n\t\tMN: \"Mongolia\",\n\t\tMO: \"Macao\",\n\t\tMP: \"Northern Mariana Islands\",\n\t\tMQ: \"Martinique\",\n\t\tMR: \"Mauritania\",\n\t\tMS: \"Montserrat\",\n\t\tMT: \"Malta\",\n\t\tMU: \"Mauritius\",\n\t\tMV: \"Maldives\",\n\t\tMW: \"Malawi\",\n\t\tMX: \"Mexico\",\n\t\tMY: \"Malaysia\",\n\t\tMZ: \"Mozambique\",\n\t\tNA: \"Namibia\",\n\t\tNC: \"New Caledonia\",\n\t\tNE: \"Niger\",\n\t\tNF: \"Norfolk Island\",\n\t\tNG: \"Nigeria\",\n\t\tNI: \"Nicaragua\",\n\t\tNL: \"Netherlands\",\n\t\tNO: \"Norway\",\n\t\tNP: \"Nepal\",\n\t\tNR: \"Nauru\",\n\t\tNU: \"Niue\",\n\t\tNZ: \"New Zealand\",\n\t\tOM: \"Oman\",\n\t\tPA: \"Panama\",\n\t\tPE: \"Peru\",\n\t\tPF: \"French Polynesia\",\n\t\tPG: \"Papua New Guinea\",\n\t\tPH: \"Philippines\",\n\t\tPK: \"Pakistan\",\n\t\tPL: \"Poland\",\n\t\tPM: \"Saint Pierre and Miquelon\",\n\t\tPN: \"Pitcairn\",\n\t\tPR: \"Puerto Rico\",\n\t\tPS: \"Palestine\",\n\t\tPT: \"Portugal\",\n\t\tPW: \"Palau\",\n\t\tPY: \"Paraguay\",\n\t\tQA: \"Qatar\",\n\t\tRE: \"R\u00E9union\",\n\t\tRO: \"Romania\",\n\t\tRS: \"Serbia\",\n\t\tRU: \"Russia\",\n\t\tRW: \"Rwanda\",\n\t\tSA: \"Saudi Arabia\",\n\t\tSB: \"Solomon Islands\",\n\t\tSC: \"Seychelles\",\n\t\tSD: \"Sudan\",\n\t\tSE: \"Sweden\",\n\t\tSG: \"Singapore\",\n\t\tSH: \"Saint Helena, Ascension and Tristan da Cunha\",\n\t\tSI: \"Slovenia\",\n\t\tSJ: \"Svalbard and Jan Mayen\",\n\t\tSK: \"Slovakia\",\n\t\tSL: \"Sierra Leone\",\n\t\tSM: \"San Marino\",\n\t\tSN: \"Senegal\",\n\t\tSO: \"Somalia\",\n\t\tSR: \"Suriname\",\n\t\tSS: \"South Sudan\",\n\t\tST: \"Sao Tome and Principe\",\n\t\tSV: \"El Salvador\",\n\t\tSX: \"Sint Maarten\",\n\t\tSY: \"Syria\",\n\t\tSZ: \"Eswatini\",\n\t\tTC: \"Turks and Caicos Islands\",\n\t\tTD: \"Chad\",\n\t\tTF: \"French Southern Territories\",\n\t\tTG: \"Togo\",\n\t\tTH: \"Thailand\",\n\t\tTJ: \"Tajikistan\",\n\t\tTK: \"Tokelau\",\n\t\tTL: \"Timor-Leste\",\n\t\tTM: \"Turkmenistan\",\n\t\tTN: \"Tunisia\",\n\t\tTO: \"Tonga\",\n\t\tTR: \"Turkey\",\n\t\tTT: \"Trinidad and Tobago\",\n\t\tTV: \"Tuvalu\",\n\t\tTW: \"Taiwan\",\n\t\tTZ: \"Tanzania\",\n\t\tUA: \"Ukraine\",\n\t\tUG: \"Uganda\",\n\t\tUM: \"United States Minor Outlying Islands\",\n\t\tUS: \"United States of America\",\n\t\tUY: \"Uruguay\",\n\t\tUZ: \"Uzbekistan\",\n\t\tVA: \"Holy See\",\n\t\tVC: \"Saint Vincent and the Grenadines\",\n\t\tVE: \"Venezuela\",\n\t\tVG: \"Virgin Islands (UK)\",\n\t\tVI: \"Virgin Islands (US)\",\n\t\tVN: \"Vietnam\",\n\t\tVU: \"Vanuatu\",\n\t\tWF: \"Wallis and Futuna\",\n\t\tWS: \"Samoa\",\n\t\tYE: \"Yemen\",\n\t\tYT: \"Mayotte\",\n\t\tZA: \"South Africa\",\n\t\tZM: \"Zambia\",\n\t\tZW: \"Zimbabwe\"\n};\n\nconst timezones: Record<string, any> = {\n\t\t\"Africa/Abidjan\": {\n\t\t\tu: 0,\n\t\t\tc: [\"CI\", \"BF\", \"GH\", \"GM\", \"GN\", \"ML\", \"MR\", \"SH\", \"SL\", \"SN\", \"TG\"]\n\t\t},\n\t\t\"Africa/Accra\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"GH\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Addis_Ababa\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"ET\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Algiers\": {\n\t\t\tu: 60,\n\t\t\tc: [\"DZ\"]\n\t\t},\n\t\t\"Africa/Asmara\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"ER\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Asmera\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"ER\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Bamako\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"ML\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Bangui\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"CF\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Banjul\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"GM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Bissau\": {\n\t\t\tu: 0,\n\t\t\tc: [\"GW\"]\n\t\t},\n\t\t\"Africa/Blantyre\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"MW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Brazzaville\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"CG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Bujumbura\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"BI\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Cairo\": {\n\t\t\tu: 120,\n\t\t\tc: [\"EG\"]\n\t\t},\n\t\t\"Africa/Casablanca\": {\n\t\t\tu: 60,\n\t\t\td: 0,\n\t\t\tc: [\"MA\"]\n\t\t},\n\t\t\"Africa/Ceuta\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"ES\"]\n\t\t},\n\t\t\"Africa/Conakry\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"GN\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Dakar\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"SN\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Dar_es_Salaam\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"TZ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Djibouti\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"DJ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Douala\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"CM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/El_Aaiun\": {\n\t\t\tu: 60,\n\t\t\td: 0,\n\t\t\tc: [\"EH\"]\n\t\t},\n\t\t\"Africa/Freetown\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"SL\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Gaborone\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"BW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Harare\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"ZW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Johannesburg\": {\n\t\t\tu: 120,\n\t\t\tc: [\"ZA\", \"LS\", \"SZ\"]\n\t\t},\n\t\t\"Africa/Juba\": {\n\t\t\tu: 120,\n\t\t\tc: [\"SS\"]\n\t\t},\n\t\t\"Africa/Kampala\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"UG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Khartoum\": {\n\t\t\tu: 120,\n\t\t\tc: [\"SD\"]\n\t\t},\n\t\t\"Africa/Kigali\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"RW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Kinshasa\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"CD\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Lagos\": {\n\t\t\tu: 60,\n\t\t\tc: [\"NG\", \"AO\", \"BJ\", \"CD\", \"CF\", \"CG\", \"CM\", \"GA\", \"GQ\", \"NE\"]\n\t\t},\n\t\t\"Africa/Libreville\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"GA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Lome\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"TG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Luanda\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"AO\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Lubumbashi\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"CD\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Lusaka\": {\n\t\t\ta: \"Africa/Maputo\",\n\t\t\tc: [\"ZM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Malabo\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"GQ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Maputo\": {\n\t\t\tu: 120,\n\t\t\tc: [\"MZ\", \"BI\", \"BW\", \"CD\", \"MW\", \"RW\", \"ZM\", \"ZW\"]\n\t\t},\n\t\t\"Africa/Maseru\": {\n\t\t\ta: \"Africa/Johannesburg\",\n\t\t\tc: [\"LS\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Mbabane\": {\n\t\t\ta: \"Africa/Johannesburg\",\n\t\t\tc: [\"SZ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Mogadishu\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"SO\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Monrovia\": {\n\t\t\tu: 0,\n\t\t\tc: [\"LR\"]\n\t\t},\n\t\t\"Africa/Nairobi\": {\n\t\t\tu: 180,\n\t\t\tc: [\"KE\", \"DJ\", \"ER\", \"ET\", \"KM\", \"MG\", \"SO\", \"TZ\", \"UG\", \"YT\"]\n\t\t},\n\t\t\"Africa/Ndjamena\": {\n\t\t\tu: 60,\n\t\t\tc: [\"TD\"]\n\t\t},\n\t\t\"Africa/Niamey\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"NE\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Nouakchott\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"MR\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Ouagadougou\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"BF\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Porto-Novo\": {\n\t\t\ta: \"Africa/Lagos\",\n\t\t\tc: [\"BJ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Sao_Tome\": {\n\t\t\tu: 0,\n\t\t\tc: [\"ST\"]\n\t\t},\n\t\t\"Africa/Timbuktu\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"ML\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Africa/Tripoli\": {\n\t\t\tu: 120,\n\t\t\tc: [\"LY\"]\n\t\t},\n\t\t\"Africa/Tunis\": {\n\t\t\tu: 60,\n\t\t\tc: [\"TN\"]\n\t\t},\n\t\t\"Africa/Windhoek\": {\n\t\t\tu: 120,\n\t\t\tc: [\"NA\"]\n\t\t},\n\t\t\"America/Adak\": {\n\t\t\tu: -600,\n\t\t\td: -540,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Anchorage\": {\n\t\t\tu: -540,\n\t\t\td: -480,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Anguilla\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"AI\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Antigua\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"AG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Araguaina\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Argentina/Buenos_Aires\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Catamarca\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/ComodRivadavia\": {\n\t\t\ta: \"America/Argentina/Catamarca\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Argentina/Cordoba\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Jujuy\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/La_Rioja\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Mendoza\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Rio_Gallegos\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Salta\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/San_Juan\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/San_Luis\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Tucuman\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Argentina/Ushuaia\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AR\"]\n\t\t},\n\t\t\"America/Aruba\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"AW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Asuncion\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"PY\"]\n\t\t},\n\t\t\"America/Atikokan\": {\n\t\t\ta: \"America/Panama\",\n\t\t\tc: [\"CA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Atka\": {\n\t\t\ta: \"America/Adak\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Bahia\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Bahia_Banderas\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Barbados\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BB\"]\n\t\t},\n\t\t\"America/Belem\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Belize\": {\n\t\t\tu: -360,\n\t\t\tc: [\"BZ\"]\n\t\t},\n\t\t\"America/Blanc-Sablon\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"CA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Boa_Vista\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Bogota\": {\n\t\t\tu: -300,\n\t\t\tc: [\"CO\"]\n\t\t},\n\t\t\"America/Boise\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Buenos_Aires\": {\n\t\t\ta: \"America/Argentina/Buenos_Aires\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Cambridge_Bay\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Campo_Grande\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Cancun\": {\n\t\t\tu: -300,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Caracas\": {\n\t\t\tu: -240,\n\t\t\tc: [\"VE\"]\n\t\t},\n\t\t\"America/Catamarca\": {\n\t\t\ta: \"America/Argentina/Catamarca\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Cayenne\": {\n\t\t\tu: -180,\n\t\t\tc: [\"GF\"]\n\t\t},\n\t\t\"America/Cayman\": {\n\t\t\ta: \"America/Panama\",\n\t\t\tc: [\"KY\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Chicago\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Chihuahua\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Coral_Harbour\": {\n\t\t\ta: \"America/Panama\",\n\t\t\tc: [\"CA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Cordoba\": {\n\t\t\ta: \"America/Argentina/Cordoba\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Costa_Rica\": {\n\t\t\tu: -360,\n\t\t\tc: [\"CR\"]\n\t\t},\n\t\t\"America/Creston\": {\n\t\t\ta: \"America/Phoenix\",\n\t\t\tc: [\"CA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Cuiaba\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Curacao\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"CW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Danmarkshavn\": {\n\t\t\tu: 0,\n\t\t\tc: [\"GL\"]\n\t\t},\n\t\t\"America/Dawson\": {\n\t\t\tu: -420,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Dawson_Creek\": {\n\t\t\tu: -420,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Denver\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Detroit\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Dominica\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"DM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Edmonton\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Eirunepe\": {\n\t\t\tu: -300,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/El_Salvador\": {\n\t\t\tu: -360,\n\t\t\tc: [\"SV\"]\n\t\t},\n\t\t\"America/Ensenada\": {\n\t\t\ta: \"America/Tijuana\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Fort_Nelson\": {\n\t\t\tu: -420,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Fort_Wayne\": {\n\t\t\ta: \"America/Indiana/Indianapolis\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Fortaleza\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Glace_Bay\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Godthab\": {\n\t\t\ta: \"America/Nuuk\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Goose_Bay\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Grand_Turk\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"TC\"]\n\t\t},\n\t\t\"America/Grenada\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"GD\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Guadeloupe\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"GP\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Guatemala\": {\n\t\t\tu: -360,\n\t\t\tc: [\"GT\"]\n\t\t},\n\t\t\"America/Guayaquil\": {\n\t\t\tu: -300,\n\t\t\tc: [\"EC\"]\n\t\t},\n\t\t\"America/Guyana\": {\n\t\t\tu: -240,\n\t\t\tc: [\"GY\"]\n\t\t},\n\t\t\"America/Halifax\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Havana\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"CU\"]\n\t\t},\n\t\t\"America/Hermosillo\": {\n\t\t\tu: -420,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Indiana/Indianapolis\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Knox\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Marengo\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Petersburg\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Tell_City\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Vevay\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Vincennes\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indiana/Winamac\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Indianapolis\": {\n\t\t\ta: \"America/Indiana/Indianapolis\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Inuvik\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Iqaluit\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Jamaica\": {\n\t\t\tu: -300,\n\t\t\tc: [\"JM\"]\n\t\t},\n\t\t\"America/Jujuy\": {\n\t\t\ta: \"America/Argentina/Jujuy\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Juneau\": {\n\t\t\tu: -540,\n\t\t\td: -480,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Kentucky/Louisville\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Kentucky/Monticello\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Knox_IN\": {\n\t\t\ta: \"America/Indiana/Knox\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Kralendijk\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"BQ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/La_Paz\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BO\"]\n\t\t},\n\t\t\"America/Lima\": {\n\t\t\tu: -300,\n\t\t\tc: [\"PE\"]\n\t\t},\n\t\t\"America/Los_Angeles\": {\n\t\t\tu: -480,\n\t\t\td: -420,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Louisville\": {\n\t\t\ta: \"America/Kentucky/Louisville\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Lower_Princes\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"SX\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Maceio\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Managua\": {\n\t\t\tu: -360,\n\t\t\tc: [\"NI\"]\n\t\t},\n\t\t\"America/Manaus\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Marigot\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"MF\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Martinique\": {\n\t\t\tu: -240,\n\t\t\tc: [\"MQ\"]\n\t\t},\n\t\t\"America/Matamoros\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Mazatlan\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Mendoza\": {\n\t\t\ta: \"America/Argentina/Mendoza\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Menominee\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Merida\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Metlakatla\": {\n\t\t\tu: -540,\n\t\t\td: -480,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Mexico_City\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Miquelon\": {\n\t\t\tu: -180,\n\t\t\td: -120,\n\t\t\tc: [\"PM\"]\n\t\t},\n\t\t\"America/Moncton\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Monterrey\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Montevideo\": {\n\t\t\tu: -180,\n\t\t\tc: [\"UY\"]\n\t\t},\n\t\t\"America/Montreal\": {\n\t\t\ta: \"America/Toronto\",\n\t\t\tc: [\"CA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Montserrat\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"MS\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Nassau\": {\n\t\t\ta: \"America/Toronto\",\n\t\t\tc: [\"BS\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/New_York\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Nipigon\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Nome\": {\n\t\t\tu: -540,\n\t\t\td: -480,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Noronha\": {\n\t\t\tu: -120,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/North_Dakota/Beulah\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/North_Dakota/Center\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/North_Dakota/New_Salem\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Nuuk\": {\n\t\t\tu: -180,\n\t\t\td: -120,\n\t\t\tc: [\"GL\"]\n\t\t},\n\t\t\"America/Ojinaga\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Panama\": {\n\t\t\tu: -300,\n\t\t\tc: [\"PA\", \"CA\", \"KY\"]\n\t\t},\n\t\t\"America/Pangnirtung\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Paramaribo\": {\n\t\t\tu: -180,\n\t\t\tc: [\"SR\"]\n\t\t},\n\t\t\"America/Phoenix\": {\n\t\t\tu: -420,\n\t\t\tc: [\"US\", \"CA\"]\n\t\t},\n\t\t\"America/Port-au-Prince\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"HT\"]\n\t\t},\n\t\t\"America/Port_of_Spain\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"TT\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Porto_Acre\": {\n\t\t\ta: \"America/Rio_Branco\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Porto_Velho\": {\n\t\t\tu: -240,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Puerto_Rico\": {\n\t\t\tu: -240,\n\t\t\tc: [\n\t\t\t\t\"PR\",\n\t\t\t\t\"AG\",\n\t\t\t\t\"CA\",\n\t\t\t\t\"AI\",\n\t\t\t\t\"AW\",\n\t\t\t\t\"BL\",\n\t\t\t\t\"BQ\",\n\t\t\t\t\"CW\",\n\t\t\t\t\"DM\",\n\t\t\t\t\"GD\",\n\t\t\t\t\"GP\",\n\t\t\t\t\"KN\",\n\t\t\t\t\"LC\",\n\t\t\t\t\"MF\",\n\t\t\t\t\"MS\",\n\t\t\t\t\"SX\",\n\t\t\t\t\"TT\",\n\t\t\t\t\"VC\",\n\t\t\t\t\"VG\",\n\t\t\t\t\"VI\"\n\t\t\t]\n\t\t},\n\t\t\"America/Punta_Arenas\": {\n\t\t\tu: -180,\n\t\t\tc: [\"CL\"]\n\t\t},\n\t\t\"America/Rainy_River\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Rankin_Inlet\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Recife\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Regina\": {\n\t\t\tu: -360,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Resolute\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Rio_Branco\": {\n\t\t\tu: -300,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Rosario\": {\n\t\t\ta: \"America/Argentina/Cordoba\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Santa_Isabel\": {\n\t\t\ta: \"America/Tijuana\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Santarem\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Santiago\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"CL\"]\n\t\t},\n\t\t\"America/Santo_Domingo\": {\n\t\t\tu: -240,\n\t\t\tc: [\"DO\"]\n\t\t},\n\t\t\"America/Sao_Paulo\": {\n\t\t\tu: -180,\n\t\t\tc: [\"BR\"]\n\t\t},\n\t\t\"America/Scoresbysund\": {\n\t\t\tu: -60,\n\t\t\td: 0,\n\t\t\tc: [\"GL\"]\n\t\t},\n\t\t\"America/Shiprock\": {\n\t\t\ta: \"America/Denver\",\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Sitka\": {\n\t\t\tu: -540,\n\t\t\td: -480,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/St_Barthelemy\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"BL\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/St_Johns\": {\n\t\t\tu: -150,\n\t\t\td: -90,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/St_Kitts\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"KN\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/St_Lucia\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"LC\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/St_Thomas\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"VI\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/St_Vincent\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"VC\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Swift_Current\": {\n\t\t\tu: -360,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Tegucigalpa\": {\n\t\t\tu: -360,\n\t\t\tc: [\"HN\"]\n\t\t},\n\t\t\"America/Thule\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"GL\"]\n\t\t},\n\t\t\"America/Thunder_Bay\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Tijuana\": {\n\t\t\tu: -480,\n\t\t\td: -420,\n\t\t\tc: [\"MX\"]\n\t\t},\n\t\t\"America/Toronto\": {\n\t\t\tu: -300,\n\t\t\td: -240,\n\t\t\tc: [\"CA\", \"BS\"]\n\t\t},\n\t\t\"America/Tortola\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"VG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Vancouver\": {\n\t\t\tu: -480,\n\t\t\td: -420,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Virgin\": {\n\t\t\ta: \"America/Puerto_Rico\",\n\t\t\tc: [\"VI\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"America/Whitehorse\": {\n\t\t\tu: -420,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Winnipeg\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"America/Yakutat\": {\n\t\t\tu: -540,\n\t\t\td: -480,\n\t\t\tc: [\"US\"]\n\t\t},\n\t\t\"America/Yellowknife\": {\n\t\t\tu: -420,\n\t\t\td: -360,\n\t\t\tc: [\"CA\"]\n\t\t},\n\t\t\"Antarctica/Casey\": {\n\t\t\tu: 660,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Antarctica/Davis\": {\n\t\t\tu: 420,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Antarctica/DumontDUrville\": {\n\t\t\ta: \"Pacific/Port_Moresby\",\n\t\t\tc: [\"AQ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Antarctica/Macquarie\": {\n\t\t\tu: 600,\n\t\t\td: 660,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Antarctica/Mawson\": {\n\t\t\tu: 300,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Antarctica/McMurdo\": {\n\t\t\ta: \"Pacific/Auckland\",\n\t\t\tc: [\"AQ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Antarctica/Palmer\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Antarctica/Rothera\": {\n\t\t\tu: -180,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Antarctica/South_Pole\": {\n\t\t\ta: \"Pacific/Auckland\",\n\t\t\tc: [\"AQ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Antarctica/Syowa\": {\n\t\t\ta: \"Asia/Riyadh\",\n\t\t\tc: [\"AQ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Antarctica/Troll\": {\n\t\t\tu: 0,\n\t\t\td: 120,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Antarctica/Vostok\": {\n\t\t\tu: 360,\n\t\t\tc: [\"AQ\"]\n\t\t},\n\t\t\"Arctic/Longyearbyen\": {\n\t\t\ta: \"Europe/Oslo\",\n\t\t\tc: [\"SJ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Aden\": {\n\t\t\ta: \"Asia/Riyadh\",\n\t\t\tc: [\"YE\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Almaty\": {\n\t\t\tu: 360,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Amman\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"JO\"]\n\t\t},\n\t\t\"Asia/Anadyr\": {\n\t\t\tu: 720,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Aqtau\": {\n\t\t\tu: 300,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Aqtobe\": {\n\t\t\tu: 300,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Ashgabat\": {\n\t\t\tu: 300,\n\t\t\tc: [\"TM\"]\n\t\t},\n\t\t\"Asia/Ashkhabad\": {\n\t\t\ta: \"Asia/Ashgabat\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Atyrau\": {\n\t\t\tu: 300,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Baghdad\": {\n\t\t\tu: 180,\n\t\t\tc: [\"IQ\"]\n\t\t},\n\t\t\"Asia/Bahrain\": {\n\t\t\ta: \"Asia/Qatar\",\n\t\t\tc: [\"BH\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Baku\": {\n\t\t\tu: 240,\n\t\t\tc: [\"AZ\"]\n\t\t},\n\t\t\"Asia/Bangkok\": {\n\t\t\tu: 420,\n\t\t\tc: [\"TH\", \"KH\", \"LA\", \"VN\"]\n\t\t},\n\t\t\"Asia/Barnaul\": {\n\t\t\tu: 420,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Beirut\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"LB\"]\n\t\t},\n\t\t\"Asia/Bishkek\": {\n\t\t\tu: 360,\n\t\t\tc: [\"KG\"]\n\t\t},\n\t\t\"Asia/Brunei\": {\n\t\t\tu: 480,\n\t\t\tc: [\"BN\"]\n\t\t},\n\t\t\"Asia/Calcutta\": {\n\t\t\ta: \"Asia/Kolkata\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Chita\": {\n\t\t\tu: 540,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Choibalsan\": {\n\t\t\tu: 480,\n\t\t\tc: [\"MN\"]\n\t\t},\n\t\t\"Asia/Chongqing\": {\n\t\t\ta: \"Asia/Shanghai\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Chungking\": {\n\t\t\ta: \"Asia/Shanghai\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Colombo\": {\n\t\t\tu: 330,\n\t\t\tc: [\"LK\"]\n\t\t},\n\t\t\"Asia/Dacca\": {\n\t\t\ta: \"Asia/Dhaka\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Damascus\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"SY\"]\n\t\t},\n\t\t\"Asia/Dhaka\": {\n\t\t\tu: 360,\n\t\t\tc: [\"BD\"]\n\t\t},\n\t\t\"Asia/Dili\": {\n\t\t\tu: 540,\n\t\t\tc: [\"TL\"]\n\t\t},\n\t\t\"Asia/Dubai\": {\n\t\t\tu: 240,\n\t\t\tc: [\"AE\", \"OM\"]\n\t\t},\n\t\t\"Asia/Dushanbe\": {\n\t\t\tu: 300,\n\t\t\tc: [\"TJ\"]\n\t\t},\n\t\t\"Asia/Famagusta\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"CY\"]\n\t\t},\n\t\t\"Asia/Gaza\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"PS\"]\n\t\t},\n\t\t\"Asia/Harbin\": {\n\t\t\ta: \"Asia/Shanghai\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Hebron\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"PS\"]\n\t\t},\n\t\t\"Asia/Ho_Chi_Minh\": {\n\t\t\tu: 420,\n\t\t\tc: [\"VN\"]\n\t\t},\n\t\t\"Asia/Hong_Kong\": {\n\t\t\tu: 480,\n\t\t\tc: [\"HK\"]\n\t\t},\n\t\t\"Asia/Hovd\": {\n\t\t\tu: 420,\n\t\t\tc: [\"MN\"]\n\t\t},\n\t\t\"Asia/Irkutsk\": {\n\t\t\tu: 480,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Istanbul\": {\n\t\t\ta: \"Europe/Istanbul\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Jakarta\": {\n\t\t\tu: 420,\n\t\t\tc: [\"ID\"]\n\t\t},\n\t\t\"Asia/Jayapura\": {\n\t\t\tu: 540,\n\t\t\tc: [\"ID\"]\n\t\t},\n\t\t\"Asia/Jerusalem\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"IL\"]\n\t\t},\n\t\t\"Asia/Kabul\": {\n\t\t\tu: 270,\n\t\t\tc: [\"AF\"]\n\t\t},\n\t\t\"Asia/Kamchatka\": {\n\t\t\tu: 720,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Karachi\": {\n\t\t\tu: 300,\n\t\t\tc: [\"PK\"]\n\t\t},\n\t\t\"Asia/Kashgar\": {\n\t\t\ta: \"Asia/Urumqi\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Kathmandu\": {\n\t\t\tu: 345,\n\t\t\tc: [\"NP\"]\n\t\t},\n\t\t\"Asia/Katmandu\": {\n\t\t\ta: \"Asia/Kathmandu\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Khandyga\": {\n\t\t\tu: 540,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Kolkata\": {\n\t\t\tu: 330,\n\t\t\tc: [\"IN\"]\n\t\t},\n\t\t\"Asia/Krasnoyarsk\": {\n\t\t\tu: 420,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Kuala_Lumpur\": {\n\t\t\tu: 480,\n\t\t\tc: [\"MY\"]\n\t\t},\n\t\t\"Asia/Kuching\": {\n\t\t\tu: 480,\n\t\t\tc: [\"MY\"]\n\t\t},\n\t\t\"Asia/Kuwait\": {\n\t\t\ta: \"Asia/Riyadh\",\n\t\t\tc: [\"KW\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Macao\": {\n\t\t\ta: \"Asia/Macau\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Macau\": {\n\t\t\tu: 480,\n\t\t\tc: [\"MO\"]\n\t\t},\n\t\t\"Asia/Magadan\": {\n\t\t\tu: 660,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Makassar\": {\n\t\t\tu: 480,\n\t\t\tc: [\"ID\"]\n\t\t},\n\t\t\"Asia/Manila\": {\n\t\t\tu: 480,\n\t\t\tc: [\"PH\"]\n\t\t},\n\t\t\"Asia/Muscat\": {\n\t\t\ta: \"Asia/Dubai\",\n\t\t\tc: [\"OM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Nicosia\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"CY\"]\n\t\t},\n\t\t\"Asia/Novokuznetsk\": {\n\t\t\tu: 420,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Novosibirsk\": {\n\t\t\tu: 420,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Omsk\": {\n\t\t\tu: 360,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Oral\": {\n\t\t\tu: 300,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Phnom_Penh\": {\n\t\t\ta: \"Asia/Bangkok\",\n\t\t\tc: [\"KH\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Pontianak\": {\n\t\t\tu: 420,\n\t\t\tc: [\"ID\"]\n\t\t},\n\t\t\"Asia/Pyongyang\": {\n\t\t\tu: 540,\n\t\t\tc: [\"KP\"]\n\t\t},\n\t\t\"Asia/Qatar\": {\n\t\t\tu: 180,\n\t\t\tc: [\"QA\", \"BH\"]\n\t\t},\n\t\t\"Asia/Qostanay\": {\n\t\t\tu: 360,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Qyzylorda\": {\n\t\t\tu: 300,\n\t\t\tc: [\"KZ\"]\n\t\t},\n\t\t\"Asia/Rangoon\": {\n\t\t\ta: \"Asia/Yangon\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Riyadh\": {\n\t\t\tu: 180,\n\t\t\tc: [\"SA\", \"AQ\", \"KW\", \"YE\"]\n\t\t},\n\t\t\"Asia/Saigon\": {\n\t\t\ta: \"Asia/Ho_Chi_Minh\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Sakhalin\": {\n\t\t\tu: 660,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Samarkand\": {\n\t\t\tu: 300,\n\t\t\tc: [\"UZ\"]\n\t\t},\n\t\t\"Asia/Seoul\": {\n\t\t\tu: 540,\n\t\t\tc: [\"KR\"]\n\t\t},\n\t\t\"Asia/Shanghai\": {\n\t\t\tu: 480,\n\t\t\tc: [\"CN\"]\n\t\t},\n\t\t\"Asia/Singapore\": {\n\t\t\tu: 480,\n\t\t\tc: [\"SG\", \"MY\"]\n\t\t},\n\t\t\"Asia/Srednekolymsk\": {\n\t\t\tu: 660,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Taipei\": {\n\t\t\tu: 480,\n\t\t\tc: [\"TW\"]\n\t\t},\n\t\t\"Asia/Tashkent\": {\n\t\t\tu: 300,\n\t\t\tc: [\"UZ\"]\n\t\t},\n\t\t\"Asia/Tbilisi\": {\n\t\t\tu: 240,\n\t\t\tc: [\"GE\"]\n\t\t},\n\t\t\"Asia/Tehran\": {\n\t\t\tu: 210,\n\t\t\td: 270,\n\t\t\tc: [\"IR\"]\n\t\t},\n\t\t\"Asia/Tel_Aviv\": {\n\t\t\ta: \"Asia/Jerusalem\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Thimbu\": {\n\t\t\ta: \"Asia/Thimphu\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Thimphu\": {\n\t\t\tu: 360,\n\t\t\tc: [\"BT\"]\n\t\t},\n\t\t\"Asia/Tokyo\": {\n\t\t\tu: 540,\n\t\t\tc: [\"JP\"]\n\t\t},\n\t\t\"Asia/Tomsk\": {\n\t\t\tu: 420,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Ujung_Pandang\": {\n\t\t\ta: \"Asia/Makassar\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Ulaanbaatar\": {\n\t\t\tu: 480,\n\t\t\tc: [\"MN\"]\n\t\t},\n\t\t\"Asia/Ulan_Bator\": {\n\t\t\ta: \"Asia/Ulaanbaatar\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Urumqi\": {\n\t\t\tu: 360,\n\t\t\tc: [\"CN\"]\n\t\t},\n\t\t\"Asia/Ust-Nera\": {\n\t\t\tu: 600,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Vientiane\": {\n\t\t\ta: \"Asia/Bangkok\",\n\t\t\tc: [\"LA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Asia/Vladivostok\": {\n\t\t\tu: 600,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Yakutsk\": {\n\t\t\tu: 540,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Yangon\": {\n\t\t\tu: 390,\n\t\t\tc: [\"MM\"]\n\t\t},\n\t\t\"Asia/Yekaterinburg\": {\n\t\t\tu: 300,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Asia/Yerevan\": {\n\t\t\tu: 240,\n\t\t\tc: [\"AM\"]\n\t\t},\n\t\t\"Atlantic/Azores\": {\n\t\t\tu: -60,\n\t\t\td: 0,\n\t\t\tc: [\"PT\"]\n\t\t},\n\t\t\"Atlantic/Bermuda\": {\n\t\t\tu: -240,\n\t\t\td: -180,\n\t\t\tc: [\"BM\"]\n\t\t},\n\t\t\"Atlantic/Canary\": {\n\t\t\tu: 0,\n\t\t\td: 60,\n\t\t\tc: [\"ES\"]\n\t\t},\n\t\t\"Atlantic/Cape_Verde\": {\n\t\t\tu: -60,\n\t\t\tc: [\"CV\"]\n\t\t},\n\t\t\"Atlantic/Faeroe\": {\n\t\t\ta: \"Atlantic/Faroe\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Atlantic/Faroe\": {\n\t\t\tu: 0,\n\t\t\td: 60,\n\t\t\tc: [\"FO\"]\n\t\t},\n\t\t\"Atlantic/Jan_Mayen\": {\n\t\t\ta: \"Europe/Oslo\",\n\t\t\tc: [\"SJ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Atlantic/Madeira\": {\n\t\t\tu: 0,\n\t\t\td: 60,\n\t\t\tc: [\"PT\"]\n\t\t},\n\t\t\"Atlantic/Reykjavik\": {\n\t\t\tu: 0,\n\t\t\tc: [\"IS\"]\n\t\t},\n\t\t\"Atlantic/South_Georgia\": {\n\t\t\tu: -120,\n\t\t\tc: [\"GS\"]\n\t\t},\n\t\t\"Atlantic/St_Helena\": {\n\t\t\ta: \"Africa/Abidjan\",\n\t\t\tc: [\"SH\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Atlantic/Stanley\": {\n\t\t\tu: -180,\n\t\t\tc: [\"FK\"]\n\t\t},\n\t\t\"Australia/ACT\": {\n\t\t\ta: \"Australia/Sydney\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Adelaide\": {\n\t\t\tu: 570,\n\t\t\td: 630,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Brisbane\": {\n\t\t\tu: 600,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Broken_Hill\": {\n\t\t\tu: 570,\n\t\t\td: 630,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Canberra\": {\n\t\t\ta: \"Australia/Sydney\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Currie\": {\n\t\t\ta: \"Australia/Hobart\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Darwin\": {\n\t\t\tu: 570,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Eucla\": {\n\t\t\tu: 525,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Hobart\": {\n\t\t\tu: 600,\n\t\t\td: 660,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/LHI\": {\n\t\t\ta: \"Australia/Lord_Howe\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Lindeman\": {\n\t\t\tu: 600,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Lord_Howe\": {\n\t\t\tu: 630,\n\t\t\td: 660,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Melbourne\": {\n\t\t\tu: 600,\n\t\t\td: 660,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/NSW\": {\n\t\t\ta: \"Australia/Sydney\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/North\": {\n\t\t\ta: \"Australia/Darwin\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Perth\": {\n\t\t\tu: 480,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Queensland\": {\n\t\t\ta: \"Australia/Brisbane\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/South\": {\n\t\t\ta: \"Australia/Adelaide\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Sydney\": {\n\t\t\tu: 600,\n\t\t\td: 660,\n\t\t\tc: [\"AU\"]\n\t\t},\n\t\t\"Australia/Tasmania\": {\n\t\t\ta: \"Australia/Hobart\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Victoria\": {\n\t\t\ta: \"Australia/Melbourne\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/West\": {\n\t\t\ta: \"Australia/Perth\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Australia/Yancowinna\": {\n\t\t\ta: \"Australia/Broken_Hill\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Brazil/Acre\": {\n\t\t\ta: \"America/Rio_Branco\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Brazil/DeNoronha\": {\n\t\t\ta: \"America/Noronha\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Brazil/East\": {\n\t\t\ta: \"America/Sao_Paulo\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Brazil/West\": {\n\t\t\ta: \"America/Manaus\",\n\t\t\tr: 1\n\t\t},\n\t\tCET: {\n\t\t\tu: 60,\n\t\t\td: 120\n\t\t},\n\t\tCST6CDT: {\n\t\t\tu: -360,\n\t\t\td: -300\n\t\t},\n\t\t\"Canada/Atlantic\": {\n\t\t\ta: \"America/Halifax\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Central\": {\n\t\t\ta: \"America/Winnipeg\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Eastern\": {\n\t\t\ta: \"America/Toronto\",\n\t\t\tc: [\"CA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Mountain\": {\n\t\t\ta: \"America/Edmonton\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Newfoundland\": {\n\t\t\ta: \"America/St_Johns\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Pacific\": {\n\t\t\ta: \"America/Vancouver\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Saskatchewan\": {\n\t\t\ta: \"America/Regina\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Canada/Yukon\": {\n\t\t\ta: \"America/Whitehorse\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Chile/Continental\": {\n\t\t\ta: \"America/Santiago\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Chile/EasterIsland\": {\n\t\t\ta: \"Pacific/Easter\",\n\t\t\tr: 1\n\t\t},\n\t\tCuba: {\n\t\t\ta: \"America/Havana\",\n\t\t\tr: 1\n\t\t},\n\t\tEET: {\n\t\t\tu: 120,\n\t\t\td: 180\n\t\t},\n\t\tEST: {\n\t\t\tu: -300\n\t\t},\n\t\tEST5EDT: {\n\t\t\tu: -300,\n\t\t\td: -240\n\t\t},\n\t\tEgypt: {\n\t\t\ta: \"Africa/Cairo\",\n\t\t\tr: 1\n\t\t},\n\t\tEire: {\n\t\t\ta: \"Europe/Dublin\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/GMT\": {\n\t\t\tu: 0\n\t\t},\n\t\t\"Etc/GMT+0\": {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/GMT+1\": {\n\t\t\tu: -60\n\t\t},\n\t\t\"Etc/GMT+10\": {\n\t\t\tu: -600\n\t\t},\n\t\t\"Etc/GMT+11\": {\n\t\t\tu: -660\n\t\t},\n\t\t\"Etc/GMT+12\": {\n\t\t\tu: -720\n\t\t},\n\t\t\"Etc/GMT+2\": {\n\t\t\tu: -120\n\t\t},\n\t\t\"Etc/GMT+3\": {\n\t\t\tu: -180\n\t\t},\n\t\t\"Etc/GMT+4\": {\n\t\t\tu: -240\n\t\t},\n\t\t\"Etc/GMT+5\": {\n\t\t\tu: -300\n\t\t},\n\t\t\"Etc/GMT+6\": {\n\t\t\tu: -360\n\t\t},\n\t\t\"Etc/GMT+7\": {\n\t\t\tu: -420\n\t\t},\n\t\t\"Etc/GMT+8\": {\n\t\t\tu: -480\n\t\t},\n\t\t\"Etc/GMT+9\": {\n\t\t\tu: -540\n\t\t},\n\t\t\"Etc/GMT-0\": {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/GMT-1\": {\n\t\t\tu: 60\n\t\t},\n\t\t\"Etc/GMT-10\": {\n\t\t\tu: 600\n\t\t},\n\t\t\"Etc/GMT-11\": {\n\t\t\tu: 660\n\t\t},\n\t\t\"Etc/GMT-12\": {\n\t\t\tu: 720\n\t\t},\n\t\t\"Etc/GMT-13\": {\n\t\t\tu: 780\n\t\t},\n\t\t\"Etc/GMT-14\": {\n\t\t\tu: 840\n\t\t},\n\t\t\"Etc/GMT-2\": {\n\t\t\tu: 120\n\t\t},\n\t\t\"Etc/GMT-3\": {\n\t\t\tu: 180\n\t\t},\n\t\t\"Etc/GMT-4\": {\n\t\t\tu: 240\n\t\t},\n\t\t\"Etc/GMT-5\": {\n\t\t\tu: 300\n\t\t},\n\t\t\"Etc/GMT-6\": {\n\t\t\tu: 360\n\t\t},\n\t\t\"Etc/GMT-7\": {\n\t\t\tu: 420\n\t\t},\n\t\t\"Etc/GMT-8\": {\n\t\t\tu: 480\n\t\t},\n\t\t\"Etc/GMT-9\": {\n\t\t\tu: 540\n\t\t},\n\t\t\"Etc/GMT0\": {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/Greenwich\": {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/UCT\": {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/UTC\": {\n\t\t\tu: 0\n\t\t},\n\t\t\"Etc/Universal\": {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Etc/Zulu\": {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Amsterdam\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"NL\"]\n\t\t},\n\t\t\"Europe/Andorra\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"AD\"]\n\t\t},\n\t\t\"Europe/Astrakhan\": {\n\t\t\tu: 240,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Athens\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"GR\"]\n\t\t},\n\t\t\"Europe/Belfast\": {\n\t\t\ta: \"Europe/London\",\n\t\t\tc: [\"GB\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Belgrade\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"RS\", \"BA\", \"HR\", \"ME\", \"MK\", \"SI\"]\n\t\t},\n\t\t\"Europe/Berlin\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"DE\"]\n\t\t},\n\t\t\"Europe/Bratislava\": {\n\t\t\ta: \"Europe/Prague\",\n\t\t\tc: [\"SK\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Brussels\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"BE\"]\n\t\t},\n\t\t\"Europe/Bucharest\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"RO\"]\n\t\t},\n\t\t\"Europe/Budapest\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"HU\"]\n\t\t},\n\t\t\"Europe/Busingen\": {\n\t\t\ta: \"Europe/Zurich\",\n\t\t\tc: [\"DE\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Chisinau\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"MD\"]\n\t\t},\n\t\t\"Europe/Copenhagen\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"DK\"]\n\t\t},\n\t\t\"Europe/Dublin\": {\n\t\t\tu: 60,\n\t\t\td: 0,\n\t\t\tc: [\"IE\"]\n\t\t},\n\t\t\"Europe/Gibraltar\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"GI\"]\n\t\t},\n\t\t\"Europe/Guernsey\": {\n\t\t\ta: \"Europe/London\",\n\t\t\tc: [\"GG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Helsinki\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"FI\", \"AX\"]\n\t\t},\n\t\t\"Europe/Isle_of_Man\": {\n\t\t\ta: \"Europe/London\",\n\t\t\tc: [\"IM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Istanbul\": {\n\t\t\tu: 180,\n\t\t\tc: [\"TR\"]\n\t\t},\n\t\t\"Europe/Jersey\": {\n\t\t\ta: \"Europe/London\",\n\t\t\tc: [\"JE\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Kaliningrad\": {\n\t\t\tu: 120,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Kiev\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"UA\"]\n\t\t},\n\t\t\"Europe/Kirov\": {\n\t\t\tu: 180,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Lisbon\": {\n\t\t\tu: 0,\n\t\t\td: 60,\n\t\t\tc: [\"PT\"]\n\t\t},\n\t\t\"Europe/Ljubljana\": {\n\t\t\ta: \"Europe/Belgrade\",\n\t\t\tc: [\"SI\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/London\": {\n\t\t\tu: 0,\n\t\t\td: 60,\n\t\t\tc: [\"GB\", \"GG\", \"IM\", \"JE\"]\n\t\t},\n\t\t\"Europe/Luxembourg\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"LU\"]\n\t\t},\n\t\t\"Europe/Madrid\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"ES\"]\n\t\t},\n\t\t\"Europe/Malta\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"MT\"]\n\t\t},\n\t\t\"Europe/Mariehamn\": {\n\t\t\ta: \"Europe/Helsinki\",\n\t\t\tc: [\"AX\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Minsk\": {\n\t\t\tu: 180,\n\t\t\tc: [\"BY\"]\n\t\t},\n\t\t\"Europe/Monaco\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"MC\"]\n\t\t},\n\t\t\"Europe/Moscow\": {\n\t\t\tu: 180,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Nicosia\": {\n\t\t\ta: \"Asia/Nicosia\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Oslo\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"NO\", \"SJ\", \"BV\"]\n\t\t},\n\t\t\"Europe/Paris\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"FR\"]\n\t\t},\n\t\t\"Europe/Podgorica\": {\n\t\t\ta: \"Europe/Belgrade\",\n\t\t\tc: [\"ME\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Prague\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"CZ\", \"SK\"]\n\t\t},\n\t\t\"Europe/Riga\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"LV\"]\n\t\t},\n\t\t\"Europe/Rome\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"IT\", \"SM\", \"VA\"]\n\t\t},\n\t\t\"Europe/Samara\": {\n\t\t\tu: 240,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/San_Marino\": {\n\t\t\ta: \"Europe/Rome\",\n\t\t\tc: [\"SM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Sarajevo\": {\n\t\t\ta: \"Europe/Belgrade\",\n\t\t\tc: [\"BA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Saratov\": {\n\t\t\tu: 240,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Simferopol\": {\n\t\t\tu: 180,\n\t\t\tc: [\"RU\", \"UA\"]\n\t\t},\n\t\t\"Europe/Skopje\": {\n\t\t\ta: \"Europe/Belgrade\",\n\t\t\tc: [\"MK\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Sofia\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"BG\"]\n\t\t},\n\t\t\"Europe/Stockholm\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"SE\"]\n\t\t},\n\t\t\"Europe/Tallinn\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"EE\"]\n\t\t},\n\t\t\"Europe/Tirane\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"AL\"]\n\t\t},\n\t\t\"Europe/Tiraspol\": {\n\t\t\ta: \"Europe/Chisinau\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Ulyanovsk\": {\n\t\t\tu: 240,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Uzhgorod\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"UA\"]\n\t\t},\n\t\t\"Europe/Vaduz\": {\n\t\t\ta: \"Europe/Zurich\",\n\t\t\tc: [\"LI\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Vatican\": {\n\t\t\ta: \"Europe/Rome\",\n\t\t\tc: [\"VA\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Vienna\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"AT\"]\n\t\t},\n\t\t\"Europe/Vilnius\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"LT\"]\n\t\t},\n\t\t\"Europe/Volgograd\": {\n\t\t\tu: 180,\n\t\t\tc: [\"RU\"]\n\t\t},\n\t\t\"Europe/Warsaw\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"PL\"]\n\t\t},\n\t\t\"Europe/Zagreb\": {\n\t\t\ta: \"Europe/Belgrade\",\n\t\t\tc: [\"HR\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Europe/Zaporozhye\": {\n\t\t\tu: 120,\n\t\t\td: 180,\n\t\t\tc: [\"UA\"]\n\t\t},\n\t\t\"Europe/Zurich\": {\n\t\t\tu: 60,\n\t\t\td: 120,\n\t\t\tc: [\"CH\", \"DE\", \"LI\"]\n\t\t},\n\t\tFactory: {\n\t\t\tu: 0\n\t\t},\n\t\tGB: {\n\t\t\ta: \"Europe/London\",\n\t\t\tc: [\"GB\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"GB-Eire\": {\n\t\t\ta: \"Europe/London\",\n\t\t\tc: [\"GB\"],\n\t\t\tr: 1\n\t\t},\n\t\tGMT: {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\t\"GMT+0\": {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\t\"GMT-0\": {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\tGMT0: {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\tGreenwich: {\n\t\t\ta: \"Etc/GMT\",\n\t\t\tr: 1\n\t\t},\n\t\tHST: {\n\t\t\tu: -600\n\t\t},\n\t\tHongkong: {\n\t\t\ta: \"Asia/Hong_Kong\",\n\t\t\tr: 1\n\t\t},\n\t\tIceland: {\n\t\t\ta: \"Atlantic/Reykjavik\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Indian/Antananarivo\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"MG\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Indian/Chagos\": {\n\t\t\tu: 360,\n\t\t\tc: [\"IO\"]\n\t\t},\n\t\t\"Indian/Christmas\": {\n\t\t\tu: 420,\n\t\t\tc: [\"CX\"]\n\t\t},\n\t\t\"Indian/Cocos\": {\n\t\t\tu: 390,\n\t\t\tc: [\"CC\"]\n\t\t},\n\t\t\"Indian/Comoro\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"KM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Indian/Kerguelen\": {\n\t\t\tu: 300,\n\t\t\tc: [\"TF\", \"HM\"]\n\t\t},\n\t\t\"Indian/Mahe\": {\n\t\t\tu: 240,\n\t\t\tc: [\"SC\"]\n\t\t},\n\t\t\"Indian/Maldives\": {\n\t\t\tu: 300,\n\t\t\tc: [\"MV\"]\n\t\t},\n\t\t\"Indian/Mauritius\": {\n\t\t\tu: 240,\n\t\t\tc: [\"MU\"]\n\t\t},\n\t\t\"Indian/Mayotte\": {\n\t\t\ta: \"Africa/Nairobi\",\n\t\t\tc: [\"YT\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Indian/Reunion\": {\n\t\t\tu: 240,\n\t\t\tc: [\"RE\", \"TF\"]\n\t\t},\n\t\tIran: {\n\t\t\ta: \"Asia/Tehran\",\n\t\t\tr: 1\n\t\t},\n\t\tIsrael: {\n\t\t\ta: \"Asia/Jerusalem\",\n\t\t\tr: 1\n\t\t},\n\t\tJamaica: {\n\t\t\ta: \"America/Jamaica\",\n\t\t\tr: 1\n\t\t},\n\t\tJapan: {\n\t\t\ta: \"Asia/Tokyo\",\n\t\t\tr: 1\n\t\t},\n\t\tKwajalein: {\n\t\t\ta: \"Pacific/Kwajalein\",\n\t\t\tr: 1\n\t\t},\n\t\tLibya: {\n\t\t\ta: \"Africa/Tripoli\",\n\t\t\tr: 1\n\t\t},\n\t\tMET: {\n\t\t\tu: 60,\n\t\t\td: 120\n\t\t},\n\t\tMST: {\n\t\t\tu: -420\n\t\t},\n\t\tMST7MDT: {\n\t\t\tu: -420,\n\t\t\td: -360\n\t\t},\n\t\t\"Mexico/BajaNorte\": {\n\t\t\ta: \"America/Tijuana\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Mexico/BajaSur\": {\n\t\t\ta: \"America/Mazatlan\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Mexico/General\": {\n\t\t\ta: \"America/Mexico_City\",\n\t\t\tr: 1\n\t\t},\n\t\tNZ: {\n\t\t\ta: \"Pacific/Auckland\",\n\t\t\tc: [\"NZ\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"NZ-CHAT\": {\n\t\t\ta: \"Pacific/Chatham\",\n\t\t\tr: 1\n\t\t},\n\t\tNavajo: {\n\t\t\ta: \"America/Denver\",\n\t\t\tr: 1\n\t\t},\n\t\tPRC: {\n\t\t\ta: \"Asia/Shanghai\",\n\t\t\tr: 1\n\t\t},\n\t\tPST8PDT: {\n\t\t\tu: -480,\n\t\t\td: -420\n\t\t},\n\t\t\"Pacific/Apia\": {\n\t\t\tu: 780,\n\t\t\tc: [\"WS\"]\n\t\t},\n\t\t\"Pacific/Auckland\": {\n\t\t\tu: 720,\n\t\t\td: 780,\n\t\t\tc: [\"NZ\", \"AQ\"]\n\t\t},\n\t\t\"Pacific/Bougainville\": {\n\t\t\tu: 660,\n\t\t\tc: [\"PG\"]\n\t\t},\n\t\t\"Pacific/Chatham\": {\n\t\t\tu: 765,\n\t\t\td: 825,\n\t\t\tc: [\"NZ\"]\n\t\t},\n\t\t\"Pacific/Chuuk\": {\n\t\t\tu: 600,\n\t\t\tc: [\"FM\"]\n\t\t},\n\t\t\"Pacific/Easter\": {\n\t\t\tu: -360,\n\t\t\td: -300,\n\t\t\tc: [\"CL\"]\n\t\t},\n\t\t\"Pacific/Efate\": {\n\t\t\tu: 660,\n\t\t\tc: [\"VU\"]\n\t\t},\n\t\t\"Pacific/Enderbury\": {\n\t\t\ta: \"Pacific/Kanton\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Fakaofo\": {\n\t\t\tu: 780,\n\t\t\tc: [\"TK\"]\n\t\t},\n\t\t\"Pacific/Fiji\": {\n\t\t\tu: 720,\n\t\t\td: 780,\n\t\t\tc: [\"FJ\"]\n\t\t},\n\t\t\"Pacific/Funafuti\": {\n\t\t\tu: 720,\n\t\t\tc: [\"TV\"]\n\t\t},\n\t\t\"Pacific/Galapagos\": {\n\t\t\tu: -360,\n\t\t\tc: [\"EC\"]\n\t\t},\n\t\t\"Pacific/Gambier\": {\n\t\t\tu: -540,\n\t\t\tc: [\"PF\"]\n\t\t},\n\t\t\"Pacific/Guadalcanal\": {\n\t\t\tu: 660,\n\t\t\tc: [\"SB\"]\n\t\t},\n\t\t\"Pacific/Guam\": {\n\t\t\tu: 600,\n\t\t\tc: [\"GU\", \"MP\"]\n\t\t},\n\t\t\"Pacific/Honolulu\": {\n\t\t\tu: -600,\n\t\t\tc: [\"US\", \"UM\"]\n\t\t},\n\t\t\"Pacific/Johnston\": {\n\t\t\ta: \"Pacific/Honolulu\",\n\t\t\tc: [\"UM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Kanton\": {\n\t\t\tu: 780,\n\t\t\tc: [\"KI\"]\n\t\t},\n\t\t\"Pacific/Kiritimati\": {\n\t\t\tu: 840,\n\t\t\tc: [\"KI\"]\n\t\t},\n\t\t\"Pacific/Kosrae\": {\n\t\t\tu: 660,\n\t\t\tc: [\"FM\"]\n\t\t},\n\t\t\"Pacific/Kwajalein\": {\n\t\t\tu: 720,\n\t\t\tc: [\"MH\"]\n\t\t},\n\t\t\"Pacific/Majuro\": {\n\t\t\tu: 720,\n\t\t\tc: [\"MH\"]\n\t\t},\n\t\t\"Pacific/Marquesas\": {\n\t\t\tu: -510,\n\t\t\tc: [\"PF\"]\n\t\t},\n\t\t\"Pacific/Midway\": {\n\t\t\ta: \"Pacific/Pago_Pago\",\n\t\t\tc: [\"UM\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Nauru\": {\n\t\t\tu: 720,\n\t\t\tc: [\"NR\"]\n\t\t},\n\t\t\"Pacific/Niue\": {\n\t\t\tu: -660,\n\t\t\tc: [\"NU\"]\n\t\t},\n\t\t\"Pacific/Norfolk\": {\n\t\t\tu: 660,\n\t\t\td: 720,\n\t\t\tc: [\"NF\"]\n\t\t},\n\t\t\"Pacific/Noumea\": {\n\t\t\tu: 660,\n\t\t\tc: [\"NC\"]\n\t\t},\n\t\t\"Pacific/Pago_Pago\": {\n\t\t\tu: -660,\n\t\t\tc: [\"AS\", \"UM\"]\n\t\t},\n\t\t\"Pacific/Palau\": {\n\t\t\tu: 540,\n\t\t\tc: [\"PW\"]\n\t\t},\n\t\t\"Pacific/Pitcairn\": {\n\t\t\tu: -480,\n\t\t\tc: [\"PN\"]\n\t\t},\n\t\t\"Pacific/Pohnpei\": {\n\t\t\tu: 660,\n\t\t\tc: [\"FM\"]\n\t\t},\n\t\t\"Pacific/Ponape\": {\n\t\t\ta: \"Pacific/Pohnpei\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Port_Moresby\": {\n\t\t\tu: 600,\n\t\t\tc: [\"PG\", \"AQ\"]\n\t\t},\n\t\t\"Pacific/Rarotonga\": {\n\t\t\tu: -600,\n\t\t\tc: [\"CK\"]\n\t\t},\n\t\t\"Pacific/Saipan\": {\n\t\t\ta: \"Pacific/Guam\",\n\t\t\tc: [\"MP\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Samoa\": {\n\t\t\ta: \"Pacific/Pago_Pago\",\n\t\t\tc: [\"WS\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Tahiti\": {\n\t\t\tu: -600,\n\t\t\tc: [\"PF\"]\n\t\t},\n\t\t\"Pacific/Tarawa\": {\n\t\t\tu: 720,\n\t\t\tc: [\"KI\"]\n\t\t},\n\t\t\"Pacific/Tongatapu\": {\n\t\t\tu: 780,\n\t\t\tc: [\"TO\"]\n\t\t},\n\t\t\"Pacific/Truk\": {\n\t\t\ta: \"Pacific/Chuuk\",\n\t\t\tr: 1\n\t\t},\n\t\t\"Pacific/Wake\": {\n\t\t\tu: 720,\n\t\t\tc: [\"UM\"]\n\t\t},\n\t\t\"Pacific/Wallis\": {\n\t\t\tu: 720,\n\t\t\tc: [\"WF\"]\n\t\t},\n\t\t\"Pacific/Yap\": {\n\t\t\ta: \"Pacific/Chuuk\",\n\t\t\tr: 1\n\t\t},\n\t\tPoland: {\n\t\t\ta: \"Europe/Warsaw\",\n\t\t\tr: 1\n\t\t},\n\t\tPortugal: {\n\t\t\ta: \"Europe/Lisbon\",\n\t\t\tr: 1\n\t\t},\n\t\tROC: {\n\t\t\ta: \"Asia/Taipei\",\n\t\t\tr: 1\n\t\t},\n\t\tROK: {\n\t\t\ta: \"Asia/Seoul\",\n\t\t\tr: 1\n\t\t},\n\t\tSingapore: {\n\t\t\ta: \"Asia/Singapore\",\n\t\t\tc: [\"SG\"],\n\t\t\tr: 1\n\t\t},\n\t\tTurkey: {\n\t\t\ta: \"Europe/Istanbul\",\n\t\t\tr: 1\n\t\t},\n\t\tUCT: {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Alaska\": {\n\t\t\ta: \"America/Anchorage\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Aleutian\": {\n\t\t\ta: \"America/Adak\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Arizona\": {\n\t\t\ta: \"America/Phoenix\",\n\t\t\tc: [\"US\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Central\": {\n\t\t\ta: \"America/Chicago\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/East-Indiana\": {\n\t\t\ta: \"America/Indiana/Indianapolis\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Eastern\": {\n\t\t\ta: \"America/New_York\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Hawaii\": {\n\t\t\ta: \"Pacific/Honolulu\",\n\t\t\tc: [\"US\"],\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Indiana-Starke\": {\n\t\t\ta: \"America/Indiana/Knox\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Michigan\": {\n\t\t\ta: \"America/Detroit\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Mountain\": {\n\t\t\ta: \"America/Denver\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Pacific\": {\n\t\t\ta: \"America/Los_Angeles\",\n\t\t\tr: 1\n\t\t},\n\t\t\"US/Samoa\": {\n\t\t\ta: \"Pacific/Pago_Pago\",\n\t\t\tc: [\"WS\"],\n\t\t\tr: 1\n\t\t},\n\t\tUTC: {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t},\n\t\tUniversal: {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t},\n\t\t\"W-SU\": {\n\t\t\ta: \"Europe/Moscow\",\n\t\t\tr: 1\n\t\t},\n\t\tWET: {\n\t\t\tu: 0,\n\t\t\td: 60\n\t\t},\n\t\tZulu: {\n\t\t\ta: \"Etc/UTC\",\n\t\t\tr: 1\n\t\t}\n};\n\n/**\n * Get full country name from user's timezone\n * @returns Full country name or null if timezone is unavailable\n */\nexport function getCountry(): string | null {\n\tconst timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n\tif (timezone === \"\" || !timezone) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst _country = timezones[timezone]?.c?.[0];\n\t\tif (!_country) return null;\n\t\tconst country = (countries as Record<string, string>)[_country];\n\t\treturn country || null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Get country code (ISO 3166-1 alpha-2) from user's timezone\n * Privacy-friendly alternative to IP geolocation\n * @returns ISO 3166-1 alpha-2 country code (e.g., \"US\", \"GB\") or \"Unknown\"\n */\nexport function getCountryCodeFromTimezone(): string {\n\tconst timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n\tif (timezone === \"\" || !timezone) {\n\t\treturn \"Unknown\";\n\t}\n\n\ttry {\n\t\tconst countryCode = timezones[timezone]?.c?.[0];\n\t\treturn countryCode || \"Unknown\";\n\t} catch {\n\t\treturn \"Unknown\";\n\t}\n}\n\nexport function getState(): string | null {\n\tconst timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n\n\tif (timezone === \"\" || !timezone) {\n\t\treturn null;\n\t}\n\t\n\tconst state = timezone.split(\"/\")[1]?.replace(\"_\", \" \");\n\t\n\treturn state || null;\n}\n", "/**\n * Page Tracking for Grain Analytics\n * Automatically tracks page views with consent-aware behavior\n */\n\nimport {\n categorizeReferrer,\n parseUTMParameters,\n getOrCreateFirstTouchAttribution,\n getSessionUTMParameters,\n setSessionUTMParameters,\n type UTMParameters,\n type FirstTouchAttribution,\n} from './attribution';\nimport { getCountryCodeFromTimezone } from './countries';\n\nexport interface PageTrackingConfig {\n stripQueryParams: boolean; // Default: true for privacy\n stripHash?: boolean; // Default: false\n debug?: boolean;\n tenantId: string;\n}\n\nexport interface PageTracker {\n trackSystemEvent(eventName: string, properties: Record<string, unknown>): void;\n hasConsent(category?: string): boolean;\n getEffectiveUserId(): string;\n getEphemeralSessionId(): string;\n getSessionId(): string;\n}\n\nexport class PageTrackingManager {\n private config: PageTrackingConfig;\n private tracker: PageTracker;\n private isDestroyed = false;\n private currentPath: string | null = null;\n private originalPushState: typeof history.pushState | null = null;\n private originalReplaceState: typeof history.replaceState | null = null;\n private previousPage: string | null = null;\n private landingPage: string | null = null;\n private pageViewCount = 0;\n\n constructor(tracker: PageTracker, config: PageTrackingConfig) {\n this.tracker = tracker;\n this.config = config;\n \n // Track initial page load (this is the landing page)\n this.trackCurrentPage(true);\n \n // Setup listeners\n this.setupHistoryListeners();\n this.setupHashChangeListener();\n }\n\n /**\n * Setup History API listeners (pushState, replaceState, popstate)\n */\n private setupHistoryListeners(): void {\n if (typeof window === 'undefined' || typeof history === 'undefined') return;\n\n // Wrap pushState\n this.originalPushState = history.pushState;\n history.pushState = (state: any, title: string, url?: string | URL | null) => {\n this.originalPushState?.call(history, state, title, url);\n this.trackCurrentPage();\n };\n\n // Wrap replaceState\n this.originalReplaceState = history.replaceState;\n history.replaceState = (state: any, title: string, url?: string | URL | null) => {\n this.originalReplaceState?.call(history, state, title, url);\n this.trackCurrentPage();\n };\n\n // Listen to popstate (back/forward buttons)\n window.addEventListener('popstate', this.handlePopState);\n }\n\n /**\n * Setup hash change listener\n */\n private setupHashChangeListener(): void {\n if (typeof window === 'undefined') return;\n window.addEventListener('hashchange', this.handleHashChange);\n }\n\n /**\n * Handle popstate event (back/forward navigation)\n */\n private handlePopState = (): void => {\n if (this.isDestroyed) return;\n this.trackCurrentPage();\n };\n\n /**\n * Handle hash change event\n */\n private handleHashChange = (): void => {\n if (this.isDestroyed) return;\n this.trackCurrentPage();\n };\n\n /**\n * Track the current page\n */\n private trackCurrentPage(isLanding: boolean = false): void {\n if (this.isDestroyed || typeof window === 'undefined') return;\n\n const page = this.extractPath(window.location.href);\n \n // Don't track if it's the same page (unless it's the landing page)\n if (!isLanding && page === this.currentPath) {\n return;\n }\n\n // Store previous page before updating\n if (this.currentPath) {\n this.previousPage = this.currentPath;\n }\n\n this.currentPath = page;\n this.pageViewCount++;\n\n // Set landing page on first view\n if (isLanding) {\n this.landingPage = page;\n }\n\n const hasConsent = this.tracker.hasConsent('analytics');\n const currentUrl = window.location.href;\n const referrer = document.referrer || '';\n\n // Parse UTM parameters from current URL\n const utmParams = parseUTMParameters(currentUrl);\n \n // Store session UTM if they exist (first time only or if new UTMs appear)\n if (Object.keys(utmParams).length > 0) {\n const existing = getSessionUTMParameters();\n if (!existing || isLanding) {\n setSessionUTMParameters(utmParams);\n }\n }\n\n // Get or create first-touch attribution\n const sessionUTMs = getSessionUTMParameters() || {};\n const firstTouch = getOrCreateFirstTouchAttribution(\n this.config.tenantId,\n referrer,\n currentUrl,\n sessionUTMs\n );\n\n // Base properties (always included)\n const properties: Record<string, unknown> = {\n page,\n timestamp: Date.now(),\n };\n\n // Enhanced properties when consent is granted\n if (hasConsent) {\n properties.title = document.title || '';\n properties.full_url = this.cleanUrl(currentUrl); // Clean URL based on privacy settings\n properties.session_id = this.tracker.getSessionId();\n\n // Add referrer info\n if (referrer) {\n properties.referrer = referrer;\n properties.referrer_domain = this.extractDomain(referrer);\n properties.referrer_category = categorizeReferrer(referrer, currentUrl);\n }\n\n // Add landing page if this is not the first view\n if (this.landingPage && !isLanding) {\n properties.landing_page = this.landingPage;\n }\n\n // Add previous page if available\n if (this.previousPage) {\n properties.previous_page = this.previousPage;\n }\n\n // Add UTM parameters if present (from session)\n if (sessionUTMs.utm_source) properties.utm_source = sessionUTMs.utm_source;\n if (sessionUTMs.utm_medium) properties.utm_medium = sessionUTMs.utm_medium;\n if (sessionUTMs.utm_campaign) properties.utm_campaign = sessionUTMs.utm_campaign;\n if (sessionUTMs.utm_term) properties.utm_term = sessionUTMs.utm_term;\n if (sessionUTMs.utm_content) properties.utm_content = sessionUTMs.utm_content;\n\n // Add first-touch attribution\n properties.first_touch_source = firstTouch.source;\n properties.first_touch_medium = firstTouch.medium;\n properties.first_touch_campaign = firstTouch.campaign;\n properties.first_touch_referrer_category = firstTouch.referrer_category;\n\n // Browser and device info\n properties.device = this.getDeviceType();\n properties.browser = this.getBrowser();\n properties.os = this.getOS();\n properties.language = navigator.language || '';\n \n // Timezone and country (privacy-friendly: derived from timezone, no IP tracking)\n const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n properties.timezone = timezone;\n properties.country = getCountryCodeFromTimezone();\n \n properties.screen_resolution = `${screen.width}x${screen.height}`;\n properties.viewport = `${window.innerWidth}x${window.innerHeight}`;\n }\n\n // Track the page view event\n this.tracker.trackSystemEvent('page_view', properties);\n }\n\n /**\n * Extract domain from URL\n */\n private extractDomain(url: string): string {\n try {\n const urlObj = new URL(url);\n return urlObj.hostname;\n } catch {\n return '';\n }\n }\n\n /**\n * Detect browser name\n */\n private getBrowser(): string {\n const ua = navigator.userAgent;\n if (ua.includes('Firefox/')) return 'Firefox';\n if (ua.includes('Edg/')) return 'Edge';\n if (ua.includes('Chrome/')) return 'Chrome';\n if (ua.includes('Safari/') && !ua.includes('Chrome/')) return 'Safari';\n if (ua.includes('Opera/') || ua.includes('OPR/')) return 'Opera';\n return 'Unknown';\n }\n\n /**\n * Detect operating system\n */\n private getOS(): string {\n const ua = navigator.userAgent;\n if (ua.includes('Win')) return 'Windows';\n if (ua.includes('Mac')) return 'macOS';\n if (ua.includes('Linux')) return 'Linux';\n if (ua.includes('Android')) return 'Android';\n if (ua.includes('iOS') || ua.includes('iPhone') || ua.includes('iPad')) return 'iOS';\n return 'Unknown';\n }\n\n /**\n * Detect device type (Mobile, Tablet, Desktop)\n */\n private getDeviceType(): string {\n const ua = navigator.userAgent;\n const width = window.innerWidth;\n \n // Check for tablet-specific indicators\n if (ua.includes('iPad') || (ua.includes('Android') && !ua.includes('Mobile'))) {\n return 'Tablet';\n }\n \n // Check for mobile indicators\n if (ua.includes('Mobile') || ua.includes('iPhone') || ua.includes('Android')) {\n return 'Mobile';\n }\n \n // Fallback to screen width detection\n if (width < 768) {\n return 'Mobile';\n } else if (width >= 768 && width < 1024) {\n return 'Tablet';\n }\n \n return 'Desktop';\n }\n\n /**\n * Extract path from URL, optionally stripping query parameters\n * Privacy-first: strips query params by default\n */\n private extractPath(url: string): string {\n try {\n const urlObj = new URL(url);\n let path = urlObj.pathname;\n \n // Include query params only if not stripping\n if (!this.config.stripQueryParams && urlObj.search) {\n path += urlObj.search;\n }\n \n // Include hash only if not stripping\n if (!this.config.stripHash && urlObj.hash) {\n path += urlObj.hash;\n }\n \n return path;\n } catch (error) {\n // If URL parsing fails, return the raw string\n if (this.config.debug) {\n console.warn('[Page Tracking] Failed to parse URL:', url, error);\n }\n return url;\n }\n }\n\n /**\n * Clean URL for privacy (strip query params based on config)\n */\n private cleanUrl(url: string): string {\n if (!this.config.stripQueryParams) {\n return url;\n }\n \n try {\n const urlObj = new URL(url);\n return `${urlObj.origin}${urlObj.pathname}${this.config.stripHash ? '' : urlObj.hash}`;\n } catch (error) {\n return url;\n }\n }\n\n /**\n * Get the current page path\n */\n getCurrentPage(): string | null {\n return this.currentPath;\n }\n\n /**\n * Manually track a page view (for custom navigation)\n */\n trackPage(page: string, properties?: Record<string, unknown>): void {\n if (this.isDestroyed) return;\n\n const hasConsent = this.tracker.hasConsent('analytics');\n\n // Base properties\n const baseProperties: Record<string, unknown> = {\n page,\n timestamp: Date.now(),\n ...properties,\n };\n\n // Enhanced properties when consent is granted\n if (hasConsent && typeof document !== 'undefined' && typeof window !== 'undefined') {\n if (!baseProperties.referrer) {\n baseProperties.referrer = document.referrer || '';\n }\n if (!baseProperties.title) {\n baseProperties.title = document.title || '';\n }\n if (!baseProperties.full_url) {\n baseProperties.full_url = window.location.href;\n }\n if (!baseProperties.session_id) {\n baseProperties.session_id = this.tracker.getSessionId();\n }\n if (!baseProperties.browser) {\n baseProperties.browser = this.getBrowser();\n }\n if (!baseProperties.os) {\n baseProperties.os = this.getOS();\n }\n }\n\n this.tracker.trackSystemEvent('page_view', baseProperties);\n }\n\n /**\n * Get page view count for current session\n */\n getPageViewCount(): number {\n return this.pageViewCount;\n }\n\n /**\n * Destroy the page tracker\n */\n destroy(): void {\n if (this.isDestroyed) return;\n\n // Restore original history methods\n if (typeof history !== 'undefined') {\n if (this.originalPushState) {\n history.pushState = this.originalPushState;\n }\n if (this.originalReplaceState) {\n history.replaceState = this.originalReplaceState;\n }\n }\n\n // Remove event listeners\n if (typeof window !== 'undefined') {\n window.removeEventListener('popstate', this.handlePopState);\n window.removeEventListener('hashchange', this.handleHashChange);\n }\n\n this.isDestroyed = true;\n }\n}\n\n", "/**\n * ID Manager for Grain Analytics\n * Generates and manages user IDs based on consent mode\n * \n * Privacy-first implementation:\n * - Cookieless mode: Daily rotating IDs (no persistence)\n * - GDPR Strict: Permanent IDs only with consent\n * - GDPR Opt-out: Permanent IDs by default\n */\n\nexport type IdMode = 'cookieless' | 'permanent';\n\nexport interface IdConfig {\n mode: IdMode;\n tenantId: string;\n useLocalStorage?: boolean; // For permanent IDs only\n}\n\n/**\n * Generate a simple hash from a string\n */\nfunction simpleHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash; // Convert to 32-bit integer\n }\n return Math.abs(hash).toString(36);\n}\n\n/**\n * Generate a UUID v4\n */\nfunction generateUUID(): string {\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n \n // Fallback for older browsers\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = Math.random() * 16 | 0;\n const v = c === 'x' ? r : (r & 0x3 | 0x8);\n return v.toString(16);\n });\n}\n\n/**\n * Get minimal browser fingerprint for daily ID generation\n * NOT for tracking, just for same-day continuity\n */\nfunction getBrowserFingerprint(): string {\n if (typeof window === 'undefined') return 'server';\n \n const components: string[] = [\n screen.width?.toString() || '',\n screen.height?.toString() || '',\n navigator.language || '',\n Intl.DateTimeFormat().resolvedOptions().timeZone || ''\n ];\n \n return simpleHash(components.join('|'));\n}\n\n/**\n * Get current date string in local timezone (YYYY-MM-DD)\n */\nfunction getLocalDateString(): string {\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const day = String(now.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n}\n\n/**\n * ID Manager class\n * Handles both daily rotating IDs and permanent IDs\n */\nexport class IdManager {\n private config: IdConfig;\n private cachedDailyId: string | null = null;\n private dailyIdDate: string | null = null;\n private permanentId: string | null = null;\n \n constructor(config: IdConfig) {\n this.config = config;\n \n // Load permanent ID from localStorage if in permanent mode\n if (config.mode === 'permanent' && config.useLocalStorage) {\n this.loadPermanentId();\n }\n }\n \n /**\n * Generate a daily rotating ID\n * Rotates at midnight in user's local timezone\n * Provides same-day continuity without persistent tracking\n */\n generateDailyRotatingId(): string {\n const currentDate = getLocalDateString();\n \n // Return cached ID if still the same day\n if (this.cachedDailyId && this.dailyIdDate === currentDate) {\n return this.cachedDailyId;\n }\n \n // Generate new daily ID\n const fingerprint = getBrowserFingerprint();\n const seed = `${this.config.tenantId}|${currentDate}|${fingerprint}`;\n const dailyId = `daily_${simpleHash(seed)}_${simpleHash(Date.now().toString())}`;\n \n // Cache for same-day requests\n this.cachedDailyId = dailyId;\n this.dailyIdDate = currentDate;\n \n return dailyId;\n }\n \n /**\n * Generate or retrieve permanent user ID\n * Only used when consent is given\n */\n generatePermanentId(): string {\n if (this.permanentId) {\n return this.permanentId;\n }\n \n // Try to load from localStorage\n if (this.config.useLocalStorage) {\n const stored = this.loadPermanentId();\n if (stored) {\n return stored;\n }\n }\n \n // Generate new permanent ID\n const newId = generateUUID();\n this.permanentId = newId;\n \n // Store in localStorage if enabled\n if (this.config.useLocalStorage) {\n this.savePermanentId(newId);\n }\n \n return newId;\n }\n \n /**\n * Get the current user ID based on mode\n */\n getCurrentUserId(): string {\n if (this.config.mode === 'cookieless') {\n return this.generateDailyRotatingId();\n } else {\n return this.generatePermanentId();\n }\n }\n \n /**\n * Switch ID mode (e.g., when consent is granted/revoked)\n */\n setMode(mode: IdMode): void {\n this.config.mode = mode;\n \n // Clear cached daily ID when switching to permanent\n if (mode === 'permanent') {\n this.cachedDailyId = null;\n this.dailyIdDate = null;\n }\n \n // Clear permanent ID when switching to cookieless\n if (mode === 'cookieless') {\n this.permanentId = null;\n if (this.config.useLocalStorage) {\n this.clearPermanentId();\n }\n }\n }\n \n /**\n * Load permanent ID from localStorage\n */\n private loadPermanentId(): string | null {\n if (typeof window === 'undefined') return null;\n \n try {\n const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n this.permanentId = stored;\n return stored;\n }\n } catch (error) {\n // Silent failure - localStorage might be disabled\n }\n \n return null;\n }\n \n /**\n * Save permanent ID to localStorage\n */\n private savePermanentId(id: string): void {\n if (typeof window === 'undefined') return;\n \n try {\n const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;\n localStorage.setItem(storageKey, id);\n } catch (error) {\n // Silent failure - localStorage might be disabled\n }\n }\n \n /**\n * Clear permanent ID from localStorage\n */\n private clearPermanentId(): void {\n if (typeof window === 'undefined') return;\n \n try {\n const storageKey = `grain_anonymous_user_id_${this.config.tenantId}`;\n localStorage.removeItem(storageKey);\n } catch (error) {\n // Silent failure\n }\n }\n \n /**\n * Get info about current ID for debugging\n */\n getIdInfo(): { mode: IdMode; id: string; isDailyRotating: boolean } {\n const id = this.getCurrentUserId();\n return {\n mode: this.config.mode,\n id: id,\n isDailyRotating: id.startsWith('daily_')\n };\n }\n}\n"],
|
|
5
|
+
"mappings": "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IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,IAAI;AAAA,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",
|
|
6
6
|
"names": ["DEFAULT_OPTIONS", "DEFAULT_OPTIONS", "e", "url", "idMode", "HeatmapTrackingManager", "InteractionTrackingManager", "SectionTrackingManager", "DebugAgent"]
|
|
7
7
|
}
|