@tagadapay/headless-sdk 1.22.0 → 1.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +1 -1
- package/dist/core/client.js.map +1 -1
- package/dist/core/helpers/checkoutRisk.d.ts +29 -0
- package/dist/core/helpers/checkoutRisk.d.ts.map +1 -0
- package/dist/core/helpers/checkoutRisk.js +107 -0
- package/dist/core/helpers/checkoutRisk.js.map +1 -0
- package/dist/core/helpers/paymentsApi.d.ts +5 -0
- package/dist/core/helpers/paymentsApi.d.ts.map +1 -1
- package/dist/core/helpers/paymentsApi.js +30 -0
- package/dist/core/helpers/paymentsApi.js.map +1 -1
- package/dist/core/modules/checkout.d.ts.map +1 -1
- package/dist/core/modules/checkout.js +3 -0
- package/dist/core/modules/checkout.js.map +1 -1
- package/dist/core/modules/offers.d.ts +2 -1
- package/dist/core/modules/offers.d.ts.map +1 -1
- package/dist/core/modules/offers.js +6 -2
- package/dist/core/modules/offers.js.map +1 -1
- package/dist/core/modules/payment.d.ts.map +1 -1
- package/dist/core/modules/payment.js +12 -0
- package/dist/core/modules/payment.js.map +1 -1
- package/dist/core/modules/track.d.ts +10 -1
- package/dist/core/modules/track.d.ts.map +1 -1
- package/dist/core/modules/track.js +89 -3
- package/dist/core/modules/track.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/pixels/engine.d.ts +3 -3
- package/dist/pixels/engine.d.ts.map +1 -1
- package/dist/pixels/engine.js +12 -8
- package/dist/pixels/engine.js.map +1 -1
- package/dist/pixels/index.d.ts +3 -3
- package/dist/pixels/index.d.ts.map +1 -1
- package/dist/pixels/index.js +1 -1
- package/dist/pixels/index.js.map +1 -1
- package/dist/pixels/pixelIdentity.d.ts +23 -0
- package/dist/pixels/pixelIdentity.d.ts.map +1 -1
- package/dist/pixels/pixelIdentity.js +23 -0
- package/dist/pixels/pixelIdentity.js.map +1 -1
- package/dist/pixels/pixelMapping.d.ts +50 -6
- package/dist/pixels/pixelMapping.d.ts.map +1 -1
- package/dist/pixels/pixelMapping.js +259 -11
- package/dist/pixels/pixelMapping.js.map +1 -1
- package/dist/pixels/pixelPurchaseHanded.d.ts +5 -0
- package/dist/pixels/pixelPurchaseHanded.d.ts.map +1 -0
- package/dist/pixels/pixelPurchaseHanded.js +135 -0
- package/dist/pixels/pixelPurchaseHanded.js.map +1 -0
- package/dist/pixels/pixelTracker.d.ts +26 -8
- package/dist/pixels/pixelTracker.d.ts.map +1 -1
- package/dist/pixels/pixelTracker.js +292 -28
- package/dist/pixels/pixelTracker.js.map +1 -1
- package/dist/pixels/types.d.ts +18 -2
- package/dist/pixels/types.d.ts.map +1 -1
- package/dist/pixels/types.js +1 -0
- package/dist/pixels/types.js.map +1 -1
- package/dist/tagada-headless-commerce.min.js +2 -2
- package/dist/tagada-headless-commerce.min.js.map +3 -3
- package/dist/tagada-headless-react.min.js +2 -2
- package/dist/tagada-headless-react.min.js.map +4 -4
- package/dist/tagada-headless.js +191 -11
- package/dist/tagada-headless.min.js +2 -2
- package/dist/tagada-headless.min.js.map +4 -4
- package/dist/tagada-pixels.min.js +2 -2
- package/dist/tagada-pixels.min.js.map +4 -4
- package/dist/tgd/contract/envelope.d.ts +1 -1
- package/dist/tgd/contract/envelope.d.ts.map +1 -1
- package/dist/tgd/contract/registry.d.ts +10 -3
- package/dist/tgd/contract/registry.d.ts.map +1 -1
- package/dist/tgd/contract/registry.js +3 -2
- package/dist/tgd/contract/registry.js.map +1 -1
- package/dist/tgd/contract/unions.d.ts +1 -1
- package/dist/tgd/contract/unions.d.ts.map +1 -1
- package/dist/tgd/contract/unions.js +1 -1
- package/dist/tgd/contract/unions.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/pixels/index.ts", "../src/pixels/pixelMapping.ts", "../src/pixels/
|
|
4
|
-
"sourcesContent": ["export { createPixelEngine, SDK_PIXEL_PROVIDERS } from './engine.js';\nexport type {\n PixelEngine, PixelEngineConfig, PixelSignal, PixelSignalKind, SdkPixelProvider,\n} from './engine.js';\n\nexport { makeMetaEventId } from './metaEventId.js';\nexport { bootstrapPixelTrackerFromWindow, createPixelTracker, isSafePixelId } from './pixelTracker.js';\nexport type { PixelTracker, TrackOptions } from './pixelTracker.js';\nexport { buildGa4PurchasePayload, getEligiblePixels, isEventEnabled, pixelIdKeyOf, resolvePixelEvents } from './pixelMapping.js';\nexport type { PixelProviderKey, StandardPixelEvent } from './pixelMapping.js';\nexport type { PixelRawIdentity } from './pixelIdentity.js';\nexport type { PixelConfig, PixelsConfig } from './types.js';\n", "/**\n * Core pixel event mapping, parameter transformation, and event gating.\n *\n * This module is framework-agnostic (no React, no DOM) so it can be shared\n * between the React `PixelTrackingProvider` and the standalone vanilla SDK.\n *\n * Official event name references (verified Feb 2026 against vendor docs):\n * Meta: fbq('track', 'Purchase', { value, currency }) \u2014 developers.facebook.com/docs/meta-pixel/reference\n * TikTok: ttq.track('Purchase', { value, currency }) \u2014 ads.tiktok.com/help/article/standard-events-parameters (Sep 2025)\n * Snapchat: snaptr('track', 'PURCHASE', { price, currency }) \u2014 developers.snap.com/api/marketing-api/Conversions-API/Parameters\n * Pinterest: pintrk('track', 'checkout', { value, currency }) \u2014 help.pinterest.com/en/business/article/add-event-codes\n * GTM/GA4: gtag('event', 'purchase', { value, currency, items })\n * Clarity: clarity('event', 'Purchase') \u2014 learn.microsoft.com/en-us/clarity/setup-and-installation/clarity-api\n */\n\nimport type {\n PixelTrackingConfig,\n SnapchatTrackingConfig,\n GTMTrackingConfig,\n ClarityTrackingConfig,\n PixelConfig,\n PixelsConfig,\n} from './types.js';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type StandardPixelEvent =\n | 'PageView'\n | 'ViewContent'\n | 'AddToCart'\n | 'AddToWishlist'\n | 'Search'\n | 'InitiateCheckout'\n | 'AddPaymentInfo'\n | 'Purchase'\n | 'Lead'\n | 'CompleteRegistration'\n | 'Conversion';\n\nexport type PixelProviderKey = 'facebook' | 'tiktok' | 'snapchat' | 'pinterest' | 'gtm' | 'clarity';\n\n/** The field a pixel entry carries its tracking id in. */\nexport type PixelIdKey = 'pixelId' | 'containerId' | 'projectId';\n\n/**\n * Which key holds this entry's id: GTM stores a `containerId`, Clarity a\n * `projectId`, every other provider a `pixelId`. Callers that sanitize, split\n * or display an id go through here rather than testing the keys themselves,\n * so a new provider with its own field name is one edit, not six.\n */\nexport function pixelIdKeyOf(pixel: unknown): PixelIdKey {\n if (pixel && typeof pixel === 'object') {\n if ('containerId' in pixel) return 'containerId';\n if ('projectId' in pixel) return 'projectId';\n }\n return 'pixelId';\n}\n\nexport interface MappedEvent {\n name: string;\n params: Record<string, unknown>;\n}\n\n// ---------------------------------------------------------------------------\n// GA4-only enrichment\n//\n// Canonical GA4 ecommerce `purchase` data carries user identity + a nested\n// `ecommerce` object that the flat Meta/TikTok payload does not. We attach it\n// to the shared track() params under the reserved `_ga4` key. ONLY mapGTMEvent\n// reads it; `baseTransform` strips it so it can never leak into the\n// Meta/TikTok/Snapchat/Pinterest payloads (those would otherwise spread it,\n// shipping unhashed PII to those pixels). All monetary fields are in MINOR\n// units here \u2014 mapGTMEvent converts to major via the same currency helpers.\n// ---------------------------------------------------------------------------\n\nexport const GA4_PARAM_KEY = '_ga4' as const;\n\nexport interface Ga4UserData {\n email_address?: string;\n phone_number?: string;\n address?: {\n first_name?: string;\n last_name?: string;\n street?: string;\n city?: string;\n region?: string;\n postal_code?: string;\n country?: string;\n };\n}\n\nexport interface Ga4Item {\n item_id?: string;\n item_name?: string;\n item_variant?: string;\n /** Minor units (cents). Post-discount unit price (GA4 spec). Converted to major by mapGTMEvent. */\n price?: number;\n quantity?: number;\n /** Minor units (cents). Per-unit monetary discount (line-level + allocated order-level). */\n discount?: number;\n /** Coupon code(s) that discounted this item. */\n coupon?: string;\n}\n\nexport interface Ga4PurchasePayload {\n user_id?: string;\n user_data?: Ga4UserData;\n /** Minor units (cents). */\n value?: number;\n /** Minor units (cents). */\n tax?: number;\n /** Minor units (cents). */\n shipping?: number;\n /** Order-level coupon code(s), comma-joined. */\n coupon?: string;\n items: Ga4Item[];\n}\n\n/** Loose order shape accepted by buildGa4PurchasePayload (subset of SDK Order). */\nexport interface Ga4OrderInput {\n id?: string;\n currency?: string;\n paidAmount?: number;\n items?: Array<{\n productId?: string;\n variantId?: string | null;\n quantity?: number;\n /** Pre-discount unit amount (minor units). */\n amount?: number;\n adjustedAmount?: number;\n orderLineItemProduct?: { name?: string };\n orderLineItemVariant?: { name?: string };\n }>;\n summaries?: Array<{\n currency?: string;\n totalTaxAmount?: number;\n shippingCost?: number;\n totalAdjustedAmount?: number;\n totalPromotionAmount?: number;\n }>;\n /**\n * Applied promotions. Accepts both shapes seen in the wild:\n * promotion-usage rows with a nested `promotion` (CMS order endpoint) and\n * flat promotion summaries with a `code` (SDK OrderWithRelations).\n */\n promotions?: Array<{\n code?: string | null;\n promotion?: { code?: string | null } | null;\n }>;\n customer?: { id?: string; email?: string; phone?: string; firstName?: string; lastName?: string };\n billingAddress?: Ga4Address;\n shippingAddress?: Ga4Address;\n}\n\n/**\n * Extract the distinct coupon codes applied to an order, comma-joined.\n * Returns undefined when the order carries no coded promotions (automatic\n * promotions have `code: null` and are deliberately excluded \u2014 GA4's `coupon`\n * dimension is for codes the shopper entered).\n */\nexport function extractCouponCodes(order: Pick<Ga4OrderInput, 'promotions'>): string | undefined {\n const codes = (order.promotions ?? [])\n .map((p) => p.code ?? p.promotion?.code)\n .filter((c): c is string => typeof c === 'string' && c.length > 0);\n if (codes.length === 0) return undefined;\n return [...new Set(codes)].join(',');\n}\n\ninterface Ga4Address {\n firstName?: string;\n lastName?: string;\n address1?: string;\n city?: string;\n state?: string;\n postal?: string;\n country?: string;\n phone?: string;\n}\n\n/**\n * Build the GA4-only enrichment payload (`_ga4`) from an order. Pure, defensive,\n * framework-agnostic \u2014 shared by the native ThankYouPage and the Studio\n * OrderConfirmation island so both emit an identical canonical GA4 purchase.\n * Returns minor-unit amounts; mapGTMEvent converts them to major units.\n */\nexport function buildGa4PurchasePayload(order: Ga4OrderInput): Ga4PurchasePayload {\n const sourceItems = order.items ?? [];\n const coupon = extractCouponCodes(order);\n\n const summary =\n order.summaries?.find((s) => s.currency === order.currency) ?? order.summaries?.[0];\n\n const itemsSum = sourceItems.reduce(\n (sum, i) => sum + (i.adjustedAmount ?? 0) * (i.quantity ?? 0),\n 0,\n );\n\n // GA4 requires order-level discounts to be allocated across items: `price`\n // must be the post-discount unit price and `discount` the per-unit monetary\n // discount. Line-level discounts are already baked into adjustedAmount; the\n // order-level remainder (totalPromotionAmount minus line-level discounts,\n // capped to the item subtotal \u2014 promos can also cover shipping) is spread\n // proportionally by line value.\n const lineLevelDiscountTotal = sourceItems.reduce(\n (sum, i) => sum + Math.max(0, (i.amount ?? i.adjustedAmount ?? 0) - (i.adjustedAmount ?? 0)) * (i.quantity ?? 0),\n 0,\n );\n const orderLevelDiscount = Math.min(\n Math.max(0, (summary?.totalPromotionAmount ?? 0) - lineLevelDiscountTotal),\n itemsSum,\n );\n\n let remainingAllocation = orderLevelDiscount;\n const items: Ga4Item[] = sourceItems.map((item, index) => {\n const quantity = item.quantity ?? 0;\n const unitAdjusted = item.adjustedAmount ?? 0;\n const lineValue = unitAdjusted * quantity;\n\n // Last item takes the remainder so allocations sum exactly.\n const lineAllocation =\n orderLevelDiscount === 0 || itemsSum === 0\n ? 0\n : index === sourceItems.length - 1\n ? remainingAllocation\n : Math.round((orderLevelDiscount * lineValue) / itemsSum);\n remainingAllocation -= lineAllocation;\n\n const unitAllocation = quantity > 0 ? lineAllocation / quantity : 0;\n const lineLevelUnitDiscount = Math.max(0, (item.amount ?? unitAdjusted) - unitAdjusted);\n const unitDiscount = lineLevelUnitDiscount + unitAllocation;\n\n const ga4Item: Ga4Item = {\n item_id: item.productId || undefined,\n // GA4 convention: item_name = product, item_variant = variant.\n item_name: item.orderLineItemProduct?.name || item.orderLineItemVariant?.name || undefined,\n item_variant: item.orderLineItemVariant?.name || undefined,\n price: unitAdjusted - unitAllocation,\n quantity: item.quantity,\n };\n if (unitDiscount > 0) {\n ga4Item.discount = unitDiscount;\n if (coupon) ga4Item.coupon = coupon;\n }\n return ga4Item;\n });\n\n // Prefer the captured paid amount; fall back to the summary total, then to\n // the sum of line items. Guards against the value:0 seen in the field.\n const value =\n order.paidAmount && order.paidAmount > 0\n ? order.paidAmount\n : (summary?.totalAdjustedAmount ?? itemsSum);\n\n const payload: Ga4PurchasePayload = { items, value };\n if (summary?.totalTaxAmount != null) payload.tax = summary.totalTaxAmount;\n if (summary?.shippingCost != null) payload.shipping = summary.shippingCost;\n if (coupon) payload.coupon = coupon;\n\n if (order.customer?.id) payload.user_id = order.customer.id;\n\n const addr = order.billingAddress ?? order.shippingAddress;\n const userData: Ga4UserData = {};\n if (order.customer?.email) userData.email_address = order.customer.email;\n const phone = order.customer?.phone || addr?.phone;\n if (phone) userData.phone_number = phone;\n if (addr) {\n const address = {\n first_name: addr.firstName || order.customer?.firstName || undefined,\n last_name: addr.lastName || order.customer?.lastName || undefined,\n street: addr.address1 || undefined,\n city: addr.city || undefined,\n region: addr.state || undefined,\n postal_code: addr.postal || undefined,\n country: addr.country || undefined,\n };\n if (Object.values(address).some((v) => v != null)) userData.address = address;\n }\n if (Object.keys(userData).length > 0) payload.user_data = userData;\n\n return payload;\n}\n\n// ---------------------------------------------------------------------------\n// Currency conversion helper (inline, zero-dep)\n// ---------------------------------------------------------------------------\n\n/**\n * Convert minor units (cents) to major units using ISO 4217 digit counts.\n * Falls back to \u00F7100 for unknown currencies.\n */\nconst ZERO_DECIMAL_CURRENCIES = new Set([\n 'BIF', 'CLP', 'DJF', 'GNF', 'ISK', 'JPY', 'KMF', 'KRW',\n 'PYG', 'RWF', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF',\n]);\n\nconst THREE_DECIMAL_CURRENCIES = new Set(['BHD', 'IQD', 'JOD', 'KWD', 'LYD', 'OMR', 'TND']);\n\nfunction minorToMajor(amount: number, currency: string): number {\n const code = currency.toUpperCase();\n if (ZERO_DECIMAL_CURRENCIES.has(code)) return amount;\n if (THREE_DECIMAL_CURRENCIES.has(code)) return amount / 1000;\n return amount / 100;\n}\n\n// ---------------------------------------------------------------------------\n// Event gating \u2013 respects per-event toggles\n// ---------------------------------------------------------------------------\n\n/**\n * Returns `true` if the given event is enabled on the pixel config.\n * If the pixel has no `events` map (e.g. MetaConversionTrackingConfig) we allow all.\n */\nexport function isEventEnabled(pixel: PixelConfig, eventName: StandardPixelEvent): boolean {\n if (!('events' in pixel) || !pixel.events) return true;\n const events = pixel.events as Record<string, boolean>;\n if (!(eventName in events)) return true; // unknown event \u2192 allow\n return events[eventName] === true;\n}\n\n/**\n * Filter an array of pixel configs to only those that are globally enabled\n * AND have the specific event toggled on.\n */\nexport function getEligiblePixels<T extends PixelConfig>(\n pixels: T[] | undefined,\n eventName: StandardPixelEvent,\n): T[] {\n if (!pixels) return [];\n return pixels.filter((p) => p.enabled && isEventEnabled(p, eventName));\n}\n\n// ---------------------------------------------------------------------------\n// Shared parameter transforms\n// ---------------------------------------------------------------------------\n\nfunction ensureCurrencyUppercase(params: Record<string, unknown>): Record<string, unknown> {\n if (params.currency && typeof params.currency === 'string') {\n return { ...params, currency: params.currency.toUpperCase() };\n }\n return { ...params };\n}\n\nfunction convertValueToMajor(params: Record<string, unknown>): Record<string, unknown> {\n if (params.currency && params.value != null) {\n const currency = String(params.currency);\n const major = minorToMajor(Number(params.value), currency);\n return { ...params, value: major };\n }\n return params;\n}\n\n/** Convert top-level monetary fields (shipping, tax, subtotal, total_discount) from minor \u2192 major units. */\nfunction convertMonetaryFieldsToMajor(params: Record<string, unknown>): Record<string, unknown> {\n const currency = params.currency ? String(params.currency) : null;\n if (!currency) return params;\n const result = { ...params };\n for (const field of ['shipping', 'tax', 'subtotal', 'total_discount'] as const) {\n if (result[field] != null) {\n result[field] = minorToMajor(Number(result[field]), currency);\n }\n }\n return result;\n}\n\n/** Convert price fields inside contents[] items from minor \u2192 major units. */\nfunction convertContentsPricesToMajor(params: Record<string, unknown>): Record<string, unknown> {\n if (!params.contents || !Array.isArray(params.contents)) return params;\n const currency = params.currency ? String(params.currency) : null;\n const result = { ...params };\n result.contents = (params.contents as Record<string, unknown>[]).map((item) => {\n const itemCurrency = item.currency ? String(item.currency) : currency;\n if (!itemCurrency) return { ...item };\n const converted = { ...item };\n if (converted.price != null) converted.price = minorToMajor(Number(converted.price), itemCurrency);\n if (converted.original_price != null) converted.original_price = minorToMajor(Number(converted.original_price), itemCurrency);\n return converted;\n });\n return result;\n}\n\nfunction baseTransform(params: Record<string, unknown>): Record<string, unknown> {\n let p = ensureCurrencyUppercase(params);\n p = convertValueToMajor(p);\n p = convertMonetaryFieldsToMajor(p);\n p = convertContentsPricesToMajor(p);\n // Strip GA4-only enrichment so it never reaches Meta/TikTok/Snapchat/Pinterest\n // (those mappers spread all params). mapGTMEvent reads it from the raw input.\n if (GA4_PARAM_KEY in p) {\n p = { ...p };\n delete p[GA4_PARAM_KEY];\n }\n return p;\n}\n\n// ---------------------------------------------------------------------------\n// Meta / Facebook\n// ---------------------------------------------------------------------------\n\nconst META_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'PageView',\n ViewContent: 'ViewContent',\n AddToCart: 'AddToCart',\n AddToWishlist: 'AddToWishlist',\n Search: 'Search',\n InitiateCheckout: 'InitiateCheckout',\n AddPaymentInfo: 'AddPaymentInfo',\n Purchase: 'Purchase',\n Lead: 'Lead',\n CompleteRegistration: 'CompleteRegistration',\n};\n\nexport function mapMetaEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = META_EVENT_MAP[eventName] ?? eventName;\n // `coupon` intentionally flows through: Meta has no standard coupon param but\n // accepts custom parameters on standard events (usable in custom conversions).\n const params = baseTransform(parameters);\n\n if (params.contents && Array.isArray(params.contents)) {\n params.content_ids = (params.contents as Record<string, unknown>[]).map((i) => i.content_id).filter(Boolean);\n params.content_type = params.content_type ?? 'product';\n\n // Reshape contents to Meta's expected format (prices already converted by baseTransform)\n params.contents = (params.contents as Record<string, unknown>[]).map((item) => ({\n id: item.content_id,\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n item_price: item.price != null ? Number(item.price) : undefined,\n content_name: item.content_name,\n content_category: item.content_category,\n }));\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// TikTok\n// Official: ttq.track('Purchase', { value, currency })\n// Source: ads.tiktok.com/help/article/standard-events-parameters (Sep 2025)\n// Standard events use PascalCase. Note: TikTok has no standard PageView event\n// (page views use ttq.page()), so we pass it as-is for custom tracking.\n// TikTok has no Lead event; SubmitForm is the closest standard equivalent.\n// ---------------------------------------------------------------------------\n\nconst TIKTOK_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'Pageview',\n ViewContent: 'ViewContent',\n AddToCart: 'AddToCart',\n AddToWishlist: 'AddToWishlist',\n Search: 'Search',\n InitiateCheckout: 'InitiateCheckout',\n AddPaymentInfo: 'AddPaymentInfo',\n Purchase: 'Purchase',\n Lead: 'SubmitForm',\n CompleteRegistration: 'CompleteRegistration',\n};\n\nexport function mapTikTokEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = TIKTOK_EVENT_MAP[eventName] ?? eventName;\n const params = baseTransform(parameters);\n\n // TikTok's event spec has no coupon/discount parameter \u2014 strip it to keep\n // the payload within spec (avoids Events Manager diagnostics warnings).\n delete params.coupon;\n\n if (params.contents && Array.isArray(params.contents)) {\n const ids = (params.contents as Record<string, unknown>[])\n .map((i) => i.content_id)\n .filter(Boolean) as string[];\n\n // TikTok requires content_id (singular) at the top level for VSA\n if (!params.content_id && ids.length > 0) {\n params.content_id = ids.length === 1 ? ids[0] : JSON.stringify(ids);\n }\n\n // Also keep content_ids for backwards compatibility\n if (!params.content_ids) {\n params.content_ids = ids;\n }\n\n // Reshape contents to TikTok's expected format (prices already converted by baseTransform)\n params.contents = (params.contents as Record<string, unknown>[]).map((item) => ({\n content_id: item.content_id,\n content_name: item.content_name,\n content_type: item.content_type ?? 'product',\n content_category: item.content_category,\n price: item.price != null ? Number(item.price) : undefined,\n original_price: item.original_price != null ? Number(item.original_price) : undefined,\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n description: item.description,\n }));\n }\n\n // Set required fields for InitiateCheckout\n if (eventName === 'InitiateCheckout') {\n params.content_type = params.content_type ?? 'product';\n if (!params.delivery_category) {\n params.delivery_category = 'home_delivery';\n }\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// Snapchat\n// Official: snaptr('track', 'PURCHASE', { price, currency })\n// Source: developers.snap.com/api/marketing-api/Conversions-API/Parameters\n// All event names are UPPER_SNAKE_CASE.\n// Note: Snapchat has no LEAD standard event; we pass it as-is (custom event).\n// ---------------------------------------------------------------------------\n\nconst SNAPCHAT_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'PAGE_VIEW',\n ViewContent: 'VIEW_CONTENT',\n AddToCart: 'ADD_CART',\n AddToWishlist: 'ADD_TO_WISHLIST',\n Search: 'SEARCH',\n InitiateCheckout: 'START_CHECKOUT',\n AddPaymentInfo: 'ADD_BILLING',\n Purchase: 'PURCHASE',\n Lead: 'LEAD',\n CompleteRegistration: 'SIGN_UP',\n};\n\nexport function mapSnapchatEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = SNAPCHAT_EVENT_MAP[eventName] ?? eventName;\n let params = baseTransform(parameters);\n\n // Snap's parameter spec has no coupon/discount field \u2014 strip it.\n delete params.coupon;\n\n // Snapchat uses `price` not `value`\n if ('value' in params) {\n params = { ...params, price: params.value };\n delete params.value;\n }\n\n // Snapchat uses `number_items` not `num_items`\n if ('num_items' in params) {\n params = { ...params, number_items: params.num_items };\n delete params.num_items;\n }\n\n if (params.contents && Array.isArray(params.contents)) {\n params.item_ids = (params.contents as { content_id?: string }[]).map((i) => i.content_id).filter(Boolean);\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// Pinterest\n// Official: pintrk('track', 'checkout', { value, currency, line_items })\n// Event names are all lowercase.\n// ---------------------------------------------------------------------------\n\nconst PINTEREST_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'pagevisit',\n ViewContent: 'viewcontent',\n AddToCart: 'addtocart',\n AddToWishlist: 'addtowishlist',\n Search: 'search',\n InitiateCheckout: 'initiatecheckout',\n AddPaymentInfo: 'addpaymentinfo',\n Purchase: 'checkout',\n Lead: 'lead',\n CompleteRegistration: 'signup',\n};\n\nexport function mapPinterestEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = PINTEREST_EVENT_MAP[eventName] ?? eventName.toLowerCase();\n const params = baseTransform(parameters);\n\n // Pinterest's official field for coupon codes is `promo_code`.\n if (params.coupon != null) {\n params.promo_code = params.coupon;\n delete params.coupon;\n }\n\n if (params.order_quantity !== undefined) {\n params.order_quantity = Number(params.order_quantity);\n }\n\n if (params.contents && Array.isArray(params.contents)) {\n // Reshape to Pinterest line_items format (prices already converted by baseTransform)\n params.line_items = (params.contents as Record<string, unknown>[]).map((item) => ({\n product_id: item.content_id,\n product_name: item.content_name,\n product_category: item.content_category,\n product_price: item.price != null ? Number(item.price) : undefined,\n product_quantity: item.quantity != null ? Number(item.quantity) : undefined,\n }));\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// GTM / GA4 / Google Ads\n// Official: gtag('event', 'purchase', { value, currency, items })\n// Event names are snake_case (GA4 convention).\n// ---------------------------------------------------------------------------\n\nconst GTM_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'page_view',\n ViewContent: 'view_item',\n AddToCart: 'add_to_cart',\n AddToWishlist: 'add_to_wishlist',\n Search: 'search',\n InitiateCheckout: 'begin_checkout',\n AddPaymentInfo: 'add_payment_info',\n Purchase: 'purchase',\n Lead: 'generate_lead',\n CompleteRegistration: 'sign_up',\n Conversion: 'conversion',\n};\n\nexport function mapGTMEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = GTM_EVENT_MAP[eventName] ?? eventName.toLowerCase();\n\n // Canonical GA4 ecommerce shape: when the caller attached `_ga4` enrichment\n // (purchase from the thank-you page) emit a nested `ecommerce` object plus\n // user identity instead of the legacy flat payload. baseTransform strips\n // `_ga4`, so read it from the raw input first.\n const ga4 = parameters[GA4_PARAM_KEY] as Ga4PurchasePayload | undefined;\n if (ga4) {\n const currency =\n typeof parameters.currency === 'string' ? parameters.currency.toUpperCase() : undefined;\n const toMajor = (v: number | undefined): number | undefined =>\n v == null || !currency ? v : minorToMajor(Number(v), currency);\n\n const ecommerce: Record<string, unknown> = {\n transaction_id: parameters.transaction_id,\n currency,\n value: toMajor(ga4.value),\n };\n if (ga4.tax != null) ecommerce.tax = toMajor(ga4.tax);\n if (ga4.shipping != null) ecommerce.shipping = toMajor(ga4.shipping);\n if (ga4.coupon) ecommerce.coupon = ga4.coupon;\n ecommerce.items = (ga4.items ?? []).map((item) => ({\n item_id: item.item_id,\n item_name: item.item_name,\n item_variant: item.item_variant,\n price: toMajor(item.price),\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n ...(item.discount != null ? { discount: toMajor(item.discount) } : {}),\n ...(item.coupon ? { coupon: item.coupon } : {}),\n }));\n\n const out: Record<string, unknown> = { ecommerce };\n if (ga4.user_id) out.user_id = ga4.user_id;\n if (ga4.user_data) out.user_data = ga4.user_data;\n return { name, params: out };\n }\n\n const params = baseTransform(parameters);\n\n if (params.num_items !== undefined) {\n params.num_items = Number(params.num_items);\n }\n\n if (params.contents && Array.isArray(params.contents)) {\n // Reshape to GA4 items format (prices already converted by baseTransform)\n params.items = (params.contents as Record<string, unknown>[]).map((item) => ({\n item_id: item.content_id,\n item_name: item.content_name,\n item_category: item.content_category,\n price: item.price != null ? Number(item.price) : undefined,\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n }));\n\n params.contents = (params.contents as Record<string, unknown>[]).map((item) => ({\n id: item.content_id,\n name: item.content_name,\n category: item.content_category,\n price: item.price != null ? Number(item.price) : undefined,\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n }));\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// Microsoft Clarity\n// Official: clarity('event', 'Purchase') \u2014 custom (\"smart\") events take a name\n// and no parameters, so the mapped params are carried for the dedup guard only.\n// Clarity records page views by itself; the PageView toggle still emits a named\n// event so a merchant can filter recordings on it like any other funnel step.\n// ---------------------------------------------------------------------------\n\nconst CLARITY_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'PageView',\n ViewContent: 'ViewContent',\n AddToCart: 'AddToCart',\n AddToWishlist: 'AddToWishlist',\n Search: 'Search',\n InitiateCheckout: 'InitiateCheckout',\n AddPaymentInfo: 'AddPaymentInfo',\n Purchase: 'Purchase',\n Lead: 'Lead',\n CompleteRegistration: 'CompleteRegistration',\n};\n\nexport function mapClarityEvent(\n eventName: StandardPixelEvent,\n parameters: Record<string, unknown>,\n): MappedEvent {\n const name = CLARITY_EVENT_MAP[eventName] ?? eventName;\n return { name, params: baseTransform(parameters) };\n}\n\nfunction googleAdsTag(id: unknown): string {\n const text = String(id).trim();\n return /^\\d+$/.test(text) ? `AW-${text}` : text;\n}\n\n/**\n * Append Google Ads `send_to` parameter when conversion tracking is configured.\n */\nexport function applyGoogleAdsConversion(\n params: Record<string, unknown>,\n eventName: StandardPixelEvent,\n pixel: GTMTrackingConfig,\n): Record<string, unknown> {\n if (\n (eventName === 'Purchase' || eventName === 'Conversion') &&\n pixel.googleAdsConversionId &&\n pixel.googleAdsConversionLabel\n ) {\n // Merchants paste the bare number Google Ads shows; `send_to` wants it as `AW-<number>`.\n return {\n ...params,\n send_to: `${googleAdsTag(pixel.googleAdsConversionId)}/${pixel.googleAdsConversionLabel}`,\n };\n }\n return params;\n}\n\n// ---------------------------------------------------------------------------\n// Dispatcher \u2013 maps a StandardPixelEvent to all providers in one call\n// ---------------------------------------------------------------------------\n\nexport interface ProviderEvent {\n provider: PixelProviderKey;\n mapped: MappedEvent;\n pixel: PixelConfig;\n}\n\n/**\n * Given a PixelsConfig and an event, return per-provider mapped events\n * for every eligible (enabled + event-toggled-on) pixel.\n */\nexport function resolvePixelEvents(\n pixels: PixelsConfig,\n eventName: StandardPixelEvent,\n parameters: Record<string, unknown>,\n): ProviderEvent[] {\n const results: ProviderEvent[] = [];\n\n const fb = getEligiblePixels(pixels.facebook, eventName);\n if (fb.length > 0) {\n const mapped = mapMetaEvent(eventName, parameters);\n fb.forEach((pixel) => results.push({ provider: 'facebook', mapped, pixel }));\n }\n\n const tt = getEligiblePixels(pixels.tiktok, eventName);\n if (tt.length > 0) {\n const mapped = mapTikTokEvent(eventName, parameters);\n tt.forEach((pixel) => results.push({ provider: 'tiktok', mapped, pixel }));\n }\n\n const sc = getEligiblePixels(pixels.snapchat as SnapchatTrackingConfig[] | undefined, eventName);\n if (sc.length > 0) {\n const mapped = mapSnapchatEvent(eventName, parameters);\n sc.forEach((pixel) => results.push({ provider: 'snapchat', mapped, pixel }));\n }\n\n const pt = getEligiblePixels(pixels.pinterest, eventName);\n if (pt.length > 0) {\n const mapped = mapPinterestEvent(eventName, parameters);\n pt.forEach((pixel) => results.push({ provider: 'pinterest', mapped, pixel }));\n }\n\n const clarity = getEligiblePixels(pixels.clarity as ClarityTrackingConfig[] | undefined, eventName);\n if (clarity.length > 0) {\n const mapped = mapClarityEvent(eventName, parameters);\n clarity.forEach((pixel) => results.push({ provider: 'clarity', mapped, pixel }));\n }\n\n const gtm = getEligiblePixels(pixels.gtm as GTMTrackingConfig[] | undefined, eventName);\n if (gtm.length > 0) {\n const mapped = mapGTMEvent(eventName, parameters);\n gtm.forEach((pixel) => {\n const finalParams = applyGoogleAdsConversion(mapped.params, eventName, pixel as GTMTrackingConfig);\n results.push({ provider: 'gtm', mapped: { name: mapped.name, params: finalParams }, pixel });\n });\n }\n\n return results;\n}\n", "/**\n * Client-side identity hashing for pixel advanced matching.\n *\n * Framework-agnostic (no DOM). Normalizes + SHA-256-hashes the customer\n * identifiers (email / phone / external id) so the tracker can feed match\n * keys to Snapchat (`user_hashed_email`/`user_hashed_phone_number`) and TikTok\n * (`ttq.identify`). We hash in the browser ourselves so raw PII never leaves\n * the page \u2014 TikTok requires pre-hashed values anyway, and Snap/Meta accept\n * pre-hashed too.\n */\n\nexport interface PixelRawIdentity {\n /** Raw email (any case). */\n email?: string;\n /** Raw phone in any format. */\n phone?: string;\n /** Stable external id (e.g. Tagada customer id). */\n externalId?: string;\n}\n\nexport interface PixelHashedIdentity {\n /** SHA-256 hex of the normalized email. */\n email?: string;\n /** SHA-256 hex of the E.164-normalized phone. */\n phone?: string;\n /** SHA-256 hex of the trimmed external id. */\n externalId?: string;\n}\n\n/** Lowercase + trim \u2014 the normalization Meta/Snap/TikTok all expect for email. */\nfunction normalizeEmail(email: string): string {\n return email.trim().toLowerCase();\n}\n\n/**\n * Normalize to E.164-ish: keep a single leading `+` (if present) and digits.\n * Snap and TikTok both expect E.164 with the country-code `+`, so a single\n * hash satisfies both. (Meta wants digits-only \u2014 add a per-provider variant\n * here if Meta browser matching is added later.)\n */\nfunction normalizePhone(phone: string): string {\n const trimmed = phone.trim();\n const hasPlus = trimmed.startsWith('+');\n const digits = trimmed.replace(/[^0-9]/g, '');\n if (!digits) return '';\n return (hasPlus ? '+' : '') + digits;\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n const data = new TextEncoder().encode(input);\n const buf = await crypto.subtle.digest('SHA-256', data);\n return Array.from(new Uint8Array(buf))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/** True when SubtleCrypto is usable (secure context). */\nexport function canHashIdentity(): boolean {\n return (\n typeof crypto !== 'undefined' &&\n typeof crypto.subtle !== 'undefined' &&\n typeof crypto.subtle.digest === 'function'\n );\n}\n\n/**\n * Hash whichever identifiers are present. Empty/whitespace-only fields are\n * skipped so we never emit a hash of \"\". Returns `{}` when nothing usable.\n */\nexport async function buildHashedIdentity(id: PixelRawIdentity): Promise<PixelHashedIdentity> {\n const out: PixelHashedIdentity = {};\n\n if (id.email) {\n const n = normalizeEmail(id.email);\n if (n) out.email = await sha256Hex(n);\n }\n if (id.phone) {\n const n = normalizePhone(id.phone);\n if (n) out.phone = await sha256Hex(n);\n }\n if (id.externalId) {\n const n = id.externalId.trim();\n if (n) out.externalId = await sha256Hex(n);\n }\n\n return out;\n}\n", "/**\n * Framework-agnostic pixel tracker.\n *\n * Init / fire logic for Meta, TikTok, Snapchat, Pinterest, GTM/GA4 and\n * Microsoft Clarity pixels \u2014\n * extracted from `react/hooks/usePixelTracking.tsx` so non-React entry points\n * (Studio islands hydrator, full-SPA runtime) can fire pixel events from\n * `window.__TGD_STEP_CONFIG__.pixels`.\n *\n * The React provider is a thin adapter on top of this module.\n */\n\nimport type { ClarityTrackingConfig, GTMTrackingConfig, PixelConfig, PixelsConfig } from './types.js';\nimport {\n resolvePixelEvents,\n pixelIdKeyOf,\n GA4_PARAM_KEY,\n type Ga4PurchasePayload,\n type Ga4UserData,\n type PixelProviderKey,\n type StandardPixelEvent,\n} from './pixelMapping.js';\nimport {\n buildHashedIdentity,\n canHashIdentity,\n type PixelHashedIdentity,\n type PixelRawIdentity,\n} from './pixelIdentity.js';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * Optional per-event tracking metadata. `eventId` is the cross-channel dedup\n * key that the SDK threads to `fbq` (Meta) and `ttq` (TikTok) so the same\n * eventID/event_id can be matched against a server-side CAPI event. Use the\n * `makeMetaEventId(eventName, entityId)` helper from `core/utils/metaEventId`\n * to keep the formula in lockstep with the server.\n */\nexport interface TrackOptions {\n eventId?: string;\n}\n\nexport interface PixelTracker {\n /** Resolves once all pixel scripts have loaded (or hit their load timeout). */\n readonly initPromise: Promise<void>;\n /** True after `initPromise` resolves. */\n readonly pixelsInitialized: boolean;\n /** Track a standard pixel event. No-ops until init resolves. */\n track(\n eventName: StandardPixelEvent,\n parameters?: Record<string, unknown>,\n options?: TrackOptions,\n ): void;\n /**\n * Feed customer identifiers for advanced matching. Applies to Meta (fbq init,\n * raw \u2014 Meta hashes in-browser), Google (gtag set user_data, raw \u2014 enhanced\n * conversions), Snapchat (re-init) + TikTok (identify), the last two with\n * client-side SHA-256 hashing. Each provider persists the keys onto\n * subsequent events, so call this as soon as the email is known to lift\n * match quality on InitiateCheckout + Purchase. Idempotent per identity; safe\n * to call repeatedly.\n */\n identify(identity: PixelRawIdentity): void;\n}\n\n// ---------------------------------------------------------------------------\n// Duplicate guard (time-window based)\n// ---------------------------------------------------------------------------\n\nfunction createDuplicateGuard(windowMs: number) {\n const lastEvents = new Map<string, number>();\n return (\n eventName: StandardPixelEvent,\n parameters: Record<string, unknown>,\n eventId?: string,\n ): boolean => {\n try {\n // Include eventId in the dedup key so two distinct logical events with the\n // same name+params (e.g. two Purchases) are not collapsed by the guard.\n const key = JSON.stringify({ eventName, parameters, eventId });\n const now = Date.now();\n const last = lastEvents.get(key);\n if (last && now - last < windowMs) return false;\n lastEvents.set(key, now);\n return true;\n } catch {\n return true;\n }\n };\n}\n\n// ---------------------------------------------------------------------------\n// Browser-specific: fire an event to the correct global pixel function\n// ---------------------------------------------------------------------------\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * The entry's own identifier, read at whichever key its provider uses \u2014\n * `pixelId`, or `containerId` / `projectId` for GTM and Clarity.\n */\nfunction pixelIdOf(pixel?: PixelConfig): string | null {\n if (!pixel) return null;\n const value = (pixel as unknown as Record<string, unknown>)[pixelIdKeyOf(pixel)];\n return typeof value === 'string' && value ? value : null;\n}\n\nfunction fire(\n provider: PixelProviderKey,\n name: string,\n params: Record<string, unknown>,\n pixel?: PixelConfig,\n options: TrackOptions = {},\n) {\n if (typeof window === 'undefined') return;\n const w = window as any;\n const eventId = options.eventId;\n switch (provider) {\n case 'facebook': {\n // Target this pixel by id rather than calling the global `fbq('track')`,\n // which Meta broadcasts to EVERY pixel registered on the page \u2014 including\n // ones a merchant initialised from a pasted script we don't manage. That\n // broadcast made our Purchase land on foreign pixels, undeduplicated.\n // Mirrors the per-pixel targeting already used for TikTok below.\n //\n // Meta dedup: pass eventID as the trailing `eventID` option so this\n // browser-pixel event matches a server-side CAPI event with the same id.\n // See https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events\n // No id means no addressable pixel: stay silent rather than fall back to\n // the broadcast this change exists to remove. `sanitizePixels` drops every\n // entry without a usable id, so this is unreachable today.\n const pixelId = pixelIdOf(pixel);\n if (!pixelId) break;\n if (eventId) w.fbq?.('trackSingle', pixelId, name, params, { eventID: eventId });\n else w.fbq?.('trackSingle', pixelId, name, params);\n break;\n }\n case 'tiktok': {\n // Use ttq.instance(pixelId) to target each pixel individually,\n // since the global ttq.track() only fires for the sdkid pixel.\n const pixelId = pixelIdOf(pixel);\n const target = pixelId && w.ttq?.instance ? w.ttq.instance(pixelId) : w.ttq;\n if (name === 'Pageview') { target?.page?.(); }\n else if (eventId) { target?.track?.(name, params, { event_id: eventId }); }\n else { target?.track?.(name, params); }\n break;\n }\n case 'snapchat':\n // Snap dedup: the browser event carries client_dedup_id = the event id that the\n // server CAPI event sends as event_id (destinations.md \u00A79.3).\n w.snaptr?.('track', name, eventId ? { ...params, client_dedup_id: eventId } : params);\n break;\n case 'pinterest':\n // Pinterest handles page views via pintrk('page'), not pintrk('track', 'pagevisit')\n if (name === 'pagevisit') { w.pintrk?.('page'); }\n else { w.pintrk?.('track', name, eventId ? { ...params, event_id: eventId } : params); }\n break;\n case 'gtm': fireGTM(name, params); break;\n // Clarity's custom-event API takes a name and nothing else; params stay\n // out rather than being stringified into the event name.\n case 'clarity': w.clarity?.('event', name); break;\n }\n}\n\n/**\n * Apply advanced matching to a single Snapchat pixel. Snap reads user info set\n * at init and attaches it to every event fired afterwards; re-calling init with\n * the (now-known) hashed identifiers updates it. We pass pre-hashed values via\n * the `user_hashed_*` keys.\n */\nfunction applySnapchatIdentity(w: any, pixelId: string, h: PixelHashedIdentity) {\n if (!w?.snaptr) return;\n const userInfo: Record<string, string> = {};\n if (h.email) userInfo.user_hashed_email = h.email;\n if (h.phone) userInfo.user_hashed_phone_number = h.phone;\n if (Object.keys(userInfo).length === 0) return;\n w.snaptr('init', pixelId, userInfo);\n}\n\n/**\n * Apply advanced matching to a single TikTok pixel via `ttq.identify`. TikTok\n * applies identified data to subsequent events and accepts pre-hashed SHA-256\n * values (it detects 64-char hex and won't double-hash). Target the specific\n * pixel instance, mirroring the per-pixel track() targeting.\n */\nfunction applyTikTokIdentity(w: any, pixelId: string, h: PixelHashedIdentity) {\n const target = w?.ttq?.instance ? w.ttq.instance(pixelId) : w?.ttq;\n if (!target?.identify) return;\n const info: Record<string, string> = {};\n if (h.email) info.email = h.email;\n if (h.phone) info.phone_number = h.phone;\n if (h.externalId) info.external_id = h.externalId;\n if (Object.keys(info).length === 0) return;\n target.identify(info);\n}\n\n/**\n * Apply advanced matching to a single Meta pixel. Meta reads advanced-matching\n * data passed to `fbq('init', pixelId, userData)` and attaches it to every\n * event fired afterwards; re-calling init with the (now-known) identifiers\n * updates it (init is idempotent and never auto-fires PageView). We pass RAW\n * values \u2014 `fbevents.js` normalizes + SHA-256-hashes them in-browser before\n * they leave the page \u2014 because Meta's phone normalization (digits-only) differs\n * from Snap/TikTok's E.164, so letting Meta hash avoids a mismatch.\n */\nfunction applyMetaIdentity(w: any, pixelId: string, raw: PixelRawIdentity) {\n if (!w?.fbq) return;\n const ud: Record<string, string> = {};\n if (raw.email) ud.em = raw.email.trim().toLowerCase();\n if (raw.phone) { const d = raw.phone.replace(/[^0-9]/g, ''); if (d) ud.ph = d; }\n if (raw.externalId) ud.external_id = raw.externalId.trim();\n if (Object.keys(ud).length === 0) return;\n w.fbq('init', pixelId, ud);\n}\n\n/**\n * Google Ads enhanced conversions / GA4 user-provided data.\n *\n * Google's documented mechanism is `gtag('set', 'user_data', {...})` BEFORE the\n * conversion event fires (support.google.com/google-ads/answer/13258081) \u2014\n * `user_data` as an event parameter is not read for enhanced conversions. We\n * pass RAW values; the Google tag normalizes + SHA-256 hashes in-browser.\n * Field names per spec: `email`, `phone_number` (strict E.164 \u2014 dropped when\n * not in that shape, email is the preferred key anyway), and\n * `address.{first_name,last_name,street,city,region,postal_code,country}`.\n * Exported for unit tests.\n */\nexport function applyGoogleIdentity(w: any, ud: Ga4UserData) {\n if (typeof w?.gtag !== 'function') return;\n\n const userData: Record<string, unknown> = {};\n if (ud.email_address) userData.email = ud.email_address.trim().toLowerCase();\n\n if (ud.phone_number) {\n const phone = ud.phone_number.replace(/[^0-9+]/g, '');\n if (/^\\+[0-9]{10,14}$/.test(phone)) userData.phone_number = phone;\n }\n\n if (ud.address) {\n const a = ud.address;\n const address: Record<string, string> = {};\n if (a.first_name) address.first_name = a.first_name;\n if (a.last_name) address.last_name = a.last_name;\n if (a.street) address.street = a.street;\n if (a.city) address.city = a.city;\n if (a.region) address.region = a.region;\n if (a.postal_code) address.postal_code = a.postal_code;\n if (a.country) address.country = a.country;\n if (Object.keys(address).length > 0) userData.address = address;\n }\n\n if (Object.keys(userData).length === 0) return;\n w.gtag('set', 'user_data', userData);\n}\n\nfunction fireGTM(event: string, params: Record<string, unknown>) {\n try {\n const w = window as any;\n const hasEcommerce = params && typeof params === 'object' && 'ecommerce' in params;\n if (w.gtag) {\n // gtag.js (GA4 config tag) reads ecommerce fields at the top level of the\n // event, not under a nested `ecommerce` key \u2014 flatten it back out.\n if (hasEcommerce) {\n const { ecommerce, ...rest } = params as Record<string, unknown>;\n w.gtag('event', event, { ...rest, ...(ecommerce as Record<string, unknown>) });\n } else {\n w.gtag('event', event, params);\n }\n } else if (w.dataLayer) {\n // GA4 best practice: clear the previous ecommerce object before pushing a\n // new one so item arrays from earlier events don't bleed through.\n if (hasEcommerce) w.dataLayer.push({ ecommerce: null });\n w.dataLayer.push({ event, ...params });\n }\n } catch (error) {\n console.error('[SDK GTM] Error:', error);\n }\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n// ===========================================================================\n// Pixel initialization (browser-only)\n// All pixel globals are accessed via `win` typed as `any` to avoid\n// `declare global` augmentation issues across tsconfig scopes.\n// ===========================================================================\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nconst win = (typeof window !== 'undefined' ? window : undefined) as any;\n\nconst SCRIPT_LOAD_TIMEOUT_MS = 5000;\n\nfunction waitForScriptLoad(script: HTMLScriptElement): Promise<void> {\n // If the script has already loaded, resolve immediately\n if (script.dataset.loaded) return Promise.resolve();\n\n return new Promise((resolve) => {\n const done = () => { script.dataset.loaded = '1'; clearTimeout(timer); resolve(); };\n const timer = setTimeout(done, SCRIPT_LOAD_TIMEOUT_MS);\n script.addEventListener('load', done, { once: true });\n script.addEventListener('error', done, { once: true });\n });\n}\n\nlet _metaScriptEl: HTMLScriptElement | null = null;\n\nfunction initMetaPixel(pixelId: string): Promise<void> {\n if (!win) return Promise.resolve();\n\n // Initialize Meta base code once\n if (!win.fbq) {\n const n = function (...args: any[]) {\n if (n.callMethod) n.callMethod(...args); else n.queue.push(args);\n } as any;\n n.queue = [];\n n.loaded = true;\n n.version = '2.0';\n win.fbq = n;\n if (!win._fbq) win._fbq = n;\n const t = document.createElement('script') as HTMLScriptElement;\n t.async = true;\n t.src = 'https://connect.facebook.net/en_US/fbevents.js';\n const s = document.getElementsByTagName('script')[0];\n s?.parentNode?.insertBefore(t, s);\n _metaScriptEl = t;\n }\n\n // Register each pixel ID (fbq supports multiple pixels via multiple init calls)\n win.fbq('init', pixelId);\n return _metaScriptEl ? waitForScriptLoad(_metaScriptEl) : Promise.resolve();\n}\n\nlet _tiktokBaseInitialized = false;\n\nfunction initTikTokPixel(pixelId: string): Promise<void> {\n if (!win) return Promise.resolve();\n\n // Initialize TikTok base code once\n if (!_tiktokBaseInitialized) {\n _tiktokBaseInitialized = true;\n win.TiktokAnalyticsObject = 'ttq';\n const ttq = (win.ttq = win.ttq || []) as any;\n ttq.methods = [\n 'page', 'track', 'identify', 'instances', 'debug', 'on', 'off',\n 'once', 'ready', 'alias', 'group', 'enableCookie', 'disableCookie',\n 'holdConsent', 'revokeConsent', 'grantConsent',\n ];\n ttq.setAndDefer = function (t: any, e: string) {\n t[e] = function (...args: any[]) { t.push([e, ...args]); };\n };\n for (const method of ttq.methods) {\n ttq.setAndDefer(ttq, method);\n }\n ttq.instance = function (t: string) {\n const e = ttq._i[t] || [];\n for (const method of ttq.methods) {\n ttq.setAndDefer(e, method);\n }\n return e;\n };\n ttq.load = function (e: string, n?: any) {\n const r = 'https://analytics.tiktok.com/i18n/pixel/events.js';\n ttq._i = ttq._i || {};\n ttq._i[e] = [];\n ttq._i[e]._u = r;\n ttq._t = ttq._t || {};\n ttq._t[e] = +new Date();\n ttq._o = ttq._o || {};\n ttq._o[e] = n || {};\n const s = document.createElement('script') as HTMLScriptElement;\n s.type = 'text/javascript';\n s.async = true;\n s.src = r + '?sdkid=' + e + '&lib=ttq';\n const p = document.getElementsByTagName('script')[0];\n p?.parentNode?.insertBefore(s, p);\n };\n }\n\n // Skip if this specific pixel ID is already registered\n if (win.ttq._i?.[pixelId]) return Promise.resolve();\n\n // Register pixel and load its script\n win.ttq.load(pixelId);\n\n // Find the script we just created and wait for it\n const scripts = document.querySelectorAll<HTMLScriptElement>(\n 'script[src*=\"analytics.tiktok.com/i18n/pixel/events.js\"]'\n );\n const lastScript = scripts[scripts.length - 1];\n return lastScript ? waitForScriptLoad(lastScript) : Promise.resolve();\n}\n\nlet _snapchatScriptEl: HTMLScriptElement | null = null;\n\nfunction initSnapchatPixel(pixelId: string): Promise<void> {\n if (!win) return Promise.resolve();\n\n // Initialize Snapchat base code once\n if (!win.snaptr) {\n const a = function (...args: any[]) {\n if (a.handleRequest) a.handleRequest(...args); else a.queue.push(args);\n } as any;\n a.queue = [];\n win.snaptr = a;\n const r = document.createElement('script') as HTMLScriptElement;\n r.async = true;\n r.src = 'https://sc-static.net/scevent.min.js';\n const u = document.getElementsByTagName('script')[0];\n u?.parentNode?.insertBefore(r, u);\n _snapchatScriptEl = r;\n }\n\n // Register each pixel ID (snaptr supports multiple pixels via multiple init calls)\n win.snaptr('init', pixelId);\n return _snapchatScriptEl ? waitForScriptLoad(_snapchatScriptEl) : Promise.resolve();\n}\n\nlet _pinterestScriptEl: HTMLScriptElement | null = null;\n\nfunction initPinterestPixel(pixelId: string): Promise<void> {\n if (!win) return Promise.resolve();\n\n // Initialize Pinterest base code once\n if (!win.pintrk) {\n const a = function (...args: any[]) { a.queue.push(args); } as any;\n a.queue = [];\n win.pintrk = a;\n const s = document.createElement('script') as HTMLScriptElement;\n s.async = true;\n s.src = 'https://s.pinimg.com/ct/core.js';\n const u = document.getElementsByTagName('script')[0];\n u?.parentNode?.insertBefore(s, u);\n _pinterestScriptEl = s;\n }\n\n // Register each pixel ID (pintrk supports multiple pixels via multiple load calls)\n win.pintrk('load', pixelId);\n // Note: pintrk('page') is NOT called here \u2014 the auto page-view fires via fire().\n return _pinterestScriptEl ? waitForScriptLoad(_pinterestScriptEl) : Promise.resolve();\n}\n\n/**\n * Load the Microsoft Clarity tag for one project.\n *\n * Mirrors the vendor snippet: a queueing stub so `clarity(...)` calls made\n * before the script lands are replayed, then the tag itself. Clarity ignores a\n * second project on the same page, so a project already present is a no-op.\n */\nfunction initClarity(projectId: string): Promise<void> {\n if (!win || !projectId) return Promise.resolve();\n if (document.querySelector(`script[src*=\"clarity.ms/tag/${projectId}\"]`)) return Promise.resolve();\n\n if (!win.clarity) {\n const q = function (...args: any[]) { q.q.push(args); } as any;\n q.q = [];\n win.clarity = q;\n }\n\n const s = document.createElement('script') as HTMLScriptElement;\n s.async = true;\n s.src = `https://www.clarity.ms/tag/${projectId}`;\n const first = document.getElementsByTagName('script')[0];\n if (first?.parentNode) first.parentNode.insertBefore(s, first);\n else (document.head || document.getElementsByTagName('head')[0])?.appendChild(s);\n\n return waitForScriptLoad(s);\n}\n\nfunction initGTM(containerId: string): Promise<void> {\n if (!win || !containerId) return Promise.resolve();\n const isGtmContainer = containerId.startsWith('GTM-');\n const scriptUrlPart = isGtmContainer\n ? `googletagmanager.com/gtm.js?id=${containerId}`\n : `googletagmanager.com/gtag/js?id=${containerId}`;\n if (document.querySelector(`script[src*=\"${scriptUrlPart}\"]`)) return Promise.resolve();\n\n win.dataLayer = win.dataLayer || [];\n\n // Push referrer domain context into dataLayer before GTM loads, so tags\n // inside the container can use it for cross-domain tracking configuration.\n try {\n const ref = document.referrer && new URL(document.referrer).hostname;\n if (ref && ref !== window.location.hostname) {\n win.dataLayer.push({ tagada_referrer_domain: ref });\n }\n } catch { /* ignore invalid referrer */ }\n\n if (isGtmContainer) {\n win.dataLayer.push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });\n const f = document.getElementsByTagName('script')[0];\n const j = document.createElement('script') as HTMLScriptElement;\n j.async = true;\n j.src = 'https://www.googletagmanager.com/gtm.js?id=' + containerId;\n if (f?.parentNode) f.parentNode.insertBefore(j, f);\n else (document.head || document.getElementsByTagName('head')[0])?.appendChild(j);\n const noscript = document.createElement('noscript');\n const iframe = document.createElement('iframe');\n iframe.src = `https://www.googletagmanager.com/ns.html?id=${containerId}`;\n iframe.height = '0'; iframe.width = '0';\n iframe.style.display = 'none'; iframe.style.visibility = 'hidden';\n noscript.appendChild(iframe);\n (document.body || document.getElementsByTagName('body')[0])?.insertBefore(noscript, document.body?.firstChild ?? null);\n return waitForScriptLoad(j);\n } else {\n if (!win.gtag) {\n win.gtag = function (..._args: any[]) { win.dataLayer.push(arguments); };\n }\n win.gtag('js', new Date());\n\n // Enable cross-domain tracking: accept incoming _gl parameter from referring\n // domains (e.g. Shopify store \u2192 TagadaPay checkout) so Google preserves the\n // client-id/session across the redirect.\n const linkerConfig: Record<string, unknown> = { accept_incoming: true };\n try {\n const ref = document.referrer && new URL(document.referrer).hostname;\n if (ref && ref !== window.location.hostname) {\n linkerConfig.domains = [ref, window.location.hostname];\n }\n } catch { /* ignore invalid referrer */ }\n\n win.gtag('config', containerId, { linker: linkerConfig });\n const script = document.createElement('script') as HTMLScriptElement;\n script.async = true;\n script.src = 'https://www.googletagmanager.com/gtag/js?id=' + containerId;\n const firstScript = document.getElementsByTagName('script')[0];\n if (firstScript?.parentNode) firstScript.parentNode.insertBefore(script, firstScript);\n else (document.head || document.getElementsByTagName('head')[0])?.appendChild(script);\n return waitForScriptLoad(script);\n }\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n// ---------------------------------------------------------------------------\n// Tracker factory\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Config sanitisation (TAG-1871)\n// ---------------------------------------------------------------------------\n\n/** Longest ID we accept \u2014 real IDs top out around 20 chars. */\nconst MAX_PIXEL_ID_LENGTH = 64;\n\n/**\n * The only shape any supported pixel / container / project ID takes: Meta\n * digits, TikTok alphanumerics, Snapchat alphanumerics + dashes, Pinterest\n * digits, Clarity project ids and `GTM-`/`AW-`/`G-` containers are all drawn\n * from `[A-Za-z0-9_-]`.\n */\nconst SAFE_PIXEL_ID_PATTERN = new RegExp(`^[A-Za-z0-9_-]{1,${MAX_PIXEL_ID_LENGTH}}$`);\n\n/** True when `value` is a single, well-formed pixel / container ID. */\nexport function isSafePixelId(value: unknown): value is string {\n return typeof value === 'string' && SAFE_PIXEL_ID_PATTERN.test(value.trim());\n}\n\n/**\n * Trim every pixel/container ID and DROP the ones that aren't plausibly IDs.\n *\n * The trim keeps per-pixel event targeting (TikTok `ttq.instance`) working when\n * the CRM stored stray whitespace. The drop is the load-bearing part: a\n * merchant once pasted a whole TikTok `<script>` snippet into the Pixel ID\n * field, the CRM split it on every comma into 56 \"pixels\", and handing those\n * fragments to `ttq.load()` sent TikTok's SDK into a hot loop that pinned the\n * renderer at 100% CPU *before first paint* \u2014 a blank checkout for days.\n *\n * The CRM now rejects such values at input, but this guard is deliberately\n * independent: it neutralises configs that are ALREADY polluted, on pages that\n * were baked before the fix, with no data migration and no re-publish.\n */\nfunction sanitizePixels(pixels: PixelsConfig): PixelsConfig {\n const out: Record<string, PixelConfig[]> = {};\n const dropped: unknown[] = [];\n\n for (const [provider, list] of Object.entries(pixels)) {\n if (!Array.isArray(list)) continue;\n const kept: PixelConfig[] = [];\n for (const px of list) {\n // GTM keys off containerId, Clarity off projectId, everyone else pixelId.\n const key = pixelIdKeyOf(px);\n const raw = (px as unknown as Record<string, unknown>)?.[key];\n if (!isSafePixelId(raw)) {\n dropped.push(raw);\n continue;\n }\n kept.push({ ...px, [key]: (raw as string).trim() } as PixelConfig);\n }\n out[provider] = kept;\n }\n\n if (dropped.length > 0) {\n console.warn(\n `[SDK Pixels] Ignored ${dropped.length} malformed pixel ID(s) \u2014 tracking for those entries is disabled.`,\n dropped,\n );\n }\n return out as PixelsConfig;\n}\n\n/**\n * Resolve once the browser has had a chance to paint.\n *\n * Third-party pixel SDKs run arbitrary vendor code on the main thread and can\n * stall it (TikTok's did, indefinitely \u2014 TAG-1871). Injecting them before first\n * paint turns any such stall into a blank page. Deferring past the first frame\n * means the worst case degrades to \"no tracking\" instead of \"no checkout\".\n *\n * Double-rAF is the standard \"after paint\" signal. The timer is a fallback for\n * backgrounded tabs (where rAF may never fire) and for non-browser environments\n * that expose a `window` without `requestAnimationFrame`.\n */\nconst PAINT_FALLBACK_MS = 1500;\n\nfunction afterFirstPaint(): Promise<void> {\n if (typeof window === 'undefined') return Promise.resolve();\n return new Promise<void>((resolve) => {\n let settled = false;\n const finish = () => {\n if (settled) return;\n settled = true;\n clearTimeout(fallback);\n resolve();\n };\n const raf: ((cb: () => void) => void) | undefined =\n typeof win?.requestAnimationFrame === 'function'\n ? win.requestAnimationFrame.bind(win)\n : undefined;\n const fallback = setTimeout(finish, raf ? PAINT_FALLBACK_MS : 0);\n if (raf) raf(() => raf(finish));\n });\n}\n\n/**\n * Create a pixel tracker for a given pixels config.\n * Kicks off pixel script init once the first frame has painted, fires PageView\n * when init resolves, and returns a `track()` function that no-ops until then.\n */\nexport function createPixelTracker(rawPixels: PixelsConfig | undefined, opts?: { autoPageView?: boolean }): PixelTracker {\n const pixels = rawPixels ? sanitizePixels(rawPixels) : rawPixels;\n const shouldTrackEvent = createDuplicateGuard(5000);\n let pixelsInitialized = false;\n\n const initPromise: Promise<void> = (async () => {\n if (!pixels || typeof window === 'undefined') return;\n\n // Never inject a third-party tag before the page has painted (TAG-1871).\n await afterFirstPaint();\n\n const loadPromises: Promise<void>[] = [];\n try {\n pixels.facebook?.forEach((px) => { if (px.enabled && px.pixelId) loadPromises.push(initMetaPixel(px.pixelId)); });\n pixels.tiktok?.forEach((px) => { if (px.enabled && px.pixelId) loadPromises.push(initTikTokPixel(px.pixelId)); });\n pixels.snapchat?.forEach((px) => { if (px.enabled && px.pixelId) loadPromises.push(initSnapchatPixel(px.pixelId)); });\n pixels.pinterest?.forEach((px) => { if (px.enabled && px.pixelId) loadPromises.push(initPinterestPixel(px.pixelId)); });\n pixels.gtm?.forEach((px) => { if (px.enabled && (px as GTMTrackingConfig).containerId) loadPromises.push(initGTM((px as GTMTrackingConfig).containerId)); });\n pixels.clarity?.forEach((px) => { if (px.enabled && (px as ClarityTrackingConfig).projectId) loadPromises.push(initClarity((px as ClarityTrackingConfig).projectId)); });\n await Promise.all(loadPromises);\n } catch (error) {\n console.error('[SDK Pixels] Initialization error:', error);\n }\n pixelsInitialized = true;\n })();\n\n // Advanced matching: feed customer identity to Meta (fbq init, raw \u2014 Meta\n // hashes), Snapchat (re-init, hashed) + TikTok (identify, hashed). Applied\n // once per identity and cached, so repeated track()/identify() calls don't\n // re-apply. Each provider persists the match keys onto every subsequent\n // event it fires, so calling this as soon as the email is known lifts match\n // quality on InitiateCheckout + Purchase alike. `_identityReady` is awaited\n // before Snap/TikTok events fire so the hashed keys are attached in time.\n let _identityKey: string | null = null;\n let _identityReady: Promise<void> | null = null;\n\n const applyIdentity = (id: PixelRawIdentity): Promise<void> | null => {\n if (!pixels) return null;\n if (!id.email && !id.phone && !id.externalId) return null;\n\n const key = `${id.email ?? ''}|${id.phone ?? ''}|${id.externalId ?? ''}`;\n if (_identityKey === key && _identityReady) return _identityReady;\n _identityKey = key;\n\n // Meta takes raw values and hashes in-browser \u2014 apply immediately, no need\n // to await our own hashing (and it works even without SubtleCrypto).\n pixels.facebook?.forEach((px) => {\n if (px.enabled && px.pixelId) applyMetaIdentity(win, px.pixelId, id);\n });\n\n // Google Ads enhanced conversions: gtag('set','user_data') persists onto\n // every subsequent gtag event, including the send_to conversion. Raw values,\n // Google hashes in-browser (same rationale as Meta).\n if (pixels.gtm?.some((px) => px.enabled)) {\n applyGoogleIdentity(win, { email_address: id.email, phone_number: id.phone });\n }\n\n // Snapchat + TikTok want pre-hashed SHA-256 values, which we compute\n // ourselves so raw PII never leaves the page. Skips when no secure context.\n if (!canHashIdentity()) return (_identityReady = Promise.resolve());\n\n // Always resolves (errors are swallowed) so deferred event fires never hang.\n _identityReady = (async () => {\n try {\n const hashed = await buildHashedIdentity(id);\n pixels.snapchat?.forEach((px) => {\n if (px.enabled && px.pixelId) applySnapchatIdentity(win, px.pixelId, hashed);\n });\n pixels.tiktok?.forEach((px) => {\n if (px.enabled && px.pixelId) applyTikTokIdentity(win, px.pixelId, hashed);\n });\n } catch (error) {\n console.error('[SDK Pixels] identify error:', error);\n }\n })();\n return _identityReady;\n };\n\n // Derive identity from the GA4 enrichment the thank-you page already attaches\n // (`_ga4.user_data`), so Purchase events get advanced matching with no\n // call-site changes. Returns the readiness promise, or null when absent.\n const applyIdentityFromParams = (\n parameters: Record<string, unknown>,\n ): Promise<void> | null => {\n const ga4 = parameters[GA4_PARAM_KEY] as Ga4PurchasePayload | undefined;\n const ud = ga4?.user_data;\n if (!ud) return null;\n // Google enhanced conversions get the FULL user_data (incl. address) here,\n // richer than the email/phone identity below \u2014 and this runs synchronously\n // before the gtag('event') fires in track(), which is what Google requires.\n // Bypasses the identity dedup on purpose: gtag('set') is idempotent and the\n // address may not have been known at identify() time.\n if (pixels?.gtm?.some((px) => px.enabled)) applyGoogleIdentity(win, ud);\n return applyIdentity({\n email: ud.email_address,\n phone: ud.phone_number,\n externalId: ga4?.user_id,\n });\n };\n\n const track = (\n eventName: StandardPixelEvent,\n parameters: Record<string, unknown> = {},\n options: TrackOptions = {},\n ): void => {\n if (!pixels || !pixelsInitialized) return;\n if (!shouldTrackEvent(eventName, parameters, options.eventId)) return;\n\n try {\n // Apply advanced matching before firing so Snap/TikTok carry the match\n // keys on this event. Other providers fire immediately (unaffected).\n const identityReady = applyIdentityFromParams(parameters);\n\n const events = resolvePixelEvents(pixels, eventName, parameters);\n // Deduplicate by provider: the Snapchat/Pinterest SDKs broadcast to all\n // registered pixel IDs internally, so we only need to fire once per\n // provider. GTM, TikTok and Meta need per-pixel firing (GTM for Google Ads\n // send_to targeting, TikTok because ttq.instance() targets a specific\n // pixel, Meta because fbq('trackSingle') does \u2014 relying on Meta's\n // broadcast instead leaked our events onto pixels a pasted script had\n // initialised).\n const firedProviders = new Set<string>();\n // Per-pixel providers still need per-pixel dedup: a merchant field of\n // \"123;123\" expands into two entries with the same id (splitPixelConfig),\n // which would otherwise fire the same event twice at the same pixel.\n const firedPixels = new Set<string>();\n for (const { provider, mapped, pixel } of events) {\n // Gate Snap/TikTok on identity application (when present) so the match\n // keys are set first; a few ms of deferral, only for those providers.\n const emit =\n identityReady && (provider === 'snapchat' || provider === 'tiktok')\n ? (fn: () => void) => { identityReady.then(fn); }\n : (fn: () => void) => { fn(); };\n\n if (provider === 'gtm' || provider === 'tiktok' || provider === 'facebook') {\n const pixelKey = `${provider}:${pixelIdOf(pixel) ?? ''}`;\n if (firedPixels.has(pixelKey)) continue;\n firedPixels.add(pixelKey);\n emit(() => fire(provider, mapped.name, mapped.params, pixel, options));\n } else {\n if (!firedProviders.has(provider)) {\n emit(() => fire(provider, mapped.name, mapped.params, undefined, options));\n firedProviders.add(provider);\n }\n }\n }\n } catch (error) {\n console.error('[SDK Pixels] Tracking error:', error);\n }\n };\n\n // Auto page-view: fire once after init resolves.\n if (opts?.autoPageView !== false) initPromise.then(() => {\n if (typeof window === 'undefined') return;\n track('PageView', { path: window.location.pathname });\n });\n\n return {\n initPromise,\n get pixelsInitialized() { return pixelsInitialized; },\n track,\n identify: (identity: PixelRawIdentity) => { applyIdentity(identity); },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Window bootstrap\n// ---------------------------------------------------------------------------\n\ndeclare global {\n interface Window {\n __TGD_PIXEL_TRACKER__?: PixelTracker;\n __TGD_STEP_CONFIG__?: string | Record<string, unknown>;\n }\n}\n\nfunction readPixelsFromStepConfig(): PixelsConfig | undefined {\n if (typeof window === 'undefined') return undefined;\n const raw = window.__TGD_STEP_CONFIG__;\n if (!raw) return undefined;\n try {\n const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;\n const pixels = (parsed as { pixels?: PixelsConfig })?.pixels;\n return pixels && typeof pixels === 'object' ? pixels : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * One-shot bootstrap: reads `window.__TGD_STEP_CONFIG__.pixels`, creates a\n * tracker, kicks off init, and stashes it on `window.__TGD_PIXEL_TRACKER__`.\n *\n * Idempotent \u2014 both the islands SDK and the full-SPA runtime may call this,\n * but only the first call creates a tracker. Returns the active tracker\n * (existing or newly created), or null if there's no window or no pixels.\n */\nexport function bootstrapPixelTrackerFromWindow(): PixelTracker | null {\n if (typeof window === 'undefined') return null;\n if (window.__TGD_PIXEL_TRACKER__) return window.__TGD_PIXEL_TRACKER__;\n\n const pixels = readPixelsFromStepConfig();\n if (!pixels) return null;\n\n const tracker = createPixelTracker(pixels);\n window.__TGD_PIXEL_TRACKER__ = tracker;\n return tracker;\n}\n", "/**\n * The browser pixel engine.\n *\n * It wraps the lifted `createPixelTracker` with three things the hosted runtime\n * does not need: it stays inert until `init()`, it gates every fire on the\n * per-step configuration served by the SDK config route, and it reports what it\n * could not do (a pixel already on the page, a pixel blocked by the CSP).\n */\nimport type { PixelRawIdentity } from './pixelIdentity.js';\nimport { pixelIdKeyOf } from './pixelMapping.js';\nimport type { PixelProviderKey, StandardPixelEvent } from './pixelMapping.js';\nimport { createPixelTracker, isSafePixelId } from './pixelTracker.js';\nimport type { PixelTracker } from './pixelTracker.js';\nimport type { PixelConfig, PixelsConfig } from './types.js';\n\nexport type PixelSignalKind = 'pixel_blocked' | 'pixel_duplicate';\nexport interface PixelSignal { kind: PixelSignalKind; provider: PixelProviderKey; detail: Record<string, string> }\nexport type SdkPixelProvider = 'facebook' | 'tiktok' | 'snapchat' | 'gtm' | 'clarity';\nexport const SDK_PIXEL_PROVIDERS: readonly SdkPixelProvider[] = ['facebook', 'tiktok', 'snapchat', 'gtm', 'clarity'];\n\nexport interface PixelEngineConfig {\n pixels: PixelsConfig;\n /** Keyed by the MANIFEST step id (`sdk_steps.key`, e.g. `paywall`) \u2014 the id the merchant passes to\n `track.step()` \u2014 never the `sdkstep_\u2026` node id. R4 re-keys onto it server-side (contract \u00A76). */\n steps?: Record<string, { type?: string; events: Record<string, PixelProviderKey[]> }>;\n checkout?: { InitiateCheckout?: PixelProviderKey[]; Purchase?: PixelProviderKey[] };\n requireConsent?: boolean;\n onSignal?: (signal: PixelSignal) => void;\n}\n\nexport interface PixelEngine {\n init(): Promise<void>;\n pageView(path: string, options?: { stepId?: string }): void;\n track(event: StandardPixelEvent, data?: Record<string, unknown>, options?: { eventId?: string; stepId?: string }): void;\n trackCustom(name: string, data?: Record<string, unknown>, options?: { stepId?: string }): void;\n identify(identity: PixelRawIdentity): void;\n consent(state: { marketing: boolean }): void;\n destroy(): void;\n}\n\n/** The single origin each provider's loader fetches its script from; the drift test pins it. */\nexport const SCRIPT_ORIGINS: Record<SdkPixelProvider, string> = {\n facebook: 'https://connect.facebook.net', tiktok: 'https://analytics.tiktok.com',\n snapchat: 'https://sc-static.net', gtm: 'https://www.googletagmanager.com',\n clarity: 'https://www.clarity.ms',\n};\n\n/** The global a provider's own script installs; its presence means a second tag is on the page. */\nconst PROVIDER_GLOBALS: Record<SdkPixelProvider, string> = {\n facebook: 'fbq', tiktok: 'ttq', snapchat: 'snaptr', gtm: 'dataLayer', clarity: 'clarity',\n};\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype VendorWindow = Record<string, any>;\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nconst QUEUE_LIMIT = 50;\n/** Same window as the SDK's own step dedup: React StrictMode double-renders, nothing more. */\nconst PAGE_VIEW_DEDUP_MS = 1000;\n\nfunction isSdkProvider(provider: string): provider is SdkPixelProvider {\n return (SDK_PIXEL_PROVIDERS as readonly string[]).includes(provider);\n}\n\n/** The five SDK providers and nothing else, copied key by key: a spread would carry `pinterest` through. */\nfunction filterPixels(pixels: PixelsConfig): PixelsConfig {\n const out: PixelsConfig = {};\n if (pixels.facebook) out.facebook = pixels.facebook;\n if (pixels.tiktok) out.tiktok = pixels.tiktok;\n if (pixels.snapchat) out.snapchat = pixels.snapchat;\n if (pixels.gtm) out.gtm = pixels.gtm;\n if (pixels.clarity) out.clarity = pixels.clarity;\n return out;\n}\n\nfunction entriesOf(pixels: PixelsConfig, provider: SdkPixelProvider): PixelConfig[] {\n const list = (pixels as Record<string, PixelConfig[] | undefined>)[provider];\n return Array.isArray(list) ? list : [];\n}\n\nfunction usableIdOf(pixel: PixelConfig): string | null {\n const value = (pixel as unknown as Record<string, unknown>)[pixelIdKeyOf(pixel)];\n return isSafePixelId(value) ? value.trim() : null;\n}\n\nexport function createPixelEngine(config: PixelEngineConfig): PixelEngine {\n const pixels = filterPixels(config.pixels);\n const trackers = new Map<SdkPixelProvider, PixelTracker>();\n /** `stepId|path` \u2192 when it last fired. A window, not a page-lifetime latch: an SPA that comes\n back to a step later in the session must count as a second page view. */\n const seen = new Map<string, number>();\n const signalled = new Set<string>();\n const queue: Array<() => void> = [];\n let granted = config.requireConsent !== true;\n let latchedOff = false;\n let started = false;\n let cspHandler: ((event: Event) => void) | null = null;\n\n const signal = (kind: PixelSignalKind, provider: SdkPixelProvider, detail: Record<string, string>): void => {\n const key = `${provider}|${kind}`;\n if (signalled.has(key)) return;\n signalled.add(key);\n try { config.onSignal?.({ kind, provider, detail }); } catch { /* a consumer callback never breaks a page */ }\n };\n\n const configuredProviders = (): SdkPixelProvider[] =>\n SDK_PIXEL_PROVIDERS.filter((provider) => entriesOf(pixels, provider).length > 0);\n\n const gateFor = (event: string, stepId?: string): SdkPixelProvider[] => {\n const raw = event === 'InitiateCheckout' || event === 'Purchase'\n ? config.checkout?.[event] ?? []\n : config.steps?.[stepId ?? '']?.events?.[event] ?? [];\n return raw.filter(isSdkProvider);\n };\n\n const detectDuplicates = (win: VendorWindow): void => {\n for (const provider of configuredProviders()) {\n const host = typeof win.location?.host === 'string' ? win.location.host : '';\n if (provider === 'gtm') {\n const loaded = win.google_tag_manager;\n const clash = entriesOf(pixels, 'gtm').some((px) => {\n const id = usableIdOf(px);\n return id !== null && loaded?.[id] !== undefined;\n });\n if (clash) signal('pixel_duplicate', 'gtm', { origin: host });\n continue;\n }\n if (win[PROVIDER_GLOBALS[provider]] !== undefined) signal('pixel_duplicate', provider, { origin: host });\n }\n };\n\n const watchCsp = (win: VendorWindow): void => {\n cspHandler = (event: Event): void => {\n const violation = event as SecurityPolicyViolationEvent;\n const blocked = typeof violation.blockedURI === 'string' ? violation.blockedURI : '';\n for (const provider of SDK_PIXEL_PROVIDERS) {\n if (!blocked.startsWith(SCRIPT_ORIGINS[provider])) continue;\n signal('pixel_blocked', provider, { reason: 'csp', directive: violation.violatedDirective ?? '' });\n return;\n }\n };\n win.addEventListener('securitypolicyviolation', cspHandler);\n };\n\n const enqueue = (run: () => void): void => {\n if (latchedOff) return;\n if (queue.length >= QUEUE_LIMIT) queue.shift();\n queue.push(run);\n };\n\n const guardEventId = (eventId: string): boolean => {\n try { if (sessionStorage.getItem(`__tgd_px:${eventId}`)) return false; } catch { /* private mode */ }\n return true;\n };\n\n const markEventId = (eventId: string): void => {\n try { sessionStorage.setItem(`__tgd_px:${eventId}`, '1'); } catch { /* private mode */ }\n };\n\n const engine: PixelEngine = {\n async init(): Promise<void> {\n if (started || typeof window === 'undefined') return;\n if (!granted) return;\n started = true;\n const win = window as unknown as VendorWindow;\n detectDuplicates(win);\n watchCsp(win);\n const ready: Promise<void>[] = [];\n for (const provider of configuredProviders()) {\n // One tracker per provider: the lifted tracker fires to every provider of its own\n // config, so a per-provider gate needs a per-provider tracker.\n const tracker = createPixelTracker({ [provider]: entriesOf(pixels, provider) } as PixelsConfig, { autoPageView: false });\n trackers.set(provider, tracker);\n ready.push(tracker.initPromise);\n }\n // `track()` no-ops until `pixelsInitialized` flips, which only happens when these settle.\n await Promise.all(ready);\n },\n\n pageView(path, options): void {\n if (typeof window === 'undefined') return;\n if (!granted) { enqueue(() => engine.pageView(path, options)); return; }\n const key = `${options?.stepId ?? ''}|${path}`;\n const now = Date.now();\n const previous = seen.get(key);\n if (previous !== undefined && now - previous < PAGE_VIEW_DEDUP_MS) return;\n for (const [other, when] of seen) if (now - when >= PAGE_VIEW_DEDUP_MS) seen.delete(other);\n seen.set(key, now);\n const allowed = gateFor('PageView', options?.stepId);\n if (allowed.length === 0) return;\n // A per-step id, and a per-fire one: two steps on one path would otherwise collapse into a\n // single fire inside the tracker's own 5 s duplicate guard, and so would a genuine return\n // to the same step later in the session.\n for (const provider of allowed) trackers.get(provider)?.track('PageView', { path }, { eventId: `PageView_${key}|${now}` });\n },\n\n track(event, data, options): void {\n if (typeof window === 'undefined') return;\n if (!granted) { enqueue(() => engine.track(event, data, options)); return; }\n if (event === 'InitiateCheckout' || event === 'Purchase') {\n if (!options?.eventId) return;\n if (!guardEventId(options.eventId)) return;\n }\n const allowed = gateFor(event, options?.stepId);\n if (allowed.length === 0) return;\n for (const provider of allowed) {\n trackers.get(provider)?.track(event, data ?? {}, options?.eventId ? { eventId: options.eventId } : undefined);\n }\n if (options?.eventId) markEventId(options.eventId);\n },\n\n trackCustom(name, data, options): void {\n if (typeof window === 'undefined') return;\n if (!granted) { enqueue(() => engine.trackCustom(name, data, options)); return; }\n const win = window as unknown as VendorWindow;\n const params = data ?? {};\n for (const provider of gateFor(name, options?.stepId)) {\n for (const px of entriesOf(pixels, provider)) {\n if (!px.enabled) continue;\n const id = usableIdOf(px);\n if (id === null) continue;\n switch (provider) {\n // `trackSingle` with a custom name is read by Meta as an unknown standard event.\n case 'facebook': win.fbq?.('trackSingleCustom', id, name, params); break;\n case 'tiktok': win.ttq?.instance?.(id)?.track?.(name, params); break;\n // Snap offers no per-pixel target: the global broadcasts to every Snap pixel.\n case 'snapchat': win.snaptr?.('track', name, params); break;\n case 'gtm': win.gtag?.('event', name, params); break;\n case 'clarity': win.clarity?.('event', name); break;\n }\n }\n }\n },\n\n identify(identity): void {\n if (typeof window === 'undefined') return;\n for (const tracker of trackers.values()) tracker.identify(identity);\n },\n\n consent(state): void {\n if (!state.marketing) { queue.length = 0; latchedOff = true; granted = false; return; }\n if (latchedOff || granted) return;\n granted = true;\n void engine.init().then(() => {\n const pending = queue.splice(0, queue.length);\n for (const run of pending) run();\n });\n },\n\n destroy(): void {\n queue.length = 0;\n if (cspHandler && typeof window !== 'undefined') {\n window.removeEventListener('securitypolicyviolation', cspHandler);\n }\n cspHandler = null;\n trackers.clear();\n },\n };\n\n return engine;\n}\n", "/**\n * Stable event_id helper for Meta CAPI / browser pixel deduplication.\n *\n * The browser side (`fbq('track', name, params, { eventID })`) and the server\n * side (`ServerEvent.setEventId(...)`) must publish the same value to let Meta\n * dedup. This helper is the single source of truth for the formula, mirrored\n * on the server in `src/app/services/meta/meta-event-id.ts`. A parity test in\n * the server package keeps them byte-identical.\n *\n * Convention: `${eventName}_${entityId}`. Different event names get different\n * IDs even when fired for the same entity (e.g. a Purchase + Subscribe pair on\n * the same order), so each dedups independently.\n */\nexport function makeMetaEventId(eventName: string, entityId: string): string {\n return `${eventName}_${entityId}`;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["pixels_exports", "__export", "SDK_PIXEL_PROVIDERS", "bootstrapPixelTrackerFromWindow", "buildGa4PurchasePayload", "createPixelEngine", "createPixelTracker", "getEligiblePixels", "isEventEnabled", "isSafePixelId", "makeMetaEventId", "pixelIdKeyOf", "resolvePixelEvents", "pixelIdKeyOf", "pixel", "GA4_PARAM_KEY", "extractCouponCodes", "order", "codes", "p", "_a", "c", "buildGa4PurchasePayload", "_b", "_c", "_d", "_e", "_f", "_g", "sourceItems", "coupon", "summary", "s", "itemsSum", "sum", "i", "lineLevelDiscountTotal", "orderLevelDiscount", "remainingAllocation", "items", "item", "index", "quantity", "unitAdjusted", "lineValue", "lineAllocation", "unitAllocation", "unitDiscount", "ga4Item", "value", "payload", "addr", "userData", "
|
|
3
|
+
"sources": ["../src/pixels/index.ts", "../src/pixels/pixelIdentity.ts", "../src/pixels/pixelMapping.ts", "../src/pixels/pixelPurchaseHanded.ts", "../src/pixels/pixelTracker.ts", "../src/pixels/engine.ts", "../src/pixels/metaEventId.ts"],
|
|
4
|
+
"sourcesContent": ["export { createPixelEngine, SDK_PIXEL_PROVIDERS } from './engine.js';\nexport type {\n PixelEngine, PixelEngineConfig, PixelSignal, PixelSignalKind, SdkPixelProvider,\n} from './engine.js';\n\nexport { makeMetaEventId } from './metaEventId.js';\nexport { bootstrapPixelTrackerFromWindow, createPixelTracker, isSafePixelId } from './pixelTracker.js';\nexport type { PixelTracker, PurchaseTrace, TrackOptions } from './pixelTracker.js';\nexport {\n buildGa4PurchasePayload, getEligiblePixels, IDENTITY_HASHES_PARAM_KEY, isEventEnabled, pixelIdKeyOf, resolvePixelEvents,\n} from './pixelMapping.js';\nexport type { PixelProviderKey, StandardPixelEvent } from './pixelMapping.js';\nexport type { PixelRawIdentity, ServerIdentityHashes } from './pixelIdentity.js';\nexport type { PixelConfig, PixelsConfig } from './types.js';\n", "/**\n * Client-side identity hashing for pixel advanced matching.\n *\n * Framework-agnostic (no DOM). Normalizes + SHA-256-hashes the customer\n * identifiers (email / phone / external id) so the tracker can feed match\n * keys to Snapchat (`user_hashed_email`/`user_hashed_phone_number`) and TikTok\n * (`ttq.identify`). We hash in the browser ourselves so raw PII never leaves\n * the page \u2014 TikTok requires pre-hashed values anyway, and Snap/Meta accept\n * pre-hashed too.\n */\n\nexport interface PixelRawIdentity {\n /** Raw email (any case). */\n email?: string;\n /** Raw phone in any format. */\n phone?: string;\n /** Stable external id (e.g. Tagada customer id). */\n externalId?: string;\n}\n\nexport interface PixelHashedIdentity {\n /** SHA-256 hex of the normalized email. */\n email?: string;\n /** SHA-256 hex of the E.164-normalized phone. */\n phone?: string;\n /** SHA-256 hex of the trimmed external id. */\n externalId?: string;\n}\n\n/**\n * The buyer's email and phone hashed by our server, per ad platform format, as\n * the public order read returns them to the recognised buyer.\n */\nexport interface ServerIdentityHashes {\n meta?: IdentityHashPair;\n tiktok?: IdentityHashPair;\n snap?: IdentityHashPair;\n google?: IdentityHashPair;\n applovin?: IdentityHashPair;\n}\n\nexport interface IdentityHashPair {\n email?: string;\n phone?: string;\n}\n\nconst SHA256_HEX_PATTERN = /^[a-f0-9]{64}$/;\n\nexport function isSha256Hex(value: unknown): value is string {\n return typeof value === 'string' && SHA256_HEX_PATTERN.test(value);\n}\n\nconst MASKED_VALUE_PATTERN = /[*\u2022]/;\n\n/**\n * A masked value (`r***@gmail.com`, as the public order read returns it) is\n * never hashed nor handed to a pixel: it would become a key that matches no one.\n */\nexport function isMaskedValue(value: string | undefined): boolean {\n return value != null && MASKED_VALUE_PATTERN.test(value);\n}\n\n/** The identity with every masked value removed. */\nexport function withoutMaskedValues(id: PixelRawIdentity): PixelRawIdentity {\n const out: PixelRawIdentity = {};\n if (id.email && !isMaskedValue(id.email)) out.email = id.email;\n if (id.phone && !isMaskedValue(id.phone)) out.phone = id.phone;\n if (id.externalId && !isMaskedValue(id.externalId)) out.externalId = id.externalId;\n return out;\n}\n\n/** Lowercase + trim \u2014 the normalization Meta/Snap/TikTok all expect for email. */\nfunction normalizeEmail(email: string): string {\n return email.trim().toLowerCase();\n}\n\n/**\n * Normalize to E.164-ish: keep a single leading `+` (if present) and digits.\n * Snap and TikTok both expect E.164 with the country-code `+`, so a single\n * hash satisfies both. (Meta wants digits-only \u2014 add a per-provider variant\n * here if Meta browser matching is added later.)\n */\nfunction normalizePhone(phone: string): string {\n const trimmed = phone.trim();\n const hasPlus = trimmed.startsWith('+');\n const digits = trimmed.replace(/[^0-9]/g, '');\n if (!digits) return '';\n return (hasPlus ? '+' : '') + digits;\n}\n\nasync function sha256Hex(input: string): Promise<string> {\n const data = new TextEncoder().encode(input);\n const buf = await crypto.subtle.digest('SHA-256', data);\n return Array.from(new Uint8Array(buf))\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n}\n\n/** True when SubtleCrypto is usable (secure context). */\nexport function canHashIdentity(): boolean {\n return (\n typeof crypto !== 'undefined' &&\n typeof crypto.subtle !== 'undefined' &&\n typeof crypto.subtle.digest === 'function'\n );\n}\n\n/**\n * Hash whichever identifiers are present. Empty/whitespace-only fields are\n * skipped so we never emit a hash of \"\". Returns `{}` when nothing usable.\n */\nexport async function buildHashedIdentity(id: PixelRawIdentity): Promise<PixelHashedIdentity> {\n const out: PixelHashedIdentity = {};\n\n if (id.email) {\n const n = normalizeEmail(id.email);\n if (n) out.email = await sha256Hex(n);\n }\n if (id.phone) {\n const n = normalizePhone(id.phone);\n if (n) out.phone = await sha256Hex(n);\n }\n if (id.externalId) {\n const n = id.externalId.trim();\n if (n) out.externalId = await sha256Hex(n);\n }\n\n return out;\n}\n", "/**\n * Core pixel event mapping, parameter transformation, and event gating.\n *\n * This module is framework-agnostic (no React, no DOM) so it can be shared\n * between the React `PixelTrackingProvider` and the standalone vanilla SDK.\n *\n * Official event name references (verified Feb 2026 against vendor docs):\n * Meta: fbq('track', 'Purchase', { value, currency }) \u2014 developers.facebook.com/docs/meta-pixel/reference\n * TikTok: ttq.track('Purchase', { value, currency }) \u2014 ads.tiktok.com/help/article/standard-events-parameters (Sep 2025)\n * Snapchat: snaptr('track', 'PURCHASE', { price, currency }) \u2014 developers.snap.com/api/marketing-api/Conversions-API/Parameters\n * Pinterest: pintrk('track', 'checkout', { value, currency }) \u2014 help.pinterest.com/en/business/article/add-event-codes\n * GTM/GA4: gtag('event', 'purchase', { value, currency, items })\n * Clarity: clarity('event', 'Purchase') \u2014 learn.microsoft.com/en-us/clarity/setup-and-installation/clarity-api\n * AppLovin: axon('track', 'purchase', { value, currency, items }) \u2014 support.axon.ai/en/growth/axon-pixel/events-and-objects\n */\n\nimport type {\n SnapchatTrackingConfig,\n GTMTrackingConfig,\n ClarityTrackingConfig,\n ApplovinTrackingConfig,\n PixelConfig,\n PixelsConfig,\n} from './types.js';\nimport {\n isMaskedValue,\n isSha256Hex,\n type IdentityHashPair,\n type PixelRawIdentity,\n type ServerIdentityHashes,\n} from './pixelIdentity.js';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport type StandardPixelEvent =\n | 'PageView'\n | 'ViewContent'\n | 'AddToCart'\n | 'AddToWishlist'\n | 'Search'\n | 'InitiateCheckout'\n | 'AddPaymentInfo'\n | 'Purchase'\n | 'Lead'\n | 'CompleteRegistration'\n | 'Conversion';\n\nexport type PixelProviderKey = 'facebook' | 'tiktok' | 'snapchat' | 'pinterest' | 'gtm' | 'clarity' | 'applovin';\n\n/** The field a pixel entry carries its tracking id in. */\nexport type PixelIdKey = 'pixelId' | 'containerId' | 'projectId' | 'eventKey';\n\n/**\n * Which key holds this entry's id: GTM stores a `containerId`, Clarity a\n * `projectId`, AppLovin an `eventKey`, every other provider a `pixelId`.\n * Callers that sanitize, split or display an id go through here rather than\n * testing the keys themselves, so a new provider with its own field name is\n * one edit, not six.\n */\nexport function pixelIdKeyOf(pixel: unknown): PixelIdKey {\n if (pixel && typeof pixel === 'object') {\n if ('containerId' in pixel) return 'containerId';\n if ('projectId' in pixel) return 'projectId';\n if ('eventKey' in pixel) return 'eventKey';\n }\n return 'pixelId';\n}\n\nexport interface MappedEvent {\n name: string;\n params: Record<string, unknown>;\n}\n\n// ---------------------------------------------------------------------------\n// GA4-only enrichment\n//\n// Canonical GA4 ecommerce `purchase` data carries user identity + a nested\n// `ecommerce` object that the flat Meta/TikTok payload does not. We attach it\n// to the shared track() params under the reserved `_ga4` key. ONLY mapGTMEvent\n// reads it; `baseTransform` strips it so it can never leak into the\n// Meta/TikTok/Snapchat/Pinterest payloads (those would otherwise spread it,\n// shipping unhashed PII to those pixels). All monetary fields are in MINOR\n// units here \u2014 mapGTMEvent converts to major via the same currency helpers.\n// ---------------------------------------------------------------------------\n\nexport const GA4_PARAM_KEY = '_ga4' as const;\n\n/** Reserved key of the Purchase params carrying the server's `ServerIdentityHashes`; stripped from every payload. */\nexport const IDENTITY_HASHES_PARAM_KEY = '_identity_hashes' as const;\n\nexport interface Ga4UserData {\n email_address?: string;\n phone_number?: string;\n address?: {\n first_name?: string;\n last_name?: string;\n street?: string;\n city?: string;\n region?: string;\n postal_code?: string;\n country?: string;\n };\n}\n\nfunction hasSha256Pair(pair: unknown): boolean {\n if (typeof pair !== 'object' || pair === null) return false;\n const { email, phone } = pair as IdentityHashPair;\n return isSha256Hex(email) || isSha256Hex(phone);\n}\n\n/**\n * The server's hashes an event carries under `IDENTITY_HASHES_PARAM_KEY`, or undefined when no platform's pair holds a\n * SHA-256 hash: a buyer the server did not recognise must not switch the tracker into server-hash mode with nothing.\n */\nexport function serverIdentityHashesOf(parameters: Record<string, unknown>): ServerIdentityHashes | undefined {\n const hashes = parameters[IDENTITY_HASHES_PARAM_KEY];\n if (typeof hashes !== 'object' || hashes === null) return undefined;\n return Object.values(hashes).some(hasSha256Pair) ? (hashes as ServerIdentityHashes) : undefined;\n}\n\n/** Google's user data with the server's hashes in place of the email and the phone, the rest of the address kept. */\nexport function withGoogleServerHashes(\n ud: Ga4UserData | undefined,\n hashes: IdentityHashPair | undefined,\n): Record<string, unknown> {\n const { email_address: _email, phone_number: _phone, ...rest } = ud ?? {};\n const out: Record<string, unknown> = { ...rest };\n if (isSha256Hex(hashes?.email)) out.sha256_email_address = hashes.email;\n if (isSha256Hex(hashes?.phone)) out.sha256_phone_number = hashes.phone;\n return out;\n}\n\n/** The user data without a masked email or phone. */\nexport function withoutMaskedUserData(ud: Ga4UserData): Ga4UserData {\n const { email_address, phone_number, ...rest } = ud;\n const out: Ga4UserData = { ...rest };\n if (email_address && !isMaskedValue(email_address)) out.email_address = email_address;\n if (phone_number && !isMaskedValue(phone_number)) out.phone_number = phone_number;\n return out;\n}\n\nexport interface Ga4Item {\n item_id?: string;\n item_name?: string;\n item_variant?: string;\n /** Minor units (cents). Post-discount unit price (GA4 spec). Converted to major by mapGTMEvent. */\n price?: number;\n quantity?: number;\n /** Minor units (cents). Per-unit monetary discount (line-level + allocated order-level). */\n discount?: number;\n /** Coupon code(s) that discounted this item. */\n coupon?: string;\n}\n\nexport interface Ga4PurchasePayload {\n user_id?: string;\n user_data?: Ga4UserData;\n /** Minor units (cents). */\n value?: number;\n /** Minor units (cents). */\n tax?: number;\n /** Minor units (cents). */\n shipping?: number;\n /** Order-level coupon code(s), comma-joined. */\n coupon?: string;\n items: Ga4Item[];\n}\n\n/** Loose order shape accepted by buildGa4PurchasePayload (subset of SDK Order). */\nexport interface Ga4OrderInput {\n id?: string;\n currency?: string;\n paidAmount?: number;\n items?: Array<{\n productId?: string;\n variantId?: string | null;\n quantity?: number;\n /** Pre-discount unit amount (minor units). */\n amount?: number;\n adjustedAmount?: number;\n orderLineItemProduct?: { name?: string };\n orderLineItemVariant?: { name?: string };\n }>;\n summaries?: Array<{\n currency?: string;\n totalTaxAmount?: number;\n shippingCost?: number;\n totalAdjustedAmount?: number;\n totalPromotionAmount?: number;\n }>;\n /**\n * Applied promotions. Accepts both shapes seen in the wild:\n * promotion-usage rows with a nested `promotion` (CMS order endpoint) and\n * flat promotion summaries with a `code` (SDK OrderWithRelations).\n */\n promotions?: Array<{\n code?: string | null;\n promotion?: { code?: string | null } | null;\n }>;\n customer?: { id?: string; email?: string; phone?: string; firstName?: string; lastName?: string };\n billingAddress?: Ga4Address;\n shippingAddress?: Ga4Address;\n}\n\n/**\n * Extract the distinct coupon codes applied to an order, comma-joined.\n * Returns undefined when the order carries no coded promotions (automatic\n * promotions have `code: null` and are deliberately excluded \u2014 GA4's `coupon`\n * dimension is for codes the shopper entered).\n */\nexport function extractCouponCodes(order: Pick<Ga4OrderInput, 'promotions'>): string | undefined {\n const codes = (order.promotions ?? [])\n .map((p) => p.code ?? p.promotion?.code)\n .filter((c): c is string => typeof c === 'string' && c.length > 0);\n if (codes.length === 0) return undefined;\n return [...new Set(codes)].join(',');\n}\n\ninterface Ga4Address {\n firstName?: string;\n lastName?: string;\n address1?: string;\n city?: string;\n state?: string;\n postal?: string;\n country?: string;\n phone?: string;\n}\n\n/**\n * Build the GA4-only enrichment payload (`_ga4`) from an order. Pure, defensive,\n * framework-agnostic \u2014 shared by the native ThankYouPage and the Studio\n * OrderConfirmation island so both emit an identical canonical GA4 purchase.\n * Returns minor-unit amounts; mapGTMEvent converts them to major units.\n */\nexport function buildGa4PurchasePayload(order: Ga4OrderInput): Ga4PurchasePayload {\n const sourceItems = order.items ?? [];\n const coupon = extractCouponCodes(order);\n\n const summary =\n order.summaries?.find((s) => s.currency === order.currency) ?? order.summaries?.[0];\n\n const itemsSum = sourceItems.reduce(\n (sum, i) => sum + (i.adjustedAmount ?? 0) * (i.quantity ?? 0),\n 0,\n );\n\n // GA4 requires order-level discounts to be allocated across items: `price`\n // must be the post-discount unit price and `discount` the per-unit monetary\n // discount. Line-level discounts are already baked into adjustedAmount; the\n // order-level remainder (totalPromotionAmount minus line-level discounts,\n // capped to the item subtotal \u2014 promos can also cover shipping) is spread\n // proportionally by line value.\n const lineLevelDiscountTotal = sourceItems.reduce(\n (sum, i) => sum + Math.max(0, (i.amount ?? i.adjustedAmount ?? 0) - (i.adjustedAmount ?? 0)) * (i.quantity ?? 0),\n 0,\n );\n const orderLevelDiscount = Math.min(\n Math.max(0, (summary?.totalPromotionAmount ?? 0) - lineLevelDiscountTotal),\n itemsSum,\n );\n\n let remainingAllocation = orderLevelDiscount;\n const items: Ga4Item[] = sourceItems.map((item, index) => {\n const quantity = item.quantity ?? 0;\n const unitAdjusted = item.adjustedAmount ?? 0;\n const lineValue = unitAdjusted * quantity;\n\n // Last item takes the remainder so allocations sum exactly.\n const lineAllocation =\n orderLevelDiscount === 0 || itemsSum === 0\n ? 0\n : index === sourceItems.length - 1\n ? remainingAllocation\n : Math.round((orderLevelDiscount * lineValue) / itemsSum);\n remainingAllocation -= lineAllocation;\n\n const unitAllocation = quantity > 0 ? lineAllocation / quantity : 0;\n const lineLevelUnitDiscount = Math.max(0, (item.amount ?? unitAdjusted) - unitAdjusted);\n const unitDiscount = lineLevelUnitDiscount + unitAllocation;\n\n const ga4Item: Ga4Item = {\n item_id: item.productId || undefined,\n // GA4 convention: item_name = product, item_variant = variant.\n item_name: item.orderLineItemProduct?.name || item.orderLineItemVariant?.name || undefined,\n item_variant: item.orderLineItemVariant?.name || undefined,\n price: unitAdjusted - unitAllocation,\n quantity: item.quantity,\n };\n if (unitDiscount > 0) {\n ga4Item.discount = unitDiscount;\n if (coupon) ga4Item.coupon = coupon;\n }\n return ga4Item;\n });\n\n // Prefer the captured paid amount; fall back to the summary total, then to\n // the sum of line items. Guards against the value:0 seen in the field.\n const value =\n order.paidAmount && order.paidAmount > 0\n ? order.paidAmount\n : (summary?.totalAdjustedAmount ?? itemsSum);\n\n const payload: Ga4PurchasePayload = { items, value };\n if (summary?.totalTaxAmount != null) payload.tax = summary.totalTaxAmount;\n if (summary?.shippingCost != null) payload.shipping = summary.shippingCost;\n if (coupon) payload.coupon = coupon;\n\n if (order.customer?.id) payload.user_id = order.customer.id;\n\n const addr = order.billingAddress ?? order.shippingAddress;\n const userData: Ga4UserData = {};\n if (order.customer?.email && !isMaskedValue(order.customer.email)) userData.email_address = order.customer.email;\n const phone = [order.customer?.phone, addr?.phone].find((value) => value && !isMaskedValue(value));\n if (phone) userData.phone_number = phone;\n if (addr) {\n const address = {\n first_name: addr.firstName || order.customer?.firstName || undefined,\n last_name: addr.lastName || order.customer?.lastName || undefined,\n street: addr.address1 || undefined,\n city: addr.city || undefined,\n region: addr.state || undefined,\n postal_code: addr.postal || undefined,\n country: addr.country || undefined,\n };\n if (Object.values(address).some((v) => v != null)) userData.address = address;\n }\n if (Object.keys(userData).length > 0) payload.user_data = userData;\n\n return payload;\n}\n\n// ---------------------------------------------------------------------------\n// Currency conversion helper (inline, zero-dep)\n// ---------------------------------------------------------------------------\n\n/**\n * Convert minor units (cents) to major units using ISO 4217 digit counts.\n * Falls back to \u00F7100 for unknown currencies.\n */\nconst ZERO_DECIMAL_CURRENCIES = new Set([\n 'BIF', 'CLP', 'DJF', 'GNF', 'ISK', 'JPY', 'KMF', 'KRW',\n 'PYG', 'RWF', 'UGX', 'VND', 'VUV', 'XAF', 'XOF', 'XPF',\n]);\n\nconst THREE_DECIMAL_CURRENCIES = new Set(['BHD', 'IQD', 'JOD', 'KWD', 'LYD', 'OMR', 'TND']);\n\nfunction minorToMajor(amount: number, currency: string): number {\n const code = currency.toUpperCase();\n if (ZERO_DECIMAL_CURRENCIES.has(code)) return amount;\n if (THREE_DECIMAL_CURRENCIES.has(code)) return amount / 1000;\n return amount / 100;\n}\n\n// ---------------------------------------------------------------------------\n// Event gating \u2013 respects per-event toggles\n// ---------------------------------------------------------------------------\n\n/**\n * Returns `true` if the given event is enabled on the pixel config.\n * If the pixel has no `events` map (e.g. MetaConversionTrackingConfig) we allow all.\n */\nexport function isEventEnabled(pixel: PixelConfig, eventName: StandardPixelEvent): boolean {\n if (!('events' in pixel) || !pixel.events) return true;\n const events = pixel.events as Record<string, boolean>;\n if (!(eventName in events)) return true; // unknown event \u2192 allow\n return events[eventName] === true;\n}\n\n/**\n * Filter an array of pixel configs to only those that are globally enabled\n * AND have the specific event toggled on.\n */\nexport function getEligiblePixels<T extends PixelConfig>(\n pixels: T[] | undefined,\n eventName: StandardPixelEvent,\n): T[] {\n if (!pixels) return [];\n return pixels.filter((p) => p.enabled && isEventEnabled(p, eventName));\n}\n\n// ---------------------------------------------------------------------------\n// Shared parameter transforms\n// ---------------------------------------------------------------------------\n\nfunction ensureCurrencyUppercase(params: Record<string, unknown>): Record<string, unknown> {\n if (params.currency && typeof params.currency === 'string') {\n return { ...params, currency: params.currency.toUpperCase() };\n }\n return { ...params };\n}\n\nfunction convertValueToMajor(params: Record<string, unknown>): Record<string, unknown> {\n if (params.currency && params.value != null) {\n const currency = String(params.currency);\n const major = minorToMajor(Number(params.value), currency);\n return { ...params, value: major };\n }\n return params;\n}\n\n/** Convert top-level monetary fields (shipping, tax, subtotal, total_discount) from minor \u2192 major units. */\nfunction convertMonetaryFieldsToMajor(params: Record<string, unknown>): Record<string, unknown> {\n const currency = params.currency ? String(params.currency) : null;\n if (!currency) return params;\n const result = { ...params };\n for (const field of ['shipping', 'tax', 'subtotal', 'total_discount'] as const) {\n if (result[field] != null) {\n result[field] = minorToMajor(Number(result[field]), currency);\n }\n }\n return result;\n}\n\n/** Convert price fields inside contents[] items from minor \u2192 major units. */\nfunction convertContentsPricesToMajor(params: Record<string, unknown>): Record<string, unknown> {\n if (!params.contents || !Array.isArray(params.contents)) return params;\n const currency = params.currency ? String(params.currency) : null;\n const result = { ...params };\n result.contents = (params.contents as Record<string, unknown>[]).map((item) => {\n const itemCurrency = item.currency ? String(item.currency) : currency;\n if (!itemCurrency) return { ...item };\n const converted = { ...item };\n if (converted.price != null) converted.price = minorToMajor(Number(converted.price), itemCurrency);\n if (converted.original_price != null) converted.original_price = minorToMajor(Number(converted.original_price), itemCurrency);\n return converted;\n });\n return result;\n}\n\nfunction baseTransform(params: Record<string, unknown>): Record<string, unknown> {\n let p = ensureCurrencyUppercase(params);\n p = convertValueToMajor(p);\n p = convertMonetaryFieldsToMajor(p);\n p = convertContentsPricesToMajor(p);\n // Strip GA4-only enrichment so it never reaches Meta/TikTok/Snapchat/Pinterest\n // (those mappers spread all params). mapGTMEvent reads it from the raw input.\n if (GA4_PARAM_KEY in p || IDENTITY_HASHES_PARAM_KEY in p) {\n p = { ...p };\n delete p[GA4_PARAM_KEY];\n delete p[IDENTITY_HASHES_PARAM_KEY];\n }\n return p;\n}\n\n// ---------------------------------------------------------------------------\n// Meta / Facebook\n// ---------------------------------------------------------------------------\n\nconst META_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'PageView',\n ViewContent: 'ViewContent',\n AddToCart: 'AddToCart',\n AddToWishlist: 'AddToWishlist',\n Search: 'Search',\n InitiateCheckout: 'InitiateCheckout',\n AddPaymentInfo: 'AddPaymentInfo',\n Purchase: 'Purchase',\n Lead: 'Lead',\n CompleteRegistration: 'CompleteRegistration',\n};\n\nexport function mapMetaEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = META_EVENT_MAP[eventName] ?? eventName;\n // `coupon` intentionally flows through: Meta has no standard coupon param but\n // accepts custom parameters on standard events (usable in custom conversions).\n const params = baseTransform(parameters);\n\n if (params.contents && Array.isArray(params.contents)) {\n params.content_ids = (params.contents as Record<string, unknown>[]).map((i) => i.content_id).filter(Boolean);\n params.content_type = params.content_type ?? 'product';\n\n // Reshape contents to Meta's expected format (prices already converted by baseTransform)\n params.contents = (params.contents as Record<string, unknown>[]).map((item) => ({\n id: item.content_id,\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n item_price: item.price != null ? Number(item.price) : undefined,\n content_name: item.content_name,\n content_category: item.content_category,\n }));\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// TikTok\n// Official: ttq.track('Purchase', { value, currency })\n// Source: ads.tiktok.com/help/article/standard-events-parameters (Sep 2025)\n// Standard events use PascalCase. Note: TikTok has no standard PageView event\n// (page views use ttq.page()), so we pass it as-is for custom tracking.\n// TikTok has no Lead event; SubmitForm is the closest standard equivalent.\n// ---------------------------------------------------------------------------\n\nconst TIKTOK_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'Pageview',\n ViewContent: 'ViewContent',\n AddToCart: 'AddToCart',\n AddToWishlist: 'AddToWishlist',\n Search: 'Search',\n InitiateCheckout: 'InitiateCheckout',\n AddPaymentInfo: 'AddPaymentInfo',\n Purchase: 'Purchase',\n Lead: 'SubmitForm',\n CompleteRegistration: 'CompleteRegistration',\n};\n\nexport function mapTikTokEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = TIKTOK_EVENT_MAP[eventName] ?? eventName;\n const params = baseTransform(parameters);\n\n // TikTok's event spec has no coupon/discount parameter \u2014 strip it to keep\n // the payload within spec (avoids Events Manager diagnostics warnings).\n delete params.coupon;\n\n if (params.contents && Array.isArray(params.contents)) {\n const ids = (params.contents as Record<string, unknown>[])\n .map((i) => i.content_id)\n .filter(Boolean) as string[];\n\n if (!params.content_id && ids.length === 1) {\n params.content_id = ids[0];\n }\n\n // Also keep content_ids for backwards compatibility\n if (!params.content_ids) {\n params.content_ids = ids;\n }\n\n // Reshape contents to TikTok's expected format (prices already converted by baseTransform)\n params.contents = (params.contents as Record<string, unknown>[]).map((item) => ({\n content_id: item.content_id,\n content_name: item.content_name,\n content_type: item.content_type ?? 'product',\n content_category: item.content_category,\n price: item.price != null ? Number(item.price) : undefined,\n original_price: item.original_price != null ? Number(item.original_price) : undefined,\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n description: item.description,\n }));\n }\n\n // Set required fields for InitiateCheckout\n if (eventName === 'InitiateCheckout') {\n params.content_type = params.content_type ?? 'product';\n if (!params.delivery_category) {\n params.delivery_category = 'home_delivery';\n }\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// Snapchat\n// Official: snaptr('track', 'PURCHASE', { price, currency })\n// Source: developers.snap.com/api/marketing-api/Conversions-API/Parameters\n// All event names are UPPER_SNAKE_CASE.\n// Note: Snapchat has no LEAD standard event; we pass it as-is (custom event).\n// ---------------------------------------------------------------------------\n\nconst SNAPCHAT_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'PAGE_VIEW',\n ViewContent: 'VIEW_CONTENT',\n AddToCart: 'ADD_CART',\n AddToWishlist: 'ADD_TO_WISHLIST',\n Search: 'SEARCH',\n InitiateCheckout: 'START_CHECKOUT',\n AddPaymentInfo: 'ADD_BILLING',\n Purchase: 'PURCHASE',\n Lead: 'LEAD',\n CompleteRegistration: 'SIGN_UP',\n};\n\nexport function mapSnapchatEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = SNAPCHAT_EVENT_MAP[eventName] ?? eventName;\n let params = baseTransform(parameters);\n\n // Snap's parameter spec has no coupon/discount field \u2014 strip it.\n delete params.coupon;\n\n // Snapchat uses `price` not `value`\n if ('value' in params) {\n params = { ...params, price: params.value };\n delete params.value;\n }\n\n // Snapchat uses `number_items` not `num_items`\n if ('num_items' in params) {\n params = { ...params, number_items: params.num_items };\n delete params.num_items;\n }\n\n if (params.contents && Array.isArray(params.contents)) {\n params.item_ids = (params.contents as { content_id?: string }[]).map((i) => i.content_id).filter(Boolean);\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// Pinterest\n// Official: pintrk('track', 'checkout', { value, currency, line_items })\n// Event names are all lowercase.\n// ---------------------------------------------------------------------------\n\nconst PINTEREST_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'pagevisit',\n ViewContent: 'viewcontent',\n AddToCart: 'addtocart',\n AddToWishlist: 'addtowishlist',\n Search: 'search',\n InitiateCheckout: 'initiatecheckout',\n AddPaymentInfo: 'addpaymentinfo',\n Purchase: 'checkout',\n Lead: 'lead',\n CompleteRegistration: 'signup',\n};\n\nexport function mapPinterestEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = PINTEREST_EVENT_MAP[eventName] ?? eventName.toLowerCase();\n const params = baseTransform(parameters);\n\n // Pinterest's official field for coupon codes is `promo_code`.\n if (params.coupon != null) {\n params.promo_code = params.coupon;\n delete params.coupon;\n }\n\n if (params.order_quantity !== undefined) {\n params.order_quantity = Number(params.order_quantity);\n }\n\n if (params.contents && Array.isArray(params.contents)) {\n // Reshape to Pinterest line_items format (prices already converted by baseTransform)\n params.line_items = (params.contents as Record<string, unknown>[]).map((item) => ({\n product_id: item.content_id,\n product_name: item.content_name,\n product_category: item.content_category,\n product_price: item.price != null ? Number(item.price) : undefined,\n product_quantity: item.quantity != null ? Number(item.quantity) : undefined,\n }));\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// GTM / GA4 / Google Ads\n// Official: gtag('event', 'purchase', { value, currency, items })\n// Event names are snake_case (GA4 convention).\n// ---------------------------------------------------------------------------\n\nconst GTM_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'page_view',\n ViewContent: 'view_item',\n AddToCart: 'add_to_cart',\n AddToWishlist: 'add_to_wishlist',\n Search: 'search',\n InitiateCheckout: 'begin_checkout',\n AddPaymentInfo: 'add_payment_info',\n Purchase: 'purchase',\n Lead: 'generate_lead',\n CompleteRegistration: 'sign_up',\n Conversion: 'conversion',\n};\n\nexport function mapGTMEvent(eventName: StandardPixelEvent, parameters: Record<string, unknown>): MappedEvent {\n const name = GTM_EVENT_MAP[eventName] ?? eventName.toLowerCase();\n\n // Canonical GA4 ecommerce shape: when the caller attached `_ga4` enrichment\n // (purchase from the thank-you page) emit a nested `ecommerce` object plus\n // user identity instead of the legacy flat payload. baseTransform strips\n // `_ga4`, so read it from the raw input first.\n const ga4 = parameters[GA4_PARAM_KEY] as Ga4PurchasePayload | undefined;\n if (ga4) {\n const currency =\n typeof parameters.currency === 'string' ? parameters.currency.toUpperCase() : undefined;\n const toMajor = (v: number | undefined): number | undefined =>\n v == null || !currency ? v : minorToMajor(Number(v), currency);\n\n const ecommerce: Record<string, unknown> = {\n transaction_id: parameters.transaction_id,\n currency,\n value: toMajor(ga4.value),\n };\n if (ga4.tax != null) ecommerce.tax = toMajor(ga4.tax);\n if (ga4.shipping != null) ecommerce.shipping = toMajor(ga4.shipping);\n if (ga4.coupon) ecommerce.coupon = ga4.coupon;\n ecommerce.items = (ga4.items ?? []).map((item) => ({\n item_id: item.item_id,\n item_name: item.item_name,\n item_variant: item.item_variant,\n price: toMajor(item.price),\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n ...(item.discount != null ? { discount: toMajor(item.discount) } : {}),\n ...(item.coupon ? { coupon: item.coupon } : {}),\n }));\n\n const out: Record<string, unknown> = { ecommerce };\n if (ga4.user_id) out.user_id = ga4.user_id;\n const serverHashes = serverIdentityHashesOf(parameters);\n const userData = serverHashes\n ? withGoogleServerHashes(ga4.user_data, serverHashes.google)\n : ga4.user_data && withoutMaskedUserData(ga4.user_data);\n if (userData && Object.keys(userData).length > 0) out.user_data = userData;\n return { name, params: out };\n }\n\n const params = baseTransform(parameters);\n\n if (params.num_items !== undefined) {\n params.num_items = Number(params.num_items);\n }\n\n if (params.contents && Array.isArray(params.contents)) {\n // Reshape to GA4 items format (prices already converted by baseTransform)\n params.items = (params.contents as Record<string, unknown>[]).map((item) => ({\n item_id: item.content_id,\n item_name: item.content_name,\n item_category: item.content_category,\n price: item.price != null ? Number(item.price) : undefined,\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n }));\n\n params.contents = (params.contents as Record<string, unknown>[]).map((item) => ({\n id: item.content_id,\n name: item.content_name,\n category: item.content_category,\n price: item.price != null ? Number(item.price) : undefined,\n quantity: item.quantity != null ? Number(item.quantity) : undefined,\n }));\n }\n\n return { name, params };\n}\n\n// ---------------------------------------------------------------------------\n// Microsoft Clarity\n// Official: clarity('event', 'Purchase') \u2014 custom (\"smart\") events take a name\n// and no parameters, so the mapped params are carried for the dedup guard only.\n// Clarity records page views by itself; the PageView toggle still emits a named\n// event so a merchant can filter recordings on it like any other funnel step.\n// ---------------------------------------------------------------------------\n\nconst CLARITY_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'PageView',\n ViewContent: 'ViewContent',\n AddToCart: 'AddToCart',\n AddToWishlist: 'AddToWishlist',\n Search: 'Search',\n InitiateCheckout: 'InitiateCheckout',\n AddPaymentInfo: 'AddPaymentInfo',\n Purchase: 'Purchase',\n Lead: 'Lead',\n CompleteRegistration: 'CompleteRegistration',\n};\n\nexport function mapClarityEvent(\n eventName: StandardPixelEvent,\n parameters: Record<string, unknown>,\n): MappedEvent {\n const name = CLARITY_EVENT_MAP[eventName] ?? eventName;\n return { name, params: baseTransform(parameters) };\n}\n\n// ---------------------------------------------------------------------------\n// AppLovin (Axon pixel)\n// Official: axon('track', 'purchase', { currency, items, shipping, tax,\n// transaction_id, value, user_data }, { dedupe_id })\n// Source: support.axon.ai/en/growth/axon-pixel/events-and-objects\n// Event names are snake_case. Only the events below exist for a purchase site;\n// any other standard event is not sent to AppLovin. Every payload is rebuilt\n// from scratch, so a parameter AppLovin does not define never reaches it.\n// ---------------------------------------------------------------------------\n\nexport const APPLOVIN_EVENT_MAP: Partial<Record<StandardPixelEvent, string>> = {\n PageView: 'page_view',\n ViewContent: 'view_item',\n AddToCart: 'add_to_cart',\n InitiateCheckout: 'begin_checkout',\n AddPaymentInfo: 'add_payment_info',\n Purchase: 'purchase',\n};\n\n/** AppLovin's user data object. Raw values: the Axon script hashes them itself. */\nexport interface ApplovinUserData {\n email?: string;\n phone?: string;\n user_id?: string;\n}\n\nconst APPLOVIN_MIN_USER_ID_LENGTH = 6;\nconst APPLOVIN_IMAGE_PATTERN = /\\.(png|jpe?g)$/i;\n\n/**\n * Shape an identity as AppLovin's `user_data`: email lowercased, phone as\n * digits only (leading zeros dropped, as AppLovin's normalisation does), and\n * the external id as `user_id` only when it has the six characters AppLovin\n * requires. A masked email or phone (`r***@gmail.com`, as some order reads\n * return it) is dropped: AppLovin would hash it into a key that matches no one.\n * Returns undefined when nothing usable is left.\n */\nexport function toApplovinUserData(identity: PixelRawIdentity): ApplovinUserData | undefined {\n const out: ApplovinUserData = {};\n const email = identity.email?.trim().toLowerCase();\n if (email && !isMaskedValue(email)) out.email = email;\n const rawPhone = identity.phone?.trim();\n const phone = rawPhone && !isMaskedValue(rawPhone) && !/[a-z]/i.test(rawPhone)\n ? rawPhone.replace(/[^0-9]/g, '').replace(/^0+/, '')\n : undefined;\n if (phone) out.phone = phone;\n const userId = identity.externalId?.trim();\n if (userId && userId.length >= APPLOVIN_MIN_USER_ID_LENGTH) out.user_id = userId;\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\n/** AppLovin's `user_data` from the server's hashes, which the Axon script passes through unhashed. */\nexport function toApplovinServerUserData(\n hashes: IdentityHashPair | undefined,\n externalId: string | undefined,\n): ApplovinUserData | undefined {\n const out: ApplovinUserData = {};\n if (isSha256Hex(hashes?.email)) out.email = hashes.email;\n if (isSha256Hex(hashes?.phone)) out.phone = hashes.phone;\n const userId = toApplovinUserData({ externalId })?.user_id;\n if (userId) out.user_id = userId;\n return Object.keys(out).length > 0 ? out : undefined;\n}\n\n/**\n * The entry a page loads: AppLovin's script takes one event key per page, so\n * only the first enabled entry is initialised and only its toggles apply.\n */\nexport function activeApplovinPixel(\n pixels: ApplovinTrackingConfig[] | undefined,\n): ApplovinTrackingConfig | undefined {\n return pixels?.find((pixel) => pixel.enabled);\n}\n\nfunction finiteNumber(value: unknown): number | undefined {\n if (value == null || value === '') return undefined;\n const n = Number(value);\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction roundMoney(amount: number): number {\n return Math.round(amount * 1000) / 1000;\n}\n\n/**\n * Our `content_id` is `<productId>-<variantId>`. A product id may hold dashes\n * (`bpc157-10mg`), a variant id does not: the longest known product id that\n * starts the content id wins, else the split is at the last dash.\n */\nfunction splitContentId(contentId: string, productIds: readonly string[]): { itemId: string; variantId?: string } {\n const productId = productIds\n .filter((id) => contentId.startsWith(`${id}-`))\n .reduce<string | undefined>((longest, id) => (!longest || id.length > longest.length ? id : longest), undefined);\n if (productId) {\n const variantId = contentId.slice(productId.length + 1);\n return variantId ? { itemId: productId, variantId } : { itemId: productId };\n }\n const dash = contentId.lastIndexOf('-');\n if (dash === -1) return { itemId: contentId };\n const product = contentId.slice(0, dash);\n const variant = contentId.slice(dash + 1);\n if (!product) return { itemId: variant };\n return variant ? { itemId: product, variantId: variant } : { itemId: product };\n}\n\nfunction applovinImageUrl(value: unknown): string | undefined {\n if (typeof value !== 'string' || !value) return undefined;\n const path = value.split(/[?#]/)[0];\n return APPLOVIN_IMAGE_PATTERN.test(path) ? value : undefined;\n}\n\n/**\n * Reads `contents[]` after baseTransform, so `price` is already in major units.\n * `productIds` are the order's own product ids, from its GA4 items.\n */\nfunction applovinItems(contents: unknown, productIds: readonly string[]): Record<string, unknown>[] {\n if (!Array.isArray(contents)) return [];\n return contents.flatMap((entry) => {\n if (!entry || typeof entry !== 'object') return [];\n const item = entry as Record<string, unknown>;\n const rawId = typeof item.content_id === 'string' && item.content_id ? item.content_id : item.id;\n if (typeof rawId !== 'string' || !rawId) return [];\n const { itemId, variantId } = splitContentId(rawId, productIds);\n if (!itemId) return [];\n const out: Record<string, unknown> = { item_id: itemId };\n if (variantId) out.item_variant_id = variantId;\n if (typeof item.content_name === 'string' && item.content_name) out.item_name = item.content_name;\n const price = finiteNumber(item.price);\n if (price != null) out.price = price;\n const quantity = finiteNumber(item.quantity);\n if (quantity != null) out.quantity = quantity;\n const imageUrl = applovinImageUrl(item.image_url);\n if (imageUrl) out.image_url = imageUrl;\n return [out];\n });\n}\n\n/**\n * Map a standard event to AppLovin's name and payload, or null when AppLovin\n * has no such event. Amounts leave in major units. `value` is the subtotal\n * AppLovin asks for on `begin_checkout` and `purchase`: the amount minus\n * shipping and tax, never below zero.\n */\nexport function mapApplovinEvent(\n eventName: StandardPixelEvent,\n parameters: Record<string, unknown>,\n): MappedEvent | null {\n const name = APPLOVIN_EVENT_MAP[eventName];\n if (!name) return null;\n\n const ga4 = parameters[GA4_PARAM_KEY] as Ga4PurchasePayload | undefined;\n const params: Record<string, unknown> = {};\n const serverHashes = serverIdentityHashesOf(parameters);\n const userData = serverHashes\n ? toApplovinServerUserData(serverHashes.applovin, ga4?.user_id)\n : ga4\n ? toApplovinUserData({\n email: ga4.user_data?.email_address,\n phone: ga4.user_data?.phone_number,\n externalId: ga4.user_id,\n })\n : undefined;\n\n if (eventName === 'PageView') {\n if (userData) params.user_data = userData;\n return { name, params };\n }\n\n const p = baseTransform(parameters);\n const currency = typeof p.currency === 'string' && p.currency ? p.currency : undefined;\n const toMajor = (amount: unknown): number | undefined => {\n const n = finiteNumber(amount);\n return n == null || !currency ? undefined : minorToMajor(n, currency);\n };\n\n if (currency) params.currency = currency;\n const productIds = (ga4?.items ?? [])\n .map((item) => item.item_id)\n .filter((id): id is string => typeof id === 'string' && id.length > 0);\n const items = applovinItems(p.contents, productIds);\n if (items.length > 0) params.items = items;\n\n // Without a currency `value` is still in minor units, so it is left out.\n const value = currency ? finiteNumber(p.value) ?? toMajor(ga4?.value) : undefined;\n\n if (eventName === 'InitiateCheckout' || eventName === 'Purchase') {\n const shipping = (currency ? finiteNumber(p.shipping) : undefined) ?? toMajor(ga4?.shipping) ?? 0;\n const tax = (currency ? finiteNumber(p.tax) : undefined) ?? toMajor(ga4?.tax) ?? 0;\n if (value != null) params.value = Math.max(0, roundMoney(value - shipping - tax));\n if (eventName === 'Purchase') {\n params.shipping = shipping;\n params.tax = tax;\n if (p.transaction_id != null && p.transaction_id !== '') params.transaction_id = String(p.transaction_id);\n }\n } else if (value != null) {\n params.value = value;\n }\n\n if (userData) params.user_data = userData;\n return { name, params };\n}\n\nfunction googleAdsTag(id: unknown): string {\n const text = String(id).trim();\n return /^\\d+$/.test(text) ? `AW-${text}` : text;\n}\n\n/**\n * Append Google Ads `send_to` parameter when conversion tracking is configured.\n */\nexport function applyGoogleAdsConversion(\n params: Record<string, unknown>,\n eventName: StandardPixelEvent,\n pixel: GTMTrackingConfig,\n): Record<string, unknown> {\n if (\n (eventName === 'Purchase' || eventName === 'Conversion') &&\n pixel.googleAdsConversionId &&\n pixel.googleAdsConversionLabel\n ) {\n // Merchants paste the bare number Google Ads shows; `send_to` wants it as `AW-<number>`.\n return {\n ...params,\n send_to: `${googleAdsTag(pixel.googleAdsConversionId)}/${pixel.googleAdsConversionLabel}`,\n };\n }\n return params;\n}\n\n// ---------------------------------------------------------------------------\n// Dispatcher \u2013 maps a StandardPixelEvent to all providers in one call\n// ---------------------------------------------------------------------------\n\nexport interface ProviderEvent {\n provider: PixelProviderKey;\n mapped: MappedEvent;\n pixel: PixelConfig;\n}\n\n/**\n * Given a PixelsConfig and an event, return per-provider mapped events\n * for every eligible (enabled + event-toggled-on) pixel.\n */\nexport function resolvePixelEvents(\n pixels: PixelsConfig,\n eventName: StandardPixelEvent,\n parameters: Record<string, unknown>,\n): ProviderEvent[] {\n const results: ProviderEvent[] = [];\n\n const fb = getEligiblePixels(pixels.facebook, eventName);\n if (fb.length > 0) {\n const mapped = mapMetaEvent(eventName, parameters);\n fb.forEach((pixel) => results.push({ provider: 'facebook', mapped, pixel }));\n }\n\n const tt = getEligiblePixels(pixels.tiktok, eventName);\n if (tt.length > 0) {\n const mapped = mapTikTokEvent(eventName, parameters);\n tt.forEach((pixel) => results.push({ provider: 'tiktok', mapped, pixel }));\n }\n\n const sc = getEligiblePixels(pixels.snapchat as SnapchatTrackingConfig[] | undefined, eventName);\n if (sc.length > 0) {\n const mapped = mapSnapchatEvent(eventName, parameters);\n sc.forEach((pixel) => results.push({ provider: 'snapchat', mapped, pixel }));\n }\n\n const pt = getEligiblePixels(pixels.pinterest, eventName);\n if (pt.length > 0) {\n const mapped = mapPinterestEvent(eventName, parameters);\n pt.forEach((pixel) => results.push({ provider: 'pinterest', mapped, pixel }));\n }\n\n const clarity = getEligiblePixels(pixels.clarity as ClarityTrackingConfig[] | undefined, eventName);\n if (clarity.length > 0) {\n const mapped = mapClarityEvent(eventName, parameters);\n clarity.forEach((pixel) => results.push({ provider: 'clarity', mapped, pixel }));\n }\n\n const applovin = activeApplovinPixel(pixels.applovin);\n if (applovin && getEligiblePixels([applovin], eventName).length > 0) {\n const mapped = mapApplovinEvent(eventName, parameters);\n if (mapped) results.push({ provider: 'applovin', mapped, pixel: applovin });\n }\n\n const gtm = getEligiblePixels(pixels.gtm as GTMTrackingConfig[] | undefined, eventName);\n if (gtm.length > 0) {\n const mapped = mapGTMEvent(eventName, parameters);\n gtm.forEach((pixel) => {\n const finalParams = applyGoogleAdsConversion(mapped.params, eventName, pixel as GTMTrackingConfig);\n results.push({ provider: 'gtm', mapped: { name: mapped.name, params: finalParams }, pixel });\n });\n }\n\n return results;\n}\n", "import type { PixelProviderKey } from './pixelMapping.js';\nimport { isSha256Hex, type ServerIdentityHashes } from './pixelIdentity.js';\nimport type { PurchaseTrace } from './pixelTracker.js';\n\ntype TracedProvider = 'meta' | 'tiktok' | 'google' | 'snapchat' | 'pinterest' | 'applovin';\n\ntype ScriptState = 'loaded' | 'load_failed' | 'not_loaded' | 'unknown';\n\nconst TRACED_PROVIDERS: Partial<Record<PixelProviderKey, TracedProvider>> = {\n facebook: 'meta', tiktok: 'tiktok', gtm: 'google', snapchat: 'snapchat', pinterest: 'pinterest', applovin: 'applovin',\n};\n\nconst IDENTITY_HASHES_OF: Partial<Record<PixelProviderKey, keyof ServerIdentityHashes>> = {\n facebook: 'meta', tiktok: 'tiktok', gtm: 'google', snapchat: 'snap', applovin: 'applovin',\n};\n\nconst COLLECT_PATH = '/api/public/v2/e';\nconst PIXELS_SDK_VERSION = '1';\n// The collector's views open a session for any UUIDv7 session id: the nil id keeps this fact out of them.\nconst NIL_SESSION_ID = '00000000-0000-0000-0000-000000000000';\nconst PURCHASES_HANDED_KEY = 'tgd_pixel_purchases_handed';\nconst PURCHASE_HANDED_MEMORY_MS = 30 * 24 * 60 * 60 * 1000;\nconst PURCHASE_HANDED_MEMORY_SIZE = 300;\nconst purchasesHandedOnPage = new Set<string>();\n\nfunction scriptStateOf(scripts: readonly (HTMLScriptElement | null)[]): ScriptState {\n const states = scripts\n .filter((script): script is HTMLScriptElement => script !== null)\n .map((script) => script.dataset.tgdScriptState ?? 'not_loaded');\n if (states.length === 0) return 'unknown';\n if (states.includes('loaded')) return 'loaded';\n if (states.includes('load_failed')) return 'load_failed';\n return 'not_loaded';\n}\n\nfunction identityOriginOf(provider: PixelProviderKey, server: ServerIdentityHashes | undefined): 'server_hash' | 'none' {\n const platform = IDENTITY_HASHES_OF[provider];\n const pair = platform ? server?.[platform] : undefined;\n return isSha256Hex(pair?.email) || isSha256Hex(pair?.phone) ? 'server_hash' : 'none';\n}\n\nfunction uuidV7(now: number): string | null {\n const cryptoApi = typeof crypto !== 'undefined' ? crypto : undefined;\n if (!cryptoApi?.getRandomValues) return null;\n const bytes = cryptoApi.getRandomValues(new Uint8Array(16));\n let time = now;\n for (let i = 5; i >= 0; i -= 1) {\n bytes[i] = time % 256;\n time = Math.floor(time / 256);\n }\n bytes[6] = 0x70 | (bytes[6] & 0x0f);\n bytes[8] = 0x80 | (bytes[8] & 0x3f);\n const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\n/** True the first time this order and platform are claimed in this browser; the memory keeps 30 days and 300 entries. */\nfunction claimPurchaseHanded(key: string): boolean {\n if (purchasesHandedOnPage.has(key)) return false;\n purchasesHandedOnPage.add(key);\n const now = Date.now();\n try {\n const storage = window.localStorage;\n const parsed: unknown = JSON.parse(storage.getItem(PURCHASES_HANDED_KEY) || '{}');\n const handed: Record<string, number> = {};\n if (parsed && typeof parsed === 'object') {\n const record = parsed as Record<string, unknown>;\n Object.keys(record).forEach((id) => {\n const at = record[id];\n if (typeof at === 'number' && now - at < PURCHASE_HANDED_MEMORY_MS) handed[id] = at;\n });\n }\n if (handed[key] !== undefined) return false;\n const memory: Record<string, number> = { [key]: now };\n Object.keys(handed)\n .sort((a, b) => handed[b] - handed[a])\n .slice(0, PURCHASE_HANDED_MEMORY_SIZE - 1)\n .forEach((id) => { memory[id] = handed[id]; });\n storage.setItem(PURCHASES_HANDED_KEY, JSON.stringify(memory));\n } catch {\n /* storage unavailable: once per page load */\n }\n return true;\n}\n\n/** One fact per request, sent so that it leaves even when the tab closes. */\nfunction sendPurchaseHanded(trace: PurchaseTrace, props: Record<string, string>): void {\n const now = Date.now();\n const batchId = uuidV7(now);\n const eventId = uuidV7(now);\n if (!batchId || !eventId) return;\n const body = JSON.stringify({\n v: 1,\n batch_id: batchId,\n sent_at: now,\n store_id: trace.storeId,\n sdk: { name: 'pixels', version: PIXELS_SDK_VERSION },\n events: [{\n event_id: eventId,\n event_name: 'pixel_purchase_handed',\n source: 'browser',\n created_at: now,\n store_id: trace.storeId,\n session_id: NIL_SESSION_ID,\n props,\n }],\n });\n try {\n if (typeof fetch === 'function') {\n fetch(COLLECT_PATH, {\n method: 'POST',\n body,\n headers: { 'content-type': 'text/plain;charset=UTF-8' },\n keepalive: true,\n credentials: 'omit',\n }).catch(() => undefined);\n } else {\n navigator.sendBeacon?.(COLLECT_PATH, new Blob([body], { type: 'text/plain;charset=UTF-8' }));\n }\n } catch {\n /* the fact is lost, never the Purchase */\n }\n}\n\nexport function reportPurchaseHanded(\n trace: PurchaseTrace,\n provider: PixelProviderKey,\n eventId: string | undefined,\n server: ServerIdentityHashes | undefined,\n scripts: readonly (HTMLScriptElement | null)[],\n): void {\n const traced = TRACED_PROVIDERS[provider];\n if (!traced || !trace.storeId || !trace.orderId) return;\n if (!claimPurchaseHanded(`${trace.orderId}:${traced}`)) return;\n sendPurchaseHanded(trace, {\n provider: traced,\n provider_event_id: provider === 'gtm' || provider === 'applovin' || !eventId ? trace.orderId : eventId,\n order_id: trace.orderId,\n script_state: scriptStateOf(scripts),\n identity_origin: identityOriginOf(provider, server),\n });\n}\n", "/**\n * Framework-agnostic pixel tracker.\n *\n * Init / fire logic for Meta, TikTok, Snapchat, Pinterest, GTM/GA4,\n * Microsoft Clarity and AppLovin pixels \u2014\n * extracted from `react/hooks/usePixelTracking.tsx` so non-React entry points\n * (Studio islands hydrator, full-SPA runtime) can fire pixel events from\n * `window.__TGD_STEP_CONFIG__.pixels`.\n *\n * The React provider is a thin adapter on top of this module.\n */\n\nimport type { ClarityTrackingConfig, GTMTrackingConfig, PixelConfig, PixelsConfig } from './types.js';\nimport {\n resolvePixelEvents,\n pixelIdKeyOf,\n activeApplovinPixel,\n serverIdentityHashesOf,\n toApplovinServerUserData,\n toApplovinUserData,\n withGoogleServerHashes,\n withoutMaskedUserData,\n GA4_PARAM_KEY,\n type ApplovinUserData,\n type Ga4PurchasePayload,\n type Ga4UserData,\n type PixelProviderKey,\n type StandardPixelEvent,\n} from './pixelMapping.js';\nimport {\n buildHashedIdentity,\n canHashIdentity,\n isSha256Hex,\n withoutMaskedValues,\n type IdentityHashPair,\n type PixelHashedIdentity,\n type PixelRawIdentity,\n type ServerIdentityHashes,\n} from './pixelIdentity.js';\nimport { reportPurchaseHanded } from './pixelPurchaseHanded.js';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/**\n * Optional per-event tracking metadata. `eventId` is the cross-channel dedup\n * key that the SDK threads to `fbq` (Meta) and `ttq` (TikTok) so the same\n * eventID/event_id can be matched against a server-side CAPI event. Use the\n * `makeMetaEventId(eventName, entityId)` helper from `core/utils/metaEventId`\n * to keep the formula in lockstep with the server.\n */\nexport interface TrackOptions {\n eventId?: string;\n /**\n * When set, only the pixels of these providers receive the event; the\n * others are left untouched. Unset, every configured provider receives it.\n */\n providers?: readonly PixelProviderKey[];\n /**\n * A Purchase only: each ad platform handed this order reports it to TagadaPay's\n * collector (`pixel_purchase_handed`), once per order and platform per browser.\n */\n purchaseTrace?: PurchaseTrace;\n}\n\nexport interface PurchaseTrace {\n storeId: string;\n /** The visit's main order. */\n orderId: string;\n}\n\nexport interface PixelTracker {\n /** Resolves once all pixel scripts have loaded (or hit their load timeout). */\n readonly initPromise: Promise<void>;\n /** True after `initPromise` resolves. */\n readonly pixelsInitialized: boolean;\n /** Track a standard pixel event. No-ops until init resolves. */\n track(\n eventName: StandardPixelEvent,\n parameters?: Record<string, unknown>,\n options?: TrackOptions,\n ): void;\n /**\n * Feed customer identifiers for advanced matching. Applies to Meta (fbq init,\n * raw \u2014 Meta hashes in-browser), Google (gtag set user_data, raw \u2014 enhanced\n * conversions), Snapchat (re-init) + TikTok (identify), the last two with\n * client-side SHA-256 hashing, and AppLovin (raw `user_data` added to each\n * of its events \u2014 the Axon script hashes it). Once an event brought the\n * server's hashes under `_identity_hashes`, every one of them gets only those. Each provider persists the keys onto\n * subsequent events, so call this as soon as the email is known to lift\n * match quality on InitiateCheckout + Purchase. Idempotent per identity; safe\n * to call repeatedly.\n */\n identify(identity: PixelRawIdentity): void;\n}\n\n// ---------------------------------------------------------------------------\n// Duplicate guard (time-window based)\n// ---------------------------------------------------------------------------\n\nfunction createDuplicateGuard(windowMs: number) {\n const lastEvents = new Map<string, number>();\n return (\n eventName: StandardPixelEvent,\n parameters: Record<string, unknown>,\n eventId?: string,\n providers?: readonly PixelProviderKey[],\n ): boolean => {\n try {\n // Include eventId in the dedup key so two distinct logical events with the\n // same name+params (e.g. two Purchases) are not collapsed by the guard.\n // The provider scope too: a call aimed at one provider must not swallow\n // the same event sent to all of them.\n const key = JSON.stringify({ eventName, parameters, eventId, providers });\n const now = Date.now();\n const last = lastEvents.get(key);\n if (last && now - last < windowMs) return false;\n lastEvents.set(key, now);\n return true;\n } catch {\n return true;\n }\n };\n}\n\n// ---------------------------------------------------------------------------\n// Browser-specific: fire an event to the correct global pixel function\n// ---------------------------------------------------------------------------\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * The entry's own identifier, read at whichever key its provider uses \u2014\n * `pixelId`, or `containerId` / `projectId` for GTM and Clarity.\n */\nfunction pixelIdOf(pixel?: PixelConfig): string | null {\n if (!pixel) return null;\n const value = (pixel as unknown as Record<string, unknown>)[pixelIdKeyOf(pixel)];\n return typeof value === 'string' && value ? value : null;\n}\n\nfunction fire(\n provider: PixelProviderKey,\n name: string,\n params: Record<string, unknown>,\n pixel?: PixelConfig,\n options: TrackOptions = {},\n) {\n if (typeof window === 'undefined') return;\n const w = window as any;\n const eventId = options.eventId;\n switch (provider) {\n case 'facebook': {\n // Target this pixel by id rather than calling the global `fbq('track')`,\n // which Meta broadcasts to EVERY pixel registered on the page \u2014 including\n // ones a merchant initialised from a pasted script we don't manage. That\n // broadcast made our Purchase land on foreign pixels, undeduplicated.\n // Mirrors the per-pixel targeting already used for TikTok below.\n //\n // Meta dedup: pass eventID as the trailing `eventID` option so this\n // browser-pixel event matches a server-side CAPI event with the same id.\n // See https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events\n // No id means no addressable pixel: stay silent rather than fall back to\n // the broadcast this change exists to remove. `sanitizePixels` drops every\n // entry without a usable id, so this is unreachable today.\n const pixelId = pixelIdOf(pixel);\n if (!pixelId) break;\n if (eventId) w.fbq?.('trackSingle', pixelId, name, params, { eventID: eventId });\n else w.fbq?.('trackSingle', pixelId, name, params);\n break;\n }\n case 'tiktok': {\n // Use ttq.instance(pixelId) to target each pixel individually,\n // since the global ttq.track() only fires for the sdkid pixel.\n const pixelId = pixelIdOf(pixel);\n const target = pixelId && w.ttq?.instance ? w.ttq.instance(pixelId) : w.ttq;\n if (name === 'Pageview') { target?.page?.(); }\n else if (eventId) { target?.track?.(name, params, { event_id: eventId }); }\n else { target?.track?.(name, params); }\n break;\n }\n case 'snapchat':\n // Snap dedup: the browser event carries client_dedup_id = the event id that the\n // server CAPI event sends as event_id (destinations.md \u00A79.3).\n w.snaptr?.('track', name, eventId ? { ...params, client_dedup_id: eventId } : params);\n break;\n case 'pinterest':\n // Pinterest handles page views via pintrk('page'), not pintrk('track', 'pagevisit')\n if (name === 'pagevisit') { w.pintrk?.('page'); }\n else { w.pintrk?.('track', name, eventId ? { ...params, event_id: eventId } : params); }\n break;\n case 'gtm': fireGTM(name, params); break;\n // Clarity's custom-event API takes a name and nothing else; params stay\n // out rather than being stringified into the event name.\n case 'clarity': w.clarity?.('event', name); break;\n case 'applovin': {\n // AppLovin dedup: the order id for a purchase, else the caller's event id.\n const dedupeId =\n name === 'purchase' && typeof params.transaction_id === 'string' && params.transaction_id\n ? params.transaction_id\n : eventId;\n if (dedupeId) w.axon?.('track', name, params, { dedupe_id: dedupeId });\n else w.axon?.('track', name, params);\n break;\n }\n }\n}\n\n/**\n * Apply advanced matching to a single Snapchat pixel. Snap reads user info set\n * at init and attaches it to every event fired afterwards; re-calling init with\n * the (now-known) hashed identifiers updates it. We pass pre-hashed values via\n * the `user_hashed_*` keys.\n */\nfunction applySnapchatIdentity(w: any, pixelId: string, h: PixelHashedIdentity) {\n if (!w?.snaptr) return;\n const userInfo: Record<string, string> = {};\n if (h.email) userInfo.user_hashed_email = h.email;\n if (h.phone) userInfo.user_hashed_phone_number = h.phone;\n if (Object.keys(userInfo).length === 0) return;\n w.snaptr('init', pixelId, userInfo);\n}\n\n/**\n * Apply advanced matching to a single TikTok pixel via `ttq.identify`. TikTok\n * applies identified data to subsequent events and accepts pre-hashed SHA-256\n * values (it detects 64-char hex and won't double-hash). Target the specific\n * pixel instance, mirroring the per-pixel track() targeting.\n */\nfunction applyTikTokIdentity(w: any, pixelId: string, h: PixelHashedIdentity) {\n const target = w?.ttq?.instance ? w.ttq.instance(pixelId) : w?.ttq;\n if (!target?.identify) return;\n const info: Record<string, string> = {};\n if (h.email) info.email = h.email;\n if (h.phone) info.phone_number = h.phone;\n if (h.externalId) info.external_id = h.externalId;\n if (Object.keys(info).length === 0) return;\n target.identify(info);\n}\n\n/**\n * Apply advanced matching to a single Meta pixel. Meta reads advanced-matching\n * data passed to `fbq('init', pixelId, userData)` and attaches it to every\n * event fired afterwards; re-calling init with the (now-known) identifiers\n * updates it (init is idempotent and never auto-fires PageView). We pass RAW\n * values \u2014 `fbevents.js` normalizes + SHA-256-hashes them in-browser before\n * they leave the page \u2014 because Meta's phone normalization (digits-only) differs\n * from Snap/TikTok's E.164, so letting Meta hash avoids a mismatch.\n */\nfunction applyMetaIdentity(w: any, pixelId: string, raw: PixelRawIdentity) {\n if (!w?.fbq) return;\n const ud: Record<string, string> = {};\n if (raw.email) ud.em = raw.email.trim().toLowerCase();\n if (raw.phone) { const d = raw.phone.replace(/[^0-9]/g, ''); if (d) ud.ph = d; }\n if (raw.externalId) ud.external_id = raw.externalId.trim();\n if (Object.keys(ud).length === 0) return;\n w.fbq('init', pixelId, ud);\n}\n\n/**\n * Meta with the server's hashes, which `fbevents.js` passes through unhashed:\n * `em` and `ph` never carry a raw value, whatever else the page knows.\n */\nfunction applyMetaServerIdentity(w: any, pixelId: string, hashes: IdentityHashPair | undefined, externalId?: string) {\n if (!w?.fbq) return;\n const ud: Record<string, string> = {};\n if (isSha256Hex(hashes?.email)) ud.em = hashes.email;\n if (isSha256Hex(hashes?.phone)) ud.ph = hashes.phone;\n if (externalId) ud.external_id = externalId.trim();\n if (Object.keys(ud).length === 0) return;\n w.fbq('init', pixelId, ud);\n}\n\n/**\n * Google Ads enhanced conversions / GA4 user-provided data.\n *\n * Google's documented mechanism is `gtag('set', 'user_data', {...})` BEFORE the\n * conversion event fires (support.google.com/google-ads/answer/13258081) \u2014\n * `user_data` as an event parameter is not read for enhanced conversions. We\n * pass RAW values; the Google tag normalizes + SHA-256 hashes in-browser. With\n * the server's hashes, `sha256_email_address` and `sha256_phone_number` take the\n * place of the email and the phone. Field names per spec: `email`, `phone_number` (strict E.164 \u2014 dropped when\n * not in that shape, email is the preferred key anyway), and\n * `address.{first_name,last_name,street,city,region,postal_code,country}`.\n * Exported for unit tests.\n */\nexport function applyGoogleIdentity(w: any, input: Ga4UserData, serverHashes?: IdentityHashPair) {\n if (typeof w?.gtag !== 'function') return;\n const ud = withoutMaskedUserData(input);\n\n const userData: Record<string, unknown> = serverHashes ? withGoogleServerHashes(undefined, serverHashes) : {};\n if (!serverHashes && ud.email_address) userData.email = ud.email_address.trim().toLowerCase();\n\n if (!serverHashes && ud.phone_number) {\n const phone = ud.phone_number.replace(/[^0-9+]/g, '');\n if (/^\\+[0-9]{10,14}$/.test(phone)) userData.phone_number = phone;\n }\n\n if (ud.address) {\n const a = ud.address;\n const address: Record<string, string> = {};\n if (a.first_name) address.first_name = a.first_name;\n if (a.last_name) address.last_name = a.last_name;\n if (a.street) address.street = a.street;\n if (a.city) address.city = a.city;\n if (a.region) address.region = a.region;\n if (a.postal_code) address.postal_code = a.postal_code;\n if (a.country) address.country = a.country;\n if (Object.keys(address).length > 0) userData.address = address;\n }\n\n if (Object.keys(userData).length === 0) return;\n w.gtag('set', 'user_data', userData);\n}\n\nfunction fireGTM(event: string, params: Record<string, unknown>) {\n try {\n const w = window as any;\n const hasEcommerce = params && typeof params === 'object' && 'ecommerce' in params;\n if (w.gtag) {\n // gtag.js (GA4 config tag) reads ecommerce fields at the top level of the\n // event, not under a nested `ecommerce` key \u2014 flatten it back out.\n if (hasEcommerce) {\n const { ecommerce, ...rest } = params as Record<string, unknown>;\n w.gtag('event', event, { ...rest, ...(ecommerce as Record<string, unknown>) });\n } else {\n w.gtag('event', event, params);\n }\n } else if (w.dataLayer) {\n // GA4 best practice: clear the previous ecommerce object before pushing a\n // new one so item arrays from earlier events don't bleed through.\n if (hasEcommerce) w.dataLayer.push({ ecommerce: null });\n w.dataLayer.push({ event, ...params });\n }\n } catch (error) {\n console.error('[SDK GTM] Error:', error);\n }\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n// ===========================================================================\n// Pixel initialization (browser-only)\n// All pixel globals are accessed via `win` typed as `any` to avoid\n// `declare global` augmentation issues across tsconfig scopes.\n// ===========================================================================\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nconst win = (typeof window !== 'undefined' ? window : undefined) as any;\n\nconst SCRIPT_LOAD_TIMEOUT_MS = 5000;\n\ntype PixelScriptState = 'loaded' | 'load_failed' | 'not_loaded' | 'unknown';\n\nfunction waitForScriptLoad(script: HTMLScriptElement): Promise<void> {\n // If the script has already loaded, resolve immediately\n if (script.dataset.loaded) return Promise.resolve();\n\n return new Promise((resolve) => {\n const settle = (state: PixelScriptState) => () => {\n script.dataset.loaded = '1';\n script.dataset.tgdScriptState = state;\n clearTimeout(timer);\n resolve();\n };\n const timer = setTimeout(settle('not_loaded'), SCRIPT_LOAD_TIMEOUT_MS);\n script.addEventListener('load', settle('loaded'), { once: true });\n script.addEventListener('error', settle('load_failed'), { once: true });\n });\n}\n\nlet _metaScriptEl: HTMLScriptElement | null = null;\n\nfunction initMetaPixel(pixelId: string, autoTracking = true): Promise<void> {\n if (!win) return Promise.resolve();\n\n // Initialize Meta base code once\n if (!win.fbq) {\n const n = function (...args: any[]) {\n if (n.callMethod) n.callMethod(...args); else n.queue.push(args);\n } as any;\n n.queue = [];\n n.loaded = true;\n n.version = '2.0';\n win.fbq = n;\n if (!win._fbq) win._fbq = n;\n const t = document.createElement('script') as HTMLScriptElement;\n t.async = true;\n t.src = 'https://connect.facebook.net/en_US/fbevents.js';\n const s = document.getElementsByTagName('script')[0];\n s?.parentNode?.insertBefore(t, s);\n _metaScriptEl = t;\n }\n\n if (!autoTracking) {\n // Read by fbevents.js when it loads, so it must be set on the stub before\n // the script runs: no PageView of its own on pushState/popstate.\n win.fbq.disablePushState = true;\n // No automatic events or button/page metadata for this pixel; must precede init.\n win.fbq('set', 'autoConfig', false, pixelId);\n }\n\n // Register each pixel ID (fbq supports multiple pixels via multiple init calls)\n win.fbq('init', pixelId);\n return _metaScriptEl ? waitForScriptLoad(_metaScriptEl) : Promise.resolve();\n}\n\nlet _tiktokBaseInitialized = false;\nconst _tiktokScriptEls: HTMLScriptElement[] = [];\n\nfunction initTikTokPixel(pixelId: string): Promise<void> {\n if (!win) return Promise.resolve();\n\n // Initialize TikTok base code once\n if (!_tiktokBaseInitialized) {\n _tiktokBaseInitialized = true;\n win.TiktokAnalyticsObject = 'ttq';\n const ttq = (win.ttq = win.ttq || []) as any;\n ttq.methods = [\n 'page', 'track', 'identify', 'instances', 'debug', 'on', 'off',\n 'once', 'ready', 'alias', 'group', 'enableCookie', 'disableCookie',\n 'holdConsent', 'revokeConsent', 'grantConsent',\n ];\n ttq.setAndDefer = function (t: any, e: string) {\n t[e] = function (...args: any[]) { t.push([e, ...args]); };\n };\n for (const method of ttq.methods) {\n ttq.setAndDefer(ttq, method);\n }\n ttq.instance = function (t: string) {\n const e = ttq._i[t] || [];\n for (const method of ttq.methods) {\n ttq.setAndDefer(e, method);\n }\n return e;\n };\n ttq.load = function (e: string, n?: any) {\n const r = 'https://analytics.tiktok.com/i18n/pixel/events.js';\n ttq._i = ttq._i || {};\n ttq._i[e] = [];\n ttq._i[e]._u = r;\n ttq._t = ttq._t || {};\n ttq._t[e] = +new Date();\n ttq._o = ttq._o || {};\n ttq._o[e] = n || {};\n const s = document.createElement('script') as HTMLScriptElement;\n s.type = 'text/javascript';\n s.async = true;\n s.src = r + '?sdkid=' + e + '&lib=ttq';\n const p = document.getElementsByTagName('script')[0];\n p?.parentNode?.insertBefore(s, p);\n };\n }\n\n // Skip if this specific pixel ID is already registered\n if (win.ttq._i?.[pixelId]) return Promise.resolve();\n\n // Register pixel and load its script\n win.ttq.load(pixelId);\n\n // Find the script we just created and wait for it\n const scripts = document.querySelectorAll<HTMLScriptElement>(\n 'script[src*=\"analytics.tiktok.com/i18n/pixel/events.js\"]'\n );\n const lastScript = scripts[scripts.length - 1];\n if (lastScript) _tiktokScriptEls.push(lastScript);\n return lastScript ? waitForScriptLoad(lastScript) : Promise.resolve();\n}\n\nlet _snapchatScriptEl: HTMLScriptElement | null = null;\n\nfunction initSnapchatPixel(pixelId: string): Promise<void> {\n if (!win) return Promise.resolve();\n\n // Initialize Snapchat base code once\n if (!win.snaptr) {\n const a = function (...args: any[]) {\n if (a.handleRequest) a.handleRequest(...args); else a.queue.push(args);\n } as any;\n a.queue = [];\n win.snaptr = a;\n const r = document.createElement('script') as HTMLScriptElement;\n r.async = true;\n r.src = 'https://sc-static.net/scevent.min.js';\n const u = document.getElementsByTagName('script')[0];\n u?.parentNode?.insertBefore(r, u);\n _snapchatScriptEl = r;\n }\n\n // Register each pixel ID (snaptr supports multiple pixels via multiple init calls)\n win.snaptr('init', pixelId);\n return _snapchatScriptEl ? waitForScriptLoad(_snapchatScriptEl) : Promise.resolve();\n}\n\nlet _pinterestScriptEl: HTMLScriptElement | null = null;\n\nfunction initPinterestPixel(pixelId: string): Promise<void> {\n if (!win) return Promise.resolve();\n\n // Initialize Pinterest base code once\n if (!win.pintrk) {\n const a = function (...args: any[]) { a.queue.push(args); } as any;\n a.queue = [];\n win.pintrk = a;\n const s = document.createElement('script') as HTMLScriptElement;\n s.async = true;\n s.src = 'https://s.pinimg.com/ct/core.js';\n const u = document.getElementsByTagName('script')[0];\n u?.parentNode?.insertBefore(s, u);\n _pinterestScriptEl = s;\n }\n\n // Register each pixel ID (pintrk supports multiple pixels via multiple load calls)\n win.pintrk('load', pixelId);\n // Note: pintrk('page') is NOT called here \u2014 the auto page-view fires via fire().\n return _pinterestScriptEl ? waitForScriptLoad(_pinterestScriptEl) : Promise.resolve();\n}\n\n/**\n * Load the Microsoft Clarity tag for one project.\n *\n * Mirrors the vendor snippet: a queueing stub so `clarity(...)` calls made\n * before the script lands are replayed, then the tag itself. Clarity ignores a\n * second project on the same page, so a project already present is a no-op.\n */\nfunction initClarity(projectId: string): Promise<void> {\n if (!win || !projectId) return Promise.resolve();\n if (document.querySelector(`script[src*=\"clarity.ms/tag/${projectId}\"]`)) return Promise.resolve();\n\n if (!win.clarity) {\n const q = function (...args: any[]) { q.q.push(args); } as any;\n q.q = [];\n win.clarity = q;\n }\n\n const s = document.createElement('script') as HTMLScriptElement;\n s.async = true;\n s.src = `https://www.clarity.ms/tag/${projectId}`;\n const first = document.getElementsByTagName('script')[0];\n if (first?.parentNode) first.parentNode.insertBefore(s, first);\n else (document.head || document.getElementsByTagName('head')[0])?.appendChild(s);\n\n return waitForScriptLoad(s);\n}\n\n/**\n * True when an AppLovin tag this SDK did not load is already on the page (a\n * merchant's pasted snippet). AppLovin's script takes one event key per page,\n * so ours stays off rather than send its events to that tag.\n */\nfunction hasForeignApplovin(): boolean {\n return Boolean(win?.axon) && win.axon.tgdManaged !== true;\n}\n\n/**\n * Load the AppLovin Axon pixel, as AppLovin's own snippet does: a queueing\n * stub carrying the event key, both of its scripts, then `axon('init')`. A\n * stub already loaded by this SDK (another tracker on the page) is reused.\n */\nlet _applovinScriptEl: HTMLScriptElement | null = null;\n\nfunction initApplovin(eventKey: string): Promise<void> {\n if (!win || !eventKey || win.axon) return Promise.resolve();\n\n const a = function (...args: any[]) {\n if (a.performOperation) a.performOperation.apply(a, args); else a.operationQueue.push(args);\n } as any;\n a.operationQueue = [];\n a.ts = Date.now();\n a.eventKey = eventKey;\n a.tgdManaged = true;\n win.axon = a;\n\n const first = document.getElementsByTagName('script')[0];\n const scripts = ['https://s.axon.ai/pixel.js', 'https://res4.applovin.com/p/l/loader.iife.js'].map((src) => {\n const s = document.createElement('script') as HTMLScriptElement;\n s.async = true;\n s.src = src;\n if (first?.parentNode) first.parentNode.insertBefore(s, first);\n else (document.head || document.getElementsByTagName('head')[0])?.appendChild(s);\n return s;\n });\n _applovinScriptEl = scripts[0];\n\n win.axon('init');\n return Promise.all(scripts.map(waitForScriptLoad)).then(() => undefined);\n}\n\n/** AppLovin's script defines `performOperation` on the stub once it runs: a call is then really handed to it. */\nfunction isApplovinLoaded(): boolean {\n return typeof window !== 'undefined' && typeof (window as any).axon?.performOperation === 'function';\n}\n\n/**\n * Remember an order once AppLovin's script holds it: at once when the script\n * already took the stub over, else when its script finishes loading and takes\n * over the queue the order waits in. A script that fails or never takes over\n * leaves the order to the next page.\n */\nfunction rememberApplovinPurchaseWhenReceived(transactionId: string): void {\n if (isApplovinLoaded()) {\n markApplovinPurchaseSent(transactionId);\n return;\n }\n _applovinScriptEl?.addEventListener('load', () => {\n if (isApplovinLoaded()) markApplovinPurchaseSent(transactionId);\n }, { once: true });\n}\n\n/**\n * AppLovin's once-only purchase memory, kept across reloads of the same\n * browser: one entry mapping each order id to when it was sent, bounded to\n * the last 30 days and the 50 most recent orders.\n */\nconst APPLOVIN_PURCHASES_KEY = 'tgd_applovin_purchases';\n/** Orders handed to `axon` on this page, received or still queued: the page never sends one twice. */\nconst applovinPurchasesOnPage = new Set<string>();\nconst APPLOVIN_PURCHASE_MEMORY_MS = 30 * 24 * 60 * 60 * 1000;\nconst APPLOVIN_PURCHASE_MEMORY_SIZE = 50;\n\nfunction readApplovinPurchases(): Record<string, number> {\n const memory: Record<string, number> = {};\n try {\n const parsed: unknown = JSON.parse((window as any).localStorage?.getItem(APPLOVIN_PURCHASES_KEY) || '{}');\n if (parsed && typeof parsed === 'object') {\n const record = parsed as Record<string, unknown>;\n for (const id of Object.keys(record)) {\n const sentAt = record[id];\n if (typeof sentAt === 'number') memory[id] = sentAt;\n }\n }\n } catch {\n /* unreadable memory: start from an empty one */\n }\n return memory;\n}\n\nfunction wasApplovinPurchaseSent(transactionId: string): boolean {\n const sentAt = readApplovinPurchases()[transactionId];\n return sentAt !== undefined && Date.now() - sentAt < APPLOVIN_PURCHASE_MEMORY_MS;\n}\n\nfunction markApplovinPurchaseSent(transactionId: string): void {\n const now = Date.now();\n const sent = { ...readApplovinPurchases(), [transactionId]: now };\n const memory: Record<string, number> = {};\n Object.keys(sent)\n .filter((id) => now - sent[id] < APPLOVIN_PURCHASE_MEMORY_MS)\n .sort((a, b) => sent[b] - sent[a])\n .slice(0, APPLOVIN_PURCHASE_MEMORY_SIZE)\n .forEach((id) => { memory[id] = sent[id]; });\n try {\n (window as any).localStorage?.setItem(APPLOVIN_PURCHASES_KEY, JSON.stringify(memory));\n } catch {\n /* storage unavailable: the order is simply not remembered */\n }\n}\n\nconst _gtagScriptEls: HTMLScriptElement[] = [];\n\nfunction initGTM(containerId: string): Promise<void> {\n if (!win || !containerId) return Promise.resolve();\n const isGtmContainer = containerId.startsWith('GTM-');\n const scriptUrlPart = isGtmContainer\n ? `googletagmanager.com/gtm.js?id=${containerId}`\n : `googletagmanager.com/gtag/js?id=${containerId}`;\n if (document.querySelector(`script[src*=\"${scriptUrlPart}\"]`)) return Promise.resolve();\n\n win.dataLayer = win.dataLayer || [];\n\n // Push referrer domain context into dataLayer before GTM loads, so tags\n // inside the container can use it for cross-domain tracking configuration.\n try {\n const ref = document.referrer && new URL(document.referrer).hostname;\n if (ref && ref !== window.location.hostname) {\n win.dataLayer.push({ tagada_referrer_domain: ref });\n }\n } catch { /* ignore invalid referrer */ }\n\n if (isGtmContainer) {\n win.dataLayer.push({ 'gtm.start': new Date().getTime(), event: 'gtm.js' });\n const f = document.getElementsByTagName('script')[0];\n const j = document.createElement('script') as HTMLScriptElement;\n j.async = true;\n j.src = 'https://www.googletagmanager.com/gtm.js?id=' + containerId;\n if (f?.parentNode) f.parentNode.insertBefore(j, f);\n else (document.head || document.getElementsByTagName('head')[0])?.appendChild(j);\n const noscript = document.createElement('noscript');\n const iframe = document.createElement('iframe');\n iframe.src = `https://www.googletagmanager.com/ns.html?id=${containerId}`;\n iframe.height = '0'; iframe.width = '0';\n iframe.style.display = 'none'; iframe.style.visibility = 'hidden';\n noscript.appendChild(iframe);\n (document.body || document.getElementsByTagName('body')[0])?.insertBefore(noscript, document.body?.firstChild ?? null);\n return waitForScriptLoad(j);\n } else {\n if (!win.gtag) {\n win.gtag = function (..._args: any[]) { win.dataLayer.push(arguments); };\n }\n win.gtag('js', new Date());\n\n // Enable cross-domain tracking: accept incoming _gl parameter from referring\n // domains (e.g. Shopify store \u2192 TagadaPay checkout) so Google preserves the\n // client-id/session across the redirect.\n const linkerConfig: Record<string, unknown> = { accept_incoming: true };\n try {\n const ref = document.referrer && new URL(document.referrer).hostname;\n if (ref && ref !== window.location.hostname) {\n linkerConfig.domains = [ref, window.location.hostname];\n }\n } catch { /* ignore invalid referrer */ }\n\n win.gtag('config', containerId, { linker: linkerConfig });\n const script = document.createElement('script') as HTMLScriptElement;\n script.async = true;\n script.src = 'https://www.googletagmanager.com/gtag/js?id=' + containerId;\n const firstScript = document.getElementsByTagName('script')[0];\n if (firstScript?.parentNode) firstScript.parentNode.insertBefore(script, firstScript);\n else (document.head || document.getElementsByTagName('head')[0])?.appendChild(script);\n _gtagScriptEls.push(script);\n return waitForScriptLoad(script);\n }\n}\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n// Google's state is its Google tag's: a Tag Manager container runs the merchant's own tags, so alone it is unknown.\nconst PIXEL_SCRIPTS_OF: Partial<Record<PixelProviderKey, () => readonly (HTMLScriptElement | null)[]>> = {\n facebook: () => [_metaScriptEl],\n tiktok: () => _tiktokScriptEls,\n snapchat: () => [_snapchatScriptEl],\n pinterest: () => [_pinterestScriptEl],\n gtm: () => _gtagScriptEls,\n applovin: () => [_applovinScriptEl],\n};\n\n// ---------------------------------------------------------------------------\n// Tracker factory\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Config sanitisation (TAG-1871)\n// ---------------------------------------------------------------------------\n\n/** Longest ID we accept \u2014 real IDs top out around 20 chars. */\nconst MAX_PIXEL_ID_LENGTH = 64;\n\n/**\n * The only shape any supported pixel / container / project ID takes: Meta\n * digits, TikTok alphanumerics, Snapchat alphanumerics + dashes, Pinterest\n * digits, Clarity project ids and `GTM-`/`AW-`/`G-` containers are all drawn\n * from `[A-Za-z0-9_-]`.\n */\nconst SAFE_PIXEL_ID_PATTERN = new RegExp(`^[A-Za-z0-9_-]{1,${MAX_PIXEL_ID_LENGTH}}$`);\n\n/** True when `value` is a single, well-formed pixel / container ID. */\nexport function isSafePixelId(value: unknown): value is string {\n return typeof value === 'string' && SAFE_PIXEL_ID_PATTERN.test(value.trim());\n}\n\n/**\n * Trim every pixel/container ID and DROP the ones that aren't plausibly IDs.\n *\n * The trim keeps per-pixel event targeting (TikTok `ttq.instance`) working when\n * the CRM stored stray whitespace. The drop is the load-bearing part: a\n * merchant once pasted a whole TikTok `<script>` snippet into the Pixel ID\n * field, the CRM split it on every comma into 56 \"pixels\", and handing those\n * fragments to `ttq.load()` sent TikTok's SDK into a hot loop that pinned the\n * renderer at 100% CPU *before first paint* \u2014 a blank checkout for days.\n *\n * The CRM now rejects such values at input, but this guard is deliberately\n * independent: it neutralises configs that are ALREADY polluted, on pages that\n * were baked before the fix, with no data migration and no re-publish.\n */\nfunction sanitizePixels(pixels: PixelsConfig): PixelsConfig {\n const out: Record<string, PixelConfig[]> = {};\n const dropped: unknown[] = [];\n\n for (const [provider, list] of Object.entries(pixels)) {\n if (!Array.isArray(list)) continue;\n const kept: PixelConfig[] = [];\n for (const px of list) {\n // GTM keys off containerId, Clarity off projectId, everyone else pixelId.\n const key = pixelIdKeyOf(px);\n const raw = (px as unknown as Record<string, unknown>)?.[key];\n if (!isSafePixelId(raw)) {\n dropped.push(raw);\n continue;\n }\n kept.push({ ...px, [key]: (raw as string).trim() } as PixelConfig);\n }\n out[provider] = kept;\n }\n\n if (dropped.length > 0) {\n console.warn(\n `[SDK Pixels] Ignored ${dropped.length} malformed pixel ID(s) \u2014 tracking for those entries is disabled.`,\n dropped,\n );\n }\n return out as PixelsConfig;\n}\n\n/**\n * Resolve once the browser has had a chance to paint.\n *\n * Third-party pixel SDKs run arbitrary vendor code on the main thread and can\n * stall it (TikTok's did, indefinitely \u2014 TAG-1871). Injecting them before first\n * paint turns any such stall into a blank page. Deferring past the first frame\n * means the worst case degrades to \"no tracking\" instead of \"no checkout\".\n *\n * Double-rAF is the standard \"after paint\" signal. The timer is a fallback for\n * backgrounded tabs (where rAF may never fire) and for non-browser environments\n * that expose a `window` without `requestAnimationFrame`.\n */\nconst PAINT_FALLBACK_MS = 1500;\n\nfunction afterFirstPaint(): Promise<void> {\n if (typeof window === 'undefined') return Promise.resolve();\n return new Promise<void>((resolve) => {\n let settled = false;\n const finish = () => {\n if (settled) return;\n settled = true;\n clearTimeout(fallback);\n resolve();\n };\n const raf: ((cb: () => void) => void) | undefined =\n typeof win?.requestAnimationFrame === 'function'\n ? win.requestAnimationFrame.bind(win)\n : undefined;\n const fallback = setTimeout(finish, raf ? PAINT_FALLBACK_MS : 0);\n if (raf) raf(() => raf(finish));\n });\n}\n\n/**\n * Create a pixel tracker for a given pixels config.\n * Kicks off pixel script init once the first frame has painted, fires PageView\n * when init resolves, and returns a `track()` function that no-ops until then.\n */\nexport function createPixelTracker(rawPixels: PixelsConfig | undefined, opts?: { autoPageView?: boolean }): PixelTracker {\n const pixels = rawPixels ? sanitizePixels(rawPixels) : rawPixels;\n const shouldTrackEvent = createDuplicateGuard(5000);\n let pixelsInitialized = false;\n let applovinStoodDown = false;\n\n const initPromise: Promise<void> = (async () => {\n if (!pixels || typeof window === 'undefined') return;\n\n // Never inject a third-party tag before the page has painted (TAG-1871).\n await afterFirstPaint();\n\n const loadPromises: Promise<void>[] = [];\n try {\n pixels.facebook?.forEach((px) => { if (px.enabled && px.pixelId) loadPromises.push(initMetaPixel(px.pixelId, (px as { autoTracking?: boolean }).autoTracking !== false)); });\n pixels.tiktok?.forEach((px) => { if (px.enabled && px.pixelId) loadPromises.push(initTikTokPixel(px.pixelId)); });\n pixels.snapchat?.forEach((px) => { if (px.enabled && px.pixelId) loadPromises.push(initSnapchatPixel(px.pixelId)); });\n pixels.pinterest?.forEach((px) => { if (px.enabled && px.pixelId) loadPromises.push(initPinterestPixel(px.pixelId)); });\n pixels.gtm?.forEach((px) => { if (px.enabled && (px as GTMTrackingConfig).containerId) loadPromises.push(initGTM((px as GTMTrackingConfig).containerId)); });\n pixels.clarity?.forEach((px) => { if (px.enabled && (px as ClarityTrackingConfig).projectId) loadPromises.push(initClarity((px as ClarityTrackingConfig).projectId)); });\n const applovin = activeApplovinPixel(pixels.applovin);\n if (applovin?.eventKey && hasForeignApplovin()) {\n applovinStoodDown = true;\n console.warn('[SDK Pixels] An AppLovin pixel is already on the page: the configured AppLovin pixel stays off.');\n } else if (applovin?.eventKey) {\n loadPromises.push(initApplovin(applovin.eventKey));\n }\n await Promise.all(loadPromises);\n } catch (error) {\n console.error('[SDK Pixels] Initialization error:', error);\n }\n pixelsInitialized = true;\n })();\n\n // Advanced matching: feed customer identity to Meta (fbq init, raw \u2014 Meta\n // hashes), Snapchat (re-init, hashed) + TikTok (identify, hashed). Applied\n // once per identity and cached, so repeated track()/identify() calls don't\n // re-apply. Each provider persists the match keys onto every subsequent\n // event it fires, so calling this as soon as the email is known lifts match\n // quality on InitiateCheckout + Purchase alike. `_identityReady` is awaited\n // before Snap/TikTok events fire so the hashed keys are attached in time.\n let _identityKey: string | null = null;\n let _identityReady: Promise<void> | null = null;\n // AppLovin has no identify call: its user_data rides on every event.\n let _applovinUserData: ApplovinUserData | undefined;\n // Set by the first event carrying the server's hashes: from then on every provider gets only those.\n let _serverHashes: ServerIdentityHashes | undefined;\n let _serverExternalId: string | undefined;\n\n const applyServerIdentity = (server: ServerIdentityHashes, externalId: string | undefined): Promise<void> | null => {\n if (!pixels) return null;\n const key = JSON.stringify([server, externalId ?? '']);\n if (_identityKey === key && _identityReady) return _identityReady;\n _identityKey = key;\n _applovinUserData = toApplovinServerUserData(server.applovin, externalId);\n pixels.facebook?.forEach((px) => {\n if (px.enabled && px.pixelId) applyMetaServerIdentity(win, px.pixelId, server.meta, externalId);\n });\n const snap = server.snap;\n pixels.snapchat?.forEach((px) => {\n if (!px.enabled || !px.pixelId) return;\n applySnapchatIdentity(win, px.pixelId, {\n email: isSha256Hex(snap?.email) ? snap.email : undefined,\n phone: isSha256Hex(snap?.phone) ? snap.phone : undefined,\n });\n });\n _identityReady = (async () => {\n try {\n const hashedExternalId =\n externalId && canHashIdentity() ? (await buildHashedIdentity({ externalId })).externalId : undefined;\n const tiktok = server.tiktok;\n pixels.tiktok?.forEach((px) => {\n if (!px.enabled || !px.pixelId) return;\n applyTikTokIdentity(win, px.pixelId, {\n email: isSha256Hex(tiktok?.email) ? tiktok.email : undefined,\n phone: isSha256Hex(tiktok?.phone) ? tiktok.phone : undefined,\n externalId: hashedExternalId,\n });\n });\n } catch (error) {\n console.error('[SDK Pixels] identify error:', error);\n }\n })();\n return _identityReady;\n };\n\n const applyIdentity = (identity: PixelRawIdentity, serverHashes?: ServerIdentityHashes): Promise<void> | null => {\n if (!pixels) return null;\n if (serverHashes) _serverHashes = serverHashes;\n const id = withoutMaskedValues(identity);\n if (_serverHashes) {\n _serverExternalId = id.externalId ?? _serverExternalId;\n return applyServerIdentity(_serverHashes, _serverExternalId);\n }\n if (!id.email && !id.phone && !id.externalId) return null;\n const applovinUserData = toApplovinUserData(id);\n if (applovinUserData) _applovinUserData = { ..._applovinUserData, ...applovinUserData };\n\n const key = `${id.email ?? ''}|${id.phone ?? ''}|${id.externalId ?? ''}`;\n if (_identityKey === key && _identityReady) return _identityReady;\n _identityKey = key;\n\n // Meta takes raw values and hashes in-browser \u2014 apply immediately, no need\n // to await our own hashing (and it works even without SubtleCrypto).\n pixels.facebook?.forEach((px) => {\n if (px.enabled && px.pixelId) applyMetaIdentity(win, px.pixelId, id);\n });\n\n // Google Ads enhanced conversions: gtag('set','user_data') persists onto\n // every subsequent gtag event, including the send_to conversion. Raw values,\n // Google hashes in-browser (same rationale as Meta).\n if (pixels.gtm?.some((px) => px.enabled)) {\n applyGoogleIdentity(win, { email_address: id.email, phone_number: id.phone });\n }\n\n // Snapchat + TikTok want pre-hashed SHA-256 values, which we compute\n // ourselves so raw PII never leaves the page. Skips when no secure context.\n if (!canHashIdentity()) return (_identityReady = Promise.resolve());\n\n // Always resolves (errors are swallowed) so deferred event fires never hang.\n _identityReady = (async () => {\n try {\n const hashed = await buildHashedIdentity(id);\n pixels.snapchat?.forEach((px) => {\n if (px.enabled && px.pixelId) applySnapchatIdentity(win, px.pixelId, hashed);\n });\n pixels.tiktok?.forEach((px) => {\n if (px.enabled && px.pixelId) applyTikTokIdentity(win, px.pixelId, hashed);\n });\n } catch (error) {\n console.error('[SDK Pixels] identify error:', error);\n }\n })();\n return _identityReady;\n };\n\n // Derive identity from the GA4 enrichment the thank-you page already attaches\n // (`_ga4.user_data`), so Purchase events get advanced matching with no\n // call-site changes. Returns the readiness promise, or null when absent.\n const applyIdentityFromParams = (\n parameters: Record<string, unknown>,\n ): Promise<void> | null => {\n const ga4 = parameters[GA4_PARAM_KEY] as Ga4PurchasePayload | undefined;\n const ud = ga4?.user_data;\n const serverHashes = serverIdentityHashesOf(parameters);\n if (!ud && !serverHashes) return null;\n // Google enhanced conversions get the FULL user_data (incl. address) here,\n // richer than the email/phone identity below \u2014 and this runs synchronously\n // before the gtag('event') fires in track(), which is what Google requires.\n // Bypasses the identity dedup on purpose: gtag('set') is idempotent and the\n // address may not have been known at identify() time.\n const server = serverHashes ?? _serverHashes;\n if (pixels?.gtm?.some((px) => px.enabled)) applyGoogleIdentity(win, ud ?? {}, server && (server.google ?? {}));\n return applyIdentity(\n {\n email: ud?.email_address,\n phone: ud?.phone_number,\n externalId: ga4?.user_id,\n },\n serverHashes,\n );\n };\n\n const track = (\n eventName: StandardPixelEvent,\n parameters: Record<string, unknown> = {},\n options: TrackOptions = {},\n ): void => {\n if (!pixels || !pixelsInitialized) return;\n if (!shouldTrackEvent(eventName, parameters, options.eventId, options.providers)) return;\n\n try {\n // Apply advanced matching before firing so Snap/TikTok carry the match\n // keys on this event. Other providers fire immediately (unaffected).\n const identityReady = applyIdentityFromParams(parameters);\n const trace = eventName === 'Purchase' ? options.purchaseTrace : undefined;\n const server = serverIdentityHashesOf(parameters) ?? _serverHashes;\n const handed = (provider: PixelProviderKey) => {\n if (trace) reportPurchaseHanded(trace, provider, options.eventId, server, PIXEL_SCRIPTS_OF[provider]?.() ?? []);\n };\n\n const events = resolvePixelEvents(pixels, eventName, parameters).filter(\n ({ provider }) => !options.providers || options.providers.includes(provider),\n );\n // Deduplicate by provider: the Snapchat/Pinterest SDKs broadcast to all\n // registered pixel IDs internally, so we only need to fire once per\n // provider. GTM, TikTok and Meta need per-pixel firing (GTM for Google Ads\n // send_to targeting, TikTok because ttq.instance() targets a specific\n // pixel, Meta because fbq('trackSingle') does \u2014 relying on Meta's\n // broadcast instead leaked our events onto pixels a pasted script had\n // initialised).\n const firedProviders = new Set<string>();\n // Per-pixel providers still need per-pixel dedup: a merchant field of\n // \"123;123\" expands into two entries with the same id (splitPixelConfig),\n // which would otherwise fire the same event twice at the same pixel.\n const firedPixels = new Set<string>();\n for (const { provider, mapped, pixel } of events) {\n // Gate Snap/TikTok on identity application (when present) so the match\n // keys are set first; a few ms of deferral, only for those providers.\n const emit =\n identityReady && (provider === 'snapchat' || provider === 'tiktok')\n ? (fn: () => void) => { identityReady.then(fn); }\n : (fn: () => void) => { fn(); };\n\n if (provider === 'gtm' || provider === 'tiktok' || provider === 'facebook') {\n const pixelKey = `${provider}:${pixelIdOf(pixel) ?? ''}`;\n if (firedPixels.has(pixelKey)) continue;\n firedPixels.add(pixelKey);\n emit(() => { fire(provider, mapped.name, mapped.params, pixel, options); handed(provider); });\n } else if (provider === 'applovin') {\n if (applovinStoodDown || firedProviders.has(provider)) continue;\n firedProviders.add(provider);\n const params = _applovinUserData\n ? {\n ...mapped.params,\n user_data: { ..._applovinUserData, ...(mapped.params.user_data as ApplovinUserData | undefined) },\n }\n : mapped.params;\n const transactionId =\n mapped.name === 'purchase' && typeof params.transaction_id === 'string' ? params.transaction_id : '';\n if (transactionId && (applovinPurchasesOnPage.has(transactionId) || wasApplovinPurchaseSent(transactionId))) continue;\n fire(provider, mapped.name, params, undefined, options);\n handed(provider);\n if (transactionId) {\n applovinPurchasesOnPage.add(transactionId);\n rememberApplovinPurchaseWhenReceived(transactionId);\n }\n } else {\n if (!firedProviders.has(provider)) {\n emit(() => { fire(provider, mapped.name, mapped.params, undefined, options); handed(provider); });\n firedProviders.add(provider);\n }\n }\n }\n } catch (error) {\n console.error('[SDK Pixels] Tracking error:', error);\n }\n };\n\n // Auto page-view: fire once after init resolves.\n if (opts?.autoPageView !== false) initPromise.then(() => {\n if (typeof window === 'undefined') return;\n track('PageView', { path: window.location.pathname });\n });\n\n return {\n initPromise,\n get pixelsInitialized() { return pixelsInitialized; },\n track,\n identify: (identity: PixelRawIdentity) => { applyIdentity(identity); },\n };\n}\n\n// ---------------------------------------------------------------------------\n// Window bootstrap\n// ---------------------------------------------------------------------------\n\ndeclare global {\n interface Window {\n __TGD_PIXEL_TRACKER__?: PixelTracker;\n __TGD_STEP_CONFIG__?: string | Record<string, unknown>;\n }\n}\n\nfunction readPixelsFromStepConfig(): PixelsConfig | undefined {\n if (typeof window === 'undefined') return undefined;\n const raw = window.__TGD_STEP_CONFIG__;\n if (!raw) return undefined;\n try {\n const parsed = typeof raw === 'string' ? JSON.parse(raw) : raw;\n const pixels = (parsed as { pixels?: PixelsConfig })?.pixels;\n return pixels && typeof pixels === 'object' ? pixels : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * One-shot bootstrap: reads `window.__TGD_STEP_CONFIG__.pixels`, creates a\n * tracker, kicks off init, and stashes it on `window.__TGD_PIXEL_TRACKER__`.\n *\n * Idempotent \u2014 both the islands SDK and the full-SPA runtime may call this,\n * but only the first call creates a tracker. Returns the active tracker\n * (existing or newly created), or null if there's no window or no pixels.\n */\nexport function bootstrapPixelTrackerFromWindow(): PixelTracker | null {\n if (typeof window === 'undefined') return null;\n if (window.__TGD_PIXEL_TRACKER__) return window.__TGD_PIXEL_TRACKER__;\n\n const pixels = readPixelsFromStepConfig();\n if (!pixels) return null;\n\n const tracker = createPixelTracker(pixels);\n window.__TGD_PIXEL_TRACKER__ = tracker;\n return tracker;\n}\n", "/**\n * The browser pixel engine.\n *\n * It wraps the lifted `createPixelTracker` with three things the hosted runtime\n * does not need: it stays inert until `init()`, it gates every fire on the\n * per-step configuration served by the SDK config route, and it reports what it\n * could not do (a pixel already on the page, a pixel blocked by the CSP).\n */\nimport type { PixelRawIdentity } from './pixelIdentity.js';\nimport { pixelIdKeyOf } from './pixelMapping.js';\nimport type { PixelProviderKey, StandardPixelEvent } from './pixelMapping.js';\nimport { createPixelTracker, isSafePixelId } from './pixelTracker.js';\nimport type { PixelTracker } from './pixelTracker.js';\nimport type { PixelConfig, PixelsConfig } from './types.js';\n\nexport type PixelSignalKind = 'pixel_blocked' | 'pixel_duplicate';\nexport interface PixelSignal { kind: PixelSignalKind; provider: PixelProviderKey; detail: Record<string, string> }\nexport type SdkPixelProvider = 'facebook' | 'tiktok' | 'snapchat' | 'gtm' | 'clarity' | 'applovin';\nexport const SDK_PIXEL_PROVIDERS: readonly SdkPixelProvider[] = ['facebook', 'tiktok', 'snapchat', 'gtm', 'clarity', 'applovin'];\n\nexport interface PixelEngineConfig {\n pixels: PixelsConfig;\n /** Keyed by the MANIFEST step id (`sdk_steps.key`, e.g. `paywall`) \u2014 the id the merchant passes to\n `track.step()` \u2014 never the `sdkstep_\u2026` node id. R4 re-keys onto it server-side (contract \u00A76). */\n steps?: Record<string, { type?: string; events: Record<string, PixelProviderKey[]> }>;\n checkout?: { InitiateCheckout?: PixelProviderKey[]; Purchase?: PixelProviderKey[] };\n requireConsent?: boolean;\n onSignal?: (signal: PixelSignal) => void;\n}\n\nexport interface PixelEngine {\n init(): Promise<void>;\n pageView(path: string, options?: { stepId?: string }): void;\n track(event: StandardPixelEvent, data?: Record<string, unknown>, options?: { eventId?: string; stepId?: string }): void;\n trackCustom(name: string, data?: Record<string, unknown>, options?: { stepId?: string }): void;\n identify(identity: PixelRawIdentity): void;\n consent(state: { marketing: boolean }): void;\n destroy(): void;\n}\n\n/** The origins each provider's loader fetches its scripts from; the drift test pins them. */\nexport const SCRIPT_ORIGINS: Record<SdkPixelProvider, readonly string[]> = {\n facebook: ['https://connect.facebook.net'], tiktok: ['https://analytics.tiktok.com'],\n snapchat: ['https://sc-static.net'], gtm: ['https://www.googletagmanager.com'],\n clarity: ['https://www.clarity.ms'], applovin: ['https://s.axon.ai', 'https://res4.applovin.com'],\n};\n\n/** The global a provider's own script installs; its presence means a second tag is on the page. */\nconst PROVIDER_GLOBALS: Record<SdkPixelProvider, string> = {\n facebook: 'fbq', tiktok: 'ttq', snapchat: 'snaptr', gtm: 'dataLayer', clarity: 'clarity', applovin: 'axon',\n};\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype VendorWindow = Record<string, any>;\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nconst QUEUE_LIMIT = 50;\n/** Same window as the SDK's own step dedup: React StrictMode double-renders, nothing more. */\nconst PAGE_VIEW_DEDUP_MS = 1000;\n\nfunction isSdkProvider(provider: string): provider is SdkPixelProvider {\n return (SDK_PIXEL_PROVIDERS as readonly string[]).includes(provider);\n}\n\n/** The SDK providers and nothing else, copied key by key: a spread would carry `pinterest` through. */\nfunction filterPixels(pixels: PixelsConfig): PixelsConfig {\n const out: PixelsConfig = {};\n if (pixels.facebook) out.facebook = pixels.facebook;\n if (pixels.tiktok) out.tiktok = pixels.tiktok;\n if (pixels.snapchat) out.snapchat = pixels.snapchat;\n if (pixels.gtm) out.gtm = pixels.gtm;\n if (pixels.clarity) out.clarity = pixels.clarity;\n if (pixels.applovin) out.applovin = pixels.applovin;\n return out;\n}\n\nfunction entriesOf(pixels: PixelsConfig, provider: SdkPixelProvider): PixelConfig[] {\n const list = (pixels as Record<string, PixelConfig[] | undefined>)[provider];\n return Array.isArray(list) ? list : [];\n}\n\nfunction usableIdOf(pixel: PixelConfig): string | null {\n const value = (pixel as unknown as Record<string, unknown>)[pixelIdKeyOf(pixel)];\n return isSafePixelId(value) ? value.trim() : null;\n}\n\nexport function createPixelEngine(config: PixelEngineConfig): PixelEngine {\n const pixels = filterPixels(config.pixels);\n const trackers = new Map<SdkPixelProvider, PixelTracker>();\n /** `stepId|path` \u2192 when it last fired. A window, not a page-lifetime latch: an SPA that comes\n back to a step later in the session must count as a second page view. */\n const seen = new Map<string, number>();\n const signalled = new Set<string>();\n const queue: Array<() => void> = [];\n let granted = config.requireConsent !== true;\n let latchedOff = false;\n let started = false;\n let cspHandler: ((event: Event) => void) | null = null;\n\n const signal = (kind: PixelSignalKind, provider: SdkPixelProvider, detail: Record<string, string>): void => {\n const key = `${provider}|${kind}`;\n if (signalled.has(key)) return;\n signalled.add(key);\n try { config.onSignal?.({ kind, provider, detail }); } catch { /* a consumer callback never breaks a page */ }\n };\n\n const configuredProviders = (): SdkPixelProvider[] =>\n SDK_PIXEL_PROVIDERS.filter((provider) => entriesOf(pixels, provider).length > 0);\n\n const gateFor = (event: string, stepId?: string): SdkPixelProvider[] => {\n const raw = event === 'InitiateCheckout' || event === 'Purchase'\n ? config.checkout?.[event] ?? []\n : config.steps?.[stepId ?? '']?.events?.[event] ?? [];\n return raw.filter(isSdkProvider);\n };\n\n const detectDuplicates = (win: VendorWindow): void => {\n for (const provider of configuredProviders()) {\n const host = typeof win.location?.host === 'string' ? win.location.host : '';\n if (provider === 'gtm') {\n const loaded = win.google_tag_manager;\n const clash = entriesOf(pixels, 'gtm').some((px) => {\n const id = usableIdOf(px);\n return id !== null && loaded?.[id] !== undefined;\n });\n if (clash) signal('pixel_duplicate', 'gtm', { origin: host });\n continue;\n }\n if (win[PROVIDER_GLOBALS[provider]] !== undefined) signal('pixel_duplicate', provider, { origin: host });\n }\n };\n\n const watchCsp = (win: VendorWindow): void => {\n cspHandler = (event: Event): void => {\n const violation = event as SecurityPolicyViolationEvent;\n const blocked = typeof violation.blockedURI === 'string' ? violation.blockedURI : '';\n for (const provider of SDK_PIXEL_PROVIDERS) {\n if (!SCRIPT_ORIGINS[provider].some((origin) => blocked.startsWith(origin))) continue;\n signal('pixel_blocked', provider, { reason: 'csp', directive: violation.violatedDirective ?? '' });\n return;\n }\n };\n win.addEventListener('securitypolicyviolation', cspHandler);\n };\n\n const enqueue = (run: () => void): void => {\n if (latchedOff) return;\n if (queue.length >= QUEUE_LIMIT) queue.shift();\n queue.push(run);\n };\n\n const guardEventId = (eventId: string): boolean => {\n try { if (sessionStorage.getItem(`__tgd_px:${eventId}`)) return false; } catch { /* private mode */ }\n return true;\n };\n\n const markEventId = (eventId: string): void => {\n try { sessionStorage.setItem(`__tgd_px:${eventId}`, '1'); } catch { /* private mode */ }\n };\n\n const engine: PixelEngine = {\n async init(): Promise<void> {\n if (started || typeof window === 'undefined') return;\n if (!granted) return;\n started = true;\n const win = window as unknown as VendorWindow;\n detectDuplicates(win);\n watchCsp(win);\n const ready: Promise<void>[] = [];\n for (const provider of configuredProviders()) {\n // One tracker per provider: the lifted tracker fires to every provider of its own\n // config, so a per-provider gate needs a per-provider tracker.\n const tracker = createPixelTracker({ [provider]: entriesOf(pixels, provider) } as PixelsConfig, { autoPageView: false });\n trackers.set(provider, tracker);\n ready.push(tracker.initPromise);\n }\n // `track()` no-ops until `pixelsInitialized` flips, which only happens when these settle.\n await Promise.all(ready);\n },\n\n pageView(path, options): void {\n if (typeof window === 'undefined') return;\n if (!granted) { enqueue(() => engine.pageView(path, options)); return; }\n const key = `${options?.stepId ?? ''}|${path}`;\n const now = Date.now();\n const previous = seen.get(key);\n if (previous !== undefined && now - previous < PAGE_VIEW_DEDUP_MS) return;\n for (const [other, when] of seen) if (now - when >= PAGE_VIEW_DEDUP_MS) seen.delete(other);\n seen.set(key, now);\n const allowed = gateFor('PageView', options?.stepId);\n if (allowed.length === 0) return;\n // A per-step id, and a per-fire one: two steps on one path would otherwise collapse into a\n // single fire inside the tracker's own 5 s duplicate guard, and so would a genuine return\n // to the same step later in the session.\n for (const provider of allowed) trackers.get(provider)?.track('PageView', { path }, { eventId: `PageView_${key}|${now}` });\n },\n\n track(event, data, options): void {\n if (typeof window === 'undefined') return;\n if (!granted) { enqueue(() => engine.track(event, data, options)); return; }\n if (event === 'InitiateCheckout' || event === 'Purchase') {\n if (!options?.eventId) return;\n if (!guardEventId(options.eventId)) return;\n }\n const allowed = gateFor(event, options?.stepId);\n if (allowed.length === 0) return;\n for (const provider of allowed) {\n trackers.get(provider)?.track(event, data ?? {}, options?.eventId ? { eventId: options.eventId } : undefined);\n }\n if (options?.eventId) markEventId(options.eventId);\n },\n\n trackCustom(name, data, options): void {\n if (typeof window === 'undefined') return;\n if (!granted) { enqueue(() => engine.trackCustom(name, data, options)); return; }\n const win = window as unknown as VendorWindow;\n const params = data ?? {};\n for (const provider of gateFor(name, options?.stepId)) {\n for (const px of entriesOf(pixels, provider)) {\n if (!px.enabled) continue;\n const id = usableIdOf(px);\n if (id === null) continue;\n switch (provider) {\n // `trackSingle` with a custom name is read by Meta as an unknown standard event.\n case 'facebook': win.fbq?.('trackSingleCustom', id, name, params); break;\n case 'tiktok': win.ttq?.instance?.(id)?.track?.(name, params); break;\n // Snap offers no per-pixel target: the global broadcasts to every Snap pixel.\n case 'snapchat': win.snaptr?.('track', name, params); break;\n case 'gtm': win.gtag?.('event', name, params); break;\n case 'clarity': win.clarity?.('event', name); break;\n // AppLovin defines no custom events: a name it does not know is dropped on its side.\n case 'applovin': break;\n }\n }\n }\n },\n\n identify(identity): void {\n if (typeof window === 'undefined') return;\n for (const tracker of trackers.values()) tracker.identify(identity);\n },\n\n consent(state): void {\n if (!state.marketing) { queue.length = 0; latchedOff = true; granted = false; return; }\n if (latchedOff || granted) return;\n granted = true;\n void engine.init().then(() => {\n const pending = queue.splice(0, queue.length);\n for (const run of pending) run();\n });\n },\n\n destroy(): void {\n queue.length = 0;\n if (cspHandler && typeof window !== 'undefined') {\n window.removeEventListener('securitypolicyviolation', cspHandler);\n }\n cspHandler = null;\n trackers.clear();\n },\n };\n\n return engine;\n}\n", "/**\n * Stable event_id helper for Meta CAPI / browser pixel deduplication.\n *\n * The browser side (`fbq('track', name, params, { eventID })`) and the server\n * side (`ServerEvent.setEventId(...)`) must publish the same value to let Meta\n * dedup. This helper is the single source of truth for the formula, mirrored\n * on the server in `src/app/services/meta/meta-event-id.ts`. A parity test in\n * the server package keeps them byte-identical.\n *\n * Convention: `${eventName}_${entityId}`. Different event names get different\n * IDs even when fired for the same entity (e.g. a Purchase + Subscribe pair on\n * the same order), so each dedups independently.\n */\nexport function makeMetaEventId(eventName: string, entityId: string): string {\n return `${eventName}_${entityId}`;\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["pixels_exports", "__export", "IDENTITY_HASHES_PARAM_KEY", "SDK_PIXEL_PROVIDERS", "bootstrapPixelTrackerFromWindow", "buildGa4PurchasePayload", "createPixelEngine", "createPixelTracker", "getEligiblePixels", "isEventEnabled", "isSafePixelId", "makeMetaEventId", "pixelIdKeyOf", "resolvePixelEvents", "SHA256_HEX_PATTERN", "isSha256Hex", "value", "MASKED_VALUE_PATTERN", "isMaskedValue", "withoutMaskedValues", "id", "out", "normalizeEmail", "email", "normalizePhone", "phone", "trimmed", "hasPlus", "digits", "sha256Hex", "input", "data", "buf", "b", "canHashIdentity", "buildHashedIdentity", "n", "pixelIdKeyOf", "pixel", "GA4_PARAM_KEY", "IDENTITY_HASHES_PARAM_KEY", "hasSha256Pair", "pair", "email", "phone", "isSha256Hex", "serverIdentityHashesOf", "parameters", "hashes", "withGoogleServerHashes", "ud", "_email", "_phone", "rest", "out", "withoutMaskedUserData", "email_address", "phone_number", "isMaskedValue", "extractCouponCodes", "order", "codes", "p", "_a", "c", "buildGa4PurchasePayload", "_b", "_c", "_d", "_e", "_f", "_g", "sourceItems", "coupon", "summary", "s", "itemsSum", "sum", "i", "lineLevelDiscountTotal", "orderLevelDiscount", "remainingAllocation", "items", "item", "index", "quantity", "unitAdjusted", "lineValue", "lineAllocation", "unitAllocation", "unitDiscount", "ga4Item", "value", "payload", "addr", "userData", "address", "v", "ZERO_DECIMAL_CURRENCIES", "THREE_DECIMAL_CURRENCIES", "minorToMajor", "amount", "currency", "code", "isEventEnabled", "eventName", "events", "getEligiblePixels", "pixels", "ensureCurrencyUppercase", "params", "convertValueToMajor", "major", "convertMonetaryFieldsToMajor", "result", "field", "convertContentsPricesToMajor", "itemCurrency", "converted", "baseTransform", "META_EVENT_MAP", "mapMetaEvent", "name", "TIKTOK_EVENT_MAP", "mapTikTokEvent", "ids", "SNAPCHAT_EVENT_MAP", "mapSnapchatEvent", "PINTEREST_EVENT_MAP", "mapPinterestEvent", "GTM_EVENT_MAP", "mapGTMEvent", "ga4", "toMajor", "ecommerce", "serverHashes", "CLARITY_EVENT_MAP", "mapClarityEvent", "APPLOVIN_EVENT_MAP", "APPLOVIN_MIN_USER_ID_LENGTH", "APPLOVIN_IMAGE_PATTERN", "toApplovinUserData", "identity", "rawPhone", "userId", "toApplovinServerUserData", "externalId", "activeApplovinPixel", "finiteNumber", "roundMoney", "splitContentId", "contentId", "productIds", "productId", "id", "longest", "variantId", "dash", "product", "variant", "applovinImageUrl", "path", "applovinItems", "contents", "entry", "rawId", "itemId", "price", "imageUrl", "mapApplovinEvent", "n", "shipping", "tax", "googleAdsTag", "text", "applyGoogleAdsConversion", "resolvePixelEvents", "results", "fb", "mapped", "tt", "sc", "pt", "clarity", "applovin", "gtm", "finalParams", "TRACED_PROVIDERS", "IDENTITY_HASHES_OF", "COLLECT_PATH", "PIXELS_SDK_VERSION", "NIL_SESSION_ID", "PURCHASES_HANDED_KEY", "PURCHASE_HANDED_MEMORY_MS", "PURCHASE_HANDED_MEMORY_SIZE", "purchasesHandedOnPage", "scriptStateOf", "scripts", "states", "script", "identityOriginOf", "provider", "server", "platform", "pair", "isSha256Hex", "uuidV7", "now", "cryptoApi", "bytes", "time", "i", "hex", "byte", "claimPurchaseHanded", "key", "storage", "parsed", "handed", "record", "id", "at", "memory", "b", "sendPurchaseHanded", "trace", "props", "_a", "batchId", "eventId", "body", "reportPurchaseHanded", "traced", "createDuplicateGuard", "windowMs", "lastEvents", "eventName", "parameters", "eventId", "providers", "key", "now", "last", "pixelIdOf", "pixel", "value", "pixelIdKeyOf", "fire", "provider", "name", "params", "options", "_a", "_b", "_c", "_d", "_e", "_f", "_g", "_h", "_i", "_j", "_k", "_l", "w", "pixelId", "target", "fireGTM", "dedupeId", "applySnapchatIdentity", "h", "userInfo", "applyTikTokIdentity", "info", "applyMetaIdentity", "raw", "ud", "d", "applyMetaServerIdentity", "hashes", "externalId", "isSha256Hex", "applyGoogleIdentity", "input", "serverHashes", "withoutMaskedUserData", "userData", "withGoogleServerHashes", "phone", "a", "address", "event", "hasEcommerce", "ecommerce", "rest", "error", "win", "SCRIPT_LOAD_TIMEOUT_MS", "waitForScriptLoad", "script", "resolve", "settle", "state", "timer", "_metaScriptEl", "initMetaPixel", "autoTracking", "n", "args", "t", "s", "_tiktokBaseInitialized", "_tiktokScriptEls", "initTikTokPixel", "ttq", "e", "method", "r", "p", "scripts", "lastScript", "_snapchatScriptEl", "initSnapchatPixel", "u", "_pinterestScriptEl", "initPinterestPixel", "initClarity", "projectId", "q", "first", "hasForeignApplovin", "_applovinScriptEl", "initApplovin", "eventKey", "src", "isApplovinLoaded", "rememberApplovinPurchaseWhenReceived", "transactionId", "markApplovinPurchaseSent", "APPLOVIN_PURCHASES_KEY", "applovinPurchasesOnPage", "APPLOVIN_PURCHASE_MEMORY_MS", "APPLOVIN_PURCHASE_MEMORY_SIZE", "readApplovinPurchases", "memory", "parsed", "record", "id", "sentAt", "wasApplovinPurchaseSent", "sent", "b", "_gtagScriptEls", "initGTM", "containerId", "isGtmContainer", "scriptUrlPart", "ref", "f", "j", "noscript", "iframe", "_args", "linkerConfig", "firstScript", "PIXEL_SCRIPTS_OF", "MAX_PIXEL_ID_LENGTH", "SAFE_PIXEL_ID_PATTERN", "isSafePixelId", "sanitizePixels", "pixels", "out", "dropped", "list", "kept", "px", "PAINT_FALLBACK_MS", "afterFirstPaint", "settled", "finish", "fallback", "raf", "createPixelTracker", "rawPixels", "opts", "shouldTrackEvent", "pixelsInitialized", "applovinStoodDown", "initPromise", "loadPromises", "applovin", "activeApplovinPixel", "_identityKey", "_identityReady", "_applovinUserData", "_serverHashes", "_serverExternalId", "applyServerIdentity", "server", "toApplovinServerUserData", "snap", "hashedExternalId", "canHashIdentity", "buildHashedIdentity", "tiktok", "applyIdentity", "identity", "withoutMaskedValues", "applovinUserData", "toApplovinUserData", "hashed", "applyIdentityFromParams", "ga4", "GA4_PARAM_KEY", "serverIdentityHashesOf", "track", "identityReady", "trace", "handed", "reportPurchaseHanded", "events", "resolvePixelEvents", "firedProviders", "firedPixels", "mapped", "emit", "fn", "pixelKey", "readPixelsFromStepConfig", "bootstrapPixelTrackerFromWindow", "tracker", "SDK_PIXEL_PROVIDERS", "SCRIPT_ORIGINS", "PROVIDER_GLOBALS", "QUEUE_LIMIT", "PAGE_VIEW_DEDUP_MS", "isSdkProvider", "provider", "filterPixels", "pixels", "out", "entriesOf", "list", "usableIdOf", "pixel", "value", "pixelIdKeyOf", "isSafePixelId", "createPixelEngine", "config", "trackers", "seen", "signalled", "queue", "granted", "latchedOff", "started", "cspHandler", "signal", "kind", "detail", "_a", "key", "configuredProviders", "gateFor", "event", "stepId", "_b", "_c", "_d", "detectDuplicates", "win", "host", "loaded", "px", "id", "watchCsp", "violation", "blocked", "origin", "enqueue", "run", "guardEventId", "eventId", "markEventId", "engine", "ready", "tracker", "createPixelTracker", "path", "options", "now", "previous", "other", "when", "allowed", "data", "name", "_e", "_f", "_g", "_h", "params", "identity", "state", "pending", "makeMetaEventId", "eventName", "entityId"]
|
|
7
7
|
}
|