@elevateab/sdk 1.2.2 → 1.2.4

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts","../src/utils/storage.ts","../src/utils/assignment.ts","../node_modules/ua-parser-js/src/ua-parser.js","../src/mutations/cartAttributes.mutation.ts","../src/utils/cartAttributes.ts","../src/index.ts","../src/utils/tracking.ts","../src/utils/conditions.ts","../src/utils/preview.ts","../src/utils/geo.ts","../src/utils/antiFlicker.ts","../src/utils/analytics.ts","../src/utils/shopify.ts","../src/utils/manualTracking.ts","../src/components/Experiment.tsx","../src/contexts/ElevateContext.tsx","../src/components/ElevateProvider.tsx","../src/components/ElevateAnalytics.tsx"],"sourcesContent":["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 * 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","/**\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/* UAParser.js v1.0.41\n Copyright © 2012-2025 Faisal Salman <f@faisalman.com>\n MIT License *//*\n Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.\n Supports browser & node.js environment. \n Demo : https://faisalman.github.io/ua-parser-js\n Source : https://github.com/faisalman/ua-parser-js */\n/////////////////////////////////////////////////////////////////////////////////\n\n(function (window, undefined) {\n\n 'use strict';\n\n //////////////\n // Constants\n /////////////\n\n\n var LIBVERSION = '1.0.41',\n EMPTY = '',\n UNKNOWN = '?',\n FUNC_TYPE = 'function',\n UNDEF_TYPE = 'undefined',\n OBJ_TYPE = 'object',\n STR_TYPE = 'string',\n MAJOR = 'major',\n MODEL = 'model',\n NAME = 'name',\n TYPE = 'type',\n VENDOR = 'vendor',\n VERSION = 'version',\n ARCHITECTURE= 'architecture',\n CONSOLE = 'console',\n MOBILE = 'mobile',\n TABLET = 'tablet',\n SMARTTV = 'smarttv',\n WEARABLE = 'wearable',\n EMBEDDED = 'embedded',\n UA_MAX_LENGTH = 500;\n\n var AMAZON = 'Amazon',\n APPLE = 'Apple',\n ASUS = 'ASUS',\n BLACKBERRY = 'BlackBerry',\n BROWSER = 'Browser',\n CHROME = 'Chrome',\n EDGE = 'Edge',\n FIREFOX = 'Firefox',\n GOOGLE = 'Google',\n HONOR = 'Honor',\n HUAWEI = 'Huawei',\n LENOVO = 'Lenovo',\n LG = 'LG',\n MICROSOFT = 'Microsoft',\n MOTOROLA = 'Motorola',\n NVIDIA = 'Nvidia',\n ONEPLUS = 'OnePlus',\n OPERA = 'Opera',\n OPPO = 'OPPO',\n SAMSUNG = 'Samsung',\n SHARP = 'Sharp',\n SONY = 'Sony',\n XIAOMI = 'Xiaomi',\n ZEBRA = 'Zebra',\n FACEBOOK = 'Facebook',\n CHROMIUM_OS = 'Chromium OS',\n MAC_OS = 'Mac OS',\n SUFFIX_BROWSER = ' Browser';\n\n ///////////\n // Helper\n //////////\n\n var extend = function (regexes, extensions) {\n var mergedRegexes = {};\n for (var i in regexes) {\n if (extensions[i] && extensions[i].length % 2 === 0) {\n mergedRegexes[i] = extensions[i].concat(regexes[i]);\n } else {\n mergedRegexes[i] = regexes[i];\n }\n }\n return mergedRegexes;\n },\n enumerize = function (arr) {\n var enums = {};\n for (var i=0; i<arr.length; i++) {\n enums[arr[i].toUpperCase()] = arr[i];\n }\n return enums;\n },\n has = function (str1, str2) {\n return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;\n },\n lowerize = function (str) {\n return str.toLowerCase();\n },\n majorize = function (version) {\n return typeof(version) === STR_TYPE ? version.replace(/[^\\d\\.]/g, EMPTY).split('.')[0] : undefined;\n },\n trim = function (str, len) {\n if (typeof(str) === STR_TYPE) {\n str = str.replace(/^\\s\\s*/, EMPTY);\n return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);\n }\n };\n\n ///////////////\n // Map helper\n //////////////\n\n var rgxMapper = function (ua, arrays) {\n\n var i = 0, j, k, p, q, matches, match;\n\n // loop through all regexes maps\n while (i < arrays.length && !matches) {\n\n var regex = arrays[i], // even sequence (0,2,4,..)\n props = arrays[i + 1]; // odd sequence (1,3,5,..)\n j = k = 0;\n\n // try matching uastring with regexes\n while (j < regex.length && !matches) {\n\n if (!regex[j]) { break; }\n matches = regex[j++].exec(ua);\n\n if (!!matches) {\n for (p = 0; p < props.length; p++) {\n match = matches[++k];\n q = props[p];\n // check if given property is actually array\n if (typeof q === OBJ_TYPE && q.length > 0) {\n if (q.length === 2) {\n if (typeof q[1] == FUNC_TYPE) {\n // assign modified match\n this[q[0]] = q[1].call(this, match);\n } else {\n // assign given value, ignore regex match\n this[q[0]] = q[1];\n }\n } else if (q.length === 3) {\n // check whether function or regex\n if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {\n // call function (usually string mapper)\n this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;\n } else {\n // sanitize match using given regex\n this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;\n }\n } else if (q.length === 4) {\n this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;\n }\n } else {\n this[q] = match ? match : undefined;\n }\n }\n }\n }\n i += 2;\n }\n },\n\n strMapper = function (str, map) {\n\n for (var i in map) {\n // check if current value is array\n if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {\n for (var j = 0; j < map[i].length; j++) {\n if (has(map[i][j], str)) {\n return (i === UNKNOWN) ? undefined : i;\n }\n }\n } else if (has(map[i], str)) {\n return (i === UNKNOWN) ? undefined : i;\n }\n }\n return map.hasOwnProperty('*') ? map['*'] : str;\n };\n\n ///////////////\n // String map\n //////////////\n\n // Safari < 3.0\n var oldSafariMap = {\n '1.0' : '/8',\n '1.2' : '/1',\n '1.3' : '/3',\n '2.0' : '/412',\n '2.0.2' : '/416',\n '2.0.3' : '/417',\n '2.0.4' : '/419',\n '?' : '/'\n },\n windowsVersionMap = {\n 'ME' : '4.90',\n 'NT 3.11' : 'NT3.51',\n 'NT 4.0' : 'NT4.0',\n '2000' : 'NT 5.0',\n 'XP' : ['NT 5.1', 'NT 5.2'],\n 'Vista' : 'NT 6.0',\n '7' : 'NT 6.1',\n '8' : 'NT 6.2',\n '8.1' : 'NT 6.3',\n '10' : ['NT 6.4', 'NT 10.0'],\n 'RT' : 'ARM'\n };\n\n //////////////\n // Regex map\n /////////////\n\n var regexes = {\n\n browser : [[\n\n /\\b(?:crmo|crios)\\/([\\w\\.]+)/i // Chrome for Android/iOS\n ], [VERSION, [NAME, 'Chrome']], [\n /edg(?:e|ios|a)?\\/([\\w\\.]+)/i // Microsoft Edge\n ], [VERSION, [NAME, 'Edge']], [\n\n // Presto based\n /(opera mini)\\/([-\\w\\.]+)/i, // Opera Mini\n /(opera [mobiletab]{3,6})\\b.+version\\/([-\\w\\.]+)/i, // Opera Mobi/Tablet\n /(opera)(?:.+version\\/|[\\/ ]+)([\\w\\.]+)/i // Opera\n ], [NAME, VERSION], [\n /opios[\\/ ]+([\\w\\.]+)/i // Opera mini on iphone >= 8.0\n ], [VERSION, [NAME, OPERA+' Mini']], [\n /\\bop(?:rg)?x\\/([\\w\\.]+)/i // Opera GX\n ], [VERSION, [NAME, OPERA+' GX']], [\n /\\bopr\\/([\\w\\.]+)/i // Opera Webkit\n ], [VERSION, [NAME, OPERA]], [\n\n // Mixed\n /\\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\\/ ]?([\\w\\.]+)/i // Baidu\n ], [VERSION, [NAME, 'Baidu']], [\n /\\b(?:mxbrowser|mxios|myie2)\\/?([-\\w\\.]*)\\b/i // Maxthon\n ], [VERSION, [NAME, 'Maxthon']], [\n /(kindle)\\/([\\w\\.]+)/i, // Kindle\n /(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\\/ ]?([\\w\\.]*)/i, \n // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir\n // Trident based\n /(avant|iemobile|slim(?:browser|boat|jet))[\\/ ]?([\\d\\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet\n /(?:ms|\\()(ie) ([\\w\\.]+)/i, // Internet Explorer\n\n // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon\n /(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,\n // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon\n /(heytap|ovi|115)browser\\/([\\d\\.]+)/i, // HeyTap/Ovi/115\n /(weibo)__([\\d\\.]+)/i // Weibo\n ], [NAME, VERSION], [\n /quark(?:pc)?\\/([-\\w\\.]+)/i // Quark\n ], [VERSION, [NAME, 'Quark']], [\n /\\bddg\\/([\\w\\.]+)/i // DuckDuckGo\n ], [VERSION, [NAME, 'DuckDuckGo']], [\n /(?:\\buc? ?browser|(?:juc.+)ucweb)[\\/ ]?([\\w\\.]+)/i // UCBrowser\n ], [VERSION, [NAME, 'UC'+BROWSER]], [\n /microm.+\\bqbcore\\/([\\w\\.]+)/i, // WeChat Desktop for Windows Built-in Browser\n /\\bqbcore\\/([\\w\\.]+).+microm/i,\n /micromessenger\\/([\\w\\.]+)/i // WeChat\n ], [VERSION, [NAME, 'WeChat']], [\n /konqueror\\/([\\w\\.]+)/i // Konqueror\n ], [VERSION, [NAME, 'Konqueror']], [\n /trident.+rv[: ]([\\w\\.]{1,9})\\b.+like gecko/i // IE11\n ], [VERSION, [NAME, 'IE']], [\n /ya(?:search)?browser\\/([\\w\\.]+)/i // Yandex\n ], [VERSION, [NAME, 'Yandex']], [\n /slbrowser\\/([\\w\\.]+)/i // Smart Lenovo Browser\n ], [VERSION, [NAME, 'Smart Lenovo '+BROWSER]], [\n /(avast|avg)\\/([\\w\\.]+)/i // Avast/AVG Secure Browser\n ], [[NAME, /(.+)/, '$1 Secure '+BROWSER], VERSION], [\n /\\bfocus\\/([\\w\\.]+)/i // Firefox Focus\n ], [VERSION, [NAME, FIREFOX+' Focus']], [\n /\\bopt\\/([\\w\\.]+)/i // Opera Touch\n ], [VERSION, [NAME, OPERA+' Touch']], [\n /coc_coc\\w+\\/([\\w\\.]+)/i // Coc Coc Browser\n ], [VERSION, [NAME, 'Coc Coc']], [\n /dolfin\\/([\\w\\.]+)/i // Dolphin\n ], [VERSION, [NAME, 'Dolphin']], [\n /coast\\/([\\w\\.]+)/i // Opera Coast\n ], [VERSION, [NAME, OPERA+' Coast']], [\n /miuibrowser\\/([\\w\\.]+)/i // MIUI Browser\n ], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [\n /fxios\\/([\\w\\.-]+)/i // Firefox for iOS\n ], [VERSION, [NAME, FIREFOX]], [\n /\\bqihoobrowser\\/?([\\w\\.]*)/i // 360\n ], [VERSION, [NAME, '360']], [\n /\\b(qq)\\/([\\w\\.]+)/i // QQ\n ], [[NAME, /(.+)/, '$1Browser'], VERSION], [\n /(oculus|sailfish|huawei|vivo|pico)browser\\/([\\w\\.]+)/i\n ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser\n /samsungbrowser\\/([\\w\\.]+)/i // Samsung Internet\n ], [VERSION, [NAME, SAMSUNG + ' Internet']], [\n /metasr[\\/ ]?([\\d\\.]+)/i // Sogou Explorer\n ], [VERSION, [NAME, 'Sogou Explorer']], [\n /(sogou)mo\\w+\\/([\\d\\.]+)/i // Sogou Mobile\n ], [[NAME, 'Sogou Mobile'], VERSION], [\n /(electron)\\/([\\w\\.]+) safari/i, // Electron-based App\n /(tesla)(?: qtcarbrowser|\\/(20\\d\\d\\.[-\\w\\.]+))/i, // Tesla\n /m?(qqbrowser|2345(?=browser|chrome|explorer))\\w*[\\/ ]?v?([\\w\\.]+)/i // QQ/2345\n ], [NAME, VERSION], [\n /(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq\n /\\[(linkedin)app\\]/i // LinkedIn App for iOS & Android\n ], [NAME], [\n /ome\\/([\\w\\.]+) \\w* ?(iron) saf/i, // Iron\n /ome\\/([\\w\\.]+).+qihu (360)[es]e/i // 360\n ], [VERSION, NAME], [\n\n // WebView\n /((?:fban\\/fbios|fb_iab\\/fb4a)(?!.+fbav)|;fbav\\/([\\w\\.]+);)/i // Facebook App for iOS & Android\n ], [[NAME, FACEBOOK], VERSION], [\n /(Klarna)\\/([\\w\\.]+)/i, // Klarna Shopping Browser for iOS & Android\n /(kakao(?:talk|story))[\\/ ]([\\w\\.]+)/i, // Kakao App\n /(naver)\\(.*?(\\d+\\.[\\w\\.]+).*\\)/i, // Naver InApp\n /(daum)apps[\\/ ]([\\w\\.]+)/i, // Daum App\n /safari (line)\\/([\\w\\.]+)/i, // Line App for iOS\n /\\b(line)\\/([\\w\\.]+)\\/iab/i, // Line App for Android\n /(alipay)client\\/([\\w\\.]+)/i, // Alipay\n /(twitter)(?:and| f.+e\\/([\\w\\.]+))/i, // Twitter\n /(chromium|instagram|snapchat)[\\/ ]([-\\w\\.]+)/i // Chromium/Instagram/Snapchat\n ], [NAME, VERSION], [\n /\\bgsa\\/([\\w\\.]+) .*safari\\//i // Google Search Appliance on iOS\n ], [VERSION, [NAME, 'GSA']], [\n /musical_ly(?:.+app_?version\\/|_)([\\w\\.]+)/i // TikTok\n ], [VERSION, [NAME, 'TikTok']], [\n\n /headlesschrome(?:\\/([\\w\\.]+)| )/i // Chrome Headless\n ], [VERSION, [NAME, CHROME+' Headless']], [\n\n / wv\\).+(chrome)\\/([\\w\\.]+)/i // Chrome WebView\n ], [[NAME, CHROME+' WebView'], VERSION], [\n\n /droid.+ version\\/([\\w\\.]+)\\b.+(?:mobile safari|safari)/i // Android Browser\n ], [VERSION, [NAME, 'Android '+BROWSER]], [\n\n /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\\/v?([\\w\\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia\n ], [NAME, VERSION], [\n\n /version\\/([\\w\\.\\,]+) .*mobile\\/\\w+ (safari)/i // Mobile Safari\n ], [VERSION, [NAME, 'Mobile Safari']], [\n /version\\/([\\w(\\.|\\,)]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile\n ], [VERSION, NAME], [\n /webkit.+?(mobile ?safari|safari)(\\/[\\w\\.]+)/i // Safari < 3.0\n ], [NAME, [VERSION, strMapper, oldSafariMap]], [\n\n /(webkit|khtml)\\/([\\w\\.]+)/i\n ], [NAME, VERSION], [\n\n // Gecko based\n /(navigator|netscape\\d?)\\/([-\\w\\.]+)/i // Netscape\n ], [[NAME, 'Netscape'], VERSION], [\n /(wolvic|librewolf)\\/([\\w\\.]+)/i // Wolvic/LibreWolf\n ], [NAME, VERSION], [\n /mobile vr; rv:([\\w\\.]+)\\).+firefox/i // Firefox Reality\n ], [VERSION, [NAME, FIREFOX+' Reality']], [\n /ekiohf.+(flow)\\/([\\w\\.]+)/i, // Flow\n /(swiftfox)/i, // Swiftfox\n /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\\/ ]?([\\w\\.\\+]+)/i,\n // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror\n /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\\/([-\\w\\.]+)$/i,\n // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix\n /(firefox)\\/([\\w\\.]+)/i, // Other Firefox-based\n /(mozilla)\\/([\\w\\.]+) .+rv\\:.+gecko\\/\\d+/i, // Mozilla\n\n // Other\n /(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\\. ]?browser)[-\\/ ]?v?([\\w\\.]+)/i,\n // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser/Ladybird\n /\\b(links) \\(([\\w\\.]+)/i // Links\n ], [NAME, [VERSION, /_/g, '.']], [\n \n /(cobalt)\\/([\\w\\.]+)/i // Cobalt\n ], [NAME, [VERSION, /master.|lts./, \"\"]]\n ],\n\n cpu : [[\n\n /\\b((amd|x|x86[-_]?|wow|win)64)\\b/i // AMD64 (x64)\n ], [[ARCHITECTURE, 'amd64']], [\n\n /(ia32(?=;))/i, // IA32 (quicktime)\n /\\b((i[346]|x)86)(pc)?\\b/i // IA32 (x86)\n ], [[ARCHITECTURE, 'ia32']], [\n\n /\\b(aarch64|arm(v?[89]e?l?|_?64))\\b/i // ARM64\n ], [[ARCHITECTURE, 'arm64']], [\n\n /\\b(arm(v[67])?ht?n?[fl]p?)\\b/i // ARMHF\n ], [[ARCHITECTURE, 'armhf']], [\n\n // PocketPC mistakenly identified as PowerPC\n /( (ce|mobile); ppc;|\\/[\\w\\.]+arm\\b)/i\n ], [[ARCHITECTURE, 'arm']], [\n\n /((ppc|powerpc)(64)?)( mac|;|\\))/i // PowerPC\n ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [\n\n / sun4\\w[;\\)]/i // SPARC\n ], [[ARCHITECTURE, 'sparc']], [\n\n /\\b(avr32|ia64(?=;)|68k(?=\\))|\\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\\b|pa-risc)/i\n // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC\n ], [[ARCHITECTURE, lowerize]]\n ],\n\n device : [[\n\n //////////////////////////\n // MOBILES & TABLETS\n /////////////////////////\n\n // Samsung\n /\\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\n ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [\n /\\b((?:s[cgp]h|gt|sm)-(?![lr])\\w+|sc[g-]?[\\d]+a?|galaxy nexus)/i,\n /samsung[- ]((?!sm-[lr])[-\\w]+)/i,\n /sec-(sgh\\w+)/i\n ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [\n\n // Apple\n /(?:\\/|\\()(ip(?:hone|od)[\\w, ]*)(?:\\/|;)/i // iPod/iPhone\n ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [\n /\\((ipad);[-\\w\\),; ]+apple/i, // iPad\n /applecoremedia\\/[\\w\\.]+ \\((ipad)/i,\n /\\b(ipad)\\d\\d?,\\d\\d?[;\\]].+ios/i\n ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [\n /(macintosh);/i\n ], [MODEL, [VENDOR, APPLE]], [\n\n // Sharp\n /\\b(sh-?[altvz]?\\d\\d[a-ekm]?)/i\n ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [\n\n // Honor\n /\\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\\)|;)/i\n ], [MODEL, [VENDOR, HONOR], [TYPE, TABLET]], [\n /honor([-\\w ]+)[;\\)]/i\n ], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [\n\n // Huawei\n /\\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\n ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [\n /(?:huawei)([-\\w ]+)[;\\)]/i,\n /\\b(nexus 6p|\\w{2,4}e?-[atu]?[ln][\\dx][012359c][adn]?)\\b(?!.+d\\/s)/i\n ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [\n\n // Xiaomi\n /oid[^\\)]+; (2[\\dbc]{4}(182|283|rp\\w{2})[cgl]|m2105k81a?c)(?: bui|\\))/i,\n /\\b((?:red)?mi[-_ ]?pad[\\w- ]*)(?: bui|\\))/i // Mi Pad tablets\n ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [\n\n /\\b(poco[\\w ]+|m2\\d{3}j\\d\\d[a-z]{2})(?: bui|\\))/i, // Xiaomi POCO\n /\\b; (\\w+) build\\/hm\\1/i, // Xiaomi Hongmi 'numeric' models\n /\\b(hm[-_ ]?note?[_ ]?(?:\\d\\w)?) bui/i, // Xiaomi Hongmi\n /\\b(redmi[\\-_ ]?(?:note|k)?[\\w_ ]+)(?: bui|\\))/i, // Xiaomi Redmi\n /oid[^\\)]+; (m?[12][0-389][01]\\w{3,6}[c-y])( bui|; wv|\\))/i, // Xiaomi Redmi 'numeric' models\n /\\b(mi[-_ ]?(?:a\\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\\d?\\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\\))/i, // Xiaomi Mi\n / ([\\w ]+) miui\\/v?\\d/i\n ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [\n\n // OPPO\n /; (\\w+) bui.+ oppo/i,\n /\\b(cph[12]\\d{3}|p(?:af|c[al]|d\\w|e[ar])[mt]\\d0|x9007|a101op)\\b/i\n ], [MODEL, [VENDOR, OPPO], [TYPE, MOBILE]], [\n /\\b(opd2(\\d{3}a?))(?: bui|\\))/i\n ], [MODEL, [VENDOR, strMapper, { 'OnePlus' : ['304', '403', '203'], '*' : OPPO }], [TYPE, TABLET]], [\n\n // Vivo\n /vivo (\\w+)(?: bui|\\))/i,\n /\\b(v[12]\\d{3}\\w?[at])(?: bui|;)/i\n ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [\n\n // Realme\n /\\b(rmx[1-3]\\d{3})(?: bui|;|\\))/i\n ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [\n\n // Motorola\n /\\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\\b[\\w ]+build\\//i,\n /\\bmot(?:orola)?[- ](\\w*)/i,\n /((?:moto(?! 360)[\\w\\(\\) ]+|xt\\d{3,4}|nexus 6)(?= bui|\\)))/i\n ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [\n /\\b(mz60\\d|xoom[2 ]{0,2}) build\\//i\n ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [\n\n // LG\n /((?=lg)?[vl]k\\-?\\d{3}) bui| 3\\.[-\\w; ]{10}lg?-([06cv9]{3,4})/i\n ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [\n /(lm(?:-?f100[nv]?|-[\\w\\.]+)(?= bui|\\))|nexus [45])/i,\n /\\blg[-e;\\/ ]+((?!browser|netcast|android tv|watch)\\w+)/i,\n /\\blg-?([\\d\\w]+) bui/i\n ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [\n\n // Lenovo\n /(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,\n /lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\\w- ]+?)|tb[\\w-]{6,7})( bui|;|\\)|\\/)/i\n ], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [\n\n // Nokia\n /(nokia) (t[12][01])/i\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n /(?:maemo|nokia).*(n900|lumia \\d+|rm-\\d+)/i,\n /nokia[-_ ]?(([-\\w\\. ]*))/i\n ], [[MODEL, /_/g, ' '], [TYPE, MOBILE], [VENDOR, 'Nokia']], [\n\n // Google\n /(pixel (c|tablet))\\b/i // Google Pixel C/Tablet\n ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [\n /droid.+; (pixel[\\daxl ]{0,6})(?: bui|\\))/i // Google Pixel\n ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [\n\n // Sony\n /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\n ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [\n /sony tablet [ps]/i,\n /\\b(?:sony)?sgp\\w+(?: bui|\\))/i\n ], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [\n\n // OnePlus\n / (kb2005|in20[12]5|be20[12][59])\\b/i,\n /(?:one)?(?:plus)? (a\\d0\\d\\d)(?: b|\\))/i\n ], [MODEL, [VENDOR, ONEPLUS], [TYPE, MOBILE]], [\n\n // Amazon\n /(alexa)webm/i,\n /(kf[a-z]{2}wi|aeo(?!bc)\\w\\w)( bui|\\))/i, // Kindle Fire without Silk / Echo Show\n /(kf[a-z]+)( bui|\\)).+silk\\//i // Kindle Fire HD\n ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [\n /((?:sd|kf)[0349hijorstuw]+)( bui|\\)).+silk\\//i // Fire Phone\n ], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [\n\n // BlackBerry\n /(playbook);[-\\w\\),; ]+(rim)/i // BlackBerry PlayBook\n ], [MODEL, VENDOR, [TYPE, TABLET]], [\n /\\b((?:bb[a-f]|st[hv])100-\\d)/i,\n /\\(bb10; (\\w+)/i // BlackBerry 10\n ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [\n\n // Asus\n /(?:\\b|asus_)(transfo[prime ]{4,10} \\w+|eeepc|slider \\w+|nexus 7|padfone|p00[cj])/i\n ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [\n / (z[bes]6[027][012][km][ls]|zenfone \\d\\w?)\\b/i\n ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [\n\n // HTC\n /(nexus 9)/i // HTC Nexus 9\n ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [\n /(htc)[-;_ ]{1,2}([\\w ]+(?=\\)| bui)|\\w+)/i, // HTC\n\n // ZTE\n /(zte)[- ]([\\w ]+?)(?: bui|\\/|\\))/i,\n /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\\.))|sony(?!-bra))[-_ ]?([-\\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony\n ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [\n\n // TCL\n /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\n ], [MODEL, [VENDOR, 'TCL'], [TYPE, TABLET]], [\n\n // itel\n /(itel) ((\\w+))/i\n ], [[VENDOR, lowerize], MODEL, [TYPE, strMapper, { 'tablet' : ['p10001l', 'w7001'], '*' : 'mobile' }]], [\n\n // Acer\n /droid.+; ([ab][1-7]-?[0178a]\\d\\d?)/i\n ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [\n\n // Meizu\n /droid.+; (m[1-5] note) bui/i,\n /\\bmz-([-\\w]{2,})/i\n ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [\n \n // Ulefone\n /; ((?:power )?armor(?:[\\w ]{0,8}))(?: bui|\\))/i\n ], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [\n\n // Energizer\n /; (energy ?\\w+)(?: bui|\\))/i,\n /; energizer ([\\w ]+)(?: bui|\\))/i\n ], [MODEL, [VENDOR, 'Energizer'], [TYPE, MOBILE]], [\n\n // Cat\n /; cat (b35);/i,\n /; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\\))/i\n ], [MODEL, [VENDOR, 'Cat'], [TYPE, MOBILE]], [\n\n // Smartfren\n /((?:new )?andromax[\\w- ]+)(?: bui|\\))/i\n ], [MODEL, [VENDOR, 'Smartfren'], [TYPE, MOBILE]], [\n\n // Nothing\n /droid.+; (a(?:015|06[35]|142p?))/i\n ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [\n\n // Archos\n /; (x67 5g|tikeasy \\w+|ac[1789]\\d\\w+)( b|\\))/i,\n /archos ?(5|gamepad2?|([\\w ]*[t1789]|hello) ?\\d+[\\w ]*)( b|\\))/i\n ], [MODEL, [VENDOR, 'Archos'], [TYPE, TABLET]], [\n /archos ([\\w ]+)( b|\\))/i,\n /; (ac[3-6]\\d\\w{2,8})( b|\\))/i \n ], [MODEL, [VENDOR, 'Archos'], [TYPE, MOBILE]], [\n\n // MIXED\n /(imo) (tab \\w+)/i, // IMO\n /(infinix) (x1101b?)/i // Infinix XPad\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /(blackberry|benq|palm(?=\\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\\w]*)/i,\n // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan\n /; (hmd|imo) ([\\w ]+?)(?: bui|\\))/i, // HMD/IMO\n /(hp) ([\\w ]+\\w)/i, // HP iPAQ\n /(microsoft); (lumia[\\w ]+)/i, // Microsoft Lumia\n /(lenovo)[-_ ]?([-\\w ]+?)(?: bui|\\)|\\/)/i, // Lenovo\n /(oppo) ?([\\w ]+) bui/i // OPPO\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n\n /(kobo)\\s(ereader|touch)/i, // Kobo\n /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad\n /(kindle)\\/([\\w\\.]+)/i, // Kindle\n /(nook)[\\w ]+build\\/(\\w+)/i, // Nook\n /(dell) (strea[kpr\\d ]*[\\dko])/i, // Dell Streak\n /(le[- ]+pan)[- ]+(\\w{1,9}) bui/i, // Le Pan Tablets\n /(trinity)[- ]*(t\\d{3}) bui/i, // Trinity Tablets\n /(gigaset)[- ]+(q\\w{1,9}) bui/i, // Gigaset Tablets\n /(vodafone) ([\\w ]+)(?:\\)| bui)/i // Vodafone\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /(surface duo)/i // Surface Duo\n ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [\n /droid [\\d\\.]+; (fp\\du?)(?: b|\\))/i // Fairphone\n ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [\n /(u304aa)/i // AT&T\n ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [\n /\\bsie-(\\w*)/i // Siemens\n ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [\n /\\b(rct\\w+) b/i // RCA Tablets\n ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [\n /\\b(venue[\\d ]{2,7}) b/i // Dell Venue Tablets\n ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [\n /\\b(q(?:mv|ta)\\w+) b/i // Verizon Tablet\n ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [\n /\\b(?:barnes[& ]+noble |bn[rt])([\\w\\+ ]*) b/i // Barnes & Noble Tablet\n ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [\n /\\b(tm\\d{3}\\w+) b/i\n ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [\n /\\b(k88) b/i // ZTE K Series Tablet\n ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [\n /\\b(nx\\d{3}j) b/i // ZTE Nubia\n ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [\n /\\b(gen\\d{3}) b.+49h/i // Swiss GEN Mobile\n ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [\n /\\b(zur\\d{3}) b/i // Swiss ZUR Tablet\n ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [\n /\\b((zeki)?tb.*\\b) b/i // Zeki Tablets\n ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [\n /\\b([yr]\\d{2}) b/i,\n /\\b(dragon[- ]+touch |dt)(\\w{5}) b/i // Dragon Touch Tablet\n ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [\n /\\b(ns-?\\w{0,9}) b/i // Insignia Tablets\n ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [\n /\\b((nxa|next)-?\\w{0,9}) b/i // NextBook Tablets\n ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [\n /\\b(xtreme\\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones\n ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [\n /\\b(lvtel\\-)?(v1[12]) b/i // LvTel Phones\n ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [\n /\\b(ph-1) /i // Essential PH-1\n ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [\n /\\b(v(100md|700na|7011|917g).*\\b) b/i // Envizen Tablets\n ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [\n /\\b(trio[-\\w\\. ]+) b/i // MachSpeed Tablets\n ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [\n /\\btu_(1491) b/i // Rotor Tablets\n ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [\n /((?:tegranote|shield t(?!.+d tv))[\\w- ]*?)(?: b|\\))/i // Nvidia Tablets\n ], [MODEL, [VENDOR, NVIDIA], [TYPE, TABLET]], [\n /(sprint) (\\w+)/i // Sprint Phones\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n /(kin\\.[onetw]{3})/i // Microsoft Kin\n ], [[MODEL, /\\./g, ' '], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [\n /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\\)/i // Zebra\n ], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [\n /droid.+; (ec30|ps20|tc[2-8]\\d[kx])\\)/i\n ], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [\n\n ///////////////////\n // SMARTTVS\n ///////////////////\n\n /smart-tv.+(samsung)/i // Samsung\n ], [VENDOR, [TYPE, SMARTTV]], [\n /hbbtv.+maple;(\\d+)/i\n ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [\n /(nux; netcast.+smarttv|lg (netcast\\.tv-201\\d|android tv))/i // LG SmartTV\n ], [[VENDOR, LG], [TYPE, SMARTTV]], [\n /(apple) ?tv/i // Apple TV\n ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [\n /crkey/i // Google Chromecast\n ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [\n /droid.+aft(\\w+)( bui|\\))/i // Fire TV\n ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [\n /(shield \\w+ tv)/i // Nvidia Shield TV\n ], [MODEL, [VENDOR, NVIDIA], [TYPE, SMARTTV]], [\n /\\(dtv[\\);].+(aquos)/i,\n /(aquos-tv[\\w ]+)\\)/i // Sharp\n ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[\n /(bravia[\\w ]+)( bui|\\))/i // Sony\n ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [\n /(mi(tv|box)-?\\w+) bui/i // Xiaomi\n ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [\n /Hbbtv.*(technisat) (.*);/i // TechniSAT\n ], [VENDOR, MODEL, [TYPE, SMARTTV]], [\n /\\b(roku)[\\dx]*[\\)\\/]((?:dvp-)?[\\d\\.]*)/i, // Roku\n /hbbtv\\/\\d+\\.\\d+\\.\\d+ +\\([\\w\\+ ]*; *([\\w\\d][^;]*);([^;]*)/i // HbbTV devices\n ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [\n // SmartTV from Unidentified Vendors\n /droid.+; ([\\w- ]+) (?:android tv|smart[- ]?tv)/i\n ], [MODEL, [TYPE, SMARTTV]], [\n /\\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\\b/i\n ], [[TYPE, SMARTTV]], [\n\n ///////////////////\n // CONSOLES\n ///////////////////\n\n /(ouya)/i, // Ouya\n /(nintendo) ([wids3utch]+)/i // Nintendo\n ], [VENDOR, MODEL, [TYPE, CONSOLE]], [\n /droid.+; (shield)( bui|\\))/i // Nvidia Portable\n ], [MODEL, [VENDOR, NVIDIA], [TYPE, CONSOLE]], [\n /(playstation \\w+)/i // Playstation\n ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [\n /\\b(xbox(?: one)?(?!; xbox))[\\); ]/i // Microsoft Xbox\n ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [\n\n ///////////////////\n // WEARABLES\n ///////////////////\n\n /\\b(sm-[lr]\\d\\d[0156][fnuw]?s?|gear live)\\b/i // Samsung Galaxy Watch\n ], [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]], [\n /((pebble))app/i, // Pebble\n /(asus|google|lg|oppo) ((pixel |zen)?watch[\\w ]*)( bui|\\))/i // Asus ZenWatch / LG Watch / Pixel Watch\n ], [VENDOR, MODEL, [TYPE, WEARABLE]], [\n /(ow(?:19|20)?we?[1-3]{1,3})/i // Oppo Watch\n ], [MODEL, [VENDOR, OPPO], [TYPE, WEARABLE]], [\n /(watch)(?: ?os[,\\/]|\\d,\\d\\/)[\\d\\.]+/i // Apple Watch\n ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [\n /(opwwe\\d{3})/i // OnePlus Watch\n ], [MODEL, [VENDOR, ONEPLUS], [TYPE, WEARABLE]], [\n /(moto 360)/i // Motorola 360\n ], [MODEL, [VENDOR, MOTOROLA], [TYPE, WEARABLE]], [\n /(smartwatch 3)/i // Sony SmartWatch\n ], [MODEL, [VENDOR, SONY], [TYPE, WEARABLE]], [\n /(g watch r)/i // LG G Watch R\n ], [MODEL, [VENDOR, LG], [TYPE, WEARABLE]], [\n /droid.+; (wt63?0{2,3})\\)/i\n ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [\n\n ///////////////////\n // XR\n ///////////////////\n\n /droid.+; (glass) \\d/i // Google Glass\n ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [\n /(pico) (4|neo3(?: link|pro)?)/i // Pico\n ], [VENDOR, MODEL, [TYPE, WEARABLE]], [\n /; (quest( \\d| pro)?)/i // Oculus Quest\n ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [\n\n ///////////////////\n // EMBEDDED\n ///////////////////\n\n /(tesla)(?: qtcarbrowser|\\/[-\\w\\.]+)/i // Tesla\n ], [VENDOR, [TYPE, EMBEDDED]], [\n /(aeobc)\\b/i // Echo Dot\n ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [\n /(homepod).+mac os/i // Apple HomePod\n ], [MODEL, [VENDOR, APPLE], [TYPE, EMBEDDED]], [\n /windows iot/i\n ], [[TYPE, EMBEDDED]], [\n\n ////////////////////\n // MIXED (GENERIC)\n ///////////////////\n\n /droid .+?; ([^;]+?)(?: bui|; wv\\)|\\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors\n ], [MODEL, [TYPE, MOBILE]], [\n /droid .+?; ([^;]+?)(?: bui|\\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors\n ], [MODEL, [TYPE, TABLET]], [\n /\\b((tablet|tab)[;\\/]|focus\\/\\d(?!.+mobile))/i // Unidentifiable Tablet\n ], [[TYPE, TABLET]], [\n /(phone|mobile(?:[;\\/]| [ \\w\\/\\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile\n ], [[TYPE, MOBILE]], [\n /droid .+?; ([\\w\\. -]+)( bui|\\))/i // Generic Android Device\n ], [MODEL, [VENDOR, 'Generic']]\n ],\n\n engine : [[\n\n /windows.+ edge\\/([\\w\\.]+)/i // EdgeHTML\n ], [VERSION, [NAME, EDGE+'HTML']], [\n\n /(arkweb)\\/([\\w\\.]+)/i // ArkWeb\n ], [NAME, VERSION], [\n\n /webkit\\/537\\.36.+chrome\\/(?!27)([\\w\\.]+)/i // Blink\n ], [VERSION, [NAME, 'Blink']], [\n\n /(presto)\\/([\\w\\.]+)/i, // Presto\n /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\\/([\\w\\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna/Servo\n /ekioh(flow)\\/([\\w\\.]+)/i, // Flow\n /(khtml|tasman|links)[\\/ ]\\(?([\\w\\.]+)/i, // KHTML/Tasman/Links\n /(icab)[\\/ ]([23]\\.[\\d\\.]+)/i, // iCab\n\n /\\b(libweb)/i // LibWeb\n ], [NAME, VERSION], [\n /ladybird\\//i\n ], [[NAME, 'LibWeb']], [\n\n /rv\\:([\\w\\.]{1,9})\\b.+(gecko)/i // Gecko\n ], [VERSION, NAME]\n ],\n\n os : [[\n\n // Windows\n /microsoft (windows) (vista|xp)/i // Windows (iTunes)\n ], [NAME, VERSION], [\n /(windows (?:phone(?: os)?|mobile|iot))[\\/ ]?([\\d\\.\\w ]*)/i // Windows Phone\n ], [NAME, [VERSION, strMapper, windowsVersionMap]], [\n /windows nt 6\\.2; (arm)/i, // Windows RT\n /windows[\\/ ]([ntce\\d\\. ]+\\w)(?!.+xbox)/i,\n /(?:win(?=3|9|n)|win 9x )([nt\\d\\.]+)/i\n ], [[VERSION, strMapper, windowsVersionMap], [NAME, 'Windows']], [\n\n // iOS/macOS\n /[adehimnop]{4,7}\\b(?:.*os ([\\w]+) like mac|; opera)/i, // iOS\n /(?:ios;fbsv\\/|iphone.+ios[\\/ ])([\\d\\.]+)/i,\n /cfnetwork\\/.+darwin/i\n ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [\n /(mac os x) ?([\\w\\. ]*)/i,\n /(macintosh|mac_powerpc\\b)(?!.+haiku)/i // Mac OS\n ], [[NAME, MAC_OS], [VERSION, /_/g, '.']], [\n\n // Mobile OSes\n /droid ([\\w\\.]+)\\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS\n ], [VERSION, NAME], [ \n /(ubuntu) ([\\w\\.]+) like android/i // Ubuntu Touch\n ], [[NAME, /(.+)/, '$1 Touch'], VERSION], [\n // Android/Blackberry/WebOS/QNX/Bada/RIM/KaiOS/Maemo/MeeGo/S40/Sailfish OS/OpenHarmony/Tizen\n /(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen|webos)\\w*[-\\/; ]?([\\d\\.]*)/i\n ], [NAME, VERSION], [\n /\\(bb(10);/i // BlackBerry 10\n ], [VERSION, [NAME, BLACKBERRY]], [\n /(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\\/ ]?([\\w\\.]*)/i // Symbian\n ], [VERSION, [NAME, 'Symbian']], [\n /mozilla\\/[\\d\\.]+ \\((?:mobile|tablet|tv|mobile; [\\w ]+); rv:.+ gecko\\/([\\w\\.]+)/i // Firefox OS\n ], [VERSION, [NAME, FIREFOX+' OS']], [\n /web0s;.+rt(tv)/i,\n /\\b(?:hp)?wos(?:browser)?\\/([\\w\\.]+)/i // WebOS\n ], [VERSION, [NAME, 'webOS']], [\n /watch(?: ?os[,\\/]|\\d,\\d\\/)([\\d\\.]+)/i // watchOS\n ], [VERSION, [NAME, 'watchOS']], [\n\n // Google Chromecast\n /crkey\\/([\\d\\.]+)/i // Google Chromecast\n ], [VERSION, [NAME, CHROME+'cast']], [\n /(cros) [\\w]+(?:\\)| ([\\w\\.]+)\\b)/i // Chromium OS\n ], [[NAME, CHROMIUM_OS], VERSION],[\n\n // Smart TVs\n /panasonic;(viera)/i, // Panasonic Viera\n /(netrange)mmh/i, // Netrange\n /(nettv)\\/(\\d+\\.[\\w\\.]+)/i, // NetTV\n\n // Console\n /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation\n /(xbox); +xbox ([^\\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)\n\n // Other\n /\\b(joli|palm)\\b ?(?:os)?\\/?([\\w\\.]*)/i, // Joli/Palm\n /(mint)[\\/\\(\\) ]?(\\w*)/i, // Mint\n /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux\n /([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,\n // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire\n /(hurd|linux)(?: arm\\w*| x86\\w*| ?)([\\w\\.]*)/i, // Hurd/Linux\n /(gnu) ?([\\w\\.]*)/i, // GNU\n /\\b([-frentopcghs]{0,5}bsd|dragonfly)[\\/ ]?(?!amd|[ix346]{1,2}86)([\\w\\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly\n /(haiku) (\\w+)/i // Haiku\n ], [NAME, VERSION], [\n /(sunos) ?([\\w\\.\\d]*)/i // Solaris\n ], [[NAME, 'Solaris'], VERSION], [\n /((?:open)?solaris)[-\\/ ]?([\\w\\.]*)/i, // Solaris\n /(aix) ((\\d)(?=\\.|\\)| )[\\w\\.])*/i, // AIX\n /\\b(beos|os\\/2|amigaos|morphos|openvms|fuchsia|hp-ux|serenityos)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX/SerenityOS\n /(unix) ?([\\w\\.]*)/i // UNIX\n ], [NAME, VERSION]\n ]\n };\n\n /////////////////\n // Constructor\n ////////////////\n\n var UAParser = function (ua, extensions) {\n\n if (typeof ua === OBJ_TYPE) {\n extensions = ua;\n ua = undefined;\n }\n\n if (!(this instanceof UAParser)) {\n return new UAParser(ua, extensions).getResult();\n }\n\n var _navigator = (typeof window !== UNDEF_TYPE && window.navigator) ? window.navigator : undefined;\n var _ua = ua || ((_navigator && _navigator.userAgent) ? _navigator.userAgent : EMPTY);\n var _uach = (_navigator && _navigator.userAgentData) ? _navigator.userAgentData : undefined;\n var _rgxmap = extensions ? extend(regexes, extensions) : regexes;\n var _isSelfNav = _navigator && _navigator.userAgent == _ua;\n\n this.getBrowser = function () {\n var _browser = {};\n _browser[NAME] = undefined;\n _browser[VERSION] = undefined;\n rgxMapper.call(_browser, _ua, _rgxmap.browser);\n _browser[MAJOR] = majorize(_browser[VERSION]);\n // Brave-specific detection\n if (_isSelfNav && _navigator && _navigator.brave && typeof _navigator.brave.isBrave == FUNC_TYPE) {\n _browser[NAME] = 'Brave';\n }\n return _browser;\n };\n this.getCPU = function () {\n var _cpu = {};\n _cpu[ARCHITECTURE] = undefined;\n rgxMapper.call(_cpu, _ua, _rgxmap.cpu);\n return _cpu;\n };\n this.getDevice = function () {\n var _device = {};\n _device[VENDOR] = undefined;\n _device[MODEL] = undefined;\n _device[TYPE] = undefined;\n rgxMapper.call(_device, _ua, _rgxmap.device);\n if (_isSelfNav && !_device[TYPE] && _uach && _uach.mobile) {\n _device[TYPE] = MOBILE;\n }\n // iPadOS-specific detection: identified as Mac, but has some iOS-only properties\n if (_isSelfNav && _device[MODEL] == 'Macintosh' && _navigator && typeof _navigator.standalone !== UNDEF_TYPE && _navigator.maxTouchPoints && _navigator.maxTouchPoints > 2) {\n _device[MODEL] = 'iPad';\n _device[TYPE] = TABLET;\n }\n return _device;\n };\n this.getEngine = function () {\n var _engine = {};\n _engine[NAME] = undefined;\n _engine[VERSION] = undefined;\n rgxMapper.call(_engine, _ua, _rgxmap.engine);\n return _engine;\n };\n this.getOS = function () {\n var _os = {};\n _os[NAME] = undefined;\n _os[VERSION] = undefined;\n rgxMapper.call(_os, _ua, _rgxmap.os);\n if (_isSelfNav && !_os[NAME] && _uach && _uach.platform && _uach.platform != 'Unknown') {\n _os[NAME] = _uach.platform \n .replace(/chrome os/i, CHROMIUM_OS)\n .replace(/macos/i, MAC_OS); // backward compatibility\n }\n return _os;\n };\n this.getResult = function () {\n return {\n ua : this.getUA(),\n browser : this.getBrowser(),\n engine : this.getEngine(),\n os : this.getOS(),\n device : this.getDevice(),\n cpu : this.getCPU()\n };\n };\n this.getUA = function () {\n return _ua;\n };\n this.setUA = function (ua) {\n _ua = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua;\n return this;\n };\n this.setUA(_ua);\n return this;\n };\n\n UAParser.VERSION = LIBVERSION;\n UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);\n UAParser.CPU = enumerize([ARCHITECTURE]);\n UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);\n UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);\n\n ///////////\n // Export\n //////////\n\n // check js environment\n if (typeof(exports) !== UNDEF_TYPE) {\n // nodejs env\n if (typeof module !== UNDEF_TYPE && module.exports) {\n exports = module.exports = UAParser;\n }\n exports.UAParser = UAParser;\n } else {\n // requirejs env (optional)\n if (typeof(define) === FUNC_TYPE && define.amd) {\n define(function () {\n return UAParser;\n });\n } else if (typeof window !== UNDEF_TYPE) {\n // browser env\n window.UAParser = UAParser;\n }\n }\n\n // jQuery/Zepto specific (optional)\n // Note:\n // In AMD env the global scope should be kept clean, but jQuery is an exception.\n // jQuery always exports to global scope, unless jQuery.noConflict(true) is used,\n // and we should catch that.\n var $ = typeof window !== UNDEF_TYPE && (window.jQuery || window.Zepto);\n if ($ && !$.ua) {\n var parser = new UAParser();\n $.ua = parser.getResult();\n $.ua.get = function () {\n return parser.getUA();\n };\n $.ua.set = function (ua) {\n parser.setUA(ua);\n var result = parser.getResult();\n for (var prop in result) {\n $.ua[prop] = result[prop];\n }\n };\n }\n\n})(typeof window === 'object' ? window : this);\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","// Main entry point for the Elevate AB Testing NPM package\n\n// ============================================================================\n// TYPE EXPORTS\n// ============================================================================\n\n// Core SDK types\nexport type {\n Test,\n Variation,\n ElevateConfig,\n ElevateProviderProps,\n ElevateContextValue,\n ElevateAnalyticsProps,\n ExperimentStatus,\n BackendConfig,\n BackendTest,\n BackendVariation,\n} from \"./types\";\n\n// Event tracking types (for manual tracking)\nexport type {\n // Base config\n BaseTrackingConfig,\n // Individual event params\n TrackPageViewParams,\n TrackProductViewParams,\n TrackAddToCartParams,\n TrackRemoveFromCartParams,\n TrackCartViewParams,\n TrackSearchSubmittedParams,\n TrackCheckoutStartedParams,\n TrackCheckoutCompletedParams,\n UsePageViewTrackingParams,\n // Shared types\n CartItemInput,\n NoteAttribute,\n TestAssignment,\n // Internal payload (for advanced users)\n EventPayload,\n CartItemPayload,\n} from \"./types\";\n\n// Cart attribute types\nexport type { CartAttributesOptions, CartAttributeInput } from \"./types\";\n\n// Legacy types (deprecated)\nexport type { TrackingEvent } from \"./types\";\n\nexport {\n assignVariant,\n hashString,\n validateConfig,\n generateExperimentId,\n calculateRevenueLift,\n} from \"./utils\";\n\n// Storage utilities\nexport {\n setCookie,\n getCookie,\n getJsonCookie,\n deleteCookie,\n setSessionItem,\n getSessionItem,\n getJsonSessionItem,\n getVisitorId,\n initializeVisitorId,\n getSessionId,\n initializeSessionId,\n setReferrerData,\n getReferrerData,\n uuidv4,\n} from \"./utils/storage\";\n\n// Assignment utilities\nexport {\n getTestList,\n saveTestList,\n getAssignedVariant,\n assignAndPersistVariant,\n shouldShowTest,\n} from \"./utils/assignment\";\n\n// Tracking utilities\nexport {\n trackViews,\n trackUniqueView,\n trackSessionView,\n hasSessionView,\n hasUniqueView,\n} from \"./utils/tracking\";\n\n// Condition utilities\nexport {\n getDeviceType,\n getTrafficSource,\n checkFacebookBrowser,\n checkInstagramBrowser,\n checkTikTokBrowser,\n checkPinterestBrowser,\n} from \"./utils/conditions\";\n\n// Preview mode utilities\nexport {\n getPreviewState,\n isPreviewTest,\n getPreviewVariation,\n buildEabTestsParam,\n updateUrlWithTestParams,\n clearPreviewMode,\n isInPreviewMode,\n} from \"./utils/preview\";\nexport type { PreviewState } from \"./utils/preview\";\n\n// Geo-targeting utilities\nexport {\n getCountryCode,\n getGeoLocation,\n setCountryCode,\n setGeoLocation,\n isCountryIncluded,\n isCountryExcluded,\n matchesGeoTargeting,\n COUNTRIES,\n REGIONS,\n} from \"./utils/geo\";\nexport type { GeoLocation } from \"./utils/geo\";\n\n// Anti-flicker utilities\nexport {\n setupFlickerPrevention,\n injectFlickerStyles,\n hideForFlicker,\n revealAfterFlicker,\n cleanupFlickerPrevention,\n isFlickerPreventionActive,\n getFlickerPreventionScript,\n} from \"./utils/antiFlicker\";\n\n// Analytics utilities\nexport {\n parseAddViewData,\n extractProductId,\n extractProductVariantId,\n extractCartToken,\n cleanCartToken,\n getPageTypeFromPathname,\n sanitizeString,\n roundToTwo,\n checkFacebookInstagramBrowser,\n checkVisitorIdParams,\n getUserAgentNoBrowser,\n} from \"./utils/analytics\";\n\nexport type { ParsedViewData } from \"./utils/analytics\";\n\n// Shopify utilities\nexport {\n extractShopifyId,\n extractShopifyType,\n isShopifyGid,\n detectShopifyCurrency,\n} from \"./utils/shopify\";\n\n// Cart attribute utilities\nexport {\n updateCartAttributes,\n cleanupCartAttributes,\n getCartAttributesPayload,\n} from \"./utils/cartAttributes\";\n\n// Cart mutations\nexport { CART_ATTRIBUTES_UPDATE_MUTATION } from \"./mutations/cartAttributes.mutation\";\n\n// Manual tracking utilities (for Next.js and other frameworks)\n// Note: ElevateProvider auto-calls initAnalytics, so you usually don't need to call it manually\nexport {\n initAnalytics,\n trackPageView,\n trackProductView,\n trackAddToCart,\n trackRemoveFromCart,\n trackCartView,\n trackSearchSubmitted,\n trackCheckoutStarted,\n trackCheckoutCompleted,\n usePageViewTracking,\n} from \"./utils/manualTracking\";\n\n// Components\nexport { useExperiment } from \"./components/Experiment\";\nexport type { UseExperimentResult } from \"./components/Experiment\";\nexport { ElevateProvider } from \"./components/ElevateProvider\";\n\n// Analytics components\n// For Hydrogen stores: import from '@elevateab/sdk/hydrogen' for ElevateHydrogenAnalytics\n// For Next.js/Remix: use ElevateAnalytics with manual hook injection\nexport { ElevateAnalytics } from \"./components/ElevateAnalytics\";\nexport type {\n UseAnalyticsHook,\n ElevateHydrogenAnalyticsProps,\n} from \"./components/ElevateAnalytics\";\n\n// Note: ElevateHydrogenAnalytics is exported from '@elevateab/sdk/hydrogen' sub-path\n// to avoid bundling @shopify/hydrogen in non-Hydrogen projects\n\n// Contexts\nexport { useElevateConfig } from \"./contexts/ElevateContext\";\n\n// Package version\nexport const VERSION = \"1.1.2\";\n\n// Default configuration\nexport const DEFAULT_CONFIG = {\n enabled: true,\n trackingEndpoint: \"https://analytics.elevateab.com/track\",\n cacheDuration: 3600,\n};\n","/**\n * Tracking utilities for views and participation\n */\n\nimport {\n setCookie,\n setSessionItem,\n getJsonCookie,\n getJsonSessionItem,\n} from \"./storage\";\n\n/**\n * Track unique view for a test (ABAU cookie)\n */\nexport function trackUniqueView(testId: string): void {\n const addedUniqueViews = getJsonCookie<Record<string, boolean>>(\"ABAU\") || {};\n\n if (!addedUniqueViews[testId]) {\n addedUniqueViews[testId] = true;\n setCookie(\"ABAU\", JSON.stringify(addedUniqueViews));\n }\n}\n\n/**\n * Track session view for a test (ABAV session storage)\n */\nexport function trackSessionView(testId: string): void {\n const addedViews = getJsonSessionItem<Record<string, boolean>>(\"ABAV\") || {};\n\n if (!addedViews[testId]) {\n addedViews[testId] = true;\n setSessionItem(\"ABAV\", addedViews);\n }\n}\n\n/**\n * Track both unique and session views\n */\nexport function trackViews(testId: string): void {\n trackUniqueView(testId);\n trackSessionView(testId);\n}\n\n/**\n * Check if test has been viewed in this session\n */\nexport function hasSessionView(testId: string): boolean {\n const addedViews = getJsonSessionItem<Record<string, boolean>>(\"ABAV\") || {};\n return !!addedViews[testId];\n}\n\n/**\n * Check if test has a unique view\n */\nexport function hasUniqueView(testId: string): boolean {\n const addedUniqueViews = getJsonCookie<Record<string, boolean>>(\"ABAU\") || {};\n return !!addedUniqueViews[testId];\n}\n","/**\n * Condition checking utilities for targeting and filtering\n */\n\n/**\n * Detect device type\n */\nexport function getDeviceType(): \"desktop\" | \"tablet\" | \"mobile\" {\n if (typeof navigator === \"undefined\") return \"desktop\";\n\n const ua =\n navigator.userAgent || navigator.vendor || (window as any).opera || \"\";\n const lower = ua.toLowerCase();\n\n if (\n /windows nt.*tablet pc|pixelbook/i.test(ua) ||\n (/(?:macintosh|windows nt|win(?:95|98)|linux x86_64)/i.test(ua) &&\n !/android|mobile|tablet|ipad|iphone|ipod/i.test(lower))\n )\n return \"desktop\";\n\n const isTablet =\n /ipad|playbook|tablet|kindle|nexus (7|10)|xoom|sm-t\\d+|galaxy tab|tb-\\d+|tb\\d+[a-z]+|lenovo.*tb|dtab|ideatab|mediapad|matepad|honor.*pad|pad\\s+\\d+|mi\\s+pad|redmi.*pad|xiaomi.*pad|oppo.*pad|oneplus.*pad|opd\\d+|tcl.*tab|9\\d{3}[a-z]|kobo|archos.*5(?!\\d)|ereader|droipad/i.test(\n ua\n ) ||\n (/android(?!.*mobile)/i.test(lower) &&\n !/dalvik.*miui|pocophone|mi\\s+mix|edge\\s+\\d+|sm-g9\\d+|pixel\\s+\\d|pixel\\s+fold|advan\\s+\\d{4}/i.test(\n ua\n ));\n\n if (isTablet) return \"tablet\";\n\n const isMobile =\n /android.+mobile|iphone|ipod|windows phone|blackberry|mobile|phone|kaios/i.test(\n lower\n ) ||\n /^mobile;/i.test(ua) ||\n /dalvik.*miui|pocophone|mi\\s+mix|pixel\\s+\\d|pixel\\s+fold/i.test(ua);\n\n if (isMobile) return \"mobile\";\n\n return \"desktop\";\n}\n\n/**\n * Check if Facebook in-app browser\n */\nexport function checkFacebookBrowser(): boolean {\n if (typeof navigator === \"undefined\") return false;\n\n const userAgent =\n navigator.userAgent || navigator.vendor || (window as any).opera;\n const facebookBrowserRegex =\n /((?:fban\\/fbios|fb_iab\\/fb4a)(?!.+fbav)|;fbav\\/([\\w\\.]+);)/i;\n return facebookBrowserRegex.test(userAgent);\n}\n\n/**\n * Check if Instagram in-app browser\n */\nexport function checkInstagramBrowser(): boolean {\n if (typeof navigator === \"undefined\") return false;\n\n const userAgent =\n navigator.userAgent || navigator.vendor || (window as any).opera;\n const instagramBrowserRegex = /(instagram)[\\/ ]([-\\w\\.]+)/i;\n return instagramBrowserRegex.test(userAgent);\n}\n\n/**\n * Check if TikTok in-app browser\n */\nexport function checkTikTokBrowser(): boolean {\n if (typeof navigator === \"undefined\") return false;\n\n const userAgent =\n navigator.userAgent || navigator.vendor || (window as any).opera;\n const tikTokBrowserRegex = /musical_ly/i;\n return tikTokBrowserRegex.test(userAgent);\n}\n\n/**\n * Check if Pinterest in-app browser\n */\nexport function checkPinterestBrowser(): boolean {\n if (typeof navigator === \"undefined\") return false;\n\n const userAgent =\n navigator.userAgent || navigator.vendor || (window as any).opera;\n const pinterestBrowserRegex = /(pinterest)[\\/ ]([-\\w\\.]+)/i;\n return pinterestBrowserRegex.test(userAgent);\n}\n\n/**\n * Get traffic source\n */\nexport function getTrafficSource(): string {\n if (typeof window === \"undefined\") return \"direct\";\n\n const referrer = (document.referrer || \"\").toLowerCase();\n const referrerDomain = referrer\n ? new URL(referrer).hostname.replace(\"www.\", \"\")\n : \"\";\n const hostname = window.location.hostname;\n\n const isFacebookBrowser = checkFacebookBrowser();\n const isInstagramBrowser = checkInstagramBrowser();\n const isTikTokBrowser = checkTikTokBrowser();\n const isPinterestBrowser = checkPinterestBrowser();\n\n if (\n isFacebookBrowser ||\n [\n \"facebook.com\",\n \"fb.com\",\n \"fb.me\",\n \"m.facebook.com\",\n \"l.facebook.com\",\n \"lm.facebook.com\",\n ].includes(referrerDomain)\n ) {\n return \"facebook\";\n } else if (isInstagramBrowser || referrerDomain.includes(\"instagram\")) {\n return \"instagram\";\n } else if (\n isTikTokBrowser ||\n [\"tiktok.com\", \"pangleglobal.com\", \"ads.tiktok.com\"].includes(\n referrerDomain\n )\n ) {\n return \"tiktok\";\n } else if (\n isPinterestBrowser ||\n referrerDomain.includes(\"pinterest\") ||\n referrerDomain === \"pin.it\"\n ) {\n return \"pinterest\";\n } else if (referrerDomain.includes(\"google\")) {\n return \"google\";\n } else if (!referrer || hostname === referrerDomain) {\n return \"direct\";\n } else {\n return \"other\";\n }\n}\n","/**\n * Preview Mode Utilities\n *\n * Enables QA/preview functionality for A/B tests via URL parameters.\n *\n * URL Format:\n * ?eabUserPreview=true&abtid=<test_id>&eab_tests=<shortid>_<variation>_<seen>\n *\n * Example:\n * https://store.com/?eabUserPreview=true&abtid=b6e2ecb8-e35a-450e-ae49-bdc560cf0fd7&eab_tests=f0fd7_29913_1\n */\n\nimport {\n getCookie,\n setCookie,\n getSessionItem,\n setSessionItem,\n} from \"./storage\";\n\n/**\n * Preview mode state\n */\nexport interface PreviewState {\n /** Whether preview mode is active */\n isPreview: boolean;\n /** The test ID being previewed (full UUID or short ID) */\n previewTestId: string | null;\n /** Forced test assignments from URL params */\n forcedAssignments: Record<string, string>;\n /** Tests that have been marked as \"seen\" in preview */\n previewedViews: Record<string, boolean>;\n}\n\n/**\n * Parse eab_tests parameter format: shortid_variation_seen~shortid2_variation2_seen2\n * Example: \"f0fd7_29913_1\" or \"f0fd7_29913_1~a1b2c_12345_0\"\n */\nfunction parseEabTestsParam(param: string): {\n assignments: Record<string, string>;\n views: Record<string, boolean>;\n} {\n const assignments: Record<string, string> = {};\n const views: Record<string, boolean> = {};\n\n if (!param) return { assignments, views };\n\n const tests = param.split(\"~\");\n for (const test of tests) {\n const parts = test.split(\"_\");\n if (parts.length >= 2) {\n const shortTestId = parts[0];\n const variationId = parts[1];\n const hasSeen = parts[2] === \"1\";\n\n assignments[shortTestId] = variationId;\n views[shortTestId] = hasSeen;\n }\n }\n\n return { assignments, views };\n}\n\n/**\n * Get preview state from URL parameters and cookies\n */\nexport function getPreviewState(): PreviewState {\n if (typeof window === \"undefined\") {\n return {\n isPreview: false,\n previewTestId: null,\n forcedAssignments: {},\n previewedViews: {},\n };\n }\n\n const urlParams = new URLSearchParams(window.location.search);\n\n // Check URL param first, then cookie\n const eabUserPreview =\n urlParams.get(\"eabUserPreview\") || getCookie(\"eabUserPreview\");\n const isPreview = eabUserPreview === \"true\";\n\n // Get test ID from URL param or sessionStorage\n let previewTestId = urlParams.get(\"abtid\");\n if (!previewTestId) {\n previewTestId = getSessionItem(\"eabPreviewTestId\");\n }\n\n // Parse forced assignments from eab_tests param\n const eabTestsParam = urlParams.get(\"eab_tests\") || \"\";\n const { assignments, views } = parseEabTestsParam(eabTestsParam);\n\n // If URL has preview params, persist to storage\n if (urlParams.has(\"eabUserPreview\")) {\n setCookie(\"eabUserPreview\", \"true\");\n }\n if (urlParams.has(\"abtid\") && previewTestId) {\n setSessionItem(\"eabPreviewTestId\", previewTestId);\n }\n\n return {\n isPreview,\n previewTestId,\n forcedAssignments: assignments,\n previewedViews: views,\n };\n}\n\n/**\n * Check if a test matches the preview test ID\n * Supports both full UUID and short ID (last 5 chars) matching\n */\nexport function isPreviewTest(\n testId: string,\n previewTestId: string | null,\n): boolean {\n if (!previewTestId) return false;\n\n // Exact match\n if (testId === previewTestId) return true;\n\n // Short ID match (last 5 characters)\n const shortTestId = testId.slice(-5);\n if (shortTestId === previewTestId || previewTestId.endsWith(shortTestId)) {\n return true;\n }\n\n // Preview ID might be short, check if test ends with it\n if (testId.endsWith(previewTestId)) return true;\n\n return false;\n}\n\n/**\n * Get forced variation for a test in preview mode\n * Returns null if no forced assignment exists\n */\nexport function getPreviewVariation(\n testId: string,\n previewState: PreviewState,\n): string | null {\n if (!previewState.isPreview) return null;\n\n // Check by full test ID\n if (previewState.forcedAssignments[testId]) {\n return previewState.forcedAssignments[testId];\n }\n\n // Check by short test ID\n const shortTestId = testId.slice(-5);\n if (previewState.forcedAssignments[shortTestId]) {\n return previewState.forcedAssignments[shortTestId];\n }\n\n return null;\n}\n\n/**\n * Build eab_tests URL parameter string from test assignments\n * Used for sharing preview URLs with Facebook/Instagram traffic\n */\nexport function buildEabTestsParam(\n testAssignments: Record<string, string>,\n viewedTests: Record<string, boolean>,\n): string {\n return Object.entries(testAssignments)\n .map(([testId, variationId]) => {\n const shortTestId = testId.slice(-5);\n const hasSeen = viewedTests[testId] ? \"1\" : \"0\";\n return `${shortTestId}_${variationId}_${hasSeen}`;\n })\n .join(\"~\");\n}\n\n/**\n * Update URL with test parameters for social media browsers (FB/IG/TikTok)\n * These browsers often lose cookies, so we persist test assignments in URL\n */\nexport function updateUrlWithTestParams(\n testAssignments: Record<string, string>,\n viewedTests: Record<string, boolean>,\n visitorId?: string,\n): void {\n if (typeof window === \"undefined\") return;\n\n const url = new URL(window.location.href);\n const eabTestsValue = buildEabTestsParam(testAssignments, viewedTests);\n\n if (eabTestsValue) {\n url.searchParams.set(\"eab_tests\", eabTestsValue);\n }\n\n if (visitorId) {\n url.searchParams.set(\"eabUserId\", visitorId);\n }\n\n // Update URL without reload\n window.history.replaceState({}, \"\", url.toString());\n}\n\n/**\n * Clear preview mode\n */\nexport function clearPreviewMode(): void {\n if (typeof document === \"undefined\") return;\n\n // Clear cookie\n document.cookie =\n \"eabUserPreview=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;\";\n\n // Clear session storage\n if (typeof sessionStorage !== \"undefined\") {\n sessionStorage.removeItem(\"eabPreviewTestId\");\n }\n\n // Remove preview params from URL\n if (typeof window !== \"undefined\") {\n const url = new URL(window.location.href);\n url.searchParams.delete(\"eabUserPreview\");\n url.searchParams.delete(\"abtid\");\n url.searchParams.delete(\"eab_tests\");\n window.history.replaceState({}, \"\", url.toString());\n }\n}\n\n/**\n * Check if current session is in preview mode\n */\nexport function isInPreviewMode(): boolean {\n return getPreviewState().isPreview;\n}\n","/**\n * Geo-targeting Utilities\n *\n * Provides country detection and geo-based targeting for A/B tests.\n */\n\nimport { getCookie, setCookie } from \"./storage\";\n\n/**\n * Geo-location data\n */\nexport interface GeoLocation {\n /** ISO 3166-1 alpha-2 country code (e.g., \"US\", \"GB\", \"CA\") */\n country: string | null;\n /** Region/state code (if available) */\n region?: string | null;\n /** City name (if available) */\n city?: string | null;\n}\n\n/**\n * Cookie names for geo data\n */\nconst GEO_COOKIE_NAMES = {\n /** Shopify's localization cookie */\n SHOPIFY_LOCALIZATION: \"localization\",\n /** Our cached country code */\n EAB_COUNTRY: \"eabCountryCode\",\n /** Full geo data (JSON) */\n EAB_GEO: \"eabGeoLocation\",\n} as const;\n\n/**\n * Get the user's country code from various sources\n * Priority: URL param > Shopify localization > our cookie > localStorage\n */\nexport function getCountryCode(): string | null {\n if (typeof window === \"undefined\") return null;\n\n // 1. Check URL param (for explicit override)\n const urlParams = new URLSearchParams(window.location.search);\n const urlCountry = urlParams.get(\"country\");\n if (urlCountry) {\n // Cache it\n setCookie(GEO_COOKIE_NAMES.EAB_COUNTRY, urlCountry.toUpperCase());\n return urlCountry.toUpperCase();\n }\n\n // 2. Check Shopify's localization cookie (most common for Shopify stores)\n const shopifyCountry = getCookie(GEO_COOKIE_NAMES.SHOPIFY_LOCALIZATION);\n if (shopifyCountry) {\n return shopifyCountry.toUpperCase();\n }\n\n // 3. Check our cached cookie\n const cachedCountry = getCookie(GEO_COOKIE_NAMES.EAB_COUNTRY);\n if (cachedCountry) {\n return cachedCountry.toUpperCase();\n }\n\n // 4. Check localStorage (fallback)\n if (typeof localStorage !== \"undefined\") {\n const storedCountry = localStorage.getItem(GEO_COOKIE_NAMES.EAB_COUNTRY);\n if (storedCountry) {\n return storedCountry.toUpperCase();\n }\n }\n\n return null;\n}\n\n/**\n * Get full geo-location data\n */\nexport function getGeoLocation(): GeoLocation {\n const country = getCountryCode();\n\n // Try to get extended geo data from cookie\n const geoData = getCookie(GEO_COOKIE_NAMES.EAB_GEO);\n if (geoData) {\n try {\n const parsed = JSON.parse(geoData) as GeoLocation;\n return {\n country: parsed.country || country,\n region: parsed.region,\n city: parsed.city,\n };\n } catch {\n // Invalid JSON, fall through\n }\n }\n\n return { country };\n}\n\n/**\n * Set the user's country code (for manual override or after geo detection)\n */\nexport function setCountryCode(countryCode: string): void {\n const normalized = countryCode.toUpperCase();\n setCookie(GEO_COOKIE_NAMES.EAB_COUNTRY, normalized);\n\n // Also store in localStorage for extra persistence\n if (typeof localStorage !== \"undefined\") {\n localStorage.setItem(GEO_COOKIE_NAMES.EAB_COUNTRY, normalized);\n }\n}\n\n/**\n * Set full geo-location data\n */\nexport function setGeoLocation(geo: GeoLocation): void {\n if (geo.country) {\n setCountryCode(geo.country);\n }\n\n // Store full geo data\n setCookie(GEO_COOKIE_NAMES.EAB_GEO, JSON.stringify(geo));\n}\n\n/**\n * Check if user's country matches a list of allowed countries\n */\nexport function isCountryIncluded(\n allowedCountries: string[],\n userCountry?: string | null,\n): boolean {\n const country = userCountry ?? getCountryCode();\n if (!country) return false;\n\n const normalizedAllowed = allowedCountries.map((c) => c.toUpperCase());\n return normalizedAllowed.includes(country.toUpperCase());\n}\n\n/**\n * Check if user's country is in an excluded list\n */\nexport function isCountryExcluded(\n excludedCountries: string[],\n userCountry?: string | null,\n): boolean {\n const country = userCountry ?? getCountryCode();\n if (!country) return false;\n\n const normalizedExcluded = excludedCountries.map((c) => c.toUpperCase());\n return normalizedExcluded.includes(country.toUpperCase());\n}\n\n/**\n * Check if user matches geo-targeting rules\n * Returns true if user should be included in the test\n */\nexport function matchesGeoTargeting(rules: {\n includeCountries?: string[];\n excludeCountries?: string[];\n}): boolean {\n const country = getCountryCode();\n\n // If no rules, include everyone\n if (!rules.includeCountries?.length && !rules.excludeCountries?.length) {\n return true;\n }\n\n // If no country detected and rules exist, exclude (can't target unknown)\n if (!country) {\n return false;\n }\n\n // Check exclusions first (takes precedence)\n if (rules.excludeCountries?.length) {\n if (isCountryExcluded(rules.excludeCountries, country)) {\n return false;\n }\n }\n\n // If include list exists, user must be in it\n if (rules.includeCountries?.length) {\n return isCountryIncluded(rules.includeCountries, country);\n }\n\n // No include list, and not excluded = included\n return true;\n}\n\n/**\n * Common country code constants for convenience\n */\nexport const COUNTRIES = {\n US: \"US\",\n CA: \"CA\",\n GB: \"GB\",\n AU: \"AU\",\n DE: \"DE\",\n FR: \"FR\",\n JP: \"JP\",\n MX: \"MX\",\n BR: \"BR\",\n IN: \"IN\",\n // Add more as needed\n} as const;\n\n/**\n * Region groupings for common use cases\n */\nexport const REGIONS = {\n NORTH_AMERICA: [\"US\", \"CA\", \"MX\"],\n EUROPE: [\n \"GB\",\n \"DE\",\n \"FR\",\n \"IT\",\n \"ES\",\n \"NL\",\n \"BE\",\n \"AT\",\n \"CH\",\n \"PL\",\n \"SE\",\n \"NO\",\n \"DK\",\n \"FI\",\n \"IE\",\n \"PT\",\n ],\n APAC: [\n \"AU\",\n \"NZ\",\n \"JP\",\n \"KR\",\n \"SG\",\n \"HK\",\n \"TW\",\n \"TH\",\n \"MY\",\n \"PH\",\n \"ID\",\n \"VN\",\n \"IN\",\n ],\n LATAM: [\"MX\", \"BR\", \"AR\", \"CL\", \"CO\", \"PE\"],\n} as const;\n","/**\n * Anti-Flicker Utilities\n *\n * Prevents visual flickering during A/B test assignment by hiding content\n * until the variant is determined. Uses a CSS-based approach for performance.\n *\n * Note: Called \"preventFlickering\" in our API to differentiate from competitors.\n */\n\n/**\n * CSS class used to hide content during flicker prevention\n */\nconst FLICKER_CLASS = \"eab-prevent-flicker\";\n\n/**\n * Inline style ID for flicker prevention\n */\nconst STYLE_ID = \"eab-flicker-styles\";\n\n/**\n * Default timeout (ms) before showing content anyway (failsafe)\n */\nconst DEFAULT_TIMEOUT = 3000;\n\n/**\n * Inject the flicker prevention CSS styles\n * This should be called as early as possible (ideally in <head>)\n */\nexport function injectFlickerStyles(timeout = DEFAULT_TIMEOUT): void {\n if (typeof document === \"undefined\") return;\n\n // Don't inject twice\n if (document.getElementById(STYLE_ID)) return;\n\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = `\n /* Elevate AB - Flicker Prevention */\n .${FLICKER_CLASS} {\n opacity: 0 !important;\n pointer-events: none !important;\n }\n \n /* Failsafe: ensure content shows after timeout via animation */\n @keyframes eab-reveal {\n to { opacity: 1; pointer-events: auto; }\n }\n \n .${FLICKER_CLASS} {\n animation: eab-reveal 0s ${timeout}ms forwards;\n }\n `;\n\n // Insert at the beginning of <head> for highest priority\n const head = document.head || document.getElementsByTagName(\"head\")[0];\n head.insertBefore(style, head.firstChild);\n}\n\n/**\n * Hide the page/element to prevent flicker\n * Call this before test assignment begins\n */\nexport function hideForFlicker(selector: string = \"body\"): void {\n if (typeof document === \"undefined\") return;\n\n const element = document.querySelector(selector);\n if (element) {\n element.classList.add(FLICKER_CLASS);\n }\n}\n\n/**\n * Show the page/element after test assignment is complete\n * Call this after variant is determined\n */\nexport function revealAfterFlicker(selector: string = \"body\"): void {\n if (typeof document === \"undefined\") return;\n\n const element = document.querySelector(selector);\n if (element) {\n element.classList.remove(FLICKER_CLASS);\n }\n}\n\n/**\n * Setup flicker prevention with automatic reveal\n * Returns a function to call when assignment is complete\n *\n * @param selector - CSS selector for element to hide (default: \"body\")\n * @param timeout - Maximum time to wait before revealing (default: 3000ms)\n * @returns Function to call when test assignment is complete\n *\n * @example\n * ```tsx\n * // In your app initialization\n * const reveal = setupFlickerPrevention();\n *\n * // After test assignment\n * reveal();\n * ```\n */\nexport function setupFlickerPrevention(\n selector: string = \"body\",\n timeout: number = DEFAULT_TIMEOUT,\n): () => void {\n if (typeof document === \"undefined\") {\n return () => {}; // No-op for SSR\n }\n\n // Inject styles\n injectFlickerStyles(timeout);\n\n // Hide content\n hideForFlicker(selector);\n\n // Setup timeout failsafe\n let hasRevealed = false;\n const timeoutId = setTimeout(() => {\n if (!hasRevealed) {\n console.warn(\n `[ElevateAB] Flicker prevention timeout (${timeout}ms) reached. ` +\n \"Revealing content. Check if test assignment is completing.\",\n );\n revealAfterFlicker(selector);\n hasRevealed = true;\n }\n }, timeout);\n\n // Return reveal function\n return () => {\n if (!hasRevealed) {\n clearTimeout(timeoutId);\n revealAfterFlicker(selector);\n hasRevealed = true;\n }\n };\n}\n\n/**\n * Remove all flicker prevention styles and classes\n * Useful for cleanup or when disabling the feature\n */\nexport function cleanupFlickerPrevention(): void {\n if (typeof document === \"undefined\") return;\n\n // Remove style tag\n const style = document.getElementById(STYLE_ID);\n if (style) {\n style.remove();\n }\n\n // Remove class from all elements\n const elements = document.querySelectorAll(`.${FLICKER_CLASS}`);\n elements.forEach((el) => el.classList.remove(FLICKER_CLASS));\n}\n\n/**\n * Check if flicker prevention is currently active\n */\nexport function isFlickerPreventionActive(): boolean {\n if (typeof document === \"undefined\") return false;\n\n return document.querySelector(`.${FLICKER_CLASS}`) !== null;\n}\n\n/**\n * Script snippet for inline injection in <head>\n * Use this when you need synchronous flicker prevention before React hydrates\n *\n * @example\n * ```tsx\n * // In your _document.tsx or layout.tsx\n * <script dangerouslySetInnerHTML={{ __html: getFlickerPreventionScript() }} />\n * ```\n */\nexport function getFlickerPreventionScript(timeout = DEFAULT_TIMEOUT): string {\n return `\n(function() {\n var style = document.createElement('style');\n style.id = '${STYLE_ID}';\n style.textContent = '.${FLICKER_CLASS}{opacity:0!important;pointer-events:none!important}@keyframes eab-reveal{to{opacity:1;pointer-events:auto}}.${FLICKER_CLASS}{animation:eab-reveal 0s ${timeout}ms forwards}';\n document.head.insertBefore(style, document.head.firstChild);\n document.body && document.body.classList.add('${FLICKER_CLASS}');\n})();\n`.trim();\n}\n","/**\n * Analytics utilities for parsing and extracting data from events\n */\n\nimport { UAParser } from \"ua-parser-js\";\n\n// URL source mappings\nconst urlSources: Record<string, string> = {\n \"facebook.com\": \"Facebook\",\n \"fb.me\": \"Facebook\",\n \"m.facebook.com\": \"Facebook\",\n \"l.facebook.com\": \"Facebook\",\n \"lm.facebook.com\": \"Facebook\",\n \"instagram.com\": \"Instagram\",\n \"l.instagram.com\": \"Instagram\",\n \"youtube.com\": \"Youtube\",\n \"youtu.be\": \"Youtube\",\n \"m.youtube.com\": \"Youtube\",\n \"bing.com\": \"Bing\",\n \"www.bing.com\": \"Bing\",\n \"msnbc.msn.com\": \"Bing\",\n \"dizionario.it.msn.com\": \"Bing\",\n \"cc.bingj.com\": \"Bing\",\n \"m.bing.com\": \"Bing\",\n \"twitter.com\": \"Twitter\",\n \"t.co\": \"Twitter\",\n};\n\n/**\n * Sanitize string values to prevent XSS\n */\nexport function sanitizeString(value: unknown): string {\n if (typeof value !== \"string\") return String(value);\n return value.replace(/[\\\\\"'`\\x00-\\x1F\\x7F]/g, \"\");\n}\n\n/**\n * Round number to 2 decimal places\n */\nexport function roundToTwo(value: unknown): number | null {\n if (value === null || value === undefined) {\n return null;\n }\n const num = typeof value === \"string\" ? parseFloat(value) : Number(value);\n\n if (isNaN(num)) {\n return null;\n }\n return Number(Math.round(Number(num + \"e2\")) + \"e-2\");\n}\n\n/**\n * Extract product ID from Shopify GID\n */\nexport function extractProductId(gid: string | undefined): string | null {\n if (!gid) return null;\n const regex = /gid:\\/\\/shopify\\/Product\\/(\\d+)/;\n const match = gid.match(regex);\n return match ? match[1] : null;\n}\n\n/**\n * Extract product variant ID from Shopify GID\n */\nexport function extractProductVariantId(\n gid: string | undefined\n): string | null {\n if (!gid) return null;\n const regex = /gid:\\/\\/shopify\\/ProductVariant\\/(\\d+)/;\n const match = gid.match(regex);\n return match ? match[1] : null;\n}\n\n/**\n * Extract cart token from Shopify GID\n */\nexport function extractCartToken(\n gid: string | undefined | null\n): string | null {\n if (!gid) return null;\n const regex = /gid:\\/\\/shopify\\/Cart\\/([^?]+(\\?.+)?)/;\n const match = gid.match(regex);\n return match ? match[1] : null;\n}\n\n/**\n * Clean cart token by removing query parameters\n */\nexport function cleanCartToken(\n cartToken: string | null | undefined\n): string | null {\n try {\n if (typeof cartToken !== \"string\") {\n return null;\n }\n const decodedToken = decodeURIComponent(cartToken);\n const tokenPart = decodedToken.split(\"?\")[0];\n return tokenPart;\n } catch {\n // Silently fail - cart token extraction is not critical\n return cartToken || null;\n }\n}\n\n/**\n * Check if Facebook in-app browser\n */\nexport function checkFacebookBrowser(userAgent: string): boolean {\n const facebookBrowserRegex =\n /((?:fban\\/fbios|fb_iab\\/fb4a)(?!.+fbav)|;fbav\\/([\\w\\.]+);)/i;\n return facebookBrowserRegex.test(userAgent);\n}\n\n/**\n * Check if Instagram in-app browser\n */\nexport function checkInstagramBrowser(userAgent: string): boolean {\n const instagramBrowserRegex = /(instagram)[\\/ ]([-\\w\\.]+)/i;\n return instagramBrowserRegex.test(userAgent);\n}\n\n/**\n * Check if Facebook or Instagram browser\n */\nexport function checkFacebookInstagramBrowser(userAgent: string): boolean {\n return checkFacebookBrowser(userAgent) || checkInstagramBrowser(userAgent);\n}\n\n/**\n * Get browser name from UA parser result\n */\nfunction getBrowserName(browser: string | undefined): string {\n if (!browser) {\n return \"\";\n }\n switch (browser) {\n case \"Mobile Safari\":\n return \"Safari\";\n case \"Chrome Mobile\":\n case \"Chrome Mobile iOS\":\n return \"Chrome\";\n case \"Firefox Mobile\":\n case \"Firefox Mobile iOS\":\n return \"Firefox\";\n case \"Opera Mobile\":\n case \"Opera Mini\":\n case \"Opera Mini iOS\":\n return \"Opera\";\n case \"Yandex Browser Lite\":\n return \"Yandex Browser\";\n case \"Chrome Webview\":\n case \"Mobile App\":\n return \"Mobile App\";\n default:\n return browser;\n }\n}\n\n/**\n * Extract query parameters from URL\n */\nfunction getQueryParams(parsedUrl: URL): Record<string, string> {\n const queryParams: Record<string, string> = {};\n\n parsedUrl.searchParams.forEach((value, key) => {\n if (!queryParams[key]) {\n queryParams[key] = value;\n }\n });\n\n return queryParams;\n}\n\n/**\n * Check if referrer URI is valid\n */\nfunction isValidReferrerURI(uri: URL): boolean {\n return !!uri.host && [\"http:\", \"https:\"].includes(uri.protocol);\n}\n\n/**\n * Extract referrer source from hostname\n */\nfunction extractReferrerSource(host: string): string {\n return host.replace(/^www\\./, \"\");\n}\n\n/**\n * Parse referrer to determine traffic source\n */\nfunction parseReferrer(\n referrer: string | undefined,\n browser: string,\n siteHostname: string | undefined\n): string {\n const browserObj: Record<string, string> = {\n Facebook: \"Facebook\",\n Instagram: \"Instagram\",\n };\n if (browser && browserObj[browser]) {\n return browser;\n }\n\n let referrerObj: URL | undefined;\n let host: string | undefined;\n try {\n if (referrer && referrer.trim() !== '') {\n referrerObj = new URL(referrer);\n } else {\n return \"Direct\";\n }\n if (referrerObj?.hostname && isValidReferrerURI(referrerObj)) {\n host = referrerObj.hostname;\n if (siteHostname && siteHostname === host) {\n return \"Direct\";\n }\n } else {\n return \"\";\n }\n } catch {\n // Silently handle invalid referrer URLs\n }\n if (!host) {\n return \"\";\n }\n const source = extractReferrerSource(host);\n if (!source) {\n return \"\";\n }\n if (urlSources[source]) {\n return urlSources[source];\n }\n if (source?.includes(\"google\")) {\n return \"Google\";\n }\n return source;\n}\n\n/**\n * Parse and extract analytics view data from referrer, entry page, and user agent\n */\nexport interface ParsedViewData {\n referrer_source: string;\n browser_info: string;\n os_info: string;\n device_type: string;\n page_entry_path: string;\n utm_medium: string;\n utm_source: string;\n utm_campaign: string;\n utm_content: string;\n utm_term: string;\n referrer_url: string;\n gclid: string;\n fbclid: string;\n pins_campaign_id: string;\n epik: string;\n}\n\nexport function parseAddViewData(params: {\n referrer?: string;\n entryPage?: string;\n userAgent?: string;\n}): ParsedViewData {\n const { referrer, entryPage, userAgent } = params;\n\n const data: ParsedViewData = {\n referrer_source: \"\",\n browser_info: \"\",\n os_info: \"\",\n device_type: \"\",\n page_entry_path: \"\",\n utm_medium: \"\",\n utm_source: \"\",\n utm_campaign: \"\",\n utm_content: \"\",\n utm_term: \"\",\n referrer_url: referrer || \"\",\n gclid: \"\",\n fbclid: \"\",\n pins_campaign_id: \"\",\n epik: \"\",\n };\n\n try {\n let siteHostname: string | undefined;\n if (entryPage && entryPage.trim() !== '' && entryPage.startsWith('http')) {\n try {\n const entryObj = new URL(entryPage);\n const entryPath = entryObj?.pathname;\n siteHostname = entryObj?.hostname;\n if (entryPath) {\n data.page_entry_path = entryPath ?? \"\";\n }\n const entryQueryParams = getQueryParams(entryObj);\n data.utm_medium = entryQueryParams[\"utm_medium\"] ?? \"\";\n data.utm_source = entryQueryParams[\"utm_source\"] ?? \"\";\n data.utm_campaign = entryQueryParams[\"utm_campaign\"] ?? \"\";\n data.utm_content = entryQueryParams[\"utm_content\"] ?? \"\";\n data.utm_term = entryQueryParams[\"utm_term\"] ?? \"\";\n data.gclid = entryQueryParams[\"gclid\"] ?? \"\";\n data.fbclid = entryQueryParams[\"fbclid\"] ?? \"\";\n data.pins_campaign_id = entryQueryParams[\"pins_campaign_id\"] ?? \"\";\n data.epik = entryQueryParams[\"epik\"] ?? \"\";\n } catch {\n // Silently handle invalid URLs - entry page might be invalid in some contexts\n }\n }\n\n if (userAgent) {\n const userAgentObj = UAParser(userAgent);\n const browser = userAgentObj?.browser?.name;\n const browserName = getBrowserName(browser);\n data.browser_info = browserName ?? \"\";\n data.os_info = userAgentObj?.os?.name ?? \"\";\n if (userAgent) {\n data.device_type =\n (userAgentObj?.device?.type || \"desktop\")?.toUpperCase() ?? \"\";\n }\n }\n\n data.referrer_source =\n parseReferrer(referrer, data?.browser_info, siteHostname) ?? \"\";\n return data;\n } catch {\n // Return partial data on parse error\n return data;\n }\n}\n\n/**\n * Get page type from pathname\n */\nexport function getPageTypeFromPathname(\n path: string,\n hasLocalizedPaths?: boolean\n): string {\n const hasNormalPath = path === \"/\" || path === \"\";\n\n // Check if this is a localized homepage (e.g., /en-us/, /fr-ca/)\n const localizedHomepagePattern = /^\\/[a-z]{2}(-[a-z]{2})?\\/?$/i;\n const isLocalizedHomepage =\n hasLocalizedPaths && localizedHomepagePattern.test(path);\n\n if (hasNormalPath || isLocalizedHomepage) {\n return \"index\";\n }\n\n if (/\\/products\\//.test(path)) {\n return \"product\";\n }\n\n if (/\\/collections\\//.test(path)) {\n return \"collection\";\n }\n\n if (/\\/pages\\//.test(path)) {\n return \"page\";\n }\n if (/\\/search/.test(path)) {\n return \"search\";\n }\n\n if (/\\/cart/.test(path)) {\n return \"cart\";\n }\n\n if (/\\/checkouts\\//.test(path)) {\n return \"checkout\";\n }\n\n return \"unknown\";\n}\n\n/**\n * Check if visitor ID is in URL params\n */\nexport function checkVisitorIdParams(searchParams: string): string | false {\n try {\n if (!searchParams) return false;\n const params = new URLSearchParams(searchParams);\n return params.get(\"eabUserId\") || false;\n } catch {\n // URL parsing failed, return false\n return false;\n }\n}\n\n/**\n * Get user agent string without browser info\n * Used for more consistent user fingerprinting\n */\nexport function getUserAgentNoBrowser(userAgent: string): string {\n if (!userAgent) return \"\";\n\n try {\n const userAgentObj = UAParser(userAgent);\n const os = userAgentObj?.os;\n const device = userAgentObj?.device;\n\n let result = \"\";\n if (os?.name) {\n result += os.name;\n if (os.version) result += ` ${os.version}`;\n }\n if (device?.type) {\n result += result ? ` (${device.type})` : device.type;\n }\n if (device?.vendor) {\n result += result ? ` ${device.vendor}` : device.vendor;\n }\n if (device?.model) {\n result += result ? ` ${device.model}` : device.model;\n }\n\n return result || userAgent;\n } catch {\n return userAgent;\n }\n}\n","/**\n * Shopify-specific utilities\n */\n\n/**\n * Extract numeric ID from a Shopify Global ID (GID).\n *\n * Shopify uses GIDs like \"gid://shopify/Product/123456789\" or \"gid://shopify/ProductVariant/987654321\".\n * This utility extracts the numeric ID portion.\n *\n * @param gid - Shopify Global ID or numeric ID string\n * @returns The numeric ID portion (e.g., \"123456789\")\n *\n * @example\n * ```ts\n * extractShopifyId(\"gid://shopify/Product/123456789\"); // \"123456789\"\n * extractShopifyId(\"gid://shopify/ProductVariant/987654321\"); // \"987654321\"\n * extractShopifyId(\"gid://shopify/Cart/abc123\"); // \"abc123\"\n * extractShopifyId(\"123456789\"); // \"123456789\" (already numeric)\n * ```\n */\nexport function extractShopifyId(gid: string | null | undefined): string {\n if (!gid) return \"\";\n\n // If it's a GID, extract the last segment\n if (gid.includes(\"gid://\")) {\n return gid.split(\"/\").pop() || gid;\n }\n\n // Already a plain ID\n return gid;\n}\n\n/**\n * Extract the resource type from a Shopify Global ID.\n *\n * @param gid - Shopify Global ID\n * @returns The resource type (e.g., \"Product\", \"ProductVariant\", \"Cart\")\n *\n * @example\n * ```ts\n * extractShopifyType(\"gid://shopify/Product/123\"); // \"Product\"\n * extractShopifyType(\"gid://shopify/ProductVariant/456\"); // \"ProductVariant\"\n * extractShopifyType(\"123456789\"); // null (not a GID)\n * ```\n */\nexport function extractShopifyType(\n gid: string | null | undefined,\n): string | null {\n if (!gid || !gid.includes(\"gid://\")) return null;\n\n const parts = gid.split(\"/\");\n // gid://shopify/Product/123 -> parts = [\"gid:\", \"\", \"shopify\", \"Product\", \"123\"]\n return parts[3] || null;\n}\n\n/**\n * Check if a string is a Shopify Global ID.\n *\n * @param value - String to check\n * @returns True if it's a GID\n *\n * @example\n * ```ts\n * isShopifyGid(\"gid://shopify/Product/123\"); // true\n * isShopifyGid(\"123456789\"); // false\n * ```\n */\nexport function isShopifyGid(value: string | null | undefined): boolean {\n return !!value && value.startsWith(\"gid://shopify/\");\n}\n\n/**\n * Try to detect the shop currency from Shopify's global object.\n * Only works on Shopify theme stores, not headless.\n *\n * @returns Currency code (e.g., \"USD\") or undefined\n */\nexport function detectShopifyCurrency(): string | undefined {\n if (typeof window === \"undefined\") return undefined;\n\n // Try Shopify's global currency object (theme stores only)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const shopify = (window as any).Shopify;\n if (shopify?.currency?.active) {\n return shopify.currency.active;\n }\n\n return undefined;\n}\n","/**\n * Manual tracking functions for non-Hydrogen frameworks (Next.js, etc.)\n *\n * Initialize once with initAnalytics(), then call tracking functions without params:\n *\n * @example\n * ```tsx\n * // In your layout/provider (once)\n * initAnalytics({\n * storeId: 'your-store.myshopify.com',\n * storefrontAccessToken: 'your-token',\n * });\n *\n * // Then anywhere in your app (no params needed)\n * trackPageView();\n * trackAddToCart({ cartId, productId, ... });\n * ```\n */\n\nimport type {\n EventPayload,\n TestAssignment,\n TrackPageViewParams,\n TrackProductViewParams,\n TrackAddToCartParams,\n TrackRemoveFromCartParams,\n TrackCartViewParams,\n TrackSearchSubmittedParams,\n TrackCheckoutStartedParams,\n TrackCheckoutCompletedParams,\n} from \"../types\";\n\nimport { extractShopifyId } from \"./shopify\";\n\n// Re-import types for cleaner syntax below\nimport type { UsePageViewTrackingParams } from \"../types\";\nimport {\n parseAddViewData,\n extractCartToken,\n cleanCartToken,\n getPageTypeFromPathname,\n sanitizeString,\n roundToTwo,\n getUserAgentNoBrowser,\n} from \"./analytics\";\nimport {\n getVisitorId,\n getSessionId,\n getCookie,\n getJsonCookie,\n getReferrerData,\n uuidv4,\n} from \"./storage\";\n\nconst DEFAULT_WORKER_URL = \"https://bitter-river-9c62.support-67d.workers.dev\";\nconst DEFAULT_ORDERS_WORKER_URL =\n \"https://d339co84ntxcme.cloudfront.net/Prod/orders\";\n\n// ============================================================================\n// GLOBAL ANALYTICS CONFIG (initialized once, used by all tracking functions)\n// ============================================================================\n\ninterface AnalyticsConfig {\n storeId: string;\n storefrontAccessToken?: string;\n hasLocalizedPaths?: boolean;\n workerUrl?: string;\n ordersWorkerUrl?: string;\n}\n\nlet globalConfig: AnalyticsConfig | null = null;\n\n/**\n * Initialize analytics config once. Call this in your app's entry point or layout.\n * After init, tracking functions don't need storeId/token params.\n *\n * @example\n * ```tsx\n * // In _app.tsx or layout.tsx\n * initAnalytics({\n * storeId: 'your-store.myshopify.com',\n * storefrontAccessToken: process.env.NEXT_PUBLIC_STOREFRONT_TOKEN,\n * });\n * ```\n */\nexport function initAnalytics(config: AnalyticsConfig): void {\n globalConfig = config;\n}\n\n/**\n * Get the current analytics config (for internal use)\n */\nexport function getAnalyticsConfig(): AnalyticsConfig | null {\n return globalConfig;\n}\n\n/**\n * Check if analytics is initialized\n */\nexport function isAnalyticsInitialized(): boolean {\n return globalConfig !== null;\n}\n\n// Helper to get storeId from params or global config\nfunction getStoreId(params?: { storeId?: string }): string {\n const storeId = params?.storeId || globalConfig?.storeId;\n if (!storeId) {\n console.warn(\n \"[ElevateAB] No storeId provided. Call initAnalytics() first or pass storeId to tracking function.\",\n );\n return \"\";\n }\n return storeId;\n}\n\n// Transform test list format to event format\nfunction transformTestFormat(\n testObject: Record<string, string>,\n): TestAssignment[] {\n return Object.entries(testObject)\n .filter(([, variationId]) => typeof variationId === \"string\")\n .map(([testId, variationId]) => ({\n test_id: testId,\n variant_id: variationId,\n }));\n}\n\n// Transform viewed tests format\nfunction transformViewedTests(\n viewedObject: Record<string, boolean>,\n assignmentObject: Record<string, string>,\n): TestAssignment[] {\n return Object.entries(viewedObject)\n .filter(([testId]) => typeof assignmentObject[testId] === \"string\")\n .map(([testId]) => ({\n test_id: testId,\n variant_id: assignmentObject[testId],\n }));\n}\n\n// Check if we're in preview mode (should skip analytics)\nfunction isInPreviewMode(): boolean {\n if (typeof window === \"undefined\") return false;\n\n // Check cookie\n if (getCookie(\"eabUserPreview\") === \"true\") return true;\n\n // Check URL param\n const urlParams = new URLSearchParams(window.location.search);\n if (urlParams.get(\"eabUserPreview\") === \"true\") return true;\n\n return false;\n}\n\n// Create base event data (returns null if in preview mode)\nfunction createBaseEventData(\n storeId: string,\n eventType: string,\n hasLocalizedPaths?: boolean,\n): Partial<EventPayload> | null {\n if (typeof window === \"undefined\") return null;\n\n // Skip tracking in preview mode to avoid polluting analytics\n if (isInPreviewMode()) {\n return null;\n }\n\n const userAgent = navigator.userAgent;\n const pathname = window.location.pathname;\n const pageType = getPageTypeFromPathname(pathname, hasLocalizedPaths);\n\n const { referrer, entryPage } = getReferrerData();\n\n const parsedData = parseAddViewData({\n referrer,\n entryPage,\n userAgent,\n });\n\n const abtlObject = getJsonCookie<Record<string, string>>(\"ABTL\") || {};\n const abauObject = getJsonCookie<Record<string, boolean>>(\"ABAU\") || {};\n\n const testAssignments = transformTestFormat(abtlObject);\n const viewedTests = transformViewedTests(abauObject, abtlObject);\n\n const cartToken = extractCartToken(localStorage.getItem(\"shopifyCartId\"));\n const currentTimestamp = new Date().toISOString();\n\n // Get additional state\n const isFirstVisit = sessionStorage.getItem(\"eabIsFirstVisit\") === \"true\";\n const shopifyCountry = getCookie(\"localization\") || \"\";\n\n return {\n pixel_event_id: `sh-${uuidv4()}`,\n shop_name: storeId,\n timestamp: currentTimestamp,\n event_type: eventType,\n client_id: getCookie(\"_shopify_y\") || undefined,\n visitor_id: getVisitorId(),\n session_id: getSessionId(),\n cart_token: cleanCartToken(cartToken || getCookie(\"cart\")),\n\n page_url: window.location.href,\n page_pathname: pathname,\n page_search: window.location.search,\n referrer_url: referrer,\n referrer_source: parsedData?.referrer_source,\n previous_page: document.referrer,\n page_entry: entryPage,\n page_entry_path: parsedData?.page_entry_path,\n page_type: pageType,\n\n utm_medium: parsedData?.utm_medium,\n utm_source: parsedData?.utm_source,\n utm_campaign: parsedData?.utm_campaign,\n utm_content: parsedData?.utm_content,\n utm_term: parsedData?.utm_term,\n\n gclid: parsedData?.gclid,\n fbclid: parsedData?.fbclid,\n pins_campaign_id: parsedData?.pins_campaign_id,\n epik: parsedData?.epik,\n\n browser_info: parsedData?.browser_info,\n os_info: parsedData?.os_info,\n device_type: parsedData?.device_type,\n language: navigator.language,\n root_route: localStorage.getItem(\"eabRootRoute\") || \"\",\n user_agent: userAgent,\n user_agent_no_browser: getUserAgentNoBrowser(userAgent),\n\n is_first_visit: isFirstVisit,\n shopify_country: shopifyCountry,\n\n ab_test_assignments: testAssignments,\n ab_test_views: viewedTests,\n is_first_order: null,\n };\n}\n\n// Send event to CloudFlare Worker\nasync function sendEvent(\n data: Partial<EventPayload>,\n workerUrl: string = DEFAULT_WORKER_URL,\n): Promise<void> {\n try {\n const response = await fetch(workerUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(data),\n keepalive: true,\n });\n\n if (!response.ok) {\n throw new Error(`Worker error: ${response.status}`);\n }\n } catch (error) {\n console.error(\"[ElevateAB] Error sending analytics:\", error);\n }\n}\n\n/**\n * Track page view event\n * Call this on route changes or in useEffect\n *\n * @example After initAnalytics()\n * ```ts\n * await trackPageView(); // No params needed!\n * ```\n *\n * @example Without init (pass params)\n * ```ts\n * await trackPageView({ storeId: \"mystore.myshopify.com\" });\n * ```\n */\nexport async function trackPageView(\n params: Partial<TrackPageViewParams> = {},\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n\n const baseData = createBaseEventData(\n storeId,\n \"page_viewed\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: params.currency,\n };\n\n await sendEvent(eventData, workerUrl);\n}\n\n/**\n * Track product view event\n * Call this on product pages\n *\n * @example After initAnalytics()\n * ```ts\n * await trackProductView({ productId: \"123\", productPrice: 99.99 });\n * ```\n */\nexport async function trackProductView(\n params: Omit<TrackProductViewParams, \"storeId\"> & { storeId?: string },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const { productId, productVendor, productPrice, productSku, currency } =\n params;\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n\n const baseData = createBaseEventData(\n storeId,\n \"product_viewed\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n product_id: extractShopifyId(productId),\n product_vendor: sanitizeString(productVendor),\n product_price: roundToTwo(productPrice),\n product_sku: sanitizeString(productSku),\n };\n\n await sendEvent(eventData, workerUrl);\n}\n\n/**\n * Track add to cart event\n * Call this when user clicks \"Add to Cart\"\n *\n * Cart attributes are automatically updated for order attribution if\n * storefrontAccessToken was provided to initAnalytics() or passed here.\n *\n * @example After initAnalytics()\n * ```ts\n * await trackAddToCart({\n * cartId: \"gid://shopify/Cart/abc123\",\n * productId: \"123456789\",\n * variantId: \"987654321\",\n * productPrice: 99.99,\n * productQuantity: 1,\n * });\n * ```\n */\nexport async function trackAddToCart(\n params: Omit<TrackAddToCartParams, \"storeId\" | \"storefrontAccessToken\"> & {\n storeId?: string;\n storefrontAccessToken?: string;\n },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const {\n productId,\n variantId,\n productVendor,\n productPrice,\n productQuantity,\n productSku,\n currency,\n cartId,\n } = params;\n\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n const storefrontAccessToken =\n params.storefrontAccessToken ?? globalConfig?.storefrontAccessToken;\n\n const baseData = createBaseEventData(\n storeId,\n \"product_added_to_cart\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n product_id: extractShopifyId(productId),\n variant_id: extractShopifyId(variantId),\n product_vendor: sanitizeString(productVendor),\n product_price: roundToTwo(productPrice),\n product_quantity: productQuantity,\n product_sku: sanitizeString(productSku),\n };\n\n await sendEvent(eventData, workerUrl);\n\n // Auto-update cart attributes if cartId and token are available\n if (cartId && storefrontAccessToken) {\n try {\n const { updateCartAttributes } = await import(\"./cartAttributes\");\n await updateCartAttributes(cartId, { storefrontAccessToken });\n } catch (err) {\n console.error(\"[ElevateAB] Failed to update cart attributes:\", err);\n }\n }\n}\n\n/**\n * Track remove from cart event\n * Call this when user removes item from cart\n */\nexport async function trackRemoveFromCart(\n params: Omit<TrackRemoveFromCartParams, \"storeId\"> & { storeId?: string },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const {\n productId,\n variantId,\n productVendor,\n productPrice,\n productQuantity,\n productSku,\n currency,\n } = params;\n\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n\n const baseData = createBaseEventData(\n storeId,\n \"product_removed_from_cart\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n product_id: extractShopifyId(productId),\n variant_id: extractShopifyId(variantId),\n product_vendor: sanitizeString(productVendor),\n product_price: roundToTwo(productPrice),\n product_quantity: productQuantity,\n product_sku: sanitizeString(productSku),\n };\n\n await sendEvent(eventData, workerUrl);\n}\n\n/**\n * Track cart view event\n * Call this when user views cart page\n */\nexport async function trackCartView(\n params: Omit<TrackCartViewParams, \"storeId\"> & { storeId?: string },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const { cartTotalPrice, cartTotalQuantity, cartItems, currency } = params;\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n\n const baseData = createBaseEventData(\n storeId,\n \"cart_viewed\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n cart_total_price: roundToTwo(cartTotalPrice),\n cart_total_quantity: cartTotalQuantity,\n cart_items: cartItems?.map((item) => ({\n product_id: extractShopifyId(item.productId),\n variant_id: extractShopifyId(item.variantId),\n product_vendor: sanitizeString(item.productVendor) || \"\",\n product_price: roundToTwo(item.productPrice),\n product_quantity: item.productQuantity ?? null,\n product_sku: sanitizeString(item.productSku) || \"\",\n })),\n };\n\n await sendEvent(eventData, workerUrl);\n}\n\n/**\n * Track search submitted event\n * Call this when user submits a search\n *\n * @example After initAnalytics()\n * ```ts\n * await trackSearchSubmitted({ searchQuery: \"running shoes\" });\n * ```\n *\n * @example Without init (pass params)\n * ```ts\n * await trackSearchSubmitted({\n * storeId: \"mystore.myshopify.com\",\n * searchQuery: \"running shoes\",\n * currency: \"USD\"\n * });\n * ```\n */\nexport async function trackSearchSubmitted(\n params: Omit<TrackSearchSubmittedParams, \"storeId\"> & { storeId?: string },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const { searchQuery, currency } = params;\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n\n const baseData = createBaseEventData(\n storeId,\n \"search_submitted\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n search_query: sanitizeString(searchQuery),\n };\n\n await sendEvent(eventData, workerUrl);\n}\n\n/**\n * Track checkout started event\n * Call this when user starts checkout\n *\n * @example After initAnalytics()\n * ```ts\n * await trackCheckoutStarted({\n * cartTotalPrice: 109.98,\n * cartItems: [...],\n * });\n * ```\n */\nexport async function trackCheckoutStarted(\n params: Omit<TrackCheckoutStartedParams, \"storeId\"> & { storeId?: string },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const {\n cartTotalPrice,\n cartSubtotalPrice,\n cartShippingPrice,\n cartTaxAmount,\n cartDiscountAmount,\n customerId,\n cartItems,\n currency,\n } = params;\n\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n\n const baseData = createBaseEventData(\n storeId,\n \"checkout_started\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n let totalQuantity = 0;\n const items =\n cartItems?.map((item) => {\n const quantity = item.productQuantity ?? 0;\n totalQuantity += quantity;\n return {\n product_id: extractShopifyId(item.productId),\n variant_id: extractShopifyId(item.variantId),\n product_vendor: sanitizeString(item.productVendor) || \"\",\n vendor: sanitizeString(item.productVendor) || \"\",\n product_price: roundToTwo(item.productPrice),\n total_price: roundToTwo(item.productPrice),\n product_quantity: quantity,\n quantity: quantity,\n product_sku: sanitizeString(item.productSku) || \"\",\n sku: sanitizeString(item.productSku) || \"\",\n total_discount: roundToTwo(item.totalDiscount),\n };\n }) || [];\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n cart_total_price: roundToTwo(cartTotalPrice),\n cart_subtotal_price: roundToTwo(cartSubtotalPrice),\n cart_total_quantity: totalQuantity,\n cart_shipping_price: roundToTwo(cartShippingPrice),\n cart_tax_amount: roundToTwo(cartTaxAmount),\n cart_discount_amount: roundToTwo(cartDiscountAmount),\n cart_items: items,\n customer_id: customerId,\n };\n\n await sendEvent(eventData, workerUrl);\n}\n\n/**\n * Track checkout completed event (order placed)\n * Call this when order is placed\n *\n * NOTE: This sends to a different endpoint (orders worker)\n *\n * @example After initAnalytics()\n * ```ts\n * await trackCheckoutCompleted({\n * orderId: \"order_123456\",\n * cartTotalPrice: 109.98,\n * cartItems: [...],\n * });\n * ```\n */\nexport async function trackCheckoutCompleted(\n params: Omit<TrackCheckoutCompletedParams, \"storeId\"> & { storeId?: string },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const {\n orderId,\n cartTotalPrice,\n cartSubtotalPrice,\n cartShippingPrice,\n cartTaxAmount,\n cartDiscountAmount,\n customerId,\n isFirstOrder,\n noteAttributes,\n cartItems,\n currency,\n } = params;\n\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const ordersWorkerUrl =\n params.ordersWorkerUrl ??\n globalConfig?.ordersWorkerUrl ??\n DEFAULT_ORDERS_WORKER_URL;\n\n const baseData = createBaseEventData(\n storeId,\n \"checkout_completed\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n let totalQuantity = 0;\n const items =\n cartItems?.map((item) => {\n const quantity = item.productQuantity ?? 0;\n totalQuantity += quantity;\n return {\n product_id: extractShopifyId(item.productId),\n variant_id: extractShopifyId(item.variantId),\n product_vendor: sanitizeString(item.productVendor) || \"\",\n vendor: sanitizeString(item.productVendor) || \"\",\n product_price: roundToTwo(item.productPrice),\n total_price: roundToTwo(item.productPrice),\n product_quantity: quantity,\n quantity: quantity,\n product_sku: sanitizeString(item.productSku) || \"\",\n sku: sanitizeString(item.productSku) || \"\",\n total_discount: roundToTwo(item.totalDiscount),\n };\n }) || [];\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n cart_total_price: roundToTwo(cartTotalPrice),\n cart_subtotal_price: roundToTwo(cartSubtotalPrice),\n cart_total_quantity: totalQuantity,\n cart_shipping_price: roundToTwo(cartShippingPrice),\n cart_tax_amount: roundToTwo(cartTaxAmount),\n cart_discount_amount: roundToTwo(cartDiscountAmount),\n cart_items: items,\n order_id: orderId,\n customer_id: customerId,\n is_first_order: isFirstOrder ?? null,\n note_attributes: noteAttributes,\n };\n\n // Send to orders worker (different endpoint!)\n await sendEvent(eventData, ordersWorkerUrl);\n}\n\nimport { useEffect, useRef, useState } from \"react\";\n\n/**\n * Hook for automatic page view tracking on route changes\n * Use in Next.js app router or any React app\n *\n * NOTE: For Next.js App Router, consider using this with `usePathname()`:\n * ```tsx\n * const pathname = usePathname();\n * usePageViewTracking({ pathname, enabled: true });\n * ```\n *\n * @example Basic usage (tracks on mount only)\n * ```tsx\n * function Layout({ children }) {\n * usePageViewTracking({ enabled: true });\n * return <>{children}</>;\n * }\n * ```\n *\n * @example With Next.js usePathname (tracks on route changes)\n * ```tsx\n * import { usePathname } from 'next/navigation';\n *\n * function Layout({ children }) {\n * const pathname = usePathname();\n * usePageViewTracking({ pathname, enabled: true });\n * return <>{children}</>;\n * }\n * ```\n */\nexport function usePageViewTracking(\n params: UsePageViewTrackingParams & { pathname?: string },\n): void {\n const {\n storeId,\n hasLocalizedPaths,\n currency,\n workerUrl,\n enabled = true,\n pathname: externalPathname,\n } = params;\n\n // Track the last pathname we've sent an event for\n const lastTrackedPathRef = useRef<string | null>(null);\n\n // Use external pathname if provided (e.g., from Next.js usePathname),\n // otherwise try to get it from window (works on mount)\n const [currentPath, setCurrentPath] = useState<string>(() => {\n if (externalPathname) return externalPathname;\n if (typeof window !== \"undefined\") return window.location.pathname;\n return \"\";\n });\n\n // Update currentPath when externalPathname changes\n useEffect(() => {\n if (externalPathname) {\n setCurrentPath(externalPathname);\n }\n }, [externalPathname]);\n\n // Track page view when path changes\n useEffect(() => {\n if (typeof window === \"undefined\" || !enabled) return;\n\n // Don't track if we've already tracked this path\n if (lastTrackedPathRef.current === currentPath) return;\n\n // Track the page view\n lastTrackedPathRef.current = currentPath;\n trackPageView({ storeId, hasLocalizedPaths, currency, workerUrl });\n }, [currentPath, storeId, hasLocalizedPaths, currency, workerUrl, enabled]);\n}\n","import React from \"react\";\nimport type { Variation } from \"../types\";\nimport { useElevateConfig } from \"../contexts/ElevateContext\";\nimport { getVisitorId } from \"../utils/storage\";\nimport { assignAndPersistVariant, shouldShowTest } from \"../utils/assignment\";\nimport { trackViews } from \"../utils/tracking\";\n\nexport interface UseExperimentResult {\n /** The full variant object (null if not assigned) */\n variant: Variation | null;\n /** True while loading config */\n isLoading: boolean;\n /** True if assigned to control group */\n isControl: boolean;\n /** True if assigned to variation A (first non-control) */\n isA: boolean;\n /** True if assigned to variation B (second non-control) */\n isB: boolean;\n /** True if assigned to variation C (third non-control) */\n isC: boolean;\n /** True if assigned to variation D (fourth non-control) */\n isD: boolean;\n}\n\n/**\n * Hook to get assigned variant for a test\n * \n * @example\n * ```tsx\n * const { isControl, isA, isB } = useExperiment('my-test');\n * \n * if (isControl) return <Original />;\n * if (isA) return <VariantA />;\n * if (isB) return <VariantB />;\n * ```\n */\nexport function useExperiment(testId: string): UseExperimentResult {\n const { config } = useElevateConfig();\n const [variant, setVariant] = React.useState<Variation | null>(null);\n const [isLoading, setIsLoading] = React.useState(true);\n\n const testConfig = React.useMemo(() => {\n if (!config) return null;\n return config.tests.find((test) => test.testId === testId) || null;\n }, [config, testId]);\n\n // Track if we've already warned about this test (prevent duplicate warnings)\n const hasWarnedRef = React.useRef<string | null>(null);\n\n React.useEffect(() => {\n // Wait for config to load before doing anything\n if (config === null) {\n return; // Still loading config\n }\n\n // Config loaded but test not found\n if (!testConfig) {\n if (hasWarnedRef.current !== testId) {\n hasWarnedRef.current = testId;\n console.warn(`[ElevateAB] Test not found: ${testId}`);\n }\n setIsLoading(false);\n return;\n }\n\n // Test exists but is disabled\n if (!testConfig.enabled) {\n if (hasWarnedRef.current !== `${testId}-disabled`) {\n hasWarnedRef.current = `${testId}-disabled`;\n console.warn(`[ElevateAB] Test disabled: ${testId}`);\n }\n setIsLoading(false);\n return;\n }\n\n // Check traffic percentage\n if (!shouldShowTest(testConfig)) {\n setIsLoading(false);\n return;\n }\n\n // Get or create visitor ID\n const userId = getVisitorId();\n\n // Assign variant (sets isControl, isA, isB, isC, isD)\n const assigned = assignAndPersistVariant(testId, testConfig, userId);\n\n if (assigned) {\n setVariant(assigned);\n trackViews(testId);\n }\n\n setIsLoading(false);\n }, [config, testConfig, testId]);\n\n return { \n variant, \n isLoading, \n isControl: variant?.isControl ?? false,\n isA: variant?.isA ?? false,\n isB: variant?.isB ?? false,\n isC: variant?.isC ?? false,\n isD: variant?.isD ?? false,\n };\n}\n","import React from \"react\";\nimport type { ElevateContextValue } from \"../types\";\n\nexport const ElevateContext = React.createContext<ElevateContextValue | null>(\n null\n);\n\n/**\n * Hook to access Elevate config from context\n */\nexport function useElevateConfig(): ElevateContextValue {\n const context = React.useContext(ElevateContext);\n\n if (context === null) {\n throw new Error(\"useElevateConfig must be used within ElevateProvider\");\n }\n\n return context;\n}\n","import React, { useRef, useCallback } from \"react\";\nimport type { ElevateConfig, BackendConfig } from \"../types\";\nimport { ElevateContext } from \"../contexts/ElevateContext\";\nimport { parseBackendConfig } from \"../utils\";\nimport { initAnalytics } from \"../utils/manualTracking\";\nimport { getPreviewState, type PreviewState } from \"../utils/preview\";\nimport { getCountryCode } from \"../utils/geo\";\nimport { setupFlickerPrevention } from \"../utils/antiFlicker\";\n\n/**\n * Set to false during local development to use fallback config.\n * In production, this should always be true.\n */\nconst USE_CDN_CONFIG = false; // Set to false for demo/development\n\n/**\n * Fallback config for local development/testing when CDN is not available.\n * Only used when USE_CDN_CONFIG = false.\n *\n * Supported test types: SPLIT_URL, PRICE_PLUS, CONTENT, CUSTOM_CODE\n */\nconst DEV_FALLBACK_CONFIG: BackendConfig = {\n allTests: {\n // Price Plus Test - Testing different price points\n \"price-test-001\": {\n \"8606\": {\n variationName: \"Control\",\n trafficPercentage: 50,\n isDone: false,\n isControl: true,\n },\n \"8607\": {\n variationName: \"Sale Price\",\n trafficPercentage: 50,\n isDone: false,\n prices: {\n \"41883969519701\": {\n main: \"USD\",\n price: { USD: \"599.95\" },\n compare: { USD: \"699.95\" },\n },\n },\n },\n data: {\n name: \"Snowboard Price Test\",\n isLive: true,\n settings: { afterDiscounts: true },\n type: \"PRICE_PLUS\",\n filters: [],\n isPersonalization: false,\n currencies: [\"USD\"],\n handles: [\"the-complete-snowboard\"],\n productIds: [\"7240161067093\"],\n },\n },\n\n // Content Test - Simple A/B/C headline test\n \"content-test-001\": {\n \"ctrl-001\": {\n variationName: \"Control\",\n trafficPercentage: 34,\n isDone: false,\n isControl: true,\n content: {\n headline: \"Welcome to our store\",\n subheadline: \"Shop the best products\",\n },\n },\n \"var-a-001\": {\n variationName: \"Urgency Copy\",\n trafficPercentage: 33,\n isDone: false,\n content: {\n headline: \"Limited Time Offer!\",\n subheadline: \"Don't miss out - sale ends soon\",\n },\n },\n \"var-b-001\": {\n variationName: \"Value Copy\",\n trafficPercentage: 33,\n isDone: false,\n content: {\n headline: \"Premium Quality, Great Value\",\n subheadline: \"Free shipping on orders over $50\",\n },\n },\n data: {\n name: \"Homepage Headline Test\",\n isLive: true,\n settings: { afterDiscounts: true },\n type: \"CONTENT\",\n filters: [],\n isPersonalization: false,\n pathnames: [\"/\"],\n },\n },\n\n // Custom Code Test - Injecting custom JS/CSS\n \"custom-code-test-001\": {\n \"10150\": {\n variationName: \"Control\",\n trafficPercentage: 50,\n isDone: false,\n customCode: {\n id: \"c11a582c-6b27-4263-941c-8ed123437c6b\",\n js: \"console.log('[Elevate] Control variant active');\",\n css: \"\",\n pathnames: [\"*\"],\n excludePathnames: [],\n },\n isControl: true,\n },\n \"10151\": {\n variationName: \"Enhanced UI\",\n trafficPercentage: 50,\n isDone: false,\n customCode: {\n id: \"df71546a-0a5f-4ad0-8d0f-a1bdeab05e84\",\n js: \"console.log('[Elevate] Enhanced UI variant'); document.body.style.borderTop = '3px solid #10b981';\",\n css: \".hero-section { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }\",\n pathnames: [\"*\"],\n excludePathnames: [],\n },\n },\n data: {\n name: \"Custom Code Enhancement\",\n isLive: true,\n settings: { afterDiscounts: true },\n type: \"CUSTOM_CODE\",\n filters: [],\n isPersonalization: false,\n pathnames: [\"*\"],\n excludePathnames: [],\n },\n },\n\n // Split URL Test - Redirect to different landing pages\n \"split-url-test-001\": {\n \"split-ctrl\": {\n variationName: \"Control\",\n trafficPercentage: 50,\n isDone: false,\n isControl: true,\n splitUrlTestLinks: {\n default: \"/collections/all\",\n },\n },\n \"split-var-a\": {\n variationName: \"New Landing Page\",\n trafficPercentage: 50,\n isDone: false,\n splitUrlTestLinks: {\n default: \"/collections/featured\",\n },\n },\n data: {\n name: \"Landing Page Split Test\",\n isLive: true,\n settings: { afterDiscounts: true },\n type: \"SPLIT_URL\",\n filters: [],\n isPersonalization: false,\n pathnames: [\"/promo\"],\n },\n },\n },\n selectors: { selectorsV2: [] },\n};\n\ninterface ElevateProviderSimpleProps {\n /** Shopify store domain (e.g., \"your-store.myshopify.com\") */\n storeId: string;\n /**\n * Storefront Access Token - Required for cart attribute tracking (order attribution)\n *\n * This 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 * Without this token, A/B tests work but orders won't be attributed to variants.\n */\n storefrontAccessToken?: string;\n /**\n * Enable flicker prevention - hides content until test assignment is complete\n * Prevents users from seeing content flash/change when variants load\n * @default false\n */\n preventFlickering?: boolean;\n /**\n * Timeout in milliseconds for flicker prevention failsafe\n * Content will show after this time even if assignment isn't complete\n * @default 3000\n */\n flickerTimeout?: number;\n children: React.ReactNode;\n}\n\n/**\n * ElevateProvider - Provides A/B test configuration to child components\n *\n * @example Next.js / Remix\n * ```tsx\n * <ElevateProvider\n * storeId=\"your-store.myshopify.com\"\n * storefrontAccessToken=\"your-public-token\"\n * >\n * <App />\n * </ElevateProvider>\n * ```\n *\n * @example Hydrogen (with Analytics.Provider)\n * ```tsx\n * <Analytics.Provider cart={cart} shop={shop} consent={consent}>\n * <ElevateProvider storeId=\"your-store.myshopify.com\" storefrontAccessToken=\"token\">\n * <ElevateAnalytics />\n * <App />\n * </ElevateProvider>\n * </Analytics.Provider>\n * ```\n */\nexport function ElevateProvider({\n storeId,\n storefrontAccessToken,\n preventFlickering = false,\n flickerTimeout = 3000,\n children,\n}: ElevateProviderSimpleProps) {\n const [config, setConfig] = React.useState<ElevateConfig | null>(null);\n const [previewState, setPreviewState] = React.useState<PreviewState | null>(\n null,\n );\n const [countryCode, setCountryCode] = React.useState<string | null>(null);\n const revealRef = useRef<(() => void) | null>(null);\n\n // Setup flicker prevention on mount (before config loads)\n React.useEffect(() => {\n if (preventFlickering && typeof window !== \"undefined\") {\n revealRef.current = setupFlickerPrevention(\"body\", flickerTimeout);\n }\n\n return () => {\n // Cleanup: ensure content is revealed on unmount\n if (revealRef.current) {\n revealRef.current();\n }\n };\n }, [preventFlickering, flickerTimeout]);\n\n // Initialize analytics config so tracking functions don't need storeId\n React.useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n initAnalytics({\n storeId,\n storefrontAccessToken,\n });\n }, [storeId, storefrontAccessToken]);\n\n // Initialize preview state and geo on mount\n React.useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n // Get preview state from URL/cookies\n const preview = getPreviewState();\n setPreviewState(preview);\n\n // Get country code\n const country = getCountryCode();\n setCountryCode(country);\n }, []);\n\n // Reveal callback - called when config is loaded or on error\n const revealContent = useCallback(() => {\n if (revealRef.current) {\n revealRef.current();\n revealRef.current = null;\n }\n }, []);\n\n React.useEffect(() => {\n async function fetchConfig() {\n try {\n // In dev mode, skip CDN fetch and use fallback config directly\n if (!USE_CDN_CONFIG) {\n const parsedConfig = parseBackendConfig(DEV_FALLBACK_CONFIG);\n setConfig(parsedConfig);\n revealContent();\n return;\n }\n\n // Production mode: fetch from CDN\n const url = `https://configs.elevateab.com/config/${storeId}.json`;\n const response = await fetch(url);\n\n if (response.status === 404) {\n // 404 means no config - could be new store or paused subscription\n // Just render children without A/B tests, no error log for this case\n setConfig({ tests: [], selectors: undefined });\n revealContent();\n return;\n }\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch config: ${response.status} ${response.statusText}`,\n );\n }\n\n const backendData: BackendConfig = await response.json();\n\n // Check if subscription is paused/stopped\n if (backendData.subscriptionPaused) {\n console.error(\n `[ElevateAB] Subscription is paused or stopped for store: ${storeId}. ` +\n (backendData.subscriptionMessage || \"A/B tests will not run. Please reactivate your subscription.\"),\n );\n // Graceful degradation - just render children, no A/B tests\n setConfig({ tests: [], selectors: undefined });\n revealContent();\n return;\n }\n\n // Check if config is empty (all tests might have been paused)\n const hasActiveTests = Object.keys(backendData.allTests || {}).length > 0;\n if (!hasActiveTests) {\n // Empty config - could be paused subscription or no active tests\n // Don't log error, just render children normally\n setConfig({ tests: [], selectors: undefined });\n revealContent();\n return;\n }\n\n const parsedConfig = parseBackendConfig(backendData);\n setConfig(parsedConfig);\n revealContent();\n } catch (err) {\n console.error(\"[ElevateAB] Failed to load config:\", err);\n // Graceful degradation - just render children, website doesn't break\n setConfig({ tests: [], selectors: undefined });\n revealContent();\n }\n }\n\n fetchConfig();\n }, [storeId, revealContent]);\n\n const value = React.useMemo(\n () => ({\n config,\n storeId,\n storefrontAccessToken,\n isPreviewMode: previewState?.isPreview ?? false,\n previewTestId: previewState?.previewTestId ?? null,\n countryCode,\n }),\n [config, storeId, storefrontAccessToken, previewState, countryCode],\n );\n\n // Initialize analytics so tracking functions don't need storeId/token each time\n React.useEffect(() => {\n initAnalytics({ storeId, storefrontAccessToken });\n }, [storeId, storefrontAccessToken]);\n\n // Warn once if storefrontAccessToken is missing (order attribution won't work)\n const hasWarnedRef = useRef(false);\n React.useEffect(() => {\n if (!storefrontAccessToken && !hasWarnedRef.current) {\n hasWarnedRef.current = true;\n console.warn(\n \"[ElevateAB] No storefrontAccessToken provided. \" +\n \"A/B tests will work, but orders won't be attributed to test variants. \" +\n \"Add storefrontAccessToken prop to enable order tracking.\",\n );\n }\n }, [storefrontAccessToken]);\n\n return (\n <ElevateContext.Provider value={value}>{children}</ElevateContext.Provider>\n );\n}\n","/**\n * ElevateAnalytics Component\n *\n * Internal component used by ElevateHydrogenAnalytics.\n * Subscribes to Hydrogen analytics events and sends them to Elevate.\n *\n * For Hydrogen stores, use ElevateHydrogenAnalytics instead - it's zero-config!\n * For Next.js/Remix, use manual tracking functions (trackPageView, trackAddToCart, etc.)\n */\n\nimport React, { useEffect, useContext, useRef } from \"react\";\nimport type { EventPayload, TestAssignment } from \"../types\";\nimport { ElevateContext } from \"../contexts/ElevateContext\";\n\n/**\n * Type for useAnalytics hook signature (matches @shopify/hydrogen)\n */\nexport type UseAnalyticsHook = () => {\n subscribe: (event: string, callback: (data: unknown) => void) => void;\n register: (name: string) => { ready: () => void };\n};\n\n/**\n * Props for ElevateHydrogenAnalytics (public API)\n */\nexport interface ElevateHydrogenAnalyticsProps {\n /** Override storeId from context (optional) */\n storeId?: string;\n /** Override storefrontAccessToken from context (optional) */\n storefrontAccessToken?: string;\n /** Enable localized path detection (e.g., /en-us/, /fr-ca/) */\n hasLocalizedPaths?: boolean;\n /** Custom CloudFlare Worker URL */\n workerUrl?: string;\n /** Custom orders worker URL */\n ordersWorkerUrl?: string;\n}\n\n/**\n * Internal props for ElevateAnalytics (requires useAnalytics hook)\n */\ninterface ElevateAnalyticsProps extends ElevateHydrogenAnalyticsProps {\n /** The useAnalytics hook from @shopify/hydrogen (required) */\n useAnalytics: UseAnalyticsHook;\n}\nimport {\n parseAddViewData,\n extractProductId,\n extractProductVariantId,\n extractCartToken,\n cleanCartToken,\n getPageTypeFromPathname,\n sanitizeString,\n roundToTwo,\n getUserAgentNoBrowser,\n} from \"../utils/analytics\";\nimport {\n getVisitorId,\n getSessionId,\n getCookie,\n getJsonCookie,\n setReferrerData,\n getReferrerData,\n} from \"../utils/storage\";\nimport { uuidv4 } from \"../utils/storage\";\nimport { updateCartAttributes } from \"../utils/cartAttributes\";\n\n// Default CloudFlare Worker endpoints\nconst DEFAULT_WORKER_URL = \"https://bitter-river-9c62.support-67d.workers.dev\";\nconst DEFAULT_ORDERS_WORKER_URL =\n \"https://d339co84ntxcme.cloudfront.net/Prod/orders\";\n\n// Generate pixel event ID\nfunction generatePixelEventId(): string {\n return `sh-${uuidv4()}`;\n}\n\n// Transform test list format to event format\nfunction transformTestFormat(\n testObject: Record<string, string>,\n): TestAssignment[] {\n return Object.entries(testObject)\n .filter(([, variationId]) => typeof variationId === \"string\")\n .map(([testId, variationId]) => ({\n test_id: testId,\n variant_id: variationId,\n }));\n}\n\n// Transform viewed tests format\nfunction transformViewedTests(\n viewedObject: Record<string, boolean>,\n assignmentObject: Record<string, string>,\n): TestAssignment[] {\n return Object.entries(viewedObject)\n .filter(([testId]) => typeof assignmentObject[testId] === \"string\")\n .map(([testId]) => ({\n test_id: testId,\n variant_id: assignmentObject[testId],\n }));\n}\n\n/**\n * ElevateAnalytics - Subscribes to Hydrogen analytics events\n *\n * @internal Used by ElevateHydrogenAnalytics. For Hydrogen stores, use ElevateHydrogenAnalytics instead!\n */\nexport function ElevateAnalytics({\n storeId: storeIdProp,\n storefrontAccessToken: tokenProp,\n hasLocalizedPaths,\n workerUrl = DEFAULT_WORKER_URL,\n ordersWorkerUrl = DEFAULT_ORDERS_WORKER_URL,\n useAnalytics,\n}: ElevateAnalyticsProps) {\n // Get values from context, allow props to override\n const context = useContext(ElevateContext);\n const storeId = storeIdProp || context?.storeId || \"\";\n const storefrontAccessToken = tokenProp || context?.storefrontAccessToken;\n\n // Track if we've warned about missing context (warn only once)\n const hasWarnedContextRef = useRef(false);\n\n // Warn once if not inside ElevateProvider\n useEffect(() => {\n if (!context && !storeIdProp && !hasWarnedContextRef.current) {\n hasWarnedContextRef.current = true;\n console.error(\n \"[ElevateAB] ElevateAnalytics must be used inside ElevateProvider, \" +\n \"or you must pass storeId as a prop.\",\n );\n }\n }, [context, storeIdProp]);\n const { subscribe, register } = useAnalytics();\n const { ready } = register(\"Elevate Analytics\");\n\n useEffect(() => {\n // Skip in non-browser environments\n if (typeof window === \"undefined\") return;\n\n // Initialize visitor ID and session ID\n getVisitorId();\n getSessionId();\n\n // Initialize referrer data if not already set\n if (typeof document !== \"undefined\") {\n const currentReferrer = document.referrer || \"\";\n const currentUrl = window.location.href;\n setReferrerData(currentReferrer, currentUrl);\n }\n\n const setupAnalytics = () => {\n // Initialize state\n const initializeState = (event: any) => {\n const productPageId = extractProductId(event.products?.[0]?.id);\n if (productPageId && typeof localStorage !== \"undefined\") {\n localStorage.setItem(\"eabProductPageId\", productPageId);\n } else if (\n typeof window !== \"undefined\" &&\n !window.location.pathname.includes(\"/products/\")\n ) {\n localStorage?.removeItem(\"eabProductPageId\");\n }\n\n const cartToken = extractCartToken(\n typeof localStorage !== \"undefined\"\n ? localStorage.getItem(\"shopifyCartId\")\n : null,\n );\n\n const { referrer, entryPage } = getReferrerData();\n\n return {\n visitorId: getVisitorId(),\n sessionId: getSessionId(),\n cartToken: cartToken || getCookie(\"cart\") || \"\",\n referrer,\n entryPage,\n clientId: getCookie(\"_shopify_y\"),\n rootRoute:\n typeof localStorage !== \"undefined\"\n ? localStorage.getItem(\"eabRootRoute\") || \"\"\n : \"\",\n productPageId:\n typeof localStorage !== \"undefined\"\n ? localStorage.getItem(\"eabProductPageId\") || \"\"\n : \"\",\n };\n };\n\n // Create base event data\n const createBaseEventData = (\n eventName: string,\n pixelEventId: string,\n event: any,\n state: any,\n ): EventPayload => {\n const userAgent =\n typeof navigator !== \"undefined\" ? navigator.userAgent : \"\";\n const pathname = event?.url\n ? new URL(event.url).pathname\n : typeof window !== \"undefined\"\n ? window.location.pathname\n : \"\";\n const pageType = getPageTypeFromPathname(pathname, hasLocalizedPaths);\n\n const parsedData = parseAddViewData({\n referrer: state.referrer,\n entryPage: state.entryPage,\n userAgent,\n });\n\n const abtlObject = getJsonCookie<Record<string, string>>(\"ABTL\") || {};\n const abauObject = getJsonCookie<Record<string, boolean>>(\"ABAU\") || {};\n\n const testAssignments = transformTestFormat(abtlObject);\n const viewedTests = transformViewedTests(abauObject, abtlObject);\n\n const currentTimestamp = new Date().toISOString();\n\n // Get additional state from cookies/storage\n const isFirstVisit =\n typeof sessionStorage !== \"undefined\"\n ? sessionStorage.getItem(\"eabIsFirstVisit\") === \"true\"\n : false;\n const shopifyCountry = getCookie(\"localization\") || \"\";\n\n return {\n pixel_event_id: pixelEventId,\n shop_name: storeId,\n timestamp: currentTimestamp,\n event_type: eventName,\n client_id: state.clientId,\n visitor_id: state.visitorId,\n session_id: state.sessionId,\n cart_token: cleanCartToken(state.cartToken),\n\n page_url:\n event.context?.document?.location?.href ||\n (typeof window !== \"undefined\" ? window.location.href : \"\"),\n page_pathname: pathname,\n page_search:\n event.context?.document?.location?.search ||\n (typeof window !== \"undefined\" ? window.location.search : \"\"),\n referrer_url: state.referrer,\n referrer_source: parsedData?.referrer_source,\n previous_page:\n typeof document !== \"undefined\" ? document.referrer : \"\",\n page_entry: state.entryPage,\n page_entry_path: parsedData?.page_entry_path,\n page_type: pageType,\n\n utm_medium: parsedData?.utm_medium,\n utm_source: parsedData?.utm_source,\n utm_campaign: parsedData?.utm_campaign,\n utm_content: parsedData?.utm_content,\n utm_term: parsedData?.utm_term,\n\n gclid: parsedData?.gclid,\n fbclid: parsedData?.fbclid,\n pins_campaign_id: parsedData?.pins_campaign_id,\n epik: parsedData?.epik,\n\n browser_info: parsedData?.browser_info,\n os_info: parsedData?.os_info,\n device_type: parsedData?.device_type,\n language:\n event.context?.navigator?.language ||\n (typeof navigator !== \"undefined\" ? navigator.language : \"\"),\n root_route: state.rootRoute,\n user_agent: userAgent,\n user_agent_no_browser: getUserAgentNoBrowser(userAgent),\n\n is_first_visit: isFirstVisit,\n shopify_country: shopifyCountry,\n\n cart_currency: event.shop?.currency,\n\n ab_test_assignments: testAssignments,\n ab_test_views: viewedTests,\n is_first_order: null,\n };\n };\n\n // Send event to CloudFlare Worker\n const sendEvent = async (data: EventPayload) => {\n if (data.exclude) return;\n\n try {\n const response = await fetch(workerUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(data),\n keepalive: true,\n });\n\n if (!response.ok) {\n throw new Error(`Worker error: ${response.status}`);\n }\n\n return response;\n } catch (error) {\n console.error(\"[ElevateAB] Error sending analytics:\", error);\n }\n };\n\n // Event handlers\n const handlePageViewed = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const eventData = createBaseEventData(\n \"page_viewed\",\n pixelEventId,\n event,\n state,\n );\n\n await sendEvent(eventData);\n } catch (error) {\n console.error(\"[ElevateAB] Error handling page_viewed:\", error);\n }\n };\n\n const handleProductViewed = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"product_viewed\",\n pixelEventId,\n event,\n state,\n );\n\n const eventData: EventPayload = {\n ...baseData,\n product_id: extractProductId(event?.products?.[0]?.id) || \"\",\n product_vendor: sanitizeString(event?.products?.[0]?.vendor) ?? \"\",\n product_price: roundToTwo(event?.products?.[0]?.price) ?? null,\n product_sku: sanitizeString(event?.products?.[0]?.sku) ?? \"\",\n };\n\n await sendEvent(eventData);\n } catch (error) {\n console.error(\"[ElevateAB] Error handling product_viewed:\", error);\n }\n };\n\n const handleProductAddedToCart = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"product_added_to_cart\",\n pixelEventId,\n event,\n state,\n );\n\n const eventData: EventPayload = {\n ...baseData,\n product_id:\n extractProductId(event?.currentLine?.merchandise?.product?.id) ??\n \"\",\n variant_id:\n extractProductVariantId(event?.currentLine?.merchandise?.id) ??\n \"\",\n product_vendor:\n sanitizeString(\n event?.currentLine?.merchandise?.product?.vendor,\n ) ?? \"\",\n product_price:\n roundToTwo(event?.currentLine?.cost?.totalAmount?.amount) ?? null,\n product_quantity: event?.currentLine?.quantity ?? null,\n product_sku:\n sanitizeString(event?.currentLine?.merchandise?.sku) ?? \"\",\n };\n\n await sendEvent(eventData);\n\n // Update cart attributes with A/B test data (for order attribution)\n const cartId = event?.cart?.id;\n if (cartId && storefrontAccessToken && storeId) {\n updateCartAttributes(cartId, {\n storefrontAccessToken,\n storefrontApiUrl: `https://${storeId}/api/2025-01/graphql.json`,\n }).catch((err) => {\n console.error(\n \"[ElevateAB] Failed to update cart attributes:\",\n err,\n );\n });\n }\n } catch (error) {\n console.error(\n \"[ElevateAB] Error handling product_added_to_cart:\",\n error,\n );\n }\n };\n\n const handleProductRemovedFromCart = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"product_removed_from_cart\",\n pixelEventId,\n event,\n state,\n );\n\n const eventData: EventPayload = {\n ...baseData,\n product_id:\n extractProductId(event?.prevLine?.merchandise?.product?.id) ?? \"\",\n variant_id:\n extractProductVariantId(event?.prevLine?.merchandise?.id) ?? \"\",\n product_vendor:\n sanitizeString(event?.prevLine?.merchandise?.product?.vendor) ??\n \"\",\n product_price:\n roundToTwo(event?.prevLine?.cost?.totalAmount?.amount) ?? null,\n product_quantity: event?.prevLine?.quantity ?? null,\n product_sku:\n sanitizeString(event?.prevLine?.merchandise?.sku) ?? \"\",\n };\n\n await sendEvent(eventData);\n } catch (error) {\n console.error(\n \"[ElevateAB] Error handling product_removed_from_cart:\",\n error,\n );\n }\n };\n\n const handleCartViewed = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"cart_viewed\",\n pixelEventId,\n event,\n state,\n );\n\n const lines =\n event?.data?.cart?.lines?.nodes || event?.data?.cart?.lines || [];\n const cartProducts = lines.map((item: any) => ({\n product_id: extractProductId(item?.merchandise?.product?.id) ?? \"\",\n variant_id: extractProductVariantId(item?.merchandise?.id) ?? \"\",\n vendor: sanitizeString(item?.merchandise?.product?.vendor) ?? \"\",\n total_price: roundToTwo(item?.cost?.totalAmount?.amount) ?? null,\n quantity: item?.quantity ?? null,\n sku: sanitizeString(item?.merchandise?.sku) ?? \"\",\n }));\n\n const eventData: EventPayload = {\n ...baseData,\n cart_total_price:\n roundToTwo(event?.cart?.cost?.totalAmount?.amount) ?? null,\n cart_total_quantity: event?.cart?.totalQuantity ?? null,\n cart_items: cartProducts,\n };\n\n await sendEvent(eventData);\n } catch (error) {\n console.error(\"[ElevateAB] Error handling cart_viewed:\", error);\n }\n };\n\n const handleSearchSubmitted = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"search_submitted\",\n pixelEventId,\n event,\n state,\n );\n\n const eventData: EventPayload = {\n ...baseData,\n search_query:\n sanitizeString(event?.data?.searchResult?.query) ?? \"\",\n };\n\n await sendEvent(eventData);\n } catch (error) {\n console.error(\"[ElevateAB] Error handling search_submitted:\", error);\n }\n };\n\n const handleCheckoutStarted = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"checkout_started\",\n pixelEventId,\n event,\n state,\n );\n\n let totalQuantity = 0;\n const lineItems = event?.data?.checkout?.lineItems ?? [];\n const checkoutProducts = lineItems.map((item: any) => {\n const quantity = item?.quantity ?? 0;\n totalQuantity += quantity;\n\n const discountAllocations = item?.discountAllocations ?? [];\n const total_discount = discountAllocations?.reduce(\n (acc: number, discount: any) =>\n acc + (discount?.amount?.amount || 0),\n 0,\n );\n\n return {\n product_id: extractProductId(item?.variant?.product?.id) ?? \"\",\n variant_id: extractProductVariantId(item?.variant?.id) ?? \"\",\n vendor: sanitizeString(item?.variant?.product?.vendor) ?? \"\",\n total_price: roundToTwo(item?.finalLinePrice?.amount) ?? null,\n quantity: quantity,\n sku: sanitizeString(item?.variant?.sku) ?? \"\",\n total_discount: roundToTwo(total_discount) ?? null,\n };\n });\n\n const eventData: EventPayload = {\n ...baseData,\n cart_total_price:\n roundToTwo(event?.data?.checkout?.totalPrice?.amount) ?? null,\n cart_subtotal_price:\n roundToTwo(event?.data?.checkout?.subtotalPrice?.amount) ?? null,\n cart_total_quantity: totalQuantity,\n cart_shipping_price:\n roundToTwo(event?.data?.checkout?.shippingLine?.price?.amount) ??\n null,\n cart_tax_amount:\n roundToTwo(event?.data?.checkout?.totalTax?.amount) ?? null,\n cart_discount_amount:\n roundToTwo(event?.data?.checkout?.discountsAmount?.amount) ??\n null,\n cart_items: checkoutProducts,\n customer_id: event?.data?.checkout?.order?.customer?.id ?? \"\",\n };\n\n await sendEvent(eventData);\n } catch (error) {\n console.error(\"[ElevateAB] Error handling checkout_started:\", error);\n }\n };\n\n const handleCheckoutCompleted = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"checkout_completed\",\n pixelEventId,\n event,\n state,\n );\n\n let totalQuantity = 0;\n const lineItems = event?.data?.checkout?.lineItems ?? [];\n const checkoutProducts = lineItems.map((item: any) => {\n const quantity = item?.quantity ?? 0;\n totalQuantity += quantity;\n\n const discountAllocations = item?.discountAllocations ?? [];\n const total_discount = discountAllocations?.reduce(\n (acc: number, discount: any) =>\n acc + (discount?.amount?.amount || 0),\n 0,\n );\n\n return {\n product_id: extractProductId(item?.variant?.product?.id) ?? \"\",\n variant_id: extractProductVariantId(item?.variant?.id) ?? \"\",\n vendor: sanitizeString(item?.variant?.product?.vendor) ?? \"\",\n total_price: roundToTwo(item?.finalLinePrice?.amount) ?? null,\n quantity: quantity,\n sku: sanitizeString(item?.variant?.sku) ?? \"\",\n total_discount: roundToTwo(total_discount) ?? null,\n };\n });\n\n const eventData: EventPayload = {\n ...baseData,\n cart_total_price:\n roundToTwo(event?.data?.checkout?.totalPrice?.amount) ?? null,\n cart_subtotal_price:\n roundToTwo(event?.data?.checkout?.subtotalPrice?.amount) ?? null,\n cart_total_quantity: totalQuantity,\n cart_shipping_price:\n roundToTwo(event?.data?.checkout?.shippingLine?.price?.amount) ??\n null,\n cart_tax_amount:\n roundToTwo(event?.data?.checkout?.totalTax?.amount) ?? null,\n cart_discount_amount:\n roundToTwo(event?.data?.checkout?.discountsAmount?.amount) ??\n null,\n cart_items: checkoutProducts,\n order_id: event?.data?.checkout?.order?.id ?? \"\",\n customer_id: event?.data?.checkout?.order?.customer?.id ?? \"\",\n is_first_order:\n event?.data?.checkout?.order?.customer?.isFirstOrder ?? null,\n note_attributes: event?.data?.checkout?.attributes ?? [],\n };\n\n // Send to orders worker (different endpoint)\n await sendOrderEvent(eventData);\n } catch (error) {\n console.error(\n \"[ElevateAB] Error handling checkout_completed:\",\n error,\n );\n }\n };\n\n // Send event to orders CloudFlare Worker (for checkout_completed)\n const sendOrderEvent = async (data: EventPayload) => {\n if (data.exclude) return;\n\n try {\n const response = await fetch(ordersWorkerUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(data),\n keepalive: true,\n });\n\n if (!response.ok) {\n throw new Error(`Orders worker error: ${response.status}`);\n }\n\n return response;\n } catch (error) {\n console.error(\"[ElevateAB] Error sending order analytics:\", error);\n }\n };\n\n // Subscribe to events\n subscribe(\"page_viewed\", handlePageViewed);\n subscribe(\"product_viewed\", handleProductViewed);\n subscribe(\"product_added_to_cart\", handleProductAddedToCart);\n subscribe(\"product_removed_from_cart\", handleProductRemovedFromCart);\n subscribe(\"cart_viewed\", handleCartViewed);\n subscribe(\"search_submitted\", handleSearchSubmitted);\n subscribe(\"checkout_started\", handleCheckoutStarted);\n subscribe(\"checkout_completed\", handleCheckoutCompleted);\n };\n\n setupAnalytics();\n ready();\n }, [\n subscribe,\n ready,\n storeId,\n hasLocalizedPaths,\n storefrontAccessToken,\n workerUrl,\n ordersWorkerUrl,\n ]);\n\n return null;\n}\n"],"mappings":"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","names":["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","init_utils","__esmMin","uuidv4","rnds","hexValues","b","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","init_storage","__esmMin","getTestList","getJsonCookie","saveTestList","testList","setCookie","getAssignedVariant","testId","getNonControlIndex","variations","targetIndex","nonControlIndex","assignVariantForUser","userId","allHaveTrafficPercentage","v","cumulativeWeights","totalWeight","variation","defaultWeight","i","randomWeight","hashString","assignedIndex","assignedVariation","assignAndPersistVariant","test","existingVariantId","variantIndex","existingVariant","activeVariations","isPersonalization","assignedVariant","shouldShowTest","testTrafficPercentage","init_assignment","__esmMin","init_storage","init_utils","require_ua_parser","__commonJSMin","exports","module","window","undefined","LIBVERSION","EMPTY","UNKNOWN","FUNC_TYPE","UNDEF_TYPE","OBJ_TYPE","STR_TYPE","MAJOR","MODEL","NAME","TYPE","VENDOR","VERSION","ARCHITECTURE","CONSOLE","MOBILE","TABLET","SMARTTV","WEARABLE","EMBEDDED","UA_MAX_LENGTH","AMAZON","APPLE","ASUS","BLACKBERRY","BROWSER","CHROME","EDGE","FIREFOX","GOOGLE","HONOR","HUAWEI","LENOVO","LG","MICROSOFT","MOTOROLA","NVIDIA","ONEPLUS","OPERA","OPPO","SAMSUNG","SHARP","SONY","XIAOMI","ZEBRA","FACEBOOK","CHROMIUM_OS","MAC_OS","SUFFIX_BROWSER","extend","regexes","extensions","mergedRegexes","i","enumerize","arr","enums","has","str1","str2","lowerize","str","majorize","version","trim","len","rgxMapper","ua","arrays","j","k","p","q","matches","match","regex","props","strMapper","map","oldSafariMap","windowsVersionMap","UAParser","_navigator","_ua","_uach","_rgxmap","_isSelfNav","_browser","_cpu","_device","_engine","_os","$","parser","result","prop","CART_ATTRIBUTES_UPDATE_MUTATION","init_cartAttributes_mutation","__esmMin","cartAttributes_exports","__export","cleanupCartAttributes","getCartAttributesPayload","updateCartAttributes","testList","getTestList","addedUniqueViews","getJsonCookie","eabUserId","getCookie","isPreviewMode","abtidValue","viewedTests","testId","attributes","cartId","options","cartGid","storefrontUrl","getStoreDomain","response","CART_ATTRIBUTES_UPDATE_MUTATION","result","errorMsg","error","init_cartAttributes","__esmMin","init_assignment","init_storage","init_cartAttributes_mutation","index_exports","__export","CART_ATTRIBUTES_UPDATE_MUTATION","COUNTRIES","DEFAULT_CONFIG","ElevateAnalytics","ElevateProvider","REGIONS","VERSION","assignAndPersistVariant","assignVariant","buildEabTestsParam","calculateRevenueLift","checkFacebookBrowser","checkFacebookInstagramBrowser","checkInstagramBrowser","checkPinterestBrowser","checkTikTokBrowser","checkVisitorIdParams","cleanCartToken","cleanupCartAttributes","cleanupFlickerPrevention","clearPreviewMode","deleteCookie","detectShopifyCurrency","extractCartToken","extractProductId","extractProductVariantId","extractShopifyId","extractShopifyType","generateExperimentId","getAssignedVariant","getCartAttributesPayload","getCookie","getCountryCode","getDeviceType","getFlickerPreventionScript","getGeoLocation","getJsonCookie","getJsonSessionItem","getPageTypeFromPathname","getPreviewState","getPreviewVariation","getReferrerData","getSessionId","getSessionItem","getTestList","getTrafficSource","getUserAgentNoBrowser","getVisitorId","hasSessionView","hasUniqueView","hashString","hideForFlicker","initAnalytics","initializeSessionId","initializeVisitorId","injectFlickerStyles","isCountryExcluded","isCountryIncluded","isFlickerPreventionActive","isInPreviewMode","isPreviewTest","isShopifyGid","matchesGeoTargeting","parseAddViewData","revealAfterFlicker","roundToTwo","sanitizeString","saveTestList","setCookie","setCountryCode","setGeoLocation","setReferrerData","setSessionItem","setupFlickerPrevention","shouldShowTest","trackAddToCart","trackCartView","trackCheckoutCompleted","trackCheckoutStarted","trackPageView","trackProductView","trackRemoveFromCart","trackSearchSubmitted","trackSessionView","trackUniqueView","trackViews","updateCartAttributes","updateUrlWithTestParams","useElevateConfig","useExperiment","usePageViewTracking","uuidv4","validateConfig","__toCommonJS","init_utils","init_storage","init_assignment","init_storage","trackUniqueView","testId","addedUniqueViews","getJsonCookie","setCookie","trackSessionView","addedViews","getJsonSessionItem","setSessionItem","trackViews","hasSessionView","hasUniqueView","getDeviceType","ua","lower","checkFacebookBrowser","userAgent","checkInstagramBrowser","checkTikTokBrowser","checkPinterestBrowser","getTrafficSource","referrer","referrerDomain","hostname","isFacebookBrowser","isInstagramBrowser","isTikTokBrowser","isPinterestBrowser","init_storage","parseEabTestsParam","param","assignments","views","tests","test","parts","shortTestId","variationId","hasSeen","getPreviewState","urlParams","isPreview","getCookie","previewTestId","getSessionItem","eabTestsParam","setCookie","setSessionItem","isPreviewTest","testId","getPreviewVariation","previewState","buildEabTestsParam","testAssignments","viewedTests","updateUrlWithTestParams","visitorId","url","eabTestsValue","clearPreviewMode","isInPreviewMode","init_storage","GEO_COOKIE_NAMES","getCountryCode","urlCountry","setCookie","shopifyCountry","getCookie","cachedCountry","storedCountry","getGeoLocation","country","geoData","parsed","setCountryCode","countryCode","normalized","setGeoLocation","geo","isCountryIncluded","allowedCountries","userCountry","c","isCountryExcluded","excludedCountries","matchesGeoTargeting","rules","COUNTRIES","REGIONS","FLICKER_CLASS","STYLE_ID","injectFlickerStyles","timeout","STYLE_ID","style","FLICKER_CLASS","head","hideForFlicker","selector","element","revealAfterFlicker","setupFlickerPrevention","hasRevealed","timeoutId","cleanupFlickerPrevention","el","isFlickerPreventionActive","getFlickerPreventionScript","import_ua_parser_js","urlSources","sanitizeString","value","roundToTwo","num","extractProductId","gid","regex","match","extractProductVariantId","extractCartToken","cleanCartToken","cartToken","checkFacebookBrowser","userAgent","checkInstagramBrowser","checkFacebookInstagramBrowser","getBrowserName","browser","getQueryParams","parsedUrl","queryParams","key","isValidReferrerURI","uri","extractReferrerSource","host","parseReferrer","referrer","siteHostname","referrerObj","source","parseAddViewData","params","entryPage","data","entryObj","entryPath","entryQueryParams","userAgentObj","browserName","getPageTypeFromPathname","path","hasLocalizedPaths","hasNormalPath","isLocalizedHomepage","checkVisitorIdParams","searchParams","getUserAgentNoBrowser","os","device","result","extractShopifyId","gid","extractShopifyType","isShopifyGid","value","detectShopifyCurrency","shopify","init_cartAttributes","init_cartAttributes_mutation","init_storage","import_react","DEFAULT_WORKER_URL","DEFAULT_ORDERS_WORKER_URL","globalConfig","initAnalytics","config","getStoreId","params","storeId","globalConfig","transformTestFormat","testObject","variationId","testId","transformViewedTests","viewedObject","assignmentObject","isInPreviewMode","getCookie","createBaseEventData","eventType","hasLocalizedPaths","userAgent","pathname","pageType","getPageTypeFromPathname","referrer","entryPage","getReferrerData","parsedData","parseAddViewData","abtlObject","getJsonCookie","abauObject","testAssignments","viewedTests","cartToken","extractCartToken","currentTimestamp","isFirstVisit","shopifyCountry","uuidv4","getVisitorId","getSessionId","cleanCartToken","getUserAgentNoBrowser","sendEvent","data","workerUrl","DEFAULT_WORKER_URL","response","error","trackPageView","baseData","eventData","trackProductView","productId","productVendor","productPrice","productSku","currency","extractShopifyId","sanitizeString","roundToTwo","trackAddToCart","variantId","productQuantity","cartId","storefrontAccessToken","updateCartAttributes","err","trackRemoveFromCart","trackCartView","cartTotalPrice","cartTotalQuantity","cartItems","item","trackSearchSubmitted","searchQuery","trackCheckoutStarted","cartSubtotalPrice","cartShippingPrice","cartTaxAmount","cartDiscountAmount","customerId","totalQuantity","items","quantity","trackCheckoutCompleted","orderId","isFirstOrder","noteAttributes","ordersWorkerUrl","DEFAULT_ORDERS_WORKER_URL","usePageViewTracking","enabled","externalPathname","lastTrackedPathRef","currentPath","setCurrentPath","import_react","import_react","ElevateContext","React","useElevateConfig","context","init_storage","init_assignment","useExperiment","testId","config","useElevateConfig","variant","setVariant","React","isLoading","setIsLoading","testConfig","test","hasWarnedRef","shouldShowTest","userId","getVisitorId","assigned","assignAndPersistVariant","trackViews","import_react","init_utils","USE_CDN_CONFIG","DEV_FALLBACK_CONFIG","ElevateProvider","storeId","storefrontAccessToken","preventFlickering","flickerTimeout","children","config","setConfig","React","previewState","setPreviewState","countryCode","setCountryCode","revealRef","setupFlickerPrevention","initAnalytics","preview","getPreviewState","country","getCountryCode","revealContent","fetchConfig","parsedConfig","parseBackendConfig","url","response","backendData","err","value","hasWarnedRef","ElevateContext","import_react","init_storage","init_cartAttributes","DEFAULT_WORKER_URL","DEFAULT_ORDERS_WORKER_URL","generatePixelEventId","uuidv4","transformTestFormat","testObject","variationId","testId","transformViewedTests","viewedObject","assignmentObject","ElevateAnalytics","storeIdProp","tokenProp","hasLocalizedPaths","workerUrl","ordersWorkerUrl","useAnalytics","context","ElevateContext","storeId","storefrontAccessToken","hasWarnedContextRef","subscribe","register","ready","getVisitorId","getSessionId","currentReferrer","currentUrl","setReferrerData","initializeState","event","productPageId","extractProductId","cartToken","extractCartToken","referrer","entryPage","getReferrerData","getCookie","createBaseEventData","eventName","pixelEventId","state","userAgent","pathname","pageType","getPageTypeFromPathname","parsedData","parseAddViewData","abtlObject","getJsonCookie","abauObject","testAssignments","viewedTests","currentTimestamp","isFirstVisit","shopifyCountry","cleanCartToken","getUserAgentNoBrowser","sendEvent","data","response","error","handlePageViewed","eventData","handleProductViewed","sanitizeString","roundToTwo","handleProductAddedToCart","extractProductVariantId","cartId","updateCartAttributes","err","handleProductRemovedFromCart","handleCartViewed","baseData","cartProducts","item","handleSearchSubmitted","handleCheckoutStarted","totalQuantity","checkoutProducts","quantity","total_discount","acc","discount","handleCheckoutCompleted","sendOrderEvent","VERSION","DEFAULT_CONFIG"]}
1
+ {"version":3,"sources":["../src/utils.ts","../src/utils/storage.ts","../src/utils/assignment.ts","../node_modules/ua-parser-js/src/ua-parser.js","../src/mutations/cartAttributes.mutation.ts","../src/utils/cartAttributes.ts","../src/index.ts","../src/utils/tracking.ts","../src/utils/conditions.ts","../src/utils/preview.ts","../src/utils/geo.ts","../src/utils/antiFlicker.ts","../src/utils/analytics.ts","../src/utils/shopify.ts","../src/utils/manualTracking.ts","../src/components/Experiment.tsx","../src/contexts/ElevateContext.tsx","../src/components/ElevateProvider.tsx","../src/components/AntiFlickerScript.tsx","../src/components/ElevateAnalytics.tsx"],"sourcesContent":["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 * 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","/**\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/* UAParser.js v1.0.41\n Copyright © 2012-2025 Faisal Salman <f@faisalman.com>\n MIT License *//*\n Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data.\n Supports browser & node.js environment. \n Demo : https://faisalman.github.io/ua-parser-js\n Source : https://github.com/faisalman/ua-parser-js */\n/////////////////////////////////////////////////////////////////////////////////\n\n(function (window, undefined) {\n\n 'use strict';\n\n //////////////\n // Constants\n /////////////\n\n\n var LIBVERSION = '1.0.41',\n EMPTY = '',\n UNKNOWN = '?',\n FUNC_TYPE = 'function',\n UNDEF_TYPE = 'undefined',\n OBJ_TYPE = 'object',\n STR_TYPE = 'string',\n MAJOR = 'major',\n MODEL = 'model',\n NAME = 'name',\n TYPE = 'type',\n VENDOR = 'vendor',\n VERSION = 'version',\n ARCHITECTURE= 'architecture',\n CONSOLE = 'console',\n MOBILE = 'mobile',\n TABLET = 'tablet',\n SMARTTV = 'smarttv',\n WEARABLE = 'wearable',\n EMBEDDED = 'embedded',\n UA_MAX_LENGTH = 500;\n\n var AMAZON = 'Amazon',\n APPLE = 'Apple',\n ASUS = 'ASUS',\n BLACKBERRY = 'BlackBerry',\n BROWSER = 'Browser',\n CHROME = 'Chrome',\n EDGE = 'Edge',\n FIREFOX = 'Firefox',\n GOOGLE = 'Google',\n HONOR = 'Honor',\n HUAWEI = 'Huawei',\n LENOVO = 'Lenovo',\n LG = 'LG',\n MICROSOFT = 'Microsoft',\n MOTOROLA = 'Motorola',\n NVIDIA = 'Nvidia',\n ONEPLUS = 'OnePlus',\n OPERA = 'Opera',\n OPPO = 'OPPO',\n SAMSUNG = 'Samsung',\n SHARP = 'Sharp',\n SONY = 'Sony',\n XIAOMI = 'Xiaomi',\n ZEBRA = 'Zebra',\n FACEBOOK = 'Facebook',\n CHROMIUM_OS = 'Chromium OS',\n MAC_OS = 'Mac OS',\n SUFFIX_BROWSER = ' Browser';\n\n ///////////\n // Helper\n //////////\n\n var extend = function (regexes, extensions) {\n var mergedRegexes = {};\n for (var i in regexes) {\n if (extensions[i] && extensions[i].length % 2 === 0) {\n mergedRegexes[i] = extensions[i].concat(regexes[i]);\n } else {\n mergedRegexes[i] = regexes[i];\n }\n }\n return mergedRegexes;\n },\n enumerize = function (arr) {\n var enums = {};\n for (var i=0; i<arr.length; i++) {\n enums[arr[i].toUpperCase()] = arr[i];\n }\n return enums;\n },\n has = function (str1, str2) {\n return typeof str1 === STR_TYPE ? lowerize(str2).indexOf(lowerize(str1)) !== -1 : false;\n },\n lowerize = function (str) {\n return str.toLowerCase();\n },\n majorize = function (version) {\n return typeof(version) === STR_TYPE ? version.replace(/[^\\d\\.]/g, EMPTY).split('.')[0] : undefined;\n },\n trim = function (str, len) {\n if (typeof(str) === STR_TYPE) {\n str = str.replace(/^\\s\\s*/, EMPTY);\n return typeof(len) === UNDEF_TYPE ? str : str.substring(0, UA_MAX_LENGTH);\n }\n };\n\n ///////////////\n // Map helper\n //////////////\n\n var rgxMapper = function (ua, arrays) {\n\n var i = 0, j, k, p, q, matches, match;\n\n // loop through all regexes maps\n while (i < arrays.length && !matches) {\n\n var regex = arrays[i], // even sequence (0,2,4,..)\n props = arrays[i + 1]; // odd sequence (1,3,5,..)\n j = k = 0;\n\n // try matching uastring with regexes\n while (j < regex.length && !matches) {\n\n if (!regex[j]) { break; }\n matches = regex[j++].exec(ua);\n\n if (!!matches) {\n for (p = 0; p < props.length; p++) {\n match = matches[++k];\n q = props[p];\n // check if given property is actually array\n if (typeof q === OBJ_TYPE && q.length > 0) {\n if (q.length === 2) {\n if (typeof q[1] == FUNC_TYPE) {\n // assign modified match\n this[q[0]] = q[1].call(this, match);\n } else {\n // assign given value, ignore regex match\n this[q[0]] = q[1];\n }\n } else if (q.length === 3) {\n // check whether function or regex\n if (typeof q[1] === FUNC_TYPE && !(q[1].exec && q[1].test)) {\n // call function (usually string mapper)\n this[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;\n } else {\n // sanitize match using given regex\n this[q[0]] = match ? match.replace(q[1], q[2]) : undefined;\n }\n } else if (q.length === 4) {\n this[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;\n }\n } else {\n this[q] = match ? match : undefined;\n }\n }\n }\n }\n i += 2;\n }\n },\n\n strMapper = function (str, map) {\n\n for (var i in map) {\n // check if current value is array\n if (typeof map[i] === OBJ_TYPE && map[i].length > 0) {\n for (var j = 0; j < map[i].length; j++) {\n if (has(map[i][j], str)) {\n return (i === UNKNOWN) ? undefined : i;\n }\n }\n } else if (has(map[i], str)) {\n return (i === UNKNOWN) ? undefined : i;\n }\n }\n return map.hasOwnProperty('*') ? map['*'] : str;\n };\n\n ///////////////\n // String map\n //////////////\n\n // Safari < 3.0\n var oldSafariMap = {\n '1.0' : '/8',\n '1.2' : '/1',\n '1.3' : '/3',\n '2.0' : '/412',\n '2.0.2' : '/416',\n '2.0.3' : '/417',\n '2.0.4' : '/419',\n '?' : '/'\n },\n windowsVersionMap = {\n 'ME' : '4.90',\n 'NT 3.11' : 'NT3.51',\n 'NT 4.0' : 'NT4.0',\n '2000' : 'NT 5.0',\n 'XP' : ['NT 5.1', 'NT 5.2'],\n 'Vista' : 'NT 6.0',\n '7' : 'NT 6.1',\n '8' : 'NT 6.2',\n '8.1' : 'NT 6.3',\n '10' : ['NT 6.4', 'NT 10.0'],\n 'RT' : 'ARM'\n };\n\n //////////////\n // Regex map\n /////////////\n\n var regexes = {\n\n browser : [[\n\n /\\b(?:crmo|crios)\\/([\\w\\.]+)/i // Chrome for Android/iOS\n ], [VERSION, [NAME, 'Chrome']], [\n /edg(?:e|ios|a)?\\/([\\w\\.]+)/i // Microsoft Edge\n ], [VERSION, [NAME, 'Edge']], [\n\n // Presto based\n /(opera mini)\\/([-\\w\\.]+)/i, // Opera Mini\n /(opera [mobiletab]{3,6})\\b.+version\\/([-\\w\\.]+)/i, // Opera Mobi/Tablet\n /(opera)(?:.+version\\/|[\\/ ]+)([\\w\\.]+)/i // Opera\n ], [NAME, VERSION], [\n /opios[\\/ ]+([\\w\\.]+)/i // Opera mini on iphone >= 8.0\n ], [VERSION, [NAME, OPERA+' Mini']], [\n /\\bop(?:rg)?x\\/([\\w\\.]+)/i // Opera GX\n ], [VERSION, [NAME, OPERA+' GX']], [\n /\\bopr\\/([\\w\\.]+)/i // Opera Webkit\n ], [VERSION, [NAME, OPERA]], [\n\n // Mixed\n /\\bb[ai]*d(?:uhd|[ub]*[aekoprswx]{5,6})[\\/ ]?([\\w\\.]+)/i // Baidu\n ], [VERSION, [NAME, 'Baidu']], [\n /\\b(?:mxbrowser|mxios|myie2)\\/?([-\\w\\.]*)\\b/i // Maxthon\n ], [VERSION, [NAME, 'Maxthon']], [\n /(kindle)\\/([\\w\\.]+)/i, // Kindle\n /(lunascape|maxthon|netfront|jasmine|blazer|sleipnir)[\\/ ]?([\\w\\.]*)/i, \n // Lunascape/Maxthon/Netfront/Jasmine/Blazer/Sleipnir\n // Trident based\n /(avant|iemobile|slim(?:browser|boat|jet))[\\/ ]?([\\d\\.]*)/i, // Avant/IEMobile/SlimBrowser/SlimBoat/Slimjet\n /(?:ms|\\()(ie) ([\\w\\.]+)/i, // Internet Explorer\n\n // Blink/Webkit/KHTML based // Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron/Iridium/PhantomJS/Bowser/QupZilla/Falkon\n /(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,\n // Rekonq/Puffin/Brave/Whale/QQBrowserLite/QQ//Vivaldi/DuckDuckGo/Klar/Helio/Dragon\n /(heytap|ovi|115)browser\\/([\\d\\.]+)/i, // HeyTap/Ovi/115\n /(weibo)__([\\d\\.]+)/i // Weibo\n ], [NAME, VERSION], [\n /quark(?:pc)?\\/([-\\w\\.]+)/i // Quark\n ], [VERSION, [NAME, 'Quark']], [\n /\\bddg\\/([\\w\\.]+)/i // DuckDuckGo\n ], [VERSION, [NAME, 'DuckDuckGo']], [\n /(?:\\buc? ?browser|(?:juc.+)ucweb)[\\/ ]?([\\w\\.]+)/i // UCBrowser\n ], [VERSION, [NAME, 'UC'+BROWSER]], [\n /microm.+\\bqbcore\\/([\\w\\.]+)/i, // WeChat Desktop for Windows Built-in Browser\n /\\bqbcore\\/([\\w\\.]+).+microm/i,\n /micromessenger\\/([\\w\\.]+)/i // WeChat\n ], [VERSION, [NAME, 'WeChat']], [\n /konqueror\\/([\\w\\.]+)/i // Konqueror\n ], [VERSION, [NAME, 'Konqueror']], [\n /trident.+rv[: ]([\\w\\.]{1,9})\\b.+like gecko/i // IE11\n ], [VERSION, [NAME, 'IE']], [\n /ya(?:search)?browser\\/([\\w\\.]+)/i // Yandex\n ], [VERSION, [NAME, 'Yandex']], [\n /slbrowser\\/([\\w\\.]+)/i // Smart Lenovo Browser\n ], [VERSION, [NAME, 'Smart Lenovo '+BROWSER]], [\n /(avast|avg)\\/([\\w\\.]+)/i // Avast/AVG Secure Browser\n ], [[NAME, /(.+)/, '$1 Secure '+BROWSER], VERSION], [\n /\\bfocus\\/([\\w\\.]+)/i // Firefox Focus\n ], [VERSION, [NAME, FIREFOX+' Focus']], [\n /\\bopt\\/([\\w\\.]+)/i // Opera Touch\n ], [VERSION, [NAME, OPERA+' Touch']], [\n /coc_coc\\w+\\/([\\w\\.]+)/i // Coc Coc Browser\n ], [VERSION, [NAME, 'Coc Coc']], [\n /dolfin\\/([\\w\\.]+)/i // Dolphin\n ], [VERSION, [NAME, 'Dolphin']], [\n /coast\\/([\\w\\.]+)/i // Opera Coast\n ], [VERSION, [NAME, OPERA+' Coast']], [\n /miuibrowser\\/([\\w\\.]+)/i // MIUI Browser\n ], [VERSION, [NAME, 'MIUI' + SUFFIX_BROWSER]], [\n /fxios\\/([\\w\\.-]+)/i // Firefox for iOS\n ], [VERSION, [NAME, FIREFOX]], [\n /\\bqihoobrowser\\/?([\\w\\.]*)/i // 360\n ], [VERSION, [NAME, '360']], [\n /\\b(qq)\\/([\\w\\.]+)/i // QQ\n ], [[NAME, /(.+)/, '$1Browser'], VERSION], [\n /(oculus|sailfish|huawei|vivo|pico)browser\\/([\\w\\.]+)/i\n ], [[NAME, /(.+)/, '$1' + SUFFIX_BROWSER], VERSION], [ // Oculus/Sailfish/HuaweiBrowser/VivoBrowser/PicoBrowser\n /samsungbrowser\\/([\\w\\.]+)/i // Samsung Internet\n ], [VERSION, [NAME, SAMSUNG + ' Internet']], [\n /metasr[\\/ ]?([\\d\\.]+)/i // Sogou Explorer\n ], [VERSION, [NAME, 'Sogou Explorer']], [\n /(sogou)mo\\w+\\/([\\d\\.]+)/i // Sogou Mobile\n ], [[NAME, 'Sogou Mobile'], VERSION], [\n /(electron)\\/([\\w\\.]+) safari/i, // Electron-based App\n /(tesla)(?: qtcarbrowser|\\/(20\\d\\d\\.[-\\w\\.]+))/i, // Tesla\n /m?(qqbrowser|2345(?=browser|chrome|explorer))\\w*[\\/ ]?v?([\\w\\.]+)/i // QQ/2345\n ], [NAME, VERSION], [\n /(lbbrowser|rekonq)/i, // LieBao Browser/Rekonq\n /\\[(linkedin)app\\]/i // LinkedIn App for iOS & Android\n ], [NAME], [\n /ome\\/([\\w\\.]+) \\w* ?(iron) saf/i, // Iron\n /ome\\/([\\w\\.]+).+qihu (360)[es]e/i // 360\n ], [VERSION, NAME], [\n\n // WebView\n /((?:fban\\/fbios|fb_iab\\/fb4a)(?!.+fbav)|;fbav\\/([\\w\\.]+);)/i // Facebook App for iOS & Android\n ], [[NAME, FACEBOOK], VERSION], [\n /(Klarna)\\/([\\w\\.]+)/i, // Klarna Shopping Browser for iOS & Android\n /(kakao(?:talk|story))[\\/ ]([\\w\\.]+)/i, // Kakao App\n /(naver)\\(.*?(\\d+\\.[\\w\\.]+).*\\)/i, // Naver InApp\n /(daum)apps[\\/ ]([\\w\\.]+)/i, // Daum App\n /safari (line)\\/([\\w\\.]+)/i, // Line App for iOS\n /\\b(line)\\/([\\w\\.]+)\\/iab/i, // Line App for Android\n /(alipay)client\\/([\\w\\.]+)/i, // Alipay\n /(twitter)(?:and| f.+e\\/([\\w\\.]+))/i, // Twitter\n /(chromium|instagram|snapchat)[\\/ ]([-\\w\\.]+)/i // Chromium/Instagram/Snapchat\n ], [NAME, VERSION], [\n /\\bgsa\\/([\\w\\.]+) .*safari\\//i // Google Search Appliance on iOS\n ], [VERSION, [NAME, 'GSA']], [\n /musical_ly(?:.+app_?version\\/|_)([\\w\\.]+)/i // TikTok\n ], [VERSION, [NAME, 'TikTok']], [\n\n /headlesschrome(?:\\/([\\w\\.]+)| )/i // Chrome Headless\n ], [VERSION, [NAME, CHROME+' Headless']], [\n\n / wv\\).+(chrome)\\/([\\w\\.]+)/i // Chrome WebView\n ], [[NAME, CHROME+' WebView'], VERSION], [\n\n /droid.+ version\\/([\\w\\.]+)\\b.+(?:mobile safari|safari)/i // Android Browser\n ], [VERSION, [NAME, 'Android '+BROWSER]], [\n\n /(chrome|omniweb|arora|[tizenoka]{5} ?browser)\\/v?([\\w\\.]+)/i // Chrome/OmniWeb/Arora/Tizen/Nokia\n ], [NAME, VERSION], [\n\n /version\\/([\\w\\.\\,]+) .*mobile\\/\\w+ (safari)/i // Mobile Safari\n ], [VERSION, [NAME, 'Mobile Safari']], [\n /version\\/([\\w(\\.|\\,)]+) .*(mobile ?safari|safari)/i // Safari & Safari Mobile\n ], [VERSION, NAME], [\n /webkit.+?(mobile ?safari|safari)(\\/[\\w\\.]+)/i // Safari < 3.0\n ], [NAME, [VERSION, strMapper, oldSafariMap]], [\n\n /(webkit|khtml)\\/([\\w\\.]+)/i\n ], [NAME, VERSION], [\n\n // Gecko based\n /(navigator|netscape\\d?)\\/([-\\w\\.]+)/i // Netscape\n ], [[NAME, 'Netscape'], VERSION], [\n /(wolvic|librewolf)\\/([\\w\\.]+)/i // Wolvic/LibreWolf\n ], [NAME, VERSION], [\n /mobile vr; rv:([\\w\\.]+)\\).+firefox/i // Firefox Reality\n ], [VERSION, [NAME, FIREFOX+' Reality']], [\n /ekiohf.+(flow)\\/([\\w\\.]+)/i, // Flow\n /(swiftfox)/i, // Swiftfox\n /(icedragon|iceweasel|camino|chimera|fennec|maemo browser|minimo|conkeror)[\\/ ]?([\\w\\.\\+]+)/i,\n // IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror\n /(seamonkey|k-meleon|icecat|iceape|firebird|phoenix|palemoon|basilisk|waterfox)\\/([-\\w\\.]+)$/i,\n // Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix\n /(firefox)\\/([\\w\\.]+)/i, // Other Firefox-based\n /(mozilla)\\/([\\w\\.]+) .+rv\\:.+gecko\\/\\d+/i, // Mozilla\n\n // Other\n /(amaya|dillo|doris|icab|ladybird|lynx|mosaic|netsurf|obigo|polaris|w3m|(?:go|ice|up)[\\. ]?browser)[-\\/ ]?v?([\\w\\.]+)/i,\n // Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf/Obigo/Mosaic/Go/ICE/UP.Browser/Ladybird\n /\\b(links) \\(([\\w\\.]+)/i // Links\n ], [NAME, [VERSION, /_/g, '.']], [\n \n /(cobalt)\\/([\\w\\.]+)/i // Cobalt\n ], [NAME, [VERSION, /master.|lts./, \"\"]]\n ],\n\n cpu : [[\n\n /\\b((amd|x|x86[-_]?|wow|win)64)\\b/i // AMD64 (x64)\n ], [[ARCHITECTURE, 'amd64']], [\n\n /(ia32(?=;))/i, // IA32 (quicktime)\n /\\b((i[346]|x)86)(pc)?\\b/i // IA32 (x86)\n ], [[ARCHITECTURE, 'ia32']], [\n\n /\\b(aarch64|arm(v?[89]e?l?|_?64))\\b/i // ARM64\n ], [[ARCHITECTURE, 'arm64']], [\n\n /\\b(arm(v[67])?ht?n?[fl]p?)\\b/i // ARMHF\n ], [[ARCHITECTURE, 'armhf']], [\n\n // PocketPC mistakenly identified as PowerPC\n /( (ce|mobile); ppc;|\\/[\\w\\.]+arm\\b)/i\n ], [[ARCHITECTURE, 'arm']], [\n\n /((ppc|powerpc)(64)?)( mac|;|\\))/i // PowerPC\n ], [[ARCHITECTURE, /ower/, EMPTY, lowerize]], [\n\n / sun4\\w[;\\)]/i // SPARC\n ], [[ARCHITECTURE, 'sparc']], [\n\n /\\b(avr32|ia64(?=;)|68k(?=\\))|\\barm(?=v([1-7]|[5-7]1)l?|;|eabi)|(irix|mips|sparc)(64)?\\b|pa-risc)/i\n // IA64, 68K, ARM/64, AVR/32, IRIX/64, MIPS/64, SPARC/64, PA-RISC\n ], [[ARCHITECTURE, lowerize]]\n ],\n\n device : [[\n\n //////////////////////////\n // MOBILES & TABLETS\n /////////////////////////\n\n // Samsung\n /\\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\n ], [MODEL, [VENDOR, SAMSUNG], [TYPE, TABLET]], [\n /\\b((?:s[cgp]h|gt|sm)-(?![lr])\\w+|sc[g-]?[\\d]+a?|galaxy nexus)/i,\n /samsung[- ]((?!sm-[lr])[-\\w]+)/i,\n /sec-(sgh\\w+)/i\n ], [MODEL, [VENDOR, SAMSUNG], [TYPE, MOBILE]], [\n\n // Apple\n /(?:\\/|\\()(ip(?:hone|od)[\\w, ]*)(?:\\/|;)/i // iPod/iPhone\n ], [MODEL, [VENDOR, APPLE], [TYPE, MOBILE]], [\n /\\((ipad);[-\\w\\),; ]+apple/i, // iPad\n /applecoremedia\\/[\\w\\.]+ \\((ipad)/i,\n /\\b(ipad)\\d\\d?,\\d\\d?[;\\]].+ios/i\n ], [MODEL, [VENDOR, APPLE], [TYPE, TABLET]], [\n /(macintosh);/i\n ], [MODEL, [VENDOR, APPLE]], [\n\n // Sharp\n /\\b(sh-?[altvz]?\\d\\d[a-ekm]?)/i\n ], [MODEL, [VENDOR, SHARP], [TYPE, MOBILE]], [\n\n // Honor\n /\\b((?:brt|eln|hey2?|gdi|jdn)-a?[lnw]09|(?:ag[rm]3?|jdn2|kob2)-a?[lw]0[09]hn)(?: bui|\\)|;)/i\n ], [MODEL, [VENDOR, HONOR], [TYPE, TABLET]], [\n /honor([-\\w ]+)[;\\)]/i\n ], [MODEL, [VENDOR, HONOR], [TYPE, MOBILE]], [\n\n // Huawei\n /\\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\n ], [MODEL, [VENDOR, HUAWEI], [TYPE, TABLET]], [\n /(?:huawei)([-\\w ]+)[;\\)]/i,\n /\\b(nexus 6p|\\w{2,4}e?-[atu]?[ln][\\dx][012359c][adn]?)\\b(?!.+d\\/s)/i\n ], [MODEL, [VENDOR, HUAWEI], [TYPE, MOBILE]], [\n\n // Xiaomi\n /oid[^\\)]+; (2[\\dbc]{4}(182|283|rp\\w{2})[cgl]|m2105k81a?c)(?: bui|\\))/i,\n /\\b((?:red)?mi[-_ ]?pad[\\w- ]*)(?: bui|\\))/i // Mi Pad tablets\n ],[[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, TABLET]], [\n\n /\\b(poco[\\w ]+|m2\\d{3}j\\d\\d[a-z]{2})(?: bui|\\))/i, // Xiaomi POCO\n /\\b; (\\w+) build\\/hm\\1/i, // Xiaomi Hongmi 'numeric' models\n /\\b(hm[-_ ]?note?[_ ]?(?:\\d\\w)?) bui/i, // Xiaomi Hongmi\n /\\b(redmi[\\-_ ]?(?:note|k)?[\\w_ ]+)(?: bui|\\))/i, // Xiaomi Redmi\n /oid[^\\)]+; (m?[12][0-389][01]\\w{3,6}[c-y])( bui|; wv|\\))/i, // Xiaomi Redmi 'numeric' models\n /\\b(mi[-_ ]?(?:a\\d|one|one[_ ]plus|note lte|max|cc)?[_ ]?(?:\\d?\\w?)[_ ]?(?:plus|se|lite|pro)?)(?: bui|\\))/i, // Xiaomi Mi\n / ([\\w ]+) miui\\/v?\\d/i\n ], [[MODEL, /_/g, ' '], [VENDOR, XIAOMI], [TYPE, MOBILE]], [\n\n // OPPO\n /; (\\w+) bui.+ oppo/i,\n /\\b(cph[12]\\d{3}|p(?:af|c[al]|d\\w|e[ar])[mt]\\d0|x9007|a101op)\\b/i\n ], [MODEL, [VENDOR, OPPO], [TYPE, MOBILE]], [\n /\\b(opd2(\\d{3}a?))(?: bui|\\))/i\n ], [MODEL, [VENDOR, strMapper, { 'OnePlus' : ['304', '403', '203'], '*' : OPPO }], [TYPE, TABLET]], [\n\n // Vivo\n /vivo (\\w+)(?: bui|\\))/i,\n /\\b(v[12]\\d{3}\\w?[at])(?: bui|;)/i\n ], [MODEL, [VENDOR, 'Vivo'], [TYPE, MOBILE]], [\n\n // Realme\n /\\b(rmx[1-3]\\d{3})(?: bui|;|\\))/i\n ], [MODEL, [VENDOR, 'Realme'], [TYPE, MOBILE]], [\n\n // Motorola\n /\\b(milestone|droid(?:[2-4x]| (?:bionic|x2|pro|razr))?:?( 4g)?)\\b[\\w ]+build\\//i,\n /\\bmot(?:orola)?[- ](\\w*)/i,\n /((?:moto(?! 360)[\\w\\(\\) ]+|xt\\d{3,4}|nexus 6)(?= bui|\\)))/i\n ], [MODEL, [VENDOR, MOTOROLA], [TYPE, MOBILE]], [\n /\\b(mz60\\d|xoom[2 ]{0,2}) build\\//i\n ], [MODEL, [VENDOR, MOTOROLA], [TYPE, TABLET]], [\n\n // LG\n /((?=lg)?[vl]k\\-?\\d{3}) bui| 3\\.[-\\w; ]{10}lg?-([06cv9]{3,4})/i\n ], [MODEL, [VENDOR, LG], [TYPE, TABLET]], [\n /(lm(?:-?f100[nv]?|-[\\w\\.]+)(?= bui|\\))|nexus [45])/i,\n /\\blg[-e;\\/ ]+((?!browser|netcast|android tv|watch)\\w+)/i,\n /\\blg-?([\\d\\w]+) bui/i\n ], [MODEL, [VENDOR, LG], [TYPE, MOBILE]], [\n\n // Lenovo\n /(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,\n /lenovo ?(b[68]0[08]0-?[hf]?|tab(?:[\\w- ]+?)|tb[\\w-]{6,7})( bui|;|\\)|\\/)/i\n ], [MODEL, [VENDOR, LENOVO], [TYPE, TABLET]], [\n\n // Nokia\n /(nokia) (t[12][01])/i\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n /(?:maemo|nokia).*(n900|lumia \\d+|rm-\\d+)/i,\n /nokia[-_ ]?(([-\\w\\. ]*))/i\n ], [[MODEL, /_/g, ' '], [TYPE, MOBILE], [VENDOR, 'Nokia']], [\n\n // Google\n /(pixel (c|tablet))\\b/i // Google Pixel C/Tablet\n ], [MODEL, [VENDOR, GOOGLE], [TYPE, TABLET]], [\n /droid.+; (pixel[\\daxl ]{0,6})(?: bui|\\))/i // Google Pixel\n ], [MODEL, [VENDOR, GOOGLE], [TYPE, MOBILE]], [\n\n // Sony\n /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\n ], [MODEL, [VENDOR, SONY], [TYPE, MOBILE]], [\n /sony tablet [ps]/i,\n /\\b(?:sony)?sgp\\w+(?: bui|\\))/i\n ], [[MODEL, 'Xperia Tablet'], [VENDOR, SONY], [TYPE, TABLET]], [\n\n // OnePlus\n / (kb2005|in20[12]5|be20[12][59])\\b/i,\n /(?:one)?(?:plus)? (a\\d0\\d\\d)(?: b|\\))/i\n ], [MODEL, [VENDOR, ONEPLUS], [TYPE, MOBILE]], [\n\n // Amazon\n /(alexa)webm/i,\n /(kf[a-z]{2}wi|aeo(?!bc)\\w\\w)( bui|\\))/i, // Kindle Fire without Silk / Echo Show\n /(kf[a-z]+)( bui|\\)).+silk\\//i // Kindle Fire HD\n ], [MODEL, [VENDOR, AMAZON], [TYPE, TABLET]], [\n /((?:sd|kf)[0349hijorstuw]+)( bui|\\)).+silk\\//i // Fire Phone\n ], [[MODEL, /(.+)/g, 'Fire Phone $1'], [VENDOR, AMAZON], [TYPE, MOBILE]], [\n\n // BlackBerry\n /(playbook);[-\\w\\),; ]+(rim)/i // BlackBerry PlayBook\n ], [MODEL, VENDOR, [TYPE, TABLET]], [\n /\\b((?:bb[a-f]|st[hv])100-\\d)/i,\n /\\(bb10; (\\w+)/i // BlackBerry 10\n ], [MODEL, [VENDOR, BLACKBERRY], [TYPE, MOBILE]], [\n\n // Asus\n /(?:\\b|asus_)(transfo[prime ]{4,10} \\w+|eeepc|slider \\w+|nexus 7|padfone|p00[cj])/i\n ], [MODEL, [VENDOR, ASUS], [TYPE, TABLET]], [\n / (z[bes]6[027][012][km][ls]|zenfone \\d\\w?)\\b/i\n ], [MODEL, [VENDOR, ASUS], [TYPE, MOBILE]], [\n\n // HTC\n /(nexus 9)/i // HTC Nexus 9\n ], [MODEL, [VENDOR, 'HTC'], [TYPE, TABLET]], [\n /(htc)[-;_ ]{1,2}([\\w ]+(?=\\)| bui)|\\w+)/i, // HTC\n\n // ZTE\n /(zte)[- ]([\\w ]+?)(?: bui|\\/|\\))/i,\n /(alcatel|geeksphone|nexian|panasonic(?!(?:;|\\.))|sony(?!-bra))[-_ ]?([-\\w]*)/i // Alcatel/GeeksPhone/Nexian/Panasonic/Sony\n ], [VENDOR, [MODEL, /_/g, ' '], [TYPE, MOBILE]], [\n\n // TCL\n /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\n ], [MODEL, [VENDOR, 'TCL'], [TYPE, TABLET]], [\n\n // itel\n /(itel) ((\\w+))/i\n ], [[VENDOR, lowerize], MODEL, [TYPE, strMapper, { 'tablet' : ['p10001l', 'w7001'], '*' : 'mobile' }]], [\n\n // Acer\n /droid.+; ([ab][1-7]-?[0178a]\\d\\d?)/i\n ], [MODEL, [VENDOR, 'Acer'], [TYPE, TABLET]], [\n\n // Meizu\n /droid.+; (m[1-5] note) bui/i,\n /\\bmz-([-\\w]{2,})/i\n ], [MODEL, [VENDOR, 'Meizu'], [TYPE, MOBILE]], [\n \n // Ulefone\n /; ((?:power )?armor(?:[\\w ]{0,8}))(?: bui|\\))/i\n ], [MODEL, [VENDOR, 'Ulefone'], [TYPE, MOBILE]], [\n\n // Energizer\n /; (energy ?\\w+)(?: bui|\\))/i,\n /; energizer ([\\w ]+)(?: bui|\\))/i\n ], [MODEL, [VENDOR, 'Energizer'], [TYPE, MOBILE]], [\n\n // Cat\n /; cat (b35);/i,\n /; (b15q?|s22 flip|s48c|s62 pro)(?: bui|\\))/i\n ], [MODEL, [VENDOR, 'Cat'], [TYPE, MOBILE]], [\n\n // Smartfren\n /((?:new )?andromax[\\w- ]+)(?: bui|\\))/i\n ], [MODEL, [VENDOR, 'Smartfren'], [TYPE, MOBILE]], [\n\n // Nothing\n /droid.+; (a(?:015|06[35]|142p?))/i\n ], [MODEL, [VENDOR, 'Nothing'], [TYPE, MOBILE]], [\n\n // Archos\n /; (x67 5g|tikeasy \\w+|ac[1789]\\d\\w+)( b|\\))/i,\n /archos ?(5|gamepad2?|([\\w ]*[t1789]|hello) ?\\d+[\\w ]*)( b|\\))/i\n ], [MODEL, [VENDOR, 'Archos'], [TYPE, TABLET]], [\n /archos ([\\w ]+)( b|\\))/i,\n /; (ac[3-6]\\d\\w{2,8})( b|\\))/i \n ], [MODEL, [VENDOR, 'Archos'], [TYPE, MOBILE]], [\n\n // MIXED\n /(imo) (tab \\w+)/i, // IMO\n /(infinix) (x1101b?)/i // Infinix XPad\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /(blackberry|benq|palm(?=\\-)|sonyericsson|acer|asus(?! zenw)|dell|jolla|meizu|motorola|polytron|infinix|tecno|micromax|advan)[-_ ]?([-\\w]*)/i,\n // BlackBerry/BenQ/Palm/Sony-Ericsson/Acer/Asus/Dell/Meizu/Motorola/Polytron/Infinix/Tecno/Micromax/Advan\n /; (hmd|imo) ([\\w ]+?)(?: bui|\\))/i, // HMD/IMO\n /(hp) ([\\w ]+\\w)/i, // HP iPAQ\n /(microsoft); (lumia[\\w ]+)/i, // Microsoft Lumia\n /(lenovo)[-_ ]?([-\\w ]+?)(?: bui|\\)|\\/)/i, // Lenovo\n /(oppo) ?([\\w ]+) bui/i // OPPO\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n\n /(kobo)\\s(ereader|touch)/i, // Kobo\n /(hp).+(touchpad(?!.+tablet)|tablet)/i, // HP TouchPad\n /(kindle)\\/([\\w\\.]+)/i, // Kindle\n /(nook)[\\w ]+build\\/(\\w+)/i, // Nook\n /(dell) (strea[kpr\\d ]*[\\dko])/i, // Dell Streak\n /(le[- ]+pan)[- ]+(\\w{1,9}) bui/i, // Le Pan Tablets\n /(trinity)[- ]*(t\\d{3}) bui/i, // Trinity Tablets\n /(gigaset)[- ]+(q\\w{1,9}) bui/i, // Gigaset Tablets\n /(vodafone) ([\\w ]+)(?:\\)| bui)/i // Vodafone\n ], [VENDOR, MODEL, [TYPE, TABLET]], [\n\n /(surface duo)/i // Surface Duo\n ], [MODEL, [VENDOR, MICROSOFT], [TYPE, TABLET]], [\n /droid [\\d\\.]+; (fp\\du?)(?: b|\\))/i // Fairphone\n ], [MODEL, [VENDOR, 'Fairphone'], [TYPE, MOBILE]], [\n /(u304aa)/i // AT&T\n ], [MODEL, [VENDOR, 'AT&T'], [TYPE, MOBILE]], [\n /\\bsie-(\\w*)/i // Siemens\n ], [MODEL, [VENDOR, 'Siemens'], [TYPE, MOBILE]], [\n /\\b(rct\\w+) b/i // RCA Tablets\n ], [MODEL, [VENDOR, 'RCA'], [TYPE, TABLET]], [\n /\\b(venue[\\d ]{2,7}) b/i // Dell Venue Tablets\n ], [MODEL, [VENDOR, 'Dell'], [TYPE, TABLET]], [\n /\\b(q(?:mv|ta)\\w+) b/i // Verizon Tablet\n ], [MODEL, [VENDOR, 'Verizon'], [TYPE, TABLET]], [\n /\\b(?:barnes[& ]+noble |bn[rt])([\\w\\+ ]*) b/i // Barnes & Noble Tablet\n ], [MODEL, [VENDOR, 'Barnes & Noble'], [TYPE, TABLET]], [\n /\\b(tm\\d{3}\\w+) b/i\n ], [MODEL, [VENDOR, 'NuVision'], [TYPE, TABLET]], [\n /\\b(k88) b/i // ZTE K Series Tablet\n ], [MODEL, [VENDOR, 'ZTE'], [TYPE, TABLET]], [\n /\\b(nx\\d{3}j) b/i // ZTE Nubia\n ], [MODEL, [VENDOR, 'ZTE'], [TYPE, MOBILE]], [\n /\\b(gen\\d{3}) b.+49h/i // Swiss GEN Mobile\n ], [MODEL, [VENDOR, 'Swiss'], [TYPE, MOBILE]], [\n /\\b(zur\\d{3}) b/i // Swiss ZUR Tablet\n ], [MODEL, [VENDOR, 'Swiss'], [TYPE, TABLET]], [\n /\\b((zeki)?tb.*\\b) b/i // Zeki Tablets\n ], [MODEL, [VENDOR, 'Zeki'], [TYPE, TABLET]], [\n /\\b([yr]\\d{2}) b/i,\n /\\b(dragon[- ]+touch |dt)(\\w{5}) b/i // Dragon Touch Tablet\n ], [[VENDOR, 'Dragon Touch'], MODEL, [TYPE, TABLET]], [\n /\\b(ns-?\\w{0,9}) b/i // Insignia Tablets\n ], [MODEL, [VENDOR, 'Insignia'], [TYPE, TABLET]], [\n /\\b((nxa|next)-?\\w{0,9}) b/i // NextBook Tablets\n ], [MODEL, [VENDOR, 'NextBook'], [TYPE, TABLET]], [\n /\\b(xtreme\\_)?(v(1[045]|2[015]|[3469]0|7[05])) b/i // Voice Xtreme Phones\n ], [[VENDOR, 'Voice'], MODEL, [TYPE, MOBILE]], [\n /\\b(lvtel\\-)?(v1[12]) b/i // LvTel Phones\n ], [[VENDOR, 'LvTel'], MODEL, [TYPE, MOBILE]], [\n /\\b(ph-1) /i // Essential PH-1\n ], [MODEL, [VENDOR, 'Essential'], [TYPE, MOBILE]], [\n /\\b(v(100md|700na|7011|917g).*\\b) b/i // Envizen Tablets\n ], [MODEL, [VENDOR, 'Envizen'], [TYPE, TABLET]], [\n /\\b(trio[-\\w\\. ]+) b/i // MachSpeed Tablets\n ], [MODEL, [VENDOR, 'MachSpeed'], [TYPE, TABLET]], [\n /\\btu_(1491) b/i // Rotor Tablets\n ], [MODEL, [VENDOR, 'Rotor'], [TYPE, TABLET]], [\n /((?:tegranote|shield t(?!.+d tv))[\\w- ]*?)(?: b|\\))/i // Nvidia Tablets\n ], [MODEL, [VENDOR, NVIDIA], [TYPE, TABLET]], [\n /(sprint) (\\w+)/i // Sprint Phones\n ], [VENDOR, MODEL, [TYPE, MOBILE]], [\n /(kin\\.[onetw]{3})/i // Microsoft Kin\n ], [[MODEL, /\\./g, ' '], [VENDOR, MICROSOFT], [TYPE, MOBILE]], [\n /droid.+; (cc6666?|et5[16]|mc[239][23]x?|vc8[03]x?)\\)/i // Zebra\n ], [MODEL, [VENDOR, ZEBRA], [TYPE, TABLET]], [\n /droid.+; (ec30|ps20|tc[2-8]\\d[kx])\\)/i\n ], [MODEL, [VENDOR, ZEBRA], [TYPE, MOBILE]], [\n\n ///////////////////\n // SMARTTVS\n ///////////////////\n\n /smart-tv.+(samsung)/i // Samsung\n ], [VENDOR, [TYPE, SMARTTV]], [\n /hbbtv.+maple;(\\d+)/i\n ], [[MODEL, /^/, 'SmartTV'], [VENDOR, SAMSUNG], [TYPE, SMARTTV]], [\n /(nux; netcast.+smarttv|lg (netcast\\.tv-201\\d|android tv))/i // LG SmartTV\n ], [[VENDOR, LG], [TYPE, SMARTTV]], [\n /(apple) ?tv/i // Apple TV\n ], [VENDOR, [MODEL, APPLE+' TV'], [TYPE, SMARTTV]], [\n /crkey/i // Google Chromecast\n ], [[MODEL, CHROME+'cast'], [VENDOR, GOOGLE], [TYPE, SMARTTV]], [\n /droid.+aft(\\w+)( bui|\\))/i // Fire TV\n ], [MODEL, [VENDOR, AMAZON], [TYPE, SMARTTV]], [\n /(shield \\w+ tv)/i // Nvidia Shield TV\n ], [MODEL, [VENDOR, NVIDIA], [TYPE, SMARTTV]], [\n /\\(dtv[\\);].+(aquos)/i,\n /(aquos-tv[\\w ]+)\\)/i // Sharp\n ], [MODEL, [VENDOR, SHARP], [TYPE, SMARTTV]],[\n /(bravia[\\w ]+)( bui|\\))/i // Sony\n ], [MODEL, [VENDOR, SONY], [TYPE, SMARTTV]], [\n /(mi(tv|box)-?\\w+) bui/i // Xiaomi\n ], [MODEL, [VENDOR, XIAOMI], [TYPE, SMARTTV]], [\n /Hbbtv.*(technisat) (.*);/i // TechniSAT\n ], [VENDOR, MODEL, [TYPE, SMARTTV]], [\n /\\b(roku)[\\dx]*[\\)\\/]((?:dvp-)?[\\d\\.]*)/i, // Roku\n /hbbtv\\/\\d+\\.\\d+\\.\\d+ +\\([\\w\\+ ]*; *([\\w\\d][^;]*);([^;]*)/i // HbbTV devices\n ], [[VENDOR, trim], [MODEL, trim], [TYPE, SMARTTV]], [\n // SmartTV from Unidentified Vendors\n /droid.+; ([\\w- ]+) (?:android tv|smart[- ]?tv)/i\n ], [MODEL, [TYPE, SMARTTV]], [\n /\\b(android tv|smart[- ]?tv|opera tv|tv; rv:)\\b/i\n ], [[TYPE, SMARTTV]], [\n\n ///////////////////\n // CONSOLES\n ///////////////////\n\n /(ouya)/i, // Ouya\n /(nintendo) ([wids3utch]+)/i // Nintendo\n ], [VENDOR, MODEL, [TYPE, CONSOLE]], [\n /droid.+; (shield)( bui|\\))/i // Nvidia Portable\n ], [MODEL, [VENDOR, NVIDIA], [TYPE, CONSOLE]], [\n /(playstation \\w+)/i // Playstation\n ], [MODEL, [VENDOR, SONY], [TYPE, CONSOLE]], [\n /\\b(xbox(?: one)?(?!; xbox))[\\); ]/i // Microsoft Xbox\n ], [MODEL, [VENDOR, MICROSOFT], [TYPE, CONSOLE]], [\n\n ///////////////////\n // WEARABLES\n ///////////////////\n\n /\\b(sm-[lr]\\d\\d[0156][fnuw]?s?|gear live)\\b/i // Samsung Galaxy Watch\n ], [MODEL, [VENDOR, SAMSUNG], [TYPE, WEARABLE]], [\n /((pebble))app/i, // Pebble\n /(asus|google|lg|oppo) ((pixel |zen)?watch[\\w ]*)( bui|\\))/i // Asus ZenWatch / LG Watch / Pixel Watch\n ], [VENDOR, MODEL, [TYPE, WEARABLE]], [\n /(ow(?:19|20)?we?[1-3]{1,3})/i // Oppo Watch\n ], [MODEL, [VENDOR, OPPO], [TYPE, WEARABLE]], [\n /(watch)(?: ?os[,\\/]|\\d,\\d\\/)[\\d\\.]+/i // Apple Watch\n ], [MODEL, [VENDOR, APPLE], [TYPE, WEARABLE]], [\n /(opwwe\\d{3})/i // OnePlus Watch\n ], [MODEL, [VENDOR, ONEPLUS], [TYPE, WEARABLE]], [\n /(moto 360)/i // Motorola 360\n ], [MODEL, [VENDOR, MOTOROLA], [TYPE, WEARABLE]], [\n /(smartwatch 3)/i // Sony SmartWatch\n ], [MODEL, [VENDOR, SONY], [TYPE, WEARABLE]], [\n /(g watch r)/i // LG G Watch R\n ], [MODEL, [VENDOR, LG], [TYPE, WEARABLE]], [\n /droid.+; (wt63?0{2,3})\\)/i\n ], [MODEL, [VENDOR, ZEBRA], [TYPE, WEARABLE]], [\n\n ///////////////////\n // XR\n ///////////////////\n\n /droid.+; (glass) \\d/i // Google Glass\n ], [MODEL, [VENDOR, GOOGLE], [TYPE, WEARABLE]], [\n /(pico) (4|neo3(?: link|pro)?)/i // Pico\n ], [VENDOR, MODEL, [TYPE, WEARABLE]], [\n /; (quest( \\d| pro)?)/i // Oculus Quest\n ], [MODEL, [VENDOR, FACEBOOK], [TYPE, WEARABLE]], [\n\n ///////////////////\n // EMBEDDED\n ///////////////////\n\n /(tesla)(?: qtcarbrowser|\\/[-\\w\\.]+)/i // Tesla\n ], [VENDOR, [TYPE, EMBEDDED]], [\n /(aeobc)\\b/i // Echo Dot\n ], [MODEL, [VENDOR, AMAZON], [TYPE, EMBEDDED]], [\n /(homepod).+mac os/i // Apple HomePod\n ], [MODEL, [VENDOR, APPLE], [TYPE, EMBEDDED]], [\n /windows iot/i\n ], [[TYPE, EMBEDDED]], [\n\n ////////////////////\n // MIXED (GENERIC)\n ///////////////////\n\n /droid .+?; ([^;]+?)(?: bui|; wv\\)|\\) applew).+? mobile safari/i // Android Phones from Unidentified Vendors\n ], [MODEL, [TYPE, MOBILE]], [\n /droid .+?; ([^;]+?)(?: bui|\\) applew).+?(?! mobile) safari/i // Android Tablets from Unidentified Vendors\n ], [MODEL, [TYPE, TABLET]], [\n /\\b((tablet|tab)[;\\/]|focus\\/\\d(?!.+mobile))/i // Unidentifiable Tablet\n ], [[TYPE, TABLET]], [\n /(phone|mobile(?:[;\\/]| [ \\w\\/\\.]*safari)|pda(?=.+windows ce))/i // Unidentifiable Mobile\n ], [[TYPE, MOBILE]], [\n /droid .+?; ([\\w\\. -]+)( bui|\\))/i // Generic Android Device\n ], [MODEL, [VENDOR, 'Generic']]\n ],\n\n engine : [[\n\n /windows.+ edge\\/([\\w\\.]+)/i // EdgeHTML\n ], [VERSION, [NAME, EDGE+'HTML']], [\n\n /(arkweb)\\/([\\w\\.]+)/i // ArkWeb\n ], [NAME, VERSION], [\n\n /webkit\\/537\\.36.+chrome\\/(?!27)([\\w\\.]+)/i // Blink\n ], [VERSION, [NAME, 'Blink']], [\n\n /(presto)\\/([\\w\\.]+)/i, // Presto\n /(webkit|trident|netfront|netsurf|amaya|lynx|w3m|goanna|servo)\\/([\\w\\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m/Goanna/Servo\n /ekioh(flow)\\/([\\w\\.]+)/i, // Flow\n /(khtml|tasman|links)[\\/ ]\\(?([\\w\\.]+)/i, // KHTML/Tasman/Links\n /(icab)[\\/ ]([23]\\.[\\d\\.]+)/i, // iCab\n\n /\\b(libweb)/i // LibWeb\n ], [NAME, VERSION], [\n /ladybird\\//i\n ], [[NAME, 'LibWeb']], [\n\n /rv\\:([\\w\\.]{1,9})\\b.+(gecko)/i // Gecko\n ], [VERSION, NAME]\n ],\n\n os : [[\n\n // Windows\n /microsoft (windows) (vista|xp)/i // Windows (iTunes)\n ], [NAME, VERSION], [\n /(windows (?:phone(?: os)?|mobile|iot))[\\/ ]?([\\d\\.\\w ]*)/i // Windows Phone\n ], [NAME, [VERSION, strMapper, windowsVersionMap]], [\n /windows nt 6\\.2; (arm)/i, // Windows RT\n /windows[\\/ ]([ntce\\d\\. ]+\\w)(?!.+xbox)/i,\n /(?:win(?=3|9|n)|win 9x )([nt\\d\\.]+)/i\n ], [[VERSION, strMapper, windowsVersionMap], [NAME, 'Windows']], [\n\n // iOS/macOS\n /[adehimnop]{4,7}\\b(?:.*os ([\\w]+) like mac|; opera)/i, // iOS\n /(?:ios;fbsv\\/|iphone.+ios[\\/ ])([\\d\\.]+)/i,\n /cfnetwork\\/.+darwin/i\n ], [[VERSION, /_/g, '.'], [NAME, 'iOS']], [\n /(mac os x) ?([\\w\\. ]*)/i,\n /(macintosh|mac_powerpc\\b)(?!.+haiku)/i // Mac OS\n ], [[NAME, MAC_OS], [VERSION, /_/g, '.']], [\n\n // Mobile OSes\n /droid ([\\w\\.]+)\\b.+(android[- ]x86|harmonyos)/i // Android-x86/HarmonyOS\n ], [VERSION, NAME], [ \n /(ubuntu) ([\\w\\.]+) like android/i // Ubuntu Touch\n ], [[NAME, /(.+)/, '$1 Touch'], VERSION], [\n // Android/Blackberry/WebOS/QNX/Bada/RIM/KaiOS/Maemo/MeeGo/S40/Sailfish OS/OpenHarmony/Tizen\n /(android|bada|blackberry|kaios|maemo|meego|openharmony|qnx|rim tablet os|sailfish|series40|symbian|tizen|webos)\\w*[-\\/; ]?([\\d\\.]*)/i\n ], [NAME, VERSION], [\n /\\(bb(10);/i // BlackBerry 10\n ], [VERSION, [NAME, BLACKBERRY]], [\n /(?:symbian ?os|symbos|s60(?=;)|series ?60)[-\\/ ]?([\\w\\.]*)/i // Symbian\n ], [VERSION, [NAME, 'Symbian']], [\n /mozilla\\/[\\d\\.]+ \\((?:mobile|tablet|tv|mobile; [\\w ]+); rv:.+ gecko\\/([\\w\\.]+)/i // Firefox OS\n ], [VERSION, [NAME, FIREFOX+' OS']], [\n /web0s;.+rt(tv)/i,\n /\\b(?:hp)?wos(?:browser)?\\/([\\w\\.]+)/i // WebOS\n ], [VERSION, [NAME, 'webOS']], [\n /watch(?: ?os[,\\/]|\\d,\\d\\/)([\\d\\.]+)/i // watchOS\n ], [VERSION, [NAME, 'watchOS']], [\n\n // Google Chromecast\n /crkey\\/([\\d\\.]+)/i // Google Chromecast\n ], [VERSION, [NAME, CHROME+'cast']], [\n /(cros) [\\w]+(?:\\)| ([\\w\\.]+)\\b)/i // Chromium OS\n ], [[NAME, CHROMIUM_OS], VERSION],[\n\n // Smart TVs\n /panasonic;(viera)/i, // Panasonic Viera\n /(netrange)mmh/i, // Netrange\n /(nettv)\\/(\\d+\\.[\\w\\.]+)/i, // NetTV\n\n // Console\n /(nintendo|playstation) ([wids345portablevuch]+)/i, // Nintendo/Playstation\n /(xbox); +xbox ([^\\);]+)/i, // Microsoft Xbox (360, One, X, S, Series X, Series S)\n\n // Other\n /\\b(joli|palm)\\b ?(?:os)?\\/?([\\w\\.]*)/i, // Joli/Palm\n /(mint)[\\/\\(\\) ]?(\\w*)/i, // Mint\n /(mageia|vectorlinux)[; ]/i, // Mageia/VectorLinux\n /([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,\n // Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware/Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus/Raspbian/Plan9/Minix/RISCOS/Contiki/Deepin/Manjaro/elementary/Sabayon/Linspire\n /(hurd|linux)(?: arm\\w*| x86\\w*| ?)([\\w\\.]*)/i, // Hurd/Linux\n /(gnu) ?([\\w\\.]*)/i, // GNU\n /\\b([-frentopcghs]{0,5}bsd|dragonfly)[\\/ ]?(?!amd|[ix346]{1,2}86)([\\w\\.]*)/i, // FreeBSD/NetBSD/OpenBSD/PC-BSD/GhostBSD/DragonFly\n /(haiku) (\\w+)/i // Haiku\n ], [NAME, VERSION], [\n /(sunos) ?([\\w\\.\\d]*)/i // Solaris\n ], [[NAME, 'Solaris'], VERSION], [\n /((?:open)?solaris)[-\\/ ]?([\\w\\.]*)/i, // Solaris\n /(aix) ((\\d)(?=\\.|\\)| )[\\w\\.])*/i, // AIX\n /\\b(beos|os\\/2|amigaos|morphos|openvms|fuchsia|hp-ux|serenityos)/i, // BeOS/OS2/AmigaOS/MorphOS/OpenVMS/Fuchsia/HP-UX/SerenityOS\n /(unix) ?([\\w\\.]*)/i // UNIX\n ], [NAME, VERSION]\n ]\n };\n\n /////////////////\n // Constructor\n ////////////////\n\n var UAParser = function (ua, extensions) {\n\n if (typeof ua === OBJ_TYPE) {\n extensions = ua;\n ua = undefined;\n }\n\n if (!(this instanceof UAParser)) {\n return new UAParser(ua, extensions).getResult();\n }\n\n var _navigator = (typeof window !== UNDEF_TYPE && window.navigator) ? window.navigator : undefined;\n var _ua = ua || ((_navigator && _navigator.userAgent) ? _navigator.userAgent : EMPTY);\n var _uach = (_navigator && _navigator.userAgentData) ? _navigator.userAgentData : undefined;\n var _rgxmap = extensions ? extend(regexes, extensions) : regexes;\n var _isSelfNav = _navigator && _navigator.userAgent == _ua;\n\n this.getBrowser = function () {\n var _browser = {};\n _browser[NAME] = undefined;\n _browser[VERSION] = undefined;\n rgxMapper.call(_browser, _ua, _rgxmap.browser);\n _browser[MAJOR] = majorize(_browser[VERSION]);\n // Brave-specific detection\n if (_isSelfNav && _navigator && _navigator.brave && typeof _navigator.brave.isBrave == FUNC_TYPE) {\n _browser[NAME] = 'Brave';\n }\n return _browser;\n };\n this.getCPU = function () {\n var _cpu = {};\n _cpu[ARCHITECTURE] = undefined;\n rgxMapper.call(_cpu, _ua, _rgxmap.cpu);\n return _cpu;\n };\n this.getDevice = function () {\n var _device = {};\n _device[VENDOR] = undefined;\n _device[MODEL] = undefined;\n _device[TYPE] = undefined;\n rgxMapper.call(_device, _ua, _rgxmap.device);\n if (_isSelfNav && !_device[TYPE] && _uach && _uach.mobile) {\n _device[TYPE] = MOBILE;\n }\n // iPadOS-specific detection: identified as Mac, but has some iOS-only properties\n if (_isSelfNav && _device[MODEL] == 'Macintosh' && _navigator && typeof _navigator.standalone !== UNDEF_TYPE && _navigator.maxTouchPoints && _navigator.maxTouchPoints > 2) {\n _device[MODEL] = 'iPad';\n _device[TYPE] = TABLET;\n }\n return _device;\n };\n this.getEngine = function () {\n var _engine = {};\n _engine[NAME] = undefined;\n _engine[VERSION] = undefined;\n rgxMapper.call(_engine, _ua, _rgxmap.engine);\n return _engine;\n };\n this.getOS = function () {\n var _os = {};\n _os[NAME] = undefined;\n _os[VERSION] = undefined;\n rgxMapper.call(_os, _ua, _rgxmap.os);\n if (_isSelfNav && !_os[NAME] && _uach && _uach.platform && _uach.platform != 'Unknown') {\n _os[NAME] = _uach.platform \n .replace(/chrome os/i, CHROMIUM_OS)\n .replace(/macos/i, MAC_OS); // backward compatibility\n }\n return _os;\n };\n this.getResult = function () {\n return {\n ua : this.getUA(),\n browser : this.getBrowser(),\n engine : this.getEngine(),\n os : this.getOS(),\n device : this.getDevice(),\n cpu : this.getCPU()\n };\n };\n this.getUA = function () {\n return _ua;\n };\n this.setUA = function (ua) {\n _ua = (typeof ua === STR_TYPE && ua.length > UA_MAX_LENGTH) ? trim(ua, UA_MAX_LENGTH) : ua;\n return this;\n };\n this.setUA(_ua);\n return this;\n };\n\n UAParser.VERSION = LIBVERSION;\n UAParser.BROWSER = enumerize([NAME, VERSION, MAJOR]);\n UAParser.CPU = enumerize([ARCHITECTURE]);\n UAParser.DEVICE = enumerize([MODEL, VENDOR, TYPE, CONSOLE, MOBILE, SMARTTV, TABLET, WEARABLE, EMBEDDED]);\n UAParser.ENGINE = UAParser.OS = enumerize([NAME, VERSION]);\n\n ///////////\n // Export\n //////////\n\n // check js environment\n if (typeof(exports) !== UNDEF_TYPE) {\n // nodejs env\n if (typeof module !== UNDEF_TYPE && module.exports) {\n exports = module.exports = UAParser;\n }\n exports.UAParser = UAParser;\n } else {\n // requirejs env (optional)\n if (typeof(define) === FUNC_TYPE && define.amd) {\n define(function () {\n return UAParser;\n });\n } else if (typeof window !== UNDEF_TYPE) {\n // browser env\n window.UAParser = UAParser;\n }\n }\n\n // jQuery/Zepto specific (optional)\n // Note:\n // In AMD env the global scope should be kept clean, but jQuery is an exception.\n // jQuery always exports to global scope, unless jQuery.noConflict(true) is used,\n // and we should catch that.\n var $ = typeof window !== UNDEF_TYPE && (window.jQuery || window.Zepto);\n if ($ && !$.ua) {\n var parser = new UAParser();\n $.ua = parser.getResult();\n $.ua.get = function () {\n return parser.getUA();\n };\n $.ua.set = function (ua) {\n parser.setUA(ua);\n var result = parser.getResult();\n for (var prop in result) {\n $.ua[prop] = result[prop];\n }\n };\n }\n\n})(typeof window === 'object' ? window : this);\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","// Main entry point for the Elevate AB Testing NPM package\n\n// ============================================================================\n// TYPE EXPORTS\n// ============================================================================\n\n// Core SDK types\nexport type {\n Test,\n Variation,\n ElevateConfig,\n ElevateProviderProps,\n ElevateContextValue,\n ElevateAnalyticsProps,\n ExperimentStatus,\n BackendConfig,\n BackendTest,\n BackendVariation,\n} from \"./types\";\n\n// Event tracking types (for manual tracking)\nexport type {\n // Base config\n BaseTrackingConfig,\n // Individual event params\n TrackPageViewParams,\n TrackProductViewParams,\n TrackAddToCartParams,\n TrackRemoveFromCartParams,\n TrackCartViewParams,\n TrackSearchSubmittedParams,\n TrackCheckoutStartedParams,\n TrackCheckoutCompletedParams,\n UsePageViewTrackingParams,\n // Shared types\n CartItemInput,\n NoteAttribute,\n TestAssignment,\n // Internal payload (for advanced users)\n EventPayload,\n CartItemPayload,\n} from \"./types\";\n\n// Cart attribute types\nexport type { CartAttributesOptions, CartAttributeInput } from \"./types\";\n\n// Legacy types (deprecated)\nexport type { TrackingEvent } from \"./types\";\n\nexport {\n assignVariant,\n hashString,\n validateConfig,\n generateExperimentId,\n calculateRevenueLift,\n} from \"./utils\";\n\n// Storage utilities\nexport {\n setCookie,\n getCookie,\n getJsonCookie,\n deleteCookie,\n setSessionItem,\n getSessionItem,\n getJsonSessionItem,\n getVisitorId,\n initializeVisitorId,\n getSessionId,\n initializeSessionId,\n setReferrerData,\n getReferrerData,\n uuidv4,\n} from \"./utils/storage\";\n\n// Assignment utilities\nexport {\n getTestList,\n saveTestList,\n getAssignedVariant,\n assignAndPersistVariant,\n shouldShowTest,\n} from \"./utils/assignment\";\n\n// Tracking utilities\nexport {\n trackViews,\n trackUniqueView,\n trackSessionView,\n hasSessionView,\n hasUniqueView,\n} from \"./utils/tracking\";\n\n// Condition utilities\nexport {\n getDeviceType,\n getTrafficSource,\n checkFacebookBrowser,\n checkInstagramBrowser,\n checkTikTokBrowser,\n checkPinterestBrowser,\n} from \"./utils/conditions\";\n\n// Preview mode utilities\nexport {\n getPreviewState,\n isPreviewTest,\n getPreviewVariation,\n buildEabTestsParam,\n updateUrlWithTestParams,\n clearPreviewMode,\n isInPreviewMode,\n} from \"./utils/preview\";\nexport type { PreviewState } from \"./utils/preview\";\n\n// Geo-targeting utilities\nexport {\n getCountryCode,\n getGeoLocation,\n setCountryCode,\n setGeoLocation,\n isCountryIncluded,\n isCountryExcluded,\n matchesGeoTargeting,\n COUNTRIES,\n REGIONS,\n} from \"./utils/geo\";\nexport type { GeoLocation } from \"./utils/geo\";\n\n// Anti-flicker utilities\nexport {\n setupFlickerPrevention,\n injectFlickerStyles,\n hideForFlicker,\n revealAfterFlicker,\n cleanupFlickerPrevention,\n isFlickerPreventionActive,\n getFlickerPreventionScript,\n} from \"./utils/antiFlicker\";\n\n// Analytics utilities\nexport {\n parseAddViewData,\n extractProductId,\n extractProductVariantId,\n extractCartToken,\n cleanCartToken,\n getPageTypeFromPathname,\n sanitizeString,\n roundToTwo,\n checkFacebookInstagramBrowser,\n checkVisitorIdParams,\n getUserAgentNoBrowser,\n} from \"./utils/analytics\";\n\nexport type { ParsedViewData } from \"./utils/analytics\";\n\n// Shopify utilities\nexport {\n extractShopifyId,\n extractShopifyType,\n isShopifyGid,\n detectShopifyCurrency,\n} from \"./utils/shopify\";\n\n// Cart attribute utilities\nexport {\n updateCartAttributes,\n cleanupCartAttributes,\n getCartAttributesPayload,\n} from \"./utils/cartAttributes\";\n\n// Cart mutations\nexport { CART_ATTRIBUTES_UPDATE_MUTATION } from \"./mutations/cartAttributes.mutation\";\n\n// Manual tracking utilities (for Next.js and other frameworks)\n// Note: ElevateProvider auto-calls initAnalytics, so you usually don't need to call it manually\nexport {\n initAnalytics,\n trackPageView,\n trackProductView,\n trackAddToCart,\n trackRemoveFromCart,\n trackCartView,\n trackSearchSubmitted,\n trackCheckoutStarted,\n trackCheckoutCompleted,\n usePageViewTracking,\n} from \"./utils/manualTracking\";\n\n// Components\nexport { useExperiment } from \"./components/Experiment\";\nexport type { UseExperimentResult } from \"./components/Experiment\";\nexport { ElevateProvider } from \"./components/ElevateProvider\";\nexport { AntiFlickerScript } from \"./components/AntiFlickerScript\";\n\n// Analytics components\n// For Hydrogen stores: import from '@elevateab/sdk/hydrogen' for ElevateHydrogenAnalytics\n// For Next.js/Remix: use ElevateAnalytics with manual hook injection\nexport { ElevateAnalytics } from \"./components/ElevateAnalytics\";\nexport type {\n UseAnalyticsHook,\n ElevateHydrogenAnalyticsProps,\n} from \"./components/ElevateAnalytics\";\n\n// Note: ElevateHydrogenAnalytics is exported from '@elevateab/sdk/hydrogen' sub-path\n// to avoid bundling @shopify/hydrogen in non-Hydrogen projects\n\n// Contexts\nexport { useElevateConfig } from \"./contexts/ElevateContext\";\n\n// Package version\nexport const VERSION = \"1.1.2\";\n\n// Default configuration\nexport const DEFAULT_CONFIG = {\n enabled: true,\n trackingEndpoint: \"https://analytics.elevateab.com/track\",\n cacheDuration: 3600,\n};\n","/**\n * Tracking utilities for views and participation\n */\n\nimport {\n setCookie,\n setSessionItem,\n getJsonCookie,\n getJsonSessionItem,\n} from \"./storage\";\n\n/**\n * Track unique view for a test (ABAU cookie)\n */\nexport function trackUniqueView(testId: string): void {\n const addedUniqueViews = getJsonCookie<Record<string, boolean>>(\"ABAU\") || {};\n\n if (!addedUniqueViews[testId]) {\n addedUniqueViews[testId] = true;\n setCookie(\"ABAU\", JSON.stringify(addedUniqueViews));\n }\n}\n\n/**\n * Track session view for a test (ABAV session storage)\n */\nexport function trackSessionView(testId: string): void {\n const addedViews = getJsonSessionItem<Record<string, boolean>>(\"ABAV\") || {};\n\n if (!addedViews[testId]) {\n addedViews[testId] = true;\n setSessionItem(\"ABAV\", addedViews);\n }\n}\n\n/**\n * Track both unique and session views\n */\nexport function trackViews(testId: string): void {\n trackUniqueView(testId);\n trackSessionView(testId);\n}\n\n/**\n * Check if test has been viewed in this session\n */\nexport function hasSessionView(testId: string): boolean {\n const addedViews = getJsonSessionItem<Record<string, boolean>>(\"ABAV\") || {};\n return !!addedViews[testId];\n}\n\n/**\n * Check if test has a unique view\n */\nexport function hasUniqueView(testId: string): boolean {\n const addedUniqueViews = getJsonCookie<Record<string, boolean>>(\"ABAU\") || {};\n return !!addedUniqueViews[testId];\n}\n","/**\n * Condition checking utilities for targeting and filtering\n */\n\n/**\n * Detect device type\n */\nexport function getDeviceType(): \"desktop\" | \"tablet\" | \"mobile\" {\n if (typeof navigator === \"undefined\") return \"desktop\";\n\n const ua =\n navigator.userAgent || navigator.vendor || (window as any).opera || \"\";\n const lower = ua.toLowerCase();\n\n if (\n /windows nt.*tablet pc|pixelbook/i.test(ua) ||\n (/(?:macintosh|windows nt|win(?:95|98)|linux x86_64)/i.test(ua) &&\n !/android|mobile|tablet|ipad|iphone|ipod/i.test(lower))\n )\n return \"desktop\";\n\n const isTablet =\n /ipad|playbook|tablet|kindle|nexus (7|10)|xoom|sm-t\\d+|galaxy tab|tb-\\d+|tb\\d+[a-z]+|lenovo.*tb|dtab|ideatab|mediapad|matepad|honor.*pad|pad\\s+\\d+|mi\\s+pad|redmi.*pad|xiaomi.*pad|oppo.*pad|oneplus.*pad|opd\\d+|tcl.*tab|9\\d{3}[a-z]|kobo|archos.*5(?!\\d)|ereader|droipad/i.test(\n ua\n ) ||\n (/android(?!.*mobile)/i.test(lower) &&\n !/dalvik.*miui|pocophone|mi\\s+mix|edge\\s+\\d+|sm-g9\\d+|pixel\\s+\\d|pixel\\s+fold|advan\\s+\\d{4}/i.test(\n ua\n ));\n\n if (isTablet) return \"tablet\";\n\n const isMobile =\n /android.+mobile|iphone|ipod|windows phone|blackberry|mobile|phone|kaios/i.test(\n lower\n ) ||\n /^mobile;/i.test(ua) ||\n /dalvik.*miui|pocophone|mi\\s+mix|pixel\\s+\\d|pixel\\s+fold/i.test(ua);\n\n if (isMobile) return \"mobile\";\n\n return \"desktop\";\n}\n\n/**\n * Check if Facebook in-app browser\n */\nexport function checkFacebookBrowser(): boolean {\n if (typeof navigator === \"undefined\") return false;\n\n const userAgent =\n navigator.userAgent || navigator.vendor || (window as any).opera;\n const facebookBrowserRegex =\n /((?:fban\\/fbios|fb_iab\\/fb4a)(?!.+fbav)|;fbav\\/([\\w\\.]+);)/i;\n return facebookBrowserRegex.test(userAgent);\n}\n\n/**\n * Check if Instagram in-app browser\n */\nexport function checkInstagramBrowser(): boolean {\n if (typeof navigator === \"undefined\") return false;\n\n const userAgent =\n navigator.userAgent || navigator.vendor || (window as any).opera;\n const instagramBrowserRegex = /(instagram)[\\/ ]([-\\w\\.]+)/i;\n return instagramBrowserRegex.test(userAgent);\n}\n\n/**\n * Check if TikTok in-app browser\n */\nexport function checkTikTokBrowser(): boolean {\n if (typeof navigator === \"undefined\") return false;\n\n const userAgent =\n navigator.userAgent || navigator.vendor || (window as any).opera;\n const tikTokBrowserRegex = /musical_ly/i;\n return tikTokBrowserRegex.test(userAgent);\n}\n\n/**\n * Check if Pinterest in-app browser\n */\nexport function checkPinterestBrowser(): boolean {\n if (typeof navigator === \"undefined\") return false;\n\n const userAgent =\n navigator.userAgent || navigator.vendor || (window as any).opera;\n const pinterestBrowserRegex = /(pinterest)[\\/ ]([-\\w\\.]+)/i;\n return pinterestBrowserRegex.test(userAgent);\n}\n\n/**\n * Get traffic source\n */\nexport function getTrafficSource(): string {\n if (typeof window === \"undefined\") return \"direct\";\n\n const referrer = (document.referrer || \"\").toLowerCase();\n const referrerDomain = referrer\n ? new URL(referrer).hostname.replace(\"www.\", \"\")\n : \"\";\n const hostname = window.location.hostname;\n\n const isFacebookBrowser = checkFacebookBrowser();\n const isInstagramBrowser = checkInstagramBrowser();\n const isTikTokBrowser = checkTikTokBrowser();\n const isPinterestBrowser = checkPinterestBrowser();\n\n if (\n isFacebookBrowser ||\n [\n \"facebook.com\",\n \"fb.com\",\n \"fb.me\",\n \"m.facebook.com\",\n \"l.facebook.com\",\n \"lm.facebook.com\",\n ].includes(referrerDomain)\n ) {\n return \"facebook\";\n } else if (isInstagramBrowser || referrerDomain.includes(\"instagram\")) {\n return \"instagram\";\n } else if (\n isTikTokBrowser ||\n [\"tiktok.com\", \"pangleglobal.com\", \"ads.tiktok.com\"].includes(\n referrerDomain\n )\n ) {\n return \"tiktok\";\n } else if (\n isPinterestBrowser ||\n referrerDomain.includes(\"pinterest\") ||\n referrerDomain === \"pin.it\"\n ) {\n return \"pinterest\";\n } else if (referrerDomain.includes(\"google\")) {\n return \"google\";\n } else if (!referrer || hostname === referrerDomain) {\n return \"direct\";\n } else {\n return \"other\";\n }\n}\n","/**\n * Preview Mode Utilities\n *\n * Enables QA/preview functionality for A/B tests via URL parameters.\n *\n * URL Format:\n * ?eabUserPreview=true&abtid=<test_id>&eab_tests=<shortid>_<variation>_<seen>\n *\n * Example:\n * https://store.com/?eabUserPreview=true&abtid=b6e2ecb8-e35a-450e-ae49-bdc560cf0fd7&eab_tests=f0fd7_29913_1\n */\n\nimport {\n getCookie,\n setCookie,\n getSessionItem,\n setSessionItem,\n} from \"./storage\";\n\n/**\n * Preview mode state\n */\nexport interface PreviewState {\n /** Whether preview mode is active */\n isPreview: boolean;\n /** The test ID being previewed (full UUID or short ID) */\n previewTestId: string | null;\n /** Forced test assignments from URL params */\n forcedAssignments: Record<string, string>;\n /** Tests that have been marked as \"seen\" in preview */\n previewedViews: Record<string, boolean>;\n}\n\n/**\n * Parse eab_tests parameter format: shortid_variation_seen~shortid2_variation2_seen2\n * Example: \"f0fd7_29913_1\" or \"f0fd7_29913_1~a1b2c_12345_0\"\n */\nfunction parseEabTestsParam(param: string): {\n assignments: Record<string, string>;\n views: Record<string, boolean>;\n} {\n const assignments: Record<string, string> = {};\n const views: Record<string, boolean> = {};\n\n if (!param) return { assignments, views };\n\n const tests = param.split(\"~\");\n for (const test of tests) {\n const parts = test.split(\"_\");\n if (parts.length >= 2) {\n const shortTestId = parts[0];\n const variationId = parts[1];\n const hasSeen = parts[2] === \"1\";\n\n assignments[shortTestId] = variationId;\n views[shortTestId] = hasSeen;\n }\n }\n\n return { assignments, views };\n}\n\n/**\n * Get preview state from URL parameters and cookies\n */\nexport function getPreviewState(): PreviewState {\n if (typeof window === \"undefined\") {\n return {\n isPreview: false,\n previewTestId: null,\n forcedAssignments: {},\n previewedViews: {},\n };\n }\n\n const urlParams = new URLSearchParams(window.location.search);\n\n // Check URL param first, then cookie\n const eabUserPreview =\n urlParams.get(\"eabUserPreview\") || getCookie(\"eabUserPreview\");\n const isPreview = eabUserPreview === \"true\";\n\n // Get test ID from URL param or sessionStorage\n let previewTestId = urlParams.get(\"abtid\");\n if (!previewTestId) {\n previewTestId = getSessionItem(\"eabPreviewTestId\");\n }\n\n // Parse forced assignments from eab_tests param\n const eabTestsParam = urlParams.get(\"eab_tests\") || \"\";\n const { assignments, views } = parseEabTestsParam(eabTestsParam);\n\n // If URL has preview params, persist to storage\n if (urlParams.has(\"eabUserPreview\")) {\n setCookie(\"eabUserPreview\", \"true\");\n }\n if (urlParams.has(\"abtid\") && previewTestId) {\n setSessionItem(\"eabPreviewTestId\", previewTestId);\n }\n\n return {\n isPreview,\n previewTestId,\n forcedAssignments: assignments,\n previewedViews: views,\n };\n}\n\n/**\n * Check if a test matches the preview test ID\n * Supports both full UUID and short ID (last 5 chars) matching\n */\nexport function isPreviewTest(\n testId: string,\n previewTestId: string | null,\n): boolean {\n if (!previewTestId) return false;\n\n // Exact match\n if (testId === previewTestId) return true;\n\n // Short ID match (last 5 characters)\n const shortTestId = testId.slice(-5);\n if (shortTestId === previewTestId || previewTestId.endsWith(shortTestId)) {\n return true;\n }\n\n // Preview ID might be short, check if test ends with it\n if (testId.endsWith(previewTestId)) return true;\n\n return false;\n}\n\n/**\n * Get forced variation for a test in preview mode\n * Returns null if no forced assignment exists\n */\nexport function getPreviewVariation(\n testId: string,\n previewState: PreviewState,\n): string | null {\n if (!previewState.isPreview) return null;\n\n // Check by full test ID\n if (previewState.forcedAssignments[testId]) {\n return previewState.forcedAssignments[testId];\n }\n\n // Check by short test ID\n const shortTestId = testId.slice(-5);\n if (previewState.forcedAssignments[shortTestId]) {\n return previewState.forcedAssignments[shortTestId];\n }\n\n return null;\n}\n\n/**\n * Build eab_tests URL parameter string from test assignments\n * Used for sharing preview URLs with Facebook/Instagram traffic\n */\nexport function buildEabTestsParam(\n testAssignments: Record<string, string>,\n viewedTests: Record<string, boolean>,\n): string {\n return Object.entries(testAssignments)\n .map(([testId, variationId]) => {\n const shortTestId = testId.slice(-5);\n const hasSeen = viewedTests[testId] ? \"1\" : \"0\";\n return `${shortTestId}_${variationId}_${hasSeen}`;\n })\n .join(\"~\");\n}\n\n/**\n * Update URL with test parameters for social media browsers (FB/IG/TikTok)\n * These browsers often lose cookies, so we persist test assignments in URL\n */\nexport function updateUrlWithTestParams(\n testAssignments: Record<string, string>,\n viewedTests: Record<string, boolean>,\n visitorId?: string,\n): void {\n if (typeof window === \"undefined\") return;\n\n const url = new URL(window.location.href);\n const eabTestsValue = buildEabTestsParam(testAssignments, viewedTests);\n\n if (eabTestsValue) {\n url.searchParams.set(\"eab_tests\", eabTestsValue);\n }\n\n if (visitorId) {\n url.searchParams.set(\"eabUserId\", visitorId);\n }\n\n // Update URL without reload\n window.history.replaceState({}, \"\", url.toString());\n}\n\n/**\n * Clear preview mode\n */\nexport function clearPreviewMode(): void {\n if (typeof document === \"undefined\") return;\n\n // Clear cookie\n document.cookie =\n \"eabUserPreview=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;\";\n\n // Clear session storage\n if (typeof sessionStorage !== \"undefined\") {\n sessionStorage.removeItem(\"eabPreviewTestId\");\n }\n\n // Remove preview params from URL\n if (typeof window !== \"undefined\") {\n const url = new URL(window.location.href);\n url.searchParams.delete(\"eabUserPreview\");\n url.searchParams.delete(\"abtid\");\n url.searchParams.delete(\"eab_tests\");\n window.history.replaceState({}, \"\", url.toString());\n }\n}\n\n/**\n * Check if current session is in preview mode\n */\nexport function isInPreviewMode(): boolean {\n return getPreviewState().isPreview;\n}\n","/**\n * Geo-targeting Utilities\n *\n * Provides country detection and geo-based targeting for A/B tests.\n */\n\nimport { getCookie, setCookie } from \"./storage\";\n\n/**\n * Geo-location data\n */\nexport interface GeoLocation {\n /** ISO 3166-1 alpha-2 country code (e.g., \"US\", \"GB\", \"CA\") */\n country: string | null;\n /** Region/state code (if available) */\n region?: string | null;\n /** City name (if available) */\n city?: string | null;\n}\n\n/**\n * Cookie names for geo data\n */\nconst GEO_COOKIE_NAMES = {\n /** Shopify's localization cookie */\n SHOPIFY_LOCALIZATION: \"localization\",\n /** Our cached country code */\n EAB_COUNTRY: \"eabCountryCode\",\n /** Full geo data (JSON) */\n EAB_GEO: \"eabGeoLocation\",\n} as const;\n\n/**\n * Get the user's country code from various sources\n * Priority: URL param > Shopify localization > our cookie > localStorage\n */\nexport function getCountryCode(): string | null {\n if (typeof window === \"undefined\") return null;\n\n // 1. Check URL param (for explicit override)\n const urlParams = new URLSearchParams(window.location.search);\n const urlCountry = urlParams.get(\"country\");\n if (urlCountry) {\n // Cache it\n setCookie(GEO_COOKIE_NAMES.EAB_COUNTRY, urlCountry.toUpperCase());\n return urlCountry.toUpperCase();\n }\n\n // 2. Check Shopify's localization cookie (most common for Shopify stores)\n const shopifyCountry = getCookie(GEO_COOKIE_NAMES.SHOPIFY_LOCALIZATION);\n if (shopifyCountry) {\n return shopifyCountry.toUpperCase();\n }\n\n // 3. Check our cached cookie\n const cachedCountry = getCookie(GEO_COOKIE_NAMES.EAB_COUNTRY);\n if (cachedCountry) {\n return cachedCountry.toUpperCase();\n }\n\n // 4. Check localStorage (fallback)\n if (typeof localStorage !== \"undefined\") {\n const storedCountry = localStorage.getItem(GEO_COOKIE_NAMES.EAB_COUNTRY);\n if (storedCountry) {\n return storedCountry.toUpperCase();\n }\n }\n\n return null;\n}\n\n/**\n * Get full geo-location data\n */\nexport function getGeoLocation(): GeoLocation {\n const country = getCountryCode();\n\n // Try to get extended geo data from cookie\n const geoData = getCookie(GEO_COOKIE_NAMES.EAB_GEO);\n if (geoData) {\n try {\n const parsed = JSON.parse(geoData) as GeoLocation;\n return {\n country: parsed.country || country,\n region: parsed.region,\n city: parsed.city,\n };\n } catch {\n // Invalid JSON, fall through\n }\n }\n\n return { country };\n}\n\n/**\n * Set the user's country code (for manual override or after geo detection)\n */\nexport function setCountryCode(countryCode: string): void {\n const normalized = countryCode.toUpperCase();\n setCookie(GEO_COOKIE_NAMES.EAB_COUNTRY, normalized);\n\n // Also store in localStorage for extra persistence\n if (typeof localStorage !== \"undefined\") {\n localStorage.setItem(GEO_COOKIE_NAMES.EAB_COUNTRY, normalized);\n }\n}\n\n/**\n * Set full geo-location data\n */\nexport function setGeoLocation(geo: GeoLocation): void {\n if (geo.country) {\n setCountryCode(geo.country);\n }\n\n // Store full geo data\n setCookie(GEO_COOKIE_NAMES.EAB_GEO, JSON.stringify(geo));\n}\n\n/**\n * Check if user's country matches a list of allowed countries\n */\nexport function isCountryIncluded(\n allowedCountries: string[],\n userCountry?: string | null,\n): boolean {\n const country = userCountry ?? getCountryCode();\n if (!country) return false;\n\n const normalizedAllowed = allowedCountries.map((c) => c.toUpperCase());\n return normalizedAllowed.includes(country.toUpperCase());\n}\n\n/**\n * Check if user's country is in an excluded list\n */\nexport function isCountryExcluded(\n excludedCountries: string[],\n userCountry?: string | null,\n): boolean {\n const country = userCountry ?? getCountryCode();\n if (!country) return false;\n\n const normalizedExcluded = excludedCountries.map((c) => c.toUpperCase());\n return normalizedExcluded.includes(country.toUpperCase());\n}\n\n/**\n * Check if user matches geo-targeting rules\n * Returns true if user should be included in the test\n */\nexport function matchesGeoTargeting(rules: {\n includeCountries?: string[];\n excludeCountries?: string[];\n}): boolean {\n const country = getCountryCode();\n\n // If no rules, include everyone\n if (!rules.includeCountries?.length && !rules.excludeCountries?.length) {\n return true;\n }\n\n // If no country detected and rules exist, exclude (can't target unknown)\n if (!country) {\n return false;\n }\n\n // Check exclusions first (takes precedence)\n if (rules.excludeCountries?.length) {\n if (isCountryExcluded(rules.excludeCountries, country)) {\n return false;\n }\n }\n\n // If include list exists, user must be in it\n if (rules.includeCountries?.length) {\n return isCountryIncluded(rules.includeCountries, country);\n }\n\n // No include list, and not excluded = included\n return true;\n}\n\n/**\n * Common country code constants for convenience\n */\nexport const COUNTRIES = {\n US: \"US\",\n CA: \"CA\",\n GB: \"GB\",\n AU: \"AU\",\n DE: \"DE\",\n FR: \"FR\",\n JP: \"JP\",\n MX: \"MX\",\n BR: \"BR\",\n IN: \"IN\",\n // Add more as needed\n} as const;\n\n/**\n * Region groupings for common use cases\n */\nexport const REGIONS = {\n NORTH_AMERICA: [\"US\", \"CA\", \"MX\"],\n EUROPE: [\n \"GB\",\n \"DE\",\n \"FR\",\n \"IT\",\n \"ES\",\n \"NL\",\n \"BE\",\n \"AT\",\n \"CH\",\n \"PL\",\n \"SE\",\n \"NO\",\n \"DK\",\n \"FI\",\n \"IE\",\n \"PT\",\n ],\n APAC: [\n \"AU\",\n \"NZ\",\n \"JP\",\n \"KR\",\n \"SG\",\n \"HK\",\n \"TW\",\n \"TH\",\n \"MY\",\n \"PH\",\n \"ID\",\n \"VN\",\n \"IN\",\n ],\n LATAM: [\"MX\", \"BR\", \"AR\", \"CL\", \"CO\", \"PE\"],\n} as const;\n","/**\n * Anti-Flicker Utilities\n *\n * Prevents visual flickering during A/B test assignment by hiding content\n * until the variant is determined. Uses a CSS-based approach for performance.\n *\n * Note: Called \"preventFlickering\" in our API to differentiate from competitors.\n */\n\n/**\n * CSS class used to hide content during flicker prevention\n */\nconst FLICKER_CLASS = \"eab-prevent-flicker\";\n\n/**\n * Inline style ID for flicker prevention\n */\nconst STYLE_ID = \"eab-flicker-styles\";\n\n/**\n * Default timeout (ms) before showing content anyway (failsafe)\n */\nconst DEFAULT_TIMEOUT = 3000;\n\n/**\n * Inject the flicker prevention CSS styles\n * This should be called as early as possible (ideally in <head>)\n */\nexport function injectFlickerStyles(timeout = DEFAULT_TIMEOUT): void {\n if (typeof document === \"undefined\") return;\n\n // Don't inject twice\n if (document.getElementById(STYLE_ID)) return;\n\n const style = document.createElement(\"style\");\n style.id = STYLE_ID;\n style.textContent = `\n /* Elevate AB - Flicker Prevention */\n .${FLICKER_CLASS} {\n opacity: 0 !important;\n pointer-events: none !important;\n }\n \n /* Failsafe: ensure content shows after timeout via animation */\n @keyframes eab-reveal {\n to { opacity: 1; pointer-events: auto; }\n }\n \n .${FLICKER_CLASS} {\n animation: eab-reveal 0s ${timeout}ms forwards;\n }\n `;\n\n // Insert at the beginning of <head> for highest priority\n const head = document.head || document.getElementsByTagName(\"head\")[0];\n head.insertBefore(style, head.firstChild);\n}\n\n/**\n * Hide the page/element to prevent flicker\n * Call this before test assignment begins\n */\nexport function hideForFlicker(selector: string = \"body\"): void {\n if (typeof document === \"undefined\") return;\n\n const element = document.querySelector(selector);\n if (element) {\n element.classList.add(FLICKER_CLASS);\n }\n}\n\n/**\n * Show the page/element after test assignment is complete\n * Call this after variant is determined\n */\nexport function revealAfterFlicker(selector: string = \"body\"): void {\n if (typeof document === \"undefined\") return;\n\n const element = document.querySelector(selector);\n if (element) {\n element.classList.remove(FLICKER_CLASS);\n }\n}\n\n/**\n * Setup flicker prevention with automatic reveal\n * Returns a function to call when assignment is complete\n *\n * @param selector - CSS selector for element to hide (default: \"body\")\n * @param timeout - Maximum time to wait before revealing (default: 3000ms)\n * @returns Function to call when test assignment is complete\n *\n * @example\n * ```tsx\n * // In your app initialization\n * const reveal = setupFlickerPrevention();\n *\n * // After test assignment\n * reveal();\n * ```\n */\nexport function setupFlickerPrevention(\n selector: string = \"body\",\n timeout: number = DEFAULT_TIMEOUT,\n): () => void {\n if (typeof document === \"undefined\") {\n return () => {}; // No-op for SSR\n }\n\n // Inject styles\n injectFlickerStyles(timeout);\n\n // Hide content\n hideForFlicker(selector);\n\n // Setup timeout failsafe\n let hasRevealed = false;\n const timeoutId = setTimeout(() => {\n if (!hasRevealed) {\n console.warn(\n `[ElevateAB] Flicker prevention timeout (${timeout}ms) reached. ` +\n \"Revealing content. Check if test assignment is completing.\",\n );\n revealAfterFlicker(selector);\n hasRevealed = true;\n }\n }, timeout);\n\n // Return reveal function\n return () => {\n if (!hasRevealed) {\n clearTimeout(timeoutId);\n revealAfterFlicker(selector);\n hasRevealed = true;\n }\n };\n}\n\n/**\n * Remove all flicker prevention styles and classes\n * Useful for cleanup or when disabling the feature\n */\nexport function cleanupFlickerPrevention(): void {\n if (typeof document === \"undefined\") return;\n\n // Remove style tag\n const style = document.getElementById(STYLE_ID);\n if (style) {\n style.remove();\n }\n\n // Remove class from all elements\n const elements = document.querySelectorAll(`.${FLICKER_CLASS}`);\n elements.forEach((el) => el.classList.remove(FLICKER_CLASS));\n}\n\n/**\n * Check if flicker prevention is currently active\n */\nexport function isFlickerPreventionActive(): boolean {\n if (typeof document === \"undefined\") return false;\n\n return document.querySelector(`.${FLICKER_CLASS}`) !== null;\n}\n\n/**\n * Script snippet for inline injection in <head>\n * Use this when you need synchronous flicker prevention before React hydrates\n *\n * @example\n * ```tsx\n * // In your _document.tsx or layout.tsx\n * <script dangerouslySetInnerHTML={{ __html: getFlickerPreventionScript() }} />\n * ```\n */\nexport function getFlickerPreventionScript(timeout = DEFAULT_TIMEOUT): string {\n return `\n(function() {\n var style = document.createElement('style');\n style.id = '${STYLE_ID}';\n style.textContent = '.${FLICKER_CLASS}{opacity:0!important;pointer-events:none!important}@keyframes eab-reveal{to{opacity:1;pointer-events:auto}}.${FLICKER_CLASS}{animation:eab-reveal 0s ${timeout}ms forwards}';\n document.head.insertBefore(style, document.head.firstChild);\n document.body && document.body.classList.add('${FLICKER_CLASS}');\n})();\n`.trim();\n}\n","/**\n * Analytics utilities for parsing and extracting data from events\n */\n\nimport { UAParser } from \"ua-parser-js\";\n\n// URL source mappings\nconst urlSources: Record<string, string> = {\n \"facebook.com\": \"Facebook\",\n \"fb.me\": \"Facebook\",\n \"m.facebook.com\": \"Facebook\",\n \"l.facebook.com\": \"Facebook\",\n \"lm.facebook.com\": \"Facebook\",\n \"instagram.com\": \"Instagram\",\n \"l.instagram.com\": \"Instagram\",\n \"youtube.com\": \"Youtube\",\n \"youtu.be\": \"Youtube\",\n \"m.youtube.com\": \"Youtube\",\n \"bing.com\": \"Bing\",\n \"www.bing.com\": \"Bing\",\n \"msnbc.msn.com\": \"Bing\",\n \"dizionario.it.msn.com\": \"Bing\",\n \"cc.bingj.com\": \"Bing\",\n \"m.bing.com\": \"Bing\",\n \"twitter.com\": \"Twitter\",\n \"t.co\": \"Twitter\",\n};\n\n/**\n * Sanitize string values to prevent XSS\n */\nexport function sanitizeString(value: unknown): string {\n if (typeof value !== \"string\") return String(value);\n return value.replace(/[\\\\\"'`\\x00-\\x1F\\x7F]/g, \"\");\n}\n\n/**\n * Round number to 2 decimal places\n */\nexport function roundToTwo(value: unknown): number | null {\n if (value === null || value === undefined) {\n return null;\n }\n const num = typeof value === \"string\" ? parseFloat(value) : Number(value);\n\n if (isNaN(num)) {\n return null;\n }\n return Number(Math.round(Number(num + \"e2\")) + \"e-2\");\n}\n\n/**\n * Extract product ID from Shopify GID\n */\nexport function extractProductId(gid: string | undefined): string | null {\n if (!gid) return null;\n const regex = /gid:\\/\\/shopify\\/Product\\/(\\d+)/;\n const match = gid.match(regex);\n return match ? match[1] : null;\n}\n\n/**\n * Extract product variant ID from Shopify GID\n */\nexport function extractProductVariantId(\n gid: string | undefined\n): string | null {\n if (!gid) return null;\n const regex = /gid:\\/\\/shopify\\/ProductVariant\\/(\\d+)/;\n const match = gid.match(regex);\n return match ? match[1] : null;\n}\n\n/**\n * Extract cart token from Shopify GID\n */\nexport function extractCartToken(\n gid: string | undefined | null\n): string | null {\n if (!gid) return null;\n const regex = /gid:\\/\\/shopify\\/Cart\\/([^?]+(\\?.+)?)/;\n const match = gid.match(regex);\n return match ? match[1] : null;\n}\n\n/**\n * Clean cart token by removing query parameters\n */\nexport function cleanCartToken(\n cartToken: string | null | undefined\n): string | null {\n try {\n if (typeof cartToken !== \"string\") {\n return null;\n }\n const decodedToken = decodeURIComponent(cartToken);\n const tokenPart = decodedToken.split(\"?\")[0];\n return tokenPart;\n } catch {\n // Silently fail - cart token extraction is not critical\n return cartToken || null;\n }\n}\n\n/**\n * Check if Facebook in-app browser\n */\nexport function checkFacebookBrowser(userAgent: string): boolean {\n const facebookBrowserRegex =\n /((?:fban\\/fbios|fb_iab\\/fb4a)(?!.+fbav)|;fbav\\/([\\w\\.]+);)/i;\n return facebookBrowserRegex.test(userAgent);\n}\n\n/**\n * Check if Instagram in-app browser\n */\nexport function checkInstagramBrowser(userAgent: string): boolean {\n const instagramBrowserRegex = /(instagram)[\\/ ]([-\\w\\.]+)/i;\n return instagramBrowserRegex.test(userAgent);\n}\n\n/**\n * Check if Facebook or Instagram browser\n */\nexport function checkFacebookInstagramBrowser(userAgent: string): boolean {\n return checkFacebookBrowser(userAgent) || checkInstagramBrowser(userAgent);\n}\n\n/**\n * Get browser name from UA parser result\n */\nfunction getBrowserName(browser: string | undefined): string {\n if (!browser) {\n return \"\";\n }\n switch (browser) {\n case \"Mobile Safari\":\n return \"Safari\";\n case \"Chrome Mobile\":\n case \"Chrome Mobile iOS\":\n return \"Chrome\";\n case \"Firefox Mobile\":\n case \"Firefox Mobile iOS\":\n return \"Firefox\";\n case \"Opera Mobile\":\n case \"Opera Mini\":\n case \"Opera Mini iOS\":\n return \"Opera\";\n case \"Yandex Browser Lite\":\n return \"Yandex Browser\";\n case \"Chrome Webview\":\n case \"Mobile App\":\n return \"Mobile App\";\n default:\n return browser;\n }\n}\n\n/**\n * Extract query parameters from URL\n */\nfunction getQueryParams(parsedUrl: URL): Record<string, string> {\n const queryParams: Record<string, string> = {};\n\n parsedUrl.searchParams.forEach((value, key) => {\n if (!queryParams[key]) {\n queryParams[key] = value;\n }\n });\n\n return queryParams;\n}\n\n/**\n * Check if referrer URI is valid\n */\nfunction isValidReferrerURI(uri: URL): boolean {\n return !!uri.host && [\"http:\", \"https:\"].includes(uri.protocol);\n}\n\n/**\n * Extract referrer source from hostname\n */\nfunction extractReferrerSource(host: string): string {\n return host.replace(/^www\\./, \"\");\n}\n\n/**\n * Parse referrer to determine traffic source\n */\nfunction parseReferrer(\n referrer: string | undefined,\n browser: string,\n siteHostname: string | undefined\n): string {\n const browserObj: Record<string, string> = {\n Facebook: \"Facebook\",\n Instagram: \"Instagram\",\n };\n if (browser && browserObj[browser]) {\n return browser;\n }\n\n let referrerObj: URL | undefined;\n let host: string | undefined;\n try {\n if (referrer && referrer.trim() !== '') {\n referrerObj = new URL(referrer);\n } else {\n return \"Direct\";\n }\n if (referrerObj?.hostname && isValidReferrerURI(referrerObj)) {\n host = referrerObj.hostname;\n if (siteHostname && siteHostname === host) {\n return \"Direct\";\n }\n } else {\n return \"\";\n }\n } catch {\n // Silently handle invalid referrer URLs\n }\n if (!host) {\n return \"\";\n }\n const source = extractReferrerSource(host);\n if (!source) {\n return \"\";\n }\n if (urlSources[source]) {\n return urlSources[source];\n }\n if (source?.includes(\"google\")) {\n return \"Google\";\n }\n return source;\n}\n\n/**\n * Parse and extract analytics view data from referrer, entry page, and user agent\n */\nexport interface ParsedViewData {\n referrer_source: string;\n browser_info: string;\n os_info: string;\n device_type: string;\n page_entry_path: string;\n utm_medium: string;\n utm_source: string;\n utm_campaign: string;\n utm_content: string;\n utm_term: string;\n referrer_url: string;\n gclid: string;\n fbclid: string;\n pins_campaign_id: string;\n epik: string;\n}\n\nexport function parseAddViewData(params: {\n referrer?: string;\n entryPage?: string;\n userAgent?: string;\n}): ParsedViewData {\n const { referrer, entryPage, userAgent } = params;\n\n const data: ParsedViewData = {\n referrer_source: \"\",\n browser_info: \"\",\n os_info: \"\",\n device_type: \"\",\n page_entry_path: \"\",\n utm_medium: \"\",\n utm_source: \"\",\n utm_campaign: \"\",\n utm_content: \"\",\n utm_term: \"\",\n referrer_url: referrer || \"\",\n gclid: \"\",\n fbclid: \"\",\n pins_campaign_id: \"\",\n epik: \"\",\n };\n\n try {\n let siteHostname: string | undefined;\n if (entryPage && entryPage.trim() !== '' && entryPage.startsWith('http')) {\n try {\n const entryObj = new URL(entryPage);\n const entryPath = entryObj?.pathname;\n siteHostname = entryObj?.hostname;\n if (entryPath) {\n data.page_entry_path = entryPath ?? \"\";\n }\n const entryQueryParams = getQueryParams(entryObj);\n data.utm_medium = entryQueryParams[\"utm_medium\"] ?? \"\";\n data.utm_source = entryQueryParams[\"utm_source\"] ?? \"\";\n data.utm_campaign = entryQueryParams[\"utm_campaign\"] ?? \"\";\n data.utm_content = entryQueryParams[\"utm_content\"] ?? \"\";\n data.utm_term = entryQueryParams[\"utm_term\"] ?? \"\";\n data.gclid = entryQueryParams[\"gclid\"] ?? \"\";\n data.fbclid = entryQueryParams[\"fbclid\"] ?? \"\";\n data.pins_campaign_id = entryQueryParams[\"pins_campaign_id\"] ?? \"\";\n data.epik = entryQueryParams[\"epik\"] ?? \"\";\n } catch {\n // Silently handle invalid URLs - entry page might be invalid in some contexts\n }\n }\n\n if (userAgent) {\n const userAgentObj = UAParser(userAgent);\n const browser = userAgentObj?.browser?.name;\n const browserName = getBrowserName(browser);\n data.browser_info = browserName ?? \"\";\n data.os_info = userAgentObj?.os?.name ?? \"\";\n if (userAgent) {\n data.device_type =\n (userAgentObj?.device?.type || \"desktop\")?.toUpperCase() ?? \"\";\n }\n }\n\n data.referrer_source =\n parseReferrer(referrer, data?.browser_info, siteHostname) ?? \"\";\n return data;\n } catch {\n // Return partial data on parse error\n return data;\n }\n}\n\n/**\n * Get page type from pathname\n */\nexport function getPageTypeFromPathname(\n path: string,\n hasLocalizedPaths?: boolean\n): string {\n const hasNormalPath = path === \"/\" || path === \"\";\n\n // Check if this is a localized homepage (e.g., /en-us/, /fr-ca/)\n const localizedHomepagePattern = /^\\/[a-z]{2}(-[a-z]{2})?\\/?$/i;\n const isLocalizedHomepage =\n hasLocalizedPaths && localizedHomepagePattern.test(path);\n\n if (hasNormalPath || isLocalizedHomepage) {\n return \"index\";\n }\n\n if (/\\/products\\//.test(path)) {\n return \"product\";\n }\n\n if (/\\/collections\\//.test(path)) {\n return \"collection\";\n }\n\n if (/\\/pages\\//.test(path)) {\n return \"page\";\n }\n if (/\\/search/.test(path)) {\n return \"search\";\n }\n\n if (/\\/cart/.test(path)) {\n return \"cart\";\n }\n\n if (/\\/checkouts\\//.test(path)) {\n return \"checkout\";\n }\n\n return \"unknown\";\n}\n\n/**\n * Check if visitor ID is in URL params\n */\nexport function checkVisitorIdParams(searchParams: string): string | false {\n try {\n if (!searchParams) return false;\n const params = new URLSearchParams(searchParams);\n return params.get(\"eabUserId\") || false;\n } catch {\n // URL parsing failed, return false\n return false;\n }\n}\n\n/**\n * Get user agent string without browser info\n * Used for more consistent user fingerprinting\n */\nexport function getUserAgentNoBrowser(userAgent: string): string {\n if (!userAgent) return \"\";\n\n try {\n const userAgentObj = UAParser(userAgent);\n const os = userAgentObj?.os;\n const device = userAgentObj?.device;\n\n let result = \"\";\n if (os?.name) {\n result += os.name;\n if (os.version) result += ` ${os.version}`;\n }\n if (device?.type) {\n result += result ? ` (${device.type})` : device.type;\n }\n if (device?.vendor) {\n result += result ? ` ${device.vendor}` : device.vendor;\n }\n if (device?.model) {\n result += result ? ` ${device.model}` : device.model;\n }\n\n return result || userAgent;\n } catch {\n return userAgent;\n }\n}\n","/**\n * Shopify-specific utilities\n */\n\n/**\n * Extract numeric ID from a Shopify Global ID (GID).\n *\n * Shopify uses GIDs like \"gid://shopify/Product/123456789\" or \"gid://shopify/ProductVariant/987654321\".\n * This utility extracts the numeric ID portion.\n *\n * @param gid - Shopify Global ID or numeric ID string\n * @returns The numeric ID portion (e.g., \"123456789\")\n *\n * @example\n * ```ts\n * extractShopifyId(\"gid://shopify/Product/123456789\"); // \"123456789\"\n * extractShopifyId(\"gid://shopify/ProductVariant/987654321\"); // \"987654321\"\n * extractShopifyId(\"gid://shopify/Cart/abc123\"); // \"abc123\"\n * extractShopifyId(\"123456789\"); // \"123456789\" (already numeric)\n * ```\n */\nexport function extractShopifyId(gid: string | null | undefined): string {\n if (!gid) return \"\";\n\n // If it's a GID, extract the last segment\n if (gid.includes(\"gid://\")) {\n return gid.split(\"/\").pop() || gid;\n }\n\n // Already a plain ID\n return gid;\n}\n\n/**\n * Extract the resource type from a Shopify Global ID.\n *\n * @param gid - Shopify Global ID\n * @returns The resource type (e.g., \"Product\", \"ProductVariant\", \"Cart\")\n *\n * @example\n * ```ts\n * extractShopifyType(\"gid://shopify/Product/123\"); // \"Product\"\n * extractShopifyType(\"gid://shopify/ProductVariant/456\"); // \"ProductVariant\"\n * extractShopifyType(\"123456789\"); // null (not a GID)\n * ```\n */\nexport function extractShopifyType(\n gid: string | null | undefined,\n): string | null {\n if (!gid || !gid.includes(\"gid://\")) return null;\n\n const parts = gid.split(\"/\");\n // gid://shopify/Product/123 -> parts = [\"gid:\", \"\", \"shopify\", \"Product\", \"123\"]\n return parts[3] || null;\n}\n\n/**\n * Check if a string is a Shopify Global ID.\n *\n * @param value - String to check\n * @returns True if it's a GID\n *\n * @example\n * ```ts\n * isShopifyGid(\"gid://shopify/Product/123\"); // true\n * isShopifyGid(\"123456789\"); // false\n * ```\n */\nexport function isShopifyGid(value: string | null | undefined): boolean {\n return !!value && value.startsWith(\"gid://shopify/\");\n}\n\n/**\n * Try to detect the shop currency from Shopify's global object.\n * Only works on Shopify theme stores, not headless.\n *\n * @returns Currency code (e.g., \"USD\") or undefined\n */\nexport function detectShopifyCurrency(): string | undefined {\n if (typeof window === \"undefined\") return undefined;\n\n // Try Shopify's global currency object (theme stores only)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const shopify = (window as any).Shopify;\n if (shopify?.currency?.active) {\n return shopify.currency.active;\n }\n\n return undefined;\n}\n","/**\n * Manual tracking functions for non-Hydrogen frameworks (Next.js, etc.)\n *\n * Initialize once with initAnalytics(), then call tracking functions without params:\n *\n * @example\n * ```tsx\n * // In your layout/provider (once)\n * initAnalytics({\n * storeId: 'your-store.myshopify.com',\n * storefrontAccessToken: 'your-token',\n * });\n *\n * // Then anywhere in your app (no params needed)\n * trackPageView();\n * trackAddToCart({ cartId, productId, ... });\n * ```\n */\n\nimport type {\n EventPayload,\n TestAssignment,\n TrackPageViewParams,\n TrackProductViewParams,\n TrackAddToCartParams,\n TrackRemoveFromCartParams,\n TrackCartViewParams,\n TrackSearchSubmittedParams,\n TrackCheckoutStartedParams,\n TrackCheckoutCompletedParams,\n} from \"../types\";\n\nimport { extractShopifyId } from \"./shopify\";\n\n// Re-import types for cleaner syntax below\nimport type { UsePageViewTrackingParams } from \"../types\";\nimport {\n parseAddViewData,\n extractCartToken,\n cleanCartToken,\n getPageTypeFromPathname,\n sanitizeString,\n roundToTwo,\n getUserAgentNoBrowser,\n} from \"./analytics\";\nimport {\n getVisitorId,\n getSessionId,\n getCookie,\n getJsonCookie,\n getReferrerData,\n uuidv4,\n} from \"./storage\";\n\nconst DEFAULT_WORKER_URL = \"https://bitter-river-9c62.support-67d.workers.dev\";\nconst DEFAULT_ORDERS_WORKER_URL =\n \"https://d339co84ntxcme.cloudfront.net/Prod/orders\";\n\n// ============================================================================\n// GLOBAL ANALYTICS CONFIG (initialized once, used by all tracking functions)\n// ============================================================================\n\ninterface AnalyticsConfig {\n storeId: string;\n storefrontAccessToken?: string;\n hasLocalizedPaths?: boolean;\n workerUrl?: string;\n ordersWorkerUrl?: string;\n}\n\nlet globalConfig: AnalyticsConfig | null = null;\n\n/**\n * Initialize analytics config once. Call this in your app's entry point or layout.\n * After init, tracking functions don't need storeId/token params.\n *\n * @example\n * ```tsx\n * // In _app.tsx or layout.tsx\n * initAnalytics({\n * storeId: 'your-store.myshopify.com',\n * storefrontAccessToken: process.env.NEXT_PUBLIC_STOREFRONT_TOKEN,\n * });\n * ```\n */\nexport function initAnalytics(config: AnalyticsConfig): void {\n globalConfig = config;\n}\n\n/**\n * Get the current analytics config (for internal use)\n */\nexport function getAnalyticsConfig(): AnalyticsConfig | null {\n return globalConfig;\n}\n\n/**\n * Check if analytics is initialized\n */\nexport function isAnalyticsInitialized(): boolean {\n return globalConfig !== null;\n}\n\n// Helper to get storeId from params or global config\nfunction getStoreId(params?: { storeId?: string }): string {\n const storeId = params?.storeId || globalConfig?.storeId;\n if (!storeId) {\n console.warn(\n \"[ElevateAB] No storeId provided. Call initAnalytics() first or pass storeId to tracking function.\",\n );\n return \"\";\n }\n return storeId;\n}\n\n// Transform test list format to event format\nfunction transformTestFormat(\n testObject: Record<string, string>,\n): TestAssignment[] {\n return Object.entries(testObject)\n .filter(([, variationId]) => typeof variationId === \"string\")\n .map(([testId, variationId]) => ({\n test_id: testId,\n variant_id: variationId,\n }));\n}\n\n// Transform viewed tests format\nfunction transformViewedTests(\n viewedObject: Record<string, boolean>,\n assignmentObject: Record<string, string>,\n): TestAssignment[] {\n return Object.entries(viewedObject)\n .filter(([testId]) => typeof assignmentObject[testId] === \"string\")\n .map(([testId]) => ({\n test_id: testId,\n variant_id: assignmentObject[testId],\n }));\n}\n\n// Check if we're in preview mode (should skip analytics)\nfunction isInPreviewMode(): boolean {\n if (typeof window === \"undefined\") return false;\n\n // Check cookie\n if (getCookie(\"eabUserPreview\") === \"true\") return true;\n\n // Check URL param\n const urlParams = new URLSearchParams(window.location.search);\n if (urlParams.get(\"eabUserPreview\") === \"true\") return true;\n\n return false;\n}\n\n// Create base event data (returns null if in preview mode)\nfunction createBaseEventData(\n storeId: string,\n eventType: string,\n hasLocalizedPaths?: boolean,\n): Partial<EventPayload> | null {\n if (typeof window === \"undefined\") return null;\n\n // Skip tracking in preview mode to avoid polluting analytics\n if (isInPreviewMode()) {\n return null;\n }\n\n const userAgent = navigator.userAgent;\n const pathname = window.location.pathname;\n const pageType = getPageTypeFromPathname(pathname, hasLocalizedPaths);\n\n const { referrer, entryPage } = getReferrerData();\n\n const parsedData = parseAddViewData({\n referrer,\n entryPage,\n userAgent,\n });\n\n const abtlObject = getJsonCookie<Record<string, string>>(\"ABTL\") || {};\n const abauObject = getJsonCookie<Record<string, boolean>>(\"ABAU\") || {};\n\n const testAssignments = transformTestFormat(abtlObject);\n const viewedTests = transformViewedTests(abauObject, abtlObject);\n\n const cartToken = extractCartToken(localStorage.getItem(\"shopifyCartId\"));\n const currentTimestamp = new Date().toISOString();\n\n // Get additional state\n const isFirstVisit = sessionStorage.getItem(\"eabIsFirstVisit\") === \"true\";\n const shopifyCountry = getCookie(\"localization\") || \"\";\n\n return {\n pixel_event_id: `sh-${uuidv4()}`,\n shop_name: storeId,\n timestamp: currentTimestamp,\n event_type: eventType,\n client_id: getCookie(\"_shopify_y\") || undefined,\n visitor_id: getVisitorId(),\n session_id: getSessionId(),\n cart_token: cleanCartToken(cartToken || getCookie(\"cart\")),\n\n page_url: window.location.href,\n page_pathname: pathname,\n page_search: window.location.search,\n referrer_url: referrer,\n referrer_source: parsedData?.referrer_source,\n previous_page: document.referrer,\n page_entry: entryPage,\n page_entry_path: parsedData?.page_entry_path,\n page_type: pageType,\n\n utm_medium: parsedData?.utm_medium,\n utm_source: parsedData?.utm_source,\n utm_campaign: parsedData?.utm_campaign,\n utm_content: parsedData?.utm_content,\n utm_term: parsedData?.utm_term,\n\n gclid: parsedData?.gclid,\n fbclid: parsedData?.fbclid,\n pins_campaign_id: parsedData?.pins_campaign_id,\n epik: parsedData?.epik,\n\n browser_info: parsedData?.browser_info,\n os_info: parsedData?.os_info,\n device_type: parsedData?.device_type,\n language: navigator.language,\n root_route: localStorage.getItem(\"eabRootRoute\") || \"\",\n user_agent: userAgent,\n user_agent_no_browser: getUserAgentNoBrowser(userAgent),\n\n is_first_visit: isFirstVisit,\n shopify_country: shopifyCountry,\n\n ab_test_assignments: testAssignments,\n ab_test_views: viewedTests,\n is_first_order: null,\n };\n}\n\n// Send event to CloudFlare Worker\nasync function sendEvent(\n data: Partial<EventPayload>,\n workerUrl: string = DEFAULT_WORKER_URL,\n): Promise<void> {\n try {\n const response = await fetch(workerUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(data),\n keepalive: true,\n });\n\n if (!response.ok) {\n throw new Error(`Worker error: ${response.status}`);\n }\n } catch (error) {\n console.error(\"[ElevateAB] Error sending analytics:\", error);\n }\n}\n\n/**\n * Track page view event\n * Call this on route changes or in useEffect\n *\n * @example After initAnalytics()\n * ```ts\n * await trackPageView(); // No params needed!\n * ```\n *\n * @example Without init (pass params)\n * ```ts\n * await trackPageView({ storeId: \"mystore.myshopify.com\" });\n * ```\n */\nexport async function trackPageView(\n params: Partial<TrackPageViewParams> = {},\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n\n const baseData = createBaseEventData(\n storeId,\n \"page_viewed\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: params.currency,\n };\n\n await sendEvent(eventData, workerUrl);\n}\n\n/**\n * Track product view event\n * Call this on product pages\n *\n * @example After initAnalytics()\n * ```ts\n * await trackProductView({ productId: \"123\", productPrice: 99.99 });\n * ```\n */\nexport async function trackProductView(\n params: Omit<TrackProductViewParams, \"storeId\"> & { storeId?: string },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const { productId, productVendor, productPrice, productSku, currency } =\n params;\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n\n const baseData = createBaseEventData(\n storeId,\n \"product_viewed\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n product_id: extractShopifyId(productId),\n product_vendor: sanitizeString(productVendor),\n product_price: roundToTwo(productPrice),\n product_sku: sanitizeString(productSku),\n };\n\n await sendEvent(eventData, workerUrl);\n}\n\n/**\n * Track add to cart event\n * Call this when user clicks \"Add to Cart\"\n *\n * Cart attributes are automatically updated for order attribution if\n * storefrontAccessToken was provided to initAnalytics() or passed here.\n *\n * @example After initAnalytics()\n * ```ts\n * await trackAddToCart({\n * cartId: \"gid://shopify/Cart/abc123\",\n * productId: \"123456789\",\n * variantId: \"987654321\",\n * productPrice: 99.99,\n * productQuantity: 1,\n * });\n * ```\n */\nexport async function trackAddToCart(\n params: Omit<TrackAddToCartParams, \"storeId\" | \"storefrontAccessToken\"> & {\n storeId?: string;\n storefrontAccessToken?: string;\n },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const {\n productId,\n variantId,\n productVendor,\n productPrice,\n productQuantity,\n productSku,\n currency,\n cartId,\n } = params;\n\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n const storefrontAccessToken =\n params.storefrontAccessToken ?? globalConfig?.storefrontAccessToken;\n\n const baseData = createBaseEventData(\n storeId,\n \"product_added_to_cart\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n product_id: extractShopifyId(productId),\n variant_id: extractShopifyId(variantId),\n product_vendor: sanitizeString(productVendor),\n product_price: roundToTwo(productPrice),\n product_quantity: productQuantity,\n product_sku: sanitizeString(productSku),\n };\n\n await sendEvent(eventData, workerUrl);\n\n // Auto-update cart attributes if cartId and token are available\n if (cartId && storefrontAccessToken) {\n try {\n const { updateCartAttributes } = await import(\"./cartAttributes\");\n await updateCartAttributes(cartId, { storefrontAccessToken });\n } catch (err) {\n console.error(\"[ElevateAB] Failed to update cart attributes:\", err);\n }\n }\n}\n\n/**\n * Track remove from cart event\n * Call this when user removes item from cart\n */\nexport async function trackRemoveFromCart(\n params: Omit<TrackRemoveFromCartParams, \"storeId\"> & { storeId?: string },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const {\n productId,\n variantId,\n productVendor,\n productPrice,\n productQuantity,\n productSku,\n currency,\n } = params;\n\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n\n const baseData = createBaseEventData(\n storeId,\n \"product_removed_from_cart\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n product_id: extractShopifyId(productId),\n variant_id: extractShopifyId(variantId),\n product_vendor: sanitizeString(productVendor),\n product_price: roundToTwo(productPrice),\n product_quantity: productQuantity,\n product_sku: sanitizeString(productSku),\n };\n\n await sendEvent(eventData, workerUrl);\n}\n\n/**\n * Track cart view event\n * Call this when user views cart page\n */\nexport async function trackCartView(\n params: Omit<TrackCartViewParams, \"storeId\"> & { storeId?: string },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const { cartTotalPrice, cartTotalQuantity, cartItems, currency } = params;\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n\n const baseData = createBaseEventData(\n storeId,\n \"cart_viewed\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n cart_total_price: roundToTwo(cartTotalPrice),\n cart_total_quantity: cartTotalQuantity,\n cart_items: cartItems?.map((item) => ({\n product_id: extractShopifyId(item.productId),\n variant_id: extractShopifyId(item.variantId),\n product_vendor: sanitizeString(item.productVendor) || \"\",\n product_price: roundToTwo(item.productPrice),\n product_quantity: item.productQuantity ?? null,\n product_sku: sanitizeString(item.productSku) || \"\",\n })),\n };\n\n await sendEvent(eventData, workerUrl);\n}\n\n/**\n * Track search submitted event\n * Call this when user submits a search\n *\n * @example After initAnalytics()\n * ```ts\n * await trackSearchSubmitted({ searchQuery: \"running shoes\" });\n * ```\n *\n * @example Without init (pass params)\n * ```ts\n * await trackSearchSubmitted({\n * storeId: \"mystore.myshopify.com\",\n * searchQuery: \"running shoes\",\n * currency: \"USD\"\n * });\n * ```\n */\nexport async function trackSearchSubmitted(\n params: Omit<TrackSearchSubmittedParams, \"storeId\"> & { storeId?: string },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const { searchQuery, currency } = params;\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n\n const baseData = createBaseEventData(\n storeId,\n \"search_submitted\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n search_query: sanitizeString(searchQuery),\n };\n\n await sendEvent(eventData, workerUrl);\n}\n\n/**\n * Track checkout started event\n * Call this when user starts checkout\n *\n * @example After initAnalytics()\n * ```ts\n * await trackCheckoutStarted({\n * cartTotalPrice: 109.98,\n * cartItems: [...],\n * });\n * ```\n */\nexport async function trackCheckoutStarted(\n params: Omit<TrackCheckoutStartedParams, \"storeId\"> & { storeId?: string },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const {\n cartTotalPrice,\n cartSubtotalPrice,\n cartShippingPrice,\n cartTaxAmount,\n cartDiscountAmount,\n customerId,\n cartItems,\n currency,\n } = params;\n\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const workerUrl = params.workerUrl ?? globalConfig?.workerUrl;\n\n const baseData = createBaseEventData(\n storeId,\n \"checkout_started\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n let totalQuantity = 0;\n const items =\n cartItems?.map((item) => {\n const quantity = item.productQuantity ?? 0;\n totalQuantity += quantity;\n return {\n product_id: extractShopifyId(item.productId),\n variant_id: extractShopifyId(item.variantId),\n product_vendor: sanitizeString(item.productVendor) || \"\",\n vendor: sanitizeString(item.productVendor) || \"\",\n product_price: roundToTwo(item.productPrice),\n total_price: roundToTwo(item.productPrice),\n product_quantity: quantity,\n quantity: quantity,\n product_sku: sanitizeString(item.productSku) || \"\",\n sku: sanitizeString(item.productSku) || \"\",\n total_discount: roundToTwo(item.totalDiscount),\n };\n }) || [];\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n cart_total_price: roundToTwo(cartTotalPrice),\n cart_subtotal_price: roundToTwo(cartSubtotalPrice),\n cart_total_quantity: totalQuantity,\n cart_shipping_price: roundToTwo(cartShippingPrice),\n cart_tax_amount: roundToTwo(cartTaxAmount),\n cart_discount_amount: roundToTwo(cartDiscountAmount),\n cart_items: items,\n customer_id: customerId,\n };\n\n await sendEvent(eventData, workerUrl);\n}\n\n/**\n * Track checkout completed event (order placed)\n * Call this when order is placed\n *\n * NOTE: This sends to a different endpoint (orders worker)\n *\n * @example After initAnalytics()\n * ```ts\n * await trackCheckoutCompleted({\n * orderId: \"order_123456\",\n * cartTotalPrice: 109.98,\n * cartItems: [...],\n * });\n * ```\n */\nexport async function trackCheckoutCompleted(\n params: Omit<TrackCheckoutCompletedParams, \"storeId\"> & { storeId?: string },\n): Promise<void> {\n const storeId = getStoreId(params);\n if (!storeId) return;\n\n const {\n orderId,\n cartTotalPrice,\n cartSubtotalPrice,\n cartShippingPrice,\n cartTaxAmount,\n cartDiscountAmount,\n customerId,\n isFirstOrder,\n noteAttributes,\n cartItems,\n currency,\n } = params;\n\n const hasLocalizedPaths =\n params.hasLocalizedPaths ?? globalConfig?.hasLocalizedPaths;\n const ordersWorkerUrl =\n params.ordersWorkerUrl ??\n globalConfig?.ordersWorkerUrl ??\n DEFAULT_ORDERS_WORKER_URL;\n\n const baseData = createBaseEventData(\n storeId,\n \"checkout_completed\",\n hasLocalizedPaths,\n );\n if (!baseData) return; // Skip in preview mode\n\n let totalQuantity = 0;\n const items =\n cartItems?.map((item) => {\n const quantity = item.productQuantity ?? 0;\n totalQuantity += quantity;\n return {\n product_id: extractShopifyId(item.productId),\n variant_id: extractShopifyId(item.variantId),\n product_vendor: sanitizeString(item.productVendor) || \"\",\n vendor: sanitizeString(item.productVendor) || \"\",\n product_price: roundToTwo(item.productPrice),\n total_price: roundToTwo(item.productPrice),\n product_quantity: quantity,\n quantity: quantity,\n product_sku: sanitizeString(item.productSku) || \"\",\n sku: sanitizeString(item.productSku) || \"\",\n total_discount: roundToTwo(item.totalDiscount),\n };\n }) || [];\n\n const eventData: Partial<EventPayload> = {\n ...baseData,\n cart_currency: currency,\n cart_total_price: roundToTwo(cartTotalPrice),\n cart_subtotal_price: roundToTwo(cartSubtotalPrice),\n cart_total_quantity: totalQuantity,\n cart_shipping_price: roundToTwo(cartShippingPrice),\n cart_tax_amount: roundToTwo(cartTaxAmount),\n cart_discount_amount: roundToTwo(cartDiscountAmount),\n cart_items: items,\n order_id: orderId,\n customer_id: customerId,\n is_first_order: isFirstOrder ?? null,\n note_attributes: noteAttributes,\n };\n\n // Send to orders worker (different endpoint!)\n await sendEvent(eventData, ordersWorkerUrl);\n}\n\nimport { useEffect, useRef, useState } from \"react\";\n\n/**\n * Hook for automatic page view tracking on route changes\n * Use in Next.js app router or any React app\n *\n * NOTE: For Next.js App Router, consider using this with `usePathname()`:\n * ```tsx\n * const pathname = usePathname();\n * usePageViewTracking({ pathname, enabled: true });\n * ```\n *\n * @example Basic usage (tracks on mount only)\n * ```tsx\n * function Layout({ children }) {\n * usePageViewTracking({ enabled: true });\n * return <>{children}</>;\n * }\n * ```\n *\n * @example With Next.js usePathname (tracks on route changes)\n * ```tsx\n * import { usePathname } from 'next/navigation';\n *\n * function Layout({ children }) {\n * const pathname = usePathname();\n * usePageViewTracking({ pathname, enabled: true });\n * return <>{children}</>;\n * }\n * ```\n */\nexport function usePageViewTracking(\n params: UsePageViewTrackingParams & { pathname?: string },\n): void {\n const {\n storeId,\n hasLocalizedPaths,\n currency,\n workerUrl,\n enabled = true,\n pathname: externalPathname,\n } = params;\n\n // Track the last pathname we've sent an event for\n const lastTrackedPathRef = useRef<string | null>(null);\n\n // Use external pathname if provided (e.g., from Next.js usePathname),\n // otherwise try to get it from window (works on mount)\n const [currentPath, setCurrentPath] = useState<string>(() => {\n if (externalPathname) return externalPathname;\n if (typeof window !== \"undefined\") return window.location.pathname;\n return \"\";\n });\n\n // Update currentPath when externalPathname changes\n useEffect(() => {\n if (externalPathname) {\n setCurrentPath(externalPathname);\n }\n }, [externalPathname]);\n\n // Track page view when path changes\n useEffect(() => {\n if (typeof window === \"undefined\" || !enabled) return;\n\n // Don't track if we've already tracked this path\n if (lastTrackedPathRef.current === currentPath) return;\n\n // Track the page view\n lastTrackedPathRef.current = currentPath;\n trackPageView({ storeId, hasLocalizedPaths, currency, workerUrl });\n }, [currentPath, storeId, hasLocalizedPaths, currency, workerUrl, enabled]);\n}\n","import React from \"react\";\nimport type { Variation } from \"../types\";\nimport { useElevateConfig } from \"../contexts/ElevateContext\";\nimport { getVisitorId } from \"../utils/storage\";\nimport { assignAndPersistVariant, shouldShowTest } from \"../utils/assignment\";\nimport { trackViews } from \"../utils/tracking\";\n\nexport interface UseExperimentResult {\n /** The full variant object (null if not assigned) */\n variant: Variation | null;\n /** True while loading config */\n isLoading: boolean;\n /** True if assigned to control group */\n isControl: boolean;\n /** True if assigned to variation A (first non-control) */\n isA: boolean;\n /** True if assigned to variation B (second non-control) */\n isB: boolean;\n /** True if assigned to variation C (third non-control) */\n isC: boolean;\n /** True if assigned to variation D (fourth non-control) */\n isD: boolean;\n}\n\n/**\n * Hook to get assigned variant for a test\n * \n * @example\n * ```tsx\n * const { isControl, isA, isB } = useExperiment('my-test');\n * \n * if (isControl) return <Original />;\n * if (isA) return <VariantA />;\n * if (isB) return <VariantB />;\n * ```\n */\nexport function useExperiment(testId: string): UseExperimentResult {\n const { config } = useElevateConfig();\n const [variant, setVariant] = React.useState<Variation | null>(null);\n const [isLoading, setIsLoading] = React.useState(true);\n\n const testConfig = React.useMemo(() => {\n if (!config) return null;\n return config.tests.find((test) => test.testId === testId) || null;\n }, [config, testId]);\n\n // Track if we've already warned about this test (prevent duplicate warnings)\n const hasWarnedRef = React.useRef<string | null>(null);\n\n React.useEffect(() => {\n // Wait for config to load before doing anything\n if (config === null) {\n return; // Still loading config\n }\n\n // Config loaded but test not found\n if (!testConfig) {\n if (hasWarnedRef.current !== testId) {\n hasWarnedRef.current = testId;\n console.warn(`[ElevateAB] Test not found: ${testId}`);\n }\n setIsLoading(false);\n return;\n }\n\n // Test exists but is disabled\n if (!testConfig.enabled) {\n if (hasWarnedRef.current !== `${testId}-disabled`) {\n hasWarnedRef.current = `${testId}-disabled`;\n console.warn(`[ElevateAB] Test disabled: ${testId}`);\n }\n setIsLoading(false);\n return;\n }\n\n // Check traffic percentage\n if (!shouldShowTest(testConfig)) {\n setIsLoading(false);\n return;\n }\n\n // Get or create visitor ID\n const userId = getVisitorId();\n\n // Assign variant (sets isControl, isA, isB, isC, isD)\n const assigned = assignAndPersistVariant(testId, testConfig, userId);\n\n if (assigned) {\n setVariant(assigned);\n trackViews(testId);\n }\n\n setIsLoading(false);\n }, [config, testConfig, testId]);\n\n return { \n variant, \n isLoading, \n isControl: variant?.isControl ?? false,\n isA: variant?.isA ?? false,\n isB: variant?.isB ?? false,\n isC: variant?.isC ?? false,\n isD: variant?.isD ?? false,\n };\n}\n","import React from \"react\";\nimport type { ElevateContextValue } from \"../types\";\n\nexport const ElevateContext = React.createContext<ElevateContextValue | null>(\n null\n);\n\n/**\n * Hook to access Elevate config from context\n */\nexport function useElevateConfig(): ElevateContextValue {\n const context = React.useContext(ElevateContext);\n\n if (context === null) {\n throw new Error(\"useElevateConfig must be used within ElevateProvider\");\n }\n\n return context;\n}\n","import React, { useRef, useCallback } from \"react\";\nimport type { ElevateConfig, BackendConfig } from \"../types\";\nimport { ElevateContext } from \"../contexts/ElevateContext\";\nimport { parseBackendConfig } from \"../utils\";\nimport { initAnalytics } from \"../utils/manualTracking\";\nimport { getPreviewState, type PreviewState } from \"../utils/preview\";\nimport { getCountryCode } from \"../utils/geo\";\nimport { setupFlickerPrevention } from \"../utils/antiFlicker\";\n\n/**\n * Set to false during local development to use fallback config.\n * In production, this should always be true.\n */\nconst USE_CDN_CONFIG = false; // Set to false for demo/development\n\n/**\n * Fallback config for local development/testing when CDN is not available.\n * Only used when USE_CDN_CONFIG = false.\n *\n * Supported test types: SPLIT_URL, PRICE_PLUS, CONTENT, CUSTOM_CODE\n */\nconst DEV_FALLBACK_CONFIG: BackendConfig = {\n allTests: {\n // Price Plus Test - Testing different price points\n \"price-test-001\": {\n \"8606\": {\n variationName: \"Control\",\n trafficPercentage: 50,\n isDone: false,\n isControl: true,\n },\n \"8607\": {\n variationName: \"Sale Price\",\n trafficPercentage: 50,\n isDone: false,\n prices: {\n \"41883969519701\": {\n main: \"USD\",\n price: { USD: \"599.95\" },\n compare: { USD: \"699.95\" },\n },\n },\n },\n data: {\n name: \"Snowboard Price Test\",\n isLive: true,\n settings: { afterDiscounts: true },\n type: \"PRICE_PLUS\",\n filters: [],\n isPersonalization: false,\n currencies: [\"USD\"],\n handles: [\"the-complete-snowboard\"],\n productIds: [\"7240161067093\"],\n },\n },\n\n // Content Test - Simple A/B/C headline test\n \"content-test-001\": {\n \"ctrl-001\": {\n variationName: \"Control\",\n trafficPercentage: 34,\n isDone: false,\n isControl: true,\n content: {\n headline: \"Welcome to our store\",\n subheadline: \"Shop the best products\",\n },\n },\n \"var-a-001\": {\n variationName: \"Urgency Copy\",\n trafficPercentage: 33,\n isDone: false,\n content: {\n headline: \"Limited Time Offer!\",\n subheadline: \"Don't miss out - sale ends soon\",\n },\n },\n \"var-b-001\": {\n variationName: \"Value Copy\",\n trafficPercentage: 33,\n isDone: false,\n content: {\n headline: \"Premium Quality, Great Value\",\n subheadline: \"Free shipping on orders over $50\",\n },\n },\n data: {\n name: \"Homepage Headline Test\",\n isLive: true,\n settings: { afterDiscounts: true },\n type: \"CONTENT\",\n filters: [],\n isPersonalization: false,\n pathnames: [\"/\"],\n },\n },\n\n // Custom Code Test - Injecting custom JS/CSS\n \"custom-code-test-001\": {\n \"10150\": {\n variationName: \"Control\",\n trafficPercentage: 50,\n isDone: false,\n customCode: {\n id: \"c11a582c-6b27-4263-941c-8ed123437c6b\",\n js: \"console.log('[Elevate] Control variant active');\",\n css: \"\",\n pathnames: [\"*\"],\n excludePathnames: [],\n },\n isControl: true,\n },\n \"10151\": {\n variationName: \"Enhanced UI\",\n trafficPercentage: 50,\n isDone: false,\n customCode: {\n id: \"df71546a-0a5f-4ad0-8d0f-a1bdeab05e84\",\n js: \"console.log('[Elevate] Enhanced UI variant'); document.body.style.borderTop = '3px solid #10b981';\",\n css: \".hero-section { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }\",\n pathnames: [\"*\"],\n excludePathnames: [],\n },\n },\n data: {\n name: \"Custom Code Enhancement\",\n isLive: true,\n settings: { afterDiscounts: true },\n type: \"CUSTOM_CODE\",\n filters: [],\n isPersonalization: false,\n pathnames: [\"*\"],\n excludePathnames: [],\n },\n },\n\n // Split URL Test - Redirect to different landing pages\n \"split-url-test-001\": {\n \"split-ctrl\": {\n variationName: \"Control\",\n trafficPercentage: 50,\n isDone: false,\n isControl: true,\n splitUrlTestLinks: {\n default: \"/collections/all\",\n },\n },\n \"split-var-a\": {\n variationName: \"New Landing Page\",\n trafficPercentage: 50,\n isDone: false,\n splitUrlTestLinks: {\n default: \"/collections/featured\",\n },\n },\n data: {\n name: \"Landing Page Split Test\",\n isLive: true,\n settings: { afterDiscounts: true },\n type: \"SPLIT_URL\",\n filters: [],\n isPersonalization: false,\n pathnames: [\"/promo\"],\n },\n },\n },\n selectors: { selectorsV2: [] },\n};\n\ninterface ElevateProviderSimpleProps {\n /** Shopify store domain (e.g., \"your-store.myshopify.com\") */\n storeId: string;\n /**\n * Storefront Access Token - Required for cart attribute tracking (order attribution)\n *\n * This 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 * Without this token, A/B tests work but orders won't be attributed to variants.\n */\n storefrontAccessToken?: string;\n /**\n * Enable flicker prevention - hides content until test assignment is complete\n * Prevents users from seeing content flash/change when variants load\n * @default false\n */\n preventFlickering?: boolean;\n /**\n * Timeout in milliseconds for flicker prevention failsafe\n * Content will show after this time even if assignment isn't complete\n * @default 3000\n */\n flickerTimeout?: number;\n children: React.ReactNode;\n}\n\n/**\n * ElevateProvider - Provides A/B test configuration to child components\n *\n * @example Next.js / Remix\n * ```tsx\n * <ElevateProvider\n * storeId=\"your-store.myshopify.com\"\n * storefrontAccessToken=\"your-public-token\"\n * >\n * <App />\n * </ElevateProvider>\n * ```\n *\n * @example Hydrogen (with Analytics.Provider)\n * ```tsx\n * <Analytics.Provider cart={cart} shop={shop} consent={consent}>\n * <ElevateProvider storeId=\"your-store.myshopify.com\" storefrontAccessToken=\"token\">\n * <ElevateAnalytics />\n * <App />\n * </ElevateProvider>\n * </Analytics.Provider>\n * ```\n */\nexport function ElevateProvider({\n storeId,\n storefrontAccessToken,\n preventFlickering = false,\n flickerTimeout = 3000,\n children,\n}: ElevateProviderSimpleProps) {\n const [config, setConfig] = React.useState<ElevateConfig | null>(null);\n const [previewState, setPreviewState] = React.useState<PreviewState | null>(\n null,\n );\n const [countryCode, setCountryCode] = React.useState<string | null>(null);\n const revealRef = useRef<(() => void) | null>(null);\n\n // Setup flicker prevention on mount (before config loads)\n React.useEffect(() => {\n if (preventFlickering && typeof window !== \"undefined\") {\n revealRef.current = setupFlickerPrevention(\"body\", flickerTimeout);\n }\n\n return () => {\n // Cleanup: ensure content is revealed on unmount\n if (revealRef.current) {\n revealRef.current();\n }\n };\n }, [preventFlickering, flickerTimeout]);\n\n // Initialize analytics config so tracking functions don't need storeId\n React.useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n initAnalytics({\n storeId,\n storefrontAccessToken,\n });\n }, [storeId, storefrontAccessToken]);\n\n // Initialize preview state and geo on mount\n React.useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n // Get preview state from URL/cookies\n const preview = getPreviewState();\n setPreviewState(preview);\n\n // Get country code\n const country = getCountryCode();\n setCountryCode(country);\n }, []);\n\n // Reveal callback - called when config is loaded or on error\n const revealContent = useCallback(() => {\n if (revealRef.current) {\n revealRef.current();\n revealRef.current = null;\n }\n }, []);\n\n React.useEffect(() => {\n async function fetchConfig() {\n try {\n // In dev mode, skip CDN fetch and use fallback config directly\n if (!USE_CDN_CONFIG) {\n const parsedConfig = parseBackendConfig(DEV_FALLBACK_CONFIG);\n setConfig(parsedConfig);\n revealContent();\n return;\n }\n\n // Production mode: fetch from CDN\n const url = `https://configs.elevateab.com/config/${storeId}.json`;\n const response = await fetch(url);\n\n if (response.status === 404) {\n // 404 means no config - could be new store or paused subscription\n // Just render children without A/B tests, no error log for this case\n setConfig({ tests: [], selectors: undefined });\n revealContent();\n return;\n }\n\n if (!response.ok) {\n throw new Error(\n `Failed to fetch config: ${response.status} ${response.statusText}`,\n );\n }\n\n const backendData: BackendConfig = await response.json();\n\n // Check if subscription is paused/stopped\n if (backendData.subscriptionPaused) {\n console.error(\n `[ElevateAB] Subscription is paused or stopped for store: ${storeId}. ` +\n (backendData.subscriptionMessage || \"A/B tests will not run. Please reactivate your subscription.\"),\n );\n // Graceful degradation - just render children, no A/B tests\n setConfig({ tests: [], selectors: undefined });\n revealContent();\n return;\n }\n\n // Check if config is empty (all tests might have been paused)\n const hasActiveTests = Object.keys(backendData.allTests || {}).length > 0;\n if (!hasActiveTests) {\n // Empty config - could be paused subscription or no active tests\n // Don't log error, just render children normally\n setConfig({ tests: [], selectors: undefined });\n revealContent();\n return;\n }\n\n const parsedConfig = parseBackendConfig(backendData);\n setConfig(parsedConfig);\n revealContent();\n } catch (err) {\n console.error(\"[ElevateAB] Failed to load config:\", err);\n // Graceful degradation - just render children, website doesn't break\n setConfig({ tests: [], selectors: undefined });\n revealContent();\n }\n }\n\n fetchConfig();\n }, [storeId, revealContent]);\n\n const value = React.useMemo(\n () => ({\n config,\n storeId,\n storefrontAccessToken,\n isPreviewMode: previewState?.isPreview ?? false,\n previewTestId: previewState?.previewTestId ?? null,\n countryCode,\n }),\n [config, storeId, storefrontAccessToken, previewState, countryCode],\n );\n\n // Initialize analytics so tracking functions don't need storeId/token each time\n React.useEffect(() => {\n initAnalytics({ storeId, storefrontAccessToken });\n }, [storeId, storefrontAccessToken]);\n\n // Warn once if storefrontAccessToken is missing (order attribution won't work)\n const hasWarnedRef = useRef(false);\n React.useEffect(() => {\n if (!storefrontAccessToken && !hasWarnedRef.current) {\n hasWarnedRef.current = true;\n console.warn(\n \"[ElevateAB] No storefrontAccessToken provided. \" +\n \"A/B tests will work, but orders won't be attributed to test variants. \" +\n \"Add storefrontAccessToken prop to enable order tracking.\",\n );\n }\n }, [storefrontAccessToken]);\n\n return (\n <ElevateContext.Provider value={value}>{children}</ElevateContext.Provider>\n );\n}\n","import React from \"react\";\nimport { getFlickerPreventionScript } from \"../utils/antiFlicker\";\n\nexport interface AntiFlickerScriptProps {\n /**\n * Maximum time (ms) to wait before showing content anyway (failsafe)\n * @default 3000\n */\n timeout?: number;\n}\n\n/**\n * Anti-flicker script component\n *\n * Renders a script tag that prevents content flash during A/B test loading.\n * Place this in your <head> element before any other scripts.\n *\n * @example Hydrogen (app/root.tsx)\n * ```tsx\n * import { AntiFlickerScript, ElevateProvider } from \"@elevateab/sdk\";\n *\n * export default function Root() {\n * return (\n * <html>\n * <head>\n * <AntiFlickerScript />\n * </head>\n * <body>\n * <ElevateProvider storeId=\"...\" preventFlickering={true}>\n * <Outlet />\n * </ElevateProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n *\n * @example Next.js (app/layout.tsx)\n * ```tsx\n * import { AntiFlickerScript } from \"@elevateab/sdk\";\n * import { ElevateNextProvider } from \"@elevateab/sdk/next\";\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <head>\n * <AntiFlickerScript />\n * </head>\n * <body>\n * <ElevateNextProvider storeId=\"...\" preventFlickering={true}>\n * {children}\n * </ElevateNextProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nexport function AntiFlickerScript({ timeout = 3000 }: AntiFlickerScriptProps) {\n return (\n <script\n dangerouslySetInnerHTML={{\n __html: getFlickerPreventionScript(timeout),\n }}\n />\n );\n}\n\nexport default AntiFlickerScript;\n","/**\n * ElevateAnalytics Component\n *\n * Internal component used by ElevateHydrogenAnalytics.\n * Subscribes to Hydrogen analytics events and sends them to Elevate.\n *\n * For Hydrogen stores, use ElevateHydrogenAnalytics instead - it's zero-config!\n * For Next.js/Remix, use manual tracking functions (trackPageView, trackAddToCart, etc.)\n */\n\nimport React, { useEffect, useContext, useRef } from \"react\";\nimport type { EventPayload, TestAssignment } from \"../types\";\nimport { ElevateContext } from \"../contexts/ElevateContext\";\n\n/**\n * Type for useAnalytics hook signature (matches @shopify/hydrogen)\n */\nexport type UseAnalyticsHook = () => {\n subscribe: (event: string, callback: (data: unknown) => void) => void;\n register: (name: string) => { ready: () => void };\n};\n\n/**\n * Props for ElevateHydrogenAnalytics (public API)\n */\nexport interface ElevateHydrogenAnalyticsProps {\n /** Override storeId from context (optional) */\n storeId?: string;\n /** Override storefrontAccessToken from context (optional) */\n storefrontAccessToken?: string;\n /** Enable localized path detection (e.g., /en-us/, /fr-ca/) */\n hasLocalizedPaths?: boolean;\n /** Custom CloudFlare Worker URL */\n workerUrl?: string;\n /** Custom orders worker URL */\n ordersWorkerUrl?: string;\n}\n\n/**\n * Internal props for ElevateAnalytics (requires useAnalytics hook)\n */\ninterface ElevateAnalyticsProps extends ElevateHydrogenAnalyticsProps {\n /** The useAnalytics hook from @shopify/hydrogen (required) */\n useAnalytics: UseAnalyticsHook;\n}\nimport {\n parseAddViewData,\n extractProductId,\n extractProductVariantId,\n extractCartToken,\n cleanCartToken,\n getPageTypeFromPathname,\n sanitizeString,\n roundToTwo,\n getUserAgentNoBrowser,\n} from \"../utils/analytics\";\nimport {\n getVisitorId,\n getSessionId,\n getCookie,\n getJsonCookie,\n setReferrerData,\n getReferrerData,\n} from \"../utils/storage\";\nimport { uuidv4 } from \"../utils/storage\";\nimport { updateCartAttributes } from \"../utils/cartAttributes\";\n\n// Default CloudFlare Worker endpoints\nconst DEFAULT_WORKER_URL = \"https://bitter-river-9c62.support-67d.workers.dev\";\nconst DEFAULT_ORDERS_WORKER_URL =\n \"https://d339co84ntxcme.cloudfront.net/Prod/orders\";\n\n// Generate pixel event ID\nfunction generatePixelEventId(): string {\n return `sh-${uuidv4()}`;\n}\n\n// Transform test list format to event format\nfunction transformTestFormat(\n testObject: Record<string, string>,\n): TestAssignment[] {\n return Object.entries(testObject)\n .filter(([, variationId]) => typeof variationId === \"string\")\n .map(([testId, variationId]) => ({\n test_id: testId,\n variant_id: variationId,\n }));\n}\n\n// Transform viewed tests format\nfunction transformViewedTests(\n viewedObject: Record<string, boolean>,\n assignmentObject: Record<string, string>,\n): TestAssignment[] {\n return Object.entries(viewedObject)\n .filter(([testId]) => typeof assignmentObject[testId] === \"string\")\n .map(([testId]) => ({\n test_id: testId,\n variant_id: assignmentObject[testId],\n }));\n}\n\n/**\n * ElevateAnalytics - Subscribes to Hydrogen analytics events\n *\n * @internal Used by ElevateHydrogenAnalytics. For Hydrogen stores, use ElevateHydrogenAnalytics instead!\n */\nexport function ElevateAnalytics({\n storeId: storeIdProp,\n storefrontAccessToken: tokenProp,\n hasLocalizedPaths,\n workerUrl = DEFAULT_WORKER_URL,\n ordersWorkerUrl = DEFAULT_ORDERS_WORKER_URL,\n useAnalytics,\n}: ElevateAnalyticsProps) {\n // Get values from context, allow props to override\n const context = useContext(ElevateContext);\n const storeId = storeIdProp || context?.storeId || \"\";\n const storefrontAccessToken = tokenProp || context?.storefrontAccessToken;\n\n // Track if we've warned about missing context (warn only once)\n const hasWarnedContextRef = useRef(false);\n\n // Warn once if not inside ElevateProvider\n useEffect(() => {\n if (!context && !storeIdProp && !hasWarnedContextRef.current) {\n hasWarnedContextRef.current = true;\n console.error(\n \"[ElevateAB] ElevateAnalytics must be used inside ElevateProvider, \" +\n \"or you must pass storeId as a prop.\",\n );\n }\n }, [context, storeIdProp]);\n const { subscribe, register } = useAnalytics();\n const { ready } = register(\"Elevate Analytics\");\n\n useEffect(() => {\n // Skip in non-browser environments\n if (typeof window === \"undefined\") return;\n\n // Initialize visitor ID and session ID\n getVisitorId();\n getSessionId();\n\n // Initialize referrer data if not already set\n if (typeof document !== \"undefined\") {\n const currentReferrer = document.referrer || \"\";\n const currentUrl = window.location.href;\n setReferrerData(currentReferrer, currentUrl);\n }\n\n const setupAnalytics = () => {\n // Initialize state\n const initializeState = (event: any) => {\n const productPageId = extractProductId(event.products?.[0]?.id);\n if (productPageId && typeof localStorage !== \"undefined\") {\n localStorage.setItem(\"eabProductPageId\", productPageId);\n } else if (\n typeof window !== \"undefined\" &&\n !window.location.pathname.includes(\"/products/\")\n ) {\n localStorage?.removeItem(\"eabProductPageId\");\n }\n\n const cartToken = extractCartToken(\n typeof localStorage !== \"undefined\"\n ? localStorage.getItem(\"shopifyCartId\")\n : null,\n );\n\n const { referrer, entryPage } = getReferrerData();\n\n return {\n visitorId: getVisitorId(),\n sessionId: getSessionId(),\n cartToken: cartToken || getCookie(\"cart\") || \"\",\n referrer,\n entryPage,\n clientId: getCookie(\"_shopify_y\"),\n rootRoute:\n typeof localStorage !== \"undefined\"\n ? localStorage.getItem(\"eabRootRoute\") || \"\"\n : \"\",\n productPageId:\n typeof localStorage !== \"undefined\"\n ? localStorage.getItem(\"eabProductPageId\") || \"\"\n : \"\",\n };\n };\n\n // Create base event data\n const createBaseEventData = (\n eventName: string,\n pixelEventId: string,\n event: any,\n state: any,\n ): EventPayload => {\n const userAgent =\n typeof navigator !== \"undefined\" ? navigator.userAgent : \"\";\n const pathname = event?.url\n ? new URL(event.url).pathname\n : typeof window !== \"undefined\"\n ? window.location.pathname\n : \"\";\n const pageType = getPageTypeFromPathname(pathname, hasLocalizedPaths);\n\n const parsedData = parseAddViewData({\n referrer: state.referrer,\n entryPage: state.entryPage,\n userAgent,\n });\n\n const abtlObject = getJsonCookie<Record<string, string>>(\"ABTL\") || {};\n const abauObject = getJsonCookie<Record<string, boolean>>(\"ABAU\") || {};\n\n const testAssignments = transformTestFormat(abtlObject);\n const viewedTests = transformViewedTests(abauObject, abtlObject);\n\n const currentTimestamp = new Date().toISOString();\n\n // Get additional state from cookies/storage\n const isFirstVisit =\n typeof sessionStorage !== \"undefined\"\n ? sessionStorage.getItem(\"eabIsFirstVisit\") === \"true\"\n : false;\n const shopifyCountry = getCookie(\"localization\") || \"\";\n\n return {\n pixel_event_id: pixelEventId,\n shop_name: storeId,\n timestamp: currentTimestamp,\n event_type: eventName,\n client_id: state.clientId,\n visitor_id: state.visitorId,\n session_id: state.sessionId,\n cart_token: cleanCartToken(state.cartToken),\n\n page_url:\n event.context?.document?.location?.href ||\n (typeof window !== \"undefined\" ? window.location.href : \"\"),\n page_pathname: pathname,\n page_search:\n event.context?.document?.location?.search ||\n (typeof window !== \"undefined\" ? window.location.search : \"\"),\n referrer_url: state.referrer,\n referrer_source: parsedData?.referrer_source,\n previous_page:\n typeof document !== \"undefined\" ? document.referrer : \"\",\n page_entry: state.entryPage,\n page_entry_path: parsedData?.page_entry_path,\n page_type: pageType,\n\n utm_medium: parsedData?.utm_medium,\n utm_source: parsedData?.utm_source,\n utm_campaign: parsedData?.utm_campaign,\n utm_content: parsedData?.utm_content,\n utm_term: parsedData?.utm_term,\n\n gclid: parsedData?.gclid,\n fbclid: parsedData?.fbclid,\n pins_campaign_id: parsedData?.pins_campaign_id,\n epik: parsedData?.epik,\n\n browser_info: parsedData?.browser_info,\n os_info: parsedData?.os_info,\n device_type: parsedData?.device_type,\n language:\n event.context?.navigator?.language ||\n (typeof navigator !== \"undefined\" ? navigator.language : \"\"),\n root_route: state.rootRoute,\n user_agent: userAgent,\n user_agent_no_browser: getUserAgentNoBrowser(userAgent),\n\n is_first_visit: isFirstVisit,\n shopify_country: shopifyCountry,\n\n cart_currency: event.shop?.currency,\n\n ab_test_assignments: testAssignments,\n ab_test_views: viewedTests,\n is_first_order: null,\n };\n };\n\n // Send event to CloudFlare Worker\n const sendEvent = async (data: EventPayload) => {\n if (data.exclude) return;\n\n try {\n const response = await fetch(workerUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(data),\n keepalive: true,\n });\n\n if (!response.ok) {\n throw new Error(`Worker error: ${response.status}`);\n }\n\n return response;\n } catch (error) {\n console.error(\"[ElevateAB] Error sending analytics:\", error);\n }\n };\n\n // Event handlers\n const handlePageViewed = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const eventData = createBaseEventData(\n \"page_viewed\",\n pixelEventId,\n event,\n state,\n );\n\n await sendEvent(eventData);\n } catch (error) {\n console.error(\"[ElevateAB] Error handling page_viewed:\", error);\n }\n };\n\n const handleProductViewed = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"product_viewed\",\n pixelEventId,\n event,\n state,\n );\n\n const eventData: EventPayload = {\n ...baseData,\n product_id: extractProductId(event?.products?.[0]?.id) || \"\",\n product_vendor: sanitizeString(event?.products?.[0]?.vendor) ?? \"\",\n product_price: roundToTwo(event?.products?.[0]?.price) ?? null,\n product_sku: sanitizeString(event?.products?.[0]?.sku) ?? \"\",\n };\n\n await sendEvent(eventData);\n } catch (error) {\n console.error(\"[ElevateAB] Error handling product_viewed:\", error);\n }\n };\n\n const handleProductAddedToCart = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"product_added_to_cart\",\n pixelEventId,\n event,\n state,\n );\n\n const eventData: EventPayload = {\n ...baseData,\n product_id:\n extractProductId(event?.currentLine?.merchandise?.product?.id) ??\n \"\",\n variant_id:\n extractProductVariantId(event?.currentLine?.merchandise?.id) ??\n \"\",\n product_vendor:\n sanitizeString(\n event?.currentLine?.merchandise?.product?.vendor,\n ) ?? \"\",\n product_price:\n roundToTwo(event?.currentLine?.cost?.totalAmount?.amount) ?? null,\n product_quantity: event?.currentLine?.quantity ?? null,\n product_sku:\n sanitizeString(event?.currentLine?.merchandise?.sku) ?? \"\",\n };\n\n await sendEvent(eventData);\n\n // Update cart attributes with A/B test data (for order attribution)\n const cartId = event?.cart?.id;\n if (cartId && storefrontAccessToken && storeId) {\n updateCartAttributes(cartId, {\n storefrontAccessToken,\n storefrontApiUrl: `https://${storeId}/api/2025-01/graphql.json`,\n }).catch((err) => {\n console.error(\n \"[ElevateAB] Failed to update cart attributes:\",\n err,\n );\n });\n }\n } catch (error) {\n console.error(\n \"[ElevateAB] Error handling product_added_to_cart:\",\n error,\n );\n }\n };\n\n const handleProductRemovedFromCart = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"product_removed_from_cart\",\n pixelEventId,\n event,\n state,\n );\n\n const eventData: EventPayload = {\n ...baseData,\n product_id:\n extractProductId(event?.prevLine?.merchandise?.product?.id) ?? \"\",\n variant_id:\n extractProductVariantId(event?.prevLine?.merchandise?.id) ?? \"\",\n product_vendor:\n sanitizeString(event?.prevLine?.merchandise?.product?.vendor) ??\n \"\",\n product_price:\n roundToTwo(event?.prevLine?.cost?.totalAmount?.amount) ?? null,\n product_quantity: event?.prevLine?.quantity ?? null,\n product_sku:\n sanitizeString(event?.prevLine?.merchandise?.sku) ?? \"\",\n };\n\n await sendEvent(eventData);\n } catch (error) {\n console.error(\n \"[ElevateAB] Error handling product_removed_from_cart:\",\n error,\n );\n }\n };\n\n const handleCartViewed = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"cart_viewed\",\n pixelEventId,\n event,\n state,\n );\n\n const lines =\n event?.data?.cart?.lines?.nodes || event?.data?.cart?.lines || [];\n const cartProducts = lines.map((item: any) => ({\n product_id: extractProductId(item?.merchandise?.product?.id) ?? \"\",\n variant_id: extractProductVariantId(item?.merchandise?.id) ?? \"\",\n vendor: sanitizeString(item?.merchandise?.product?.vendor) ?? \"\",\n total_price: roundToTwo(item?.cost?.totalAmount?.amount) ?? null,\n quantity: item?.quantity ?? null,\n sku: sanitizeString(item?.merchandise?.sku) ?? \"\",\n }));\n\n const eventData: EventPayload = {\n ...baseData,\n cart_total_price:\n roundToTwo(event?.cart?.cost?.totalAmount?.amount) ?? null,\n cart_total_quantity: event?.cart?.totalQuantity ?? null,\n cart_items: cartProducts,\n };\n\n await sendEvent(eventData);\n } catch (error) {\n console.error(\"[ElevateAB] Error handling cart_viewed:\", error);\n }\n };\n\n const handleSearchSubmitted = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"search_submitted\",\n pixelEventId,\n event,\n state,\n );\n\n const eventData: EventPayload = {\n ...baseData,\n search_query:\n sanitizeString(event?.data?.searchResult?.query) ?? \"\",\n };\n\n await sendEvent(eventData);\n } catch (error) {\n console.error(\"[ElevateAB] Error handling search_submitted:\", error);\n }\n };\n\n const handleCheckoutStarted = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"checkout_started\",\n pixelEventId,\n event,\n state,\n );\n\n let totalQuantity = 0;\n const lineItems = event?.data?.checkout?.lineItems ?? [];\n const checkoutProducts = lineItems.map((item: any) => {\n const quantity = item?.quantity ?? 0;\n totalQuantity += quantity;\n\n const discountAllocations = item?.discountAllocations ?? [];\n const total_discount = discountAllocations?.reduce(\n (acc: number, discount: any) =>\n acc + (discount?.amount?.amount || 0),\n 0,\n );\n\n return {\n product_id: extractProductId(item?.variant?.product?.id) ?? \"\",\n variant_id: extractProductVariantId(item?.variant?.id) ?? \"\",\n vendor: sanitizeString(item?.variant?.product?.vendor) ?? \"\",\n total_price: roundToTwo(item?.finalLinePrice?.amount) ?? null,\n quantity: quantity,\n sku: sanitizeString(item?.variant?.sku) ?? \"\",\n total_discount: roundToTwo(total_discount) ?? null,\n };\n });\n\n const eventData: EventPayload = {\n ...baseData,\n cart_total_price:\n roundToTwo(event?.data?.checkout?.totalPrice?.amount) ?? null,\n cart_subtotal_price:\n roundToTwo(event?.data?.checkout?.subtotalPrice?.amount) ?? null,\n cart_total_quantity: totalQuantity,\n cart_shipping_price:\n roundToTwo(event?.data?.checkout?.shippingLine?.price?.amount) ??\n null,\n cart_tax_amount:\n roundToTwo(event?.data?.checkout?.totalTax?.amount) ?? null,\n cart_discount_amount:\n roundToTwo(event?.data?.checkout?.discountsAmount?.amount) ??\n null,\n cart_items: checkoutProducts,\n customer_id: event?.data?.checkout?.order?.customer?.id ?? \"\",\n };\n\n await sendEvent(eventData);\n } catch (error) {\n console.error(\"[ElevateAB] Error handling checkout_started:\", error);\n }\n };\n\n const handleCheckoutCompleted = async (event: any) => {\n try {\n const state = initializeState(event);\n const pixelEventId = generatePixelEventId();\n const baseData = createBaseEventData(\n \"checkout_completed\",\n pixelEventId,\n event,\n state,\n );\n\n let totalQuantity = 0;\n const lineItems = event?.data?.checkout?.lineItems ?? [];\n const checkoutProducts = lineItems.map((item: any) => {\n const quantity = item?.quantity ?? 0;\n totalQuantity += quantity;\n\n const discountAllocations = item?.discountAllocations ?? [];\n const total_discount = discountAllocations?.reduce(\n (acc: number, discount: any) =>\n acc + (discount?.amount?.amount || 0),\n 0,\n );\n\n return {\n product_id: extractProductId(item?.variant?.product?.id) ?? \"\",\n variant_id: extractProductVariantId(item?.variant?.id) ?? \"\",\n vendor: sanitizeString(item?.variant?.product?.vendor) ?? \"\",\n total_price: roundToTwo(item?.finalLinePrice?.amount) ?? null,\n quantity: quantity,\n sku: sanitizeString(item?.variant?.sku) ?? \"\",\n total_discount: roundToTwo(total_discount) ?? null,\n };\n });\n\n const eventData: EventPayload = {\n ...baseData,\n cart_total_price:\n roundToTwo(event?.data?.checkout?.totalPrice?.amount) ?? null,\n cart_subtotal_price:\n roundToTwo(event?.data?.checkout?.subtotalPrice?.amount) ?? null,\n cart_total_quantity: totalQuantity,\n cart_shipping_price:\n roundToTwo(event?.data?.checkout?.shippingLine?.price?.amount) ??\n null,\n cart_tax_amount:\n roundToTwo(event?.data?.checkout?.totalTax?.amount) ?? null,\n cart_discount_amount:\n roundToTwo(event?.data?.checkout?.discountsAmount?.amount) ??\n null,\n cart_items: checkoutProducts,\n order_id: event?.data?.checkout?.order?.id ?? \"\",\n customer_id: event?.data?.checkout?.order?.customer?.id ?? \"\",\n is_first_order:\n event?.data?.checkout?.order?.customer?.isFirstOrder ?? null,\n note_attributes: event?.data?.checkout?.attributes ?? [],\n };\n\n // Send to orders worker (different endpoint)\n await sendOrderEvent(eventData);\n } catch (error) {\n console.error(\n \"[ElevateAB] Error handling checkout_completed:\",\n error,\n );\n }\n };\n\n // Send event to orders CloudFlare Worker (for checkout_completed)\n const sendOrderEvent = async (data: EventPayload) => {\n if (data.exclude) return;\n\n try {\n const response = await fetch(ordersWorkerUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(data),\n keepalive: true,\n });\n\n if (!response.ok) {\n throw new Error(`Orders worker error: ${response.status}`);\n }\n\n return response;\n } catch (error) {\n console.error(\"[ElevateAB] Error sending order analytics:\", error);\n }\n };\n\n // Subscribe to events\n subscribe(\"page_viewed\", handlePageViewed);\n subscribe(\"product_viewed\", handleProductViewed);\n subscribe(\"product_added_to_cart\", handleProductAddedToCart);\n subscribe(\"product_removed_from_cart\", handleProductRemovedFromCart);\n subscribe(\"cart_viewed\", handleCartViewed);\n subscribe(\"search_submitted\", handleSearchSubmitted);\n subscribe(\"checkout_started\", handleCheckoutStarted);\n subscribe(\"checkout_completed\", handleCheckoutCompleted);\n };\n\n setupAnalytics();\n ready();\n }, [\n subscribe,\n ready,\n storeId,\n hasLocalizedPaths,\n storefrontAccessToken,\n workerUrl,\n ordersWorkerUrl,\n ]);\n\n return null;\n}\n"],"mappings":"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","names":["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","init_utils","__esmMin","uuidv4","rnds","hexValues","b","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","init_storage","__esmMin","getTestList","getJsonCookie","saveTestList","testList","setCookie","getAssignedVariant","testId","getNonControlIndex","variations","targetIndex","nonControlIndex","assignVariantForUser","userId","allHaveTrafficPercentage","v","cumulativeWeights","totalWeight","variation","defaultWeight","i","randomWeight","hashString","assignedIndex","assignedVariation","assignAndPersistVariant","test","existingVariantId","variantIndex","existingVariant","activeVariations","isPersonalization","assignedVariant","shouldShowTest","testTrafficPercentage","init_assignment","__esmMin","init_storage","init_utils","require_ua_parser","__commonJSMin","exports","module","window","undefined","LIBVERSION","EMPTY","UNKNOWN","FUNC_TYPE","UNDEF_TYPE","OBJ_TYPE","STR_TYPE","MAJOR","MODEL","NAME","TYPE","VENDOR","VERSION","ARCHITECTURE","CONSOLE","MOBILE","TABLET","SMARTTV","WEARABLE","EMBEDDED","UA_MAX_LENGTH","AMAZON","APPLE","ASUS","BLACKBERRY","BROWSER","CHROME","EDGE","FIREFOX","GOOGLE","HONOR","HUAWEI","LENOVO","LG","MICROSOFT","MOTOROLA","NVIDIA","ONEPLUS","OPERA","OPPO","SAMSUNG","SHARP","SONY","XIAOMI","ZEBRA","FACEBOOK","CHROMIUM_OS","MAC_OS","SUFFIX_BROWSER","extend","regexes","extensions","mergedRegexes","i","enumerize","arr","enums","has","str1","str2","lowerize","str","majorize","version","trim","len","rgxMapper","ua","arrays","j","k","p","q","matches","match","regex","props","strMapper","map","oldSafariMap","windowsVersionMap","UAParser","_navigator","_ua","_uach","_rgxmap","_isSelfNav","_browser","_cpu","_device","_engine","_os","$","parser","result","prop","CART_ATTRIBUTES_UPDATE_MUTATION","init_cartAttributes_mutation","__esmMin","cartAttributes_exports","__export","cleanupCartAttributes","getCartAttributesPayload","updateCartAttributes","testList","getTestList","addedUniqueViews","getJsonCookie","eabUserId","getCookie","isPreviewMode","abtidValue","viewedTests","testId","attributes","cartId","options","cartGid","storefrontUrl","getStoreDomain","response","CART_ATTRIBUTES_UPDATE_MUTATION","result","errorMsg","error","init_cartAttributes","__esmMin","init_assignment","init_storage","init_cartAttributes_mutation","index_exports","__export","AntiFlickerScript","CART_ATTRIBUTES_UPDATE_MUTATION","COUNTRIES","DEFAULT_CONFIG","ElevateAnalytics","ElevateProvider","REGIONS","VERSION","assignAndPersistVariant","assignVariant","buildEabTestsParam","calculateRevenueLift","checkFacebookBrowser","checkFacebookInstagramBrowser","checkInstagramBrowser","checkPinterestBrowser","checkTikTokBrowser","checkVisitorIdParams","cleanCartToken","cleanupCartAttributes","cleanupFlickerPrevention","clearPreviewMode","deleteCookie","detectShopifyCurrency","extractCartToken","extractProductId","extractProductVariantId","extractShopifyId","extractShopifyType","generateExperimentId","getAssignedVariant","getCartAttributesPayload","getCookie","getCountryCode","getDeviceType","getFlickerPreventionScript","getGeoLocation","getJsonCookie","getJsonSessionItem","getPageTypeFromPathname","getPreviewState","getPreviewVariation","getReferrerData","getSessionId","getSessionItem","getTestList","getTrafficSource","getUserAgentNoBrowser","getVisitorId","hasSessionView","hasUniqueView","hashString","hideForFlicker","initAnalytics","initializeSessionId","initializeVisitorId","injectFlickerStyles","isCountryExcluded","isCountryIncluded","isFlickerPreventionActive","isInPreviewMode","isPreviewTest","isShopifyGid","matchesGeoTargeting","parseAddViewData","revealAfterFlicker","roundToTwo","sanitizeString","saveTestList","setCookie","setCountryCode","setGeoLocation","setReferrerData","setSessionItem","setupFlickerPrevention","shouldShowTest","trackAddToCart","trackCartView","trackCheckoutCompleted","trackCheckoutStarted","trackPageView","trackProductView","trackRemoveFromCart","trackSearchSubmitted","trackSessionView","trackUniqueView","trackViews","updateCartAttributes","updateUrlWithTestParams","useElevateConfig","useExperiment","usePageViewTracking","uuidv4","validateConfig","__toCommonJS","init_utils","init_storage","init_assignment","init_storage","trackUniqueView","testId","addedUniqueViews","getJsonCookie","setCookie","trackSessionView","addedViews","getJsonSessionItem","setSessionItem","trackViews","hasSessionView","hasUniqueView","getDeviceType","ua","lower","checkFacebookBrowser","userAgent","checkInstagramBrowser","checkTikTokBrowser","checkPinterestBrowser","getTrafficSource","referrer","referrerDomain","hostname","isFacebookBrowser","isInstagramBrowser","isTikTokBrowser","isPinterestBrowser","init_storage","parseEabTestsParam","param","assignments","views","tests","test","parts","shortTestId","variationId","hasSeen","getPreviewState","urlParams","isPreview","getCookie","previewTestId","getSessionItem","eabTestsParam","setCookie","setSessionItem","isPreviewTest","testId","getPreviewVariation","previewState","buildEabTestsParam","testAssignments","viewedTests","updateUrlWithTestParams","visitorId","url","eabTestsValue","clearPreviewMode","isInPreviewMode","init_storage","GEO_COOKIE_NAMES","getCountryCode","urlCountry","setCookie","shopifyCountry","getCookie","cachedCountry","storedCountry","getGeoLocation","country","geoData","parsed","setCountryCode","countryCode","normalized","setGeoLocation","geo","isCountryIncluded","allowedCountries","userCountry","c","isCountryExcluded","excludedCountries","matchesGeoTargeting","rules","COUNTRIES","REGIONS","FLICKER_CLASS","STYLE_ID","injectFlickerStyles","timeout","STYLE_ID","style","FLICKER_CLASS","head","hideForFlicker","selector","element","revealAfterFlicker","setupFlickerPrevention","hasRevealed","timeoutId","cleanupFlickerPrevention","el","isFlickerPreventionActive","getFlickerPreventionScript","import_ua_parser_js","urlSources","sanitizeString","value","roundToTwo","num","extractProductId","gid","regex","match","extractProductVariantId","extractCartToken","cleanCartToken","cartToken","checkFacebookBrowser","userAgent","checkInstagramBrowser","checkFacebookInstagramBrowser","getBrowserName","browser","getQueryParams","parsedUrl","queryParams","key","isValidReferrerURI","uri","extractReferrerSource","host","parseReferrer","referrer","siteHostname","referrerObj","source","parseAddViewData","params","entryPage","data","entryObj","entryPath","entryQueryParams","userAgentObj","browserName","getPageTypeFromPathname","path","hasLocalizedPaths","hasNormalPath","isLocalizedHomepage","checkVisitorIdParams","searchParams","getUserAgentNoBrowser","os","device","result","extractShopifyId","gid","extractShopifyType","isShopifyGid","value","detectShopifyCurrency","shopify","init_cartAttributes","init_cartAttributes_mutation","init_storage","import_react","DEFAULT_WORKER_URL","DEFAULT_ORDERS_WORKER_URL","globalConfig","initAnalytics","config","getStoreId","params","storeId","globalConfig","transformTestFormat","testObject","variationId","testId","transformViewedTests","viewedObject","assignmentObject","isInPreviewMode","getCookie","createBaseEventData","eventType","hasLocalizedPaths","userAgent","pathname","pageType","getPageTypeFromPathname","referrer","entryPage","getReferrerData","parsedData","parseAddViewData","abtlObject","getJsonCookie","abauObject","testAssignments","viewedTests","cartToken","extractCartToken","currentTimestamp","isFirstVisit","shopifyCountry","uuidv4","getVisitorId","getSessionId","cleanCartToken","getUserAgentNoBrowser","sendEvent","data","workerUrl","DEFAULT_WORKER_URL","response","error","trackPageView","baseData","eventData","trackProductView","productId","productVendor","productPrice","productSku","currency","extractShopifyId","sanitizeString","roundToTwo","trackAddToCart","variantId","productQuantity","cartId","storefrontAccessToken","updateCartAttributes","err","trackRemoveFromCart","trackCartView","cartTotalPrice","cartTotalQuantity","cartItems","item","trackSearchSubmitted","searchQuery","trackCheckoutStarted","cartSubtotalPrice","cartShippingPrice","cartTaxAmount","cartDiscountAmount","customerId","totalQuantity","items","quantity","trackCheckoutCompleted","orderId","isFirstOrder","noteAttributes","ordersWorkerUrl","DEFAULT_ORDERS_WORKER_URL","usePageViewTracking","enabled","externalPathname","lastTrackedPathRef","currentPath","setCurrentPath","import_react","import_react","ElevateContext","React","useElevateConfig","context","init_storage","init_assignment","useExperiment","testId","config","useElevateConfig","variant","setVariant","React","isLoading","setIsLoading","testConfig","test","hasWarnedRef","shouldShowTest","userId","getVisitorId","assigned","assignAndPersistVariant","trackViews","import_react","init_utils","USE_CDN_CONFIG","DEV_FALLBACK_CONFIG","ElevateProvider","storeId","storefrontAccessToken","preventFlickering","flickerTimeout","children","config","setConfig","React","previewState","setPreviewState","countryCode","setCountryCode","revealRef","setupFlickerPrevention","initAnalytics","preview","getPreviewState","country","getCountryCode","revealContent","fetchConfig","parsedConfig","parseBackendConfig","url","response","backendData","err","value","hasWarnedRef","ElevateContext","import_react","AntiFlickerScript","timeout","React","getFlickerPreventionScript","import_react","init_storage","init_cartAttributes","DEFAULT_WORKER_URL","DEFAULT_ORDERS_WORKER_URL","generatePixelEventId","uuidv4","transformTestFormat","testObject","variationId","testId","transformViewedTests","viewedObject","assignmentObject","ElevateAnalytics","storeIdProp","tokenProp","hasLocalizedPaths","workerUrl","ordersWorkerUrl","useAnalytics","context","ElevateContext","storeId","storefrontAccessToken","hasWarnedContextRef","subscribe","register","ready","getVisitorId","getSessionId","currentReferrer","currentUrl","setReferrerData","initializeState","event","productPageId","extractProductId","cartToken","extractCartToken","referrer","entryPage","getReferrerData","getCookie","createBaseEventData","eventName","pixelEventId","state","userAgent","pathname","pageType","getPageTypeFromPathname","parsedData","parseAddViewData","abtlObject","getJsonCookie","abauObject","testAssignments","viewedTests","currentTimestamp","isFirstVisit","shopifyCountry","cleanCartToken","getUserAgentNoBrowser","sendEvent","data","response","error","handlePageViewed","eventData","handleProductViewed","sanitizeString","roundToTwo","handleProductAddedToCart","extractProductVariantId","cartId","updateCartAttributes","err","handleProductRemovedFromCart","handleCartViewed","baseData","cartProducts","item","handleSearchSubmitted","handleCheckoutStarted","totalQuantity","checkoutProducts","quantity","total_discount","acc","discount","handleCheckoutCompleted","sendOrderEvent","VERSION","DEFAULT_CONFIG"]}