@elevateab/sdk 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/storage.ts","../src/utils.ts","../src/utils/assignment.ts","../src/mutations/cartAttributes.mutation.ts","../src/utils/cartAttributes.ts"],"sourcesContent":["/**\n * Cookie and Session Storage utilities\n */\n\n/**\n * Generate a UUID v4\n */\nexport function uuidv4(): string {\n try {\n if (\n typeof window !== \"undefined\" &&\n window.crypto &&\n window.crypto.getRandomValues\n ) {\n const rnds = new Uint8Array(16);\n window.crypto.getRandomValues(rnds);\n rnds[6] = (rnds[6] & 0x0f) | 0x40; // Version 4\n rnds[8] = (rnds[8] & 0x3f) | 0x80; // Variant 1\n\n const hexValues = Array.from(rnds).map((b) =>\n b.toString(16).padStart(2, \"0\")\n );\n\n return [\n hexValues.slice(0, 4).join(\"\"),\n hexValues.slice(4, 6).join(\"\"),\n hexValues.slice(6, 8).join(\"\"),\n hexValues.slice(8, 10).join(\"\"),\n hexValues.slice(10, 16).join(\"\"),\n ].join(\"-\");\n }\n } catch (e) {\n console.warn(\n \"[ElevateAB] Crypto UUID generation failed, falling back to Math.random()\",\n e\n );\n }\n\n // Fallback to Math.random\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n/**\n * Set a cookie with 1 year expiration\n */\nexport function setCookie(name: string, value: string): void {\n if (typeof document === \"undefined\") return;\n\n const date = new Date();\n date.setTime(date.getTime() + 365 * 24 * 60 * 60 * 1000);\n const expires = \"; expires=\" + date.toUTCString();\n document.cookie = name + \"=\" + (value || \"\") + expires + \"; path=/\";\n}\n\n/**\n * Get a cookie value by name\n */\nexport function getCookie(name: string): string | null {\n if (typeof document === \"undefined\") return null;\n\n const nameEQ = name + \"=\";\n const ca = document.cookie.split(\";\");\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === \" \") c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n}\n\n/**\n * Get a JSON-parsed cookie value\n */\nexport function getJsonCookie<T = Record<string, unknown>>(\n name: string\n): T | null {\n const cookieValue = getCookie(name);\n if (cookieValue) {\n try {\n return JSON.parse(cookieValue) as T;\n } catch (error) {\n console.error(\"[ElevateAB] Error parsing JSON from cookie\", error);\n return null;\n }\n }\n return null;\n}\n\n/**\n * Delete a cookie\n */\nexport function deleteCookie(cookieName: string): void {\n if (typeof document === \"undefined\") return;\n\n document.cookie =\n cookieName + \"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;\";\n}\n\n/**\n * Set a session storage item\n */\nexport function setSessionItem(name: string, value: unknown): void {\n if (typeof sessionStorage === \"undefined\") return;\n\n sessionStorage.setItem(name, JSON.stringify(value));\n}\n\n/**\n * Get a session storage item\n */\nexport function getSessionItem(name: string): string | null {\n if (typeof sessionStorage === \"undefined\") return null;\n\n return sessionStorage.getItem(name);\n}\n\n/**\n * Get a JSON-parsed session storage item\n */\nexport function getJsonSessionItem<T = unknown>(name: string): T | null {\n const item = getSessionItem(name);\n return item ? (JSON.parse(item) as T) : null;\n}\n\n/**\n * Initialize visitor ID - creates eabUserId cookie if it doesn't exist\n */\nexport function initializeVisitorId(): string {\n let visitorId = getCookie(\"eabUserId\");\n\n if (!visitorId) {\n visitorId = uuidv4();\n setCookie(\"eabUserId\", visitorId);\n }\n\n return visitorId;\n}\n\n/**\n * Get or create visitor ID\n */\nexport function getVisitorId(): string {\n return initializeVisitorId();\n}\n\n/**\n * Initialize session ID - creates eabSessionId in sessionStorage if it doesn't exist\n */\nexport function initializeSessionId(): string {\n let sessionId = getSessionItem(\"eabSessionId\");\n\n if (!sessionId) {\n sessionId = uuidv4();\n setSessionItem(\"eabSessionId\", sessionId);\n }\n\n return sessionId;\n}\n\n/**\n * Get or create session ID\n */\nexport function getSessionId(): string {\n return initializeSessionId();\n}\n\n/**\n * Store referrer and entry page data in sessionStorage\n */\nexport function setReferrerData(referrer: string, entryPage: string): void {\n if (typeof sessionStorage === \"undefined\") return;\n\n // Only set if not already set (preserve first referrer/entry)\n const existingReferrer = getSessionItem(\"eabReferrer\");\n const existingEntry = getSessionItem(\"eabEntry\");\n\n if (!existingReferrer) {\n setSessionItem(\"eabReferrer\", referrer);\n }\n if (!existingEntry) {\n setSessionItem(\"eabEntry\", entryPage);\n }\n}\n\n/**\n * Get referrer data from sessionStorage\n */\nexport function getReferrerData(): { referrer: string; entryPage: string } {\n return {\n referrer: getSessionItem(\"eabReferrer\") || \"\",\n entryPage: getSessionItem(\"eabEntry\") || \"\",\n };\n}\n","import type { Variation, Test, BackendConfig, ElevateConfig } from \"./types\";\n\n/**\n * Assigns a variant based on weighted distribution\n */\nexport function assignVariant(\n variations: Variation[],\n userId: string\n): Variation {\n const totalWeight = variations.reduce((sum, v) => sum + v.weight, 0);\n const hash = hashString(userId);\n const normalized = hash % totalWeight;\n\n let cumulative = 0;\n for (const variation of variations) {\n cumulative += variation.weight;\n if (normalized < cumulative) {\n return variation;\n }\n }\n\n return variations[0];\n}\n\nexport function hashString(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return Math.abs(hash);\n}\n\nexport function validateConfig(config: Test): boolean {\n if (!config.testId || !config.name) return false;\n if (!config.variations || config.variations.length === 0) return false;\n\n const totalWeight = config.variations.reduce((sum, v) => sum + v.weight, 0);\n return totalWeight === 100;\n}\n\nexport function generateExperimentId(name: string): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 9);\n const safeName = name.toLowerCase().replace(/[^a-z0-9]/g, \"-\");\n return `exp-${safeName}-${timestamp}-${random}`;\n}\n\nexport function calculateRevenueLift(\n controlRevenue: number,\n variantRevenue: number,\n controlSampleSize: number,\n variantSampleSize: number\n): { lift: number; confidence: number } {\n const controlMean = controlRevenue / controlSampleSize;\n const variantMean = variantRevenue / variantSampleSize;\n\n const lift = ((variantMean - controlMean) / controlMean) * 100;\n\n const pooledStdDev = Math.sqrt(\n (controlRevenue + variantRevenue) / (controlSampleSize + variantSampleSize)\n );\n const standardError =\n pooledStdDev * Math.sqrt(1 / controlSampleSize + 1 / variantSampleSize);\n const zScore = Math.abs(variantMean - controlMean) / standardError;\n const confidence = Math.min(99.9, zScore * 34);\n\n return { lift, confidence };\n}\n\n/**\n * Parse backend config format to SDK normalized format\n */\nexport function parseBackendConfig(backendData: BackendConfig): ElevateConfig {\n const tests: Test[] = [];\n\n for (const [testId, testData] of Object.entries(backendData.allTests)) {\n // Skip if not live\n if (!testData.data.isLive) continue;\n\n // Extract variations (all keys except 'data')\n const variations: Variation[] = [];\n let nonControlIndex = 0; // Count only non-control variations for isA/isB/isC/isD\n for (const [key, value] of Object.entries(testData)) {\n if (key === \"data\") continue;\n\n const variation = value as BackendConfig[\"allTests\"][string][string];\n if (\n typeof variation === \"object\" &&\n variation !== null &&\n \"variationName\" in variation\n ) {\n const isControl = !!variation.isControl;\n variations.push({\n id: key,\n name: variation.variationName,\n weight: variation.trafficPercentage,\n isControl,\n productId: variation.id,\n handle: variation.handle,\n price: variation.price,\n // Set convenience flags: isA = first non-control, isB = second, etc.\n isA: !isControl && nonControlIndex === 0,\n isB: !isControl && nonControlIndex === 1,\n isC: !isControl && nonControlIndex === 2,\n isD: !isControl && nonControlIndex === 3,\n });\n if (!isControl) nonControlIndex++;\n }\n }\n\n // Only include tests with variations\n if (variations.length > 0) {\n tests.push({\n testId,\n name: testData.data.name,\n enabled: testData.data.isLive,\n type: testData.data.type,\n variations,\n });\n }\n }\n\n return {\n tests,\n selectors: backendData.selectors,\n };\n}\n","/**\n * Variant assignment logic\n */\n\nimport type { Test, Variation } from \"../types\";\nimport { getCookie, setCookie, getJsonCookie } from \"./storage\";\nimport { hashString } from \"../utils\";\n\nexport interface TestList {\n [testId: string]: string; // testId -> variantId\n}\n\n/**\n * Get the test list from ABTL cookie\n */\nexport function getTestList(): TestList {\n return getJsonCookie<TestList>(\"ABTL\") || {};\n}\n\n/**\n * Save test list to ABTL cookie\n */\nexport function saveTestList(testList: TestList): void {\n setCookie(\"ABTL\", JSON.stringify(testList));\n}\n\n/**\n * Get assigned variant for a test from ABTL cookie\n */\nexport function getAssignedVariant(testId: string): string | null {\n const testList = getTestList();\n return testList[testId] || null;\n}\n\n/**\n * Get the non-control index for a variation (for isA, isB, isC, isD flags)\n * Control gets -1, first non-control gets 0 (isA), second gets 1 (isB), etc.\n */\nfunction getNonControlIndex(variations: Variation[], targetIndex: number): number {\n const variation = variations[targetIndex];\n if (variation?.isControl) return -1; // Control doesn't get isA/isB/etc\n \n // Count how many non-control variations come before this one\n let nonControlIndex = 0;\n for (let i = 0; i < targetIndex; i++) {\n if (!variations[i]?.isControl) {\n nonControlIndex++;\n }\n }\n return nonControlIndex;\n}\n\n/**\n * Assign a variant to a user based on userId and variations\n */\nexport function assignVariantForUser(\n variations: Variation[],\n userId: string\n): Variation {\n // Check if all variations have trafficPercentage\n const allHaveTrafficPercentage = variations.every(\n (v) => typeof v.weight === \"number\"\n );\n\n let cumulativeWeights: number[] = [];\n let totalWeight = 0;\n\n if (allHaveTrafficPercentage) {\n // Use traffic percentages\n for (const variation of variations) {\n totalWeight += variation.weight;\n cumulativeWeights.push(totalWeight);\n }\n } else {\n // Split evenly\n const defaultWeight = 100 / variations.length;\n for (let i = 0; i < variations.length; i++) {\n totalWeight += defaultWeight;\n cumulativeWeights.push(totalWeight);\n }\n }\n\n // Generate hash from userId\n const hash = hashString(userId);\n const randomWeight = (hash % 10000) / 100; // 0-100 range\n\n // Find which variation to assign\n let assignedIndex = 0;\n for (let i = 0; i < cumulativeWeights.length; i++) {\n if (randomWeight < cumulativeWeights[i]) {\n assignedIndex = i;\n break;\n }\n }\n\n const assignedVariation = variations[assignedIndex] || variations[0];\n const nonControlIndex = getNonControlIndex(variations, assignedIndex);\n\n // Set convenience flags: isA = first non-control, isB = second non-control, etc.\n return {\n ...assignedVariation,\n isA: nonControlIndex === 0,\n isB: nonControlIndex === 1,\n isC: nonControlIndex === 2,\n isD: nonControlIndex === 3,\n };\n}\n\n/**\n * Assign and persist variant for a test\n */\nexport function assignAndPersistVariant(\n testId: string,\n test: Test,\n userId: string\n): Variation | null {\n // Check if already assigned (from cookie)\n const existingVariantId = getAssignedVariant(testId);\n if (existingVariantId) {\n const variantIndex = test.variations.findIndex(\n (v) => v.id === existingVariantId\n );\n if (variantIndex !== -1) {\n const existingVariant = test.variations[variantIndex];\n const nonControlIndex = getNonControlIndex(test.variations, variantIndex);\n // Set convenience flags: isA = first non-control, isB = second, etc.\n return {\n ...existingVariant,\n isA: nonControlIndex === 0,\n isB: nonControlIndex === 1,\n isC: nonControlIndex === 2,\n isD: nonControlIndex === 3,\n };\n }\n }\n\n // Filter out completed/done variations (keep all active ones)\n const activeVariations = test.variations.filter((v) => {\n // Check if variation has isDone flag (from backend)\n const isDone = (v as any).isDone;\n return !isDone;\n });\n\n if (activeVariations.length === 0) {\n return null;\n }\n\n // Check if it's a personalization (always assign to non-control)\n const isPersonalization = (test as any).isPersonalization;\n let assignedVariant: Variation;\n\n if (isPersonalization) {\n // Find the non-control variation\n const personalizedVariation = activeVariations.find((v) => !v.isControl);\n assignedVariant = personalizedVariation || activeVariations[0];\n } else {\n // Regular A/B test - use weighted assignment\n assignedVariant = assignVariantForUser(activeVariations, userId);\n }\n\n // Persist to ABTL cookie\n const testList = getTestList();\n testList[testId] = assignedVariant.id;\n saveTestList(testList);\n\n return assignedVariant;\n}\n\n/**\n * Check if test should be shown based on traffic percentage\n */\nexport function shouldShowTest(test: Test): boolean {\n const testTrafficPercentage = (test as any).testTrafficPercentage;\n\n if (typeof testTrafficPercentage !== \"number\") {\n return true; // No traffic limiting\n }\n\n // Check if user is already in this test\n const existingVariantId = getAssignedVariant(test.testId);\n if (existingVariantId) {\n return true; // Already assigned, always show\n }\n\n // Random check against traffic percentage\n const random = Math.random() * 100;\n return random < testTrafficPercentage;\n}\n","/**\n * GraphQL mutations for cart attributes\n */\n\n/**\n * GraphQL mutation for updating cart attributes\n * Use this in your Storefront API calls\n */\nexport const CART_ATTRIBUTES_UPDATE_MUTATION = `#graphql\n mutation cartAttributesUpdate($cartId: ID!, $attributes: [AttributeInput!]!) {\n cartAttributesUpdate(cartId: $cartId, attributes: $attributes) {\n cart {\n id\n attributes {\n key\n value\n }\n }\n userErrors {\n field\n message\n }\n }\n }\n`;\n","/**\n * Cart attribute utilities for tagging carts with A/B test data\n *\n * These functions update Shopify cart attributes with test assignment data,\n * enabling order attribution for A/B test analysis.\n */\n\nimport { getTestList } from \"./assignment\";\nimport { getCookie, getJsonCookie } from \"./storage\";\nimport { CART_ATTRIBUTES_UPDATE_MUTATION } from \"../mutations/cartAttributes.mutation\";\nimport type { CartAttributesOptions, CartAttributeInput } from \"../types\";\n\n// Re-export types for backwards compatibility\nexport type { CartAttributesOptions, CartAttributeInput } from \"../types\";\n\n/**\n * Get cart attributes payload from current test assignments\n * Returns an array of key-value pairs ready to be sent to Shopify\n *\n * @example\n * ```ts\n * const attributes = getCartAttributesPayload();\n * // Use with your own Storefront client\n * await storefront.mutate(CART_ATTRIBUTES_UPDATE_MUTATION, {\n * variables: { cartId, attributes }\n * });\n * ```\n */\nexport function getCartAttributesPayload(): CartAttributeInput[] {\n const testList = getTestList(); // ABTL - all assignments\n const addedUniqueViews = getJsonCookie<Record<string, boolean>>(\"ABAU\") || {};\n const eabUserId = getCookie(\"eabUserId\");\n const isPreviewMode = getCookie(\"eabUserPreview\") === \"true\";\n const abtidValue = getCookie(\"abtid\");\n\n // Filter viewed tests - only include tests that have been viewed\n const viewedTests: Record<string, string> = {};\n for (const testId in testList) {\n if (addedUniqueViews[testId]) {\n viewedTests[testId] = testList[testId];\n }\n }\n\n const attributes: CartAttributeInput[] = [\n {\n key: \"_eabTestsList\",\n value: JSON.stringify(viewedTests),\n },\n {\n key: \"_eabUserId\",\n value: eabUserId || \"\",\n },\n {\n key: \"_eabList\",\n value: JSON.stringify(testList),\n },\n ];\n\n // Add preview test if in preview mode\n if (isPreviewMode && abtidValue) {\n attributes.push({\n key: \"_eabPreviewTest\",\n value: abtidValue,\n });\n }\n\n return attributes;\n}\n\n/**\n * Update cart attributes with test assignment data\n *\n * This function calls the Shopify Storefront API to update cart attributes.\n *\n * ## Authentication\n *\n * **For Hydrogen stores:** Use your storefront client directly with `getCartAttributesPayload()`\n *\n * **For Next.js/Other stores:** Pass the `storefrontAccessToken` option.\n *\n * ✅ The Storefront Access Token is **safe to use client-side**.\n * It's a public token designed by Shopify for browser use.\n * It can only read products and manage carts - it CANNOT delete products,\n * access admin functions, or do anything destructive.\n *\n * Get your token from: Shopify Admin → Settings → Apps → Develop apps\n *\n * @param cartId - The cart ID (GID or token, e.g., \"gid://shopify/Cart/abc123\" or just \"abc123\")\n * @param options - Configuration options including storefrontAccessToken\n * @returns Promise with success status and optional error message\n *\n * @example\n * ```ts\n * // Next.js usage - token is safe to use client-side!\n * const result = await updateCartAttributes(cartId, {\n * storefrontAccessToken: process.env.NEXT_PUBLIC_STOREFRONT_TOKEN\n * });\n *\n * if (!result.success) {\n * console.error('Failed to update cart attributes:', result.error);\n * }\n * ```\n */\nexport async function updateCartAttributes(\n cartId: string,\n options: CartAttributesOptions = {}\n): Promise<{ success: boolean; error?: string }> {\n if (typeof window === \"undefined\") {\n return { success: false, error: \"Not in browser environment\" };\n }\n\n // Validate token is provided for direct API calls\n if (!options.storefrontAccessToken && !options.storefrontApiUrl) {\n console.warn(\n \"[ElevateAB] Missing storefrontAccessToken. \" +\n \"For Next.js/non-Hydrogen stores, you must provide a Storefront Access Token. \" +\n \"This token is SAFE to use client-side - it's a public token with limited permissions. \" +\n \"Get it from: Shopify Admin → Settings → Apps → Develop apps\"\n );\n return {\n success: false,\n error:\n \"Missing storefrontAccessToken. Required for direct Storefront API calls.\",\n };\n }\n\n try {\n const attributes = getCartAttributesPayload();\n\n // Format cartId as GID if it's not already\n const cartGid = cartId.startsWith(\"gid://\")\n ? cartId\n : `gid://shopify/Cart/${cartId}`;\n\n const storefrontUrl =\n options.storefrontApiUrl ||\n `https://${getStoreDomain()}/api/2025-01/graphql.json`;\n\n const response = await fetch(storefrontUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Shopify-Storefront-Access-Token\": options.storefrontAccessToken!,\n },\n body: JSON.stringify({\n query: CART_ATTRIBUTES_UPDATE_MUTATION,\n variables: {\n cartId: cartGid,\n attributes,\n },\n }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result = await response.json();\n\n if (\n result.errors ||\n result.data?.cartAttributesUpdate?.userErrors?.length > 0\n ) {\n const errorMsg =\n result.errors?.[0]?.message ||\n result.data?.cartAttributesUpdate?.userErrors?.[0]?.message ||\n \"Unknown error\";\n console.error(\"[ElevateAB] Cart attributes update failed:\", errorMsg);\n return { success: false, error: errorMsg };\n }\n\n return { success: true };\n } catch (error) {\n console.error(\"[ElevateAB] Error updating cart attributes:\", error);\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n}\n\n/**\n * Cleanup/remove cart attributes\n * Sets all Elevate attributes to empty strings\n *\n * @param cartId - The cart ID (GID or token)\n * @param options - Configuration options including storefrontAccessToken\n */\nexport async function cleanupCartAttributes(\n cartId: string,\n options: CartAttributesOptions = {}\n): Promise<{ success: boolean; error?: string }> {\n if (typeof window === \"undefined\") {\n return { success: false, error: \"Not in browser environment\" };\n }\n\n // Validate token is provided\n if (!options.storefrontAccessToken && !options.storefrontApiUrl) {\n return {\n success: false,\n error:\n \"Missing storefrontAccessToken. Required for direct Storefront API calls.\",\n };\n }\n\n try {\n const cartGid = cartId.startsWith(\"gid://\")\n ? cartId\n : `gid://shopify/Cart/${cartId}`;\n\n const attributes: CartAttributeInput[] = [\n { key: \"_eabTestsList\", value: \"\" },\n { key: \"_eabUserId\", value: \"\" },\n { key: \"_eabList\", value: \"\" },\n { key: \"_eabPreviewTest\", value: \"\" },\n ];\n\n const storefrontUrl =\n options.storefrontApiUrl ||\n `https://${getStoreDomain()}/api/2025-01/graphql.json`;\n\n const response = await fetch(storefrontUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Shopify-Storefront-Access-Token\": options.storefrontAccessToken!,\n },\n body: JSON.stringify({\n query: CART_ATTRIBUTES_UPDATE_MUTATION,\n variables: {\n cartId: cartGid,\n attributes,\n },\n }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result = await response.json();\n\n if (\n result.errors ||\n result.data?.cartAttributesUpdate?.userErrors?.length > 0\n ) {\n const errorMsg =\n result.errors?.[0]?.message ||\n result.data?.cartAttributesUpdate?.userErrors?.[0]?.message ||\n \"Unknown error\";\n console.error(\"[ElevateAB] Cart attributes cleanup failed:\", errorMsg);\n return { success: false, error: errorMsg };\n }\n\n return { success: true };\n } catch (error) {\n console.error(\"[ElevateAB] Error cleaning up cart attributes:\", error);\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n}\n\n/**\n * Helper to get store domain from current URL\n * Assumes format: mystore.myshopify.com or custom domain\n */\nfunction getStoreDomain(): string {\n if (typeof window === \"undefined\") return \"\";\n return window.location.hostname;\n}\n"],"mappings":";ygBAOO,SAASA,GAAiB,CAC/B,GAAI,CACF,GACE,OAAO,OAAW,KAClB,OAAO,QACP,OAAO,OAAO,gBACd,CACA,IAAMC,EAAO,IAAI,WAAW,EAAE,EAC9B,OAAO,OAAO,gBAAgBA,CAAI,EAClCA,EAAK,CAAC,EAAKA,EAAK,CAAC,EAAI,GAAQ,GAC7BA,EAAK,CAAC,EAAKA,EAAK,CAAC,EAAI,GAAQ,IAE7B,IAAMC,EAAY,MAAM,KAAKD,CAAI,EAAE,IAAKE,GACtCA,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAChC,EAEA,MAAO,CACLD,EAAU,MAAM,EAAG,CAAC,EAAE,KAAK,EAAE,EAC7BA,EAAU,MAAM,EAAG,CAAC,EAAE,KAAK,EAAE,EAC7BA,EAAU,MAAM,EAAG,CAAC,EAAE,KAAK,EAAE,EAC7BA,EAAU,MAAM,EAAG,EAAE,EAAE,KAAK,EAAE,EAC9BA,EAAU,MAAM,GAAI,EAAE,EAAE,KAAK,EAAE,CACjC,EAAE,KAAK,GAAG,CACZ,CACF,OAASE,EAAG,CACV,QAAQ,KACN,2EACAA,CACF,CACF,CAGA,MAAO,uCAAuC,QAAQ,QAAUC,GAAM,CACpE,IAAMC,EAAK,KAAK,OAAO,EAAI,GAAM,EAEjC,OADUD,IAAM,IAAMC,EAAKA,EAAI,EAAO,GAC7B,SAAS,EAAE,CACtB,CAAC,CACH,CAKO,SAASC,EAAUC,EAAcC,EAAqB,CAC3D,GAAI,OAAO,SAAa,IAAa,OAErC,IAAMC,EAAO,IAAI,KACjBA,EAAK,QAAQA,EAAK,QAAQ,EAAI,IAAM,GAAK,GAAK,GAAK,GAAI,EACvD,IAAMC,EAAU,aAAeD,EAAK,YAAY,EAChD,SAAS,OAASF,EAAO,KAAOC,GAAS,IAAME,EAAU,UAC3D,CAKO,SAASC,EAAUJ,EAA6B,CACrD,GAAI,OAAO,SAAa,IAAa,OAAO,KAE5C,IAAMK,EAASL,EAAO,IAChBM,EAAK,SAAS,OAAO,MAAM,GAAG,EACpC,QAASC,EAAI,EAAGA,EAAID,EAAG,OAAQC,IAAK,CAClC,IAAIV,EAAIS,EAAGC,CAAC,EACZ,KAAOV,EAAE,OAAO,CAAC,IAAM,KAAKA,EAAIA,EAAE,UAAU,EAAGA,EAAE,MAAM,EACvD,GAAIA,EAAE,QAAQQ,CAAM,IAAM,EAAG,OAAOR,EAAE,UAAUQ,EAAO,OAAQR,EAAE,MAAM,CACzE,CACA,OAAO,IACT,CAKO,SAASW,EACdR,EACU,CACV,IAAMS,EAAcL,EAAUJ,CAAI,EAClC,GAAIS,EACF,GAAI,CACF,OAAO,KAAK,MAAMA,CAAW,CAC/B,OAASC,EAAO,CACd,eAAQ,MAAM,6CAA8CA,CAAK,EAC1D,IACT,CAEF,OAAO,IACT,CAeO,SAASC,EAAeC,EAAcC,EAAsB,CAC7D,OAAO,eAAmB,KAE9B,eAAe,QAAQD,EAAM,KAAK,UAAUC,CAAK,CAAC,CACpD,CAKO,SAASC,EAAeF,EAA6B,CAC1D,OAAI,OAAO,eAAmB,IAAoB,KAE3C,eAAe,QAAQA,CAAI,CACpC,CAKO,SAASG,EAAgCH,EAAwB,CACtE,IAAMI,EAAOF,EAAeF,CAAI,EAChC,OAAOI,EAAQ,KAAK,MAAMA,CAAI,EAAU,IAC1C,CAKO,SAASC,GAA8B,CAC5C,IAAIC,EAAYC,EAAU,WAAW,EAErC,OAAKD,IACHA,EAAYE,EAAO,EACnBC,EAAU,YAAaH,CAAS,GAG3BA,CACT,CAKO,SAASI,GAAuB,CACrC,OAAOL,EAAoB,CAC7B,CAKO,SAASM,GAA8B,CAC5C,IAAIC,EAAYV,EAAe,cAAc,EAE7C,OAAKU,IACHA,EAAYJ,EAAO,EACnBT,EAAe,eAAgBa,CAAS,GAGnCA,CACT,CAKO,SAASC,GAAuB,CACrC,OAAOF,EAAoB,CAC7B,CAuBO,SAASG,GAA2D,CACzE,MAAO,CACL,SAAUC,EAAe,aAAa,GAAK,GAC3C,UAAWA,EAAe,UAAU,GAAK,EAC3C,CACF,CC5KO,SAASC,EAAWC,EAAqB,CAC9C,IAAIC,EAAO,EACX,QAASC,EAAI,EAAGA,EAAIF,EAAI,OAAQE,IAAK,CACnC,IAAMC,EAAOH,EAAI,WAAWE,CAAC,EAC7BD,GAAQA,GAAQ,GAAKA,EAAOE,EAC5BF,EAAOA,EAAOA,CAChB,CACA,OAAO,KAAK,IAAIA,CAAI,CACtB,CA0CO,SAASG,EAAmBC,EAA2C,CAC5E,IAAMC,EAAgB,CAAC,EAEvB,OAAW,CAACC,EAAQC,CAAQ,IAAK,OAAO,QAAQH,EAAY,QAAQ,EAAG,CAErE,GAAI,CAACG,EAAS,KAAK,OAAQ,SAG3B,IAAMC,EAA0B,CAAC,EAC7BC,EAAkB,EACtB,OAAW,CAACC,EAAKC,CAAK,IAAK,OAAO,QAAQJ,CAAQ,EAAG,CACnD,GAAIG,IAAQ,OAAQ,SAEpB,IAAME,EAAYD,EAClB,GACE,OAAOC,GAAc,UACrBA,IAAc,MACd,kBAAmBA,EACnB,CACA,IAAMC,EAAY,CAAC,CAACD,EAAU,UAC9BJ,EAAW,KAAK,CACd,GAAIE,EACJ,KAAME,EAAU,cAChB,OAAQA,EAAU,kBAClB,UAAAC,EACA,UAAWD,EAAU,GACrB,OAAQA,EAAU,OAClB,MAAOA,EAAU,MAEjB,IAAK,CAACC,GAAaJ,IAAoB,EACvC,IAAK,CAACI,GAAaJ,IAAoB,EACvC,IAAK,CAACI,GAAaJ,IAAoB,EACvC,IAAK,CAACI,GAAaJ,IAAoB,CACzC,CAAC,EACII,GAAWJ,GAClB,CACF,CAGID,EAAW,OAAS,GACtBH,EAAM,KAAK,CACT,OAAAC,EACA,KAAMC,EAAS,KAAK,KACpB,QAASA,EAAS,KAAK,OACvB,KAAMA,EAAS,KAAK,KACpB,WAAAC,CACF,CAAC,CAEL,CAEA,MAAO,CACL,MAAAH,EACA,UAAWD,EAAY,SACzB,CACF,CCjHO,SAASU,GAAwB,CACtC,OAAOC,EAAwB,MAAM,GAAK,CAAC,CAC7C,CAKO,SAASC,EAAaC,EAA0B,CACrDC,EAAU,OAAQ,KAAK,UAAUD,CAAQ,CAAC,CAC5C,CAKO,SAASE,EAAmBC,EAA+B,CAEhE,OADiBN,EAAY,EACbM,CAAM,GAAK,IAC7B,CAMA,SAASC,EAAmBC,EAAyBC,EAA6B,CAEhF,GADkBD,EAAWC,CAAW,GACzB,UAAW,MAAO,GAGjC,IAAIC,EAAkB,EACtB,QAASC,EAAI,EAAGA,EAAIF,EAAaE,IAC1BH,EAAWG,CAAC,GAAG,WAClBD,IAGJ,OAAOA,CACT,CAKO,SAASE,EACdJ,EACAK,EACW,CAEX,IAAMC,EAA2BN,EAAW,MACzCO,GAAM,OAAOA,EAAE,QAAW,QAC7B,EAEIC,EAA8B,CAAC,EAC/BC,EAAc,EAElB,GAAIH,EAEF,QAAWI,KAAaV,EACtBS,GAAeC,EAAU,OACzBF,EAAkB,KAAKC,CAAW,MAE/B,CAEL,IAAME,EAAgB,IAAMX,EAAW,OACvC,QAASG,EAAI,EAAGA,EAAIH,EAAW,OAAQG,IACrCM,GAAeE,EACfH,EAAkB,KAAKC,CAAW,CAEtC,CAIA,IAAMG,EADOC,EAAWR,CAAM,EACD,IAAS,IAGlCS,EAAgB,EACpB,QAASX,EAAI,EAAGA,EAAIK,EAAkB,OAAQL,IAC5C,GAAIS,EAAeJ,EAAkBL,CAAC,EAAG,CACvCW,EAAgBX,EAChB,KACF,CAGF,IAAMY,EAAoBf,EAAWc,CAAa,GAAKd,EAAW,CAAC,EAC7DE,EAAkBH,EAAmBC,EAAYc,CAAa,EAGpE,MAAO,CACL,GAAGC,EACH,IAAKb,IAAoB,EACzB,IAAKA,IAAoB,EACzB,IAAKA,IAAoB,EACzB,IAAKA,IAAoB,CAC3B,CACF,CAKO,SAASc,EACdlB,EACAmB,EACAZ,EACkB,CAElB,IAAMa,EAAoBrB,EAAmBC,CAAM,EACnD,GAAIoB,EAAmB,CACrB,IAAMC,EAAeF,EAAK,WAAW,UAClCV,GAAMA,EAAE,KAAOW,CAClB,EACA,GAAIC,IAAiB,GAAI,CACvB,IAAMC,EAAkBH,EAAK,WAAWE,CAAY,EAC9CjB,EAAkBH,EAAmBkB,EAAK,WAAYE,CAAY,EAExE,MAAO,CACL,GAAGC,EACH,IAAKlB,IAAoB,EACzB,IAAKA,IAAoB,EACzB,IAAKA,IAAoB,EACzB,IAAKA,IAAoB,CAC3B,CACF,CACF,CAGA,IAAMmB,EAAmBJ,EAAK,WAAW,OAAQV,GAGxC,CADSA,EAAU,MAE3B,EAED,GAAIc,EAAiB,SAAW,EAC9B,OAAO,KAIT,IAAMC,EAAqBL,EAAa,kBACpCM,EAEAD,EAGFC,EAD8BF,EAAiB,KAAMd,GAAM,CAACA,EAAE,SAAS,GAC5Bc,EAAiB,CAAC,EAG7DE,EAAkBnB,EAAqBiB,EAAkBhB,CAAM,EAIjE,IAAMV,EAAWH,EAAY,EAC7B,OAAAG,EAASG,CAAM,EAAIyB,EAAgB,GACnC7B,EAAaC,CAAQ,EAEd4B,CACT,CAKO,SAASC,EAAeP,EAAqB,CAClD,IAAMQ,EAAyBR,EAAa,sBAQ5C,OANI,OAAOQ,GAA0B,UAKX5B,EAAmBoB,EAAK,MAAM,EAE/C,GAIM,KAAK,OAAO,EAAI,IACfQ,CAClB,CCnLO,IAAMC,EAAkC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ECoBxC,SAASC,GAAiD,CAC/D,IAAMC,EAAWC,EAAY,EACvBC,EAAmBC,EAAuC,MAAM,GAAK,CAAC,EACtEC,EAAYC,EAAU,WAAW,EACjCC,EAAgBD,EAAU,gBAAgB,IAAM,OAChDE,EAAaF,EAAU,OAAO,EAG9BG,EAAsC,CAAC,EAC7C,QAAWC,KAAUT,EACfE,EAAiBO,CAAM,IACzBD,EAAYC,CAAM,EAAIT,EAASS,CAAM,GAIzC,IAAMC,EAAmC,CACvC,CACE,IAAK,gBACL,MAAO,KAAK,UAAUF,CAAW,CACnC,EACA,CACE,IAAK,aACL,MAAOJ,GAAa,EACtB,EACA,CACE,IAAK,WACL,MAAO,KAAK,UAAUJ,CAAQ,CAChC,CACF,EAGA,OAAIM,GAAiBC,GACnBG,EAAW,KAAK,CACd,IAAK,kBACL,MAAOH,CACT,CAAC,EAGIG,CACT,CAoCA,eAAsBC,GACpBC,EACAC,EAAiC,CAAC,EACa,CAC/C,GAAI,OAAO,OAAW,IACpB,MAAO,CAAE,QAAS,GAAO,MAAO,4BAA6B,EAI/D,GAAI,CAACA,EAAQ,uBAAyB,CAACA,EAAQ,iBAC7C,eAAQ,KACN,0RAIF,EACO,CACL,QAAS,GACT,MACE,0EACJ,EAGF,GAAI,CACF,IAAMH,EAAaX,EAAyB,EAGtCe,EAAUF,EAAO,WAAW,QAAQ,EACtCA,EACA,sBAAsBA,CAAM,GAE1BG,EACJF,EAAQ,kBACR,WAAWG,EAAe,CAAC,4BAEvBC,EAAW,MAAM,MAAMF,EAAe,CAC1C,OAAQ,OACR,QAAS,CACP,eAAgB,mBAChB,oCAAqCF,EAAQ,qBAC/C,EACA,KAAM,KAAK,UAAU,CACnB,MAAOK,EACP,UAAW,CACT,OAAQJ,EACR,WAAAJ,CACF,CACF,CAAC,CACH,CAAC,EAED,GAAI,CAACO,EAAS,GACZ,MAAM,IAAI,MAAM,uBAAuBA,EAAS,MAAM,EAAE,EAG1D,IAAME,EAAS,MAAMF,EAAS,KAAK,EAEnC,GACEE,EAAO,QACPA,EAAO,MAAM,sBAAsB,YAAY,OAAS,EACxD,CACA,IAAMC,EACJD,EAAO,SAAS,CAAC,GAAG,SACpBA,EAAO,MAAM,sBAAsB,aAAa,CAAC,GAAG,SACpD,gBACF,eAAQ,MAAM,6CAA8CC,CAAQ,EAC7D,CAAE,QAAS,GAAO,MAAOA,CAAS,CAC3C,CAEA,MAAO,CAAE,QAAS,EAAK,CACzB,OAASC,EAAO,CACd,eAAQ,MAAM,8CAA+CA,CAAK,EAC3D,CACL,QAAS,GACT,MAAOA,aAAiB,MAAQA,EAAM,QAAU,eAClD,CACF,CACF,CASA,eAAsBC,GACpBV,EACAC,EAAiC,CAAC,EACa,CAC/C,GAAI,OAAO,OAAW,IACpB,MAAO,CAAE,QAAS,GAAO,MAAO,4BAA6B,EAI/D,GAAI,CAACA,EAAQ,uBAAyB,CAACA,EAAQ,iBAC7C,MAAO,CACL,QAAS,GACT,MACE,0EACJ,EAGF,GAAI,CACF,IAAMC,EAAUF,EAAO,WAAW,QAAQ,EACtCA,EACA,sBAAsBA,CAAM,GAE1BF,EAAmC,CACvC,CAAE,IAAK,gBAAiB,MAAO,EAAG,EAClC,CAAE,IAAK,aAAc,MAAO,EAAG,EAC/B,CAAE,IAAK,WAAY,MAAO,EAAG,EAC7B,CAAE,IAAK,kBAAmB,MAAO,EAAG,CACtC,EAEMK,EACJF,EAAQ,kBACR,WAAWG,EAAe,CAAC,4BAEvBC,EAAW,MAAM,MAAMF,EAAe,CAC1C,OAAQ,OACR,QAAS,CACP,eAAgB,mBAChB,oCAAqCF,EAAQ,qBAC/C,EACA,KAAM,KAAK,UAAU,CACnB,MAAOK,EACP,UAAW,CACT,OAAQJ,EACR,WAAAJ,CACF,CACF,CAAC,CACH,CAAC,EAED,GAAI,CAACO,EAAS,GACZ,MAAM,IAAI,MAAM,uBAAuBA,EAAS,MAAM,EAAE,EAG1D,IAAME,EAAS,MAAMF,EAAS,KAAK,EAEnC,GACEE,EAAO,QACPA,EAAO,MAAM,sBAAsB,YAAY,OAAS,EACxD,CACA,IAAMC,EACJD,EAAO,SAAS,CAAC,GAAG,SACpBA,EAAO,MAAM,sBAAsB,aAAa,CAAC,GAAG,SACpD,gBACF,eAAQ,MAAM,8CAA+CC,CAAQ,EAC9D,CAAE,QAAS,GAAO,MAAOA,CAAS,CAC3C,CAEA,MAAO,CAAE,QAAS,EAAK,CACzB,OAASC,EAAO,CACd,eAAQ,MAAM,iDAAkDA,CAAK,EAC9D,CACL,QAAS,GACT,MAAOA,aAAiB,MAAQA,EAAM,QAAU,eAClD,CACF,CACF,CAMA,SAASL,GAAyB,CAChC,OAAI,OAAO,OAAW,IAAoB,GACnC,OAAO,SAAS,QACzB","names":["uuidv4","rnds","hexValues","b","e","c","r","setCookie","name","value","date","expires","getCookie","nameEQ","ca","i","getJsonCookie","cookieValue","error","setSessionItem","name","value","getSessionItem","getJsonSessionItem","item","initializeVisitorId","visitorId","getCookie","uuidv4","setCookie","getVisitorId","initializeSessionId","sessionId","getSessionId","getReferrerData","getSessionItem","hashString","str","hash","i","char","parseBackendConfig","backendData","tests","testId","testData","variations","nonControlIndex","key","value","variation","isControl","getTestList","getJsonCookie","saveTestList","testList","setCookie","getAssignedVariant","testId","getNonControlIndex","variations","targetIndex","nonControlIndex","i","assignVariantForUser","userId","allHaveTrafficPercentage","v","cumulativeWeights","totalWeight","variation","defaultWeight","randomWeight","hashString","assignedIndex","assignedVariation","assignAndPersistVariant","test","existingVariantId","variantIndex","existingVariant","activeVariations","isPersonalization","assignedVariant","shouldShowTest","testTrafficPercentage","CART_ATTRIBUTES_UPDATE_MUTATION","getCartAttributesPayload","testList","getTestList","addedUniqueViews","getJsonCookie","eabUserId","getCookie","isPreviewMode","abtidValue","viewedTests","testId","attributes","updateCartAttributes","cartId","options","cartGid","storefrontUrl","getStoreDomain","response","CART_ATTRIBUTES_UPDATE_MUTATION","result","errorMsg","error","cleanupCartAttributes"]}
@@ -0,0 +1,18 @@
1
+ var k=Object.create;var T=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var U=Object.getPrototypeOf,E=Object.prototype.hasOwnProperty;var N=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var V=(t,e,r,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of S(e))!E.call(t,s)&&s!==r&&T(t,s,{get:()=>e[s],enumerable:!(n=I(e,s))||n.enumerable});return t};var D=(t,e,r)=>(r=t!=null?k(U(t)):{},V(e||!t||!t.__esModule?T(r,"default",{value:t,enumerable:!0}):r,t));function A(){try{if(typeof window<"u"&&window.crypto&&window.crypto.getRandomValues){let t=new Uint8Array(16);window.crypto.getRandomValues(t),t[6]=t[6]&15|64,t[8]=t[8]&63|128;let e=Array.from(t).map(r=>r.toString(16).padStart(2,"0"));return[e.slice(0,4).join(""),e.slice(4,6).join(""),e.slice(6,8).join(""),e.slice(8,10).join(""),e.slice(10,16).join("")].join("-")}}catch(t){console.warn("[ElevateAB] Crypto UUID generation failed, falling back to Math.random()",t)}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,t=>{let e=Math.random()*16|0;return(t==="x"?e:e&3|8).toString(16)})}function x(t,e){if(typeof document>"u")return;let r=new Date;r.setTime(r.getTime()+365*24*60*60*1e3);let n="; expires="+r.toUTCString();document.cookie=t+"="+(e||"")+n+"; path=/"}function d(t){if(typeof document>"u")return null;let e=t+"=",r=document.cookie.split(";");for(let n=0;n<r.length;n++){let s=r[n];for(;s.charAt(0)===" ";)s=s.substring(1,s.length);if(s.indexOf(e)===0)return s.substring(e.length,s.length)}return null}function g(t){let e=d(t);if(e)try{return JSON.parse(e)}catch(r){return console.error("[ElevateAB] Error parsing JSON from cookie",r),null}return null}function R(t){typeof document>"u"||(document.cookie=t+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;")}function h(t,e){typeof sessionStorage>"u"||sessionStorage.setItem(t,JSON.stringify(e))}function l(t){return typeof sessionStorage>"u"?null:sessionStorage.getItem(t)}function J(t){let e=l(t);return e?JSON.parse(e):null}function P(){let t=d("eabUserId");return t||(t=A(),x("eabUserId",t)),t}function _(){return P()}function L(){let t=l("eabSessionId");return t||(t=A(),h("eabSessionId",t)),t}function $(){return L()}function q(t,e){if(typeof sessionStorage>"u")return;let r=l("eabReferrer"),n=l("eabEntry");r||h("eabReferrer",t),n||h("eabEntry",e)}function W(){return{referrer:l("eabReferrer")||"",entryPage:l("eabEntry")||""}}function H(t,e){let r=t.reduce((o,a)=>o+a.weight,0),s=m(e)%r,i=0;for(let o of t)if(i+=o.weight,s<i)return o;return t[0]}function m(t){let e=0;for(let r=0;r<t.length;r++){let n=t.charCodeAt(r);e=(e<<5)-e+n,e=e&e}return Math.abs(e)}function F(t){return!t.testId||!t.name||!t.variations||t.variations.length===0?!1:t.variations.reduce((r,n)=>r+n.weight,0)===100}function G(t){let e=Date.now(),r=Math.random().toString(36).substring(2,9);return`exp-${t.toLowerCase().replace(/[^a-z0-9]/g,"-")}-${e}-${r}`}function X(t,e,r,n){let s=t/r,i=e/n,o=(i-s)/s*100,c=Math.sqrt((t+e)/(r+n))*Math.sqrt(1/r+1/n),u=Math.abs(i-s)/c,f=Math.min(99.9,u*34);return{lift:o,confidence:f}}function Q(t){let e=[];for(let[r,n]of Object.entries(t.allTests)){if(!n.data.isLive)continue;let s=[],i=0;for(let[o,a]of Object.entries(n)){if(o==="data")continue;let c=a;if(typeof c=="object"&&c!==null&&"variationName"in c){let u=!!c.isControl;s.push({id:o,name:c.variationName,weight:c.trafficPercentage,isControl:u,productId:c.id,handle:c.handle,price:c.price,isA:!u&&i===0,isB:!u&&i===1,isC:!u&&i===2,isD:!u&&i===3}),u||i++}}s.length>0&&e.push({testId:r,name:n.data.name,enabled:n.data.isLive,type:n.data.type,variations:s})}return{tests:e,selectors:t.selectors}}function p(){return g("ABTL")||{}}function O(t){x("ABTL",JSON.stringify(t))}function v(t){return p()[t]||null}function w(t,e){if(t[e]?.isControl)return-1;let n=0;for(let s=0;s<e;s++)t[s]?.isControl||n++;return n}function B(t,e){let r=t.every(f=>typeof f.weight=="number"),n=[],s=0;if(r)for(let f of t)s+=f.weight,n.push(s);else{let f=100/t.length;for(let y=0;y<t.length;y++)s+=f,n.push(s)}let o=m(e)%1e4/100,a=0;for(let f=0;f<n.length;f++)if(o<n[f]){a=f;break}let c=t[a]||t[0],u=w(t,a);return{...c,isA:u===0,isB:u===1,isC:u===2,isD:u===3}}function et(t,e,r){let n=v(t);if(n){let c=e.variations.findIndex(u=>u.id===n);if(c!==-1){let u=e.variations[c],f=w(e.variations,c);return{...u,isA:f===0,isB:f===1,isC:f===2,isD:f===3}}}let s=e.variations.filter(c=>!c.isDone);if(s.length===0)return null;let i=e.isPersonalization,o;i?o=s.find(u=>!u.isControl)||s[0]:o=B(s,r);let a=p();return a[t]=o.id,O(a),o}function rt(t){let e=t.testTrafficPercentage;return typeof e!="number"||v(t.testId)?!0:Math.random()*100<e}var b=`#graphql
2
+ mutation cartAttributesUpdate($cartId: ID!, $attributes: [AttributeInput!]!) {
3
+ cartAttributesUpdate(cartId: $cartId, attributes: $attributes) {
4
+ cart {
5
+ id
6
+ attributes {
7
+ key
8
+ value
9
+ }
10
+ }
11
+ userErrors {
12
+ field
13
+ message
14
+ }
15
+ }
16
+ }
17
+ `;function M(){let t=p(),e=g("ABAU")||{},r=d("eabUserId"),n=d("eabUserPreview")==="true",s=d("abtid"),i={};for(let a in t)e[a]&&(i[a]=t[a]);let o=[{key:"_eabTestsList",value:JSON.stringify(i)},{key:"_eabUserId",value:r||""},{key:"_eabList",value:JSON.stringify(t)}];return n&&s&&o.push({key:"_eabPreviewTest",value:s}),o}async function ct(t,e={}){if(typeof window>"u")return{success:!1,error:"Not in browser environment"};if(!e.storefrontAccessToken&&!e.storefrontApiUrl)return console.warn("[ElevateAB] Missing storefrontAccessToken. For Next.js/non-Hydrogen stores, you must provide a Storefront Access Token. This token is SAFE to use client-side - it's a public token with limited permissions. Get it from: Shopify Admin \u2192 Settings \u2192 Apps \u2192 Develop apps"),{success:!1,error:"Missing storefrontAccessToken. Required for direct Storefront API calls."};try{let r=M(),n=t.startsWith("gid://")?t:`gid://shopify/Cart/${t}`,s=e.storefrontApiUrl||`https://${C()}/api/2025-01/graphql.json`,i=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json","X-Shopify-Storefront-Access-Token":e.storefrontAccessToken},body:JSON.stringify({query:b,variables:{cartId:n,attributes:r}})});if(!i.ok)throw new Error(`HTTP error! status: ${i.status}`);let o=await i.json();if(o.errors||o.data?.cartAttributesUpdate?.userErrors?.length>0){let a=o.errors?.[0]?.message||o.data?.cartAttributesUpdate?.userErrors?.[0]?.message||"Unknown error";return console.error("[ElevateAB] Cart attributes update failed:",a),{success:!1,error:a}}return{success:!0}}catch(r){return console.error("[ElevateAB] Error updating cart attributes:",r),{success:!1,error:r instanceof Error?r.message:"Unknown error"}}}async function ut(t,e={}){if(typeof window>"u")return{success:!1,error:"Not in browser environment"};if(!e.storefrontAccessToken&&!e.storefrontApiUrl)return{success:!1,error:"Missing storefrontAccessToken. Required for direct Storefront API calls."};try{let r=t.startsWith("gid://")?t:`gid://shopify/Cart/${t}`,n=[{key:"_eabTestsList",value:""},{key:"_eabUserId",value:""},{key:"_eabList",value:""},{key:"_eabPreviewTest",value:""}],s=e.storefrontApiUrl||`https://${C()}/api/2025-01/graphql.json`,i=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json","X-Shopify-Storefront-Access-Token":e.storefrontAccessToken},body:JSON.stringify({query:b,variables:{cartId:r,attributes:n}})});if(!i.ok)throw new Error(`HTTP error! status: ${i.status}`);let o=await i.json();if(o.errors||o.data?.cartAttributesUpdate?.userErrors?.length>0){let a=o.errors?.[0]?.message||o.data?.cartAttributesUpdate?.userErrors?.[0]?.message||"Unknown error";return console.error("[ElevateAB] Cart attributes cleanup failed:",a),{success:!1,error:a}}return{success:!0}}catch(r){return console.error("[ElevateAB] Error cleaning up cart attributes:",r),{success:!1,error:r instanceof Error?r.message:"Unknown error"}}}function C(){return typeof window>"u"?"":window.location.hostname}export{N as a,D as b,A as c,x as d,d as e,g as f,R as g,h,l as i,J as j,P as k,_ as l,L as m,$ as n,q as o,W as p,H as q,m as r,F as s,G as t,X as u,Q as v,p as w,O as x,v as y,et as z,rt as A,b as B,M as C,ct as D,ut as E};
18
+ //# sourceMappingURL=chunk-VUGOZ5MR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/storage.ts","../src/utils.ts","../src/utils/assignment.ts","../src/mutations/cartAttributes.mutation.ts","../src/utils/cartAttributes.ts"],"sourcesContent":["/**\n * Cookie and Session Storage utilities\n */\n\n/**\n * Generate a UUID v4\n */\nexport function uuidv4(): string {\n try {\n if (\n typeof window !== \"undefined\" &&\n window.crypto &&\n window.crypto.getRandomValues\n ) {\n const rnds = new Uint8Array(16);\n window.crypto.getRandomValues(rnds);\n rnds[6] = (rnds[6] & 0x0f) | 0x40; // Version 4\n rnds[8] = (rnds[8] & 0x3f) | 0x80; // Variant 1\n\n const hexValues = Array.from(rnds).map((b) =>\n b.toString(16).padStart(2, \"0\")\n );\n\n return [\n hexValues.slice(0, 4).join(\"\"),\n hexValues.slice(4, 6).join(\"\"),\n hexValues.slice(6, 8).join(\"\"),\n hexValues.slice(8, 10).join(\"\"),\n hexValues.slice(10, 16).join(\"\"),\n ].join(\"-\");\n }\n } catch (e) {\n console.warn(\n \"[ElevateAB] Crypto UUID generation failed, falling back to Math.random()\",\n e\n );\n }\n\n // Fallback to Math.random\n return \"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx\".replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === \"x\" ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n/**\n * Set a cookie with 1 year expiration\n */\nexport function setCookie(name: string, value: string): void {\n if (typeof document === \"undefined\") return;\n\n const date = new Date();\n date.setTime(date.getTime() + 365 * 24 * 60 * 60 * 1000);\n const expires = \"; expires=\" + date.toUTCString();\n document.cookie = name + \"=\" + (value || \"\") + expires + \"; path=/\";\n}\n\n/**\n * Get a cookie value by name\n */\nexport function getCookie(name: string): string | null {\n if (typeof document === \"undefined\") return null;\n\n const nameEQ = name + \"=\";\n const ca = document.cookie.split(\";\");\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === \" \") c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n}\n\n/**\n * Get a JSON-parsed cookie value\n */\nexport function getJsonCookie<T = Record<string, unknown>>(\n name: string\n): T | null {\n const cookieValue = getCookie(name);\n if (cookieValue) {\n try {\n return JSON.parse(cookieValue) as T;\n } catch (error) {\n console.error(\"[ElevateAB] Error parsing JSON from cookie\", error);\n return null;\n }\n }\n return null;\n}\n\n/**\n * Delete a cookie\n */\nexport function deleteCookie(cookieName: string): void {\n if (typeof document === \"undefined\") return;\n\n document.cookie =\n cookieName + \"=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;\";\n}\n\n/**\n * Set a session storage item\n */\nexport function setSessionItem(name: string, value: unknown): void {\n if (typeof sessionStorage === \"undefined\") return;\n\n sessionStorage.setItem(name, JSON.stringify(value));\n}\n\n/**\n * Get a session storage item\n */\nexport function getSessionItem(name: string): string | null {\n if (typeof sessionStorage === \"undefined\") return null;\n\n return sessionStorage.getItem(name);\n}\n\n/**\n * Get a JSON-parsed session storage item\n */\nexport function getJsonSessionItem<T = unknown>(name: string): T | null {\n const item = getSessionItem(name);\n return item ? (JSON.parse(item) as T) : null;\n}\n\n/**\n * Initialize visitor ID - creates eabUserId cookie if it doesn't exist\n */\nexport function initializeVisitorId(): string {\n let visitorId = getCookie(\"eabUserId\");\n\n if (!visitorId) {\n visitorId = uuidv4();\n setCookie(\"eabUserId\", visitorId);\n }\n\n return visitorId;\n}\n\n/**\n * Get or create visitor ID\n */\nexport function getVisitorId(): string {\n return initializeVisitorId();\n}\n\n/**\n * Initialize session ID - creates eabSessionId in sessionStorage if it doesn't exist\n */\nexport function initializeSessionId(): string {\n let sessionId = getSessionItem(\"eabSessionId\");\n\n if (!sessionId) {\n sessionId = uuidv4();\n setSessionItem(\"eabSessionId\", sessionId);\n }\n\n return sessionId;\n}\n\n/**\n * Get or create session ID\n */\nexport function getSessionId(): string {\n return initializeSessionId();\n}\n\n/**\n * Store referrer and entry page data in sessionStorage\n */\nexport function setReferrerData(referrer: string, entryPage: string): void {\n if (typeof sessionStorage === \"undefined\") return;\n\n // Only set if not already set (preserve first referrer/entry)\n const existingReferrer = getSessionItem(\"eabReferrer\");\n const existingEntry = getSessionItem(\"eabEntry\");\n\n if (!existingReferrer) {\n setSessionItem(\"eabReferrer\", referrer);\n }\n if (!existingEntry) {\n setSessionItem(\"eabEntry\", entryPage);\n }\n}\n\n/**\n * Get referrer data from sessionStorage\n */\nexport function getReferrerData(): { referrer: string; entryPage: string } {\n return {\n referrer: getSessionItem(\"eabReferrer\") || \"\",\n entryPage: getSessionItem(\"eabEntry\") || \"\",\n };\n}\n","import type { Variation, Test, BackendConfig, ElevateConfig } from \"./types\";\n\n/**\n * Assigns a variant based on weighted distribution\n */\nexport function assignVariant(\n variations: Variation[],\n userId: string\n): Variation {\n const totalWeight = variations.reduce((sum, v) => sum + v.weight, 0);\n const hash = hashString(userId);\n const normalized = hash % totalWeight;\n\n let cumulative = 0;\n for (const variation of variations) {\n cumulative += variation.weight;\n if (normalized < cumulative) {\n return variation;\n }\n }\n\n return variations[0];\n}\n\nexport function hashString(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return Math.abs(hash);\n}\n\nexport function validateConfig(config: Test): boolean {\n if (!config.testId || !config.name) return false;\n if (!config.variations || config.variations.length === 0) return false;\n\n const totalWeight = config.variations.reduce((sum, v) => sum + v.weight, 0);\n return totalWeight === 100;\n}\n\nexport function generateExperimentId(name: string): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 9);\n const safeName = name.toLowerCase().replace(/[^a-z0-9]/g, \"-\");\n return `exp-${safeName}-${timestamp}-${random}`;\n}\n\nexport function calculateRevenueLift(\n controlRevenue: number,\n variantRevenue: number,\n controlSampleSize: number,\n variantSampleSize: number\n): { lift: number; confidence: number } {\n const controlMean = controlRevenue / controlSampleSize;\n const variantMean = variantRevenue / variantSampleSize;\n\n const lift = ((variantMean - controlMean) / controlMean) * 100;\n\n const pooledStdDev = Math.sqrt(\n (controlRevenue + variantRevenue) / (controlSampleSize + variantSampleSize)\n );\n const standardError =\n pooledStdDev * Math.sqrt(1 / controlSampleSize + 1 / variantSampleSize);\n const zScore = Math.abs(variantMean - controlMean) / standardError;\n const confidence = Math.min(99.9, zScore * 34);\n\n return { lift, confidence };\n}\n\n/**\n * Parse backend config format to SDK normalized format\n */\nexport function parseBackendConfig(backendData: BackendConfig): ElevateConfig {\n const tests: Test[] = [];\n\n for (const [testId, testData] of Object.entries(backendData.allTests)) {\n // Skip if not live\n if (!testData.data.isLive) continue;\n\n // Extract variations (all keys except 'data')\n const variations: Variation[] = [];\n let nonControlIndex = 0; // Count only non-control variations for isA/isB/isC/isD\n for (const [key, value] of Object.entries(testData)) {\n if (key === \"data\") continue;\n\n const variation = value as BackendConfig[\"allTests\"][string][string];\n if (\n typeof variation === \"object\" &&\n variation !== null &&\n \"variationName\" in variation\n ) {\n const isControl = !!variation.isControl;\n variations.push({\n id: key,\n name: variation.variationName,\n weight: variation.trafficPercentage,\n isControl,\n productId: variation.id,\n handle: variation.handle,\n price: variation.price,\n // Set convenience flags: isA = first non-control, isB = second, etc.\n isA: !isControl && nonControlIndex === 0,\n isB: !isControl && nonControlIndex === 1,\n isC: !isControl && nonControlIndex === 2,\n isD: !isControl && nonControlIndex === 3,\n });\n if (!isControl) nonControlIndex++;\n }\n }\n\n // Only include tests with variations\n if (variations.length > 0) {\n tests.push({\n testId,\n name: testData.data.name,\n enabled: testData.data.isLive,\n type: testData.data.type,\n variations,\n });\n }\n }\n\n return {\n tests,\n selectors: backendData.selectors,\n };\n}\n","/**\n * Variant assignment logic\n */\n\nimport type { Test, Variation } from \"../types\";\nimport { getCookie, setCookie, getJsonCookie } from \"./storage\";\nimport { hashString } from \"../utils\";\n\nexport interface TestList {\n [testId: string]: string; // testId -> variantId\n}\n\n/**\n * Get the test list from ABTL cookie\n */\nexport function getTestList(): TestList {\n return getJsonCookie<TestList>(\"ABTL\") || {};\n}\n\n/**\n * Save test list to ABTL cookie\n */\nexport function saveTestList(testList: TestList): void {\n setCookie(\"ABTL\", JSON.stringify(testList));\n}\n\n/**\n * Get assigned variant for a test from ABTL cookie\n */\nexport function getAssignedVariant(testId: string): string | null {\n const testList = getTestList();\n return testList[testId] || null;\n}\n\n/**\n * Get the non-control index for a variation (for isA, isB, isC, isD flags)\n * Control gets -1, first non-control gets 0 (isA), second gets 1 (isB), etc.\n */\nfunction getNonControlIndex(variations: Variation[], targetIndex: number): number {\n const variation = variations[targetIndex];\n if (variation?.isControl) return -1; // Control doesn't get isA/isB/etc\n \n // Count how many non-control variations come before this one\n let nonControlIndex = 0;\n for (let i = 0; i < targetIndex; i++) {\n if (!variations[i]?.isControl) {\n nonControlIndex++;\n }\n }\n return nonControlIndex;\n}\n\n/**\n * Assign a variant to a user based on userId and variations\n */\nexport function assignVariantForUser(\n variations: Variation[],\n userId: string\n): Variation {\n // Check if all variations have trafficPercentage\n const allHaveTrafficPercentage = variations.every(\n (v) => typeof v.weight === \"number\"\n );\n\n let cumulativeWeights: number[] = [];\n let totalWeight = 0;\n\n if (allHaveTrafficPercentage) {\n // Use traffic percentages\n for (const variation of variations) {\n totalWeight += variation.weight;\n cumulativeWeights.push(totalWeight);\n }\n } else {\n // Split evenly\n const defaultWeight = 100 / variations.length;\n for (let i = 0; i < variations.length; i++) {\n totalWeight += defaultWeight;\n cumulativeWeights.push(totalWeight);\n }\n }\n\n // Generate hash from userId\n const hash = hashString(userId);\n const randomWeight = (hash % 10000) / 100; // 0-100 range\n\n // Find which variation to assign\n let assignedIndex = 0;\n for (let i = 0; i < cumulativeWeights.length; i++) {\n if (randomWeight < cumulativeWeights[i]) {\n assignedIndex = i;\n break;\n }\n }\n\n const assignedVariation = variations[assignedIndex] || variations[0];\n const nonControlIndex = getNonControlIndex(variations, assignedIndex);\n\n // Set convenience flags: isA = first non-control, isB = second non-control, etc.\n return {\n ...assignedVariation,\n isA: nonControlIndex === 0,\n isB: nonControlIndex === 1,\n isC: nonControlIndex === 2,\n isD: nonControlIndex === 3,\n };\n}\n\n/**\n * Assign and persist variant for a test\n */\nexport function assignAndPersistVariant(\n testId: string,\n test: Test,\n userId: string\n): Variation | null {\n // Check if already assigned (from cookie)\n const existingVariantId = getAssignedVariant(testId);\n if (existingVariantId) {\n const variantIndex = test.variations.findIndex(\n (v) => v.id === existingVariantId\n );\n if (variantIndex !== -1) {\n const existingVariant = test.variations[variantIndex];\n const nonControlIndex = getNonControlIndex(test.variations, variantIndex);\n // Set convenience flags: isA = first non-control, isB = second, etc.\n return {\n ...existingVariant,\n isA: nonControlIndex === 0,\n isB: nonControlIndex === 1,\n isC: nonControlIndex === 2,\n isD: nonControlIndex === 3,\n };\n }\n }\n\n // Filter out completed/done variations (keep all active ones)\n const activeVariations = test.variations.filter((v) => {\n // Check if variation has isDone flag (from backend)\n const isDone = (v as any).isDone;\n return !isDone;\n });\n\n if (activeVariations.length === 0) {\n return null;\n }\n\n // Check if it's a personalization (always assign to non-control)\n const isPersonalization = (test as any).isPersonalization;\n let assignedVariant: Variation;\n\n if (isPersonalization) {\n // Find the non-control variation\n const personalizedVariation = activeVariations.find((v) => !v.isControl);\n assignedVariant = personalizedVariation || activeVariations[0];\n } else {\n // Regular A/B test - use weighted assignment\n assignedVariant = assignVariantForUser(activeVariations, userId);\n }\n\n // Persist to ABTL cookie\n const testList = getTestList();\n testList[testId] = assignedVariant.id;\n saveTestList(testList);\n\n return assignedVariant;\n}\n\n/**\n * Check if test should be shown based on traffic percentage\n */\nexport function shouldShowTest(test: Test): boolean {\n const testTrafficPercentage = (test as any).testTrafficPercentage;\n\n if (typeof testTrafficPercentage !== \"number\") {\n return true; // No traffic limiting\n }\n\n // Check if user is already in this test\n const existingVariantId = getAssignedVariant(test.testId);\n if (existingVariantId) {\n return true; // Already assigned, always show\n }\n\n // Random check against traffic percentage\n const random = Math.random() * 100;\n return random < testTrafficPercentage;\n}\n","/**\n * GraphQL mutations for cart attributes\n */\n\n/**\n * GraphQL mutation for updating cart attributes\n * Use this in your Storefront API calls\n */\nexport const CART_ATTRIBUTES_UPDATE_MUTATION = `#graphql\n mutation cartAttributesUpdate($cartId: ID!, $attributes: [AttributeInput!]!) {\n cartAttributesUpdate(cartId: $cartId, attributes: $attributes) {\n cart {\n id\n attributes {\n key\n value\n }\n }\n userErrors {\n field\n message\n }\n }\n }\n`;\n","/**\n * Cart attribute utilities for tagging carts with A/B test data\n *\n * These functions update Shopify cart attributes with test assignment data,\n * enabling order attribution for A/B test analysis.\n */\n\nimport { getTestList } from \"./assignment\";\nimport { getCookie, getJsonCookie } from \"./storage\";\nimport { CART_ATTRIBUTES_UPDATE_MUTATION } from \"../mutations/cartAttributes.mutation\";\nimport type { CartAttributesOptions, CartAttributeInput } from \"../types\";\n\n// Re-export types for backwards compatibility\nexport type { CartAttributesOptions, CartAttributeInput } from \"../types\";\n\n/**\n * Get cart attributes payload from current test assignments\n * Returns an array of key-value pairs ready to be sent to Shopify\n *\n * @example\n * ```ts\n * const attributes = getCartAttributesPayload();\n * // Use with your own Storefront client\n * await storefront.mutate(CART_ATTRIBUTES_UPDATE_MUTATION, {\n * variables: { cartId, attributes }\n * });\n * ```\n */\nexport function getCartAttributesPayload(): CartAttributeInput[] {\n const testList = getTestList(); // ABTL - all assignments\n const addedUniqueViews = getJsonCookie<Record<string, boolean>>(\"ABAU\") || {};\n const eabUserId = getCookie(\"eabUserId\");\n const isPreviewMode = getCookie(\"eabUserPreview\") === \"true\";\n const abtidValue = getCookie(\"abtid\");\n\n // Filter viewed tests - only include tests that have been viewed\n const viewedTests: Record<string, string> = {};\n for (const testId in testList) {\n if (addedUniqueViews[testId]) {\n viewedTests[testId] = testList[testId];\n }\n }\n\n const attributes: CartAttributeInput[] = [\n {\n key: \"_eabTestsList\",\n value: JSON.stringify(viewedTests),\n },\n {\n key: \"_eabUserId\",\n value: eabUserId || \"\",\n },\n {\n key: \"_eabList\",\n value: JSON.stringify(testList),\n },\n ];\n\n // Add preview test if in preview mode\n if (isPreviewMode && abtidValue) {\n attributes.push({\n key: \"_eabPreviewTest\",\n value: abtidValue,\n });\n }\n\n return attributes;\n}\n\n/**\n * Update cart attributes with test assignment data\n *\n * This function calls the Shopify Storefront API to update cart attributes.\n *\n * ## Authentication\n *\n * **For Hydrogen stores:** Use your storefront client directly with `getCartAttributesPayload()`\n *\n * **For Next.js/Other stores:** Pass the `storefrontAccessToken` option.\n *\n * ✅ The Storefront Access Token is **safe to use client-side**.\n * It's a public token designed by Shopify for browser use.\n * It can only read products and manage carts - it CANNOT delete products,\n * access admin functions, or do anything destructive.\n *\n * Get your token from: Shopify Admin → Settings → Apps → Develop apps\n *\n * @param cartId - The cart ID (GID or token, e.g., \"gid://shopify/Cart/abc123\" or just \"abc123\")\n * @param options - Configuration options including storefrontAccessToken\n * @returns Promise with success status and optional error message\n *\n * @example\n * ```ts\n * // Next.js usage - token is safe to use client-side!\n * const result = await updateCartAttributes(cartId, {\n * storefrontAccessToken: process.env.NEXT_PUBLIC_STOREFRONT_TOKEN\n * });\n *\n * if (!result.success) {\n * console.error('Failed to update cart attributes:', result.error);\n * }\n * ```\n */\nexport async function updateCartAttributes(\n cartId: string,\n options: CartAttributesOptions = {}\n): Promise<{ success: boolean; error?: string }> {\n if (typeof window === \"undefined\") {\n return { success: false, error: \"Not in browser environment\" };\n }\n\n // Validate token is provided for direct API calls\n if (!options.storefrontAccessToken && !options.storefrontApiUrl) {\n console.warn(\n \"[ElevateAB] Missing storefrontAccessToken. \" +\n \"For Next.js/non-Hydrogen stores, you must provide a Storefront Access Token. \" +\n \"This token is SAFE to use client-side - it's a public token with limited permissions. \" +\n \"Get it from: Shopify Admin → Settings → Apps → Develop apps\"\n );\n return {\n success: false,\n error:\n \"Missing storefrontAccessToken. Required for direct Storefront API calls.\",\n };\n }\n\n try {\n const attributes = getCartAttributesPayload();\n\n // Format cartId as GID if it's not already\n const cartGid = cartId.startsWith(\"gid://\")\n ? cartId\n : `gid://shopify/Cart/${cartId}`;\n\n const storefrontUrl =\n options.storefrontApiUrl ||\n `https://${getStoreDomain()}/api/2025-01/graphql.json`;\n\n const response = await fetch(storefrontUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Shopify-Storefront-Access-Token\": options.storefrontAccessToken!,\n },\n body: JSON.stringify({\n query: CART_ATTRIBUTES_UPDATE_MUTATION,\n variables: {\n cartId: cartGid,\n attributes,\n },\n }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result = await response.json();\n\n if (\n result.errors ||\n result.data?.cartAttributesUpdate?.userErrors?.length > 0\n ) {\n const errorMsg =\n result.errors?.[0]?.message ||\n result.data?.cartAttributesUpdate?.userErrors?.[0]?.message ||\n \"Unknown error\";\n console.error(\"[ElevateAB] Cart attributes update failed:\", errorMsg);\n return { success: false, error: errorMsg };\n }\n\n return { success: true };\n } catch (error) {\n console.error(\"[ElevateAB] Error updating cart attributes:\", error);\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n}\n\n/**\n * Cleanup/remove cart attributes\n * Sets all Elevate attributes to empty strings\n *\n * @param cartId - The cart ID (GID or token)\n * @param options - Configuration options including storefrontAccessToken\n */\nexport async function cleanupCartAttributes(\n cartId: string,\n options: CartAttributesOptions = {}\n): Promise<{ success: boolean; error?: string }> {\n if (typeof window === \"undefined\") {\n return { success: false, error: \"Not in browser environment\" };\n }\n\n // Validate token is provided\n if (!options.storefrontAccessToken && !options.storefrontApiUrl) {\n return {\n success: false,\n error:\n \"Missing storefrontAccessToken. Required for direct Storefront API calls.\",\n };\n }\n\n try {\n const cartGid = cartId.startsWith(\"gid://\")\n ? cartId\n : `gid://shopify/Cart/${cartId}`;\n\n const attributes: CartAttributeInput[] = [\n { key: \"_eabTestsList\", value: \"\" },\n { key: \"_eabUserId\", value: \"\" },\n { key: \"_eabList\", value: \"\" },\n { key: \"_eabPreviewTest\", value: \"\" },\n ];\n\n const storefrontUrl =\n options.storefrontApiUrl ||\n `https://${getStoreDomain()}/api/2025-01/graphql.json`;\n\n const response = await fetch(storefrontUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Shopify-Storefront-Access-Token\": options.storefrontAccessToken!,\n },\n body: JSON.stringify({\n query: CART_ATTRIBUTES_UPDATE_MUTATION,\n variables: {\n cartId: cartGid,\n attributes,\n },\n }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result = await response.json();\n\n if (\n result.errors ||\n result.data?.cartAttributesUpdate?.userErrors?.length > 0\n ) {\n const errorMsg =\n result.errors?.[0]?.message ||\n result.data?.cartAttributesUpdate?.userErrors?.[0]?.message ||\n \"Unknown error\";\n console.error(\"[ElevateAB] Cart attributes cleanup failed:\", errorMsg);\n return { success: false, error: errorMsg };\n }\n\n return { success: true };\n } catch (error) {\n console.error(\"[ElevateAB] Error cleaning up cart attributes:\", error);\n return {\n success: false,\n error: error instanceof Error ? error.message : \"Unknown error\",\n };\n }\n}\n\n/**\n * Helper to get store domain from current URL\n * Assumes format: mystore.myshopify.com or custom domain\n */\nfunction getStoreDomain(): string {\n if (typeof window === \"undefined\") return \"\";\n return window.location.hostname;\n}\n"],"mappings":"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","names":["uuidv4","rnds","hexValues","b","e","c","r","setCookie","name","value","date","expires","getCookie","nameEQ","ca","i","getJsonCookie","cookieValue","error","deleteCookie","cookieName","setSessionItem","getSessionItem","getJsonSessionItem","item","initializeVisitorId","visitorId","getVisitorId","initializeSessionId","sessionId","getSessionId","setReferrerData","referrer","entryPage","existingReferrer","existingEntry","getReferrerData","assignVariant","variations","userId","totalWeight","sum","v","normalized","hashString","cumulative","variation","str","hash","i","char","validateConfig","config","generateExperimentId","name","timestamp","random","calculateRevenueLift","controlRevenue","variantRevenue","controlSampleSize","variantSampleSize","controlMean","variantMean","lift","standardError","zScore","confidence","parseBackendConfig","backendData","tests","testId","testData","nonControlIndex","key","value","isControl","getTestList","getJsonCookie","saveTestList","testList","setCookie","getAssignedVariant","testId","getNonControlIndex","variations","targetIndex","nonControlIndex","i","assignVariantForUser","userId","allHaveTrafficPercentage","v","cumulativeWeights","totalWeight","variation","defaultWeight","randomWeight","hashString","assignedIndex","assignedVariation","assignAndPersistVariant","test","existingVariantId","variantIndex","existingVariant","activeVariations","isPersonalization","assignedVariant","shouldShowTest","testTrafficPercentage","CART_ATTRIBUTES_UPDATE_MUTATION","getCartAttributesPayload","testList","getTestList","addedUniqueViews","getJsonCookie","eabUserId","getCookie","isPreviewMode","abtidValue","viewedTests","testId","attributes","updateCartAttributes","cartId","options","cartGid","storefrontUrl","getStoreDomain","response","CART_ATTRIBUTES_UPDATE_MUTATION","result","errorMsg","error","cleanupCartAttributes"]}
@@ -0,0 +1,2 @@
1
+ import{D as De,a as Ye,b as Xe,c as Ce,e as le,f as he,l as _e,n as ve,o as Be,p as Ne}from"./chunk-VUGOZ5MR.js";var Ue=Ye((se,be)=>{"use strict";(function(a,s){"use strict";var p="1.0.41",v="",m="?",I="function",y="undefined",N="object",P="string",ee="major",e="model",o="name",t="type",r="vendor",i="version",A="architecture",D="console",d="mobile",l="tablet",S="smarttv",O="wearable",Y="embedded",te=500,Q="Amazon",H="Apple",ce="ASUS",n="BlackBerry",c="Browser",h="Chrome",x="Edge",E="Firefox",C="Google",U="Honor",_="Huawei",T="Lenovo",q="LG",X="Microsoft",F="Motorola",V="Nvidia",W="OnePlus",K="Opera",me="OPPO",re="Samsung",xe="Sharp",ie="Sony",pe="Xiaomi",we="Zebra",Ee="Facebook",Ae="Chromium OS",Pe="Mac OS",Te=" Browser",We=function(w,g){var b={};for(var k in w)g[k]&&g[k].length%2===0?b[k]=g[k].concat(w[k]):b[k]=w[k];return b},ue=function(w){for(var g={},b=0;b<w.length;b++)g[w[b].toUpperCase()]=w[b];return g},Re=function(w,g){return typeof w===P?oe(g).indexOf(oe(w))!==-1:!1},oe=function(w){return w.toLowerCase()},$e=function(w){return typeof w===P?w.replace(/[^\d\.]/g,v).split(".")[0]:s},ge=function(w,g){if(typeof w===P)return w=w.replace(/^\s\s*/,v),typeof g===y?w:w.substring(0,te)},ae=function(w,g){for(var b=0,k,j,M,f,u,z;b<g.length&&!u;){var fe=g[b],Ie=g[b+1];for(k=j=0;k<fe.length&&!u&&fe[k];)if(u=fe[k++].exec(w),u)for(M=0;M<Ie.length;M++)z=u[++j],f=Ie[M],typeof f===N&&f.length>0?f.length===2?typeof f[1]==I?this[f[0]]=f[1].call(this,z):this[f[0]]=f[1]:f.length===3?typeof f[1]===I&&!(f[1].exec&&f[1].test)?this[f[0]]=z?f[1].call(this,z,f[2]):s:this[f[0]]=z?z.replace(f[1],f[2]):s:f.length===4&&(this[f[0]]=z?f[3].call(this,z.replace(f[1],f[2])):s):this[f]=z||s;b+=2}},ne=function(w,g){for(var b in g)if(typeof g[b]===N&&g[b].length>0){for(var k=0;k<g[b].length;k++)if(Re(g[b][k],w))return b===m?s:b}else if(Re(g[b],w))return b===m?s:b;return g.hasOwnProperty("*")?g["*"]:w},Ge={"1.0":"/8","1.2":"/1","1.3":"/3","2.0":"/412","2.0.2":"/416","2.0.3":"/417","2.0.4":"/419","?":"/"},Se={ME:"4.90","NT 3.11":"NT3.51","NT 4.0":"NT4.0",2e3:"NT 5.0",XP:["NT 5.1","NT 5.2"],Vista:"NT 6.0",7:"NT 6.1",8:"NT 6.2","8.1":"NT 6.3",10:["NT 6.4","NT 10.0"],RT:"ARM"},Oe={browser:[[/\b(?:crmo|crios)\/([\w\.]+)/i],[i,[o,"Chrome"]],[/edg(?:e|ios|a)?\/([\w\.]+)/i],[i,[o,"Edge"]],[/(opera mini)\/([-\w\.]+)/i,/(opera [mobiletab]{3,6})\b.+version\/([-\w\.]+)/i,/(opera)(?:.+version\/|[\/ ]+)([\w\.]+)/i],[o,i],[/opios[\/ ]+([\w\.]+)/i],[i,[o,K+" Mini"]],[/\bop(?:rg)?x\/([\w\.]+)/i],[i,[o,K+" GX"]],[/\bopr\/([\w\.]+)/i],[i,[o,K]],[/\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\/ ]?([\w\.]+)/i],[i,[o,"Baidu"]],[/\b(?:mxbrowser|mxios|myie2)\/?([-\w\.]*)\b/i],[i,[o,"Maxthon"]],[/(kindle)\/([\w\.]+)/i,/(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\/ ]?([\w\.]*)/i,/(avant|iemobile|slim(?:browser|boat|jet))[\/ ]?([\d\.]*)/i,/(?:ms|\()(ie) ([\w\.]+)/i,/(flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi|iridium|phantomjs|bowser|qupzilla|falkon|rekonq|puffin|brave|whale(?!.+naver)|qqbrowserlite|duckduckgo|klar|helio|(?=comodo_)?dragon)\/([-\w\.]+)/i,/(heytap|ovi|115)browser\/([\d\.]+)/i,/(weibo)__([\d\.]+)/i],[o,i],[/quark(?:pc)?\/([-\w\.]+)/i],[i,[o,"Quark"]],[/\bddg\/([\w\.]+)/i],[i,[o,"DuckDuckGo"]],[/(?:\buc? ?browser|(?:juc.+)ucweb)[\/ ]?([\w\.]+)/i],[i,[o,"UC"+c]],[/microm.+\bqbcore\/([\w\.]+)/i,/\bqbcore\/([\w\.]+).+microm/i,/micromessenger\/([\w\.]+)/i],[i,[o,"WeChat"]],[/konqueror\/([\w\.]+)/i],[i,[o,"Konqueror"]],[/trident.+rv[: ]([\w\.]{1,9})\b.+like gecko/i],[i,[o,"IE"]],[/ya(?:search)?browser\/([\w\.]+)/i],[i,[o,"Yandex"]],[/slbrowser\/([\w\.]+)/i],[i,[o,"Smart Lenovo "+c]],[/(avast|avg)\/([\w\.]+)/i],[[o,/(.+)/,"$1 Secure "+c],i],[/\bfocus\/([\w\.]+)/i],[i,[o,E+" Focus"]],[/\bopt\/([\w\.]+)/i],[i,[o,K+" Touch"]],[/coc_coc\w+\/([\w\.]+)/i],[i,[o,"Coc Coc"]],[/dolfin\/([\w\.]+)/i],[i,[o,"Dolphin"]],[/coast\/([\w\.]+)/i],[i,[o,K+" Coast"]],[/miuibrowser\/([\w\.]+)/i],[i,[o,"MIUI"+Te]],[/fxios\/([\w\.-]+)/i],[i,[o,E]],[/\bqihoobrowser\/?([\w\.]*)/i],[i,[o,"360"]],[/\b(qq)\/([\w\.]+)/i],[[o,/(.+)/,"$1Browser"],i],[/(oculus|sailfish|huawei|vivo|pico)browser\/([\w\.]+)/i],[[o,/(.+)/,"$1"+Te],i],[/samsungbrowser\/([\w\.]+)/i],[i,[o,re+" Internet"]],[/metasr[\/ ]?([\d\.]+)/i],[i,[o,"Sogou Explorer"]],[/(sogou)mo\w+\/([\d\.]+)/i],[[o,"Sogou Mobile"],i],[/(electron)\/([\w\.]+) safari/i,/(tesla)(?: qtcarbrowser|\/(20\d\d\.[-\w\.]+))/i,/m?(qqbrowser|2345(?=browser|chrome|explorer))\w*[\/ ]?v?([\w\.]+)/i],[o,i],[/(lbbrowser|rekonq)/i,/\[(linkedin)app\]/i],[o],[/ome\/([\w\.]+) \w* ?(iron) saf/i,/ome\/([\w\.]+).+qihu (360)[es]e/i],[i,o],[/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i],[[o,Ee],i],[/(Klarna)\/([\w\.]+)/i,/(kakao(?:talk|story))[\/ ]([\w\.]+)/i,/(naver)\(.*?(\d+\.[\w\.]+).*\)/i,/(daum)apps[\/ ]([\w\.]+)/i,/safari (line)\/([\w\.]+)/i,/\b(line)\/([\w\.]+)\/iab/i,/(alipay)client\/([\w\.]+)/i,/(twitter)(?:and| f.+e\/([\w\.]+))/i,/(chromium|instagram|snapchat)[\/ ]([-\w\.]+)/i],[o,i],[/\bgsa\/([\w\.]+) .*safari\//i],[i,[o,"GSA"]],[/musical_ly(?:.+app_?version\/|_)([\w\.]+)/i],[i,[o,"TikTok"]],[/headlesschrome(?:\/([\w\.]+)| )/i],[i,[o,h+" Headless"]],[/ wv\).+(chrome)\/([\w\.]+)/i],[[o,h+" WebView"],i],[/droid.+ version\/([\w\.]+)\b.+(?:mobile safari|safari)/i],[i,[o,"Android "+c]],[/(chrome|omniweb|arora|[tizenoka]{5} ?browser)\/v?([\w\.]+)/i],[o,i],[/version\/([\w\.\,]+) .*mobile\/\w+ (safari)/i],[i,[o,"Mobile Safari"]],[/version\/([\w(\.|\,)]+) .*(mobile ?safari|safari)/i],[i,o],[/webkit.+?(mobile ?safari|safari)(\/[\w\.]+)/i],[o,[i,ne,Ge]],[/(webkit|khtml)\/([\w\.]+)/i],[o,i],[/(navigator|netscape\d?)\/([-\w\.]+)/i],[[o,"Netscape"],i],[/(wolvic|librewolf)\/([\w\.]+)/i],[o,i],[/mobile vr; rv:([\w\.]+)\).+firefox/i],[i,[o,E+" Reality"]],[/ekiohf.+(flow)\/([\w\.]+)/i,/(swiftfox)/i,/(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\/ ]?([\w\.\+]+)/i,/(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\/([-\w\.]+)$/i,/(firefox)\/([\w\.]+)/i,/(mozilla)\/([\w\.]+) .+rv\:.+gecko\/\d+/i,/(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\. ]?browser)[-\/ ]?v?([\w\.]+)/i,/\b(links) \(([\w\.]+)/i],[o,[i,/_/g,"."]],[/(cobalt)\/([\w\.]+)/i],[o,[i,/master.|lts./,""]]],cpu:[[/\b((amd|x|x86[-_]?|wow|win)64)\b/i],[[A,"amd64"]],[/(ia32(?=;))/i,/\b((i[346]|x)86)(pc)?\b/i],[[A,"ia32"]],[/\b(aarch64|arm(v?[89]e?l?|_?64))\b/i],[[A,"arm64"]],[/\b(arm(v[67])?ht?n?[fl]p?)\b/i],[[A,"armhf"]],[/( (ce|mobile); ppc;|\/[\w\.]+arm\b)/i],[[A,"arm"]],[/((ppc|powerpc)(64)?)( mac|;|\))/i],[[A,/ower/,v,oe]],[/ sun4\w[;\)]/i],[[A,"sparc"]],[/\b(avr32|ia64(?=;)|68k(?=\))|\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\b|pa-risc)/i],[[A,oe]]],device:[[/\b(sch-i[89]0\d|shw-m380s|sm-[ptx]\w{2,4}|gt-[pn]\d{2,4}|sgh-t8[56]9|nexus 10)/i],[e,[r,re],[t,l]],[/\b((?:s[cgp]h|gt|sm)-(?![lr])\w+|sc[g-]?[\d]+a?|galaxy nexus)/i,/samsung[- ]((?!sm-[lr])[-\w]+)/i,/sec-(sgh\w+)/i],[e,[r,re],[t,d]],[/(?:\/|\()(ip(?:hone|od)[\w, ]*)(?:\/|;)/i],[e,[r,H],[t,d]],[/\((ipad);[-\w\),; ]+apple/i,/applecoremedia\/[\w\.]+ \((ipad)/i,/\b(ipad)\d\d?,\d\d?[;\]].+ios/i],[e,[r,H],[t,l]],[/(macintosh);/i],[e,[r,H]],[/\b(sh-?[altvz]?\d\d[a-ekm]?)/i],[e,[r,xe],[t,d]],[/\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\)|;)/i],[e,[r,U],[t,l]],[/honor([-\w ]+)[;\)]/i],[e,[r,U],[t,d]],[/\b((?:ag[rs][2356]?k?|bah[234]?|bg[2o]|bt[kv]|cmr|cpn|db[ry]2?|jdn2|got|kob2?k?|mon|pce|scm|sht?|[tw]gr|vrd)-[ad]?[lw][0125][09]b?|605hw|bg2-u03|(?:gem|fdr|m2|ple|t1)-[7a]0[1-4][lu]|t1-a2[13][lw]|mediapad[\w\. ]*(?= bui|\)))\b(?!.+d\/s)/i],[e,[r,_],[t,l]],[/(?:huawei)([-\w ]+)[;\)]/i,/\b(nexus 6p|\w{2,4}e?-[atu]?[ln][\dx][012359c][adn]?)\b(?!.+d\/s)/i],[e,[r,_],[t,d]],[/oid[^\)]+; (2[\dbc]{4}(182|283|rp\w{2})[cgl]|m2105k81a?c)(?: bui|\))/i,/\b((?:red)?mi[-_ ]?pad[\w- ]*)(?: bui|\))/i],[[e,/_/g," "],[r,pe],[t,l]],[/\b(poco[\w ]+|m2\d{3}j\d\d[a-z]{2})(?: bui|\))/i,/\b; (\w+) build\/hm\1/i,/\b(hm[-_ ]?note?[_ ]?(?:\d\w)?) bui/i,/\b(redmi[\-_ ]?(?:note|k)?[\w_ ]+)(?: bui|\))/i,/oid[^\)]+; (m?[12][0-389][01]\w{3,6}[c-y])( bui|; wv|\))/i,/\b(mi[-_ ]?(?:a\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\d?\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\))/i,/ ([\w ]+) miui\/v?\d/i],[[e,/_/g," "],[r,pe],[t,d]],[/; (\w+) bui.+ oppo/i,/\b(cph[12]\d{3}|p(?:af|c[al]|d\w|e[ar])[mt]\d0|x9007|a101op)\b/i],[e,[r,me],[t,d]],[/\b(opd2(\d{3}a?))(?: bui|\))/i],[e,[r,ne,{OnePlus:["304","403","203"],"*":me}],[t,l]],[/vivo (\w+)(?: bui|\))/i,/\b(v[12]\d{3}\w?[at])(?: bui|;)/i],[e,[r,"Vivo"],[t,d]],[/\b(rmx[1-3]\d{3})(?: bui|;|\))/i],[e,[r,"Realme"],[t,d]],[/\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\b[\w ]+build\//i,/\bmot(?:orola)?[- ](\w*)/i,/((?:moto(?! 360)[\w\(\) ]+|xt\d{3,4}|nexus 6)(?= bui|\)))/i],[e,[r,F],[t,d]],[/\b(mz60\d|xoom[2 ]{0,2}) build\//i],[e,[r,F],[t,l]],[/((?=lg)?[vl]k\-?\d{3}) bui| 3\.[-\w; ]{10}lg?-([06cv9]{3,4})/i],[e,[r,q],[t,l]],[/(lm(?:-?f100[nv]?|-[\w\.]+)(?= bui|\))|nexus [45])/i,/\blg[-e;\/ ]+((?!browser|netcast|android tv|watch)\w+)/i,/\blg-?([\d\w]+) bui/i],[e,[r,q],[t,d]],[/(ideatab[-\w ]+|602lv|d-42a|a101lv|a2109a|a3500-hv|s[56]000|pb-6505[my]|tb-?x?\d{3,4}(?:f[cu]|xu|[av])|yt\d?-[jx]?\d+[lfmx])( bui|;|\)|\/)/i,/lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\w- ]+?)|tb[\w-]{6,7})( bui|;|\)|\/)/i],[e,[r,T],[t,l]],[/(nokia) (t[12][01])/i],[r,e,[t,l]],[/(?:maemo|nokia).*(n900|lumia \d+|rm-\d+)/i,/nokia[-_ ]?(([-\w\. ]*))/i],[[e,/_/g," "],[t,d],[r,"Nokia"]],[/(pixel (c|tablet))\b/i],[e,[r,C],[t,l]],[/droid.+; (pixel[\daxl ]{0,6})(?: bui|\))/i],[e,[r,C],[t,d]],[/droid.+; (a?\d[0-2]{2}so|[c-g]\d{4}|so[-gl]\w+|xq-a\w[4-7][12])(?= bui|\).+chrome\/(?![1-6]{0,1}\d\.))/i],[e,[r,ie],[t,d]],[/sony tablet [ps]/i,/\b(?:sony)?sgp\w+(?: bui|\))/i],[[e,"Xperia Tablet"],[r,ie],[t,l]],[/ (kb2005|in20[12]5|be20[12][59])\b/i,/(?:one)?(?:plus)? (a\d0\d\d)(?: b|\))/i],[e,[r,W],[t,d]],[/(alexa)webm/i,/(kf[a-z]{2}wi|aeo(?!bc)\w\w)( bui|\))/i,/(kf[a-z]+)( bui|\)).+silk\//i],[e,[r,Q],[t,l]],[/((?:sd|kf)[0349hijorstuw]+)( bui|\)).+silk\//i],[[e,/(.+)/g,"Fire Phone $1"],[r,Q],[t,d]],[/(playbook);[-\w\),; ]+(rim)/i],[e,r,[t,l]],[/\b((?:bb[a-f]|st[hv])100-\d)/i,/\(bb10; (\w+)/i],[e,[r,n],[t,d]],[/(?:\b|asus_)(transfo[prime ]{4,10} \w+|eeepc|slider \w+|nexus 7|padfone|p00[cj])/i],[e,[r,ce],[t,l]],[/ (z[bes]6[027][012][km][ls]|zenfone \d\w?)\b/i],[e,[r,ce],[t,d]],[/(nexus 9)/i],[e,[r,"HTC"],[t,l]],[/(htc)[-;_ ]{1,2}([\w ]+(?=\)| bui)|\w+)/i,/(zte)[- ]([\w ]+?)(?: bui|\/|\))/i,/(alcatel|geeksphone|nexian|panasonic(?!(?:;|\.))|sony(?!-bra))[-_ ]?([-\w]*)/i],[r,[e,/_/g," "],[t,d]],[/droid [\w\.]+; ((?:8[14]9[16]|9(?:0(?:48|60|8[01])|1(?:3[27]|66)|2(?:6[69]|9[56])|466))[gqswx])\w*(\)| bui)/i],[e,[r,"TCL"],[t,l]],[/(itel) ((\w+))/i],[[r,oe],e,[t,ne,{tablet:["p10001l","w7001"],"*":"mobile"}]],[/droid.+; ([ab][1-7]-?[0178a]\d\d?)/i],[e,[r,"Acer"],[t,l]],[/droid.+; (m[1-5] note) bui/i,/\bmz-([-\w]{2,})/i],[e,[r,"Meizu"],[t,d]],[/; ((?:power )?armor(?:[\w ]{0,8}))(?: bui|\))/i],[e,[r,"Ulefone"],[t,d]],[/; (energy ?\w+)(?: bui|\))/i,/; energizer ([\w ]+)(?: bui|\))/i],[e,[r,"Energizer"],[t,d]],[/; cat (b35);/i,/; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\))/i],[e,[r,"Cat"],[t,d]],[/((?:new )?andromax[\w- ]+)(?: bui|\))/i],[e,[r,"Smartfren"],[t,d]],[/droid.+; (a(?:015|06[35]|142p?))/i],[e,[r,"Nothing"],[t,d]],[/; (x67 5g|tikeasy \w+|ac[1789]\d\w+)( b|\))/i,/archos ?(5|gamepad2?|([\w ]*[t1789]|hello) ?\d+[\w ]*)( b|\))/i],[e,[r,"Archos"],[t,l]],[/archos ([\w ]+)( b|\))/i,/; (ac[3-6]\d\w{2,8})( b|\))/i],[e,[r,"Archos"],[t,d]],[/(imo) (tab \w+)/i,/(infinix) (x1101b?)/i],[r,e,[t,l]],[/(blackberry|benq|palm(?=\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\w]*)/i,/; (hmd|imo) ([\w ]+?)(?: bui|\))/i,/(hp) ([\w ]+\w)/i,/(microsoft); (lumia[\w ]+)/i,/(lenovo)[-_ ]?([-\w ]+?)(?: bui|\)|\/)/i,/(oppo) ?([\w ]+) bui/i],[r,e,[t,d]],[/(kobo)\s(ereader|touch)/i,/(hp).+(touchpad(?!.+tablet)|tablet)/i,/(kindle)\/([\w\.]+)/i,/(nook)[\w ]+build\/(\w+)/i,/(dell) (strea[kpr\d ]*[\dko])/i,/(le[- ]+pan)[- ]+(\w{1,9}) bui/i,/(trinity)[- ]*(t\d{3}) bui/i,/(gigaset)[- ]+(q\w{1,9}) bui/i,/(vodafone) ([\w ]+)(?:\)| bui)/i],[r,e,[t,l]],[/(surface duo)/i],[e,[r,X],[t,l]],[/droid [\d\.]+; (fp\du?)(?: b|\))/i],[e,[r,"Fairphone"],[t,d]],[/(u304aa)/i],[e,[r,"AT&T"],[t,d]],[/\bsie-(\w*)/i],[e,[r,"Siemens"],[t,d]],[/\b(rct\w+) b/i],[e,[r,"RCA"],[t,l]],[/\b(venue[\d ]{2,7}) b/i],[e,[r,"Dell"],[t,l]],[/\b(q(?:mv|ta)\w+) b/i],[e,[r,"Verizon"],[t,l]],[/\b(?:barnes[& ]+noble |bn[rt])([\w\+ ]*) b/i],[e,[r,"Barnes & Noble"],[t,l]],[/\b(tm\d{3}\w+) b/i],[e,[r,"NuVision"],[t,l]],[/\b(k88) b/i],[e,[r,"ZTE"],[t,l]],[/\b(nx\d{3}j) b/i],[e,[r,"ZTE"],[t,d]],[/\b(gen\d{3}) b.+49h/i],[e,[r,"Swiss"],[t,d]],[/\b(zur\d{3}) b/i],[e,[r,"Swiss"],[t,l]],[/\b((zeki)?tb.*\b) b/i],[e,[r,"Zeki"],[t,l]],[/\b([yr]\d{2}) b/i,/\b(dragon[- ]+touch |dt)(\w{5}) b/i],[[r,"Dragon Touch"],e,[t,l]],[/\b(ns-?\w{0,9}) b/i],[e,[r,"Insignia"],[t,l]],[/\b((nxa|next)-?\w{0,9}) b/i],[e,[r,"NextBook"],[t,l]],[/\b(xtreme\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i],[[r,"Voice"],e,[t,d]],[/\b(lvtel\-)?(v1[12]) b/i],[[r,"LvTel"],e,[t,d]],[/\b(ph-1) /i],[e,[r,"Essential"],[t,d]],[/\b(v(100md|700na|7011|917g).*\b) b/i],[e,[r,"Envizen"],[t,l]],[/\b(trio[-\w\. ]+) b/i],[e,[r,"MachSpeed"],[t,l]],[/\btu_(1491) b/i],[e,[r,"Rotor"],[t,l]],[/((?:tegranote|shield t(?!.+d tv))[\w- ]*?)(?: b|\))/i],[e,[r,V],[t,l]],[/(sprint) (\w+)/i],[r,e,[t,d]],[/(kin\.[onetw]{3})/i],[[e,/\./g," "],[r,X],[t,d]],[/droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\)/i],[e,[r,we],[t,l]],[/droid.+; (ec30|ps20|tc[2-8]\d[kx])\)/i],[e,[r,we],[t,d]],[/smart-tv.+(samsung)/i],[r,[t,S]],[/hbbtv.+maple;(\d+)/i],[[e,/^/,"SmartTV"],[r,re],[t,S]],[/(nux; netcast.+smarttv|lg (netcast\.tv-201\d|android tv))/i],[[r,q],[t,S]],[/(apple) ?tv/i],[r,[e,H+" TV"],[t,S]],[/crkey/i],[[e,h+"cast"],[r,C],[t,S]],[/droid.+aft(\w+)( bui|\))/i],[e,[r,Q],[t,S]],[/(shield \w+ tv)/i],[e,[r,V],[t,S]],[/\(dtv[\);].+(aquos)/i,/(aquos-tv[\w ]+)\)/i],[e,[r,xe],[t,S]],[/(bravia[\w ]+)( bui|\))/i],[e,[r,ie],[t,S]],[/(mi(tv|box)-?\w+) bui/i],[e,[r,pe],[t,S]],[/Hbbtv.*(technisat) (.*);/i],[r,e,[t,S]],[/\b(roku)[\dx]*[\)\/]((?:dvp-)?[\d\.]*)/i,/hbbtv\/\d+\.\d+\.\d+ +\([\w\+ ]*; *([\w\d][^;]*);([^;]*)/i],[[r,ge],[e,ge],[t,S]],[/droid.+; ([\w- ]+) (?:android tv|smart[- ]?tv)/i],[e,[t,S]],[/\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\b/i],[[t,S]],[/(ouya)/i,/(nintendo) ([wids3utch]+)/i],[r,e,[t,D]],[/droid.+; (shield)( bui|\))/i],[e,[r,V],[t,D]],[/(playstation \w+)/i],[e,[r,ie],[t,D]],[/\b(xbox(?: one)?(?!; xbox))[\); ]/i],[e,[r,X],[t,D]],[/\b(sm-[lr]\d\d[0156][fnuw]?s?|gear live)\b/i],[e,[r,re],[t,O]],[/((pebble))app/i,/(asus|google|lg|oppo) ((pixel |zen)?watch[\w ]*)( bui|\))/i],[r,e,[t,O]],[/(ow(?:19|20)?we?[1-3]{1,3})/i],[e,[r,me],[t,O]],[/(watch)(?: ?os[,\/]|\d,\d\/)[\d\.]+/i],[e,[r,H],[t,O]],[/(opwwe\d{3})/i],[e,[r,W],[t,O]],[/(moto 360)/i],[e,[r,F],[t,O]],[/(smartwatch 3)/i],[e,[r,ie],[t,O]],[/(g watch r)/i],[e,[r,q],[t,O]],[/droid.+; (wt63?0{2,3})\)/i],[e,[r,we],[t,O]],[/droid.+; (glass) \d/i],[e,[r,C],[t,O]],[/(pico) (4|neo3(?: link|pro)?)/i],[r,e,[t,O]],[/; (quest( \d| pro)?)/i],[e,[r,Ee],[t,O]],[/(tesla)(?: qtcarbrowser|\/[-\w\.]+)/i],[r,[t,Y]],[/(aeobc)\b/i],[e,[r,Q],[t,Y]],[/(homepod).+mac os/i],[e,[r,H],[t,Y]],[/windows iot/i],[[t,Y]],[/droid .+?; ([^;]+?)(?: bui|; wv\)|\) applew).+? mobile safari/i],[e,[t,d]],[/droid .+?; ([^;]+?)(?: bui|\) applew).+?(?! mobile) safari/i],[e,[t,l]],[/\b((tablet|tab)[;\/]|focus\/\d(?!.+mobile))/i],[[t,l]],[/(phone|mobile(?:[;\/]| [ \w\/\.]*safari)|pda(?=.+windows ce))/i],[[t,d]],[/droid .+?; ([\w\. -]+)( bui|\))/i],[e,[r,"Generic"]]],engine:[[/windows.+ edge\/([\w\.]+)/i],[i,[o,x+"HTML"]],[/(arkweb)\/([\w\.]+)/i],[o,i],[/webkit\/537\.36.+chrome\/(?!27)([\w\.]+)/i],[i,[o,"Blink"]],[/(presto)\/([\w\.]+)/i,/(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\/([\w\.]+)/i,/ekioh(flow)\/([\w\.]+)/i,/(khtml|tasman|links)[\/ ]\(?([\w\.]+)/i,/(icab)[\/ ]([23]\.[\d\.]+)/i,/\b(libweb)/i],[o,i],[/ladybird\//i],[[o,"LibWeb"]],[/rv\:([\w\.]{1,9})\b.+(gecko)/i],[i,o]],os:[[/microsoft (windows) (vista|xp)/i],[o,i],[/(windows (?:phone(?: os)?|mobile|iot))[\/ ]?([\d\.\w ]*)/i],[o,[i,ne,Se]],[/windows nt 6\.2; (arm)/i,/windows[\/ ]([ntce\d\. ]+\w)(?!.+xbox)/i,/(?:win(?=3|9|n)|win 9x )([nt\d\.]+)/i],[[i,ne,Se],[o,"Windows"]],[/[adehimnop]{4,7}\b(?:.*os ([\w]+) like mac|; opera)/i,/(?:ios;fbsv\/|iphone.+ios[\/ ])([\d\.]+)/i,/cfnetwork\/.+darwin/i],[[i,/_/g,"."],[o,"iOS"]],[/(mac os x) ?([\w\. ]*)/i,/(macintosh|mac_powerpc\b)(?!.+haiku)/i],[[o,Pe],[i,/_/g,"."]],[/droid ([\w\.]+)\b.+(android[- ]x86|harmonyos)/i],[i,o],[/(ubuntu) ([\w\.]+) like android/i],[[o,/(.+)/,"$1 Touch"],i],[/(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen|webos)\w*[-\/; ]?([\d\.]*)/i],[o,i],[/\(bb(10);/i],[i,[o,n]],[/(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\/ ]?([\w\.]*)/i],[i,[o,"Symbian"]],[/mozilla\/[\d\.]+ \((?:mobile|tablet|tv|mobile; [\w ]+); rv:.+ gecko\/([\w\.]+)/i],[i,[o,E+" OS"]],[/web0s;.+rt(tv)/i,/\b(?:hp)?wos(?:browser)?\/([\w\.]+)/i],[i,[o,"webOS"]],[/watch(?: ?os[,\/]|\d,\d\/)([\d\.]+)/i],[i,[o,"watchOS"]],[/crkey\/([\d\.]+)/i],[i,[o,h+"cast"]],[/(cros) [\w]+(?:\)| ([\w\.]+)\b)/i],[[o,Ae],i],[/panasonic;(viera)/i,/(netrange)mmh/i,/(nettv)\/(\d+\.[\w\.]+)/i,/(nintendo|playstation) ([wids345portablevuch]+)/i,/(xbox); +xbox ([^\);]+)/i,/\b(joli|palm)\b ?(?:os)?\/?([\w\.]*)/i,/(mint)[\/\(\) ]?(\w*)/i,/(mageia|vectorlinux)[; ]/i,/([kxln]?ubuntu|debian|suse|opensuse|gentoo|arch(?= linux)|slackware|fedora|mandriva|centos|pclinuxos|red ?hat|zenwalk|linpus|raspbian|plan 9|minix|risc os|contiki|deepin|manjaro|elementary os|sabayon|linspire)(?: gnu\/linux)?(?: enterprise)?(?:[- ]linux)?(?:-gnu)?[-\/ ]?(?!chrom|package)([-\w\.]*)/i,/(hurd|linux)(?: arm\w*| x86\w*| ?)([\w\.]*)/i,/(gnu) ?([\w\.]*)/i,/\b([-frentopcghs]{0,5}bsd|dragonfly)[\/ ]?(?!amd|[ix346]{1,2}86)([\w\.]*)/i,/(haiku) (\w+)/i],[o,i],[/(sunos) ?([\w\.\d]*)/i],[[o,"Solaris"],i],[/((?:open)?solaris)[-\/ ]?([\w\.]*)/i,/(aix) ((\d)(?=\.|\)| )[\w\.])*/i,/\b(beos|os\/2|amigaos|morphos|openvms|fuchsia|hp-ux|serenityos)/i,/(unix) ?([\w\.]*)/i],[o,i]]},L=function(w,g){if(typeof w===N&&(g=w,w=s),!(this instanceof L))return new L(w,g).getResult();var b=typeof a!==y&&a.navigator?a.navigator:s,k=w||(b&&b.userAgent?b.userAgent:v),j=b&&b.userAgentData?b.userAgentData:s,M=g?We(Oe,g):Oe,f=b&&b.userAgent==k;return this.getBrowser=function(){var u={};return u[o]=s,u[i]=s,ae.call(u,k,M.browser),u[ee]=$e(u[i]),f&&b&&b.brave&&typeof b.brave.isBrave==I&&(u[o]="Brave"),u},this.getCPU=function(){var u={};return u[A]=s,ae.call(u,k,M.cpu),u},this.getDevice=function(){var u={};return u[r]=s,u[e]=s,u[t]=s,ae.call(u,k,M.device),f&&!u[t]&&j&&j.mobile&&(u[t]=d),f&&u[e]=="Macintosh"&&b&&typeof b.standalone!==y&&b.maxTouchPoints&&b.maxTouchPoints>2&&(u[e]="iPad",u[t]=l),u},this.getEngine=function(){var u={};return u[o]=s,u[i]=s,ae.call(u,k,M.engine),u},this.getOS=function(){var u={};return u[o]=s,u[i]=s,ae.call(u,k,M.os),f&&!u[o]&&j&&j.platform&&j.platform!="Unknown"&&(u[o]=j.platform.replace(/chrome os/i,Ae).replace(/macos/i,Pe)),u},this.getResult=function(){return{ua:this.getUA(),browser:this.getBrowser(),engine:this.getEngine(),os:this.getOS(),device:this.getDevice(),cpu:this.getCPU()}},this.getUA=function(){return k},this.setUA=function(u){return k=typeof u===P&&u.length>te?ge(u,te):u,this},this.setUA(k),this};L.VERSION=p,L.BROWSER=ue([o,i,ee]),L.CPU=ue([A]),L.DEVICE=ue([e,r,t,D,d,S,l,O,Y]),L.ENGINE=L.OS=ue([o,i]),typeof se!==y?(typeof be!==y&&be.exports&&(se=be.exports=L),se.UAParser=L):typeof define===I&&define.amd?define(function(){return L}):typeof a!==y&&(a.UAParser=L);var Z=typeof a!==y&&(a.jQuery||a.Zepto);if(Z&&!Z.ua){var de=new L;Z.ua=de.getResult(),Z.ua.get=function(){return de.getUA()},Z.ua.set=function(w){de.setUA(w);var g=de.getResult();for(var b in g)Z.ua[b]=g[b]}}})(typeof window=="object"?window:se)});import Le from"react";var ye=Le.createContext(null);function dt(){let a=Le.useContext(ye);if(a===null)throw new Error("useElevateConfig must be used within ElevateProvider");return a}var ke=Xe(Ue(),1),qe={"facebook.com":"Facebook","fb.me":"Facebook","m.facebook.com":"Facebook","l.facebook.com":"Facebook","lm.facebook.com":"Facebook","instagram.com":"Instagram","l.instagram.com":"Instagram","youtube.com":"Youtube","youtu.be":"Youtube","m.youtube.com":"Youtube","bing.com":"Bing","www.bing.com":"Bing","msnbc.msn.com":"Bing","dizionario.it.msn.com":"Bing","cc.bingj.com":"Bing","m.bing.com":"Bing","twitter.com":"Twitter","t.co":"Twitter"};function B(a){return typeof a!="string"?String(a):a.replace(/[\\"'`\x00-\x1F\x7F]/g,"")}function R(a){if(a==null)return null;let s=typeof a=="string"?parseFloat(a):Number(a);return isNaN(s)?null:+(Math.round(+(s+"e2"))+"e-2")}function $(a){if(!a)return null;let s=/gid:\/\/shopify\/Product\/(\d+)/,p=a.match(s);return p?p[1]:null}function J(a){if(!a)return null;let s=/gid:\/\/shopify\/ProductVariant\/(\d+)/,p=a.match(s);return p?p[1]:null}function Me(a){if(!a)return null;let s=/gid:\/\/shopify\/Cart\/([^?]+(\?.+)?)/,p=a.match(s);return p?p[1]:null}function ze(a){try{return typeof a!="string"?null:decodeURIComponent(a).split("?")[0]}catch{return a||null}}function Ke(a){return/((?:fban\/fbios|fb_iab\/fb4a)(?!.+fbav)|;fbav\/([\w\.]+);)/i.test(a)}function Qe(a){return/(instagram)[\/ ]([-\w\.]+)/i.test(a)}function bt(a){return Ke(a)||Qe(a)}function Ze(a){if(!a)return"";switch(a){case"Mobile Safari":return"Safari";case"Chrome Mobile":case"Chrome Mobile iOS":return"Chrome";case"Firefox Mobile":case"Firefox Mobile iOS":return"Firefox";case"Opera Mobile":case"Opera Mini":case"Opera Mini iOS":return"Opera";case"Yandex Browser Lite":return"Yandex Browser";case"Chrome Webview":case"Mobile App":return"Mobile App";default:return a}}function Je(a){let s={};return a.searchParams.forEach((p,v)=>{s[v]||(s[v]=p)}),s}function et(a){return!!a.host&&["http:","https:"].includes(a.protocol)}function tt(a){return a.replace(/^www\./,"")}function rt(a,s,p){if(s&&{Facebook:"Facebook",Instagram:"Instagram"}[s])return s;let m,I;try{if(a&&a.trim()!=="")m=new URL(a);else return"Direct";if(m?.hostname&&et(m)){if(I=m.hostname,p&&p===I)return"Direct"}else return""}catch{}if(!I)return"";let y=tt(I);return y?qe[y]?qe[y]:y?.includes("google")?"Google":y:""}function Fe(a){let{referrer:s,entryPage:p,userAgent:v}=a,m={referrer_source:"",browser_info:"",os_info:"",device_type:"",page_entry_path:"",utm_medium:"",utm_source:"",utm_campaign:"",utm_content:"",utm_term:"",referrer_url:s||"",gclid:"",fbclid:"",pins_campaign_id:"",epik:""};try{let I;if(p&&p.trim()!==""&&p.startsWith("http"))try{let y=new URL(p),N=y?.pathname;I=y?.hostname,N&&(m.page_entry_path=N??"");let P=Je(y);m.utm_medium=P.utm_medium??"",m.utm_source=P.utm_source??"",m.utm_campaign=P.utm_campaign??"",m.utm_content=P.utm_content??"",m.utm_term=P.utm_term??"",m.gclid=P.gclid??"",m.fbclid=P.fbclid??"",m.pins_campaign_id=P.pins_campaign_id??"",m.epik=P.epik??""}catch{}if(v){let y=(0,ke.UAParser)(v),N=y?.browser?.name,P=Ze(N);m.browser_info=P??"",m.os_info=y?.os?.name??"",v&&(m.device_type=(y?.device?.type||"desktop")?.toUpperCase()??"")}return m.referrer_source=rt(s,m?.browser_info,I)??"",m}catch{return m}}function Ve(a,s){let p=a==="/"||a==="",m=s&&/^\/[a-z]{2}(-[a-z]{2})?\/?$/i.test(a);return p||m?"index":/\/products\//.test(a)?"product":/\/collections\//.test(a)?"collection":/\/pages\//.test(a)?"page":/\/search/.test(a)?"search":/\/cart/.test(a)?"cart":/\/checkouts\//.test(a)?"checkout":"unknown"}function mt(a){try{return a&&new URLSearchParams(a).get("eabUserId")||!1}catch{return!1}}function je(a){if(!a)return"";try{let s=(0,ke.UAParser)(a),p=s?.os,v=s?.device,m="";return p?.name&&(m+=p.name,p.version&&(m+=` ${p.version}`)),v?.type&&(m+=m?` (${v.type})`:v.type),v?.vendor&&(m+=m?` ${v.vendor}`:v.vendor),v?.model&&(m+=m?` ${v.model}`:v.model),m||a}catch{return a}}import{useEffect as He,useContext as it,useRef as ot}from"react";var at="https://bitter-river-9c62.support-67d.workers.dev",nt="https://d339co84ntxcme.cloudfront.net/Prod/orders";function G(){return`sh-${Ce()}`}function st(a){return Object.entries(a).filter(([,s])=>typeof s=="string").map(([s,p])=>({test_id:s,variant_id:p}))}function ct(a,s){return Object.entries(a).filter(([p])=>typeof s[p]=="string").map(([p])=>({test_id:p,variant_id:s[p]}))}function kt({storeId:a,storefrontAccessToken:s,hasLocalizedPaths:p,workerUrl:v=at,ordersWorkerUrl:m=nt,useAnalytics:I}){let y=it(ye),N=a||y?.storeId||"",P=s||y?.storefrontAccessToken,ee=ot(!1);He(()=>{!y&&!a&&!ee.current&&(ee.current=!0,console.error("[ElevateAB] ElevateAnalytics must be used inside ElevateProvider, or you must pass storeId as a prop."))},[y,a]);let{subscribe:e,register:o}=I(),{ready:t}=o("Elevate Analytics");return He(()=>{if(typeof window>"u")return;if(_e(),ve(),typeof document<"u"){let i=document.referrer||"",A=window.location.href;Be(i,A)}(()=>{let i=n=>{let c=$(n.products?.[0]?.id);c&&typeof localStorage<"u"?localStorage.setItem("eabProductPageId",c):typeof window<"u"&&!window.location.pathname.includes("/products/")&&localStorage?.removeItem("eabProductPageId");let h=Me(typeof localStorage<"u"?localStorage.getItem("shopifyCartId"):null),{referrer:x,entryPage:E}=Ne();return{visitorId:_e(),sessionId:ve(),cartToken:h||le("cart")||"",referrer:x,entryPage:E,clientId:le("_shopify_y"),rootRoute:typeof localStorage<"u"&&localStorage.getItem("eabRootRoute")||"",productPageId:typeof localStorage<"u"&&localStorage.getItem("eabProductPageId")||""}},A=(n,c,h,x)=>{let E=typeof navigator<"u"?navigator.userAgent:"",C=h?.url?new URL(h.url).pathname:typeof window<"u"?window.location.pathname:"",U=Ve(C,p),_=Fe({referrer:x.referrer,entryPage:x.entryPage,userAgent:E}),T=he("ABTL")||{},q=he("ABAU")||{},X=st(T),F=ct(q,T),V=new Date().toISOString(),W=typeof sessionStorage<"u"?sessionStorage.getItem("eabIsFirstVisit")==="true":!1,K=le("localization")||"";return{pixel_event_id:c,shop_name:N,timestamp:V,event_type:n,client_id:x.clientId,visitor_id:x.visitorId,session_id:x.sessionId,cart_token:ze(x.cartToken),page_url:h.context?.document?.location?.href||(typeof window<"u"?window.location.href:""),page_pathname:C,page_search:h.context?.document?.location?.search||(typeof window<"u"?window.location.search:""),referrer_url:x.referrer,referrer_source:_?.referrer_source,previous_page:typeof document<"u"?document.referrer:"",page_entry:x.entryPage,page_entry_path:_?.page_entry_path,page_type:U,utm_medium:_?.utm_medium,utm_source:_?.utm_source,utm_campaign:_?.utm_campaign,utm_content:_?.utm_content,utm_term:_?.utm_term,gclid:_?.gclid,fbclid:_?.fbclid,pins_campaign_id:_?.pins_campaign_id,epik:_?.epik,browser_info:_?.browser_info,os_info:_?.os_info,device_type:_?.device_type,language:h.context?.navigator?.language||(typeof navigator<"u"?navigator.language:""),root_route:x.rootRoute,user_agent:E,user_agent_no_browser:je(E),is_first_visit:W,shopify_country:K,cart_currency:h.shop?.currency,ab_test_assignments:X,ab_test_views:F,is_first_order:null}},D=async n=>{if(!n.exclude)try{let c=await fetch(v,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),keepalive:!0});if(!c.ok)throw new Error(`Worker error: ${c.status}`);return c}catch(c){console.error("[ElevateAB] Error sending analytics:",c)}},d=async n=>{try{let c=i(n),h=G(),x=A("page_viewed",h,n,c);await D(x)}catch(c){console.error("[ElevateAB] Error handling page_viewed:",c)}},l=async n=>{try{let c=i(n),h=G(),E={...A("product_viewed",h,n,c),product_id:$(n?.products?.[0]?.id)||"",product_vendor:B(n?.products?.[0]?.vendor)??"",product_price:R(n?.products?.[0]?.price)??null,product_sku:B(n?.products?.[0]?.sku)??""};await D(E)}catch(c){console.error("[ElevateAB] Error handling product_viewed:",c)}},S=async n=>{try{let c=i(n),h=G(),E={...A("product_added_to_cart",h,n,c),product_id:$(n?.currentLine?.merchandise?.product?.id)??"",variant_id:J(n?.currentLine?.merchandise?.id)??"",product_vendor:B(n?.currentLine?.merchandise?.product?.vendor)??"",product_price:R(n?.currentLine?.cost?.totalAmount?.amount)??null,product_quantity:n?.currentLine?.quantity??null,product_sku:B(n?.currentLine?.merchandise?.sku)??""};await D(E);let C=n?.cart?.id;C&&P&&N&&De(C,{storefrontAccessToken:P,storefrontApiUrl:`https://${N}/api/2025-01/graphql.json`}).catch(U=>{console.error("[ElevateAB] Failed to update cart attributes:",U)})}catch(c){console.error("[ElevateAB] Error handling product_added_to_cart:",c)}},O=async n=>{try{let c=i(n),h=G(),E={...A("product_removed_from_cart",h,n,c),product_id:$(n?.prevLine?.merchandise?.product?.id)??"",variant_id:J(n?.prevLine?.merchandise?.id)??"",product_vendor:B(n?.prevLine?.merchandise?.product?.vendor)??"",product_price:R(n?.prevLine?.cost?.totalAmount?.amount)??null,product_quantity:n?.prevLine?.quantity??null,product_sku:B(n?.prevLine?.merchandise?.sku)??""};await D(E)}catch(c){console.error("[ElevateAB] Error handling product_removed_from_cart:",c)}},Y=async n=>{try{let c=i(n),h=G(),x=A("cart_viewed",h,n,c),C=(n?.data?.cart?.lines?.nodes||n?.data?.cart?.lines||[]).map(_=>({product_id:$(_?.merchandise?.product?.id)??"",variant_id:J(_?.merchandise?.id)??"",vendor:B(_?.merchandise?.product?.vendor)??"",total_price:R(_?.cost?.totalAmount?.amount)??null,quantity:_?.quantity??null,sku:B(_?.merchandise?.sku)??""})),U={...x,cart_total_price:R(n?.cart?.cost?.totalAmount?.amount)??null,cart_total_quantity:n?.cart?.totalQuantity??null,cart_items:C};await D(U)}catch(c){console.error("[ElevateAB] Error handling cart_viewed:",c)}},te=async n=>{try{let c=i(n),h=G(),E={...A("search_submitted",h,n,c),search_query:B(n?.data?.searchResult?.query)??""};await D(E)}catch(c){console.error("[ElevateAB] Error handling search_submitted:",c)}},Q=async n=>{try{let c=i(n),h=G(),x=A("checkout_started",h,n,c),E=0,U=(n?.data?.checkout?.lineItems??[]).map(T=>{let q=T?.quantity??0;E+=q;let F=(T?.discountAllocations??[])?.reduce((V,W)=>V+(W?.amount?.amount||0),0);return{product_id:$(T?.variant?.product?.id)??"",variant_id:J(T?.variant?.id)??"",vendor:B(T?.variant?.product?.vendor)??"",total_price:R(T?.finalLinePrice?.amount)??null,quantity:q,sku:B(T?.variant?.sku)??"",total_discount:R(F)??null}}),_={...x,cart_total_price:R(n?.data?.checkout?.totalPrice?.amount)??null,cart_subtotal_price:R(n?.data?.checkout?.subtotalPrice?.amount)??null,cart_total_quantity:E,cart_shipping_price:R(n?.data?.checkout?.shippingLine?.price?.amount)??null,cart_tax_amount:R(n?.data?.checkout?.totalTax?.amount)??null,cart_discount_amount:R(n?.data?.checkout?.discountsAmount?.amount)??null,cart_items:U,customer_id:n?.data?.checkout?.order?.customer?.id??""};await D(_)}catch(c){console.error("[ElevateAB] Error handling checkout_started:",c)}},H=async n=>{try{let c=i(n),h=G(),x=A("checkout_completed",h,n,c),E=0,U=(n?.data?.checkout?.lineItems??[]).map(T=>{let q=T?.quantity??0;E+=q;let F=(T?.discountAllocations??[])?.reduce((V,W)=>V+(W?.amount?.amount||0),0);return{product_id:$(T?.variant?.product?.id)??"",variant_id:J(T?.variant?.id)??"",vendor:B(T?.variant?.product?.vendor)??"",total_price:R(T?.finalLinePrice?.amount)??null,quantity:q,sku:B(T?.variant?.sku)??"",total_discount:R(F)??null}}),_={...x,cart_total_price:R(n?.data?.checkout?.totalPrice?.amount)??null,cart_subtotal_price:R(n?.data?.checkout?.subtotalPrice?.amount)??null,cart_total_quantity:E,cart_shipping_price:R(n?.data?.checkout?.shippingLine?.price?.amount)??null,cart_tax_amount:R(n?.data?.checkout?.totalTax?.amount)??null,cart_discount_amount:R(n?.data?.checkout?.discountsAmount?.amount)??null,cart_items:U,order_id:n?.data?.checkout?.order?.id??"",customer_id:n?.data?.checkout?.order?.customer?.id??"",is_first_order:n?.data?.checkout?.order?.customer?.isFirstOrder??null,note_attributes:n?.data?.checkout?.attributes??[]};await ce(_)}catch(c){console.error("[ElevateAB] Error handling checkout_completed:",c)}},ce=async n=>{if(!n.exclude)try{let c=await fetch(m,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),keepalive:!0});if(!c.ok)throw new Error(`Orders worker error: ${c.status}`);return c}catch(c){console.error("[ElevateAB] Error sending order analytics:",c)}};e("page_viewed",d),e("product_viewed",l),e("product_added_to_cart",S),e("product_removed_from_cart",O),e("cart_viewed",Y),e("search_submitted",te),e("checkout_started",Q),e("checkout_completed",H)})(),t()},[e,t,N,p,P,v,m]),null}export{ye as a,dt as b,B as c,R as d,$ as e,J as f,Me as g,ze as h,bt as i,Fe as j,Ve as k,mt as l,je as m,kt as n};
2
+ //# sourceMappingURL=chunk-XXNIBCJ6.js.map