{"version":3,"sources":["../src/config.ts","../src/push.ts","../src/format.ts","../src/hash.ts","../src/auth.ts","../src/types/index.ts","../src/index.ts"],"sourcesContent":["import type {\n  ValidatedConfig,\n  Settings,\n  PartialConfig,\n  EventSource,\n} from './types';\nimport type { Logger } from '@walkeros/core';\n\nexport function getConfig(\n  partialConfig: PartialConfig = {},\n  logger: Logger.Instance,\n): ValidatedConfig {\n  const settings = (partialConfig.settings || {}) as Partial<Settings>;\n  const { destinations, eventSource = 'WEB' } = settings;\n\n  if (!destinations || destinations.length === 0)\n    logger.throw('Config settings destinations missing or empty');\n\n  const settingsConfig: Settings & { eventSource: EventSource } = {\n    ...settings,\n    destinations,\n    eventSource,\n  };\n\n  return { ...partialConfig, settings: settingsConfig };\n}\n","import type { PushFn } from './types';\nimport type { IngestEventsRequest, IngestEventsResponse } from './types';\nimport { getMappingValue, isObject } from '@walkeros/core';\nimport { formatEvent, formatConsent } from './format';\nimport { getAccessToken } from './auth';\nimport { getConfig } from './config';\n\nexport const push: PushFn = async function (\n  event,\n  { config, rule, data, collector, env, logger },\n) {\n  // Validate config and get typed settings\n  const validatedConfig = getConfig(config, logger);\n  const {\n    destinations,\n    eventSource,\n    validateOnly = false,\n    url = 'https://datamanager.googleapis.com/v1',\n    consent: requestConsent,\n    testEventCode,\n    userData,\n    userId,\n    clientId,\n    appInstanceId,\n    sessionAttributes,\n    consentAdUserData,\n    consentAdPersonalization,\n  } = validatedConfig.settings;\n\n  // Extract Settings guided helpers\n  const userDataMapped = userData\n    ? await getMappingValue(event, { map: userData }, { collector })\n    : {};\n  const userIdMapped = userId\n    ? await getMappingValue(event, userId, { collector })\n    : undefined;\n  const clientIdMapped = clientId\n    ? await getMappingValue(event, clientId, { collector })\n    : undefined;\n  const appInstanceIdMapped = appInstanceId\n    ? await getMappingValue(event, appInstanceId, { collector })\n    : undefined;\n  const sessionAttributesMapped = sessionAttributes\n    ? await getMappingValue(event, sessionAttributes, { collector })\n    : undefined;\n\n  // Extract consent from Settings\n  const consentAdUserDataValue =\n    typeof consentAdUserData === 'boolean'\n      ? consentAdUserData\n      : typeof consentAdUserData === 'string' && event.consent\n        ? event.consent[consentAdUserData]\n        : undefined;\n\n  const consentAdPersonalizationValue =\n    typeof consentAdPersonalization === 'boolean'\n      ? consentAdPersonalization\n      : typeof consentAdPersonalization === 'string' && event.consent\n        ? event.consent[consentAdPersonalization]\n        : undefined;\n\n  // Build Settings helpers object\n  const settingsHelpers: Record<string, unknown> = {};\n  if (isObject(userDataMapped)) {\n    Object.assign(settingsHelpers, userDataMapped);\n  }\n  if (userIdMapped !== undefined) settingsHelpers.userId = userIdMapped;\n  if (clientIdMapped !== undefined) settingsHelpers.clientId = clientIdMapped;\n  if (appInstanceIdMapped !== undefined)\n    settingsHelpers.appInstanceId = appInstanceIdMapped;\n  if (sessionAttributesMapped !== undefined)\n    settingsHelpers.sessionAttributes = sessionAttributesMapped;\n  if (consentAdUserDataValue !== undefined)\n    settingsHelpers.adUserData = consentAdUserDataValue;\n  if (consentAdPersonalizationValue !== undefined)\n    settingsHelpers.adPersonalization = consentAdPersonalizationValue;\n\n  // Get mapped data from destination config and event mapping\n  const configData = validatedConfig.data\n    ? await getMappingValue(event, validatedConfig.data, { collector })\n    : {};\n  const eventData = isObject(data) ? data : {};\n\n  // Merge: Settings helpers < config.data < event mapping data\n  const finalData = {\n    ...settingsHelpers,\n    ...(isObject(configData) ? configData : {}),\n    ...eventData,\n  };\n\n  // Format event for Data Manager API\n  const dataManagerEvent = await formatEvent(event, finalData);\n\n  // Apply event source from settings (required)\n  if (!dataManagerEvent.eventSource) {\n    dataManagerEvent.eventSource = eventSource;\n  }\n\n  // Apply request-level consent if event doesn't have consent\n  if (!dataManagerEvent.consent && requestConsent) {\n    dataManagerEvent.consent = requestConsent;\n  }\n\n  // Validate required fields before API call\n  if (!dataManagerEvent.transactionId) {\n    logger.throw('transactionId is required');\n  }\n\n  // Check if any destination is GA4 (requires eventName)\n  const hasGA4Destination = destinations.some(\n    (d) => d.operatingAccount?.accountType === 'GOOGLE_ANALYTICS_PROPERTY',\n  );\n\n  if (hasGA4Destination && !dataManagerEvent.eventName) {\n    logger.throw('eventName is required for GA4 destinations');\n  }\n\n  // Build API request. Encoding is pinned to HEX because all hashing in this\n  // destination (email/phone/name) emits lowercase hex SHA-256 digests; mixing\n  // BASE64 here would silently produce mismatched identifiers.\n  const requestBody: IngestEventsRequest = {\n    events: [dataManagerEvent],\n    destinations,\n    encoding: 'HEX',\n  };\n\n  // Add optional parameters\n  if (requestConsent) {\n    requestBody.consent = requestConsent;\n  }\n\n  if (validateOnly) {\n    requestBody.validateOnly = true;\n  }\n\n  if (testEventCode) {\n    requestBody.testEventCode = testEventCode;\n  }\n\n  const authClient = env?.authClient;\n  if (!authClient) {\n    return logger.throw(\n      'Auth client not initialized. Ensure init() was called successfully.',\n    );\n  }\n\n  let accessToken: string;\n  try {\n    accessToken = await getAccessToken(authClient);\n  } catch (error) {\n    logger.error('Authentication failed', { error });\n    throw error;\n  }\n\n  const fetchFn = env?.fetch || fetch;\n  const endpoint = `${url}/events:ingest`;\n\n  logger.debug('Sending to Data Manager API', {\n    endpoint,\n    eventCount: requestBody.events.length,\n    destinations: destinations.length,\n    validateOnly,\n  });\n\n  const response = await fetchFn(endpoint, {\n    method: 'POST',\n    headers: {\n      Authorization: `Bearer ${accessToken}`,\n      'Content-Type': 'application/json',\n    },\n    body: JSON.stringify(requestBody),\n  });\n\n  if (!response.ok) {\n    const errorText = await response.text();\n    logger.throw(`Data Manager API error (${response.status}): ${errorText}`);\n  }\n\n  const result: IngestEventsResponse = await response.json();\n\n  logger.debug('API response', {\n    status: response.status,\n    requestId: result.requestId,\n  });\n\n  // If validation errors exist, throw them\n  if (result.validationErrors && result.validationErrors.length > 0) {\n    logger.throw(\n      `Validation errors: ${JSON.stringify(result.validationErrors)}`,\n    );\n  }\n};\n","import type { WalkerOS } from '@walkeros/core';\nimport { isString, isDefined } from '@walkeros/core';\nimport type {\n  Event,\n  UserData,\n  UserIdentifier,\n  AdIdentifiers,\n  Consent,\n  ConsentStatus,\n} from './types';\nimport { hashEmail, hashPhone, hashName } from './hash';\n\n/**\n * Format walkerOS event timestamp to RFC 3339 format\n * https://developers.google.com/data-manager/api/reference/rest/v1/Event\n *\n * walkerOS timestamp is in milliseconds, RFC 3339 format: \"2024-01-15T10:30:00Z\"\n */\nexport function formatTimestamp(timestamp: number): string {\n  return new Date(timestamp).toISOString();\n}\n\n/**\n * Format user identifiers from mapped data\n * https://developers.google.com/data-manager/api/reference/rest/v1/UserData\n *\n * User data must be explicitly mapped in the mapping configuration.\n * Max 10 identifiers per event\n */\nexport async function formatUserData(\n  data: Record<string, unknown>,\n): Promise<UserData | undefined> {\n  const identifiers: UserIdentifier[] = [];\n\n  // Extract from mapped data only\n  // Email\n  if (isString(data.email) && data.email) {\n    const hashedEmail = await hashEmail(data.email);\n    if (hashedEmail) {\n      identifiers.push({ emailAddress: hashedEmail });\n    }\n  }\n\n  // Phone\n  if (isString(data.phone) && data.phone) {\n    const hashedPhone = await hashPhone(data.phone);\n    if (hashedPhone) {\n      identifiers.push({ phoneNumber: hashedPhone });\n    }\n  }\n\n  // Address from mapped properties\n  const hasAddress =\n    data.firstName || data.lastName || data.regionCode || data.postalCode;\n\n  if (hasAddress) {\n    const address: Record<string, string> = {};\n\n    if (isString(data.firstName) && data.firstName) {\n      address.givenName = await hashName(data.firstName, 'given');\n    }\n\n    if (isString(data.lastName) && data.lastName) {\n      address.familyName = await hashName(data.lastName, 'family');\n    }\n\n    // Region code is NOT hashed\n    if (isString(data.regionCode) && data.regionCode) {\n      address.regionCode = data.regionCode.toUpperCase();\n    }\n\n    // Postal code is NOT hashed\n    if (isString(data.postalCode) && data.postalCode) {\n      address.postalCode = data.postalCode;\n    }\n\n    if (Object.keys(address).length > 0) {\n      identifiers.push({ address });\n    }\n  }\n\n  // Limit to 10 identifiers\n  if (identifiers.length === 0) return undefined;\n\n  return {\n    userIdentifiers: identifiers.slice(0, 10),\n  };\n}\n\n/**\n * Extract and format attribution identifiers from mapped data\n * https://developers.google.com/data-manager/api/reference/rest/v1/AdIdentifiers\n *\n * Attribution identifiers should be mapped explicitly in the mapping configuration.\n * Example: { gclid: 'context.gclid', gbraid: 'context.gbraid' }\n */\nexport function formatAdIdentifiers(\n  data: Record<string, unknown>,\n): AdIdentifiers | undefined {\n  const identifiers: AdIdentifiers = {};\n\n  // Extract from mapped data (already processed by mapping system)\n  if (isString(data.gclid) && data.gclid) {\n    identifiers.gclid = data.gclid;\n  }\n  if (isString(data.gbraid) && data.gbraid) {\n    identifiers.gbraid = data.gbraid;\n  }\n  if (isString(data.wbraid) && data.wbraid) {\n    identifiers.wbraid = data.wbraid;\n  }\n  if (isString(data.sessionAttributes) && data.sessionAttributes) {\n    identifiers.sessionAttributes = data.sessionAttributes;\n  }\n\n  return Object.keys(identifiers).length > 0 ? identifiers : undefined;\n}\n\n/**\n * Map walkerOS consent to Data Manager consent format\n * https://developers.google.com/data-manager/api/devguides/concepts/dma\n *\n * walkerOS: { marketing: true, personalization: false }\n * Data Manager: { adUserData: 'CONSENT_GRANTED', adPersonalization: 'CONSENT_DENIED' }\n */\nexport function formatConsent(\n  walkerOSConsent: WalkerOS.Consent | undefined,\n): Consent | undefined {\n  if (!walkerOSConsent) return undefined;\n\n  const consent: Consent = {};\n\n  // Map marketing consent to adUserData\n  if (isDefined(walkerOSConsent.marketing)) {\n    consent.adUserData = walkerOSConsent.marketing\n      ? 'CONSENT_GRANTED'\n      : 'CONSENT_DENIED';\n  }\n\n  // Map personalization consent to adPersonalization\n  if (isDefined(walkerOSConsent.personalization)) {\n    consent.adPersonalization = walkerOSConsent.personalization\n      ? 'CONSENT_GRANTED'\n      : 'CONSENT_DENIED';\n  }\n\n  return Object.keys(consent).length > 0 ? consent : undefined;\n}\n\n/**\n * Format complete event for Data Manager API\n * https://developers.google.com/data-manager/api/reference/rest/v1/Event\n */\nexport async function formatEvent(\n  event: WalkerOS.Event,\n  mappedData?: Record<string, unknown>,\n): Promise<Event> {\n  const dataManagerEvent: Event = {\n    eventTimestamp: formatTimestamp(event.timestamp),\n  };\n\n  // Use only mapped data (no fallback to event.data)\n  const data = mappedData || {};\n\n  // Transaction ID for deduplication\n  if (isString(data.transactionId) && data.transactionId) {\n    dataManagerEvent.transactionId = data.transactionId.substring(0, 512);\n  }\n\n  // Client ID (GA)\n  if (isString(data.clientId) && data.clientId) {\n    dataManagerEvent.clientId = data.clientId.substring(0, 255);\n  }\n\n  // User ID\n  if (isString(data.userId) && data.userId) {\n    dataManagerEvent.userId = data.userId.substring(0, 256);\n  }\n\n  // User data\n  const userData = await formatUserData(data);\n  if (userData) {\n    dataManagerEvent.userData = userData;\n  }\n\n  // Attribution identifiers\n  const adIdentifiers = formatAdIdentifiers(data);\n  if (adIdentifiers) {\n    dataManagerEvent.adIdentifiers = adIdentifiers;\n  }\n\n  // Conversion value\n  if (typeof data.conversionValue === 'number') {\n    dataManagerEvent.conversionValue = data.conversionValue;\n  }\n\n  // Currency\n  if (isString(data.currency) && data.currency) {\n    dataManagerEvent.currency = data.currency.substring(0, 3).toUpperCase();\n  }\n\n  // Cart data\n  if (data.cartData && typeof data.cartData === 'object') {\n    dataManagerEvent.cartData = data.cartData as Event['cartData'];\n  }\n\n  // Event name (for GA4)\n  if (isString(data.eventName) && data.eventName) {\n    dataManagerEvent.eventName = data.eventName.substring(0, 40);\n  }\n\n  // App instance ID (GA4 app stream)\n  if (isString(data.appInstanceId) && data.appInstanceId) {\n    dataManagerEvent.appInstanceId = data.appInstanceId;\n  }\n\n  // Store ID (Google Ads store sales / IN_STORE events)\n  if (isString(data.storeId) && data.storeId) {\n    dataManagerEvent.eventLocation = { storeId: data.storeId };\n  }\n\n  // Event source\n  if (isString(data.eventSource) && data.eventSource) {\n    dataManagerEvent.eventSource = data.eventSource as Event['eventSource'];\n  }\n\n  // Consent - check mapped data first, then fallback to event.consent\n  const mappedConsent: Consent = {};\n\n  // Check for mapped consent values (from Settings or event mapping)\n  if (typeof data.adUserData === 'boolean') {\n    mappedConsent.adUserData = data.adUserData\n      ? 'CONSENT_GRANTED'\n      : 'CONSENT_DENIED';\n  }\n  if (typeof data.adPersonalization === 'boolean') {\n    mappedConsent.adPersonalization = data.adPersonalization\n      ? 'CONSENT_GRANTED'\n      : 'CONSENT_DENIED';\n  }\n\n  // If no mapped consent, fall back to event.consent\n  if (Object.keys(mappedConsent).length === 0) {\n    const eventConsent = formatConsent(event.consent);\n    if (eventConsent) {\n      dataManagerEvent.consent = eventConsent;\n    }\n  } else {\n    dataManagerEvent.consent = mappedConsent;\n  }\n\n  return dataManagerEvent;\n}\n","import { isString } from '@walkeros/core';\nimport { getHashServer } from '@walkeros/server-core';\n\n/**\n * Normalize email address according to Google Data Manager requirements\n * https://developers.google.com/data-manager/api/devguides/concepts/formatting#email\n *\n * 1. Trim whitespace\n * 2. Convert to lowercase\n * 3. Remove dots (.) for gmail.com and googlemail.com\n * 4. SHA-256 hash\n */\nexport async function hashEmail(email: string): Promise<string> {\n  if (!isString(email) || !email) return '';\n\n  // Trim and lowercase\n  let normalized = email.trim().toLowerCase();\n\n  // Remove dots for Gmail addresses\n  if (\n    normalized.endsWith('@gmail.com') ||\n    normalized.endsWith('@googlemail.com')\n  ) {\n    const [localPart, domain] = normalized.split('@');\n    normalized = `${localPart.replace(/\\./g, '')}@${domain}`;\n  }\n\n  return getHashServer(normalized);\n}\n\n/**\n * Normalize phone number to E.164 format and hash\n * https://developers.google.com/data-manager/api/devguides/concepts/formatting#phone\n *\n * E.164 format: +[country code][number] (max 15 digits after +)\n * Example: +18005550100\n *\n * 1. Remove all non-digit characters except leading +\n * 2. Ensure it starts with +\n * 3. SHA-256 hash\n */\nexport async function hashPhone(phone: string): Promise<string> {\n  if (!isString(phone) || !phone) return '';\n\n  // Remove all non-digit characters except + at the start\n  let normalized = phone.trim();\n\n  // Extract country code if present\n  const hasPlus = normalized.startsWith('+');\n\n  // Remove all non-digits\n  normalized = normalized.replace(/\\D/g, '');\n\n  // Add + prefix if it was there or if number is long enough\n  if (hasPlus || normalized.length > 10) {\n    normalized = `+${normalized}`;\n  } else {\n    // Assume US number if no country code (default behavior)\n    normalized = `+1${normalized}`;\n  }\n\n  return getHashServer(normalized);\n}\n\n/**\n * Normalize and hash a name (first or last name)\n * https://developers.google.com/data-manager/api/devguides/concepts/formatting#name\n *\n * 1. Trim whitespace\n * 2. Convert to lowercase\n * 3. Remove common prefixes (Mr., Mrs., Dr.) for first names\n * 4. Remove common suffixes (Jr., Sr., III) for last names\n * 5. SHA-256 hash\n */\nexport async function hashName(\n  name: string,\n  type: 'given' | 'family' = 'given',\n): Promise<string> {\n  if (!isString(name) || !name) return '';\n\n  // Trim and lowercase\n  let normalized = name.trim().toLowerCase();\n\n  // Remove prefixes for given names\n  if (type === 'given') {\n    const prefixes = ['mr.', 'mrs.', 'ms.', 'miss.', 'dr.', 'prof.'];\n    for (const prefix of prefixes) {\n      if (normalized.startsWith(prefix)) {\n        normalized = normalized.substring(prefix.length).trim();\n        break;\n      }\n    }\n  }\n\n  // Remove suffixes for family names (check with and without space)\n  // Sort by length (longest first) to match \"iii\" before \"ii\"\n  if (type === 'family') {\n    const suffixes = ['jr.', 'sr.', 'iii', 'ii', 'iv', 'v'];\n    for (const suffix of suffixes) {\n      // Check for suffix with space before it (e.g., \" jr.\")\n      const suffixWithSpace = ` ${suffix}`;\n      if (normalized.endsWith(suffixWithSpace)) {\n        normalized = normalized\n          .substring(0, normalized.length - suffixWithSpace.length)\n          .trim();\n        break;\n      }\n      // Check for suffix without space\n      if (normalized.endsWith(suffix)) {\n        normalized = normalized\n          .substring(0, normalized.length - suffix.length)\n          .trim();\n        break;\n      }\n    }\n  }\n\n  return getHashServer(normalized);\n}\n\n/**\n * Hash multiple email addresses\n */\nexport async function hashEmails(emails: string[]): Promise<string[]> {\n  return Promise.all(emails.map((email) => hashEmail(email)));\n}\n\n/**\n * Hash multiple phone numbers\n */\nexport async function hashPhones(phones: string[]): Promise<string[]> {\n  return Promise.all(phones.map((phone) => hashPhone(phone)));\n}\n","import { GoogleAuth, type OAuth2Client } from 'google-auth-library';\nimport type { Logger, ServiceAccount } from '@walkeros/core';\nimport type { Config } from './types';\n\nconst DEFAULT_SCOPES = ['https://www.googleapis.com/auth/datamanager'];\n\n/**\n * Authentication error with cause tracking\n */\nexport class AuthError extends Error {\n  constructor(\n    message: string,\n    public cause?: Error,\n  ) {\n    super(message);\n    this.name = 'DataManagerAuthError';\n  }\n}\n\n/**\n * Resolves credentials with precedence `config.credentials ?? settings.credentials`.\n * Warns once (per instance) when the deprecated `settings.credentials` path is used.\n */\nfunction resolveCredentials(\n  config: Partial<Config>,\n  logger: Logger.Instance,\n): Credential | undefined {\n  if (config.credentials !== undefined) return config.credentials;\n\n  const settingsCredentials = config.settings?.credentials;\n  if (settingsCredentials !== undefined) {\n    logger.warn(\n      'settings.credentials is deprecated, use config.credentials instead',\n    );\n    return settingsCredentials;\n  }\n\n  return undefined;\n}\n\ntype Credential = string | ServiceAccount;\n\n/**\n * Normalizes a credential into the object form GoogleAuth expects.\n *\n * The shared `Credential<ServiceAccount>` union allows a JSON string (often a\n * `$env` reference). GoogleAuth requires a parsed object, so parse-if-string\n * here before handing it over.\n *\n * @throws AuthError if a string credential is not valid JSON\n */\nfunction parseCredentials(credentials: Credential): ServiceAccount {\n  if (typeof credentials !== 'string') return credentials;\n\n  try {\n    const parsed: ServiceAccount = JSON.parse(credentials);\n    return parsed;\n  } catch (error) {\n    throw new AuthError(\n      'Invalid credentials: expected a service account object or a JSON string',\n      error instanceof Error ? error : undefined,\n    );\n  }\n}\n\n/**\n * Creates Google Auth client based on config\n *\n * Authentication priority:\n * 1. credentials (inline service account) - if provided\n *    Resolved as `config.credentials ?? settings.credentials`. A string\n *    credential (e.g. a `$env` JSON value) is parsed before use.\n * 2. keyFilename (service account file) - if provided\n * 3. Application Default Credentials (ADC) - automatic fallback\n *    - GOOGLE_APPLICATION_CREDENTIALS env var\n *    - GCP metadata server (Cloud Functions, Cloud Run, GCE)\n *\n * @param config - Validated config with auth options\n * @param logger - Logger instance for deprecation warnings\n * @returns OAuth2Client for token retrieval\n * @throws AuthError if authentication fails\n */\nexport async function createAuthClient(\n  config: Partial<Config>,\n  logger: Logger.Instance,\n): Promise<OAuth2Client> {\n  const { keyFilename, scopes = DEFAULT_SCOPES } = config.settings || {};\n  const credentials = resolveCredentials(config, logger);\n\n  // Parse before the try so an invalid-JSON error surfaces with its own\n  // message rather than being wrapped as a generic auth failure.\n  const parsedCredentials = credentials\n    ? parseCredentials(credentials)\n    : undefined;\n\n  try {\n    if (parsedCredentials) {\n      const auth = new GoogleAuth({\n        credentials: parsedCredentials,\n        scopes,\n      });\n      return (await auth.getClient()) as OAuth2Client;\n    }\n\n    if (keyFilename) {\n      const auth = new GoogleAuth({\n        keyFilename,\n        scopes,\n      });\n      return (await auth.getClient()) as OAuth2Client;\n    }\n\n    const auth = new GoogleAuth({ scopes });\n    return (await auth.getClient()) as OAuth2Client;\n  } catch (error) {\n    throw new AuthError(\n      'Failed to create auth client. Check credentials configuration or ensure GOOGLE_APPLICATION_CREDENTIALS is set.',\n      error instanceof Error ? error : undefined,\n    );\n  }\n}\n\n/**\n * Gets access token from auth client\n * Automatically returns cached token if valid or refreshes if expired\n *\n * @param authClient - OAuth2 client from createAuthClient()\n * @returns Fresh access token\n * @throws AuthError if token retrieval fails\n */\nexport async function getAccessToken(\n  authClient: OAuth2Client,\n): Promise<string> {\n  try {\n    const tokenResponse = await authClient.getAccessToken();\n\n    if (!tokenResponse.token) {\n      throw new AuthError('Auth client returned empty token');\n    }\n\n    return tokenResponse.token;\n  } catch (error) {\n    throw new AuthError(\n      'Failed to obtain access token',\n      error instanceof Error ? error : undefined,\n    );\n  }\n}\n","import type {\n  Mapping as WalkerOSMapping,\n  Destination as CoreDestination,\n  Credential,\n  ServiceAccount,\n} from '@walkeros/core';\nimport type { DestinationServer } from '@walkeros/server-core';\nimport type { OAuth2Client } from 'google-auth-library';\n\nexport interface Settings {\n  /**\n   * Service account credentials (client_email + private_key)\n   * Recommended for serverless environments (AWS Lambda, Docker, etc.)\n   *\n   * @deprecated Use `config.credentials` instead. This field still works but\n   * will be removed in a future major version.\n   */\n  credentials?: {\n    client_email: string;\n    private_key: string;\n  };\n\n  /**\n   * Path to service account JSON file\n   * For local development or environments with filesystem access\n   */\n  keyFilename?: string;\n\n  /**\n   * OAuth scopes for Data Manager API\n   * @default ['https://www.googleapis.com/auth/datamanager']\n   */\n  scopes?: string[];\n\n  /** Array of destination accounts and conversion actions/user lists */\n  destinations: Destination[];\n\n  /** Event source for all events. Defaults to WEB if not specified */\n  eventSource?: EventSource;\n\n  /** Maximum number of events to batch before sending (max 2000) */\n  batchSize?: number;\n\n  /** Time in milliseconds to wait before auto-flushing batch */\n  batchInterval?: number;\n\n  /** If true, validate request without ingestion (testing mode) */\n  validateOnly?: boolean;\n\n  /** Override API endpoint (for testing) */\n  url?: string;\n\n  /** Request-level consent for all events */\n  consent?: Consent;\n\n  /** Test event code for debugging (optional) */\n  testEventCode?: string;\n\n  /** Guided helpers: User data mapping (applies to all events) */\n  userData?: WalkerOSMapping.Map;\n\n  /** Guided helper: First-party user ID */\n  userId?: WalkerOSMapping.Value;\n\n  /** Guided helper: GA4 client ID */\n  clientId?: WalkerOSMapping.Value;\n\n  /** Guided helper: GA4 app instance ID (Firebase) */\n  appInstanceId?: WalkerOSMapping.Value;\n\n  /** Guided helper: Privacy-safe attribution (Google's sessionAttributes) */\n  sessionAttributes?: WalkerOSMapping.Value;\n\n  /** Consent mapping: Map consent field to adUserData (string = field name, boolean = static value) */\n  consentAdUserData?: string | boolean;\n\n  /** Consent mapping: Map consent field to adPersonalization (string = field name, boolean = static value) */\n  consentAdPersonalization?: string | boolean;\n}\n\nexport interface Mapping {\n  // Attribution identifiers (optional, for explicit mapping)\n  gclid?: WalkerOSMapping.Value;\n  gbraid?: WalkerOSMapping.Value;\n  wbraid?: WalkerOSMapping.Value;\n  sessionAttributes?: WalkerOSMapping.Value;\n}\n\nexport interface Env extends DestinationServer.Env {\n  fetch?: typeof fetch;\n  authClient?: OAuth2Client | null;\n}\n\nexport type InitSettings = Partial<Settings>;\n\nexport type Types = CoreDestination.Types<\n  Settings,\n  Mapping,\n  Env,\n  InitSettings,\n  unknown,\n  Credential<ServiceAccount>\n>;\n\nexport interface DestinationInterface extends DestinationServer.Destination<Types> {\n  init: DestinationServer.InitFn<Types>;\n}\n\nexport type Config = {\n  settings: Settings;\n} & DestinationServer.Config<Types>;\n\n/**\n * Config after validation - settings is guaranteed to exist with required fields\n * Use this type after calling getConfig() to get proper type narrowing\n * After validation, eventSource is always set (defaults to 'WEB')\n */\nexport type ValidatedConfig = Omit<Config, 'settings'> & {\n  settings: Settings & { eventSource: EventSource };\n};\n\nexport type InitFn = DestinationServer.InitFn<Types>;\nexport type PushFn = DestinationServer.PushFn<Types>;\n\nexport type PartialConfig = DestinationServer.PartialConfig<Types>;\n\nexport type PushEvents = DestinationServer.PushEvents<Mapping>;\n\nexport type Rule = WalkerOSMapping.Rule<Mapping>;\nexport type Rules = WalkerOSMapping.Rules<Rule>;\n\n// Google Data Manager API Types\n// https://developers.google.com/data-manager/api/reference\n\n/**\n * Destination account and product identifier\n * https://developers.google.com/data-manager/api/reference/rest/v1/Destination\n */\nexport interface Destination {\n  /** Reference identifier for this destination */\n  reference?: string;\n\n  /** Login account (account initiating the request) */\n  loginAccount?: ProductAccount;\n\n  /** Linked account (child account linked to login account) */\n  linkedAccount?: ProductAccount;\n\n  /** Operating account (account where data is sent) */\n  operatingAccount?: ProductAccount;\n\n  /** Product-specific destination ID (conversion action or user list) */\n  productDestinationId?: string;\n}\n\n/**\n * Product account information\n */\nexport interface ProductAccount {\n  /** Account ID (e.g., \"123-456-7890\" for Google Ads) */\n  accountId: string;\n\n  /** Type of account */\n  accountType: AccountType;\n}\n\nexport type AccountType =\n  | 'ACCOUNT_TYPE_UNSPECIFIED'\n  | 'GOOGLE_ADS'\n  | 'DISPLAY_VIDEO_ADVERTISER'\n  | 'DISPLAY_VIDEO_PARTNER'\n  | 'GOOGLE_ANALYTICS_PROPERTY'\n  | 'DATA_PARTNER';\n\nexport type EventSource = 'WEB' | 'APP' | 'IN_STORE' | 'PHONE' | 'OTHER';\n\n/**\n * Hash encoding for user identifiers (required for UserData uploads)\n * https://developers.google.com/data-manager/api/reference/rest/v1/Encoding\n */\nexport type Encoding = 'HEX' | 'BASE64';\n\n/**\n * Consent for Digital Markets Act (DMA) compliance\n * https://developers.google.com/data-manager/api/devguides/concepts/dma\n */\nexport interface Consent {\n  /** Consent for data collection and use */\n  adUserData?: ConsentStatus;\n\n  /** Consent for ad personalization */\n  adPersonalization?: ConsentStatus;\n}\n\nexport type ConsentStatus = 'CONSENT_GRANTED' | 'CONSENT_DENIED';\n\n/**\n * Request body for events.ingest API\n * https://developers.google.com/data-manager/api/reference/rest/v1/events/ingest\n */\nexport interface IngestEventsRequest {\n  /** Array of destinations for these events (max 10) */\n  destinations: Destination[];\n\n  /** Array of events to ingest (max 2000) */\n  events: Event[];\n\n  /** Request-level consent (overridden by event-level) */\n  consent?: Consent;\n\n  /** If true, validate without ingestion */\n  validateOnly?: boolean;\n\n  /** Test event code for debugging */\n  testEventCode?: string;\n\n  /** Hash encoding for user identifiers. Required for UserData uploads. */\n  encoding?: Encoding;\n}\n\n/**\n * Single event for ingestion\n * https://developers.google.com/data-manager/api/reference/rest/v1/Event\n */\nexport interface Event {\n  /** Destination references for routing */\n  destinationReferences?: string[];\n\n  /** Transaction ID for deduplication (max 512 chars) */\n  transactionId?: string;\n\n  /** Event timestamp in RFC 3339 format */\n  eventTimestamp?: string;\n\n  /** Last updated timestamp in RFC 3339 format */\n  lastUpdatedTimestamp?: string;\n\n  /** User data with identifiers (max 10 identifiers) */\n  userData?: UserData;\n\n  /** Event-level consent (overrides request-level) */\n  consent?: Consent;\n\n  /** Attribution identifiers */\n  adIdentifiers?: AdIdentifiers;\n\n  /** Currency code (ISO 4217, 3 chars) */\n  currency?: string;\n\n  /** Conversion value */\n  conversionValue?: number;\n\n  /** Source of the event */\n  eventSource?: EventSource;\n\n  /** Device information for the event */\n  eventDeviceInfo?: DeviceInfo;\n\n  /** Shopping cart data */\n  cartData?: CartData;\n\n  /** Custom variables for the event */\n  customVariables?: CustomVariable[];\n\n  /** Experimental fields (subject to change) */\n  experimentalFields?: ExperimentalField[];\n\n  /** User properties */\n  userProperties?: UserProperties;\n\n  /** Event name for GA4 (max 40 chars, required for GA4) */\n  eventName?: string;\n\n  /** Google Analytics client ID (max 255 chars) */\n  clientId?: string;\n\n  /** First-party user ID (max 256 chars) */\n  userId?: string;\n\n  /** Additional event parameters */\n  additionalEventParameters?: EventParameter[];\n\n  /** GA4 app instance ID (Firebase) */\n  appInstanceId?: string;\n\n  /** Third-party user data (e.g. data partner identifiers) */\n  thirdPartyUserData?: UserData;\n\n  /** Event location (required for Store Sales / IN_STORE events) */\n  eventLocation?: EventLocation;\n}\n\n/**\n * Event location data\n * https://developers.google.com/data-manager/api/reference/rest/v1/EventLocation\n */\nexport interface EventLocation {\n  /** Required for Store Sales. Identifier of the physical store where the event happened. */\n  storeId?: string;\n}\n\n/**\n * Device information\n */\nexport interface DeviceInfo {\n  /** User agent string */\n  userAgent?: string;\n}\n\n/**\n * Custom variable\n */\nexport interface CustomVariable {\n  /** Variable name */\n  name?: string;\n\n  /** Variable value */\n  value?: string;\n}\n\n/**\n * Experimental field\n */\nexport interface ExperimentalField {\n  /** Field name */\n  name?: string;\n\n  /** Field value */\n  value?: string;\n}\n\n/**\n * User properties\n */\nexport interface UserProperties {\n  /** Property values */\n  [key: string]: string | number | boolean | undefined;\n}\n\n/**\n * Event parameter\n */\nexport interface EventParameter {\n  /** Parameter name */\n  name?: string;\n\n  /** Parameter value */\n  value?: string | number;\n}\n\n/**\n * User data with identifiers\n * https://developers.google.com/data-manager/api/reference/rest/v1/UserData\n */\nexport interface UserData {\n  /** Array of user identifiers (max 10) */\n  userIdentifiers: UserIdentifier[];\n}\n\n/**\n * User identifier (email, phone, or address)\n */\nexport type UserIdentifier =\n  | { emailAddress: string }\n  | { phoneNumber: string }\n  | { address: Address };\n\n/**\n * Address for user identification\n * https://developers.google.com/data-manager/api/reference/rest/v1/Address\n */\nexport interface Address {\n  /** Given name (first name) - SHA-256 hashed */\n  givenName?: string;\n\n  /** Family name (last name) - SHA-256 hashed */\n  familyName?: string;\n\n  /** ISO-3166-1 alpha-2 country code - NOT hashed (e.g., \"US\", \"GB\") */\n  regionCode?: string;\n\n  /** Postal code - NOT hashed */\n  postalCode?: string;\n}\n\n/**\n * Attribution identifiers\n * https://developers.google.com/data-manager/api/reference/rest/v1/AdIdentifiers\n */\nexport interface AdIdentifiers {\n  /** Session attributes (privacy-safe attribution) */\n  sessionAttributes?: string;\n\n  /** Google Click ID (primary attribution) */\n  gclid?: string;\n\n  /** iOS attribution identifier (post-ATT) */\n  gbraid?: string;\n\n  /** Web-to-app attribution identifier */\n  wbraid?: string;\n\n  /** Device information for landing page */\n  landingPageDeviceInfo?: DeviceInfo;\n}\n\n/**\n * Shopping cart data\n * https://developers.google.com/data-manager/api/reference/rest/v1/CartData\n */\nexport interface CartData {\n  /** Array of cart items (max 200) */\n  items: CartItem[];\n}\n\n/**\n * Single cart item\n * https://developers.google.com/data-manager/api/reference/rest/v1/CartItem\n */\nexport interface CartItem {\n  /** Merchant product ID (max 127 chars) */\n  merchantProductId?: string;\n\n  /** Item price */\n  price?: number;\n\n  /** Item quantity */\n  quantity?: number;\n}\n\n/**\n * Response from events.ingest API\n * https://developers.google.com/data-manager/api/reference/rest/v1/IngestEventsResponse\n */\nexport interface IngestEventsResponse {\n  /** Unique request ID for status checking */\n  requestId: string;\n\n  /** Validation errors (only if validateOnly=true) */\n  validationErrors?: ValidationError[];\n}\n\n/**\n * Validation error\n */\nexport interface ValidationError {\n  /** Error code */\n  code: string;\n\n  /** Human-readable error message */\n  message: string;\n\n  /** Field path that caused the error */\n  fieldPath?: string;\n}\n\n/**\n * Request status response\n * https://developers.google.com/data-manager/api/reference/rest/v1/requestStatus/retrieve\n */\nexport interface RequestStatusResponse {\n  /** Unique request ID */\n  requestId: string;\n\n  /** Processing state */\n  state: RequestState;\n\n  /** Number of events successfully ingested */\n  eventsIngested?: number;\n\n  /** Number of events that failed */\n  eventsFailed?: number;\n\n  /** Array of errors (if any) */\n  errors?: RequestError[];\n}\n\nexport type RequestState =\n  | 'STATE_UNSPECIFIED'\n  | 'PENDING'\n  | 'PROCESSING'\n  | 'SUCCEEDED'\n  | 'FAILED'\n  | 'PARTIALLY_SUCCEEDED';\n\n/**\n * Request error\n */\nexport interface RequestError {\n  /** Error code */\n  code: string;\n\n  /** Human-readable error message */\n  message: string;\n\n  /** Number of events affected by this error */\n  eventCount?: number;\n}\n","import type { DestinationInterface } from './types';\nimport { getConfig } from './config';\nimport { push } from './push';\nimport { createAuthClient } from './auth';\n\nexport * as DestinationDataManager from './types';\n\nexport const destinationDataManager: DestinationInterface = {\n  type: 'datamanager',\n\n  config: {},\n\n  async init({ config: partialConfig, env, logger }) {\n    // getConfig validates required fields and returns ValidatedConfig\n    const config = getConfig(partialConfig, logger);\n\n    try {\n      const authClient = await createAuthClient(config, logger);\n      logger.debug('Auth client created');\n\n      return {\n        ...config,\n        env: {\n          ...env,\n          authClient,\n        },\n      };\n    } catch (error) {\n      logger.throw(\n        `Data Manager authentication failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n      );\n    }\n  },\n\n  async push(event, context) {\n    return await push(event, context);\n  },\n};\n\nexport default destinationDataManager;\n"],"mappings":";AAQO,SAAS,UACd,gBAA+B,CAAC,GAChC,QACiB;AACjB,QAAM,WAAY,cAAc,YAAY,CAAC;AAC7C,QAAM,EAAE,cAAc,cAAc,MAAM,IAAI;AAE9C,MAAI,CAAC,gBAAgB,aAAa,WAAW;AAC3C,WAAO,MAAM,+CAA+C;AAE9D,QAAM,iBAA0D;AAAA,IAC9D,GAAG;AAAA,IACH;AAAA,IACA;AAAA,EACF;AAEA,SAAO,EAAE,GAAG,eAAe,UAAU,eAAe;AACtD;;;ACvBA,SAAS,iBAAiB,gBAAgB;;;ACD1C,SAAS,YAAAA,WAAU,iBAAiB;;;ACDpC,SAAS,gBAAgB;AACzB,SAAS,qBAAqB;AAW9B,eAAsB,UAAU,OAAgC;AAC9D,MAAI,CAAC,SAAS,KAAK,KAAK,CAAC,MAAO,QAAO;AAGvC,MAAI,aAAa,MAAM,KAAK,EAAE,YAAY;AAG1C,MACE,WAAW,SAAS,YAAY,KAChC,WAAW,SAAS,iBAAiB,GACrC;AACA,UAAM,CAAC,WAAW,MAAM,IAAI,WAAW,MAAM,GAAG;AAChD,iBAAa,GAAG,UAAU,QAAQ,OAAO,EAAE,CAAC,IAAI,MAAM;AAAA,EACxD;AAEA,SAAO,cAAc,UAAU;AACjC;AAaA,eAAsB,UAAU,OAAgC;AAC9D,MAAI,CAAC,SAAS,KAAK,KAAK,CAAC,MAAO,QAAO;AAGvC,MAAI,aAAa,MAAM,KAAK;AAG5B,QAAM,UAAU,WAAW,WAAW,GAAG;AAGzC,eAAa,WAAW,QAAQ,OAAO,EAAE;AAGzC,MAAI,WAAW,WAAW,SAAS,IAAI;AACrC,iBAAa,IAAI,UAAU;AAAA,EAC7B,OAAO;AAEL,iBAAa,KAAK,UAAU;AAAA,EAC9B;AAEA,SAAO,cAAc,UAAU;AACjC;AAYA,eAAsB,SACpB,MACA,OAA2B,SACV;AACjB,MAAI,CAAC,SAAS,IAAI,KAAK,CAAC,KAAM,QAAO;AAGrC,MAAI,aAAa,KAAK,KAAK,EAAE,YAAY;AAGzC,MAAI,SAAS,SAAS;AACpB,UAAM,WAAW,CAAC,OAAO,QAAQ,OAAO,SAAS,OAAO,OAAO;AAC/D,eAAW,UAAU,UAAU;AAC7B,UAAI,WAAW,WAAW,MAAM,GAAG;AACjC,qBAAa,WAAW,UAAU,OAAO,MAAM,EAAE,KAAK;AACtD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAIA,MAAI,SAAS,UAAU;AACrB,UAAM,WAAW,CAAC,OAAO,OAAO,OAAO,MAAM,MAAM,GAAG;AACtD,eAAW,UAAU,UAAU;AAE7B,YAAM,kBAAkB,IAAI,MAAM;AAClC,UAAI,WAAW,SAAS,eAAe,GAAG;AACxC,qBAAa,WACV,UAAU,GAAG,WAAW,SAAS,gBAAgB,MAAM,EACvD,KAAK;AACR;AAAA,MACF;AAEA,UAAI,WAAW,SAAS,MAAM,GAAG;AAC/B,qBAAa,WACV,UAAU,GAAG,WAAW,SAAS,OAAO,MAAM,EAC9C,KAAK;AACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,cAAc,UAAU;AACjC;;;ADpGO,SAAS,gBAAgB,WAA2B;AACzD,SAAO,IAAI,KAAK,SAAS,EAAE,YAAY;AACzC;AASA,eAAsB,eACpB,MAC+B;AAC/B,QAAM,cAAgC,CAAC;AAIvC,MAAIC,UAAS,KAAK,KAAK,KAAK,KAAK,OAAO;AACtC,UAAM,cAAc,MAAM,UAAU,KAAK,KAAK;AAC9C,QAAI,aAAa;AACf,kBAAY,KAAK,EAAE,cAAc,YAAY,CAAC;AAAA,IAChD;AAAA,EACF;AAGA,MAAIA,UAAS,KAAK,KAAK,KAAK,KAAK,OAAO;AACtC,UAAM,cAAc,MAAM,UAAU,KAAK,KAAK;AAC9C,QAAI,aAAa;AACf,kBAAY,KAAK,EAAE,aAAa,YAAY,CAAC;AAAA,IAC/C;AAAA,EACF;AAGA,QAAM,aACJ,KAAK,aAAa,KAAK,YAAY,KAAK,cAAc,KAAK;AAE7D,MAAI,YAAY;AACd,UAAM,UAAkC,CAAC;AAEzC,QAAIA,UAAS,KAAK,SAAS,KAAK,KAAK,WAAW;AAC9C,cAAQ,YAAY,MAAM,SAAS,KAAK,WAAW,OAAO;AAAA,IAC5D;AAEA,QAAIA,UAAS,KAAK,QAAQ,KAAK,KAAK,UAAU;AAC5C,cAAQ,aAAa,MAAM,SAAS,KAAK,UAAU,QAAQ;AAAA,IAC7D;AAGA,QAAIA,UAAS,KAAK,UAAU,KAAK,KAAK,YAAY;AAChD,cAAQ,aAAa,KAAK,WAAW,YAAY;AAAA,IACnD;AAGA,QAAIA,UAAS,KAAK,UAAU,KAAK,KAAK,YAAY;AAChD,cAAQ,aAAa,KAAK;AAAA,IAC5B;AAEA,QAAI,OAAO,KAAK,OAAO,EAAE,SAAS,GAAG;AACnC,kBAAY,KAAK,EAAE,QAAQ,CAAC;AAAA,IAC9B;AAAA,EACF;AAGA,MAAI,YAAY,WAAW,EAAG,QAAO;AAErC,SAAO;AAAA,IACL,iBAAiB,YAAY,MAAM,GAAG,EAAE;AAAA,EAC1C;AACF;AASO,SAAS,oBACd,MAC2B;AAC3B,QAAM,cAA6B,CAAC;AAGpC,MAAIA,UAAS,KAAK,KAAK,KAAK,KAAK,OAAO;AACtC,gBAAY,QAAQ,KAAK;AAAA,EAC3B;AACA,MAAIA,UAAS,KAAK,MAAM,KAAK,KAAK,QAAQ;AACxC,gBAAY,SAAS,KAAK;AAAA,EAC5B;AACA,MAAIA,UAAS,KAAK,MAAM,KAAK,KAAK,QAAQ;AACxC,gBAAY,SAAS,KAAK;AAAA,EAC5B;AACA,MAAIA,UAAS,KAAK,iBAAiB,KAAK,KAAK,mBAAmB;AAC9D,gBAAY,oBAAoB,KAAK;AAAA,EACvC;AAEA,SAAO,OAAO,KAAK,WAAW,EAAE,SAAS,IAAI,cAAc;AAC7D;AASO,SAAS,cACd,iBACqB;AACrB,MAAI,CAAC,gBAAiB,QAAO;AAE7B,QAAM,UAAmB,CAAC;AAG1B,MAAI,UAAU,gBAAgB,SAAS,GAAG;AACxC,YAAQ,aAAa,gBAAgB,YACjC,oBACA;AAAA,EACN;AAGA,MAAI,UAAU,gBAAgB,eAAe,GAAG;AAC9C,YAAQ,oBAAoB,gBAAgB,kBACxC,oBACA;AAAA,EACN;AAEA,SAAO,OAAO,KAAK,OAAO,EAAE,SAAS,IAAI,UAAU;AACrD;AAMA,eAAsB,YACpB,OACA,YACgB;AAChB,QAAM,mBAA0B;AAAA,IAC9B,gBAAgB,gBAAgB,MAAM,SAAS;AAAA,EACjD;AAGA,QAAM,OAAO,cAAc,CAAC;AAG5B,MAAIA,UAAS,KAAK,aAAa,KAAK,KAAK,eAAe;AACtD,qBAAiB,gBAAgB,KAAK,cAAc,UAAU,GAAG,GAAG;AAAA,EACtE;AAGA,MAAIA,UAAS,KAAK,QAAQ,KAAK,KAAK,UAAU;AAC5C,qBAAiB,WAAW,KAAK,SAAS,UAAU,GAAG,GAAG;AAAA,EAC5D;AAGA,MAAIA,UAAS,KAAK,MAAM,KAAK,KAAK,QAAQ;AACxC,qBAAiB,SAAS,KAAK,OAAO,UAAU,GAAG,GAAG;AAAA,EACxD;AAGA,QAAM,WAAW,MAAM,eAAe,IAAI;AAC1C,MAAI,UAAU;AACZ,qBAAiB,WAAW;AAAA,EAC9B;AAGA,QAAM,gBAAgB,oBAAoB,IAAI;AAC9C,MAAI,eAAe;AACjB,qBAAiB,gBAAgB;AAAA,EACnC;AAGA,MAAI,OAAO,KAAK,oBAAoB,UAAU;AAC5C,qBAAiB,kBAAkB,KAAK;AAAA,EAC1C;AAGA,MAAIA,UAAS,KAAK,QAAQ,KAAK,KAAK,UAAU;AAC5C,qBAAiB,WAAW,KAAK,SAAS,UAAU,GAAG,CAAC,EAAE,YAAY;AAAA,EACxE;AAGA,MAAI,KAAK,YAAY,OAAO,KAAK,aAAa,UAAU;AACtD,qBAAiB,WAAW,KAAK;AAAA,EACnC;AAGA,MAAIA,UAAS,KAAK,SAAS,KAAK,KAAK,WAAW;AAC9C,qBAAiB,YAAY,KAAK,UAAU,UAAU,GAAG,EAAE;AAAA,EAC7D;AAGA,MAAIA,UAAS,KAAK,aAAa,KAAK,KAAK,eAAe;AACtD,qBAAiB,gBAAgB,KAAK;AAAA,EACxC;AAGA,MAAIA,UAAS,KAAK,OAAO,KAAK,KAAK,SAAS;AAC1C,qBAAiB,gBAAgB,EAAE,SAAS,KAAK,QAAQ;AAAA,EAC3D;AAGA,MAAIA,UAAS,KAAK,WAAW,KAAK,KAAK,aAAa;AAClD,qBAAiB,cAAc,KAAK;AAAA,EACtC;AAGA,QAAM,gBAAyB,CAAC;AAGhC,MAAI,OAAO,KAAK,eAAe,WAAW;AACxC,kBAAc,aAAa,KAAK,aAC5B,oBACA;AAAA,EACN;AACA,MAAI,OAAO,KAAK,sBAAsB,WAAW;AAC/C,kBAAc,oBAAoB,KAAK,oBACnC,oBACA;AAAA,EACN;AAGA,MAAI,OAAO,KAAK,aAAa,EAAE,WAAW,GAAG;AAC3C,UAAM,eAAe,cAAc,MAAM,OAAO;AAChD,QAAI,cAAc;AAChB,uBAAiB,UAAU;AAAA,IAC7B;AAAA,EACF,OAAO;AACL,qBAAiB,UAAU;AAAA,EAC7B;AAEA,SAAO;AACT;;;AE5PA,SAAS,kBAAqC;AAI9C,IAAM,iBAAiB,CAAC,6CAA6C;AAK9D,IAAM,YAAN,cAAwB,MAAM;AAAA,EACnC,YACE,SACO,OACP;AACA,UAAM,OAAO;AAFN;AAGP,SAAK,OAAO;AAAA,EACd;AAAA,EAJS;AAKX;AAMA,SAAS,mBACP,QACA,QACwB;AACxB,MAAI,OAAO,gBAAgB,OAAW,QAAO,OAAO;AAEpD,QAAM,sBAAsB,OAAO,UAAU;AAC7C,MAAI,wBAAwB,QAAW;AACrC,WAAO;AAAA,MACL;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAaA,SAAS,iBAAiB,aAAyC;AACjE,MAAI,OAAO,gBAAgB,SAAU,QAAO;AAE5C,MAAI;AACF,UAAM,SAAyB,KAAK,MAAM,WAAW;AACrD,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,MACA,iBAAiB,QAAQ,QAAQ;AAAA,IACnC;AAAA,EACF;AACF;AAmBA,eAAsB,iBACpB,QACA,QACuB;AACvB,QAAM,EAAE,aAAa,SAAS,eAAe,IAAI,OAAO,YAAY,CAAC;AACrE,QAAM,cAAc,mBAAmB,QAAQ,MAAM;AAIrD,QAAM,oBAAoB,cACtB,iBAAiB,WAAW,IAC5B;AAEJ,MAAI;AACF,QAAI,mBAAmB;AACrB,YAAMC,QAAO,IAAI,WAAW;AAAA,QAC1B,aAAa;AAAA,QACb;AAAA,MACF,CAAC;AACD,aAAQ,MAAMA,MAAK,UAAU;AAAA,IAC/B;AAEA,QAAI,aAAa;AACf,YAAMA,QAAO,IAAI,WAAW;AAAA,QAC1B;AAAA,QACA;AAAA,MACF,CAAC;AACD,aAAQ,MAAMA,MAAK,UAAU;AAAA,IAC/B;AAEA,UAAM,OAAO,IAAI,WAAW,EAAE,OAAO,CAAC;AACtC,WAAQ,MAAM,KAAK,UAAU;AAAA,EAC/B,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,MACA,iBAAiB,QAAQ,QAAQ;AAAA,IACnC;AAAA,EACF;AACF;AAUA,eAAsB,eACpB,YACiB;AACjB,MAAI;AACF,UAAM,gBAAgB,MAAM,WAAW,eAAe;AAEtD,QAAI,CAAC,cAAc,OAAO;AACxB,YAAM,IAAI,UAAU,kCAAkC;AAAA,IACxD;AAEA,WAAO,cAAc;AAAA,EACvB,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR;AAAA,MACA,iBAAiB,QAAQ,QAAQ;AAAA,IACnC;AAAA,EACF;AACF;;;AH5IO,IAAM,OAAe,eAC1B,OACA,EAAE,QAAQ,MAAM,MAAM,WAAW,KAAK,OAAO,GAC7C;AAEA,QAAM,kBAAkB,UAAU,QAAQ,MAAM;AAChD,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA,eAAe;AAAA,IACf,MAAM;AAAA,IACN,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,gBAAgB;AAGpB,QAAM,iBAAiB,WACnB,MAAM,gBAAgB,OAAO,EAAE,KAAK,SAAS,GAAG,EAAE,UAAU,CAAC,IAC7D,CAAC;AACL,QAAM,eAAe,SACjB,MAAM,gBAAgB,OAAO,QAAQ,EAAE,UAAU,CAAC,IAClD;AACJ,QAAM,iBAAiB,WACnB,MAAM,gBAAgB,OAAO,UAAU,EAAE,UAAU,CAAC,IACpD;AACJ,QAAM,sBAAsB,gBACxB,MAAM,gBAAgB,OAAO,eAAe,EAAE,UAAU,CAAC,IACzD;AACJ,QAAM,0BAA0B,oBAC5B,MAAM,gBAAgB,OAAO,mBAAmB,EAAE,UAAU,CAAC,IAC7D;AAGJ,QAAM,yBACJ,OAAO,sBAAsB,YACzB,oBACA,OAAO,sBAAsB,YAAY,MAAM,UAC7C,MAAM,QAAQ,iBAAiB,IAC/B;AAER,QAAM,gCACJ,OAAO,6BAA6B,YAChC,2BACA,OAAO,6BAA6B,YAAY,MAAM,UACpD,MAAM,QAAQ,wBAAwB,IACtC;AAGR,QAAM,kBAA2C,CAAC;AAClD,MAAI,SAAS,cAAc,GAAG;AAC5B,WAAO,OAAO,iBAAiB,cAAc;AAAA,EAC/C;AACA,MAAI,iBAAiB,OAAW,iBAAgB,SAAS;AACzD,MAAI,mBAAmB,OAAW,iBAAgB,WAAW;AAC7D,MAAI,wBAAwB;AAC1B,oBAAgB,gBAAgB;AAClC,MAAI,4BAA4B;AAC9B,oBAAgB,oBAAoB;AACtC,MAAI,2BAA2B;AAC7B,oBAAgB,aAAa;AAC/B,MAAI,kCAAkC;AACpC,oBAAgB,oBAAoB;AAGtC,QAAM,aAAa,gBAAgB,OAC/B,MAAM,gBAAgB,OAAO,gBAAgB,MAAM,EAAE,UAAU,CAAC,IAChE,CAAC;AACL,QAAM,YAAY,SAAS,IAAI,IAAI,OAAO,CAAC;AAG3C,QAAM,YAAY;AAAA,IAChB,GAAG;AAAA,IACH,GAAI,SAAS,UAAU,IAAI,aAAa,CAAC;AAAA,IACzC,GAAG;AAAA,EACL;AAGA,QAAM,mBAAmB,MAAM,YAAY,OAAO,SAAS;AAG3D,MAAI,CAAC,iBAAiB,aAAa;AACjC,qBAAiB,cAAc;AAAA,EACjC;AAGA,MAAI,CAAC,iBAAiB,WAAW,gBAAgB;AAC/C,qBAAiB,UAAU;AAAA,EAC7B;AAGA,MAAI,CAAC,iBAAiB,eAAe;AACnC,WAAO,MAAM,2BAA2B;AAAA,EAC1C;AAGA,QAAM,oBAAoB,aAAa;AAAA,IACrC,CAAC,MAAM,EAAE,kBAAkB,gBAAgB;AAAA,EAC7C;AAEA,MAAI,qBAAqB,CAAC,iBAAiB,WAAW;AACpD,WAAO,MAAM,4CAA4C;AAAA,EAC3D;AAKA,QAAM,cAAmC;AAAA,IACvC,QAAQ,CAAC,gBAAgB;AAAA,IACzB;AAAA,IACA,UAAU;AAAA,EACZ;AAGA,MAAI,gBAAgB;AAClB,gBAAY,UAAU;AAAA,EACxB;AAEA,MAAI,cAAc;AAChB,gBAAY,eAAe;AAAA,EAC7B;AAEA,MAAI,eAAe;AACjB,gBAAY,gBAAgB;AAAA,EAC9B;AAEA,QAAM,aAAa,KAAK;AACxB,MAAI,CAAC,YAAY;AACf,WAAO,OAAO;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACJ,MAAI;AACF,kBAAc,MAAM,eAAe,UAAU;AAAA,EAC/C,SAAS,OAAO;AACd,WAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC;AAC/C,UAAM;AAAA,EACR;AAEA,QAAM,UAAU,KAAK,SAAS;AAC9B,QAAM,WAAW,GAAG,GAAG;AAEvB,SAAO,MAAM,+BAA+B;AAAA,IAC1C;AAAA,IACA,YAAY,YAAY,OAAO;AAAA,IAC/B,cAAc,aAAa;AAAA,IAC3B;AAAA,EACF,CAAC;AAED,QAAM,WAAW,MAAM,QAAQ,UAAU;AAAA,IACvC,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,eAAe,UAAU,WAAW;AAAA,MACpC,gBAAgB;AAAA,IAClB;AAAA,IACA,MAAM,KAAK,UAAU,WAAW;AAAA,EAClC,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,YAAY,MAAM,SAAS,KAAK;AACtC,WAAO,MAAM,2BAA2B,SAAS,MAAM,MAAM,SAAS,EAAE;AAAA,EAC1E;AAEA,QAAM,SAA+B,MAAM,SAAS,KAAK;AAEzD,SAAO,MAAM,gBAAgB;AAAA,IAC3B,QAAQ,SAAS;AAAA,IACjB,WAAW,OAAO;AAAA,EACpB,CAAC;AAGD,MAAI,OAAO,oBAAoB,OAAO,iBAAiB,SAAS,GAAG;AACjE,WAAO;AAAA,MACL,sBAAsB,KAAK,UAAU,OAAO,gBAAgB,CAAC;AAAA,IAC/D;AAAA,EACF;AACF;;;AI/LA;;;ACOO,IAAM,yBAA+C;AAAA,EAC1D,MAAM;AAAA,EAEN,QAAQ,CAAC;AAAA,EAET,MAAM,KAAK,EAAE,QAAQ,eAAe,KAAK,OAAO,GAAG;AAEjD,UAAM,SAAS,UAAU,eAAe,MAAM;AAE9C,QAAI;AACF,YAAM,aAAa,MAAM,iBAAiB,QAAQ,MAAM;AACxD,aAAO,MAAM,qBAAqB;AAElC,aAAO;AAAA,QACL,GAAG;AAAA,QACH,KAAK;AAAA,UACH,GAAG;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,aAAO;AAAA,QACL,uCAAuC,iBAAiB,QAAQ,MAAM,UAAU,eAAe;AAAA,MACjG;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,OAAO,SAAS;AACzB,WAAO,MAAM,KAAK,OAAO,OAAO;AAAA,EAClC;AACF;AAEA,IAAO,gBAAQ;","names":["isString","isString","auth"]}