{"version":3,"sources":["../src/lib/keyBuilder.ts","../src/constants.ts","../src/lib/error.ts","../src/lib/invariant.ts","../src/lib/link.ts","../src/lib/logger.ts","../src/lib/parseUrl.ts","../src/lib/queue.ts","../src/lib/isBeaconSupported.ts","../src/lib/requester.ts","../src/lib/safelyRunOnBrowser.ts","../src/lib/viewport.ts","../src/lib/runtimeContext.ts","../src/lib/generateId.ts","../src/lib/sessionManager.ts","../src/lib/storage.ts","../src/lib/validateUserId.ts","../src/core.ts","../src/index.ts"],"sourcesContent":["export function createKeyBuilder(prefix: string, separator: string) {\n  return (...parts: string[]) => {\n    return [prefix, ...parts].join(separator);\n  };\n}\n","import { createKeyBuilder } from './lib/keyBuilder';\n\nconst STORAGE_KEY_PREFIX = 'atbl';\nexport const keyBuilder = createKeyBuilder(STORAGE_KEY_PREFIX, '.');\nexport const STORAGE_KEY_TEST = keyBuilder('check');\n\nexport const PREFIX_SESSION_ID = 'session';\nexport const PREFIX_ANONYMOUS_ID = 'anonymous';\nexport const PREFIX_DEVICE_ID = 'device';\n\nconst MINUTE_IN_MS = 1_000 * 60;\nexport const AUTO_CAPTURE_INTERVAL_MS = 100;\nexport const SESSION_EXPIRATION_TIME_MS = 30 * MINUTE_IN_MS;\nexport const MAX_QUEUE_SIZE = 1_000;\nexport const REQUEST_TIMEOUT_MS = 5_000;\n\nexport const EVENT_PAGEVIEW = '$pageview';\n\nexport const PROPERTY_LIB = '$lib';\nexport const PROPERTY_LIB_VERSION = '$lib_version';\nexport const PROPERTY_REFERER = '$referer';\nexport const PROPERTY_RELEASE = '$release';\nexport const PROPERTY_URL = '$url';\nexport const PROPERTY_VIEWPORT = '$viewport';\n\n/**\n * Available tracking consent states.\n *\n * Use these constants to manage user consent for tracking and analytics.\n *\n * @property GRANTED User has granted consent for tracking\n * @property DENIED User has denied consent for tracking\n * @property PENDING User hasn't made a decision yet\n * @property DISMISSED User dismissed the consent prompt\n *\n * @example\n * ```javascript\n * import { altertable, TrackingConsent } from '@altertable/altertable-js';\n *\n * // Set tracking consent to granted\n * altertable.configure({\n *   trackingConsent: TrackingConsent.GRANTED,\n * });\n *\n * // Check current consent state\n * const consent = altertable.getTrackingConsent();\n * if (consent === TrackingConsent.GRANTED) {\n *   // Tracking is allowed\n * }\n * ```\n */\nexport const TrackingConsent = {\n  DENIED: 'denied',\n  DISMISSED: 'dismissed',\n  GRANTED: 'granted',\n  PENDING: 'pending',\n} as const;\n\nexport type TrackingConsentType =\n  (typeof TrackingConsent)[keyof typeof TrackingConsent];\n\nexport const RESERVED_USER_IDS = [\n  'anonymous_id',\n  'anonymous',\n  'distinct_id',\n  'distinctid',\n  'false',\n  'guest',\n  'id',\n  'not_authenticated',\n  'true',\n  'undefined',\n  'user_id',\n  'user',\n  'visitor_id',\n  'visitor',\n];\nexport const RESERVED_USER_IDS_CASE_SENSITIVE = new Set([\n  '[object Object]',\n  '0',\n  'NaN',\n  'none',\n  'None',\n  'null',\n]);\n","import { StringWithAutocomplete } from '../types';\n\nexport type ApiErrorCode = StringWithAutocomplete<'environment-not-found'>;\n\nexport interface ApiErrorResponse {\n  error_code?: ApiErrorCode;\n  message?: string;\n  [key: string]: unknown;\n}\n\n/**\n * Base error class for Altertable SDK errors\n */\nexport class AltertableError extends Error {\n  constructor(message: string) {\n    super(message);\n    this.name = 'AltertableError';\n  }\n}\n\n/**\n * Error thrown when an API request fails\n */\nexport class ApiError extends AltertableError {\n  constructor(\n    public status: number,\n    public statusText: string,\n    public errorCode?: ApiErrorCode,\n    public details?: ApiErrorResponse,\n    public requestContext?: {\n      url: string;\n      method: string;\n      payload?: unknown;\n    }\n  ) {\n    super(`HTTP ${status}: ${statusText}${errorCode ? ` (${errorCode})` : ''}`);\n    this.name = 'ApiError';\n  }\n}\n\n/**\n * Error thrown when a network request fails (timeout, connection error, etc.)\n */\nexport class NetworkError extends AltertableError {\n  constructor(\n    message: string,\n    public cause?: unknown\n  ) {\n    super(message);\n    this.name = 'NetworkError';\n  }\n}\n\nexport function isAltertableError(error: unknown): error is AltertableError {\n  return error instanceof AltertableError;\n}\n\nexport function isApiError(error: unknown): error is ApiError {\n  return error instanceof ApiError;\n}\n\nexport function isNetworkError(error: unknown): error is NetworkError {\n  return error instanceof NetworkError;\n}\n","/**\n * Throws an error if the condition is not met.\n *\n * The error is exhaustive in development, and becomes generic in production.\n *\n * This is used to make development a better experience to provide guidance as\n * to where the error comes from.\n */\nexport function invariant(\n  condition: unknown,\n  message: string | (() => string)\n): asserts condition {\n  if (condition) {\n    return;\n  }\n\n  throw new InvariantError(\n    `[Altertable] ${typeof message === 'function' ? message() : message}`\n  );\n}\n\nclass InvariantError extends Error {\n  constructor(message: string) {\n    super(message);\n    Object.setPrototypeOf(this, InvariantError.prototype);\n  }\n}\n","export function dashboardUrl(path: string = '') {\n  return `https://altertable.ai/dashboard${path}`;\n}\n","/* eslint-disable no-console */\n\nimport {\n  PROPERTY_URL,\n  TrackingConsent,\n  TrackingConsentType,\n} from '../constants';\nimport { AliasPayload, IdentifyPayload, TrackPayload } from '../types';\n\nexport type Logger = ReturnType<typeof createLogger>;\n\nexport function createLogger(prefix: string) {\n  return {\n    log: (...args: unknown[]) => {\n      console.log(`[${prefix}]`, ...args);\n    },\n    logHeader: () => {\n      const header = `Altertable v${__LIB_VERSION__} %c• Debug mode enabled`;\n      const hasAlreadyPrinted = loggerCache.current[header];\n\n      if (!hasAlreadyPrinted) {\n        loggerCache.current[header] = true;\n        console.log(header, 'color: #64748b;');\n      }\n    },\n    logEvent: (\n      payload: TrackPayload,\n      { trackingConsent }: { trackingConsent: TrackingConsentType }\n    ) => {\n      const [eventBadgeLabel, eventBadgeStyle] = createEventBadgeElement(\n        payload.event === '$pageview' ? 'Page' : 'Track'\n      );\n      const [eventTitleLabel, eventTitleStyle] = createEventTitleElement(\n        payload.event === '$pageview'\n          ? String(payload.properties[PROPERTY_URL])\n          : payload.event\n      );\n      const [environmentBadgeLabel, environmentBadgeStyle] =\n        createEnvironmentBadgeElement(payload.environment);\n      const [timestampLabel, timestampStyle] = createTimestampElement(\n        payload.timestamp\n      );\n      const [consentBadgeLabel, consentBadgeStyle] =\n        getConsentBadgeElement(trackingConsent);\n\n      console.groupCollapsed(\n        `[${prefix}] %c${eventBadgeLabel}%c ${eventTitleLabel} %c[${environmentBadgeLabel}] %c${timestampLabel} %c${consentBadgeLabel}`,\n        eventBadgeStyle,\n        eventTitleStyle,\n        environmentBadgeStyle,\n        timestampStyle,\n        consentBadgeStyle\n      );\n\n      const [userLabel, userLabelStyle] = createEventLabelElement('User ID');\n      const [userValueLabel, userValueStyle] = createValueElement(\n        payload.distinct_id ?? 'Not set'\n      );\n      const [anonymousLabel, anonymousLabelStyle] =\n        createEventLabelElement('Anonymous ID');\n      const [anonymousValueLabel, anonymousValueStyle] = createValueElement(\n        payload.anonymous_id ?? 'Not set'\n      );\n      const [sessionLabel, sessionLabelStyle] =\n        createEventLabelElement('Session ID');\n      const [sessionValueLabel, sessionValueStyle] = createValueElement(\n        payload.session_id ?? 'Not set'\n      );\n\n      console.log(\n        `%c${userLabel} %c${userValueLabel}`,\n        userLabelStyle,\n        userValueStyle\n      );\n      console.log(\n        `%c${anonymousLabel} %c${anonymousValueLabel}`,\n        anonymousLabelStyle,\n        anonymousValueStyle\n      );\n      console.log(\n        `%c${sessionLabel} %c${sessionValueLabel}`,\n        sessionLabelStyle,\n        sessionValueStyle\n      );\n      console.table(payload.properties);\n      console.groupEnd();\n    },\n    logIdentify: (\n      payload: IdentifyPayload,\n      { trackingConsent }: { trackingConsent: TrackingConsentType }\n    ) => {\n      const [eventBadgeLabel, eventBadgeStyle] =\n        createEventBadgeElement('Identify');\n      const [environmentBadgeLabel, environmentBadgeStyle] =\n        createEnvironmentBadgeElement(payload.environment);\n      const [consentBadgeLabel, consentBadgeStyle] =\n        getConsentBadgeElement(trackingConsent);\n\n      console.groupCollapsed(\n        `[${prefix}] %c${eventBadgeLabel}%c ${payload.distinct_id} %c[${environmentBadgeLabel}] %c${consentBadgeLabel}`,\n        eventBadgeStyle,\n        'font-weight: 600;',\n        environmentBadgeStyle,\n        consentBadgeStyle\n      );\n\n      const [distinctIdLabel, distinctIdLabelStyle] =\n        createEventLabelElement('Distinct ID');\n      const [distinctIdValueLabel, distinctIdValueStyle] = createValueElement(\n        payload.distinct_id ?? 'Not set'\n      );\n      const [anonymousLabel, anonymousLabelStyle] =\n        createEventLabelElement('Anonymous ID');\n      const [anonymousalueLabel, anonymousValueStyle] = createValueElement(\n        payload.anonymous_id ?? 'Not set'\n      );\n\n      console.log(\n        `%c${distinctIdLabel} %c${distinctIdValueLabel}`,\n        distinctIdLabelStyle,\n        distinctIdValueStyle\n      );\n      console.log(\n        `%c${anonymousLabel} %c${anonymousalueLabel}`,\n        anonymousLabelStyle,\n        anonymousValueStyle\n      );\n      console.table(payload.traits);\n      console.groupEnd();\n    },\n    logAlias: (\n      payload: AliasPayload,\n      { trackingConsent }: { trackingConsent: TrackingConsentType }\n    ) => {\n      const [eventBadgeLabel, eventBadgeStyle] =\n        createEventBadgeElement('Alias');\n      const [environmentBadgeLabel, environmentBadgeStyle] =\n        createEnvironmentBadgeElement(payload.environment);\n      const [consentBadgeLabel, consentBadgeStyle] =\n        getConsentBadgeElement(trackingConsent);\n\n      console.groupCollapsed(\n        `[${prefix}] %c${eventBadgeLabel}%c ${payload.distinct_id} %c[${environmentBadgeLabel}] %c${consentBadgeLabel}`,\n        eventBadgeStyle,\n        'font-weight: 600;',\n        environmentBadgeStyle,\n        consentBadgeStyle\n      );\n\n      const [distinctIdLabel, distinctIdLabelStyle] =\n        createEventLabelElement('Distinct ID');\n      const [distinctIdValueLabel, distinctIdValueStyle] = createValueElement(\n        payload.distinct_id ?? 'Not set'\n      );\n\n      const [newUserIdLabel, newUserIdLabelStyle] =\n        createEventLabelElement('New User ID');\n      const [newUserIdValueLabel, newUserIdValueStyle] = createValueElement(\n        payload.new_user_id ?? 'Not set'\n      );\n\n      console.log(\n        `%c${distinctIdLabel} %c${distinctIdValueLabel}`,\n        distinctIdLabelStyle,\n        distinctIdValueStyle\n      );\n      console.log(\n        `%c${newUserIdLabel} %c${newUserIdValueLabel}`,\n        newUserIdLabelStyle,\n        newUserIdValueStyle\n      );\n      console.groupEnd();\n    },\n    warn: (...args: unknown[]) => {\n      console.warn(`[${prefix}]`, ...args);\n    },\n    warnDev: (message: string, ...args: unknown[]) => {\n      if (!__DEV__) {\n        return;\n      }\n\n      const sanitizedMessage = message.trim();\n      const hasAlreadyPrinted = loggerCache.current[sanitizedMessage];\n\n      if (!hasAlreadyPrinted) {\n        loggerCache.current[sanitizedMessage] = true;\n        const warning = `[${prefix}] ${sanitizedMessage}`;\n\n        console.warn(warning, ...args);\n\n        try {\n          // Welcome to debugging Altertable.\n          //\n          // This error was thrown as a convenience so that you can find the source\n          // of the warning that appears in the console by enabling \"Pause on exceptions\"\n          // in your debugger.\n          throw new Error(warning);\n        } catch (error) {\n          // Do nothing\n        }\n      }\n    },\n    error: (...args: unknown[]) => {\n      console.error(`[${prefix}]`, ...args);\n    },\n  };\n}\n\nexport const loggerCache: { current: Record<string, boolean> } = {\n  current: {},\n};\n\nfunction formatEventTime(timestamp: string) {\n  return new Date(timestamp).toLocaleTimeString('en-US', {\n    hour12: false,\n    hour: '2-digit',\n    minute: '2-digit',\n    second: '2-digit',\n  });\n}\n\nfunction getEventBadgeColor(event: string) {\n  switch (event) {\n    case 'Page':\n      return '#64748b';\n    case 'Identify':\n      return '#a855f7';\n    case 'Track':\n      return '#10b981';\n    default:\n      return '#1e293b';\n  }\n}\n\nfunction createEventBadgeElement(event: string): [string, string] {\n  return [\n    event,\n    `background: ${getEventBadgeColor(event)}; color: #ffffff; padding: 2px 8px; border-radius: 6px; font-weight: 400;`,\n  ];\n}\n\nfunction createEventTitleElement(event: string): [string, string] {\n  const label = event === '$pageview' ? 'Page Viewed' : event;\n  return [label, 'font-weight: 600;'];\n}\n\nfunction createEnvironmentBadgeElement(value: string): [string, string] {\n  return [value, `color: ${getEnvironmentColor(value)}; font-weight: 400;`];\n}\n\nfunction getEnvironmentColor(environment: string) {\n  const formattedEnv = environment.toLocaleLowerCase().startsWith('prod')\n    ? 'production'\n    : environment;\n\n  switch (formattedEnv) {\n    case 'production':\n      return '#ef4444';\n    default:\n      return '#3b82f6';\n  }\n}\n\nfunction createTimestampElement(value: string): [string, string] {\n  return [formatEventTime(value), 'color: #64748b; font-weight: 400;'];\n}\n\nfunction createEventLabelElement(value: string): [string, string] {\n  return [value, 'color: #64748b; font-size: 11px;'];\n}\n\nfunction createValueElement(value: string): [string, string] {\n  return [\n    value,\n    'background: #f8fafc; color: #1e293b; padding: 2px 8px; border: 1px solid #e2e8f0; border-radius: 6px; font-family: \"SF Mono\", \"Monaco\", monospace; font-size: 11px;',\n  ];\n}\n\nfunction getConsentBadgeElement(\n  trackingConsent: TrackingConsentType\n): [string, string] {\n  switch (trackingConsent) {\n    case TrackingConsent.GRANTED:\n      return ['', ''];\n    case TrackingConsent.DENIED:\n      return [\n        'DENIED',\n        'background: #ef4444; color: #ffffff; padding: 2px 6px; border-radius: 4px; font-size: 10px; font-weight: 600;',\n      ];\n    case TrackingConsent.PENDING:\n    case TrackingConsent.DISMISSED:\n      return [\n        'PENDING',\n        'background: #f59e0b; color: #ffffff; padding: 2px 6px; border-radius: 4px; font-size: 10px; font-weight: 600;',\n      ];\n    default:\n      return [\n        'UNKNOWN',\n        'background: #6b7280; color: #ffffff; padding: 2px 6px; border-radius: 4px; font-size: 10px; font-weight: 600;',\n      ];\n  }\n}\n","type ParsedUrl = {\n  baseUrl: string;\n  searchParams: Record<string, string>;\n};\n\nexport function parseUrl(url: string): ParsedUrl | null {\n  try {\n    const parsedUrl = new URL(url);\n    return {\n      baseUrl: `${parsedUrl.origin}${parsedUrl.pathname}`,\n      searchParams: Object.fromEntries(parsedUrl.searchParams),\n    };\n  } catch {\n    return null;\n  }\n}\n","interface QueueOptions<TItem> {\n  capacity: number;\n  onDropOldest?: (command: TItem) => void;\n}\n\nexport class Queue<TItem> {\n  private _items: TItem[] = [];\n  private _maxSize: number;\n  private _onDropOldest?: (command: TItem) => void;\n\n  constructor(options: QueueOptions<TItem>) {\n    this._maxSize = options.capacity;\n    this._onDropOldest = options.onDropOldest;\n  }\n\n  enqueue(command: TItem): void {\n    if (this._items.length >= this._maxSize) {\n      const dropped = this._items.shift();\n      if (dropped) {\n        this._onDropOldest?.(dropped);\n      }\n    }\n    this._items.push(command);\n  }\n\n  flush(): TItem[] {\n    const items = [...this._items];\n    this._items = [];\n    return items;\n  }\n\n  clear(): void {\n    this._items = [];\n  }\n\n  /** @internal */\n  getSize(): number {\n    return this._items.length;\n  }\n\n  /** @internal */\n  getAll(): readonly TItem[] {\n    return this._items;\n  }\n}\n","export function isBeaconSupported(): boolean {\n  return (\n    typeof window !== 'undefined' &&\n    typeof navigator !== 'undefined' &&\n    typeof navigator.sendBeacon === 'function'\n  );\n}\n","import { EventPayload } from '../types';\nimport { ApiError, ApiErrorResponse, NetworkError } from './error';\nimport { isBeaconSupported } from './isBeaconSupported';\n\nexport interface RequesterConfig {\n  baseUrl: string;\n  apiKey: string;\n  requestTimeout: number;\n}\n\nexport class Requester<TPayload extends EventPayload> {\n  private readonly _config: Required<RequesterConfig>;\n\n  constructor(config: RequesterConfig) {\n    this._config = config;\n  }\n\n  private _constructUrl(path: string): string {\n    return `${this._config.baseUrl}${path}?apiKey=${encodeURIComponent(\n      this._config.apiKey\n    )}`;\n  }\n\n  async send(path: string, payload: TPayload): Promise<void> {\n    if (isBeaconSupported()) {\n      return this._sendWithBeacon(path, payload);\n    }\n\n    return this._sendWithFetch(path, payload);\n  }\n\n  private async _sendWithBeacon(\n    path: string,\n    payload: TPayload\n  ): Promise<void> {\n    const url = this._constructUrl(path);\n    const data = new Blob([JSON.stringify(payload)], {\n      type: 'application/json',\n    });\n\n    try {\n      const success = navigator.sendBeacon(url, data);\n      if (!success) {\n        return this._sendWithFetch(path, payload);\n      }\n    } catch (error) {\n      return this._sendWithFetch(path, payload);\n    }\n  }\n\n  private async _sendWithFetch(path: string, payload: TPayload): Promise<void> {\n    const url = this._constructUrl(path);\n    const controller = new AbortController();\n    const timeoutId = setTimeout(\n      () => controller.abort(),\n      this._config.requestTimeout\n    );\n\n    try {\n      const response = await fetch(url, {\n        method: 'POST',\n        headers: {\n          'Content-Type': 'application/json',\n        },\n        body: JSON.stringify(payload),\n        keepalive: true,\n        signal: controller.signal,\n      });\n\n      if (!response.ok) {\n        let errorResponse: ApiErrorResponse | undefined;\n\n        try {\n          errorResponse = await response.json();\n        } catch {\n          // If parsing fails, continue without parsed response\n        }\n\n        throw new ApiError(\n          response.status,\n          response.statusText,\n          errorResponse?.error_code,\n          errorResponse,\n          {\n            url,\n            method: 'POST',\n            payload,\n          }\n        );\n      }\n    } catch (error) {\n      if (error instanceof ApiError) {\n        throw error;\n      }\n\n      throw new NetworkError(\n        error instanceof Error ? error.message : 'Network request failed',\n        error\n      );\n    } finally {\n      clearTimeout(timeoutId);\n    }\n  }\n}\n","/* eslint-disable no-restricted-globals */\n\n/** Runs code on browser environments safely. */\nexport function safelyRunOnBrowser<TReturn>(\n  callback: (params: { window: typeof window }) => TReturn,\n  /** Fallback to run on server environments. */\n  fallback: () => TReturn = () => undefined as unknown as TReturn\n): TReturn {\n  if (typeof window === 'undefined') {\n    return fallback();\n  }\n\n  return callback({ window });\n}\n","import { safelyRunOnBrowser } from './safelyRunOnBrowser';\n\nexport type PropertyViewport = string | null;\n\nexport function getViewport(): PropertyViewport {\n  return safelyRunOnBrowser<PropertyViewport>(\n    ({ window }) => `${window.innerWidth}x${window.innerHeight}`,\n    () => null\n  );\n}\n","import { safelyRunOnBrowser } from './safelyRunOnBrowser';\nimport { getViewport, PropertyViewport } from './viewport';\n\n/**\n * Runtime context captured at event time.\n *\n * This is used for events that need browser state (URL, viewport, referrer)\n * prior to the library being initialized. It ensures that the event payload\n * reflects the correct time-sensitive data from when the user called the method,\n * not when the queue is flushed post-init.\n */\nexport type RuntimeContext = {\n  timestamp: string;\n  url: PropertyUrl;\n  referrer: PropertyReferrer;\n  viewport: PropertyViewport;\n};\ntype PropertyReferrer = string | null;\ntype PropertyUrl = string | null;\n\nexport function captureRuntimeContext(): RuntimeContext {\n  return {\n    timestamp: new Date().toISOString(),\n    url: safelyRunOnBrowser<PropertyUrl>(\n      ({ window }) => window.location.href || null,\n      () => null\n    ),\n    referrer: safelyRunOnBrowser<PropertyReferrer>(\n      ({ window }) => window.document.referrer || null,\n      () => null\n    ),\n    viewport: getViewport(),\n  };\n}\n","export function generateId<T extends string>(prefix: T): `${T}-${string}` {\n  if (\n    typeof globalThis.crypto !== 'undefined' &&\n    typeof globalThis.crypto.randomUUID === 'function'\n  ) {\n    try {\n      return `${prefix}-${crypto.randomUUID()}`;\n    } catch {\n      // Continue with Math.random() fallback.\n    }\n  }\n  return `${prefix}-${Math.random().toString(36).substring(2)}`;\n}\n","import {\n  PREFIX_ANONYMOUS_ID,\n  PREFIX_DEVICE_ID,\n  PREFIX_SESSION_ID,\n  SESSION_EXPIRATION_TIME_MS,\n  TrackingConsent,\n  TrackingConsentType,\n} from '../constants';\nimport type {\n  AnonymousId,\n  DeviceId,\n  DistinctId,\n  SessionId,\n  UserId,\n} from '../types';\nimport { generateId } from './generateId';\nimport { Logger } from './logger';\nimport { type StorageApi } from './storage';\n\ntype SessionData = {\n  deviceId: DeviceId;\n  distinctId: DistinctId;\n  anonymousId: AnonymousId | null;\n  sessionId: SessionId;\n  lastEventAt: string | null;\n  trackingConsent: TrackingConsentType;\n};\n\nexport class SessionManager {\n  private _defaultTrackingConsent: TrackingConsentType;\n  private _logger: Logger;\n  private _sessionData: SessionData;\n  private _storage: StorageApi;\n  private _storageKey: string;\n\n  constructor(options: {\n    storage: StorageApi;\n    storageKey: string;\n    logger: Logger;\n    defaultTrackingConsent: TrackingConsentType;\n  }) {\n    this._storage = options.storage;\n    this._storageKey = options.storageKey;\n    this._logger = options.logger;\n    this._defaultTrackingConsent =\n      options.defaultTrackingConsent ?? TrackingConsent.PENDING;\n    this._sessionData = this._createDefaultSessionData();\n  }\n\n  init(): void {\n    const storedData = this._storage.getItem(this._storageKey);\n\n    if (!storedData) {\n      this._sessionData = this._createDefaultSessionData();\n      this._persistToStorage();\n      return;\n    }\n\n    try {\n      const parsedData = JSON.parse(storedData) as Partial<SessionData>;\n\n      this._sessionData = {\n        deviceId: parsedData.deviceId || this._generateDeviceId(),\n        distinctId: parsedData.distinctId || this._generateAnonymousId(),\n        sessionId: parsedData.sessionId || this._generateSessionId(),\n        anonymousId: parsedData.anonymousId || null,\n        lastEventAt: parsedData.lastEventAt || null,\n        trackingConsent: isValidTrackingConsent(parsedData.trackingConsent)\n          ? parsedData.trackingConsent\n          : this._defaultTrackingConsent,\n      };\n    } catch (error) {\n      this._logger.warnDev(\n        'Failed to parse storage data. Resetting session data.'\n      );\n      this._sessionData = this._createDefaultSessionData();\n    }\n\n    this._persistToStorage();\n  }\n\n  getSessionId(): SessionId {\n    return this._sessionData.sessionId;\n  }\n\n  getDeviceId(): DeviceId {\n    return this._sessionData.deviceId;\n  }\n\n  getDistinctId(): DistinctId {\n    return this._sessionData.distinctId;\n  }\n\n  getAnonymousId(): AnonymousId | null {\n    return this._sessionData.anonymousId;\n  }\n\n  /**\n   * Returns whether the current user is identified.\n   *\n   * The `anonymousId` field is a \"before\" snapshot: if set, the user was previously\n   * anonymous and is now identified. If `null`, the user is still anonymous.\n   *\n   * When transitioning from anonymous to identified, we preserve the anonymous ID\n   * to enable identity merging on the backend. This allows:\n   * - Linking pre-identification events (anonymous ID) to post-identification events (user ID)\n   * - Merging user profiles so anonymous browsing behavior is associated with the identified user\n   * - Maintaining a complete user journey from first visit through identification\n   *\n   * **State Transitions:**\n   * - **Anonymous:** `anonymousId = null`, `distinctId = anonymousId`, `isIdentified() = false`\n   * - **Identified:** `anonymousId = previous distinctId`, `distinctId = userId`, `isIdentified() = true`\n   */\n  isIdentified(): boolean {\n    return Boolean(this._sessionData.anonymousId);\n  }\n\n  getLastEventAt(): string | null {\n    return this._sessionData.lastEventAt;\n  }\n\n  getTrackingConsent(): TrackingConsentType {\n    return this._sessionData.trackingConsent;\n  }\n\n  identify(userId: UserId): void {\n    this._sessionData.anonymousId = this._sessionData.distinctId as AnonymousId;\n    this._sessionData.distinctId = userId;\n    this._persistToStorage();\n  }\n\n  setTrackingConsent(consent: TrackingConsentType): void {\n    this._sessionData.trackingConsent = consent;\n    this._persistToStorage();\n  }\n\n  updateLastEventAt(timestamp: string): void {\n    this._sessionData.lastEventAt = timestamp;\n    this._persistToStorage();\n  }\n\n  renewSessionIfNeeded(): boolean {\n    const shouldRenew = this._shouldRenewSession();\n\n    if (shouldRenew) {\n      this._renewSession();\n      this._persistToStorage();\n      return true;\n    }\n\n    return false;\n  }\n\n  reset({\n    resetDeviceId = false,\n    resetTrackingConsent = false,\n  }: {\n    resetDeviceId?: boolean;\n    resetTrackingConsent?: boolean;\n  } = {}): void {\n    if (resetDeviceId) {\n      this._sessionData.deviceId = this._generateDeviceId();\n    }\n\n    if (resetTrackingConsent) {\n      this._sessionData.trackingConsent = this._defaultTrackingConsent;\n    }\n\n    this._sessionData.sessionId = this._generateSessionId();\n    this._sessionData.anonymousId = null;\n    this._sessionData.distinctId = this._generateAnonymousId();\n    this._sessionData.lastEventAt = null;\n    this._persistToStorage();\n  }\n\n  private _createDefaultSessionData(): SessionData {\n    return {\n      anonymousId: null,\n      deviceId: this._generateDeviceId(),\n      distinctId: this._generateAnonymousId(),\n      lastEventAt: null,\n      sessionId: this._generateSessionId(),\n      trackingConsent: this._defaultTrackingConsent,\n    };\n  }\n\n  private _generateSessionId(): SessionId {\n    return generateId(PREFIX_SESSION_ID);\n  }\n\n  private _generateDeviceId(): DeviceId {\n    return generateId(PREFIX_DEVICE_ID);\n  }\n\n  private _generateAnonymousId(): AnonymousId {\n    return generateId(PREFIX_ANONYMOUS_ID);\n  }\n\n  private _shouldRenewSession(): boolean {\n    const { lastEventAt } = this._sessionData;\n\n    if (!lastEventAt) {\n      return true;\n    }\n\n    const now = new Date().getTime();\n    const lastEventTime = new Date(lastEventAt).getTime();\n    const timeSinceLastEvent = now - lastEventTime;\n\n    return timeSinceLastEvent > SESSION_EXPIRATION_TIME_MS;\n  }\n\n  private _renewSession(): void {\n    this._sessionData.sessionId = this._generateSessionId();\n    this._sessionData.lastEventAt = null;\n  }\n\n  private _persistToStorage(): void {\n    try {\n      this._storage.setItem(\n        this._storageKey,\n        JSON.stringify(this._sessionData)\n      );\n    } catch (error) {\n      this._logger.warnDev('Failed to persist session data to storage.');\n    }\n  }\n}\n\nfunction isValidTrackingConsent(value: unknown): value is TrackingConsentType {\n  return (\n    typeof value === 'string' &&\n    Object.values(TrackingConsent).includes(value as TrackingConsentType)\n  );\n}\n","import { STORAGE_KEY_TEST } from '../constants';\nimport { safelyRunOnBrowser } from './safelyRunOnBrowser';\n\nexport type StorageType =\n  | 'localStorage'\n  | 'sessionStorage'\n  | 'cookie'\n  | 'memory'\n  | 'localStorage+cookie';\n\nexport interface StorageApi {\n  getItem(key: string): string | null;\n  setItem(key: string, value: string): void;\n  removeItem(key: string): void;\n  migrate(fromStorage: StorageApi, keys: string[]): void;\n}\n\nfunction migrateKeys(\n  toStorage: StorageApi,\n  fromStorage: StorageApi,\n  keys: string[]\n): void {\n  for (const key of keys) {\n    const value = fromStorage.getItem(key);\n    if (value !== null) {\n      toStorage.setItem(key, value);\n      fromStorage.removeItem(key);\n    }\n  }\n}\n\nclass MemoryStore implements StorageApi {\n  private store: Record<string, string> = {};\n  getItem(key: string): string | null {\n    return this.store[key] ?? null;\n  }\n  setItem(key: string, value: string) {\n    this.store[key] = value;\n  }\n  removeItem(key: string) {\n    delete this.store[key];\n  }\n  migrate(fromStorage: StorageApi, keys: string[]) {\n    migrateKeys(this, fromStorage, keys);\n  }\n}\n\nclass CookieStore implements StorageApi {\n  getItem(key: string): string | null {\n    return safelyRunOnBrowser<string | null>(\n      ({ window }) => {\n        const match = window.document.cookie.match(\n          new RegExp('(^| )' + key + '=([^;]+)')\n        );\n        return match ? decodeURIComponent(match[2]) : null;\n      },\n      () => null\n    );\n  }\n  setItem(key: string, value: string) {\n    safelyRunOnBrowser(({ window }) => {\n      window.document.cookie = `${key}=${encodeURIComponent(value)}; path=/;`;\n    });\n  }\n  removeItem(key: string) {\n    safelyRunOnBrowser(({ window }) => {\n      window.document.cookie = `${key}=; Max-Age=0; path=/;`;\n    });\n  }\n  migrate(fromStorage: StorageApi, keys: string[]) {\n    migrateKeys(this, fromStorage, keys);\n  }\n}\n\nclass WebStorageStore implements StorageApi {\n  constructor(private storage: 'localStorage' | 'sessionStorage') {}\n  getItem(key: string): string | null {\n    return safelyRunOnBrowser<string | null>(\n      ({ window }) => {\n        try {\n          return window[this.storage].getItem(key);\n        } catch {\n          return null;\n        }\n      },\n      () => null\n    );\n  }\n  setItem(key: string, value: string) {\n    safelyRunOnBrowser(({ window }) => {\n      try {\n        window[this.storage].setItem(key, value);\n      } catch {\n        /* ignore */\n      }\n    });\n  }\n  removeItem(key: string) {\n    safelyRunOnBrowser(({ window }) => {\n      try {\n        window[this.storage].removeItem(key);\n      } catch {\n        /* ignore */\n      }\n    });\n  }\n  migrate(fromStorage: StorageApi, keys: string[]) {\n    migrateKeys(this, fromStorage, keys);\n  }\n}\n\nclass LocalPlusCookieStore implements StorageApi {\n  private localStore = new WebStorageStore('localStorage');\n  private cookieStore = new CookieStore();\n  getItem(key: string): string | null {\n    return this.localStore.getItem(key) ?? this.cookieStore.getItem(key);\n  }\n  setItem(key: string, value: string) {\n    this.localStore.setItem(key, value);\n    this.cookieStore.setItem(key, value);\n  }\n  removeItem(key: string) {\n    this.localStore.removeItem(key);\n    this.cookieStore.removeItem(key);\n  }\n  migrate(fromStorage: StorageApi, keys: string[]) {\n    // Migrate to both localStorage and cookie without removing from source yet\n    for (const key of keys) {\n      const value = fromStorage.getItem(key);\n      if (value !== null) {\n        this.localStore.setItem(key, value);\n        this.cookieStore.setItem(key, value);\n      }\n    }\n\n    for (const key of keys) {\n      fromStorage.removeItem(key);\n    }\n  }\n}\n\nfunction testStorageSupport(\n  storageType: 'localStorage' | 'sessionStorage' | 'cookie'\n) {\n  return safelyRunOnBrowser(\n    ({ window }) => {\n      try {\n        if (storageType === 'cookie') {\n          window.document.cookie = `${STORAGE_KEY_TEST}=1`;\n          const supported =\n            window.document.cookie.indexOf(`${STORAGE_KEY_TEST}=`) !== -1;\n          window.document.cookie = `${STORAGE_KEY_TEST}=; Max-Age=0`;\n          return supported;\n        } else {\n          window[storageType].setItem(STORAGE_KEY_TEST, '1');\n          window[storageType].removeItem(STORAGE_KEY_TEST);\n          return true;\n        }\n      } catch {\n        return false;\n      }\n    },\n    () => false\n  );\n}\n\nexport function selectStorage(\n  type: StorageType | 'unknown',\n  params: { onFallback: (message: string) => void }\n): StorageApi {\n  const { onFallback } = params;\n\n  switch (type) {\n    case 'localStorage': {\n      if (testStorageSupport('localStorage')) {\n        return new WebStorageStore('localStorage');\n      }\n      onFallback(\n        'localStorage not supported, falling back to localStorage+cookie.'\n      );\n      return selectStorage('localStorage+cookie', params);\n    }\n\n    case 'localStorage+cookie': {\n      const localStorageSupported = testStorageSupport('localStorage');\n      const cookieSupported = testStorageSupport('cookie');\n\n      if (localStorageSupported && cookieSupported) {\n        return new LocalPlusCookieStore();\n      } else if (cookieSupported) {\n        onFallback(\n          'localStorage+cookie not fully supported, falling back to cookie.'\n        );\n        return new CookieStore();\n      } else if (localStorageSupported) {\n        onFallback('cookie not supported, falling back to localStorage.');\n        return new WebStorageStore('localStorage');\n      } else {\n        onFallback(\n          'Neither localStorage nor cookie supported, falling back to memory.'\n        );\n        return new MemoryStore();\n      }\n    }\n\n    case 'sessionStorage': {\n      if (testStorageSupport('sessionStorage')) {\n        return new WebStorageStore('sessionStorage');\n      }\n      onFallback('sessionStorage not supported, falling back to memory.');\n      return new MemoryStore();\n    }\n\n    case 'cookie': {\n      if (testStorageSupport('cookie')) {\n        return new CookieStore();\n      }\n      onFallback('cookie not supported, falling back to memory.');\n      return new MemoryStore();\n    }\n\n    case 'memory': {\n      return new MemoryStore();\n    }\n\n    default: {\n      throw new Error(\n        `Unknown storage type: \"${type}\". Valid types are: localStorage, sessionStorage, cookie, memory, localStorage+cookie.`\n      );\n    }\n  }\n}\n","import {\n  RESERVED_USER_IDS,\n  RESERVED_USER_IDS_CASE_SENSITIVE,\n} from '../constants';\n\nconst reservedIdentifiersList = [\n  ...RESERVED_USER_IDS,\n  ...RESERVED_USER_IDS_CASE_SENSITIVE,\n]\n  .map(id => `- \"${id}\"`)\n  .join('\\n');\nconst reservedIdentifiersInfo = `List of reserved identifiers:\\n${reservedIdentifiersList}`;\n\nexport function validateUserId(userId: string): void {\n  if (!userId || userId.trim() === '') {\n    throw new Error('User ID cannot be empty or contain only whitespace.');\n  }\n\n  const isCaseInsensitiveBlocked = RESERVED_USER_IDS.some(\n    blockedId => userId.toLowerCase() === blockedId.toLowerCase()\n  );\n\n  if (isCaseInsensitiveBlocked) {\n    throw new Error(\n      `User ID \"${userId}\" is a reserved identifier and cannot be used.\\n\\n` +\n        reservedIdentifiersInfo\n    );\n  }\n\n  const isCaseSensitiveBlocked = RESERVED_USER_IDS_CASE_SENSITIVE.has(userId);\n\n  if (isCaseSensitiveBlocked) {\n    throw new Error(\n      `User ID \"${userId}\" is a reserved identifier and cannot be used.\\n\\n` +\n        reservedIdentifiersInfo\n    );\n  }\n}\n","import {\n  AUTO_CAPTURE_INTERVAL_MS,\n  EVENT_PAGEVIEW,\n  keyBuilder,\n  MAX_QUEUE_SIZE,\n  PROPERTY_LIB,\n  PROPERTY_LIB_VERSION,\n  PROPERTY_REFERER,\n  PROPERTY_RELEASE,\n  PROPERTY_URL,\n  PROPERTY_VIEWPORT,\n  REQUEST_TIMEOUT_MS,\n  TrackingConsent,\n  TrackingConsentType,\n} from './constants';\nimport { isAltertableError, isApiError, isNetworkError } from './lib/error';\nimport { invariant } from './lib/invariant';\nimport { dashboardUrl } from './lib/link';\nimport { createLogger } from './lib/logger';\nimport { parseUrl } from './lib/parseUrl';\nimport { Queue } from './lib/queue';\nimport { Requester } from './lib/requester';\nimport { captureRuntimeContext, RuntimeContext } from './lib/runtimeContext';\nimport { safelyRunOnBrowser } from './lib/safelyRunOnBrowser';\nimport { SessionManager } from './lib/sessionManager';\nimport {\n  selectStorage,\n  type StorageApi,\n  type StorageType,\n} from './lib/storage';\nimport { validateUserId } from './lib/validateUserId';\nimport { getViewport } from './lib/viewport';\nimport {\n  AliasPayload,\n  AltertableContext,\n  DistinctId,\n  Environment,\n  EventPayload,\n  EventProperties,\n  EventType,\n  IdentifyPayload,\n  TrackPayload,\n  UserTraits,\n} from './types';\n\nexport interface AltertableConfig {\n  /**\n   * The base URL of the Altertable API.\n   * @default https://api.altertable.ai\n   */\n  baseUrl?: string;\n  /**\n   * The environment of the application.\n   * @default \"production\"\n   */\n  environment?: Environment;\n  /**\n   * Whether to automatically capture page views and events.\n   * @default true\n   */\n  autoCapture?: boolean;\n  /**\n   * The release ID of the application.\n   * This is helpful to identify the version of the application an event is coming from.\n   */\n  release?: string;\n  /**\n   * Whether to log events to the console.\n   * @default false\n   */\n  debug?: boolean;\n  /**\n   * The persistence strategy for storing IDs.\n   * @default \"localStorage+cookie\"\n   */\n  persistence?: StorageType;\n  /**\n   * The tracking consent state.\n   * @default \"granted\"\n   */\n  trackingConsent?: TrackingConsentType;\n  /**\n   * Optional error handler for intercepting SDK errors.\n   */\n  onError?: (error: Error) => void;\n}\n\nconst DEFAULT_CONFIG: AltertableConfig = {\n  autoCapture: true,\n  baseUrl: 'https://api.altertable.ai',\n  debug: false,\n  environment: 'production',\n  persistence: 'localStorage+cookie',\n  release: undefined,\n  trackingConsent: TrackingConsent.GRANTED,\n};\n\nexport class Altertable {\n  private _cleanupAutoCapture: (() => void) | undefined;\n  private _config: AltertableConfig;\n  private _queue: Queue<QueueItem>;\n  private _isInitialized = false;\n  private _lastUrl: string | null;\n  private _logger = createLogger('Altertable');\n  private _referrer: string | null;\n  private _requester: Requester<EventPayload> | undefined;\n  private _sessionManager: SessionManager | undefined;\n  private _storage: StorageApi | undefined;\n  private _storageKey: string | undefined;\n\n  constructor() {\n    this._lastUrl = null;\n    this._referrer = null;\n    this._queue = new Queue<QueueItem>({\n      capacity: MAX_QUEUE_SIZE,\n      onDropOldest: droppedItem => {\n        const method =\n          droppedItem.type === 'command'\n            ? droppedItem.method\n            : droppedItem.eventType;\n        this._logger.warnDev(\n          `Queue is full (${MAX_QUEUE_SIZE} items). Dropping ${method} call.`\n        );\n      },\n    });\n  }\n\n  /**\n   * Initializes the Altertable SDK with your API key and optional configuration.\n   *\n   * @param apiKey Your Altertable API key\n   * @param config Configuration options\n   * @returns A cleanup function to remove event listeners\n   *\n   * @example\n   * ```javascript\n   * altertable.init('YOUR_API_KEY', {\n   *   environment: 'development',\n   * });\n   * ```\n   */\n  init(apiKey: string, config: AltertableConfig = {}) {\n    invariant(apiKey, 'Missing API key');\n    this._config = { ...DEFAULT_CONFIG, ...config };\n    this._storageKey = keyBuilder(apiKey, this._config.environment);\n    this._referrer = safelyRunOnBrowser<string | null>(\n      ({ window }) => window.document.referrer || null,\n      () => null\n    );\n    this._lastUrl = safelyRunOnBrowser<string | null>(\n      ({ window }) => window.location.href || null,\n      () => null\n    );\n    this._storage = selectStorage(this._config.persistence, {\n      onFallback: message => this._logger.warn(message),\n    });\n    this._requester = new Requester({\n      baseUrl: this._config.baseUrl,\n      apiKey,\n      requestTimeout: REQUEST_TIMEOUT_MS,\n    });\n    this._sessionManager = new SessionManager({\n      storage: this._storage,\n      storageKey: this._storageKey,\n      logger: this._logger,\n      defaultTrackingConsent: this._config.trackingConsent,\n    });\n    this._sessionManager.init();\n\n    this._isInitialized = true;\n\n    if (this._config.debug) {\n      this._logger.logHeader();\n    }\n\n    const trackingConsent = this._sessionManager.getTrackingConsent();\n    if (trackingConsent === TrackingConsent.GRANTED) {\n      this._flushQueue();\n    } else if (trackingConsent === TrackingConsent.DENIED) {\n      this._queue.clear();\n    }\n\n    this._handleAutoCaptureChange(this._config.autoCapture);\n\n    return () => {\n      this._cleanupAutoCapture?.();\n    };\n  }\n\n  /**\n   * Updates the configuration after initialization.\n   *\n   * @param updates Configuration updates to apply\n   *\n   * @example\n   * ```javascript\n   * altertable.configure({\n   *   trackingConsent: 'granted',\n   * });\n   * ```\n   */\n  configure(updates: Partial<AltertableConfig>) {\n    invariant(\n      this._isInitialized,\n      'The client must be initialized with init() before configuring.'\n    );\n\n    if (\n      updates.autoCapture !== undefined &&\n      updates.autoCapture !== this._config.autoCapture\n    ) {\n      this._handleAutoCaptureChange(updates.autoCapture);\n    }\n\n    if (\n      updates.persistence !== undefined &&\n      updates.persistence !== this._config.persistence\n    ) {\n      const previousStorage = this._storage;\n      this._storage = selectStorage(updates.persistence, {\n        onFallback: message => this._logger.warn(message),\n      });\n      this._storage.migrate(previousStorage, [this._storageKey]);\n    }\n\n    const currentTrackingConsent = this._sessionManager.getTrackingConsent();\n    if (\n      updates.trackingConsent !== undefined &&\n      updates.trackingConsent !== currentTrackingConsent\n    ) {\n      this._sessionManager.setTrackingConsent(updates.trackingConsent);\n\n      if (\n        currentTrackingConsent !== TrackingConsent.GRANTED &&\n        updates.trackingConsent === TrackingConsent.GRANTED\n      ) {\n        this._flushQueue();\n      } else if (updates.trackingConsent === TrackingConsent.DENIED) {\n        this._queue.clear();\n      }\n    }\n\n    this._config = { ...this._config, ...updates };\n  }\n\n  private _handleAutoCaptureChange(enableAutoCapture: boolean) {\n    this._cleanupAutoCapture?.();\n\n    if (enableAutoCapture) {\n      if (this._lastUrl) {\n        this.page(this._lastUrl);\n      }\n\n      const checkForChanges = this._checkForChanges.bind(this);\n      const intervalId = setInterval(checkForChanges, AUTO_CAPTURE_INTERVAL_MS);\n\n      safelyRunOnBrowser(({ window }) => {\n        window.addEventListener('popstate', checkForChanges);\n        window.addEventListener('hashchange', checkForChanges);\n      });\n\n      this._cleanupAutoCapture = () => {\n        clearInterval(intervalId);\n        safelyRunOnBrowser(({ window }) => {\n          window.removeEventListener('popstate', checkForChanges);\n          window.removeEventListener('hashchange', checkForChanges);\n        });\n      };\n    } else {\n      this._cleanupAutoCapture = undefined;\n    }\n  }\n\n  /**\n   * Identifies a user with their ID and optional traits.\n   *\n   * Notes:\n   * - You can call this method multiple times with the same ID.\n   * - To change traits, use {@link updateTraits} instead.\n   * - To switch to a new user ID, call {@link reset} first.\n   *\n   * @param userId The user's unique identifier\n   * @param traits User properties\n   *\n   * @example\n   * ```javascript\n   * altertable.identify('u_01jza857w4f23s1hf2s61befmw', {\n   *   email: 'john.doe@example.com',\n   *   name: 'John Doe',\n   *   company: 'Acme Corp',\n   *   role: 'Software Engineer',\n   * });\n   * ```\n   */\n  identify(userId: DistinctId, traits: UserTraits = {}) {\n    try {\n      validateUserId(userId);\n    } catch (error) {\n      throw new Error(`[Altertable] ${error.message}`);\n    }\n\n    if (!this._isInitialized) {\n      this._queue.enqueue({\n        type: 'command',\n        method: 'identify',\n        args: [userId, { ...traits }],\n      });\n      return;\n    }\n\n    this._identify(userId, { ...traits });\n  }\n\n  private _identify(userId: DistinctId, traits: UserTraits = {}) {\n    if (\n      this._sessionManager.isIdentified() &&\n      userId !== this._sessionManager.getDistinctId()\n    ) {\n      this._logger.warnDev(\n        `User \"${userId}\" is already identified as \"${this._sessionManager.getDistinctId()}\".\\n\\n` +\n          `The session has been automatically reset. Use alias() to link the new ID to the existing one if intentional.`\n      );\n      this.reset();\n    }\n\n    if (userId !== this._sessionManager.getDistinctId()) {\n      this._sessionManager.identify(userId);\n    }\n\n    const context = this._getContext();\n    const payload: IdentifyPayload = {\n      environment: context.environment,\n      device_id: context.device_id,\n      distinct_id: context.distinct_id,\n      traits,\n      anonymous_id: context.anonymous_id,\n    };\n    this._processEvent('identify', payload);\n\n    if (this._config.debug) {\n      const trackingConsent = this._sessionManager.getTrackingConsent();\n      this._logger.logIdentify(payload, { trackingConsent });\n    }\n  }\n\n  /**\n   * Link a new ID to the current identity.\n   *\n   * @param newUserId The new user ID\n   *\n   * @example\n   * ```javascript\n   * altertable.alias('u_01jza857w4f23s1hf2s61befmw');\n   * ```\n   */\n  alias(newUserId: DistinctId) {\n    try {\n      validateUserId(newUserId);\n    } catch (error) {\n      throw new Error(`[Altertable] ${error.message}`);\n    }\n\n    if (!this._isInitialized) {\n      this._queue.enqueue({\n        type: 'command',\n        method: 'alias',\n        args: [newUserId],\n      });\n      return;\n    }\n\n    this._alias(newUserId);\n  }\n\n  private _alias(newUserId: DistinctId) {\n    const context = this._getContext();\n\n    const payload: AliasPayload = {\n      environment: context.environment,\n      device_id: context.device_id,\n      anonymous_id: context.anonymous_id,\n      distinct_id: context.distinct_id,\n      new_user_id: newUserId,\n    };\n\n    this._processEvent('alias', payload);\n\n    if (this._config.debug) {\n      const trackingConsent = this._sessionManager.getTrackingConsent();\n      this._logger.logAlias(payload, { trackingConsent });\n    }\n  }\n\n  /**\n   * Updates user traits for the current user.\n   *\n   * @param traits User properties to update\n   *\n   * @example\n   * ```javascript\n   * altertable.updateTraits({\n   *   onboarding_completed: true,\n   * });\n   * ```\n   */\n  updateTraits(traits: UserTraits) {\n    if (!this._isInitialized) {\n      this._queue.enqueue({\n        type: 'command',\n        method: 'updateTraits',\n        args: [{ ...traits }],\n      });\n      return;\n    }\n\n    this._updateTraits({ ...traits });\n  }\n\n  private _updateTraits(traits: UserTraits) {\n    const context = this._getContext();\n\n    if (context.anonymous_id === null) {\n      this._logger.warnDev(\n        'User must be identified with identify() before updating traits.'\n      );\n      return;\n    }\n\n    const payload = {\n      environment: context.environment,\n      device_id: context.device_id,\n      distinct_id: context.distinct_id,\n      traits,\n      anonymous_id: context.anonymous_id,\n      session_id: context.session_id,\n    };\n    this._processEvent('identify', payload);\n\n    if (this._config.debug) {\n      const trackingConsent = this._sessionManager.getTrackingConsent();\n      this._logger.logIdentify(payload, { trackingConsent });\n    }\n  }\n\n  /**\n   * Resets device and session IDs.\n   *\n   * @example\n   * ```javascript\n   * // Reset session, user and visitor (default)\n   * altertable.reset();\n   *\n   * // Reset session, user, visitor and device\n   * altertable.reset({\n   *   resetDeviceId: true,\n   * });\n   * ```\n   */\n  reset({\n    resetDeviceId = false,\n  }: {\n    /** Whether to reset device ID (default: false) */\n    resetDeviceId?: boolean;\n  } = {}) {\n    // Clear queued commands to prevent cross-identity/session mixing\n    this._queue.clear();\n\n    if (!this._isInitialized) {\n      return;\n    }\n\n    this._sessionManager.reset({\n      resetDeviceId,\n    });\n  }\n\n  /**\n   * Tracks a page view event.\n   *\n   * When `autoCapture` is enabled (default), this method is automatically called when the page URL changes.\n   *\n   * @param url The page URL\n   *\n   * @example\n   * ```javascript\n   * altertable.page('https://example.com/products');\n   * ```\n   *\n   * @remarks\n   * **Page Tracking**: By default, Altertable automatically captures page views. Only use `page()` when you've disabled auto-capture.\n   *\n   * **Why use auto-capture (default)?**\n   * - No manual tracking required\n   * - Handles browser navigation events (popstate, hashchange)\n   * - Consistent tracking across all page changes\n   *\n   * **When to use `page()`:**\n   * - Custom routing that doesn't trigger browser events\n   * - Virtual page views that don't trigger URL changes (modals, step changes)\n   * - Server-side tracking where auto-capture isn't available\n   */\n  page(url: string) {\n    if (!this._isInitialized) {\n      this._queue.enqueue({\n        type: 'command',\n        method: 'page',\n        runtimeContext: captureRuntimeContext(),\n        args: [url],\n      });\n      return;\n    }\n\n    this._page(url);\n  }\n\n  private _page(url: string, runtimeContext?: RuntimeContext) {\n    const parsedUrl = parseUrl(url);\n    const baseUrl = parsedUrl ? parsedUrl.baseUrl : url;\n\n    const viewport = runtimeContext?.viewport ?? getViewport();\n    const referrer = runtimeContext?.referrer ?? this._referrer;\n\n    this._track(\n      EVENT_PAGEVIEW,\n      {\n        [PROPERTY_URL]: baseUrl,\n        [PROPERTY_VIEWPORT]: viewport,\n        [PROPERTY_REFERER]: referrer,\n        ...parsedUrl?.searchParams,\n      },\n      runtimeContext\n    );\n  }\n\n  /**\n   * Tracks a custom event with optional properties.\n   *\n   * @param eventThe event name\n   * @param properties Custom event properties\n   *\n   * @example\n   * ```javascript\n   * altertable.track('Purchase Completed', {\n   *   product_id: 'p_01jza8fr5efvgbxxdd1bwkd0m5',\n   *   amount: 29.99,\n   *   currency: 'USD',\n   * });\n   * ```\n   */\n  track(event: string, properties: EventProperties = {}) {\n    if (!this._isInitialized) {\n      this._queue.enqueue({\n        type: 'command',\n        method: 'track',\n        runtimeContext: captureRuntimeContext(),\n        args: [event, { ...properties }],\n      });\n      return;\n    }\n\n    this._track(event, { ...properties });\n  }\n\n  private _track(\n    event: string,\n    properties: EventProperties,\n    runtimeContext: RuntimeContext = captureRuntimeContext()\n  ) {\n    this._sessionManager.renewSessionIfNeeded();\n    this._sessionManager.updateLastEventAt(runtimeContext.timestamp);\n\n    const context = this._getContext();\n\n    // Strip undefined $url to prevent it from overriding computed URL\n    const { [PROPERTY_URL]: userUrl, ...restProperties } = properties;\n    const hasUrl = userUrl !== undefined;\n    const urlForEvent = hasUrl ? null : runtimeContext.url;\n\n    const parsedUrl = urlForEvent ? parseUrl(urlForEvent) : null;\n    const baseUrl = parsedUrl ? parsedUrl.baseUrl : urlForEvent;\n\n    const payload: TrackPayload = {\n      timestamp: runtimeContext.timestamp,\n      event,\n      environment: context.environment,\n      device_id: context.device_id,\n      distinct_id: context.distinct_id,\n      anonymous_id: context.anonymous_id,\n      session_id: context.session_id,\n      properties: {\n        [PROPERTY_LIB]: __LIB__,\n        [PROPERTY_LIB_VERSION]: __LIB_VERSION__,\n        [PROPERTY_RELEASE]: this._config.release,\n        [PROPERTY_URL]: hasUrl ? userUrl : baseUrl,\n        // The above properties might be overridden by user-provided fields\n        // and the React library\n        ...restProperties,\n      },\n    };\n\n    this._processEvent('track', payload);\n\n    if (this._config.debug) {\n      const trackingConsent = this._sessionManager.getTrackingConsent();\n      this._logger.logEvent(payload, { trackingConsent });\n    }\n  }\n\n  /**\n   * Returns the current tracking consent state.\n   *\n   * @returns The current tracking consent state\n   * @see {@link TrackingConsent}\n   *\n   * @example\n   * ```javascript\n   * const consent = altertable.getTrackingConsent();\n   * if (consent === 'granted') {\n   *   // Tracking is allowed\n   * }\n   * ```\n   */\n  getTrackingConsent(): TrackingConsentType {\n    if (!this._isInitialized) {\n      return TrackingConsent.PENDING;\n    }\n    return this._sessionManager.getTrackingConsent();\n  }\n\n  private _flushQueue() {\n    const items = this._queue.flush();\n\n    if (items.length === 0) {\n      return;\n    }\n\n    if (this._config.debug) {\n      this._logger.log(\n        `Processing ${items.length} queued ${items.length === 1 ? 'item' : 'items'}.`\n      );\n    }\n\n    for (const item of items) {\n      this._executeQueueItem(item);\n    }\n  }\n\n  private _executeQueueItem(item: QueueItem) {\n    if (item.type === 'event') {\n      // Send pre-built payload directly (preserves original session context)\n      this._sendEvent(item.eventType, item.payload);\n      return;\n    }\n    // Execute command (pre-init path)\n    this._executeCommand(item);\n  }\n\n  private _executeCommand(cmd: QueuedCommand) {\n    try {\n      switch (cmd.method) {\n        case 'identify':\n          this._identify(...cmd.args);\n          break;\n        case 'track':\n          this._track(...cmd.args, cmd.runtimeContext);\n          break;\n        case 'page':\n          this._page(...cmd.args, cmd.runtimeContext);\n          break;\n        case 'alias':\n          this._alias(...cmd.args);\n          break;\n        case 'updateTraits':\n          this._updateTraits(...cmd.args);\n          break;\n      }\n    } catch (error) {\n      const errorMessage =\n        error instanceof Error ? error.message : String(error);\n      this._logger.warnDev(\n        `Failed to process queued ${cmd.method}() command:\\n${errorMessage}`\n      );\n    }\n  }\n\n  private _checkForChanges() {\n    safelyRunOnBrowser(({ window }) => {\n      const currentUrl = window.location.href;\n      if (currentUrl !== this._lastUrl) {\n        this._referrer = this._lastUrl;\n        this._lastUrl = currentUrl;\n        this.page(currentUrl);\n      }\n    });\n  }\n\n  private _getContext(): AltertableContext {\n    return {\n      environment: this._config.environment,\n      device_id: this._sessionManager.getDeviceId(),\n      distinct_id: this._sessionManager.getDistinctId(),\n      anonymous_id: this._sessionManager.getAnonymousId(),\n      session_id: this._sessionManager.getSessionId(),\n    };\n  }\n\n  private _processEvent<TPayload extends EventPayload>(\n    eventType: EventType,\n    payload: TPayload\n  ) {\n    const trackingConsent = this._sessionManager.getTrackingConsent();\n\n    switch (trackingConsent) {\n      case TrackingConsent.GRANTED:\n        this._sendEvent(eventType, payload);\n        break;\n      case TrackingConsent.PENDING:\n      case TrackingConsent.DISMISSED:\n        this._queue.enqueue({\n          type: 'event',\n          eventType,\n          payload,\n        });\n        break;\n      case TrackingConsent.DENIED:\n        // Do nothing (don't collect or send data)\n        break;\n    }\n  }\n\n  private async _sendEvent<TPayload extends EventPayload>(\n    eventType: EventType,\n    payload: TPayload\n  ) {\n    try {\n      await this._requester.send(`/${eventType}`, payload);\n    } catch (error) {\n      if (isAltertableError(error)) {\n        this._config.onError?.(error);\n      }\n\n      if (isApiError(error) && error.errorCode === 'environment-not-found') {\n        this._logger.warnDev(\n          `Environment \"${this._config.environment}\" not found. Please create this environment in your Altertable dashboard at ${dashboardUrl(`/environments/new?name=${this._config.environment}`)} before tracking events.`\n        );\n      } else if (isNetworkError(error)) {\n        this._logger.error('Network error while sending event', {\n          error: error.message,\n          cause: error.cause,\n          eventType,\n        });\n      } else {\n        this._logger.error('Failed to send event', {\n          error,\n          eventType,\n          payload,\n        });\n      }\n    }\n  }\n}\n\ntype QueuedCommand =\n  | {\n      type: 'command';\n      method: 'identify';\n      args: Parameters<Altertable['identify']>;\n    }\n  | {\n      type: 'command';\n      method: 'track';\n      args: Parameters<Altertable['track']>;\n      runtimeContext: RuntimeContext;\n    }\n  | {\n      type: 'command';\n      method: 'page';\n      args: Parameters<Altertable['page']>;\n      runtimeContext: RuntimeContext;\n    }\n  | {\n      type: 'command';\n      method: 'alias';\n      args: Parameters<Altertable['alias']>;\n    }\n  | {\n      type: 'command';\n      method: 'updateTraits';\n      args: Parameters<Altertable['updateTraits']>;\n    };\n\ntype QueuedEvent = {\n  type: 'event';\n  eventType: EventType;\n  payload: EventPayload;\n};\n\ntype QueueItem = QueuedCommand | QueuedEvent;\n","import { TrackingConsent } from './constants';\nimport { Altertable, type AltertableConfig } from './core';\nimport { safelyRunOnBrowser } from './lib/safelyRunOnBrowser';\n\nexport type { Altertable, AltertableConfig };\nexport { TrackingConsent };\n\ndeclare global {\n  interface Window {\n    Altertable: Altertable | Array<Array<unknown>> | undefined;\n  }\n}\n\nexport const altertable = new Altertable();\n\nsafelyRunOnBrowser(({ window }) => {\n  const stub = window.Altertable;\n  if (stub && Array.isArray(stub)) {\n    for (const item of stub) {\n      const method = item[0];\n      const args = item.slice(1);\n      (altertable[method as keyof Altertable] as any)(...args);\n    }\n  }\n\n  window.Altertable = altertable;\n});\n"],"mappings":";AAAO,SAASA,EAAiBC,EAAgBC,EAAmB,CAClE,MAAO,IAAIC,IACF,CAACF,EAAQ,GAAGE,CAAK,EAAE,KAAKD,CAAS,CAE5C,CCFA,IAAME,GAAqB,OACdC,EAAaC,EAAiBF,GAAoB,GAAG,EACrDG,EAAmBF,EAAW,OAAO,EAErCG,EAAoB,UACpBC,GAAsB,YACtBC,GAAmB,SAE1BC,GAAe,IAAQ,GAChBC,GAA2B,IAC3BC,GAA6B,GAAKF,GAClCG,EAAiB,IACjBC,GAAqB,IAErBC,GAAiB,YAEjBC,GAAe,OACfC,GAAuB,eACvBC,GAAmB,WACnBC,GAAmB,WACnBC,EAAe,OACfC,GAAoB,YA4BpBC,EAAkB,CAC7B,OAAQ,SACR,UAAW,YACX,QAAS,UACT,QAAS,SACX,EAKaC,EAAoB,CAC/B,eACA,YACA,cACA,aACA,QACA,QACA,KACA,oBACA,OACA,YACA,UACA,OACA,aACA,SACF,EACaC,EAAmC,IAAI,IAAI,CACtD,kBACA,IACA,MACA,OACA,OACA,MACF,CAAC,ECvEM,IAAMC,EAAN,cAA8B,KAAM,CACzC,YAAYC,EAAiB,CAC3B,MAAMA,CAAO,EACb,KAAK,KAAO,iBACd,CACF,EAKaC,EAAN,cAAuBF,CAAgB,CAC5C,YACSG,EACAC,EACAC,EACAC,EACAC,EAKP,CACA,MAAM,QAAQJ,CAAM,KAAKC,CAAU,GAAGC,EAAY,KAAKA,CAAS,IAAM,EAAE,EAAE,EAVnE,YAAAF,EACA,gBAAAC,EACA,eAAAC,EACA,aAAAC,EACA,oBAAAC,EAOP,KAAK,KAAO,UACd,CACF,EAKaC,EAAN,cAA2BR,CAAgB,CAChD,YACEC,EACOQ,EACP,CACA,MAAMR,CAAO,EAFN,WAAAQ,EAGP,KAAK,KAAO,cACd,CACF,EAEO,SAASC,GAAkBC,EAA0C,CAC1E,OAAOA,aAAiBX,CAC1B,CAEO,SAASY,GAAWD,EAAmC,CAC5D,OAAOA,aAAiBT,CAC1B,CAEO,SAASW,GAAeF,EAAuC,CACpE,OAAOA,aAAiBH,CAC1B,CCvDO,SAASM,EACdC,EACAC,EACmB,CACnB,GAAI,CAAAD,EAIJ,MAAM,IAAIE,EACR,gBAAgB,OAAOD,GAAY,WAAaA,EAAQ,EAAIA,CAAO,EACrE,CACF,CAEA,IAAMC,EAAN,MAAMC,UAAuB,KAAM,CACjC,YAAYF,EAAiB,CAC3B,MAAMA,CAAO,EACb,OAAO,eAAe,KAAME,EAAe,SAAS,CACtD,CACF,EC1BO,SAASC,GAAaC,EAAe,GAAI,CAC9C,MAAO,kCAAkCA,CAAI,EAC/C,CCSO,SAASC,GAAaC,EAAgB,CAC3C,MAAO,CACL,IAAK,IAAIC,IAAoB,CAC3B,QAAQ,IAAI,IAAID,CAAM,IAAK,GAAGC,CAAI,CACpC,EACA,UAAW,IAAM,CACf,IAAMC,EAAS,gDACWC,EAAY,QAAQD,CAAM,IAGlDC,EAAY,QAAQD,CAAM,EAAI,GAC9B,QAAQ,IAAIA,EAAQ,iBAAiB,EAEzC,EACA,SAAU,CACRE,EACA,CAAE,gBAAAC,CAAgB,IACf,CACH,GAAM,CAACC,EAAiBC,CAAe,EAAIC,EACzCJ,EAAQ,QAAU,YAAc,OAAS,OAC3C,EACM,CAACK,EAAiBC,CAAe,EAAIC,GACzCP,EAAQ,QAAU,YACd,OAAOA,EAAQ,WAAWQ,CAAY,CAAC,EACvCR,EAAQ,KACd,EACM,CAACS,EAAuBC,CAAqB,EACjDC,EAA8BX,EAAQ,WAAW,EAC7C,CAACY,EAAgBC,CAAc,EAAIC,GACvCd,EAAQ,SACV,EACM,CAACe,EAAmBC,CAAiB,EACzCC,EAAuBhB,CAAe,EAExC,QAAQ,eACN,IAAIL,CAAM,OAAOM,CAAe,MAAMG,CAAe,OAAOI,CAAqB,OAAOG,CAAc,MAAMG,CAAiB,GAC7HZ,EACAG,EACAI,EACAG,EACAG,CACF,EAEA,GAAM,CAACE,EAAWC,CAAc,EAAIC,EAAwB,SAAS,EAC/D,CAACC,EAAgBC,CAAc,EAAIC,EACvCvB,EAAQ,aAAe,SACzB,EACM,CAACwB,GAAgBC,EAAmB,EACxCL,EAAwB,cAAc,EAClC,CAACM,GAAqBC,EAAmB,EAAIJ,EACjDvB,EAAQ,cAAgB,SAC1B,EACM,CAAC4B,GAAcC,EAAiB,EACpCT,EAAwB,YAAY,EAChC,CAACU,GAAmBC,EAAiB,EAAIR,EAC7CvB,EAAQ,YAAc,SACxB,EAEA,QAAQ,IACN,KAAKkB,CAAS,MAAMG,CAAc,GAClCF,EACAG,CACF,EACA,QAAQ,IACN,KAAKE,EAAc,MAAME,EAAmB,GAC5CD,GACAE,EACF,EACA,QAAQ,IACN,KAAKC,EAAY,MAAME,EAAiB,GACxCD,GACAE,EACF,EACA,QAAQ,MAAM/B,EAAQ,UAAU,EAChC,QAAQ,SAAS,CACnB,EACA,YAAa,CACXA,EACA,CAAE,gBAAAC,CAAgB,IACf,CACH,GAAM,CAACC,EAAiBC,CAAe,EACrCC,EAAwB,UAAU,EAC9B,CAACK,EAAuBC,CAAqB,EACjDC,EAA8BX,EAAQ,WAAW,EAC7C,CAACe,EAAmBC,CAAiB,EACzCC,EAAuBhB,CAAe,EAExC,QAAQ,eACN,IAAIL,CAAM,OAAOM,CAAe,MAAMF,EAAQ,WAAW,OAAOS,CAAqB,OAAOM,CAAiB,GAC7GZ,EACA,oBACAO,EACAM,CACF,EAEA,GAAM,CAACgB,EAAiBC,CAAoB,EAC1Cb,EAAwB,aAAa,EACjC,CAACc,EAAsBC,CAAoB,EAAIZ,EACnDvB,EAAQ,aAAe,SACzB,EACM,CAACwB,EAAgBC,CAAmB,EACxCL,EAAwB,cAAc,EAClC,CAACgB,EAAoBT,CAAmB,EAAIJ,EAChDvB,EAAQ,cAAgB,SAC1B,EAEA,QAAQ,IACN,KAAKgC,CAAe,MAAME,CAAoB,GAC9CD,EACAE,CACF,EACA,QAAQ,IACN,KAAKX,CAAc,MAAMY,CAAkB,GAC3CX,EACAE,CACF,EACA,QAAQ,MAAM3B,EAAQ,MAAM,EAC5B,QAAQ,SAAS,CACnB,EACA,SAAU,CACRA,EACA,CAAE,gBAAAC,CAAgB,IACf,CACH,GAAM,CAACC,EAAiBC,CAAe,EACrCC,EAAwB,OAAO,EAC3B,CAACK,EAAuBC,CAAqB,EACjDC,EAA8BX,EAAQ,WAAW,EAC7C,CAACe,EAAmBC,CAAiB,EACzCC,EAAuBhB,CAAe,EAExC,QAAQ,eACN,IAAIL,CAAM,OAAOM,CAAe,MAAMF,EAAQ,WAAW,OAAOS,CAAqB,OAAOM,CAAiB,GAC7GZ,EACA,oBACAO,EACAM,CACF,EAEA,GAAM,CAACgB,EAAiBC,CAAoB,EAC1Cb,EAAwB,aAAa,EACjC,CAACc,EAAsBC,CAAoB,EAAIZ,EACnDvB,EAAQ,aAAe,SACzB,EAEM,CAACqC,EAAgBC,CAAmB,EACxClB,EAAwB,aAAa,EACjC,CAACmB,EAAqBC,CAAmB,EAAIjB,EACjDvB,EAAQ,aAAe,SACzB,EAEA,QAAQ,IACN,KAAKgC,CAAe,MAAME,CAAoB,GAC9CD,EACAE,CACF,EACA,QAAQ,IACN,KAAKE,CAAc,MAAME,CAAmB,GAC5CD,EACAE,CACF,EACA,QAAQ,SAAS,CACnB,EACA,KAAM,IAAI3C,IAAoB,CAC5B,QAAQ,KAAK,IAAID,CAAM,IAAK,GAAGC,CAAI,CACrC,EACA,QAAS,CAAC4C,KAAoB5C,IAAoB,CAE9C,OAMF,GAAI,CAAC6C,EAAmB,CACtB3C,EAAY,QAAQ4C,CAAgB,EAAI,GACxC,IAAMC,EAAU,IAAIhD,CAAM,KAAK+C,CAAgB,GAE/C,QAAQ,KAAKC,EAAS,GAAG/C,CAAI,EAE7B,GAAI,CAMF,MAAM,IAAI,MAAM+C,CAAO,CACzB,MAAgB,CAEhB,CACF,CACF,EACA,MAAO,IAAI/C,IAAoB,CAC7B,QAAQ,MAAM,IAAID,CAAM,IAAK,GAAGC,CAAI,CACtC,CACF,CACF,CAEO,IAAME,EAAoD,CAC/D,QAAS,CAAC,CACZ,EAEA,SAAS8C,GAAgBC,EAAmB,CAC1C,OAAO,IAAI,KAAKA,CAAS,EAAE,mBAAmB,QAAS,CACrD,OAAQ,GACR,KAAM,UACN,OAAQ,UACR,OAAQ,SACV,CAAC,CACH,CAEA,SAASC,GAAmBC,EAAe,CACzC,OAAQA,EAAO,CACb,IAAK,OACH,MAAO,UACT,IAAK,WACH,MAAO,UACT,IAAK,QACH,MAAO,UACT,QACE,MAAO,SACX,CACF,CAEA,SAAS5C,EAAwB4C,EAAiC,CAChE,MAAO,CACLA,EACA,eAAeD,GAAmBC,CAAK,CAAC,2EAC1C,CACF,CAEA,SAASzC,GAAwByC,EAAiC,CAEhE,MAAO,CADOA,IAAU,YAAc,cAAgBA,EACvC,mBAAmB,CACpC,CAEA,SAASrC,EAA8BsC,EAAiC,CACtE,MAAO,CAACA,EAAO,UAAUC,GAAoBD,CAAK,CAAC,qBAAqB,CAC1E,CAEA,SAASC,GAAoBC,EAAqB,CAKhD,OAJqBA,EAAY,kBAAkB,EAAE,WAAW,MAAM,EAClE,aACAA,EAEkB,CACpB,IAAK,aACH,MAAO,UACT,QACE,MAAO,SACX,CACF,CAEA,SAASrC,GAAuBmC,EAAiC,CAC/D,MAAO,CAACJ,GAAgBI,CAAK,EAAG,mCAAmC,CACrE,CAEA,SAAS7B,EAAwB6B,EAAiC,CAChE,MAAO,CAACA,EAAO,kCAAkC,CACnD,CAEA,SAAS1B,EAAmB0B,EAAiC,CAC3D,MAAO,CACLA,EACA,qKACF,CACF,CAEA,SAAShC,EACPhB,EACkB,CAClB,OAAQA,EAAiB,CACvB,KAAKmD,EAAgB,QACnB,MAAO,CAAC,GAAI,EAAE,EAChB,KAAKA,EAAgB,OACnB,MAAO,CACL,SACA,+GACF,EACF,KAAKA,EAAgB,QACrB,KAAKA,EAAgB,UACnB,MAAO,CACL,UACA,+GACF,EACF,QACE,MAAO,CACL,UACA,+GACF,CACJ,CACF,CCxSO,SAASC,EAASC,EAA+B,CACtD,GAAI,CACF,IAAMC,EAAY,IAAI,IAAID,CAAG,EAC7B,MAAO,CACL,QAAS,GAAGC,EAAU,MAAM,GAAGA,EAAU,QAAQ,GACjD,aAAc,OAAO,YAAYA,EAAU,YAAY,CACzD,CACF,MAAQ,CACN,OAAO,IACT,CACF,CCVO,IAAMC,EAAN,KAAmB,CAChB,OAAkB,CAAC,EACnB,SACA,cAER,YAAYC,EAA8B,CACxC,KAAK,SAAWA,EAAQ,SACxB,KAAK,cAAgBA,EAAQ,YAC/B,CAEA,QAAQC,EAAsB,CAC5B,GAAI,KAAK,OAAO,QAAU,KAAK,SAAU,CACvC,IAAMC,EAAU,KAAK,OAAO,MAAM,EAC9BA,GACF,KAAK,gBAAgBA,CAAO,CAEhC,CACA,KAAK,OAAO,KAAKD,CAAO,CAC1B,CAEA,OAAiB,CACf,IAAME,EAAQ,CAAC,GAAG,KAAK,MAAM,EAC7B,YAAK,OAAS,CAAC,EACRA,CACT,CAEA,OAAc,CACZ,KAAK,OAAS,CAAC,CACjB,CAGA,SAAkB,CAChB,OAAO,KAAK,OAAO,MACrB,CAGA,QAA2B,CACzB,OAAO,KAAK,MACd,CACF,EC5CO,SAASC,IAA6B,CAC3C,OACE,OAAO,OAAW,KAClB,OAAO,UAAc,KACrB,OAAO,UAAU,YAAe,UAEpC,CCIO,IAAMC,EAAN,KAA+C,CACnC,QAEjB,YAAYC,EAAyB,CACnC,KAAK,QAAUA,CACjB,CAEQ,cAAcC,EAAsB,CAC1C,MAAO,GAAG,KAAK,QAAQ,OAAO,GAAGA,CAAI,WAAW,mBAC9C,KAAK,QAAQ,MACf,CAAC,EACH,CAEA,MAAM,KAAKA,EAAcC,EAAkC,CACzD,OAAIC,GAAkB,EACb,KAAK,gBAAgBF,EAAMC,CAAO,EAGpC,KAAK,eAAeD,EAAMC,CAAO,CAC1C,CAEA,MAAc,gBACZD,EACAC,EACe,CACf,IAAME,EAAM,KAAK,cAAcH,CAAI,EAC7BI,EAAO,IAAI,KAAK,CAAC,KAAK,UAAUH,CAAO,CAAC,EAAG,CAC/C,KAAM,kBACR,CAAC,EAED,GAAI,CAEF,GAAI,CADY,UAAU,WAAWE,EAAKC,CAAI,EAE5C,OAAO,KAAK,eAAeJ,EAAMC,CAAO,CAE5C,MAAgB,CACd,OAAO,KAAK,eAAeD,EAAMC,CAAO,CAC1C,CACF,CAEA,MAAc,eAAeD,EAAcC,EAAkC,CAC3E,IAAME,EAAM,KAAK,cAAcH,CAAI,EAC7BK,EAAa,IAAI,gBACjBC,EAAY,WAChB,IAAMD,EAAW,MAAM,EACvB,KAAK,QAAQ,cACf,EAEA,GAAI,CACF,IAAME,EAAW,MAAM,MAAMJ,EAAK,CAChC,OAAQ,OACR,QAAS,CACP,eAAgB,kBAClB,EACA,KAAM,KAAK,UAAUF,CAAO,EAC5B,UAAW,GACX,OAAQI,EAAW,MACrB,CAAC,EAED,GAAI,CAACE,EAAS,GAAI,CAChB,IAAIC,EAEJ,GAAI,CACFA,EAAgB,MAAMD,EAAS,KAAK,CACtC,MAAQ,CAER,CAEA,MAAM,IAAIE,EACRF,EAAS,OACTA,EAAS,WACTC,GAAe,WACfA,EACA,CACE,IAAAL,EACA,OAAQ,OACR,QAAAF,CACF,CACF,CACF,CACF,OAASS,EAAO,CACd,MAAIA,aAAiBD,EACbC,EAGF,IAAIC,EACRD,aAAiB,MAAQA,EAAM,QAAU,yBACzCA,CACF,CACF,QAAE,CACA,aAAaJ,CAAS,CACxB,CACF,CACF,ECpGO,SAASM,EACdC,EAEAC,EAA0B,IAAG,GACpB,CACT,OAAI,OAAO,OAAW,IACbA,EAAS,EAGXD,EAAS,CAAE,MAAO,CAAC,CAC5B,CCTO,SAASE,GAAgC,CAC9C,OAAOC,EACL,CAAC,CAAE,OAAAC,CAAO,IAAM,GAAGA,EAAO,UAAU,IAAIA,EAAO,WAAW,GAC1D,IAAM,IACR,CACF,CCWO,SAASC,GAAwC,CACtD,MAAO,CACL,UAAW,IAAI,KAAK,EAAE,YAAY,EAClC,IAAKC,EACH,CAAC,CAAE,OAAAC,CAAO,IAAMA,EAAO,SAAS,MAAQ,KACxC,IAAM,IACR,EACA,SAAUD,EACR,CAAC,CAAE,OAAAC,CAAO,IAAMA,EAAO,SAAS,UAAY,KAC5C,IAAM,IACR,EACA,SAAUC,EAAY,CACxB,CACF,CCjCO,SAASC,EAA6BC,EAA6B,CACxE,GACE,OAAO,WAAW,OAAW,KAC7B,OAAO,WAAW,OAAO,YAAe,WAExC,GAAI,CACF,MAAO,GAAGA,CAAM,IAAI,OAAO,WAAW,CAAC,EACzC,MAAQ,CAER,CAEF,MAAO,GAAGA,CAAM,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,CAAC,CAAC,EAC7D,CCgBO,IAAMC,EAAN,KAAqB,CAClB,wBACA,QACA,aACA,SACA,YAER,YAAYC,EAKT,CACD,KAAK,SAAWA,EAAQ,QACxB,KAAK,YAAcA,EAAQ,WAC3B,KAAK,QAAUA,EAAQ,OACvB,KAAK,wBACHA,EAAQ,wBAA0BC,EAAgB,QACpD,KAAK,aAAe,KAAK,0BAA0B,CACrD,CAEA,MAAa,CACX,IAAMC,EAAa,KAAK,SAAS,QAAQ,KAAK,WAAW,EAEzD,GAAI,CAACA,EAAY,CACf,KAAK,aAAe,KAAK,0BAA0B,EACnD,KAAK,kBAAkB,EACvB,MACF,CAEA,GAAI,CACF,IAAMC,EAAa,KAAK,MAAMD,CAAU,EAExC,KAAK,aAAe,CAClB,SAAUC,EAAW,UAAY,KAAK,kBAAkB,EACxD,WAAYA,EAAW,YAAc,KAAK,qBAAqB,EAC/D,UAAWA,EAAW,WAAa,KAAK,mBAAmB,EAC3D,YAAaA,EAAW,aAAe,KACvC,YAAaA,EAAW,aAAe,KACvC,gBAAiBC,GAAuBD,EAAW,eAAe,EAC9DA,EAAW,gBACX,KAAK,uBACX,CACF,MAAgB,CACd,KAAK,QAAQ,QACX,uDACF,EACA,KAAK,aAAe,KAAK,0BAA0B,CACrD,CAEA,KAAK,kBAAkB,CACzB,CAEA,cAA0B,CACxB,OAAO,KAAK,aAAa,SAC3B,CAEA,aAAwB,CACtB,OAAO,KAAK,aAAa,QAC3B,CAEA,eAA4B,CAC1B,OAAO,KAAK,aAAa,UAC3B,CAEA,gBAAqC,CACnC,OAAO,KAAK,aAAa,WAC3B,CAkBA,cAAwB,CACtB,MAAO,EAAQ,KAAK,aAAa,WACnC,CAEA,gBAAgC,CAC9B,OAAO,KAAK,aAAa,WAC3B,CAEA,oBAA0C,CACxC,OAAO,KAAK,aAAa,eAC3B,CAEA,SAASE,EAAsB,CAC7B,KAAK,aAAa,YAAc,KAAK,aAAa,WAClD,KAAK,aAAa,WAAaA,EAC/B,KAAK,kBAAkB,CACzB,CAEA,mBAAmBC,EAAoC,CACrD,KAAK,aAAa,gBAAkBA,EACpC,KAAK,kBAAkB,CACzB,CAEA,kBAAkBC,EAAyB,CACzC,KAAK,aAAa,YAAcA,EAChC,KAAK,kBAAkB,CACzB,CAEA,sBAAgC,CAG9B,OAFoB,KAAK,oBAAoB,GAG3C,KAAK,cAAc,EACnB,KAAK,kBAAkB,EAChB,IAGF,EACT,CAEA,MAAM,CACJ,cAAAC,EAAgB,GAChB,qBAAAC,EAAuB,EACzB,EAGI,CAAC,EAAS,CACRD,IACF,KAAK,aAAa,SAAW,KAAK,kBAAkB,GAGlDC,IACF,KAAK,aAAa,gBAAkB,KAAK,yBAG3C,KAAK,aAAa,UAAY,KAAK,mBAAmB,EACtD,KAAK,aAAa,YAAc,KAChC,KAAK,aAAa,WAAa,KAAK,qBAAqB,EACzD,KAAK,aAAa,YAAc,KAChC,KAAK,kBAAkB,CACzB,CAEQ,2BAAyC,CAC/C,MAAO,CACL,YAAa,KACb,SAAU,KAAK,kBAAkB,EACjC,WAAY,KAAK,qBAAqB,EACtC,YAAa,KACb,UAAW,KAAK,mBAAmB,EACnC,gBAAiB,KAAK,uBACxB,CACF,CAEQ,oBAAgC,CACtC,OAAOC,EAAWC,CAAiB,CACrC,CAEQ,mBAA8B,CACpC,OAAOD,EAAWE,EAAgB,CACpC,CAEQ,sBAAoC,CAC1C,OAAOF,EAAWG,EAAmB,CACvC,CAEQ,qBAA+B,CACrC,GAAM,CAAE,YAAAC,CAAY,EAAI,KAAK,aAE7B,GAAI,CAACA,EACH,MAAO,GAGT,IAAMC,EAAM,IAAI,KAAK,EAAE,QAAQ,EACzBC,EAAgB,IAAI,KAAKF,CAAW,EAAE,QAAQ,EAGpD,OAF2BC,EAAMC,EAELC,EAC9B,CAEQ,eAAsB,CAC5B,KAAK,aAAa,UAAY,KAAK,mBAAmB,EACtD,KAAK,aAAa,YAAc,IAClC,CAEQ,mBAA0B,CAChC,GAAI,CACF,KAAK,SAAS,QACZ,KAAK,YACL,KAAK,UAAU,KAAK,YAAY,CAClC,CACF,MAAgB,CACd,KAAK,QAAQ,QAAQ,4CAA4C,CACnE,CACF,CACF,EAEA,SAASb,GAAuBc,EAA8C,CAC5E,OACE,OAAOA,GAAU,UACjB,OAAO,OAAOjB,CAAe,EAAE,SAASiB,CAA4B,CAExE,CCzNA,SAASC,EACPC,EACAC,EACAC,EACM,CACN,QAAWC,KAAOD,EAAM,CACtB,IAAME,EAAQH,EAAY,QAAQE,CAAG,EACjCC,IAAU,OACZJ,EAAU,QAAQG,EAAKC,CAAK,EAC5BH,EAAY,WAAWE,CAAG,EAE9B,CACF,CAEA,IAAME,EAAN,KAAwC,CAC9B,MAAgC,CAAC,EACzC,QAAQF,EAA4B,CAClC,OAAO,KAAK,MAAMA,CAAG,GAAK,IAC5B,CACA,QAAQA,EAAaC,EAAe,CAClC,KAAK,MAAMD,CAAG,EAAIC,CACpB,CACA,WAAWD,EAAa,CACtB,OAAO,KAAK,MAAMA,CAAG,CACvB,CACA,QAAQF,EAAyBC,EAAgB,CAC/CH,EAAY,KAAME,EAAaC,CAAI,CACrC,CACF,EAEMI,EAAN,KAAwC,CACtC,QAAQH,EAA4B,CAClC,OAAOI,EACL,CAAC,CAAE,OAAAC,CAAO,IAAM,CACd,IAAMC,EAAQD,EAAO,SAAS,OAAO,MACnC,IAAI,OAAO,QAAUL,EAAM,UAAU,CACvC,EACA,OAAOM,EAAQ,mBAAmBA,EAAM,CAAC,CAAC,EAAI,IAChD,EACA,IAAM,IACR,CACF,CACA,QAAQN,EAAaC,EAAe,CAClCG,EAAmB,CAAC,CAAE,OAAAC,CAAO,IAAM,CACjCA,EAAO,SAAS,OAAS,GAAGL,CAAG,IAAI,mBAAmBC,CAAK,CAAC,WAC9D,CAAC,CACH,CACA,WAAWD,EAAa,CACtBI,EAAmB,CAAC,CAAE,OAAAC,CAAO,IAAM,CACjCA,EAAO,SAAS,OAAS,GAAGL,CAAG,uBACjC,CAAC,CACH,CACA,QAAQF,EAAyBC,EAAgB,CAC/CH,EAAY,KAAME,EAAaC,CAAI,CACrC,CACF,EAEMQ,EAAN,KAA4C,CAC1C,YAAoBC,EAA4C,CAA5C,aAAAA,CAA6C,CACjE,QAAQR,EAA4B,CAClC,OAAOI,EACL,CAAC,CAAE,OAAAC,CAAO,IAAM,CACd,GAAI,CACF,OAAOA,EAAO,KAAK,OAAO,EAAE,QAAQL,CAAG,CACzC,MAAQ,CACN,OAAO,IACT,CACF,EACA,IAAM,IACR,CACF,CACA,QAAQA,EAAaC,EAAe,CAClCG,EAAmB,CAAC,CAAE,OAAAC,CAAO,IAAM,CACjC,GAAI,CACFA,EAAO,KAAK,OAAO,EAAE,QAAQL,EAAKC,CAAK,CACzC,MAAQ,CAER,CACF,CAAC,CACH,CACA,WAAWD,EAAa,CACtBI,EAAmB,CAAC,CAAE,OAAAC,CAAO,IAAM,CACjC,GAAI,CACFA,EAAO,KAAK,OAAO,EAAE,WAAWL,CAAG,CACrC,MAAQ,CAER,CACF,CAAC,CACH,CACA,QAAQF,EAAyBC,EAAgB,CAC/CH,EAAY,KAAME,EAAaC,CAAI,CACrC,CACF,EAEMU,EAAN,KAAiD,CACvC,WAAa,IAAIF,EAAgB,cAAc,EAC/C,YAAc,IAAIJ,EAC1B,QAAQH,EAA4B,CAClC,OAAO,KAAK,WAAW,QAAQA,CAAG,GAAK,KAAK,YAAY,QAAQA,CAAG,CACrE,CACA,QAAQA,EAAaC,EAAe,CAClC,KAAK,WAAW,QAAQD,EAAKC,CAAK,EAClC,KAAK,YAAY,QAAQD,EAAKC,CAAK,CACrC,CACA,WAAWD,EAAa,CACtB,KAAK,WAAW,WAAWA,CAAG,EAC9B,KAAK,YAAY,WAAWA,CAAG,CACjC,CACA,QAAQF,EAAyBC,EAAgB,CAE/C,QAAWC,KAAOD,EAAM,CACtB,IAAME,EAAQH,EAAY,QAAQE,CAAG,EACjCC,IAAU,OACZ,KAAK,WAAW,QAAQD,EAAKC,CAAK,EAClC,KAAK,YAAY,QAAQD,EAAKC,CAAK,EAEvC,CAEA,QAAWD,KAAOD,EAChBD,EAAY,WAAWE,CAAG,CAE9B,CACF,EAEA,SAASU,EACPC,EACA,CACA,OAAOP,EACL,CAAC,CAAE,OAAAC,CAAO,IAAM,CACd,GAAI,CACF,GAAIM,IAAgB,SAAU,CAC5BN,EAAO,SAAS,OAAS,GAAGO,CAAgB,KAC5C,IAAMC,EACJR,EAAO,SAAS,OAAO,QAAQ,GAAGO,CAAgB,GAAG,IAAM,GAC7D,OAAAP,EAAO,SAAS,OAAS,GAAGO,CAAgB,eACrCC,CACT,KACE,QAAAR,EAAOM,CAAW,EAAE,QAAQC,EAAkB,GAAG,EACjDP,EAAOM,CAAW,EAAE,WAAWC,CAAgB,EACxC,EAEX,MAAQ,CACN,MAAO,EACT,CACF,EACA,IAAM,EACR,CACF,CAEO,SAASE,EACdC,EACAC,EACY,CACZ,GAAM,CAAE,WAAAC,CAAW,EAAID,EAEvB,OAAQD,EAAM,CACZ,IAAK,eACH,OAAIL,EAAmB,cAAc,EAC5B,IAAIH,EAAgB,cAAc,GAE3CU,EACE,kEACF,EACOH,EAAc,sBAAuBE,CAAM,GAGpD,IAAK,sBAAuB,CAC1B,IAAME,EAAwBR,EAAmB,cAAc,EACzDS,EAAkBT,EAAmB,QAAQ,EAEnD,OAAIQ,GAAyBC,EACpB,IAAIV,EACFU,GACTF,EACE,kEACF,EACO,IAAId,GACFe,GACTD,EAAW,qDAAqD,EACzD,IAAIV,EAAgB,cAAc,IAEzCU,EACE,oEACF,EACO,IAAIf,EAEf,CAEA,IAAK,iBACH,OAAIQ,EAAmB,gBAAgB,EAC9B,IAAIH,EAAgB,gBAAgB,GAE7CU,EAAW,uDAAuD,EAC3D,IAAIf,GAGb,IAAK,SACH,OAAIQ,EAAmB,QAAQ,EACtB,IAAIP,GAEbc,EAAW,+CAA+C,EACnD,IAAIf,GAGb,IAAK,SACH,OAAO,IAAIA,EAGb,QACE,MAAM,IAAI,MACR,0BAA0Ba,CAAI,wFAChC,CAEJ,CACF,CClOA,IAAMK,GAA0B,CAC9B,GAAGC,EACH,GAAGC,CACL,EACG,IAAIC,GAAM,MAAMA,CAAE,GAAG,EACrB,KAAK;AAAA,CAAI,EACNC,GAA0B;AAAA,EAAkCJ,EAAuB,GAElF,SAASK,EAAeC,EAAsB,CACnD,GAAI,CAACA,GAAUA,EAAO,KAAK,IAAM,GAC/B,MAAM,IAAI,MAAM,qDAAqD,EAOvE,GAJiCL,EAAkB,KACjDM,GAAaD,EAAO,YAAY,IAAMC,EAAU,YAAY,CAC9D,EAGE,MAAM,IAAI,MACR,YAAYD,CAAM;AAAA;AAAA,EAChBF,EACJ,EAKF,GAF+BF,EAAiC,IAAII,CAAM,EAGxE,MAAM,IAAI,MACR,YAAYA,CAAM;AAAA;AAAA,EAChBF,EACJ,CAEJ,CCkDA,IAAMI,GAAmC,CACvC,YAAa,GACb,QAAS,4BACT,MAAO,GACP,YAAa,aACb,YAAa,sBACb,QAAS,OACT,gBAAiBC,EAAgB,OACnC,EAEaC,EAAN,KAAiB,CACd,oBACA,QACA,OACA,eAAiB,GACjB,SACA,QAAUC,GAAa,YAAY,EACnC,UACA,WACA,gBACA,SACA,YAER,aAAc,CACZ,KAAK,SAAW,KAChB,KAAK,UAAY,KACjB,KAAK,OAAS,IAAIC,EAAiB,CACjC,SAAUC,EACV,aAAcC,GAAe,CAC3B,IAAMC,EACJD,EAAY,OAAS,UACjBA,EAAY,OACZA,EAAY,UAClB,KAAK,QAAQ,QACX,kBAAkBD,CAAc,qBAAqBE,CAAM,QAC7D,CACF,CACF,CAAC,CACH,CAgBA,KAAKC,EAAgBC,EAA2B,CAAC,EAAG,CAClDC,EAAUF,EAAQ,iBAAiB,EACnC,KAAK,QAAU,CAAE,GAAGR,GAAgB,GAAGS,CAAO,EAC9C,KAAK,YAAcE,EAAWH,EAAQ,KAAK,QAAQ,WAAW,EAC9D,KAAK,UAAYI,EACf,CAAC,CAAE,OAAAC,CAAO,IAAMA,EAAO,SAAS,UAAY,KAC5C,IAAM,IACR,EACA,KAAK,SAAWD,EACd,CAAC,CAAE,OAAAC,CAAO,IAAMA,EAAO,SAAS,MAAQ,KACxC,IAAM,IACR,EACA,KAAK,SAAWC,EAAc,KAAK,QAAQ,YAAa,CACtD,WAAYC,GAAW,KAAK,QAAQ,KAAKA,CAAO,CAClD,CAAC,EACD,KAAK,WAAa,IAAIC,EAAU,CAC9B,QAAS,KAAK,QAAQ,QACtB,OAAAR,EACA,eAAgBS,EAClB,CAAC,EACD,KAAK,gBAAkB,IAAIC,EAAe,CACxC,QAAS,KAAK,SACd,WAAY,KAAK,YACjB,OAAQ,KAAK,QACb,uBAAwB,KAAK,QAAQ,eACvC,CAAC,EACD,KAAK,gBAAgB,KAAK,EAE1B,KAAK,eAAiB,GAElB,KAAK,QAAQ,OACf,KAAK,QAAQ,UAAU,EAGzB,IAAMC,EAAkB,KAAK,gBAAgB,mBAAmB,EAChE,OAAIA,IAAoBlB,EAAgB,QACtC,KAAK,YAAY,EACRkB,IAAoBlB,EAAgB,QAC7C,KAAK,OAAO,MAAM,EAGpB,KAAK,yBAAyB,KAAK,QAAQ,WAAW,EAE/C,IAAM,CACX,KAAK,sBAAsB,CAC7B,CACF,CAcA,UAAUmB,EAAoC,CAa5C,GAZAV,EACE,KAAK,eACL,gEACF,EAGEU,EAAQ,cAAgB,QACxBA,EAAQ,cAAgB,KAAK,QAAQ,aAErC,KAAK,yBAAyBA,EAAQ,WAAW,EAIjDA,EAAQ,cAAgB,QACxBA,EAAQ,cAAgB,KAAK,QAAQ,YACrC,CACA,IAAMC,EAAkB,KAAK,SAC7B,KAAK,SAAWP,EAAcM,EAAQ,YAAa,CACjD,WAAYL,GAAW,KAAK,QAAQ,KAAKA,CAAO,CAClD,CAAC,EACD,KAAK,SAAS,QAAQM,EAAiB,CAAC,KAAK,WAAW,CAAC,CAC3D,CAEA,IAAMC,EAAyB,KAAK,gBAAgB,mBAAmB,EAErEF,EAAQ,kBAAoB,QAC5BA,EAAQ,kBAAoBE,IAE5B,KAAK,gBAAgB,mBAAmBF,EAAQ,eAAe,EAG7DE,IAA2BrB,EAAgB,SAC3CmB,EAAQ,kBAAoBnB,EAAgB,QAE5C,KAAK,YAAY,EACRmB,EAAQ,kBAAoBnB,EAAgB,QACrD,KAAK,OAAO,MAAM,GAItB,KAAK,QAAU,CAAE,GAAG,KAAK,QAAS,GAAGmB,CAAQ,CAC/C,CAEQ,yBAAyBG,EAA4B,CAG3D,GAFA,KAAK,sBAAsB,EAEvBA,EAAmB,CACjB,KAAK,UACP,KAAK,KAAK,KAAK,QAAQ,EAGzB,IAAMC,EAAkB,KAAK,iBAAiB,KAAK,IAAI,EACjDC,EAAa,YAAYD,EAAiBE,EAAwB,EAExEd,EAAmB,CAAC,CAAE,OAAAC,CAAO,IAAM,CACjCA,EAAO,iBAAiB,WAAYW,CAAe,EACnDX,EAAO,iBAAiB,aAAcW,CAAe,CACvD,CAAC,EAED,KAAK,oBAAsB,IAAM,CAC/B,cAAcC,CAAU,EACxBb,EAAmB,CAAC,CAAE,OAAAC,CAAO,IAAM,CACjCA,EAAO,oBAAoB,WAAYW,CAAe,EACtDX,EAAO,oBAAoB,aAAcW,CAAe,CAC1D,CAAC,CACH,CACF,MACE,KAAK,oBAAsB,MAE/B,CAuBA,SAASG,EAAoBC,EAAqB,CAAC,EAAG,CACpD,GAAI,CACFC,EAAeF,CAAM,CACvB,OAASG,EAAO,CACd,MAAM,IAAI,MAAM,gBAAgBA,EAAM,OAAO,EAAE,CACjD,CAEA,GAAI,CAAC,KAAK,eAAgB,CACxB,KAAK,OAAO,QAAQ,CAClB,KAAM,UACN,OAAQ,WACR,KAAM,CAACH,EAAQ,CAAE,GAAGC,CAAO,CAAC,CAC9B,CAAC,EACD,MACF,CAEA,KAAK,UAAUD,EAAQ,CAAE,GAAGC,CAAO,CAAC,CACtC,CAEQ,UAAUD,EAAoBC,EAAqB,CAAC,EAAG,CAE3D,KAAK,gBAAgB,aAAa,GAClCD,IAAW,KAAK,gBAAgB,cAAc,IAE9C,KAAK,QAAQ,QACX,SAASA,CAAM,+BAA+B,KAAK,gBAAgB,cAAc,CAAC;AAAA;AAAA,6GAEpF,EACA,KAAK,MAAM,GAGTA,IAAW,KAAK,gBAAgB,cAAc,GAChD,KAAK,gBAAgB,SAASA,CAAM,EAGtC,IAAMI,EAAU,KAAK,YAAY,EAC3BC,EAA2B,CAC/B,YAAaD,EAAQ,YACrB,UAAWA,EAAQ,UACnB,YAAaA,EAAQ,YACrB,OAAAH,EACA,aAAcG,EAAQ,YACxB,EAGA,GAFA,KAAK,cAAc,WAAYC,CAAO,EAElC,KAAK,QAAQ,MAAO,CACtB,IAAMb,EAAkB,KAAK,gBAAgB,mBAAmB,EAChE,KAAK,QAAQ,YAAYa,EAAS,CAAE,gBAAAb,CAAgB,CAAC,CACvD,CACF,CAYA,MAAMc,EAAuB,CAC3B,GAAI,CACFJ,EAAeI,CAAS,CAC1B,OAASH,EAAO,CACd,MAAM,IAAI,MAAM,gBAAgBA,EAAM,OAAO,EAAE,CACjD,CAEA,GAAI,CAAC,KAAK,eAAgB,CACxB,KAAK,OAAO,QAAQ,CAClB,KAAM,UACN,OAAQ,QACR,KAAM,CAACG,CAAS,CAClB,CAAC,EACD,MACF,CAEA,KAAK,OAAOA,CAAS,CACvB,CAEQ,OAAOA,EAAuB,CACpC,IAAMF,EAAU,KAAK,YAAY,EAE3BC,EAAwB,CAC5B,YAAaD,EAAQ,YACrB,UAAWA,EAAQ,UACnB,aAAcA,EAAQ,aACtB,YAAaA,EAAQ,YACrB,YAAaE,CACf,EAIA,GAFA,KAAK,cAAc,QAASD,CAAO,EAE/B,KAAK,QAAQ,MAAO,CACtB,IAAMb,EAAkB,KAAK,gBAAgB,mBAAmB,EAChE,KAAK,QAAQ,SAASa,EAAS,CAAE,gBAAAb,CAAgB,CAAC,CACpD,CACF,CAcA,aAAaS,EAAoB,CAC/B,GAAI,CAAC,KAAK,eAAgB,CACxB,KAAK,OAAO,QAAQ,CAClB,KAAM,UACN,OAAQ,eACR,KAAM,CAAC,CAAE,GAAGA,CAAO,CAAC,CACtB,CAAC,EACD,MACF,CAEA,KAAK,cAAc,CAAE,GAAGA,CAAO,CAAC,CAClC,CAEQ,cAAcA,EAAoB,CACxC,IAAMG,EAAU,KAAK,YAAY,EAEjC,GAAIA,EAAQ,eAAiB,KAAM,CACjC,KAAK,QAAQ,QACX,iEACF,EACA,MACF,CAEA,IAAMC,EAAU,CACd,YAAaD,EAAQ,YACrB,UAAWA,EAAQ,UACnB,YAAaA,EAAQ,YACrB,OAAAH,EACA,aAAcG,EAAQ,aACtB,WAAYA,EAAQ,UACtB,EAGA,GAFA,KAAK,cAAc,WAAYC,CAAO,EAElC,KAAK,QAAQ,MAAO,CACtB,IAAMb,EAAkB,KAAK,gBAAgB,mBAAmB,EAChE,KAAK,QAAQ,YAAYa,EAAS,CAAE,gBAAAb,CAAgB,CAAC,CACvD,CACF,CAgBA,MAAM,CACJ,cAAAe,EAAgB,EAClB,EAGI,CAAC,EAAG,CAEN,KAAK,OAAO,MAAM,EAEb,KAAK,gBAIV,KAAK,gBAAgB,MAAM,CACzB,cAAAA,CACF,CAAC,CACH,CA2BA,KAAKC,EAAa,CAChB,GAAI,CAAC,KAAK,eAAgB,CACxB,KAAK,OAAO,QAAQ,CAClB,KAAM,UACN,OAAQ,OACR,eAAgBC,EAAsB,EACtC,KAAM,CAACD,CAAG,CACZ,CAAC,EACD,MACF,CAEA,KAAK,MAAMA,CAAG,CAChB,CAEQ,MAAMA,EAAaE,EAAiC,CAC1D,IAAMC,EAAYC,EAASJ,CAAG,EACxBK,EAAUF,EAAYA,EAAU,QAAUH,EAE1CM,EAAWJ,GAAgB,UAAYK,EAAY,EACnDC,EAAWN,GAAgB,UAAY,KAAK,UAElD,KAAK,OACHO,GACA,CACE,CAACC,CAAY,EAAGL,EAChB,CAACM,EAAiB,EAAGL,EACrB,CAACM,EAAgB,EAAGJ,EACpB,GAAGL,GAAW,YAChB,EACAD,CACF,CACF,CAiBA,MAAMW,EAAeC,EAA8B,CAAC,EAAG,CACrD,GAAI,CAAC,KAAK,eAAgB,CACxB,KAAK,OAAO,QAAQ,CAClB,KAAM,UACN,OAAQ,QACR,eAAgBb,EAAsB,EACtC,KAAM,CAACY,EAAO,CAAE,GAAGC,CAAW,CAAC,CACjC,CAAC,EACD,MACF,CAEA,KAAK,OAAOD,EAAO,CAAE,GAAGC,CAAW,CAAC,CACtC,CAEQ,OACND,EACAC,EACAZ,EAAiCD,EAAsB,EACvD,CACA,KAAK,gBAAgB,qBAAqB,EAC1C,KAAK,gBAAgB,kBAAkBC,EAAe,SAAS,EAE/D,IAAMN,EAAU,KAAK,YAAY,EAG3B,CAAE,CAACc,CAAY,EAAGK,EAAS,GAAGC,CAAe,EAAIF,EACjDG,EAASF,IAAY,OACrBG,EAAcD,EAAS,KAAOf,EAAe,IAE7CC,EAAYe,EAAcd,EAASc,CAAW,EAAI,KAClDb,EAAUF,EAAYA,EAAU,QAAUe,EAE1CrB,EAAwB,CAC5B,UAAWK,EAAe,UAC1B,MAAAW,EACA,YAAajB,EAAQ,YACrB,UAAWA,EAAQ,UACnB,YAAaA,EAAQ,YACrB,aAAcA,EAAQ,aACtB,WAAYA,EAAQ,WACpB,WAAY,CACV,CAACuB,EAAY,EAAG,4BAChB,CAACC,EAAoB,EAAG,QACxB,CAACC,EAAgB,EAAG,KAAK,QAAQ,QACjC,CAACX,CAAY,EAAGO,EAASF,EAAUV,EAGnC,GAAGW,CACL,CACF,EAIA,GAFA,KAAK,cAAc,QAASnB,CAAO,EAE/B,KAAK,QAAQ,MAAO,CACtB,IAAMb,EAAkB,KAAK,gBAAgB,mBAAmB,EAChE,KAAK,QAAQ,SAASa,EAAS,CAAE,gBAAAb,CAAgB,CAAC,CACpD,CACF,CAgBA,oBAA0C,CACxC,OAAK,KAAK,eAGH,KAAK,gBAAgB,mBAAmB,EAFtClB,EAAgB,OAG3B,CAEQ,aAAc,CACpB,IAAMwD,EAAQ,KAAK,OAAO,MAAM,EAEhC,GAAIA,EAAM,SAAW,EAIrB,CAAI,KAAK,QAAQ,OACf,KAAK,QAAQ,IACX,cAAcA,EAAM,MAAM,WAAWA,EAAM,SAAW,EAAI,OAAS,OAAO,GAC5E,EAGF,QAAWC,KAAQD,EACjB,KAAK,kBAAkBC,CAAI,EAE/B,CAEQ,kBAAkBA,EAAiB,CACzC,GAAIA,EAAK,OAAS,QAAS,CAEzB,KAAK,WAAWA,EAAK,UAAWA,EAAK,OAAO,EAC5C,MACF,CAEA,KAAK,gBAAgBA,CAAI,CAC3B,CAEQ,gBAAgBC,EAAoB,CAC1C,GAAI,CACF,OAAQA,EAAI,OAAQ,CAClB,IAAK,WACH,KAAK,UAAU,GAAGA,EAAI,IAAI,EAC1B,MACF,IAAK,QACH,KAAK,OAAO,GAAGA,EAAI,KAAMA,EAAI,cAAc,EAC3C,MACF,IAAK,OACH,KAAK,MAAM,GAAGA,EAAI,KAAMA,EAAI,cAAc,EAC1C,MACF,IAAK,QACH,KAAK,OAAO,GAAGA,EAAI,IAAI,EACvB,MACF,IAAK,eACH,KAAK,cAAc,GAAGA,EAAI,IAAI,EAC9B,KACJ,CACF,OAAS7B,EAAO,CACd,IAAM8B,EACJ9B,aAAiB,MAAQA,EAAM,QAAU,OAAOA,CAAK,EACvD,KAAK,QAAQ,QACX,4BAA4B6B,EAAI,MAAM;AAAA,EAAgBC,CAAY,EACpE,CACF,CACF,CAEQ,kBAAmB,CACzBhD,EAAmB,CAAC,CAAE,OAAAC,CAAO,IAAM,CACjC,IAAMgD,EAAahD,EAAO,SAAS,KAC/BgD,IAAe,KAAK,WACtB,KAAK,UAAY,KAAK,SACtB,KAAK,SAAWA,EAChB,KAAK,KAAKA,CAAU,EAExB,CAAC,CACH,CAEQ,aAAiC,CACvC,MAAO,CACL,YAAa,KAAK,QAAQ,YAC1B,UAAW,KAAK,gBAAgB,YAAY,EAC5C,YAAa,KAAK,gBAAgB,cAAc,EAChD,aAAc,KAAK,gBAAgB,eAAe,EAClD,WAAY,KAAK,gBAAgB,aAAa,CAChD,CACF,CAEQ,cACNC,EACA9B,EACA,CAGA,OAFwB,KAAK,gBAAgB,mBAAmB,EAEvC,CACvB,KAAK/B,EAAgB,QACnB,KAAK,WAAW6D,EAAW9B,CAAO,EAClC,MACF,KAAK/B,EAAgB,QACrB,KAAKA,EAAgB,UACnB,KAAK,OAAO,QAAQ,CAClB,KAAM,QACN,UAAA6D,EACA,QAAA9B,CACF,CAAC,EACD,MACF,KAAK/B,EAAgB,OAEnB,KACJ,CACF,CAEA,MAAc,WACZ6D,EACA9B,EACA,CACA,GAAI,CACF,MAAM,KAAK,WAAW,KAAK,IAAI8B,CAAS,GAAI9B,CAAO,CACrD,OAASF,EAAO,CACViC,GAAkBjC,CAAK,GACzB,KAAK,QAAQ,UAAUA,CAAK,EAG1BkC,GAAWlC,CAAK,GAAKA,EAAM,YAAc,wBAC3C,KAAK,QAAQ,QACX,gBAAgB,KAAK,QAAQ,WAAW,+EAA+EmC,GAAa,0BAA0B,KAAK,QAAQ,WAAW,EAAE,CAAC,0BAC3L,EACSC,GAAepC,CAAK,EAC7B,KAAK,QAAQ,MAAM,oCAAqC,CACtD,MAAOA,EAAM,QACb,MAAOA,EAAM,MACb,UAAAgC,CACF,CAAC,EAED,KAAK,QAAQ,MAAM,uBAAwB,CACzC,MAAAhC,EACA,UAAAgC,EACA,QAAA9B,CACF,CAAC,CAEL,CACF,CACF,EC3uBO,IAAMmC,GAAa,IAAIC,EAE9BC,EAAmB,CAAC,CAAE,OAAAC,CAAO,IAAM,CACjC,IAAMC,EAAOD,EAAO,WACpB,GAAIC,GAAQ,MAAM,QAAQA,CAAI,EAC5B,QAAWC,KAAQD,EAAM,CACvB,IAAME,EAASD,EAAK,CAAC,EACfE,EAAOF,EAAK,MAAM,CAAC,EACxBL,GAAWM,CAA0B,EAAU,GAAGC,CAAI,CACzD,CAGFJ,EAAO,WAAaH,EACtB,CAAC","names":["createKeyBuilder","prefix","separator","parts","STORAGE_KEY_PREFIX","keyBuilder","createKeyBuilder","STORAGE_KEY_TEST","PREFIX_SESSION_ID","PREFIX_ANONYMOUS_ID","PREFIX_DEVICE_ID","MINUTE_IN_MS","AUTO_CAPTURE_INTERVAL_MS","SESSION_EXPIRATION_TIME_MS","MAX_QUEUE_SIZE","REQUEST_TIMEOUT_MS","EVENT_PAGEVIEW","PROPERTY_LIB","PROPERTY_LIB_VERSION","PROPERTY_REFERER","PROPERTY_RELEASE","PROPERTY_URL","PROPERTY_VIEWPORT","TrackingConsent","RESERVED_USER_IDS","RESERVED_USER_IDS_CASE_SENSITIVE","AltertableError","message","ApiError","status","statusText","errorCode","details","requestContext","NetworkError","cause","isAltertableError","error","isApiError","isNetworkError","invariant","condition","message","InvariantError","_InvariantError","dashboardUrl","path","createLogger","prefix","args","header","loggerCache","payload","trackingConsent","eventBadgeLabel","eventBadgeStyle","createEventBadgeElement","eventTitleLabel","eventTitleStyle","createEventTitleElement","PROPERTY_URL","environmentBadgeLabel","environmentBadgeStyle","createEnvironmentBadgeElement","timestampLabel","timestampStyle","createTimestampElement","consentBadgeLabel","consentBadgeStyle","getConsentBadgeElement","userLabel","userLabelStyle","createEventLabelElement","userValueLabel","userValueStyle","createValueElement","anonymousLabel","anonymousLabelStyle","anonymousValueLabel","anonymousValueStyle","sessionLabel","sessionLabelStyle","sessionValueLabel","sessionValueStyle","distinctIdLabel","distinctIdLabelStyle","distinctIdValueLabel","distinctIdValueStyle","anonymousalueLabel","newUserIdLabel","newUserIdLabelStyle","newUserIdValueLabel","newUserIdValueStyle","message","hasAlreadyPrinted","sanitizedMessage","warning","formatEventTime","timestamp","getEventBadgeColor","event","value","getEnvironmentColor","environment","TrackingConsent","parseUrl","url","parsedUrl","Queue","options","command","dropped","items","isBeaconSupported","Requester","config","path","payload","isBeaconSupported","url","data","controller","timeoutId","response","errorResponse","ApiError","error","NetworkError","safelyRunOnBrowser","callback","fallback","getViewport","safelyRunOnBrowser","window","captureRuntimeContext","safelyRunOnBrowser","window","getViewport","generateId","prefix","SessionManager","options","TrackingConsent","storedData","parsedData","isValidTrackingConsent","userId","consent","timestamp","resetDeviceId","resetTrackingConsent","generateId","PREFIX_SESSION_ID","PREFIX_DEVICE_ID","PREFIX_ANONYMOUS_ID","lastEventAt","now","lastEventTime","SESSION_EXPIRATION_TIME_MS","value","migrateKeys","toStorage","fromStorage","keys","key","value","MemoryStore","CookieStore","safelyRunOnBrowser","window","match","WebStorageStore","storage","LocalPlusCookieStore","testStorageSupport","storageType","STORAGE_KEY_TEST","supported","selectStorage","type","params","onFallback","localStorageSupported","cookieSupported","reservedIdentifiersList","RESERVED_USER_IDS","RESERVED_USER_IDS_CASE_SENSITIVE","id","reservedIdentifiersInfo","validateUserId","userId","blockedId","DEFAULT_CONFIG","TrackingConsent","Altertable","createLogger","Queue","MAX_QUEUE_SIZE","droppedItem","method","apiKey","config","invariant","keyBuilder","safelyRunOnBrowser","window","selectStorage","message","Requester","REQUEST_TIMEOUT_MS","SessionManager","trackingConsent","updates","previousStorage","currentTrackingConsent","enableAutoCapture","checkForChanges","intervalId","AUTO_CAPTURE_INTERVAL_MS","userId","traits","validateUserId","error","context","payload","newUserId","resetDeviceId","url","captureRuntimeContext","runtimeContext","parsedUrl","parseUrl","baseUrl","viewport","getViewport","referrer","EVENT_PAGEVIEW","PROPERTY_URL","PROPERTY_VIEWPORT","PROPERTY_REFERER","event","properties","userUrl","restProperties","hasUrl","urlForEvent","PROPERTY_LIB","PROPERTY_LIB_VERSION","PROPERTY_RELEASE","items","item","cmd","errorMessage","currentUrl","eventType","isAltertableError","isApiError","dashboardUrl","isNetworkError","altertable","Altertable","safelyRunOnBrowser","window","stub","item","method","args"]}