@fynd-design-engineering/fynd-one-v2 3.3.23 → 3.3.25

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
- "use strict";(()=>{(function(){window.phoneValidator={},document.addEventListener("DOMContentLoaded",function(){setTimeout(function(){u()},100)});function u(){document.querySelectorAll("input[type='tel'], .phone-input").forEach(function(t){t.id||(t.id="phone-input-"+Math.floor(Math.random()*1e4));try{let i=window.intlTelInput(t,{utilsScript:"https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/utils.js",separateDialCode:!0,initialCountry:"auto",geoIpLookup:function(n){fetch("https://ipapi.co/json").then(o=>o.json()).then(o=>n(o.country_code)).catch(()=>n("in"))},nationalMode:!1,allowDropdown:!0,autoPlaceholder:"polite",formatOnDisplay:!0});t.iti=i,t.addEventListener("countrychange",function(){})}catch{}}),window.validatePhone=(t,i)=>{let n=c(t);if(!n)return{isValid:!1,message:"No phone input found"};let o=n.iti;if(!o)return{isValid:!1,message:"Phone validator not initialized"};i!==void 0&&(n.value=i,o.setNumber(i));let a=n.value.trim();if(!a)return{isValid:!1,message:"No phone number provided"};let e=d(n,a,o);if(e.isValid)return e;try{if(o.isValidNumber&&o.isValidNumber()){let r=o.getNumber(),l=o.getSelectedCountryData(),s=l.dialCode;return{isValid:!0,message:"Valid number (standard validation)",fullNumber:r,countryCode:s,phoneNumber:r.substring(1+s.length),countryIso:l.iso2,countryName:l.name,validationMethod:"standard"}}}catch(r){console.warn("Standard validation failed:",r)}return e};function d(t,i,n){let o=n.getSelectedCountryData(),a=o.iso2?.toUpperCase(),e=i.replace(/\D/g,"");if(a==="US")return e.length===10&&/^[2-9]/.test(e)?{isValid:!0,message:"Valid US number",fullNumber:`+1${e}`,countryCode:"1",phoneNumber:e,countryIso:"us",countryName:"United States",formatInternational:`+1 ${e.slice(0,3)} ${e.slice(3,6)} ${e.slice(6)}`,formatNational:`(${e.slice(0,3)}) ${e.slice(3,6)}-${e.slice(6)}`,validationMethod:"custom"}:{isValid:!1,message:e.length!==10?`US numbers must be 10 digits (got ${e.length})`:"US numbers cannot start with 0 or 1"};if(a==="IN")return e.length===10&&/^[6-9]/.test(e)?{isValid:!0,message:"Valid Indian mobile number",fullNumber:`+91${e}`,countryCode:"91",phoneNumber:e,countryIso:"in",countryName:"India",formatInternational:`+91 ${e.slice(0,5)} ${e.slice(5)}`,formatNational:`${e.slice(0,5)} ${e.slice(5)}`,validationMethod:"custom"}:{isValid:!1,message:e.length!==10?`Indian mobile numbers must be 10 digits (got ${e.length})`:"Indian mobile numbers must start with 6, 7, 8, or 9"};if(a==="GB"){if(e.length===11&&e.startsWith("07"))return{isValid:!0,message:"Valid UK mobile number",fullNumber:`+44${e.slice(1)}`,countryCode:"44",phoneNumber:e.slice(1),countryIso:"gb",countryName:"United Kingdom",validationMethod:"custom"};if(e.length>=10&&e.length<=11&&/^0[12]/.test(e))return{isValid:!0,message:"Valid UK landline number",fullNumber:`+44${e.slice(1)}`,countryCode:"44",phoneNumber:e.slice(1),countryIso:"gb",countryName:"United Kingdom",validationMethod:"custom"}}return a==="AU"&&e.length===10&&e.startsWith("04")?{isValid:!0,message:"Valid Australian mobile number",fullNumber:`+61${e.slice(1)}`,countryCode:"61",phoneNumber:e.slice(1),countryIso:"au",countryName:"Australia",validationMethod:"custom"}:a==="CA"&&e.length===10&&/^[2-9]/.test(e)?{isValid:!0,message:"Valid Canadian number",fullNumber:`+1${e}`,countryCode:"1",phoneNumber:e,countryIso:"ca",countryName:"Canada",validationMethod:"custom"}:{isValid:!1,message:`No validation rules for ${o.name||"this country"}`}}function c(t){return typeof t=="string"?document.getElementById(t)||document.querySelector(t):t instanceof HTMLElement?t:document.querySelector("#phone-number")||document.querySelector("input[type='tel']")}window.validatePhoneAsync=async(t,i)=>{let n=0;for(;!window.intlTelInputUtils&&n<20;)await new Promise(o=>setTimeout(o,100)),n++;return window.validatePhone?window.validatePhone(t,i||""):{isValid:!1,message:"Validation not available"}},window.validatePhoneCustom=window.validatePhone,window.updateCountryCode=()=>{let t=document.querySelector("#phone-number"),i=document.querySelector("#country-code");if(!t||!i)return"91";try{if(t.iti){let n=t.iti.getSelectedCountryData();return i.value="+"+n.dialCode,n.dialCode}}catch(n){console.error("Error updating country code:",n)}return i.value="+91","91"},window.validatePhoneNumber=window.validatePhone,window.testPhoneNumber=window.validatePhone}})();})();
1
+ "use strict";(()=>{(function(){window.phoneValidator={},document.addEventListener("DOMContentLoaded",function(){setTimeout(function(){s()},100)});function s(){document.querySelectorAll("input[type='tel'], .phone-input").forEach(function(t){t.id||(t.id="phone-input-"+Math.floor(Math.random()*1e4));try{let i=window.intlTelInput(t,{utilsScript:"https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/utils.js",separateDialCode:!0,initialCountry:"auto",geoIpLookup:function(n){fetch("https://ipapi.co/json").then(o=>o.json()).then(o=>n(o.country_code)).catch(()=>n("in"))},nationalMode:!1,allowDropdown:!0,autoPlaceholder:"polite",formatOnDisplay:!0});t.iti=i,t.addEventListener("countrychange",function(){let n=i.getSelectedCountryData(),o=document.querySelector("#country-code");o&&(o.value="+"+n.dialCode)})}catch{}}),window.validatePhone=(t,i)=>{let n=c(t);if(!n)return{isValid:!1,message:"No phone input found"};let o=n.iti;if(!o)return{isValid:!1,message:"Phone validator not initialized"};i!==void 0&&(n.value=i,o.setNumber(i));let a=n.value.trim();if(!a)return{isValid:!1,message:"No phone number provided"};let e=d(n,a,o);if(e.isValid)return e;try{if(o.isValidNumber&&o.isValidNumber()){let r=o.getNumber(),l=o.getSelectedCountryData(),u=l.dialCode;return{isValid:!0,message:"Valid number (standard validation)",fullNumber:r,countryCode:u,phoneNumber:r.substring(1+u.length),countryIso:l.iso2,countryName:l.name,validationMethod:"standard"}}}catch(r){console.warn("Standard validation failed:",r)}return e};function d(t,i,n){let o=n.getSelectedCountryData(),a=o.iso2?.toUpperCase(),e=i.replace(/\D/g,"");if(a==="US")return e.length===10&&/^[2-9]/.test(e)?{isValid:!0,message:"Valid US number",fullNumber:`+1${e}`,countryCode:"1",phoneNumber:e,countryIso:"us",countryName:"United States",formatInternational:`+1 ${e.slice(0,3)} ${e.slice(3,6)} ${e.slice(6)}`,formatNational:`(${e.slice(0,3)}) ${e.slice(3,6)}-${e.slice(6)}`,validationMethod:"custom"}:{isValid:!1,message:e.length!==10?`US numbers must be 10 digits (got ${e.length})`:"US numbers cannot start with 0 or 1"};if(a==="IN")return e.length===10&&/^[6-9]/.test(e)?{isValid:!0,message:"Valid Indian mobile number",fullNumber:`+91${e}`,countryCode:"91",phoneNumber:e,countryIso:"in",countryName:"India",formatInternational:`+91 ${e.slice(0,5)} ${e.slice(5)}`,formatNational:`${e.slice(0,5)} ${e.slice(5)}`,validationMethod:"custom"}:{isValid:!1,message:e.length!==10?`Indian mobile numbers must be 10 digits (got ${e.length})`:"Indian mobile numbers must start with 6, 7, 8, or 9"};if(a==="GB"){if(e.length===11&&e.startsWith("07"))return{isValid:!0,message:"Valid UK mobile number",fullNumber:`+44${e.slice(1)}`,countryCode:"44",phoneNumber:e.slice(1),countryIso:"gb",countryName:"United Kingdom",validationMethod:"custom"};if(e.length>=10&&e.length<=11&&/^0[12]/.test(e))return{isValid:!0,message:"Valid UK landline number",fullNumber:`+44${e.slice(1)}`,countryCode:"44",phoneNumber:e.slice(1),countryIso:"gb",countryName:"United Kingdom",validationMethod:"custom"}}return a==="AU"&&e.length===10&&e.startsWith("04")?{isValid:!0,message:"Valid Australian mobile number",fullNumber:`+61${e.slice(1)}`,countryCode:"61",phoneNumber:e.slice(1),countryIso:"au",countryName:"Australia",validationMethod:"custom"}:a==="CA"&&e.length===10&&/^[2-9]/.test(e)?{isValid:!0,message:"Valid Canadian number",fullNumber:`+1${e}`,countryCode:"1",phoneNumber:e,countryIso:"ca",countryName:"Canada",validationMethod:"custom"}:{isValid:!1,message:`No validation rules for ${o.name||"this country"}`}}function c(t){return typeof t=="string"?document.getElementById(t)||document.querySelector(t):t instanceof HTMLElement?t:document.querySelector("#phone-number")||document.querySelector("input[type='tel']")}window.validatePhoneAsync=async(t,i)=>{let n=0;for(;!window.intlTelInputUtils&&n<20;)await new Promise(o=>setTimeout(o,100)),n++;return window.validatePhone?window.validatePhone(t,i||""):{isValid:!1,message:"Validation not available"}},window.validatePhoneCustom=window.validatePhone,window.updateCountryCode=()=>{let t=document.querySelector("#phone-number"),i=document.querySelector("#country-code");if(!t||!i)return"91";try{if(t.iti){let n=t.iti.getSelectedCountryData();return i.value="+"+n.dialCode,n.dialCode}}catch(n){console.error("Error updating country code:",n)}return i.value="+91","91"},window.validatePhoneNumber=window.validatePhone,window.testPhoneNumber=window.validatePhone}})();})();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../bin/live-reload.js", "../../src/form/phone-validator.ts"],
4
- "sourcesContent": ["// Only enable live reload when running on localhost\nif (\n window.location.hostname === \"localhost\" ||\n window.location.hostname === \"127.0.0.1\"\n) {\n new EventSource(`${SERVE_ORIGIN}/esbuild`).addEventListener(\"change\", () =>\n location.reload()\n );\n} else {\n // console.log(\"Live reload disabled: not running on localhost\");\n}\n", "\n//migrated from https://cdn.jsdelivr.net/gh/Fynd-Design-Engineering/fynd-one@4.0.2/form/phone-validator-2.0.js\n\n/**\n * Reliable Phone Validator Library - TypeScript Version\n * Uses custom validation rules as primary method with utils as fallback\n */\n\n// Make this file a module to allow global declarations\nexport {};\n\n// Type definitions\ninterface CountryData {\n iso2: string;\n dialCode: string;\n name: string;\n }\n \n interface ValidationResult {\n isValid: boolean;\n message?: string;\n fullNumber?: string;\n countryCode?: string;\n phoneNumber?: string;\n countryIso?: string;\n countryName?: string;\n formatInternational?: string;\n formatNational?: string;\n validationMethod?: 'custom' | 'standard';\n }\n \n interface IntlTelInputInstance {\n getSelectedCountryData(): CountryData;\n setNumber(number: string): void;\n getNumber(): string;\n isValidNumber?(): boolean;\n }\n \n interface PhoneInputElement extends HTMLInputElement {\n iti?: IntlTelInputInstance;\n }\n \n interface IntlTelInputOptions {\n utilsScript: string;\n separateDialCode: boolean;\n initialCountry: string;\n geoIpLookup: (callback: (countryCode: string) => void) => void;\n nationalMode: boolean;\n allowDropdown: boolean;\n autoPlaceholder: string;\n formatOnDisplay: boolean;\n }\n \n interface GeoIPResponse {\n country_code: string;\n }\n \n // Extend window interface for missing properties\n declare global {\n interface Window {\n phoneValidator: Record<string, unknown>;\n intlTelInput: (element: HTMLInputElement, options: IntlTelInputOptions) => IntlTelInputInstance;\n intlTelInputUtils?: unknown;\n validatePhoneAsync?: (phoneInput?: string | HTMLElement, phoneNumber?: string) => Promise<ValidationResult>;\n updateCountryCode?: () => string;\n validatePhoneNumber?: (selector: string, value: string) => ValidationResult;\n testPhoneNumber?: (selector: string, value: string) => ValidationResult;\n }\n }\n \n (function (): void {\n window.phoneValidator = {};\n \n document.addEventListener(\"DOMContentLoaded\", function (): void {\n setTimeout(function (): void {\n initializePhoneInputs();\n }, 100);\n });\n \n function initializePhoneInputs(): void {\n const phoneInputs = document.querySelectorAll<HTMLInputElement>(\n \"input[type='tel'], .phone-input\"\n );\n \n phoneInputs.forEach(function (input: HTMLInputElement): void {\n if (!input.id) {\n input.id = \"phone-input-\" + Math.floor(Math.random() * 10000);\n }\n \n try {\n const iti: IntlTelInputInstance = window.intlTelInput(input, {\n utilsScript:\n \"https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/utils.js\",\n separateDialCode: true,\n initialCountry: \"auto\",\n geoIpLookup: function (callback: (countryCode: string) => void): void {\n fetch(\"https://ipapi.co/json\")\n .then((res: Response) => res.json())\n .then((data: GeoIPResponse) => callback(data.country_code))\n .catch(() => callback(\"in\"));\n },\n nationalMode: false,\n allowDropdown: true,\n autoPlaceholder: \"polite\",\n formatOnDisplay: true,\n });\n \n (input as PhoneInputElement).iti = iti;\n \n input.addEventListener(\"countrychange\", function (): void {\n // console.log(\"Country changed to:\", iti.getSelectedCountryData());\n });\n \n // console.log(\"Phone input initialized:\", input.id);\n } catch (error) {\n // console.error(\"Failed to initialize phone input:\", error);\n }\n });\n \n // Primary validation function - uses custom rules first, then falls back to utils\n window.validatePhone = (phoneInput?: string | HTMLElement, phoneNumber?: string): ValidationResult => {\n const input: PhoneInputElement | null = getPhoneInput(phoneInput);\n if (!input) {\n return { isValid: false, message: \"No phone input found\" };\n }\n \n const iti: IntlTelInputInstance | undefined = input.iti;\n if (!iti) {\n return { isValid: false, message: \"Phone validator not initialized\" };\n }\n \n // Set the number if provided\n if (phoneNumber !== undefined) {\n input.value = phoneNumber;\n iti.setNumber(phoneNumber);\n }\n \n const number: string = input.value.trim();\n if (!number) {\n return { isValid: false, message: \"No phone number provided\" };\n }\n \n // Try custom validation first (most reliable)\n const customResult: ValidationResult = validateWithCustomRules(input, number, iti);\n if (customResult.isValid) {\n return customResult;\n }\n \n // Fallback to standard validation if custom rules don't match\n try {\n if (iti.isValidNumber && iti.isValidNumber()) {\n const fullNumber: string = iti.getNumber();\n const countryData: CountryData = iti.getSelectedCountryData();\n const countryCode: string = countryData.dialCode;\n \n return {\n isValid: true,\n message: \"Valid number (standard validation)\",\n fullNumber: fullNumber,\n countryCode: countryCode,\n phoneNumber: fullNumber.substring(1 + countryCode.length),\n countryIso: countryData.iso2,\n countryName: countryData.name,\n validationMethod: \"standard\",\n };\n }\n } catch (error) {\n console.warn(\"Standard validation failed:\", error);\n }\n \n // If both methods fail, return the custom validation result (which explains why it failed)\n return customResult;\n };\n \n // Custom validation rules for different countries\n function validateWithCustomRules(input: PhoneInputElement, number: string, iti: IntlTelInputInstance): ValidationResult {\n const countryData: CountryData = iti.getSelectedCountryData();\n const countryCode: string | undefined = countryData.iso2?.toUpperCase();\n const digitsOnly: string = number.replace(/\\D/g, \"\");\n \n // United States validation\n if (countryCode === \"US\") {\n if (digitsOnly.length === 10 && /^[2-9]/.test(digitsOnly)) {\n return {\n isValid: true,\n message: \"Valid US number\",\n fullNumber: `+1${digitsOnly}`,\n countryCode: \"1\",\n phoneNumber: digitsOnly,\n countryIso: \"us\",\n countryName: \"United States\",\n formatInternational: `+1 ${digitsOnly.slice(\n 0,\n 3\n )} ${digitsOnly.slice(3, 6)} ${digitsOnly.slice(6)}`,\n formatNational: `(${digitsOnly.slice(0, 3)}) ${digitsOnly.slice(\n 3,\n 6\n )}-${digitsOnly.slice(6)}`,\n validationMethod: \"custom\",\n };\n } else {\n return {\n isValid: false,\n message:\n digitsOnly.length !== 10\n ? `US numbers must be 10 digits (got ${digitsOnly.length})`\n : \"US numbers cannot start with 0 or 1\",\n };\n }\n }\n \n // India validation\n if (countryCode === \"IN\") {\n if (digitsOnly.length === 10 && /^[6-9]/.test(digitsOnly)) {\n return {\n isValid: true,\n message: \"Valid Indian mobile number\",\n fullNumber: `+91${digitsOnly}`,\n countryCode: \"91\",\n phoneNumber: digitsOnly,\n countryIso: \"in\",\n countryName: \"India\",\n formatInternational: `+91 ${digitsOnly.slice(\n 0,\n 5\n )} ${digitsOnly.slice(5)}`,\n formatNational: `${digitsOnly.slice(0, 5)} ${digitsOnly.slice(5)}`,\n validationMethod: \"custom\",\n };\n } else {\n return {\n isValid: false,\n message:\n digitsOnly.length !== 10\n ? `Indian mobile numbers must be 10 digits (got ${digitsOnly.length})`\n : \"Indian mobile numbers must start with 6, 7, 8, or 9\",\n };\n }\n }\n \n // United Kingdom validation\n if (countryCode === \"GB\") {\n // UK mobile numbers (07xxx xxxxxx)\n if (digitsOnly.length === 11 && digitsOnly.startsWith(\"07\")) {\n return {\n isValid: true,\n message: \"Valid UK mobile number\",\n fullNumber: `+44${digitsOnly.slice(1)}`,\n countryCode: \"44\",\n phoneNumber: digitsOnly.slice(1),\n countryIso: \"gb\",\n countryName: \"United Kingdom\",\n validationMethod: \"custom\",\n };\n }\n // UK landline numbers (01xxx or 02xxx)\n if (\n digitsOnly.length >= 10 &&\n digitsOnly.length <= 11 &&\n /^0[12]/.test(digitsOnly)\n ) {\n return {\n isValid: true,\n message: \"Valid UK landline number\",\n fullNumber: `+44${digitsOnly.slice(1)}`,\n countryCode: \"44\",\n phoneNumber: digitsOnly.slice(1),\n countryIso: \"gb\",\n countryName: \"United Kingdom\",\n validationMethod: \"custom\",\n };\n }\n }\n \n // Australia validation\n if (countryCode === \"AU\") {\n // Australian mobile numbers (04xx xxx xxx)\n if (digitsOnly.length === 10 && digitsOnly.startsWith(\"04\")) {\n return {\n isValid: true,\n message: \"Valid Australian mobile number\",\n fullNumber: `+61${digitsOnly.slice(1)}`,\n countryCode: \"61\",\n phoneNumber: digitsOnly.slice(1),\n countryIso: \"au\",\n countryName: \"Australia\",\n validationMethod: \"custom\",\n };\n }\n }\n \n // Canada validation (same as US)\n if (countryCode === \"CA\") {\n if (digitsOnly.length === 10 && /^[2-9]/.test(digitsOnly)) {\n return {\n isValid: true,\n message: \"Valid Canadian number\",\n fullNumber: `+1${digitsOnly}`,\n countryCode: \"1\",\n phoneNumber: digitsOnly,\n countryIso: \"ca\",\n countryName: \"Canada\",\n validationMethod: \"custom\",\n };\n }\n }\n \n // If no custom rules match, return invalid\n return {\n isValid: false,\n message: `No validation rules for ${\n countryData.name || \"this country\"\n }`,\n };\n }\n \n // Helper function to get phone input\n function getPhoneInput(phoneInput?: string | HTMLElement): PhoneInputElement | null {\n if (typeof phoneInput === \"string\") {\n return (\n document.getElementById(phoneInput) as PhoneInputElement ||\n document.querySelector(phoneInput) as PhoneInputElement\n );\n } else if (phoneInput instanceof HTMLElement) {\n return phoneInput as PhoneInputElement;\n } else {\n return (\n document.querySelector(\"#phone-number\") as PhoneInputElement ||\n document.querySelector(\"input[type='tel']\") as PhoneInputElement\n );\n }\n }\n \n // Async version that waits for utils (but still uses custom rules first)\n window.validatePhoneAsync = async (phoneInput?: string | HTMLElement, phoneNumber?: string): Promise<ValidationResult> => {\n // Wait a bit for utils to load\n let attempts: number = 0;\n while (!window.intlTelInputUtils && attempts < 20) {\n await new Promise<void>((resolve) => setTimeout(resolve, 100));\n attempts++;\n }\n \n return window.validatePhone ? window.validatePhone(phoneInput as string, phoneNumber || '') : { isValid: false, message: 'Validation not available' };\n };\n \n // Keep the old custom validation function for backward compatibility\n window.validatePhoneCustom = window.validatePhone;\n \n // Country code update function\n window.updateCountryCode = (): string => {\n const phoneInput: PhoneInputElement | null = document.querySelector(\"#phone-number\");\n const countryCodeInput: HTMLInputElement | null = document.querySelector(\"#country-code\");\n \n if (!phoneInput || !countryCodeInput) return \"91\";\n \n try {\n if (phoneInput.iti) {\n const countryData: CountryData = phoneInput.iti.getSelectedCountryData();\n countryCodeInput.value = \"+\" + countryData.dialCode;\n return countryData.dialCode;\n }\n } catch (error) {\n console.error(\"Error updating country code:\", error);\n }\n \n countryCodeInput.value = \"+91\";\n return \"91\";\n };\n \n // For backward compatibility\n window.validatePhoneNumber = window.validatePhone;\n window.testPhoneNumber = window.validatePhone;\n \n // console.log(\n // \"%c Reliable Phone Validator Ready! \uD83D\uDE80\",\n // \"color: green; font-weight: bold;\"\n // );\n // console.log(\"\u2705 Uses custom validation rules as primary method\");\n // console.log(\"\u2705 Falls back to standard validation when available\");\n // console.log(\"\u2705 Supports: US, India, UK, Australia, Canada\");\n }\n })();"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Only enable live reload when running on localhost\nif (\n window.location.hostname === \"localhost\" ||\n window.location.hostname === \"127.0.0.1\"\n) {\n new EventSource(`${SERVE_ORIGIN}/esbuild`).addEventListener(\"change\", () =>\n location.reload()\n );\n} else {\n // console.log(\"Live reload disabled: not running on localhost\");\n}\n", "\n//migrated from https://cdn.jsdelivr.net/gh/Fynd-Design-Engineering/fynd-one@4.0.2/form/phone-validator-2.0.js\n\n/**\n * Reliable Phone Validator Library - TypeScript Version\n * Uses custom validation rules as primary method with utils as fallback\n */\n\n// Make this file a module to allow global declarations\nexport {};\n\n// Type definitions\ninterface CountryData {\n iso2: string;\n dialCode: string;\n name: string;\n }\n \n interface ValidationResult {\n isValid: boolean;\n message?: string;\n fullNumber?: string;\n countryCode?: string;\n phoneNumber?: string;\n countryIso?: string;\n countryName?: string;\n formatInternational?: string;\n formatNational?: string;\n validationMethod?: 'custom' | 'standard';\n }\n \n interface IntlTelInputInstance {\n getSelectedCountryData(): CountryData;\n setNumber(number: string): void;\n getNumber(): string;\n isValidNumber?(): boolean;\n }\n \n interface PhoneInputElement extends HTMLInputElement {\n iti?: IntlTelInputInstance;\n }\n \n interface IntlTelInputOptions {\n utilsScript: string;\n separateDialCode: boolean;\n initialCountry: string;\n geoIpLookup: (callback: (countryCode: string) => void) => void;\n nationalMode: boolean;\n allowDropdown: boolean;\n autoPlaceholder: string;\n formatOnDisplay: boolean;\n }\n \n interface GeoIPResponse {\n country_code: string;\n }\n \n // Extend window interface for missing properties\n declare global {\n interface Window {\n phoneValidator: Record<string, unknown>;\n intlTelInput: (element: HTMLInputElement, options: IntlTelInputOptions) => IntlTelInputInstance;\n intlTelInputUtils?: unknown;\n validatePhoneAsync?: (phoneInput?: string | HTMLElement, phoneNumber?: string) => Promise<ValidationResult>;\n updateCountryCode?: () => string;\n validatePhoneNumber?: (selector: string, value: string) => ValidationResult;\n testPhoneNumber?: (selector: string, value: string) => ValidationResult;\n }\n }\n \n (function (): void {\n window.phoneValidator = {};\n \n document.addEventListener(\"DOMContentLoaded\", function (): void {\n setTimeout(function (): void {\n initializePhoneInputs();\n }, 100);\n });\n \n function initializePhoneInputs(): void {\n const phoneInputs = document.querySelectorAll<HTMLInputElement>(\n \"input[type='tel'], .phone-input\"\n );\n \n phoneInputs.forEach(function (input: HTMLInputElement): void {\n if (!input.id) {\n input.id = \"phone-input-\" + Math.floor(Math.random() * 10000);\n }\n \n try {\n const iti: IntlTelInputInstance = window.intlTelInput(input, {\n utilsScript:\n \"https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/17.0.8/js/utils.js\",\n separateDialCode: true,\n initialCountry: \"auto\",\n geoIpLookup: function (callback: (countryCode: string) => void): void {\n fetch(\"https://ipapi.co/json\")\n .then((res: Response) => res.json())\n .then((data: GeoIPResponse) => callback(data.country_code))\n .catch(() => callback(\"in\"));\n },\n nationalMode: false,\n allowDropdown: true,\n autoPlaceholder: \"polite\",\n formatOnDisplay: true,\n });\n \n (input as PhoneInputElement).iti = iti;\n \n input.addEventListener(\"countrychange\", function (): void {\n // console.log(\"Country changed to:\", iti.getSelectedCountryData());\n const countryData = iti.getSelectedCountryData();\n const countryCodeInput = document.querySelector<HTMLInputElement>(\"#country-code\");\n \n if (countryCodeInput) {\n countryCodeInput.value = \"+\" + countryData.dialCode;\n }\n });\n \n // console.log(\"Phone input initialized:\", input.id);\n } catch (error) {\n // console.error(\"Failed to initialize phone input:\", error);\n }\n });\n \n // Primary validation function - uses custom rules first, then falls back to utils\n window.validatePhone = (phoneInput?: string | HTMLElement, phoneNumber?: string): ValidationResult => {\n const input: PhoneInputElement | null = getPhoneInput(phoneInput);\n if (!input) {\n return { isValid: false, message: \"No phone input found\" };\n }\n \n const iti: IntlTelInputInstance | undefined = input.iti;\n if (!iti) {\n return { isValid: false, message: \"Phone validator not initialized\" };\n }\n \n // Set the number if provided\n if (phoneNumber !== undefined) {\n input.value = phoneNumber;\n iti.setNumber(phoneNumber);\n }\n \n const number: string = input.value.trim();\n if (!number) {\n return { isValid: false, message: \"No phone number provided\" };\n }\n \n // Try custom validation first (most reliable)\n const customResult: ValidationResult = validateWithCustomRules(input, number, iti);\n if (customResult.isValid) {\n return customResult;\n }\n \n // Fallback to standard validation if custom rules don't match\n try {\n if (iti.isValidNumber && iti.isValidNumber()) {\n const fullNumber: string = iti.getNumber();\n const countryData: CountryData = iti.getSelectedCountryData();\n const countryCode: string = countryData.dialCode;\n \n return {\n isValid: true,\n message: \"Valid number (standard validation)\",\n fullNumber: fullNumber,\n countryCode: countryCode,\n phoneNumber: fullNumber.substring(1 + countryCode.length),\n countryIso: countryData.iso2,\n countryName: countryData.name,\n validationMethod: \"standard\",\n };\n }\n } catch (error) {\n console.warn(\"Standard validation failed:\", error);\n }\n \n // If both methods fail, return the custom validation result (which explains why it failed)\n return customResult;\n };\n \n // Custom validation rules for different countries\n function validateWithCustomRules(input: PhoneInputElement, number: string, iti: IntlTelInputInstance): ValidationResult {\n const countryData: CountryData = iti.getSelectedCountryData();\n const countryCode: string | undefined = countryData.iso2?.toUpperCase();\n const digitsOnly: string = number.replace(/\\D/g, \"\");\n \n // United States validation\n if (countryCode === \"US\") {\n if (digitsOnly.length === 10 && /^[2-9]/.test(digitsOnly)) {\n return {\n isValid: true,\n message: \"Valid US number\",\n fullNumber: `+1${digitsOnly}`,\n countryCode: \"1\",\n phoneNumber: digitsOnly,\n countryIso: \"us\",\n countryName: \"United States\",\n formatInternational: `+1 ${digitsOnly.slice(\n 0,\n 3\n )} ${digitsOnly.slice(3, 6)} ${digitsOnly.slice(6)}`,\n formatNational: `(${digitsOnly.slice(0, 3)}) ${digitsOnly.slice(\n 3,\n 6\n )}-${digitsOnly.slice(6)}`,\n validationMethod: \"custom\",\n };\n } else {\n return {\n isValid: false,\n message:\n digitsOnly.length !== 10\n ? `US numbers must be 10 digits (got ${digitsOnly.length})`\n : \"US numbers cannot start with 0 or 1\",\n };\n }\n }\n \n // India validation\n if (countryCode === \"IN\") {\n if (digitsOnly.length === 10 && /^[6-9]/.test(digitsOnly)) {\n return {\n isValid: true,\n message: \"Valid Indian mobile number\",\n fullNumber: `+91${digitsOnly}`,\n countryCode: \"91\",\n phoneNumber: digitsOnly,\n countryIso: \"in\",\n countryName: \"India\",\n formatInternational: `+91 ${digitsOnly.slice(\n 0,\n 5\n )} ${digitsOnly.slice(5)}`,\n formatNational: `${digitsOnly.slice(0, 5)} ${digitsOnly.slice(5)}`,\n validationMethod: \"custom\",\n };\n } else {\n return {\n isValid: false,\n message:\n digitsOnly.length !== 10\n ? `Indian mobile numbers must be 10 digits (got ${digitsOnly.length})`\n : \"Indian mobile numbers must start with 6, 7, 8, or 9\",\n };\n }\n }\n \n // United Kingdom validation\n if (countryCode === \"GB\") {\n // UK mobile numbers (07xxx xxxxxx)\n if (digitsOnly.length === 11 && digitsOnly.startsWith(\"07\")) {\n return {\n isValid: true,\n message: \"Valid UK mobile number\",\n fullNumber: `+44${digitsOnly.slice(1)}`,\n countryCode: \"44\",\n phoneNumber: digitsOnly.slice(1),\n countryIso: \"gb\",\n countryName: \"United Kingdom\",\n validationMethod: \"custom\",\n };\n }\n // UK landline numbers (01xxx or 02xxx)\n if (\n digitsOnly.length >= 10 &&\n digitsOnly.length <= 11 &&\n /^0[12]/.test(digitsOnly)\n ) {\n return {\n isValid: true,\n message: \"Valid UK landline number\",\n fullNumber: `+44${digitsOnly.slice(1)}`,\n countryCode: \"44\",\n phoneNumber: digitsOnly.slice(1),\n countryIso: \"gb\",\n countryName: \"United Kingdom\",\n validationMethod: \"custom\",\n };\n }\n }\n \n // Australia validation\n if (countryCode === \"AU\") {\n // Australian mobile numbers (04xx xxx xxx)\n if (digitsOnly.length === 10 && digitsOnly.startsWith(\"04\")) {\n return {\n isValid: true,\n message: \"Valid Australian mobile number\",\n fullNumber: `+61${digitsOnly.slice(1)}`,\n countryCode: \"61\",\n phoneNumber: digitsOnly.slice(1),\n countryIso: \"au\",\n countryName: \"Australia\",\n validationMethod: \"custom\",\n };\n }\n }\n \n // Canada validation (same as US)\n if (countryCode === \"CA\") {\n if (digitsOnly.length === 10 && /^[2-9]/.test(digitsOnly)) {\n return {\n isValid: true,\n message: \"Valid Canadian number\",\n fullNumber: `+1${digitsOnly}`,\n countryCode: \"1\",\n phoneNumber: digitsOnly,\n countryIso: \"ca\",\n countryName: \"Canada\",\n validationMethod: \"custom\",\n };\n }\n }\n \n // If no custom rules match, return invalid\n return {\n isValid: false,\n message: `No validation rules for ${\n countryData.name || \"this country\"\n }`,\n };\n }\n \n // Helper function to get phone input\n function getPhoneInput(phoneInput?: string | HTMLElement): PhoneInputElement | null {\n if (typeof phoneInput === \"string\") {\n return (\n document.getElementById(phoneInput) as PhoneInputElement ||\n document.querySelector(phoneInput) as PhoneInputElement\n );\n } else if (phoneInput instanceof HTMLElement) {\n return phoneInput as PhoneInputElement;\n } else {\n return (\n document.querySelector(\"#phone-number\") as PhoneInputElement ||\n document.querySelector(\"input[type='tel']\") as PhoneInputElement\n );\n }\n }\n \n // Async version that waits for utils (but still uses custom rules first)\n window.validatePhoneAsync = async (phoneInput?: string | HTMLElement, phoneNumber?: string): Promise<ValidationResult> => {\n // Wait a bit for utils to load\n let attempts: number = 0;\n while (!window.intlTelInputUtils && attempts < 20) {\n await new Promise<void>((resolve) => setTimeout(resolve, 100));\n attempts++;\n }\n \n return window.validatePhone ? window.validatePhone(phoneInput as string, phoneNumber || '') : { isValid: false, message: 'Validation not available' };\n };\n \n // Keep the old custom validation function for backward compatibility\n window.validatePhoneCustom = window.validatePhone;\n \n // Country code update function\n window.updateCountryCode = (): string => {\n const phoneInput: PhoneInputElement | null = document.querySelector(\"#phone-number\");\n const countryCodeInput: HTMLInputElement | null = document.querySelector(\"#country-code\");\n \n if (!phoneInput || !countryCodeInput) return \"91\";\n \n try {\n if (phoneInput.iti) {\n const countryData: CountryData = phoneInput.iti.getSelectedCountryData();\n countryCodeInput.value = \"+\" + countryData.dialCode;\n return countryData.dialCode;\n }\n } catch (error) {\n console.error(\"Error updating country code:\", error);\n }\n \n countryCodeInput.value = \"+91\";\n return \"91\";\n };\n \n // For backward compatibility\n window.validatePhoneNumber = window.validatePhone;\n window.testPhoneNumber = window.validatePhone;\n \n // console.log(\n // \"%c Reliable Phone Validator Ready! \uD83D\uDE80\",\n // \"color: green; font-weight: bold;\"\n // );\n // console.log(\"\u2705 Uses custom validation rules as primary method\");\n // console.log(\"\u2705 Falls back to standard validation when available\");\n // console.log(\"\u2705 Supports: US, India, UK, Australia, Canada\");\n }\n })();"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../bin/live-reload.js", "../../src/global/geolocation/main.ts", "../../src/global/geolocation/geolocation-cached.ts", "../../src/global/animation/toggle-banner.ts", "../../src/utils/cookies.ts", "../../src/global/screen-type.ts", "../../src/navigation/country-detection/main.ts", "../../src/navigation/initialization.ts"],
4
- "sourcesContent": ["// Only enable live reload when running on localhost\nif (\n window.location.hostname === \"localhost\" ||\n window.location.hostname === \"127.0.0.1\"\n) {\n new EventSource(`${SERVE_ORIGIN}/esbuild`).addEventListener(\"change\", () =>\n location.reload()\n );\n} else {\n // console.log(\"Live reload disabled: not running on localhost\");\n}\n", "// Define the type for returned geolocation data\n// Remider for adding Fallback: ipinfo.io (HTTPS, requires token)\nexport type GeoData = {\n ip: string;\n country: string;\n region: string;\n city: string;\n latitude: number;\n longitude: number;\n isp: string;\n timezone: string;\n };\n \n // Exported function that can be reused anywhere\n export async function getGeolocation(): Promise<GeoData | null> {\n try {\n const response = await fetch(\"https://ipwho.is/\");\n if (!response.ok) {\n throw new Error(\"Failed to fetch geolocation\");\n }\n \n const data = await response.json();\n \n if (data.success === false) {\n console.error(\"Geolocation lookup failed:\", data.message);\n return null;\n }\n \n return {\n ip: data.ip,\n country: data.country,\n region: data.region,\n city: data.city,\n latitude: data.latitude,\n longitude: data.longitude,\n isp: data.connection?.isp || \"\",\n timezone: data.timezone?.id || \"\"\n };\n } catch (error) {\n console.error(\"Error fetching geolocation:\", error);\n return null;\n }\n }\n\n //used in /src/navigation/initialization.ts for displaying ip banner", "import { GeoData, getGeolocation } from \"./main\";\n\nconst GEO_CACHE_KEY = \"geo:data:v1\";\nconst GEO_COOKIE_KEY = \"geo_country\";\nconst GEO_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\ntype Cached<T> = { data: T; expiresAt: number };\n\n// --- Cookie helpers ---\nfunction setCookie(name: string, value: string, maxAgeSec: number) {\n document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; Max-Age=${maxAgeSec}; Path=/; SameSite=Lax; Secure`;\n}\n\nfunction getCookie(name: string): string | null {\n const key = `${encodeURIComponent(name)}=`;\n const parts = document.cookie.split(\"; \");\n for (const p of parts) {\n if (p.startsWith(key)) return decodeURIComponent(p.slice(key.length));\n }\n return null;\n}\n\nfunction clearCookie(name: string) {\n document.cookie = `${encodeURIComponent(name)}=; Max-Age=0; Path=/; SameSite=Lax; Secure`;\n}\n\n// --- LocalStorage helpers ---\nfunction readCache<T>(key: string): T | null {\n try {\n const raw = localStorage.getItem(key);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as Cached<T>;\n if (!parsed?.expiresAt || Date.now() > parsed.expiresAt) {\n localStorage.removeItem(key);\n return null;\n }\n return parsed.data;\n } catch {\n localStorage.removeItem(key);\n return null;\n }\n}\n\nfunction writeCache<T>(key: string, data: T, ttlMs: number) {\n const payload: Cached<T> = { data, expiresAt: Date.now() + ttlMs };\n try {\n localStorage.setItem(key, JSON.stringify(payload));\n } catch {\n // ignore quota errors\n }\n}\n\n// --- Public API ---\nexport async function getGeolocationCached(options?: {\n forceRefresh?: boolean;\n}): Promise<GeoData | null> {\n if (typeof window === \"undefined\") return null;\n\n const forceRefresh = options?.forceRefresh ?? false;\n\n if (!forceRefresh) {\n const cached = readCache<GeoData>(GEO_CACHE_KEY);\n if (cached) {\n (window as any).__GEO = cached;\n if (!getCookie(GEO_COOKIE_KEY)) {\n setCookie(GEO_COOKIE_KEY, cached.country ?? \"\", Math.floor(GEO_TTL_MS / 1000));\n }\n return cached;\n }\n }\n\n const fresh = await getGeolocation();\n if (!fresh) return null;\n\n writeCache(GEO_CACHE_KEY, fresh, GEO_TTL_MS);\n setCookie(GEO_COOKIE_KEY, fresh.country ?? \"\", Math.floor(GEO_TTL_MS / 1000));\n (window as any).__GEO = fresh;\n return fresh;\n}\n\nexport function getGeoCountryFromCookie(): string | null {\n return getCookie(GEO_COOKIE_KEY);\n}\n\nexport function clearGeolocationCache() {\n try {\n localStorage.removeItem(GEO_CACHE_KEY);\n } catch {}\n clearCookie(GEO_COOKIE_KEY);\n if (typeof window !== \"undefined\") {\n (window as any).__GEO = undefined;\n }\n}", "// toggleBanner.ts\n// Utility functions to open/close a banner using GSAP with optional target height.\n\nexport function openBanner(\n mainSelector: string,\n innerSelector: string,\n targetHeight: string | number = \"auto\" // default stays \"auto\"\n) {\n const w = (window as any) || {};\n const gsap = w.gsap as any;\n if (!gsap) {\n console.warn(\"GSAP not found on window. Did you include it globally?\");\n return;\n }\n\n const mainEl = document.querySelector<HTMLElement>(mainSelector);\n const innerEl = document.querySelector<HTMLElement>(innerSelector);\n\n if (!mainEl || !innerEl) {\n console.warn(\"openBanner: Element(s) not found for selectors:\", {\n mainSelector,\n innerSelector,\n });\n return;\n }\n\n // Ensure clean start\n gsap.set(mainEl, { height: 0, overflow: \"hidden\" });\n gsap.set(innerEl, { opacity: 0 });\n\n const tl = gsap.timeline();\n\n // Animate main from height: 0 -> targetHeight\n tl.to(mainEl, {\n height: targetHeight,\n duration: 0.5,\n ease: \"power2.out\",\n });\n\n // After 0.2s, fade inner to 1\n tl.to(\n innerEl,\n {\n opacity: 1,\n duration: 0.3,\n ease: \"power1.out\",\n },\n 0.2\n );\n\n return tl;\n}\n\nexport function closeBanner(\n mainSelector: string,\n innerSelector: string,\n targetHeight: string | number = 0 // default collapse fully\n) {\n const w = (window as any) || {};\n const gsap = w.gsap as any;\n if (!gsap) {\n console.warn(\"GSAP not found on window. Did you include it globally?\");\n return;\n }\n\n const mainEl = document.querySelector<HTMLElement>(mainSelector);\n const innerEl = document.querySelector<HTMLElement>(innerSelector);\n\n if (!mainEl || !innerEl) {\n console.warn(\"closeBanner: Element(s) not found for selectors:\", {\n mainSelector,\n innerSelector,\n });\n return;\n }\n\n gsap.set(mainEl, { overflow: \"hidden\" });\n\n const tl = gsap.timeline();\n\n // Fade inner out\n tl.to(innerEl, {\n opacity: 0,\n duration: 0.25,\n ease: \"power1.out\",\n });\n\n // Collapse height to targetHeight (default 0)\n tl.to(\n mainEl,\n {\n height: targetHeight,\n duration: 0.45,\n ease: \"power2.inOut\",\n },\n 0.2\n );\n\n return tl;\n}", "export function setCookie(name: string, value: string, hours: number) {\n const date = new Date();\n date.setTime(date.getTime() + hours * 60 * 60 * 1000);\n document.cookie = `${name}=${value}; expires=${date.toUTCString()}; path=/`;\n }\n \n export function getCookie(name: string): string | null {\n const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));\n return match ? match[2] : null;\n }", "// screen-type.ts\n// Utility to get the current screen type\n// Breakpoints:\n// - Desktop: 992px+\n// - Tablet: 768px\u2013991px\n// - Mobile Landscape: 480px\u2013767px\n// - Mobile Portrait: under 480px\n\nexport type ScreenType = \"desktop\" | \"tablet\" | \"mobileLandscape\" | \"mobilePortrait\";\n\nexport function getScreenType(): ScreenType {\n const width = window.innerWidth;\n\n if (width >= 992) {\n return \"desktop\";\n } else if (width >= 768) {\n return \"tablet\";\n } else if (width >= 480) {\n return \"mobileLandscape\";\n } else {\n return \"mobilePortrait\";\n }\n}", "// geo.ts\nimport { getGeoCountryFromCookie, getGeolocationCached } from \"src/global/geolocation/geolocation-cached\";\nimport { GeoData } from \"src/global/geolocation/main\";\n\n/** Your banner config */\ntype CountryConfig = {\n country: string; // canonical lowercase name\n countryCode: string; // ISO-2 lowercase code (e.g., \"in\")\n url: string; // leading-slash path (e.g., \"/in\")\n tagline: string; // banner text/html\n aliases?: string[]; // optional extra names to match against\n};\n\nexport const COUNTRY_CONFIG: CountryConfig[] = [\n {\n country: \"united arab emirates\",\n aliases: [\"uae\", \"u.a.e\", \"united arab emirates\"],\n countryCode: \"ae\",\n url: \"/ae\",\n tagline: \"You're in the UAE. Welcome!\"\n },\n {\n country: \"saudi arabia\",\n aliases: [\"saudi\", \"ksa\", \"kingdom of saudi arabia\"],\n countryCode: \"sa\",\n url: \"/sa\",\n tagline: \"Hello Saudi Arabia!\"\n },\n {\n country: \"south africa\",\n aliases: [\"rsa\"],\n countryCode: \"za\",\n url: \"/za\",\n tagline: \"Hi South Africa!\"\n },\n {\n country: \"malaysia\",\n countryCode: \"my\",\n url: \"/my\",\n tagline: \"Selamat datang, Malaysia!\"\n },\n {\n country: \"indonesia\",\n aliases: [\"idn\"],\n countryCode: \"id\",\n url: \"/id\",\n tagline: \"Halo Indonesia!\"\n },\n {\n country: \"philippines\",\n aliases: [\"phl\", \"the philippines\"],\n countryCode: \"ph\",\n url: \"/ph\",\n tagline: \"Kumusta, Philippines!\"\n },\n {\n country: \"india\",\n aliases: [\"bharat\"],\n countryCode: \"in\",\n url: \"/in\",\n tagline: \"This country is India. Hi some text\"\n },\n // \uD83D\uDC47 fallback\n {\n country: \"global\",\n aliases: [\"global\", \"rest of world\", \"others\"],\n countryCode: \"global\", // keep lowercase for consistency\n url: \"/global\",\n tagline: \"This is rest of world. Hi some text\"\n }\n];\n\n/** Utility: normalize strings for comparisons */\nfunction norm(s: string | null | undefined): string {\n return (s ?? \"\").trim().toLowerCase();\n}\n\n/** Utility: ensure URL starts with a single leading slash */\nfunction toPath(path: string): string {\n const p = path.trim();\n if (!p) return \"/\";\n return p.startsWith(\"/\") ? p : `/${p}`;\n}\n\n/** Determine user's country as a *string* (might be name or code depending on your geo source) */\nexport async function getUserCountry(): Promise<string | null> {\n if (typeof window === \"undefined\") return null;\n\n // 1) Cookie fast-path\n const cookieCountry = getGeoCountryFromCookie();\n if (cookieCountry) return norm(cookieCountry);\n\n // 2) Cached or network\n const geo: GeoData | null = await getGeolocationCached();\n return norm((geo as any)?.country);\n}\n\n/** Find matching config by country *name* or *ISO-2 code* with aliases */\nfunction findCountryConfig(input: string | null): CountryConfig | null {\n const v = norm(input);\n if (!v) return null;\n\n const byCode = COUNTRY_CONFIG.find(c => norm(c.countryCode) === v);\n if (byCode) return byCode;\n\n const byName = COUNTRY_CONFIG.find(c => norm(c.country) === v);\n if (byName) return byName;\n\n const byAlias = COUNTRY_CONFIG.find(c => (c.aliases ?? []).some(a => norm(a) === v));\n if (byAlias) return byAlias;\n\n return null;\n}\n\n/** Helper to fetch the global config */\nfunction getGlobalConfig(): CountryConfig {\n const g = COUNTRY_CONFIG.find(c => c.country === \"global\");\n if (!g) throw new Error(\"[geo-banner] Global config not found in COUNTRY_CONFIG\");\n return g;\n}\n\nfunction updateBannerLink(countryCode?: string | null): void {\n if (typeof window === \"undefined\") return;\n\n const code = norm(countryCode);\n const conf =\n COUNTRY_CONFIG.find(c => norm(c.countryCode) === code) ||\n getGlobalConfig();\n\n const linkEl = document.querySelector<HTMLAnchorElement>('[fynd-banner-field=\"link\"]');\n if (linkEl) {\n const base = window.location.origin;\n linkEl.href = `${base}${toPath(conf.url)}`;\n }\n}\n\nexport function setSelectValueSafely(selectEl: HTMLSelectElement, desired: string) {\n // 1) resolve config\n const conf =\n findCountryConfig(desired) ??\n COUNTRY_CONFIG.find(c => c.country === \"global\");\n if (!conf) {\n console.warn(\"[geo-banner] No matching config for\", desired);\n return false;\n }\n const desiredCode = conf.countryCode; // assume already normalized/lowercase\n\n // 2) find matching option (normalize both sides)\n const opts = Array.from(selectEl.options);\n const opt = opts.find(o => norm(o.value) === norm(desiredCode));\n if (!opt) {\n console.warn(\"[geo-banner] No matching <option> for\", desiredCode, \"on\", selectEl);\n return false;\n }\n\n // 3) update the <select> itself (more reliable than toggling option.selected)\n const prev = selectEl.value;\n selectEl.value = opt.value;\n\n // if some browsers/frameworks didn\u2019t adopt .value, force selectedIndex too\n if (selectEl.value !== opt.value) {\n selectEl.selectedIndex = opts.indexOf(opt);\n }\n\n // 4) (optional) keep options\u2019 selected flags in sync\n opts.forEach(o => (o.selected = o === opt));\n\n // 5) fire events frameworks listen to\n if (prev !== selectEl.value) {\n selectEl.dispatchEvent(new Event(\"input\", { bubbles: true }));\n selectEl.dispatchEvent(new Event(\"change\", { bubbles: true }));\n }\n\n console.log(\"[geo-banner] Select updated \u2192\", conf.country, \"(\", conf.countryCode, \")\");\n return true;\n}\n\n/** Update the banner content for a given countryCode (lowercase ISO-2) with global fallback */\nexport function updateBannerContent(countryCode?: string | null): void {\n if (typeof window === \"undefined\") return;\n\n const code = norm(countryCode);\n const conf =\n COUNTRY_CONFIG.find(c => norm(c.countryCode) === code) ||\n getGlobalConfig();\n // 1) Set <select fynd-banner-field=\"geoswitch\"> value (robustly)\n const selectEl =\n document.querySelector<HTMLSelectElement>('#geoswitch-select') ||\n document.querySelector<HTMLSelectElement>('[fynd-banner-field=\"geoswitch\"]');\n\n if (selectEl) {\n console.log(`country code is ${conf.countryCode}`)\n setSelectValueSafely(selectEl, conf.countryCode);\n selectEl.value = conf.countryCode; // or \"global\", etc.\n\n selectEl.dispatchEvent(new Event(\"change\", { bubbles: true }));\n } else {\n console.warn('[geo-banner] Select not found: #geoswitch-select / [fynd-banner-field=\"geoswitch\"]');\n }\n\n // // 2) Update banner text (unchanged)\n // const textEl = document.querySelector<HTMLElement>('[fynd-banner-field=\"banner-text\"]');\n // if (textEl) textEl.innerHTML = conf.tagline;\n\n // 3) Update link href (unchanged)\n const linkEl = document.querySelector<HTMLAnchorElement>('[fynd-banner-field=\"link\"]');\n if (linkEl) {\n const base = window.location.origin;\n linkEl.href = `${base}${toPath(conf.url)}`;\n }\n}\n\n/**\n * Main entry: detect country and update banner if it matches one of the configured countries.\n * Always falls back to global if no match is found.\n */\nexport async function initCountryDetection(): Promise<CountryConfig> {\n if (typeof window === \"undefined\") return getGlobalConfig();\n\n if (document.readyState === \"loading\") {\n await new Promise<void>(resolve => {\n document.addEventListener(\"DOMContentLoaded\", () => resolve(), { once: true });\n });\n }\n\n const rawCountry = await getUserCountry();\n const match = findCountryConfig(rawCountry);\n const resolved = match ?? getGlobalConfig();\n\n // Debug visibility\n console.log(\"[geo-banner] rawCountry:\", rawCountry, \"\u2192 resolved:\", resolved.countryCode);\n\n // \u2705 Always update from the resolved config (guarantees global fallback)\n updateBannerContent(resolved.countryCode);\n\n // (If you also attached the select change listener, keep that here)\n const selectEl = document.querySelector<HTMLSelectElement>('[fynd-banner-field=\"geoswitch\"]');\n if (selectEl && !(selectEl as any).__geoHandlerAttached) {\n selectEl.addEventListener(\"change\", (e) => {\n const value = (e.target as HTMLSelectElement).value;\n updateBannerLink(value); // only updates href on change\n });\n (selectEl as any).__geoHandlerAttached = true;\n }\n\n return resolved;\n}", "import { getGeolocationCached } from \"src/global/geolocation/geolocation-cached\";\nimport { closeBanner, openBanner } from \"src/global/animation/toggle-banner\";\nimport { getCookie, setCookie } from \"$utils/cookies\";\nimport { getScreenType } from \"src/global/screen-type\";\nimport { initCountryDetection } from \"./country-detection/main\";\n\n/**\n * Banner rules by route (normalized, no trailing slash).\n * Modes:\n * - { mode: \"always\" }\n * - { mode: \"country\", countries: [...] } \u2192 open if geo.country matches (case-insensitive)\n * - { mode: \"notCountry\", countries: [...] } \u2192 open if geo.country does NOT match\n * - { mode: \"predicate\", test: (geo) => boolean }\n */\nconst bannerRouteRules: Record<\n string,\n | { mode: \"always\" }\n | { mode: \"country\"; countries: string[] }\n | { mode: \"notCountry\"; countries: string[] }\n | { mode: \"predicate\"; test: (geo?: any) => boolean }\n> = {\n \"/global\": { mode: \"country\", countries: [\"India\"] },\n \"/\": { mode: \"notCountry\", countries: [\"India\"] },\n};\n\n// Elements\nconst ipBannerMain = '[fynd-navigation=\"ip-banner\"]';\nconst ipBannerInner = '[fynd-navigation=\"ip-banner-inner\"]';\nconst closeIpBanner = '[fynd-navigation=\"ip-banner-close\"]';\n\nconst announcementBar = document.querySelector('[fynd-navigation=\"announcement-bar\"]');\nconst announcementList = document.querySelector('[fynd-navigation=\"announcement-list\"]');\n\n// Global navigation state\nconst navigationData = {\n ipbanner: {\n visibility: false,\n height: { desktop: \"56px\", tablet: \"60px\", mobileLandscape: \"120px\", mobilePortrait: \"120px\" },\n },\n announcementbar: {\n visibility: true,\n height: { desktop: \"40px\", tablet: \"40px\", mobileLandscape: \"40px\", mobilePortrait: \"46px\" },\n },\n default: {\n visibility: true,\n height: { desktop: \"70px\", tablet: \"64px\", mobileLandscape: \"40px\", mobilePortrait: \"150px\" },\n },\n};\n\n// --- Utils -------------------------------------------------------------------\n\nfunction addPx(a: string | number, b: string | number): string {\n const toNumber = (val: string | number): number => {\n if (typeof val === \"number\") return val;\n const num = parseInt(val, 10);\n return isNaN(num) ? 0 : num;\n };\n return `${toNumber(a) + toNumber(b)}px`;\n}\n\nfunction subtractPx(a: string | number, b: string | number): string {\n const toNumber = (val: string | number): number => {\n if (typeof val === \"number\") return val;\n const num = parseInt(val, 10);\n return isNaN(num) ? 0 : num;\n };\n return `${toNumber(a) - toNumber(b)}px`;\n}\n\nconst normalizePath = (p: string) => {\n try {\n const urlPath = p.split(\"?\")[0].split(\"#\")[0];\n if (urlPath === \"/\") return \"/\";\n return urlPath.replace(/\\/+$/, \"\") || \"/\";\n } catch {\n return \"/\";\n }\n};\n\n// Longest-prefix match, so \"/india/offers\" matches \"/india\"\nfunction getMatchingRule(pathname: string) {\n const path = normalizePath(pathname);\n let bestKey = \"\";\n for (const key of Object.keys(bannerRouteRules)) {\n const normKey = normalizePath(key);\n if (path === normKey || path.startsWith(normKey + \"/\")) {\n if (normKey.length > bestKey.length) bestKey = normKey;\n }\n }\n return bestKey ? { key: bestKey, rule: bannerRouteRules[bestKey] } : null;\n}\n\nfunction shouldOpenBannerForPage(pathname: string, geo?: { country?: string }) {\n const match = getMatchingRule(pathname);\n if (!match) return false;\n\n const { rule } = match;\n const visitorCountry = (geo?.country || \"\").toLowerCase();\n\n switch (rule.mode) {\n case \"always\":\n return true;\n case \"country\":\n return rule.countries.some((c) => c.toLowerCase() === visitorCountry);\n case \"notCountry\":\n return !rule.countries.some((c) => c.toLowerCase() === visitorCountry);\n case \"predicate\":\n return !!rule.test?.(geo);\n default:\n return false;\n }\n}\n\n// --- Announcement Bar --------------------------------------------------------\n\nfunction initAnnouncementBar() {\n const swiperEl = document.querySelector<HTMLElement>('[fynd-navigation=\"announcement-swiper\"]');\n\n // Initialize swiper if present\n if (swiperEl && !(swiperEl as any).__swiperInstance) {\n try {\n const Swiper = (window as any).Swiper;\n const swiper = new Swiper(swiperEl, {\n slidesPerView: 1,\n spaceBetween: 0,\n effect: \"fade\",\n fadeEffect: { crossFade: true },\n autoplay: { delay: 3000, disableOnInteraction: false },\n loop: true,\n speed: 1000,\n allowTouchMove: false,\n on: {\n init: function (this: any): void {\n if (this.slides.length <= 1 && this.autoplay && typeof this.autoplay.stop === \"function\") {\n this.autoplay.stop();\n }\n },\n },\n });\n (swiperEl as any).__swiperInstance = swiper;\n } catch (err) {\n console.warn(\"Announcement Swiper init failed:\", err);\n }\n }\n\n // Visibility & cleanup\n if (announcementBar && announcementList && announcementList.children.length > 0) {\n navigationData.announcementbar.visibility = true;\n } else {\n navigationData.announcementbar.visibility = false;\n if (announcementBar && announcementBar.parentNode) {\n if (swiperEl && (swiperEl as any).__swiperInstance) {\n (swiperEl as any).__swiperInstance.destroy(true, true);\n (swiperEl as any).__swiperInstance = undefined;\n }\n announcementBar.parentNode.removeChild(announcementBar);\n }\n }\n}\n\n// --- Desktop Dropdown Positioning -------------------------------------------\n\nfunction initDesktopDropdownMenu() {\n const selector = '[fynd-navigation=\"dropdown-container\"]';\n const el = document.querySelector<HTMLElement>(selector);\n if (!el) {\n console.warn(`initDesktopDropdownMenu: element not found: ${selector}`);\n return;\n }\n\n const screenType = getScreenType?.() ?? \"unknown\";\n\n // Not desktop \u2192 reset transform\n if (screenType !== \"desktop\") {\n el.style.transition = el.style.transition || \"transform 0.3s ease\";\n el.style.transform = \"translateY(0px)\";\n return;\n }\n\n // Compute total stacked height\n let total = navigationData.default.height?.[screenType];\n\n if (navigationData.announcementbar?.visibility) {\n const h = navigationData.announcementbar.height?.[screenType];\n total = addPx(total, h);\n total = subtractPx(total,\"46px\")\n }\n\n if (navigationData.ipbanner?.visibility) {\n // Currently not offsetting desktop for IP banner\n const h = \"0px\";\n total = addPx(total, h);\n total = subtractPx(total,\"46px\")\n }\n\n // Offset dropdown under nav (minus header overlap 46px)\n el.style.transform = `translateY(${total})`;\n}\n\n// --- Dynamic Spacer ----------------------------------------------------------\n\nfunction initNavigationSpacer() {\n const spacer = document.querySelector<HTMLElement>(\n '[fynd-navigation=\"spacer\"][data-wf--navigation-spacer--variant=\"dynamic\"]'\n );\n\n if (!spacer) {\n console.warn(\"initNavigationSpacer: spacer element not found\");\n return;\n }\n\n const toPx = (v?: string | number): number => {\n if (typeof v === \"number\") return v;\n if (typeof v === \"string\") {\n const n = parseFloat(v);\n return Number.isFinite(n) ? n : 0;\n }\n return 0;\n };\n\n const screenType = getScreenType?.() ?? \"desktop\";\n let total = navigationData.default.height?.[screenType];\n\n if (navigationData.announcementbar?.visibility) {\n const h = navigationData.announcementbar.height?.[screenType];\n total = addPx(total, h);\n }\n\n if (navigationData.ipbanner?.visibility) {\n const h = toPx(navigationData.ipbanner.height?.[screenType]);\n total = addPx(total, h);\n }\n\n spacer.style.height = `${total}`;\n}\n\n// --- IP Banner ---------------------------------------------------------------\n\nasync function initIpBanner() {\n const ipClosed = getCookie(\"ipBannerClosed\") === \"true\";\n if (ipClosed) {\n navigationData.ipbanner.visibility = false;\n return;\n }\n\n const geo = await getGeolocationCached();\n const path = window.location.pathname || \"/\";\n const allowByRoute = shouldOpenBannerForPage(path, geo ?? undefined);\n\n const countryReady = await initCountryDetection();\n\n if (allowByRoute && countryReady) {\n openBanner(ipBannerMain, ipBannerInner, navigationData.ipbanner.height.desktop);\n navigationData.ipbanner.visibility = true;\n\n const closeBtn = document.querySelector<HTMLElement>(closeIpBanner);\n if (closeBtn) {\n closeBtn.addEventListener(\"click\", () => {\n closeBanner(ipBannerMain, ipBannerInner);\n setCookie(\"ipBannerClosed\", \"true\", 24);\n navigationData.ipbanner.visibility = false;\n initDesktopDropdownMenu();\n initNavigationSpacer();\n });\n }\n } else {\n navigationData.ipbanner.visibility = false;\n }\n}\n\n// --- Init --------------------------------------------------------------------\n\ndocument.addEventListener(\"DOMContentLoaded\", async () => {\n await initIpBanner();\n initAnnouncementBar();\n initDesktopDropdownMenu();\n initNavigationSpacer();\n});"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Only enable live reload when running on localhost\nif (\n window.location.hostname === \"localhost\" ||\n window.location.hostname === \"127.0.0.1\"\n) {\n new EventSource(`${SERVE_ORIGIN}/esbuild`).addEventListener(\"change\", () =>\n location.reload()\n );\n} else {\n // console.log(\"Live reload disabled: not running on localhost\");\n}\n", "// Define the type for returned geolocation data\n// Remider for adding Fallback: ipinfo.io (HTTPS, requires token)\nexport type GeoData = {\n ip: string;\n country: string;\n region: string;\n city: string;\n latitude: number;\n longitude: number;\n isp: string;\n timezone: string;\n };\n \n // Exported function that can be reused anywhere\n export async function getGeolocation(): Promise<GeoData | null> {\n try {\n const response = await fetch(\"https://ipwho.is/\");\n if (!response.ok) {\n throw new Error(\"Failed to fetch geolocation\");\n }\n \n const data = await response.json();\n \n if (data.success === false) {\n console.error(\"Geolocation lookup failed:\", data.message);\n return null;\n }\n \n return {\n ip: data.ip,\n country: data.country,\n region: data.region,\n city: data.city,\n latitude: data.latitude,\n longitude: data.longitude,\n isp: data.connection?.isp || \"\",\n timezone: data.timezone?.id || \"\"\n };\n } catch (error) {\n console.error(\"Error fetching geolocation:\", error);\n return null;\n }\n }\n\n //used in /src/navigation/initialization.ts for displaying ip banner", "import { GeoData, getGeolocation } from \"./main\";\n\nconst GEO_CACHE_KEY = \"geo:data:v1\";\nconst GEO_COOKIE_KEY = \"geo_country\";\nconst GEO_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\ntype Cached<T> = { data: T; expiresAt: number };\n\n// --- Cookie helpers ---\nfunction setCookie(name: string, value: string, maxAgeSec: number) {\n document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}; Max-Age=${maxAgeSec}; Path=/; SameSite=Lax; Secure`;\n}\n\nfunction getCookie(name: string): string | null {\n const key = `${encodeURIComponent(name)}=`;\n const parts = document.cookie.split(\"; \");\n for (const p of parts) {\n if (p.startsWith(key)) return decodeURIComponent(p.slice(key.length));\n }\n return null;\n}\n\nfunction clearCookie(name: string) {\n document.cookie = `${encodeURIComponent(name)}=; Max-Age=0; Path=/; SameSite=Lax; Secure`;\n}\n\n// --- LocalStorage helpers ---\nfunction readCache<T>(key: string): T | null {\n try {\n const raw = localStorage.getItem(key);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as Cached<T>;\n if (!parsed?.expiresAt || Date.now() > parsed.expiresAt) {\n localStorage.removeItem(key);\n return null;\n }\n return parsed.data;\n } catch {\n localStorage.removeItem(key);\n return null;\n }\n}\n\nfunction writeCache<T>(key: string, data: T, ttlMs: number) {\n const payload: Cached<T> = { data, expiresAt: Date.now() + ttlMs };\n try {\n localStorage.setItem(key, JSON.stringify(payload));\n } catch {\n // ignore quota errors\n }\n}\n\n// --- Public API ---\nexport async function getGeolocationCached(options?: {\n forceRefresh?: boolean;\n}): Promise<GeoData | null> {\n if (typeof window === \"undefined\") return null;\n\n const forceRefresh = options?.forceRefresh ?? false;\n\n if (!forceRefresh) {\n const cached = readCache<GeoData>(GEO_CACHE_KEY);\n if (cached) {\n (window as any).__GEO = cached;\n if (!getCookie(GEO_COOKIE_KEY)) {\n setCookie(GEO_COOKIE_KEY, cached.country ?? \"\", Math.floor(GEO_TTL_MS / 1000));\n }\n return cached;\n }\n }\n\n const fresh = await getGeolocation();\n if (!fresh) return null;\n\n writeCache(GEO_CACHE_KEY, fresh, GEO_TTL_MS);\n setCookie(GEO_COOKIE_KEY, fresh.country ?? \"\", Math.floor(GEO_TTL_MS / 1000));\n (window as any).__GEO = fresh;\n return fresh;\n}\n\nexport function getGeoCountryFromCookie(): string | null {\n return getCookie(GEO_COOKIE_KEY);\n}\n\nexport function clearGeolocationCache() {\n try {\n localStorage.removeItem(GEO_CACHE_KEY);\n } catch {}\n clearCookie(GEO_COOKIE_KEY);\n if (typeof window !== \"undefined\") {\n (window as any).__GEO = undefined;\n }\n}", "// toggleBanner.ts\n// Utility functions to open/close a banner using GSAP with optional target height.\n\nexport function openBanner(\n mainSelector: string,\n innerSelector: string,\n targetHeight: string | number = \"auto\" // default stays \"auto\"\n) {\n const w = (window as any) || {};\n const gsap = w.gsap as any;\n if (!gsap) {\n console.warn(\"GSAP not found on window. Did you include it globally?\");\n return;\n }\n\n const mainEl = document.querySelector<HTMLElement>(mainSelector);\n const innerEl = document.querySelector<HTMLElement>(innerSelector);\n\n if (!mainEl || !innerEl) {\n console.warn(\"openBanner: Element(s) not found for selectors:\", {\n mainSelector,\n innerSelector,\n });\n return;\n }\n\n // Ensure clean start\n gsap.set(mainEl, { height: 0, overflow: \"hidden\" });\n gsap.set(innerEl, { opacity: 0 });\n\n const tl = gsap.timeline();\n\n // Animate main from height: 0 -> targetHeight\n tl.to(mainEl, {\n height: targetHeight,\n duration: 0.5,\n ease: \"power2.out\",\n });\n\n // After 0.2s, fade inner to 1\n tl.to(\n innerEl,\n {\n opacity: 1,\n duration: 0.3,\n ease: \"power1.out\",\n },\n 0.2\n );\n\n return tl;\n}\n\nexport function closeBanner(\n mainSelector: string,\n innerSelector: string,\n targetHeight: string | number = 0 // default collapse fully\n) {\n const w = (window as any) || {};\n const gsap = w.gsap as any;\n if (!gsap) {\n console.warn(\"GSAP not found on window. Did you include it globally?\");\n return;\n }\n\n const mainEl = document.querySelector<HTMLElement>(mainSelector);\n const innerEl = document.querySelector<HTMLElement>(innerSelector);\n\n if (!mainEl || !innerEl) {\n console.warn(\"closeBanner: Element(s) not found for selectors:\", {\n mainSelector,\n innerSelector,\n });\n return;\n }\n\n gsap.set(mainEl, { overflow: \"hidden\" });\n\n const tl = gsap.timeline();\n\n // Fade inner out\n tl.to(innerEl, {\n opacity: 0,\n duration: 0.25,\n ease: \"power1.out\",\n });\n\n // Collapse height to targetHeight (default 0)\n tl.to(\n mainEl,\n {\n height: targetHeight,\n duration: 0.45,\n ease: \"power2.inOut\",\n },\n 0.2\n );\n\n return tl;\n}", "export function setCookie(name: string, value: string, hours: number) {\n const date = new Date();\n date.setTime(date.getTime() + hours * 60 * 60 * 1000);\n document.cookie = `${name}=${value}; expires=${date.toUTCString()}; path=/`;\n }\n \n export function getCookie(name: string): string | null {\n const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));\n return match ? match[2] : null;\n }", "// screen-type.ts\n// Utility to get the current screen type\n// Breakpoints:\n// - Desktop: 992px+\n// - Tablet: 768px\u2013991px\n// - Mobile Landscape: 480px\u2013767px\n// - Mobile Portrait: under 480px\n\nexport type ScreenType = \"desktop\" | \"tablet\" | \"mobileLandscape\" | \"mobilePortrait\";\n\nexport function getScreenType(): ScreenType {\n const width = window.innerWidth;\n\n if (width >= 992) {\n return \"desktop\";\n } else if (width >= 768) {\n return \"tablet\";\n } else if (width >= 480) {\n return \"mobileLandscape\";\n } else {\n return \"mobilePortrait\";\n }\n}", "// geo.ts\nimport { getGeoCountryFromCookie, getGeolocationCached } from \"src/global/geolocation/geolocation-cached\";\nimport { GeoData } from \"src/global/geolocation/main\";\n\n/** Your banner config */\ntype CountryConfig = {\n country: string; // canonical lowercase name\n countryCode: string; // ISO-2 lowercase code (e.g., \"in\")\n url: string; // leading-slash path (e.g., \"/in\")\n tagline: string; // banner text/html\n aliases?: string[]; // optional extra names to match against\n};\n\nexport const COUNTRY_CONFIG: CountryConfig[] = [\n {\n country: \"united arab emirates\",\n aliases: [\"uae\", \"u.a.e\", \"united arab emirates\"],\n countryCode: \"ae\",\n url: \"/ae\",\n tagline: \"You're in the UAE. Welcome!\"\n },\n {\n country: \"saudi arabia\",\n aliases: [\"saudi\", \"ksa\", \"kingdom of saudi arabia\"],\n countryCode: \"sa\",\n url: \"/sa\",\n tagline: \"Hello Saudi Arabia!\"\n },\n {\n country: \"south africa\",\n aliases: [\"rsa\"],\n countryCode: \"za\",\n url: \"/za\",\n tagline: \"Hi South Africa!\"\n },\n {\n country: \"malaysia\",\n countryCode: \"my\",\n url: \"/my\",\n tagline: \"Selamat datang, Malaysia!\"\n },\n {\n country: \"indonesia\",\n aliases: [\"idn\"],\n countryCode: \"id\",\n url: \"/id\",\n tagline: \"Halo Indonesia!\"\n },\n {\n country: \"philippines\",\n aliases: [\"phl\", \"the philippines\"],\n countryCode: \"ph\",\n url: \"/ph\",\n tagline: \"Kumusta, Philippines!\"\n },\n {\n country: \"india\",\n aliases: [\"bharat\"],\n countryCode: \"in\",\n url: \"/in\",\n tagline: \"This country is India. Hi some text\"\n },\n // \uD83D\uDC47 fallback\n {\n country: \"global\",\n aliases: [\"global\", \"rest of world\", \"others\"],\n countryCode: \"global\", // keep lowercase for consistency\n url: \"/global\",\n tagline: \"This is rest of world. Hi some text\"\n }\n];\n\n/** Utility: normalize strings for comparisons */\nfunction norm(s: string | null | undefined): string {\n return (s ?? \"\").trim().toLowerCase();\n}\n\n/** Utility: ensure URL starts with a single leading slash */\nfunction toPath(path: string): string {\n const p = path.trim();\n if (!p) return \"/\";\n return p.startsWith(\"/\") ? p : `/${p}`;\n}\n\n/** Determine user's country as a *string* (might be name or code depending on your geo source) */\nexport async function getUserCountry(): Promise<string | null> {\n if (typeof window === \"undefined\") return null;\n\n // 1) Cookie fast-path\n const cookieCountry = getGeoCountryFromCookie();\n if (cookieCountry) return norm(cookieCountry);\n\n // 2) Cached or network\n const geo: GeoData | null = await getGeolocationCached();\n return norm((geo as any)?.country);\n}\n\n/** Find matching config by country *name* or *ISO-2 code* with aliases */\nfunction findCountryConfig(input: string | null): CountryConfig | null {\n const v = norm(input);\n if (!v) return null;\n\n const byCode = COUNTRY_CONFIG.find(c => norm(c.countryCode) === v);\n if (byCode) return byCode;\n\n const byName = COUNTRY_CONFIG.find(c => norm(c.country) === v);\n if (byName) return byName;\n\n const byAlias = COUNTRY_CONFIG.find(c => (c.aliases ?? []).some(a => norm(a) === v));\n if (byAlias) return byAlias;\n\n return null;\n}\n\n/** Helper to fetch the global config */\nfunction getGlobalConfig(): CountryConfig {\n const g = COUNTRY_CONFIG.find(c => c.country === \"global\");\n if (!g) throw new Error(\"[geo-banner] Global config not found in COUNTRY_CONFIG\");\n return g;\n}\n\nfunction updateBannerLink(countryCode?: string | null): void {\n if (typeof window === \"undefined\") return;\n\n const code = norm(countryCode);\n const conf =\n COUNTRY_CONFIG.find(c => norm(c.countryCode) === code) ||\n getGlobalConfig();\n\n const linkEl = document.querySelector<HTMLAnchorElement>('[fynd-banner-field=\"link\"]');\n if (linkEl) {\n const base = window.location.origin;\n linkEl.href = `${base}${toPath(conf.url)}`;\n }\n}\n\nexport function setSelectValueSafely(selectEl: HTMLSelectElement, desired: string) {\n // 1) resolve config\n const conf =\n findCountryConfig(desired) ??\n COUNTRY_CONFIG.find(c => c.country === \"global\");\n if (!conf) {\n console.warn(\"[geo-banner] No matching config for\", desired);\n return false;\n }\n const desiredCode = conf.countryCode; // assume already normalized/lowercase\n\n // 2) find matching option (normalize both sides)\n const opts = Array.from(selectEl.options);\n const opt = opts.find(o => norm(o.value) === norm(desiredCode));\n if (!opt) {\n console.warn(\"[geo-banner] No matching <option> for\", desiredCode, \"on\", selectEl);\n return false;\n }\n\n // 3) update the <select> itself (more reliable than toggling option.selected)\n const prev = selectEl.value;\n selectEl.value = opt.value;\n\n // if some browsers/frameworks didn\u2019t adopt .value, force selectedIndex too\n if (selectEl.value !== opt.value) {\n selectEl.selectedIndex = opts.indexOf(opt);\n }\n\n // 4) (optional) keep options\u2019 selected flags in sync\n opts.forEach(o => (o.selected = o === opt));\n\n // 5) fire events frameworks listen to\n if (prev !== selectEl.value) {\n selectEl.dispatchEvent(new Event(\"input\", { bubbles: true }));\n selectEl.dispatchEvent(new Event(\"change\", { bubbles: true }));\n }\n\n console.log(\"[geo-banner] Select updated \u2192\", conf.country, \"(\", conf.countryCode, \")\");\n return true;\n}\n\n/** Update the banner content for a given countryCode (lowercase ISO-2) with global fallback */\nexport function updateBannerContent(countryCode?: string | null): void {\n if (typeof window === \"undefined\") return;\n\n const code = norm(countryCode);\n const conf =\n COUNTRY_CONFIG.find(c => norm(c.countryCode) === code) ||\n getGlobalConfig();\n // 1) Set <select fynd-banner-field=\"geoswitch\"> value (robustly)\n const selectEl =\n document.querySelector<HTMLSelectElement>('#geoswitch-select') ||\n document.querySelector<HTMLSelectElement>('[fynd-banner-field=\"geoswitch\"]');\n\n if (selectEl) {\n console.log(`country code is ${conf.countryCode}`)\n setSelectValueSafely(selectEl, conf.countryCode);\n selectEl.value = conf.countryCode; // or \"global\", etc.\n\n selectEl.dispatchEvent(new Event(\"change\", { bubbles: true }));\n } else {\n console.warn('[geo-banner] Select not found: #geoswitch-select / [fynd-banner-field=\"geoswitch\"]');\n }\n\n // // 2) Update banner text (unchanged)\n // const textEl = document.querySelector<HTMLElement>('[fynd-banner-field=\"banner-text\"]');\n // if (textEl) textEl.innerHTML = conf.tagline;\n\n // 3) Update link href (unchanged)\n const linkEl = document.querySelector<HTMLAnchorElement>('[fynd-banner-field=\"link\"]');\n if (linkEl) {\n const base = window.location.origin;\n linkEl.href = `${base}${toPath(conf.url)}`;\n }\n}\n\n/**\n * Main entry: detect country and update banner if it matches one of the configured countries.\n * Always falls back to global if no match is found.\n */\nexport async function initCountryDetection(): Promise<CountryConfig> {\n if (typeof window === \"undefined\") return getGlobalConfig();\n\n if (document.readyState === \"loading\") {\n await new Promise<void>(resolve => {\n document.addEventListener(\"DOMContentLoaded\", () => resolve(), { once: true });\n });\n }\n\n const rawCountry = await getUserCountry();\n const match = findCountryConfig(rawCountry);\n const resolved = match ?? getGlobalConfig();\n\n // Debug visibility\n console.log(\"[geo-banner] rawCountry:\", rawCountry, \"\u2192 resolved:\", resolved.countryCode);\n\n // \u2705 Always update from the resolved config (guarantees global fallback)\n updateBannerContent(resolved.countryCode);\n\n // (If you also attached the select change listener, keep that here)\n const selectEl = document.querySelector<HTMLSelectElement>('[fynd-banner-field=\"geoswitch\"]');\n if (selectEl && !(selectEl as any).__geoHandlerAttached) {\n selectEl.addEventListener(\"change\", (e) => {\n const value = (e.target as HTMLSelectElement).value;\n updateBannerLink(value); // only updates href on change\n });\n (selectEl as any).__geoHandlerAttached = true;\n }\n\n return resolved;\n}", "import { getGeolocationCached } from \"src/global/geolocation/geolocation-cached\";\nimport { closeBanner, openBanner } from \"src/global/animation/toggle-banner\";\nimport { getCookie, setCookie } from \"$utils/cookies\";\nimport { getScreenType } from \"src/global/screen-type\";\nimport { initCountryDetection } from \"./country-detection/main\";\n\n/**\n * Banner rules by route (normalized, no trailing slash).\n * Modes:\n * - { mode: \"always\" }\n * - { mode: \"country\", countries: [...] } \u2192 open if geo.country matches (case-insensitive)\n * - { mode: \"notCountry\", countries: [...] } \u2192 open if geo.country does NOT match\n * - { mode: \"predicate\", test: (geo) => boolean }\n */\nconst bannerRouteRules: Record<\n string,\n | { mode: \"always\" }\n | { mode: \"country\"; countries: string[] }\n | { mode: \"notCountry\"; countries: string[] }\n | { mode: \"predicate\"; test: (geo?: any) => boolean }\n> = {\n \"/global\": { mode: \"country\", countries: [\"India\"] },\n \"/\": { mode: \"notCountry\", countries: [\"India\"] },\n};\n\n// Elements\nconst ipBannerMain = '[fynd-navigation=\"ip-banner\"]';\nconst ipBannerInner = '[fynd-navigation=\"ip-banner-inner\"]';\nconst closeIpBanner = '[fynd-navigation=\"ip-banner-close\"]';\n\nconst announcementBar = document.querySelector('[fynd-navigation=\"announcement-bar\"]');\nconst announcementList = document.querySelector('[fynd-navigation=\"announcement-list\"]');\n\n// Global navigation state\nconst navigationData = {\n ipbanner: {\n visibility: false,\n height: { desktop: \"56px\", tablet: \"60px\", mobileLandscape: \"120px\", mobilePortrait: \"120px\" },\n },\n announcementbar: {\n visibility: true,\n height: { desktop: \"40px\", tablet: \"40px\", mobileLandscape: \"40px\", mobilePortrait: \"46px\" },\n },\n default: {\n visibility: true,\n height: { desktop: \"70px\", tablet: \"64px\", mobileLandscape: \"40px\", mobilePortrait: \"64px\" },\n },\n};\n(window as any).navigationData = navigationData;\n\n// --- Utils -------------------------------------------------------------------\n\nfunction addPx(a: string | number, b: string | number): string {\n const toNumber = (val: string | number): number => {\n if (typeof val === \"number\") return val;\n const num = parseInt(val, 10);\n return isNaN(num) ? 0 : num;\n };\n return `${toNumber(a) + toNumber(b)}px`;\n}\n\nfunction subtractPx(a: string | number, b: string | number): string {\n const toNumber = (val: string | number): number => {\n if (typeof val === \"number\") return val;\n const num = parseInt(val, 10);\n return isNaN(num) ? 0 : num;\n };\n return `${toNumber(a) - toNumber(b)}px`;\n}\n\nconst normalizePath = (p: string) => {\n try {\n const urlPath = p.split(\"?\")[0].split(\"#\")[0];\n if (urlPath === \"/\") return \"/\";\n return urlPath.replace(/\\/+$/, \"\") || \"/\";\n } catch {\n return \"/\";\n }\n};\n\n// Longest-prefix match, so \"/india/offers\" matches \"/india\"\nfunction getMatchingRule(pathname: string) {\n const path = normalizePath(pathname);\n let bestKey = \"\";\n for (const key of Object.keys(bannerRouteRules)) {\n const normKey = normalizePath(key);\n if (path === normKey || path.startsWith(normKey + \"/\")) {\n if (normKey.length > bestKey.length) bestKey = normKey;\n }\n }\n return bestKey ? { key: bestKey, rule: bannerRouteRules[bestKey] } : null;\n}\n\nfunction shouldOpenBannerForPage(pathname: string, geo?: { country?: string }) {\n const match = getMatchingRule(pathname);\n if (!match) return false;\n\n const { rule } = match;\n const visitorCountry = (geo?.country || \"\").toLowerCase();\n\n switch (rule.mode) {\n case \"always\":\n return true;\n case \"country\":\n return rule.countries.some((c) => c.toLowerCase() === visitorCountry);\n case \"notCountry\":\n return !rule.countries.some((c) => c.toLowerCase() === visitorCountry);\n case \"predicate\":\n return !!rule.test?.(geo);\n default:\n return false;\n }\n}\n\n// --- Announcement Bar --------------------------------------------------------\n\nfunction initAnnouncementBar() {\n const swiperEl = document.querySelector<HTMLElement>('[fynd-navigation=\"announcement-swiper\"]');\n\n // Initialize swiper if present\n if (swiperEl && !(swiperEl as any).__swiperInstance) {\n try {\n const Swiper = (window as any).Swiper;\n const swiper = new Swiper(swiperEl, {\n slidesPerView: 1,\n spaceBetween: 0,\n effect: \"fade\",\n fadeEffect: { crossFade: true },\n autoplay: { delay: 3000, disableOnInteraction: false },\n loop: true,\n speed: 1000,\n allowTouchMove: false,\n on: {\n init: function (this: any): void {\n if (this.slides.length <= 1 && this.autoplay && typeof this.autoplay.stop === \"function\") {\n this.autoplay.stop();\n }\n },\n },\n });\n (swiperEl as any).__swiperInstance = swiper;\n } catch (err) {\n console.warn(\"Announcement Swiper init failed:\", err);\n }\n }\n\n // Visibility & cleanup\n if (announcementBar && announcementList && announcementList.children.length > 0) {\n navigationData.announcementbar.visibility = true;\n } else {\n navigationData.announcementbar.visibility = false;\n if (announcementBar && announcementBar.parentNode) {\n if (swiperEl && (swiperEl as any).__swiperInstance) {\n (swiperEl as any).__swiperInstance.destroy(true, true);\n (swiperEl as any).__swiperInstance = undefined;\n }\n announcementBar.parentNode.removeChild(announcementBar);\n }\n }\n}\n\n// --- Desktop Dropdown Positioning -------------------------------------------\n\nfunction initDesktopDropdownMenu() {\n const selector = '[fynd-navigation=\"dropdown-container\"]';\n const el = document.querySelector<HTMLElement>(selector);\n if (!el) {\n console.warn(`initDesktopDropdownMenu: element not found: ${selector}`);\n return;\n }\n\n const screenType = getScreenType?.() ?? \"unknown\";\n\n // Not desktop \u2192 reset transform\n if (screenType !== \"desktop\") {\n el.style.transition = el.style.transition || \"transform 0.3s ease\";\n el.style.transform = \"translateY(0px)\";\n return;\n }\n\n // Compute total stacked height\n let total = navigationData.default.height?.[screenType];\n let subtractFlag = false;\n\n if (navigationData.announcementbar?.visibility) {\n const h = navigationData.announcementbar.height?.[screenType];\n total = addPx(total, h);\n total = subtractPx(total,\"46px\");\n subtractFlag= true;\n }\n\n if (navigationData.ipbanner?.visibility) {\n // Currently not offsetting desktop for IP banner\n const h = \"0px\";\n total = addPx(total, h);\n if(!subtractFlag){\n total = subtractPx(total,\"46px\");\n }\n }\n\n // Offset dropdown under nav (minus header overlap 46px)\n el.style.transform = `translateY(${total})`;\n}\n\n// --- Dynamic Spacer ----------------------------------------------------------\n\nfunction initNavigationSpacer() {\n const spacer = document.querySelector<HTMLElement>(\n '[fynd-navigation=\"spacer\"][data-wf--navigation-spacer--variant=\"dynamic\"]'\n );\n\n if (!spacer) {\n console.warn(\"initNavigationSpacer: spacer element not found\");\n return;\n }\n\n const toPx = (v?: string | number): number => {\n if (typeof v === \"number\") return v;\n if (typeof v === \"string\") {\n const n = parseFloat(v);\n return Number.isFinite(n) ? n : 0;\n }\n return 0;\n };\n\n const screenType = getScreenType?.() ?? \"desktop\";\n let total = navigationData.default.height?.[screenType];\n\n if (navigationData.announcementbar?.visibility) {\n const h = navigationData.announcementbar.height?.[screenType];\n total = addPx(total, h);\n }\n\n if (navigationData.ipbanner?.visibility) {\n const h = toPx(navigationData.ipbanner.height?.[screenType]);\n total = addPx(total, h);\n }\n\n spacer.style.height = `${total}`;\n}\n\n// --- IP Banner ---------------------------------------------------------------\n\nasync function initIpBanner() {\n const ipClosed = getCookie(\"ipBannerClosed\") === \"true\";\n if (ipClosed) {\n navigationData.ipbanner.visibility = false;\n return;\n }\n\n const geo = await getGeolocationCached();\n const path = window.location.pathname || \"/\";\n const allowByRoute = shouldOpenBannerForPage(path, geo ?? undefined);\n\n const countryReady = await initCountryDetection();\n\n if (allowByRoute && countryReady) {\n openBanner(ipBannerMain, ipBannerInner, navigationData.ipbanner.height.desktop);\n navigationData.ipbanner.visibility = true;\n\n const closeBtn = document.querySelector<HTMLElement>(closeIpBanner);\n if (closeBtn) {\n closeBtn.addEventListener(\"click\", () => {\n closeBanner(ipBannerMain, ipBannerInner);\n setCookie(\"ipBannerClosed\", \"true\", 24);\n navigationData.ipbanner.visibility = false;\n initDesktopDropdownMenu();\n initNavigationSpacer();\n });\n }\n } else {\n navigationData.ipbanner.visibility = false;\n }\n}\n\n// --- Init --------------------------------------------------------------------\n\ndocument.addEventListener(\"DOMContentLoaded\", async () => {\n await initIpBanner();\n initAnnouncementBar();\n initDesktopDropdownMenu();\n initNavigationSpacer();\n});"],
5
+ "mappings": "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",
6
6
  "names": ["setCookie", "getCookie", "getCookie", "setCookie"]
7
7
  }
@@ -1 +1 @@
1
- "use strict";(()=>{var g=n=>{let t=n.startsWith("/")?n:`/${n}`;return t!=="/"&&t.endsWith("/")?t.slice(0,-1):t},A=n=>{let t=new URLSearchParams(window.location.search).get(n);return t?t.trim():null},P=n=>{let t=n.adUTMCampaign??n.adUTMCampagin;if(!t)return!0;let e=Array.isArray(t)?t.map(r=>r.toLowerCase()):[t.toLowerCase()],i=A("utm_campaign")?.toLowerCase()??null;return!!i&&e.includes(i)},L=n=>{let t=g(window.location.pathname);for(let e of n){let i=g(e.adPageSlug);if((t===i||t.startsWith(i+"/"))&&P(e))return e}return null},M=(n,t)=>`fynd_website_ad_${n}.${t}`,w=n=>{let t=n.closest("form");return t&&(t.getAttribute("data-name")||t.getAttribute("name")||t.id)||null},p=n=>{if(window.__adsTrackingInitialized)return;let t=L(n);if(!t)return;window.__adsTrackingInitialized=!0;let e=(i,r)=>{let o=M(t.adEventExtension,i);window.trackEvent?.(o,r)};document.addEventListener("DOMContentLoaded",()=>{let i=document.querySelectorAll('[data-ph="sign-up"]'),r=document.querySelectorAll('[data-ph="sign-in"]'),o=document.querySelectorAll('[data-ph="book-a-demo"]');i.forEach(s=>s.addEventListener("click",()=>e("sign_up.clicked"))),r.forEach(s=>s.addEventListener("click",()=>e("sign_in.clicked"))),o.forEach(s=>s.addEventListener("click",()=>e("book_a_demo.clicked")));let d=document.querySelectorAll("[ph-form-field]"),f=new Set,a=function(){let s=w(this)||"unknown-form";f.has(s)||(f.add(s),e("form.started"))};d.forEach(s=>{let m=s.tagName.toLowerCase(),y=s.type?.toLowerCase();m==="button"||m==="input"&&y==="submit"||s.addEventListener("focus",a),m==="button"||m==="input"&&y==="submit"?s.addEventListener("click",a):m==="select"?s.addEventListener("change",a):s.addEventListener("input",a)}),document.querySelectorAll('[type="submit"]').forEach(s=>{s.addEventListener("click",function(){let m=w(this);setTimeout(()=>{window.validationPassed===!0&&e("form.submitted",m?{submitted_form:m}:{})},10)})})})};var b="2741377816069290";function S(){typeof window>"u"||window.fbq||function(n,t,e,i,r,o,d){n.fbq||(r=n.fbq=function(){r.callMethod?r.callMethod.apply(r,arguments):r.queue.push(arguments)},n._fbq||(n._fbq=r),r.push=r,r.loaded=!0,r.version="2.0",r.queue=[],o=t.createElement(e),o.async=!0,o.src="https://connect.facebook.net/en_US/fbevents.js",d=t.getElementsByTagName(e)[0],d.parentNode.insertBefore(o,d))}(window,document,"script",void 0)}function v(){try{let n=null;if(typeof window.getUserJourney=="function"&&(n=window.getUserJourney()),!n){let i=sessionStorage.getItem("userJourney");i&&(n=JSON.parse(i))}let t={},e=n?.formDetails;return e?.email&&(t.email=e.email),e?.phone&&(t.phone=e.phone),e?.firstName&&(t.first_name=e.firstName),e?.lastName&&(t.last_name=e.lastName),e?.city&&(t.city=e.city),e?.state&&(t.state=e.state),e?.zip&&(t.zip=e.zip),n?.country&&(t.country=n.country),n?.userId&&(t.external_id=String(n.userId)),Object.keys(t).forEach(i=>{let r=i;t[r]||delete t[r]}),Object.keys(t).length?t:null}catch{return null}}function D(n){if(!n)return null;let t={};return n["fynd_website.form_email"]&&(t.email=n["fynd_website.form_email"]),n["fynd_website.form_phone"]&&(t.phone=n["fynd_website.form_phone"]),n["fynd_website.form_first_name"]&&(t.first_name=n["fynd_website.form_first_name"]),n["fynd_website.form_last_name"]&&(t.last_name=n["fynd_website.form_last_name"]),n.city&&(t.city=n.city),n.state&&(t.state=n.state),n.zip&&(t.zip=n.zip),n.country&&(t.country=n.country),n.external_id&&(t.external_id=n.external_id),Object.keys(t).forEach(e=>{let i=e;t[i]||delete t[i]}),Object.keys(t).length?t:null}function C(n="evt"){return`${n}_${Date.now()}_${Math.random().toString(36).slice(2)}`}function l(...n){window.fbq&&window.fbq(...n)}function U(n,t){let e=t||{},i=D(e)||v();switch(n){case"fynd_website.form.submitted":{let r=e.event_id||C("lead"),o=e.submitted_form||e["fynd_website.form_name"]||"unknown_form";return{type:"track",name:"Lead",params:{form_id:e["fynd_website.form_id"]||void 0,form_name:o,value:0,currency:"INR"},options:{eventID:r},userData:i}}case"fynd_website.sign_up.clicked":return{type:"trackCustom",name:"SignUpClick",params:{},userData:i};case"fynd_website.sign_in.clicked":return{type:"trackCustom",name:"SignInClick",params:{},userData:i};case"fynd_website.book_a_demo.clicked":return{type:"trackCustom",name:"BookDemoClick",params:{source_page:e?.["fynd_website.source_page"]},userData:i};case"fynd_website.form.started":return{type:"trackCustom",name:"FormStarted",params:{form_id:e?.["fynd_website.form_id"]||void 0,form_name:e?.["fynd_website.form_name"]||void 0},userData:i};case"fynd_website.page.loaded":return{type:"track",name:"PageView",params:{},userData:i};default:return null}}function k(n={}){let{enableAdvancedMatching:t=!0,enableSpaPageViews:e=!0,hasConsent:i}=n;S();let r=t?v():null;if(i&&!i()){let d=window.setInterval(()=>{i()&&(window.clearInterval(d),l("init",b,r||{}),h(e))},250)}else l("init",b,r||{}),h(e);let o=window.trackEvent;window.trackEvent=function(d,f){try{if(typeof o=="function"&&o.call(window,d,f),i&&!i())return;let a=U(d,f);if(!a)return;a.type==="track"?a.options?.eventID?l("track",a.name,a.params||{},{eventID:a.options.eventID}):l("track",a.name,a.params||{}):l("trackCustom",a.name,a.params||{})}catch(a){console.warn("Meta tracking error:",a)}}}function h(n){if(l("track","PageView"),n){let r=function(){setTimeout(()=>l("track","PageView"),0)};var t=r;let e=history.pushState,i=history.replaceState;history.pushState=function(...o){let d=e.apply(this,o);return r(),d},history.replaceState=function(...o){let d=i.apply(this,o);return r(),d},window.addEventListener("popstate",r)}}var T=()=>{let n={};try{let t=null;if(typeof window.getUserJourney=="function"&&(t=window.getUserJourney()),!t){let e=sessionStorage.getItem("userJourney");e&&(t=JSON.parse(e))}if(t?.formDetails){let e=t.formDetails;e.formId&&(n.form_id=e.formId),e.formName&&(n.form_name=e.formName),e.firstName&&(n.form_first_name=e.firstName),e.lastName&&(n.form_last_name=e.lastName),e.email&&(n.form_email=e.email),e.phone&&(n.form_phone=e.phone)}if(t?.aiData){let e=t.aiData;e.context&&(n.aidata_context=e.context),e.platform&&(n.aidata_platform=e.platform),e.type&&(n.aidata_type=e.type),e.detectionMethod&&(n.aidata_detection=e.detectionMethod)}}catch(t){console.warn("Error getting user journey data for GA tracking:",t)}return n},_=()=>{let t={"fynd_website.source_page":window.location.pathname,"fynd_website.product":"fynd.com website","fynd_website.device_type":"Unknown","fynd_website.utm_source":new URLSearchParams(window.location.search).get("utm_source")||"","fynd_website.utm_medium":new URLSearchParams(window.location.search).get("utm_medium")||"","fynd_website.utm_campaign":new URLSearchParams(window.location.search).get("utm_campaign")||"","fynd_website.referrer":document.referrer};try{let e=null;if(typeof window.getUserJourney=="function"&&(e=window.getUserJourney()),!e){let i=sessionStorage.getItem("userJourney");i&&(e=JSON.parse(i))}if(e){if(t["fynd_website.journey_touchpoints"]=e.userJourney||e,e.formDetails){let i=e.formDetails;i.formId&&(t["fynd_website.form_id"]=i.formId),i.formName&&(t["fynd_website.form_name"]=i.formName),i.firstName&&(t["fynd_website.form_first_name"]=i.firstName),i.lastName&&(t["fynd_website.form_last_name"]=i.lastName),i.email&&(t["fynd_website.form_email"]=i.email),i.phone&&(t["fynd_website.form_phone"]=i.phone)}if(e.userJourney?.length>0){t["fynd_website.journey_total_pages"]=e.userJourney.length,t["fynd_website.journey_touchpoints_count"]=e.userJourney.length,t["fynd_website.journey_first_page"]=e.userJourney[0].page,t["fynd_website.journey_current_page"]=e.userJourney[e.userJourney.length-1].page;let i=new Date(e.userJourney[0].time),r=new Date(e.userJourney[e.userJourney.length-1].time);t["fynd_website.journey_session_duration"]=Math.floor((r.getTime()-i.getTime())/1e3),t["fynd_website.journey_entry_time"]=e.userJourney[0].time,t["fynd_website.journey_exit_time"]=e.userJourney[e.userJourney.length-1].time}if(e.deviceCategory&&(t["fynd_website.device_type"]=e.deviceCategory),e.browser&&(t["fynd_website.journey_browser"]=e.browser),e.device&&(t["fynd_website.journey_device"]=e.device),e.origin&&(t["fynd_website.journey_origin"]=e.origin),e.utmPath&&(t["fynd_website.journey_utm_path"]=e.utmPath),e.scrollDepth&&(t["fynd_website.journey_scroll_depth"]=e.scrollDepth),e.aiData){let i=e.aiData;i.context&&(t["fynd_website.aidata_context"]=i.context),i.platform&&(t["fynd_website.aidata_platform"]=i.platform),i.type&&(t["fynd_website.aidata_type"]=i.type),i.detectionMethod&&(t["fynd_website.aidata_detection"]=i.detectionMethod)}}}catch(e){console.warn("Error getting user journey data for tracking:",e)}if(t["fynd_website.device_type"]==="Unknown"){let e=navigator.userAgent;/iPad/.test(e)||/Android/.test(e)&&!/Mobile/.test(e)||/Tablet/.test(e)?t["fynd_website.device_type"]="Tablet":/Mobile|iPhone|Android|BlackBerry|Opera Mini|IEMobile|WPDesktop/.test(e)?t["fynd_website.device_type"]="Mobile":t["fynd_website.device_type"]="Desktop"}return t},j=(n,t,e)=>{if(window.dataLayer){let i={event:n,event_category:"form_interaction",event_label:n,...t};e?.submitted_form&&(i.submitted_form=e.submitted_form),window.dataLayer.push(i)}else console.warn("dataLayer not available for GA tracking")},u=(n,t)=>{try{let e=_(),i=t?{...e,...t}:e;window.posthog&&window.posthog.capture(n,i);let r=T(),o=r.aidata_context||r.aidata_platform||r.aidata_type||r.aidata_detection;(n.includes("form")||Object.keys(r).length>0||t?.submitted_form||!!o)&&j(n,r,t)}catch(e){console.error("Error tracking event:",e)}},E=n=>{let t=n.closest("form");return t&&(t.getAttribute("data-name")||t.getAttribute("name")||t.id)||null};document.addEventListener("DOMContentLoaded",()=>{let n=_();window.posthog&&window.posthog.capture("$pageview",n)});window.addEventListener("load",()=>{u("fynd_website.page.loaded")});document.addEventListener("DOMContentLoaded",()=>{let n=document.querySelectorAll('[data-ph="sign-up"]'),t=document.querySelectorAll('[data-ph="sign-in"]'),e=document.querySelectorAll('[href="#footer-form"]'),i=document.querySelectorAll('[data-ph="book-a-demo"]');document.querySelectorAll('[type="submit"]').forEach(a=>{a.addEventListener("click",function(){let c=E(this);setTimeout(()=>{window.validationPassed===!0&&u("fynd_website.form.submitted",c?{submitted_form:c}:{})},10)})}),n.forEach(a=>{a.addEventListener("click",()=>u("fynd_website.sign_up.clicked"))}),t.forEach(a=>{a.addEventListener("click",()=>u("fynd_website.sign_in.clicked"))}),e.forEach(a=>{a.addEventListener("click",()=>u("fynd_website.scroll_to_form.clicked"))}),i.forEach(a=>{a.addEventListener("click",()=>u("fynd_website.book_a_demo.clicked"))});let o=document.querySelectorAll("[ph-form-field]"),d=new Set,f=function(){let c=E(this)||"unknown-form";d.has(c)||(d.add(c),u("fynd_website.form.started"))};o.forEach(a=>{let c=a.tagName.toLowerCase(),s=a.type?.toLowerCase();c==="button"||c==="input"&&s==="submit"||a.addEventListener("focus",f),c==="button"||c==="input"&&s==="submit"?a.addEventListener("click",f):c==="select"?a.addEventListener("change",f):a.addEventListener("input",f)})});window.getPosthogTrackingProperties=_;window.trackEvent=u;window.getGaTrackingProperties=T;var I=[{adPageSlug:"/solutions/transport-management-system",adEventExtension:"tms",adUTMCampaign:"tms"}];p(I);k({enableAdvancedMatching:!0,enableSpaPageViews:!0,hasConsent:()=>window.__ad_consent==="granted"||!0});})();
1
+ "use strict";(()=>{var v=n=>{let t=new URLSearchParams(window.location.search).get(n);return t?t.trim():null},E=()=>{let n=v("utm_medium")?.toLowerCase();return n==="cpc"||n==="ads"},T="fynd_website_ad.",P=n=>`${T}${n}`,y=n=>{let t=n.closest("form");return t&&(t.getAttribute("data-name")||t.getAttribute("name")||t.id)||null},_=()=>{if(window.__adsTrackingInitializedGeneral||!E())return;window.__adsTrackingInitializedGeneral=!0;let n={"fynd_website.current_page":window.location.pathname},t=(e,i)=>{let r=P(e);window.trackEvent?.(r,{...n,...i||{}})};document.addEventListener("DOMContentLoaded",()=>{document.querySelectorAll('[data-ph="sign-up"]').forEach(a=>a.addEventListener("click",()=>t("sign_up.clicked"))),document.querySelectorAll('[data-ph="sign-in"]').forEach(a=>a.addEventListener("click",()=>t("sign_in.clicked"))),document.querySelectorAll('[data-ph="book-a-demo"]').forEach(a=>a.addEventListener("click",()=>t("book_a_demo.clicked")));let e=document.querySelectorAll("[ph-form-field]"),i=new Set,r=function(){let a=y(this)||"unknown-form";i.has(a)||(i.add(a),t("form.started",{started_form:a}))};e.forEach(a=>{let s=a.tagName.toLowerCase(),d=a.type?.toLowerCase();s==="button"||s==="input"&&d==="submit"||a.addEventListener("focus",r),s==="button"||s==="input"&&d==="submit"?a.addEventListener("click",r):s==="select"?a.addEventListener("change",r):a.addEventListener("input",r)}),document.querySelectorAll('[type="submit"]').forEach(a=>{a.addEventListener("click",function(){let s=y(this);setTimeout(()=>{window.validationPassed===!0&&t("form.submitted",s?{submitted_form:s}:{})},10)})})})};var g="2741377816069290";function L(){typeof window>"u"||window.fbq||function(n,t,e,i,r,a,s){n.fbq||(r=n.fbq=function(){r.callMethod?r.callMethod.apply(r,arguments):r.queue.push(arguments)},n._fbq||(n._fbq=r),r.push=r,r.loaded=!0,r.version="2.0",r.queue=[],a=t.createElement(e),a.async=!0,a.src="https://connect.facebook.net/en_US/fbevents.js",s=t.getElementsByTagName(e)[0],s.parentNode.insertBefore(a,s))}(window,document,"script",void 0)}function p(){try{let n=null;if(typeof window.getUserJourney=="function"&&(n=window.getUserJourney()),!n){let i=sessionStorage.getItem("userJourney");i&&(n=JSON.parse(i))}let t={},e=n?.formDetails;return e?.email&&(t.email=e.email),e?.phone&&(t.phone=e.phone),e?.firstName&&(t.first_name=e.firstName),e?.lastName&&(t.last_name=e.lastName),e?.city&&(t.city=e.city),e?.state&&(t.state=e.state),e?.zip&&(t.zip=e.zip),n?.country&&(t.country=n.country),n?.userId&&(t.external_id=String(n.userId)),Object.keys(t).forEach(i=>{let r=i;t[r]||delete t[r]}),Object.keys(t).length?t:null}catch{return null}}function A(n){if(!n)return null;let t={};return n["fynd_website.form_email"]&&(t.email=n["fynd_website.form_email"]),n["fynd_website.form_phone"]&&(t.phone=n["fynd_website.form_phone"]),n["fynd_website.form_first_name"]&&(t.first_name=n["fynd_website.form_first_name"]),n["fynd_website.form_last_name"]&&(t.last_name=n["fynd_website.form_last_name"]),n.city&&(t.city=n.city),n.state&&(t.state=n.state),n.zip&&(t.zip=n.zip),n.country&&(t.country=n.country),n.external_id&&(t.external_id=n.external_id),Object.keys(t).forEach(e=>{let i=e;t[i]||delete t[i]}),Object.keys(t).length?t:null}function M(n="evt"){return`${n}_${Date.now()}_${Math.random().toString(36).slice(2)}`}function m(...n){window.fbq&&window.fbq(...n)}function S(n,t){let e=t||{},i=A(e)||p();switch(n){case"fynd_website.form.submitted":{let r=e.event_id||M("lead"),a=e.submitted_form||e["fynd_website.form_name"]||"unknown_form";return{type:"track",name:"Lead",params:{form_id:e["fynd_website.form_id"]||void 0,form_name:a,value:0,currency:"INR"},options:{eventID:r},userData:i}}case"fynd_website.sign_up.clicked":return{type:"trackCustom",name:"SignUpClick",params:{},userData:i};case"fynd_website.sign_in.clicked":return{type:"trackCustom",name:"SignInClick",params:{},userData:i};case"fynd_website.book_a_demo.clicked":return{type:"trackCustom",name:"BookDemoClick",params:{source_page:e?.["fynd_website.source_page"]},userData:i};case"fynd_website.form.started":return{type:"trackCustom",name:"FormStarted",params:{form_id:e?.["fynd_website.form_id"]||void 0,form_name:e?.["fynd_website.form_name"]||void 0},userData:i};case"fynd_website.page.loaded":return{type:"track",name:"PageView",params:{},userData:i};default:return null}}function b(n={}){let{enableAdvancedMatching:t=!0,enableSpaPageViews:e=!0,hasConsent:i}=n;L();let r=t?p():null;if(i&&!i()){let s=window.setInterval(()=>{i()&&(window.clearInterval(s),m("init",g,r||{}),w(e))},250)}else m("init",g,r||{}),w(e);let a=window.trackEvent;window.trackEvent=function(s,d){try{if(typeof a=="function"&&a.call(window,s,d),i&&!i())return;let o=S(s,d);if(!o)return;o.type==="track"?o.options?.eventID?m("track",o.name,o.params||{},{eventID:o.options.eventID}):m("track",o.name,o.params||{}):m("trackCustom",o.name,o.params||{})}catch(o){console.warn("Meta tracking error:",o)}}}function w(n){if(m("track","PageView"),n){let r=function(){setTimeout(()=>m("track","PageView"),0)};var t=r;let e=history.pushState,i=history.replaceState;history.pushState=function(...a){let s=e.apply(this,a);return r(),s},history.replaceState=function(...a){let s=i.apply(this,a);return r(),s},window.addEventListener("popstate",r)}}var k=()=>{let n={};try{let t=null;if(typeof window.getUserJourney=="function"&&(t=window.getUserJourney()),!t){let e=sessionStorage.getItem("userJourney");e&&(t=JSON.parse(e))}if(t?.formDetails){let e=t.formDetails;e.formId&&(n.form_id=e.formId),e.formName&&(n.form_name=e.formName),e.firstName&&(n.form_first_name=e.firstName),e.lastName&&(n.form_last_name=e.lastName),e.email&&(n.form_email=e.email),e.phone&&(n.form_phone=e.phone)}if(t?.aiData){let e=t.aiData;e.context&&(n.aidata_context=e.context),e.platform&&(n.aidata_platform=e.platform),e.type&&(n.aidata_type=e.type),e.detectionMethod&&(n.aidata_detection=e.detectionMethod)}}catch(t){console.warn("Error getting user journey data for GA tracking:",t)}return n},l=()=>{let t={"fynd_website.source_page":window.location.pathname,"fynd_website.product":"fynd.com website","fynd_website.device_type":"Unknown","fynd_website.utm_source":new URLSearchParams(window.location.search).get("utm_source")||"","fynd_website.utm_medium":new URLSearchParams(window.location.search).get("utm_medium")||"","fynd_website.utm_campaign":new URLSearchParams(window.location.search).get("utm_campaign")||"","fynd_website.referrer":document.referrer};try{let e=null;if(typeof window.getUserJourney=="function"&&(e=window.getUserJourney()),!e){let i=sessionStorage.getItem("userJourney");i&&(e=JSON.parse(i))}if(e){if(t["fynd_website.journey_touchpoints"]=e.userJourney||e,e.formDetails){let i=e.formDetails;i.formId&&(t["fynd_website.form_id"]=i.formId),i.formName&&(t["fynd_website.form_name"]=i.formName),i.firstName&&(t["fynd_website.form_first_name"]=i.firstName),i.lastName&&(t["fynd_website.form_last_name"]=i.lastName),i.email&&(t["fynd_website.form_email"]=i.email),i.phone&&(t["fynd_website.form_phone"]=i.phone)}if(e.userJourney?.length>0){t["fynd_website.journey_total_pages"]=e.userJourney.length,t["fynd_website.journey_touchpoints_count"]=e.userJourney.length,t["fynd_website.journey_first_page"]=e.userJourney[0].page,t["fynd_website.journey_current_page"]=e.userJourney[e.userJourney.length-1].page;let i=new Date(e.userJourney[0].time),r=new Date(e.userJourney[e.userJourney.length-1].time);t["fynd_website.journey_session_duration"]=Math.floor((r.getTime()-i.getTime())/1e3),t["fynd_website.journey_entry_time"]=e.userJourney[0].time,t["fynd_website.journey_exit_time"]=e.userJourney[e.userJourney.length-1].time}if(e.deviceCategory&&(t["fynd_website.device_type"]=e.deviceCategory),e.browser&&(t["fynd_website.journey_browser"]=e.browser),e.device&&(t["fynd_website.journey_device"]=e.device),e.origin&&(t["fynd_website.journey_origin"]=e.origin),e.utmPath&&(t["fynd_website.journey_utm_path"]=e.utmPath),e.scrollDepth&&(t["fynd_website.journey_scroll_depth"]=e.scrollDepth),e.aiData){let i=e.aiData;i.context&&(t["fynd_website.aidata_context"]=i.context),i.platform&&(t["fynd_website.aidata_platform"]=i.platform),i.type&&(t["fynd_website.aidata_type"]=i.type),i.detectionMethod&&(t["fynd_website.aidata_detection"]=i.detectionMethod)}}}catch(e){console.warn("Error getting user journey data for tracking:",e)}if(t["fynd_website.device_type"]==="Unknown"){let e=navigator.userAgent;/iPad/.test(e)||/Android/.test(e)&&!/Mobile/.test(e)||/Tablet/.test(e)?t["fynd_website.device_type"]="Tablet":/Mobile|iPhone|Android|BlackBerry|Opera Mini|IEMobile|WPDesktop/.test(e)?t["fynd_website.device_type"]="Mobile":t["fynd_website.device_type"]="Desktop"}return t},D=(n,t,e)=>{if(window.dataLayer){let i={event:n,event_category:"form_interaction",event_label:n,...t};e?.submitted_form&&(i.submitted_form=e.submitted_form),window.dataLayer.push(i)}else console.warn("dataLayer not available for GA tracking")},f=(n,t)=>{try{let e=l(),i=t?{...e,...t}:e;window.posthog&&window.posthog.capture(n,i);let r=k(),a=r.aidata_context||r.aidata_platform||r.aidata_type||r.aidata_detection;(n.includes("form")||Object.keys(r).length>0||t?.submitted_form||!!a)&&D(n,r,t)}catch(e){console.error("Error tracking event:",e)}},h=n=>{let t=n.closest("form");return t&&(t.getAttribute("data-name")||t.getAttribute("name")||t.id)||null};document.addEventListener("DOMContentLoaded",()=>{let n=l();window.posthog&&window.posthog.capture("$pageview",n)});window.addEventListener("load",()=>{f("fynd_website.page.loaded")});document.addEventListener("DOMContentLoaded",()=>{let n=document.querySelectorAll('[data-ph="sign-up"]'),t=document.querySelectorAll('[data-ph="sign-in"]'),e=document.querySelectorAll('[href="#footer-form"]'),i=document.querySelectorAll('[data-ph="book-a-demo"]');document.querySelectorAll('[type="submit"]').forEach(o=>{o.addEventListener("click",function(){let c=h(this);setTimeout(()=>{window.validationPassed===!0&&f("fynd_website.form.submitted",c?{submitted_form:c}:{})},10)})}),n.forEach(o=>{o.addEventListener("click",()=>f("fynd_website.sign_up.clicked"))}),t.forEach(o=>{o.addEventListener("click",()=>f("fynd_website.sign_in.clicked"))}),e.forEach(o=>{o.addEventListener("click",()=>f("fynd_website.scroll_to_form.clicked"))}),i.forEach(o=>{o.addEventListener("click",()=>f("fynd_website.book_a_demo.clicked"))});let a=document.querySelectorAll("[ph-form-field]"),s=new Set,d=function(){let c=h(this)||"unknown-form";s.has(c)||(s.add(c),f("fynd_website.form.started"))};a.forEach(o=>{let c=o.tagName.toLowerCase(),u=o.type?.toLowerCase();c==="button"||c==="input"&&u==="submit"||o.addEventListener("focus",d),c==="button"||c==="input"&&u==="submit"?o.addEventListener("click",d):c==="select"?o.addEventListener("change",d):o.addEventListener("input",d)})});window.getPosthogTrackingProperties=l;window.trackEvent=f;window.getGaTrackingProperties=k;_();b({enableAdvancedMatching:!0,enableSpaPageViews:!0,hasConsent:()=>window.__ad_consent==="granted"||!0});})();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../bin/live-reload.js", "../../src/posthog-and-ga/main.ts"],
4
- "sourcesContent": ["// Only enable live reload when running on localhost\nif (\n window.location.hostname === \"localhost\" ||\n window.location.hostname === \"127.0.0.1\"\n) {\n new EventSource(`${SERVE_ORIGIN}/esbuild`).addEventListener(\"change\", () =>\n location.reload()\n );\n} else {\n // console.log(\"Live reload disabled: not running on localhost\");\n}\n", "// trackingIntegration.ts - PostHog tracking with user journey integration\nimport { FormDetails, UserJourney } from '../utils/types/user-journey';\n\n// TypeScript interface for GTM dataLayer events\ninterface GTMEvent {\n event: string;\n event_category: string;\n event_label: string;\n form_id?: string;\n form_name?: string;\n form_first_name?: string;\n form_last_name?: string;\n form_email?: string;\n form_phone?: string;\n submitted_form?: string;\n [key: string]: any; // Allow additional properties\n}\n\n// GA tracking properties interface (form-related and AI data)\ninterface GATrackingProperties {\n form_id?: string;\n form_name?: string;\n form_first_name?: string;\n form_last_name?: string;\n form_email?: string;\n form_phone?: string;\n submitted_form?: string;\n // AI data fields\n aidata_context?: string;\n aidata_platform?: string;\n aidata_type?: string;\n aidata_detection?: string;\n}\n\n// Define tracking properties interface\ninterface TrackingProperties {\n 'fynd_website.source_page': string;\n 'fynd_website.product': string;\n 'fynd_website.device_type': string;\n 'fynd_website.utm_source': string;\n 'fynd_website.utm_medium': string;\n 'fynd_website.utm_campaign': string;\n 'fynd_website.referrer': string;\n // Form details from user journey\n 'fynd_website.form_id'?: string;\n 'fynd_website.form_name'?: string;\n 'fynd_website.form_first_name'?: string;\n 'fynd_website.form_last_name'?: string;\n 'fynd_website.form_email'?: string;\n 'fynd_website.form_phone'?: string;\n // User journey details\n 'fynd_website.journey_total_pages'?: number;\n 'fynd_website.journey_session_duration'?: number;\n 'fynd_website.journey_first_page'?: string;\n 'fynd_website.journey_current_page'?: string;\n 'fynd_website.journey_device'?: string;\n 'fynd_website.journey_browser'?: string;\n 'fynd_website.journey_device_name'?: string;\n 'fynd_website.journey_origin'?: string;\n 'fynd_website.journey_touchpoints'?: any; // Array of touchpoints from userJourney field\n 'fynd_website.journey_touchpoints_count'?: number;\n 'fynd_website.journey_utm_path'?: string;\n 'fynd_website.journey_entry_time'?: string;\n 'fynd_website.journey_exit_time'?: string;\n 'fynd_website.journey_scroll_depth'?: number;\n // AI data fields\n 'fynd_website.aidata_context'?: string;\n 'fynd_website.aidata_platform'?: string;\n 'fynd_website.aidata_type'?: string;\n 'fynd_website.aidata_detection'?: string;\n // Additional event-specific properties\n submitted_form?: string;\n field_type?: string;\n field_name?: string;\n [key: string]: any; // Allow additional properties\n}\n\ndeclare global {\n interface Window {\n trackEvent: (eventName: string, properties?: any) => void;\n getPosthogTrackingProperties: () => TrackingProperties;\n getGaTrackingProperties: () => GATrackingProperties;\n validationPassed?: boolean;\n getUserJourney: () => UserJourney | null;\n dataLayer?: GTMEvent[];\n }\n}\n\n// GA tracking properties function (form-related data only)\nconst getGaTrackingProperties = (): GATrackingProperties => {\n const gaProperties: GATrackingProperties = {};\n\n // Get user journey data if available\n try {\n // Try to get from getUserJourney function first\n let journey = null;\n if (typeof (window as any).getUserJourney === 'function') {\n journey = (window as any).getUserJourney();\n }\n\n // If not available from function, try to get directly from sessionStorage\n if (!journey) {\n const storedData = sessionStorage.getItem('userJourney');\n if (storedData) {\n journey = JSON.parse(storedData);\n }\n }\n\n if (journey && journey.formDetails) {\n const formDetails: FormDetails = journey.formDetails;\n\n // Only add form properties if they have values\n if (formDetails.formId) {\n gaProperties.form_id = formDetails.formId;\n }\n if (formDetails.formName) {\n gaProperties.form_name = formDetails.formName;\n }\n if (formDetails.firstName) {\n gaProperties.form_first_name = formDetails.firstName;\n }\n if (formDetails.lastName) {\n gaProperties.form_last_name = formDetails.lastName;\n }\n if (formDetails.email) {\n gaProperties.form_email = formDetails.email;\n }\n if (formDetails.phone) {\n gaProperties.form_phone = formDetails.phone;\n }\n }\n\n // Add AI data if available\n if (journey && journey.aiData) {\n const aiData = journey.aiData;\n \n if (aiData.context) {\n gaProperties.aidata_context = aiData.context;\n }\n if (aiData.platform) {\n gaProperties.aidata_platform = aiData.platform;\n }\n if (aiData.type) {\n gaProperties.aidata_type = aiData.type;\n }\n if (aiData.detectionMethod) {\n gaProperties.aidata_detection = aiData.detectionMethod;\n }\n }\n } catch (error) {\n console.warn('Error getting user journey data for GA tracking:', error);\n }\n\n return gaProperties;\n};\n\n// Enhanced tracking properties function\nconst getPosthogTrackingProperties = (): TrackingProperties => {\n const pathname: string = window.location.pathname;\n\n // Base tracking properties\n const baseProperties: TrackingProperties = {\n 'fynd_website.source_page': pathname,\n 'fynd_website.product': \"fynd.com website\",\n 'fynd_website.device_type': \"Unknown\", // Will be updated from user journey\n 'fynd_website.utm_source':\n new URLSearchParams(window.location.search).get(\"utm_source\") || \"\",\n 'fynd_website.utm_medium':\n new URLSearchParams(window.location.search).get(\"utm_medium\") || \"\",\n 'fynd_website.utm_campaign':\n new URLSearchParams(window.location.search).get(\"utm_campaign\") || \"\",\n 'fynd_website.referrer': document.referrer,\n };\n\n // Get user journey data if available\n try {\n // Try to get from getUserJourney function first\n let journey = null;\n if (typeof (window as any).getUserJourney === 'function') {\n journey = (window as any).getUserJourney();\n }\n\n // If not available from function, try to get directly from sessionStorage\n if (!journey) {\n const storedData = sessionStorage.getItem('userJourney');\n if (storedData) {\n journey = JSON.parse(storedData);\n }\n }\n\n if (journey) {\n // Add the complete user journey object as touchpoints\n baseProperties['fynd_website.journey_touchpoints'] = journey.userJourney || journey;\n\n // Add form details if available\n if (journey.formDetails) {\n const formDetails: FormDetails = journey.formDetails;\n\n // Only add form properties if they have values\n if (formDetails.formId) {\n baseProperties['fynd_website.form_id'] = formDetails.formId;\n }\n if (formDetails.formName) {\n baseProperties['fynd_website.form_name'] = formDetails.formName;\n }\n if (formDetails.firstName) {\n baseProperties['fynd_website.form_first_name'] = formDetails.firstName;\n }\n if (formDetails.lastName) {\n baseProperties['fynd_website.form_last_name'] = formDetails.lastName;\n }\n if (formDetails.email) {\n baseProperties['fynd_website.form_email'] = formDetails.email;\n }\n if (formDetails.phone) {\n baseProperties['fynd_website.form_phone'] = formDetails.phone;\n }\n }\n\n // Add journey metadata\n if (journey.userJourney && journey.userJourney.length > 0) {\n baseProperties['fynd_website.journey_total_pages'] = journey.userJourney.length;\n baseProperties['fynd_website.journey_touchpoints_count'] = journey.userJourney.length;\n baseProperties['fynd_website.journey_first_page'] = journey.userJourney[0].page;\n baseProperties['fynd_website.journey_current_page'] = journey.userJourney[journey.userJourney.length - 1].page;\n\n // Calculate session duration\n const firstVisit = new Date(journey.userJourney[0].time);\n const lastVisit = new Date(journey.userJourney[journey.userJourney.length - 1].time);\n baseProperties['fynd_website.journey_session_duration'] = Math.floor((lastVisit.getTime() - firstVisit.getTime()) / 1000);\n \n // Add entry and exit times\n baseProperties['fynd_website.journey_entry_time'] = journey.userJourney[0].time;\n baseProperties['fynd_website.journey_exit_time'] = journey.userJourney[journey.userJourney.length - 1].time;\n }\n\n // Add device and browser info from journey\n if (journey.deviceCategory) {\n // Device category is already capitalized from user journey\n baseProperties['fynd_website.device_type'] = journey.deviceCategory;\n }\n if (journey.browser) {\n baseProperties['fynd_website.journey_browser'] = journey.browser;\n }\n if (journey.device) {\n baseProperties['fynd_website.journey_device'] = journey.device;\n }\n if (journey.origin) {\n baseProperties['fynd_website.journey_origin'] = journey.origin;\n }\n \n // Add UTM path if available\n if (journey.utmPath) {\n baseProperties['fynd_website.journey_utm_path'] = journey.utmPath;\n }\n \n // Add scroll depth if available\n if (journey.scrollDepth) {\n baseProperties['fynd_website.journey_scroll_depth'] = journey.scrollDepth;\n }\n\n // Add AI data if available\n if (journey.aiData) {\n const aiData = journey.aiData;\n \n if (aiData.context) {\n baseProperties['fynd_website.aidata_context'] = aiData.context;\n }\n if (aiData.platform) {\n baseProperties['fynd_website.aidata_platform'] = aiData.platform;\n }\n if (aiData.type) {\n baseProperties['fynd_website.aidata_type'] = aiData.type;\n }\n if (aiData.detectionMethod) {\n baseProperties['fynd_website.aidata_detection'] = aiData.detectionMethod;\n }\n }\n }\n } catch (error) {\n console.warn('Error getting user journey data for tracking:', error);\n }\n\n // Fallback device type calculation if user journey isn't available\n if (baseProperties['fynd_website.device_type'] === \"Unknown\") {\n const userAgent = navigator.userAgent;\n \n // Check for tablets first\n if (/iPad/.test(userAgent) || \n (/Android/.test(userAgent) && !/Mobile/.test(userAgent)) ||\n /Tablet/.test(userAgent)) {\n baseProperties['fynd_website.device_type'] = \"Tablet\";\n }\n // Check for mobile devices\n else if (/Mobile|iPhone|Android|BlackBerry|Opera Mini|IEMobile|WPDesktop/.test(userAgent)) {\n baseProperties['fynd_website.device_type'] = \"Mobile\";\n }\n // Default to desktop\n else {\n baseProperties['fynd_website.device_type'] = \"Desktop\";\n }\n }\n\n return baseProperties;\n};\n\n// Function to send event to GA via dataLayer\nconst sendToGA = (eventName: string, gaProperties: GATrackingProperties, additionalProperties?: any): void => {\n if ((window as any).dataLayer) {\n const eventData: GTMEvent = {\n event: eventName,\n event_category: 'form_interaction',\n event_label: eventName,\n ...gaProperties\n };\n\n // Add submitted_form from additional properties if available\n if (additionalProperties?.submitted_form) {\n eventData.submitted_form = additionalProperties.submitted_form;\n }\n\n (window as any).dataLayer.push(eventData);\n // console.log('Event sent to GA:', eventData);\n } else {\n console.warn('dataLayer not available for GA tracking');\n }\n};\n\n// Track event function\nconst trackEvent = (eventName: string, properties?: Partial<TrackingProperties>): void => {\n try {\n // Get PostHog tracking properties (all data)\n const trackingProps = getPosthogTrackingProperties();\n\n // Merge with additional properties if provided\n const finalProperties = properties ? { ...trackingProps, ...properties } : trackingProps;\n\n // Track with PostHog if available\n if ((window as any).posthog) {\n (window as any).posthog.capture(eventName, finalProperties);\n // console.log('Event sent to PostHog:', { event: eventName, properties: finalProperties });\n }\n\n // Get GA tracking properties (form-related and AI data)\n const gaProperties = getGaTrackingProperties();\n\n // Send to GA if there's form-related data, AI data, or it's a form-related event\n const hasAIData = gaProperties.aidata_context || gaProperties.aidata_platform || \n gaProperties.aidata_type || gaProperties.aidata_detection;\n const isFormRelatedEvent = eventName.includes('form') || \n Object.keys(gaProperties).length > 0 || \n properties?.submitted_form ||\n hasAIData;\n\n if (isFormRelatedEvent) {\n sendToGA(eventName, gaProperties, properties);\n }\n\n // Optional: Console log for debugging (remove in production)\n // console.log('Tracked event:', eventName, finalProperties);\n } catch (error) {\n console.error('Error tracking event:', error);\n }\n};\n\n// Helper function to get parent form name\nconst getParentFormName = (element: HTMLElement): string | null => {\n const parentForm = element.closest(\"form\") as HTMLFormElement | null;\n if (parentForm) {\n return parentForm.getAttribute(\"data-name\") ||\n parentForm.getAttribute(\"name\") ||\n parentForm.id ||\n null;\n }\n return null;\n};\n\n// Initialize PostHog pageview\ndocument.addEventListener(\"DOMContentLoaded\", function (): void {\n const trackingProps = getPosthogTrackingProperties();\n\n // PostHog pageview\n if ((window as any).posthog) {\n (window as any).posthog.capture(\"$pageview\", trackingProps);\n }\n});\n\n// Track page load event\nwindow.addEventListener(\"load\", function (): void {\n const trackingProps = getPosthogTrackingProperties();\n // console.log(\"Tracking Properties on Page Load:\", trackingProps);\n \n trackEvent(\"fynd_website.page.loaded\");\n\n // Check if this is the thank you page and trigger form success event\n checkThankYouPageEvent();\n});\n\n// Function to check and trigger thank you page event\nfunction checkThankYouPageEvent(): void {\n const currentPath = window.location.pathname;\n\n // Check if current page is thank you page\n if (currentPath === '/thank-you') {\n // Check if this is a page reload (not initial navigation)\n const navigationEntries = performance.getEntriesByType('navigation');\n if (navigationEntries.length > 0) {\n const navEntry = navigationEntries[0] as PerformanceNavigationTiming;\n\n // Check if it's a reload (type === 'reload') or if there's a referrer from the same origin\n const isReload = navEntry.type === 'reload' ||\n (document.referrer && new URL(document.referrer).origin === window.location.origin);\n\n if (isReload) {\n // Trigger event after 200ms delay\n setTimeout(() => {\n trackEvent(\"fynd_website.form.success\");\n }, 200);\n }\n }\n }\n}\n\n// Button click tracking for sign up, sign in, scroll to form and book a demo buttons\ndocument.addEventListener(\"DOMContentLoaded\", function (): void {\n const signUpButtons = document.querySelectorAll('[data-ph=\"sign-up\"]') as NodeListOf<Element>;\n const signInButtons = document.querySelectorAll('[data-ph=\"sign-in\"]') as NodeListOf<Element>;\n const scrollToFormButtons = document.querySelectorAll(\n '[href=\"#footer-form\"]'\n ) as NodeListOf<Element>;\n const bookADemoButtons = document.querySelectorAll('[data-ph=\"book-a-demo\"]') as NodeListOf<Element>;\n const submitButtons = document.querySelectorAll('[type=\"submit\"]') as NodeListOf<Element>;\n\n submitButtons.forEach((button: Element) => {\n button.addEventListener(\"click\", function (this: HTMLElement): void {\n const formName = getParentFormName(this);\n setTimeout(() => {\n if (window.validationPassed === true) {\n // If validation passed, track the submit event\n const additionalProps = formName ? { submitted_form: formName } : {};\n trackEvent(\"fynd_website.form.submitted\", additionalProps);\n }\n }, 10);\n });\n });\n\n signUpButtons.forEach((button: Element) => {\n button.addEventListener(\"click\", function (): void {\n trackEvent(\"fynd_website.sign_up.clicked\");\n });\n });\n\n signInButtons.forEach((button: Element) => {\n button.addEventListener(\"click\", function (): void {\n trackEvent(\"fynd_website.sign_in.clicked\");\n });\n });\n\n scrollToFormButtons.forEach((button: Element) => {\n button.addEventListener(\"click\", function (): void {\n trackEvent(\"fynd_website.scroll_to_form.clicked\");\n });\n });\n\n bookADemoButtons.forEach((button: Element) => {\n button.addEventListener(\"click\", function (): void {\n trackEvent(\"fynd_website.book_a_demo.clicked\");\n });\n });\n\n // Form field change tracking for fynd_form_started event\n const formFields = document.querySelectorAll('[ph-form-field]') as NodeListOf<HTMLElement>;\n \n // Set to track which forms have already triggered the event\n const triggeredForms = new Set<string>();\n\n formFields.forEach((field: HTMLElement) => {\n // Handle different element types\n const tagName = field.tagName.toLowerCase();\n const inputType = (field as HTMLInputElement).type?.toLowerCase();\n \n // Function to handle form started event\n const handleFormStarted = function (this: HTMLElement): void {\n const formName = getParentFormName(this);\n const formIdentifier = formName || 'unknown-form';\n \n // Only trigger once per form to avoid duplicate events\n if (!triggeredForms.has(formIdentifier)) {\n triggeredForms.add(formIdentifier);\n \n trackEvent(\"fynd_website.form.started\");\n }\n };\n \n // Add focus event for all interactive form fields (except buttons)\n if (!(tagName === 'button' || (tagName === 'input' && inputType === 'submit'))) {\n field.addEventListener('focus', handleFormStarted);\n }\n \n // Add specific interaction events as before\n if (tagName === 'button' || (tagName === 'input' && inputType === 'submit')) {\n field.addEventListener('click', handleFormStarted);\n } else if (tagName === 'select') {\n field.addEventListener('change', handleFormStarted);\n } else {\n field.addEventListener('input', handleFormStarted);\n }\n });\n});\n\n// Make functions globally accessible\nwindow.getPosthogTrackingProperties = getPosthogTrackingProperties;\nwindow.trackEvent = trackEvent;\nwindow.getGaTrackingProperties = getGaTrackingProperties;\n\n// Export for module usage\nexport {\n getPosthogTrackingProperties,\n getGaTrackingProperties,\n trackEvent,\n sendToGA,\n getParentFormName,\n type TrackingProperties,\n type GATrackingProperties,\n type GTMEvent\n};"],
5
- "mappings": "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",
6
- "names": []
3
+ "sources": ["../../bin/live-reload.js", "../../src/posthog-and-ga/adTracking.ts", "../../src/posthog-and-ga/meta-tracking.ts", "../../src/posthog-and-ga/main.ts"],
4
+ "sourcesContent": ["// Only enable live reload when running on localhost\nif (\n window.location.hostname === \"localhost\" ||\n window.location.hostname === \"127.0.0.1\"\n) {\n new EventSource(`${SERVE_ORIGIN}/esbuild`).addEventListener(\"change\", () =>\n location.reload()\n );\n} else {\n // console.log(\"Live reload disabled: not running on localhost\");\n}\n", "// adTracking.ts \u2014 Conditional ad events using existing tracking pipeline\n// Now supports optional UTM campaign gating per page slug.\n\nexport type AdConfig = {\n adPageSlug: string; // e.g. \"/solutions/transport-management-system\"\n adEventExtension: string; // e.g. \"tms\"\n adUTMCampaign?: string | string[]; // e.g. \"tms\" or [\"tms\",\"tms_search\"]\n /** Back-compat alias for earlier typo */\n adUTMCampagin?: string | string[];\n};\n\ndeclare global {\n interface Window {\n trackEvent: (eventName: string, properties?: any) => void;\n validationPassed?: boolean;\n __adsTrackingInitialized?: boolean;\n }\n}\n\nconst normalizePath = (p: string) => {\n const path = p.startsWith(\"/\") ? p : `/${p}`;\n return path !== \"/\" && path.endsWith(\"/\") ? path.slice(0, -1) : path;\n};\n\nconst getSearchParam = (name: string): string | null => {\n const v = new URLSearchParams(window.location.search).get(name);\n return v ? v.trim() : null;\n};\n\nconst matchesUtm = (cfg: AdConfig): boolean => {\n // If no UTM gating configured, allow.\n const configured = cfg.adUTMCampaign ?? cfg.adUTMCampagin;\n if (!configured) return true;\n\n const want = Array.isArray(configured)\n ? configured.map((s) => s.toLowerCase())\n : [configured.toLowerCase()];\n\n const got = getSearchParam(\"utm_campaign\")?.toLowerCase() ?? null;\n return !!got && want.includes(got);\n};\n\nconst getActiveAdConfig = (configs: AdConfig[]): AdConfig | null => {\n const current = normalizePath(window.location.pathname);\n for (const cfg of configs) {\n const slug = normalizePath(cfg.adPageSlug);\n const slugMatches = current === slug || current.startsWith(slug + \"/\");\n if (slugMatches && matchesUtm(cfg)) return cfg;\n }\n return null;\n};\n\nconst makeAdEvent = (ext: string, suffix: string) =>\n `fynd_website_ad_${ext}.${suffix}`;\n\n// local helper (kept here to avoid circular dependency with main.ts)\nconst getParentFormName = (element: HTMLElement): string | null => {\n const parentForm = element.closest(\"form\") as HTMLFormElement | null;\n if (!parentForm) return null;\n return (\n parentForm.getAttribute(\"data-name\") ||\n parentForm.getAttribute(\"name\") ||\n parentForm.id ||\n null\n );\n};\n\nexport const initAdsTracking = (configs: AdConfig[]) => {\n // prevent double wiring across SPA navigations / duplicate script loads\n if (window.__adsTrackingInitialized) return;\n\n const active = getActiveAdConfig(configs);\n if (!active) return; // not an ad page or UTM didn't match\n\n window.__adsTrackingInitialized = true;\n\n const emit = (suffix: string, props?: Record<string, any>) => {\n const name = makeAdEvent(active.adEventExtension, suffix);\n window.trackEvent?.(name, props);\n };\n\n document.addEventListener(\"DOMContentLoaded\", () => {\n // Buttons\n const signUpButtons = document.querySelectorAll('[data-ph=\"sign-up\"]');\n const signInButtons = document.querySelectorAll('[data-ph=\"sign-in\"]');\n const bookADemoButtons = document.querySelectorAll('[data-ph=\"book-a-demo\"]');\n\n signUpButtons.forEach((btn) =>\n btn.addEventListener(\"click\", () => emit(\"sign_up.clicked\"))\n );\n signInButtons.forEach((btn) =>\n btn.addEventListener(\"click\", () => emit(\"sign_in.clicked\"))\n );\n bookADemoButtons.forEach((btn) =>\n btn.addEventListener(\"click\", () => emit(\"book_a_demo.clicked\"))\n );\n\n // Form started (first interaction per form)\n const formFields = document.querySelectorAll<HTMLElement>(\"[ph-form-field]\");\n const triggeredForms = new Set<string>();\n\n const handleFormStarted = function (this: HTMLElement) {\n const formName = getParentFormName(this) || \"unknown-form\";\n if (!triggeredForms.has(formName)) {\n triggeredForms.add(formName);\n emit(\"form.started\");\n }\n };\n\n formFields.forEach((field) => {\n const tag = field.tagName.toLowerCase();\n const type = (field as HTMLInputElement).type?.toLowerCase();\n if (!(tag === \"button\" || (tag === \"input\" && type === \"submit\"))) {\n field.addEventListener(\"focus\", handleFormStarted);\n }\n if (tag === \"button\" || (tag === \"input\" && type === \"submit\")) {\n field.addEventListener(\"click\", handleFormStarted);\n } else if (tag === \"select\") {\n field.addEventListener(\"change\", handleFormStarted);\n } else {\n field.addEventListener(\"input\", handleFormStarted);\n }\n });\n\n // Form submitted (after validation)\n const submitButtons = document.querySelectorAll('[type=\"submit\"]');\n submitButtons.forEach((button) => {\n button.addEventListener(\"click\", function (this: HTMLElement) {\n const formName = getParentFormName(this);\n setTimeout(() => {\n if (window.validationPassed === true) {\n const props = formName ? { submitted_form: formName } : {};\n emit(\"form.submitted\", props);\n }\n }, 10);\n });\n });\n });\n};", "// meta-tracking.ts \u2014 Meta Pixel integration (standards-compliant) for Fynd website\n// - Initializes Meta Pixel (fbq) with Advanced Matching (when available)\n// - Mirrors your existing window.trackEvent() calls to Meta events\n// - Maps Fynd events -> Meta standard/custom events for better optimization\n// - Adds SPA PageView handling + eventID generation for future CAPI dedup\n// - Safe to import once anywhere in your app bootstrap\n\nimport { UserJourney } from \"../utils/types/user-journey\";\n\n// ---------- Config ----------\nconst META_PIXEL_ID = \"2741377816069290\";\n\ntype AdvancedUser = {\n email?: string;\n phone?: string;\n first_name?: string;\n last_name?: string;\n city?: string;\n state?: string;\n zip?: string;\n country?: string;\n external_id?: string;\n};\n\ntype InitOptions = {\n /**\n * If true, attempts to pull user info from window.getUserJourney/sessionStorage\n * and pass as Advanced Matching data (improves match rate for retargeting).\n */\n enableAdvancedMatching?: boolean;\n\n /**\n * If true, listens for SPA route changes and fires PageView on history changes.\n * Set true if you use a client-side router.\n */\n enableSpaPageViews?: boolean;\n\n /**\n * Optional predicate: return false to block Meta calls until consent is granted.\n * Example: () => window.__ad_consent === 'granted'\n */\n hasConsent?: () => boolean;\n};\n\n// ---------- fbq bootstrap ----------\ndeclare global {\n interface Window {\n fbq?: (...args: any[]) => void;\n _fbq?: any;\n trackEvent: (eventName: string, properties?: any) => void;\n getUserJourney: () => UserJourney | null;\n }\n}\n\nfunction loadMetaPixel(): void {\n if (typeof window === \"undefined\") return;\n if (window.fbq) return;\n\n (function (f: any, b: any, e: any, v: any, n?: any, t?: any, s?: any) {\n if (f.fbq) return;\n n = f.fbq = function () {\n (n as any).callMethod ? (n as any).callMethod.apply(n, arguments) : (n as any).queue.push(arguments);\n };\n if (!f._fbq) f._fbq = n;\n (n as any).push = (n as any);\n (n as any).loaded = true;\n (n as any).version = \"2.0\";\n (n as any).queue = [];\n t = b.createElement(e);\n t.async = true;\n t.src = \"https://connect.facebook.net/en_US/fbevents.js\";\n s = b.getElementsByTagName(e)[0];\n s.parentNode!.insertBefore(t, s);\n })(window, document, \"script\", undefined);\n}\n\n// ---------- Advanced Matching helpers ----------\nfunction getAdvancedUserFromJourney(): AdvancedUser | null {\n try {\n let journey: any = null;\n if (typeof window.getUserJourney === \"function\") {\n journey = window.getUserJourney();\n }\n if (!journey) {\n const stored = sessionStorage.getItem(\"userJourney\");\n if (stored) journey = JSON.parse(stored);\n }\n\n const u: AdvancedUser = {};\n const fd = journey?.formDetails;\n if (fd?.email) u.email = fd.email;\n if (fd?.phone) u.phone = fd.phone;\n if (fd?.firstName) u.first_name = fd.firstName;\n if (fd?.lastName) u.last_name = fd.lastName;\n if (fd?.city) u.city = fd.city;\n if (fd?.state) u.state = fd.state;\n if (fd?.zip) u.zip = fd.zip;\n if (journey?.country) u.country = journey.country;\n if (journey?.userId) u.external_id = String(journey.userId);\n\n // Remove empties\n Object.keys(u).forEach((k) => {\n const key = k as keyof AdvancedUser;\n if (!u[key]) delete u[key];\n });\n\n return Object.keys(u).length ? u : null;\n } catch {\n return null;\n }\n}\n\nfunction getAdvancedUserFromProps(props?: any): AdvancedUser | null {\n if (!props) return null;\n const u: AdvancedUser = {};\n if (props[\"fynd_website.form_email\"]) u.email = props[\"fynd_website.form_email\"];\n if (props[\"fynd_website.form_phone\"]) u.phone = props[\"fynd_website.form_phone\"];\n if (props[\"fynd_website.form_first_name\"]) u.first_name = props[\"fynd_website.form_first_name\"];\n if (props[\"fynd_website.form_last_name\"]) u.last_name = props[\"fynd_website.form_last_name\"];\n if (props.city) u.city = props.city;\n if (props.state) u.state = props.state;\n if (props.zip) u.zip = props.zip;\n if (props.country) u.country = props.country;\n if (props.external_id) u.external_id = props.external_id;\n\n Object.keys(u).forEach((k) => {\n const key = k as keyof AdvancedUser;\n if (!u[key]) delete u[key];\n });\n\n return Object.keys(u).length ? u : null;\n}\n\n// ---------- Utility ----------\nfunction genEventId(prefix: string = \"evt\"): string {\n return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2)}`;\n}\n\nfunction safeFbq(...args: any[]): void {\n if (!window.fbq) return;\n window.fbq(...args);\n}\n\n// ---------- Core mapping (Fynd -> Meta) ----------\n/**\n * Maps your event names to Meta\u2019s recommended events.\n * Returns {name, params, options} ready for fbq('track'|'trackCustom', ...)\n */\nfunction mapFyndToMeta(eventName: string, properties?: any): {\n type: \"track\" | \"trackCustom\";\n name: string;\n params?: Record<string, any>;\n options?: { eventID?: string };\n userData?: AdvancedUser | null;\n} | null {\n const props = properties || {};\n // Try to extract user for Advanced Matching\n const userData = getAdvancedUserFromProps(props) || getAdvancedUserFromJourney();\n\n switch (eventName) {\n case \"fynd_website.form.submitted\": {\n // Choose 'Lead' as default (use CompleteRegistration for account creation flows)\n const eventID = props.event_id || genEventId(\"lead\");\n const formName = props.submitted_form || props[\"fynd_website.form_name\"] || \"unknown_form\";\n return {\n type: \"track\",\n name: \"Lead\",\n params: {\n form_id: props[\"fynd_website.form_id\"] || undefined,\n form_name: formName,\n value: 0,\n currency: \"INR\",\n },\n options: { eventID },\n userData,\n };\n }\n\n case \"fynd_website.sign_up.clicked\":\n return { type: \"trackCustom\", name: \"SignUpClick\", params: {}, userData };\n\n case \"fynd_website.sign_in.clicked\":\n return { type: \"trackCustom\", name: \"SignInClick\", params: {}, userData };\n\n case \"fynd_website.book_a_demo.clicked\":\n return {\n type: \"trackCustom\",\n name: \"BookDemoClick\",\n params: {\n source_page: props?.[\"fynd_website.source_page\"],\n },\n userData,\n };\n\n case \"fynd_website.form.started\":\n return {\n type: \"trackCustom\",\n name: \"FormStarted\",\n params: {\n form_id: props?.[\"fynd_website.form_id\"] || undefined,\n form_name: props?.[\"fynd_website.form_name\"] || undefined,\n },\n userData,\n };\n\n // Page lifecycle\n case \"fynd_website.page.loaded\":\n return { type: \"track\", name: \"PageView\", params: {}, userData };\n\n default:\n // Ignore other events by default; you can add more mappings here\n return null;\n }\n}\n\n// ---------- Public API ----------\n/**\n * Initialize Meta tracking and tee into window.trackEvent so existing code just works.\n */\nexport function initMetaTracking(options: InitOptions = {}): void {\n const { enableAdvancedMatching = true, enableSpaPageViews = true, hasConsent } = options;\n\n // 1) Load fbq\n loadMetaPixel();\n\n // 2) Init with/without Advanced Matching\n const initialUser = enableAdvancedMatching ? getAdvancedUserFromJourney() : null;\n if (hasConsent && !hasConsent()) {\n // Defer init until consent flips to true (lightweight poller)\n const iv = window.setInterval(() => {\n if (hasConsent()) {\n window.clearInterval(iv);\n safeFbq(\"init\", META_PIXEL_ID, initialUser || {});\n postInit(enableSpaPageViews);\n }\n }, 250);\n } else {\n safeFbq(\"init\", META_PIXEL_ID, initialUser || {});\n postInit(enableSpaPageViews);\n }\n\n // 3) Tee into window.trackEvent to mirror to Meta\n const originalTrackEvent = window.trackEvent;\n window.trackEvent = function (eventName: string, properties?: any): void {\n try {\n // First, call original (so PostHog/GA remain unchanged)\n if (typeof originalTrackEvent === \"function\") {\n originalTrackEvent.call(window, eventName, properties);\n }\n // Then forward to Meta (respect consent if provided)\n if (hasConsent && !hasConsent()) return;\n\n const mapped = mapFyndToMeta(eventName, properties);\n if (!mapped) return;\n\n // Pass Advanced Matching userData by re-calling init? No\u2014Meta supports user data on event via fbq 2nd arg in init or as 'init' options.\n // For events, best practice is to include user data via \"Advanced Matching\" settings or CAPI.\n // Here we rely on init advanced matching; optionally, you can include userData with custom calls via setUserProperties (not available on Pixel).\n if (mapped.type === \"track\") {\n if (mapped.options?.eventID) {\n safeFbq(\"track\", mapped.name, mapped.params || {}, { eventID: mapped.options.eventID });\n } else {\n safeFbq(\"track\", mapped.name, mapped.params || {});\n }\n } else {\n // trackCustom\n // We cannot pass user data as a separate arg here; advanced matching should be handled at init or via CAPI.\n safeFbq(\"trackCustom\", mapped.name, mapped.params || {});\n }\n } catch (e) {\n // swallow to avoid interrupting primary trackers\n // eslint-disable-next-line no-console\n console.warn(\"Meta tracking error:\", e);\n }\n };\n}\n\n/**\n * Manually send a CompleteRegistration when your \u201Cform submitted\u201D is actually an account creation.\n * Reuse the same eventID for later CAPI dedup if you mirror server-side.\n */\nexport function trackCompleteRegistration(registrationMethod: string = \"email\", eventID?: string, props?: any) {\n const options = eventID ? { eventID } : undefined;\n // Respect optional consent gate if your app uses one:\n // if (window.__ad_consent !== 'granted') return;\n safeFbq(\"track\", \"CompleteRegistration\", { registration_method: registrationMethod }, options);\n}\n\n/**\n * Optional helper if you want to send a Lead directly (outside of window.trackEvent).\n */\nexport function trackLead(formId?: string, formName?: string, valueINR: number = 0, eventID?: string) {\n const params: Record<string, any> = { value: valueINR, currency: \"INR\" };\n if (formId) params.form_id = formId;\n if (formName) params.form_name = formName;\n const options = { eventID: eventID || genEventId(\"lead\") };\n safeFbq(\"track\", \"Lead\", params, options);\n}\n\n// ---------- Internal: post init tasks ----------\nfunction postInit(enableSpaPageViews: boolean) {\n // Fire initial PageView (Meta does this automatically when you call fbq('track','PageView')\u2014we mimic GA's $pageview behavior)\n safeFbq(\"track\", \"PageView\");\n\n if (enableSpaPageViews) {\n // Hook into history API to catch virtual route changes\n const origPushState = history.pushState;\n const origReplaceState = history.replaceState;\n\n function onLocationChange() {\n // Delay slightly to allow DOM/router to settle\n setTimeout(() => safeFbq(\"track\", \"PageView\"), 0);\n }\n\n history.pushState = function (...args: any[]) {\n const ret = origPushState.apply(this, args as any);\n onLocationChange();\n return ret;\n };\n\n history.replaceState = function (...args: any[]) {\n const ret = origReplaceState.apply(this, args as any);\n onLocationChange();\n return ret;\n };\n\n window.addEventListener(\"popstate\", onLocationChange);\n }\n}\n\n// ---------- (Optional) noscript pixel for non-JS fallbacks ----------\n// In your HTML <noscript>, add:\n// <img height=\"1\" width=\"1\" style=\"display:none\"\n// src=\"https://www.facebook.com/tr?id=2741377816069290&ev=PageView&noscript=1\"/>", "// main.ts \u2014 Core tracking: PostHog + GA (GTM dataLayer) + optional ad tracking bootstrap\nimport { FormDetails, UserJourney } from \"../utils/types/user-journey\";\nimport { AdConfig, initAdsTracking } from \"./adTracking\";\nimport { initMetaTracking } from \"./meta-tracking\";\n\n// ---------- Types ----------\ninterface GTMEvent {\n event: string;\n event_category: string;\n event_label: string;\n form_id?: string;\n form_name?: string;\n form_first_name?: string;\n form_last_name?: string;\n form_email?: string;\n form_phone?: string;\n submitted_form?: string;\n [key: string]: any;\n}\n\ninterface GATrackingProperties {\n form_id?: string;\n form_name?: string;\n form_first_name?: string;\n form_last_name?: string;\n form_email?: string;\n form_phone?: string;\n submitted_form?: string;\n aidata_context?: string;\n aidata_platform?: string;\n aidata_type?: string;\n aidata_detection?: string;\n}\n\ninterface TrackingProperties {\n \"fynd_website.source_page\": string;\n \"fynd_website.product\": string;\n \"fynd_website.device_type\": string;\n \"fynd_website.utm_source\": string;\n \"fynd_website.utm_medium\": string;\n \"fynd_website.utm_campaign\": string;\n \"fynd_website.referrer\": string;\n \"fynd_website.form_id\"?: string;\n \"fynd_website.form_name\"?: string;\n \"fynd_website.form_first_name\"?: string;\n \"fynd_website.form_last_name\"?: string;\n \"fynd_website.form_email\"?: string;\n \"fynd_website.form_phone\"?: string;\n \"fynd_website.journey_total_pages\"?: number;\n \"fynd_website.journey_session_duration\"?: number;\n \"fynd_website.journey_first_page\"?: string;\n \"fynd_website.journey_current_page\"?: string;\n \"fynd_website.journey_device\"?: string;\n \"fynd_website.journey_browser\"?: string;\n \"fynd_website.journey_device_name\"?: string;\n \"fynd_website.journey_origin\"?: string;\n \"fynd_website.journey_touchpoints\"?: any;\n \"fynd_website.journey_touchpoints_count\"?: number;\n \"fynd_website.journey_utm_path\"?: string;\n \"fynd_website.journey_entry_time\"?: string;\n \"fynd_website.journey_exit_time\"?: string;\n \"fynd_website.journey_scroll_depth\"?: number;\n \"fynd_website.aidata_context\"?: string;\n \"fynd_website.aidata_platform\"?: string;\n \"fynd_website.aidata_type\"?: string;\n \"fynd_website.aidata_detection\"?: string;\n submitted_form?: string;\n field_type?: string;\n field_name?: string;\n [key: string]: any;\n}\n\ndeclare global {\n interface Window {\n trackEvent: (eventName: string, properties?: any) => void;\n getPosthogTrackingProperties: () => TrackingProperties;\n getGaTrackingProperties: () => GATrackingProperties;\n validationPassed?: boolean;\n getUserJourney: () => UserJourney | null;\n dataLayer?: GTMEvent[];\n }\n}\n\n// ---------- GA helpers ----------\nconst getGaTrackingProperties = (): GATrackingProperties => {\n const gaProperties: GATrackingProperties = {};\n try {\n let journey: any = null;\n if (typeof (window as any).getUserJourney === \"function\") {\n journey = (window as any).getUserJourney();\n }\n if (!journey) {\n const storedData = sessionStorage.getItem(\"userJourney\");\n if (storedData) journey = JSON.parse(storedData);\n }\n\n if (journey?.formDetails) {\n const formDetails: FormDetails = journey.formDetails;\n if (formDetails.formId) gaProperties.form_id = formDetails.formId;\n if (formDetails.formName) gaProperties.form_name = formDetails.formName;\n if (formDetails.firstName) gaProperties.form_first_name = formDetails.firstName;\n if (formDetails.lastName) gaProperties.form_last_name = formDetails.lastName;\n if (formDetails.email) gaProperties.form_email = formDetails.email;\n if (formDetails.phone) gaProperties.form_phone = formDetails.phone;\n }\n\n if (journey?.aiData) {\n const aiData = journey.aiData;\n if (aiData.context) gaProperties.aidata_context = aiData.context;\n if (aiData.platform) gaProperties.aidata_platform = aiData.platform;\n if (aiData.type) gaProperties.aidata_type = aiData.type;\n if (aiData.detectionMethod) gaProperties.aidata_detection = aiData.detectionMethod;\n }\n } catch (err) {\n console.warn(\"Error getting user journey data for GA tracking:\", err);\n }\n return gaProperties;\n};\n\n// ---------- PostHog properties ----------\nconst getPosthogTrackingProperties = (): TrackingProperties => {\n const pathname: string = window.location.pathname;\n\n const base: TrackingProperties = {\n \"fynd_website.source_page\": pathname,\n \"fynd_website.product\": \"fynd.com website\",\n \"fynd_website.device_type\": \"Unknown\",\n \"fynd_website.utm_source\": new URLSearchParams(window.location.search).get(\"utm_source\") || \"\",\n \"fynd_website.utm_medium\": new URLSearchParams(window.location.search).get(\"utm_medium\") || \"\",\n \"fynd_website.utm_campaign\": new URLSearchParams(window.location.search).get(\"utm_campaign\") || \"\",\n \"fynd_website.referrer\": document.referrer,\n };\n\n try {\n let journey: any = null;\n if (typeof (window as any).getUserJourney === \"function\") {\n journey = (window as any).getUserJourney();\n }\n if (!journey) {\n const storedData = sessionStorage.getItem(\"userJourney\");\n if (storedData) journey = JSON.parse(storedData);\n }\n\n if (journey) {\n base[\"fynd_website.journey_touchpoints\"] = journey.userJourney || journey;\n\n if (journey.formDetails) {\n const f: FormDetails = journey.formDetails;\n if (f.formId) base[\"fynd_website.form_id\"] = f.formId;\n if (f.formName) base[\"fynd_website.form_name\"] = f.formName;\n if (f.firstName) base[\"fynd_website.form_first_name\"] = f.firstName;\n if (f.lastName) base[\"fynd_website.form_last_name\"] = f.lastName;\n if (f.email) base[\"fynd_website.form_email\"] = f.email;\n if (f.phone) base[\"fynd_website.form_phone\"] = f.phone;\n }\n\n if (journey.userJourney?.length > 0) {\n base[\"fynd_website.journey_total_pages\"] = journey.userJourney.length;\n base[\"fynd_website.journey_touchpoints_count\"] = journey.userJourney.length;\n base[\"fynd_website.journey_first_page\"] = journey.userJourney[0].page;\n base[\"fynd_website.journey_current_page\"] =\n journey.userJourney[journey.userJourney.length - 1].page;\n\n const firstVisit = new Date(journey.userJourney[0].time);\n const lastVisit = new Date(journey.userJourney[journey.userJourney.length - 1].time);\n base[\"fynd_website.journey_session_duration\"] = Math.floor(\n (lastVisit.getTime() - firstVisit.getTime()) / 1000\n );\n base[\"fynd_website.journey_entry_time\"] = journey.userJourney[0].time;\n base[\"fynd_website.journey_exit_time\"] = journey.userJourney[journey.userJourney.length - 1].time;\n }\n\n if (journey.deviceCategory) base[\"fynd_website.device_type\"] = journey.deviceCategory;\n if (journey.browser) base[\"fynd_website.journey_browser\"] = journey.browser;\n if (journey.device) base[\"fynd_website.journey_device\"] = journey.device;\n if (journey.origin) base[\"fynd_website.journey_origin\"] = journey.origin;\n if (journey.utmPath) base[\"fynd_website.journey_utm_path\"] = journey.utmPath;\n if (journey.scrollDepth) base[\"fynd_website.journey_scroll_depth\"] = journey.scrollDepth;\n\n if (journey.aiData) {\n const aiData = journey.aiData;\n if (aiData.context) base[\"fynd_website.aidata_context\"] = aiData.context;\n if (aiData.platform) base[\"fynd_website.aidata_platform\"] = aiData.platform;\n if (aiData.type) base[\"fynd_website.aidata_type\"] = aiData.type;\n if (aiData.detectionMethod) base[\"fynd_website.aidata_detection\"] = aiData.detectionMethod;\n }\n }\n } catch (err) {\n console.warn(\"Error getting user journey data for tracking:\", err);\n }\n\n // Fallback device type\n if (base[\"fynd_website.device_type\"] === \"Unknown\") {\n const ua = navigator.userAgent;\n if (/iPad/.test(ua) || (/Android/.test(ua) && !/Mobile/.test(ua)) || /Tablet/.test(ua)) {\n base[\"fynd_website.device_type\"] = \"Tablet\";\n } else if (/Mobile|iPhone|Android|BlackBerry|Opera Mini|IEMobile|WPDesktop/.test(ua)) {\n base[\"fynd_website.device_type\"] = \"Mobile\";\n } else {\n base[\"fynd_website.device_type\"] = \"Desktop\";\n }\n }\n return base;\n};\n\n// ---------- GA send ----------\nconst sendToGA = (eventName: string, gaProps: GATrackingProperties, additionalProps?: any): void => {\n if ((window as any).dataLayer) {\n const eventData: GTMEvent = {\n event: eventName,\n event_category: \"form_interaction\",\n event_label: eventName,\n ...gaProps,\n };\n if (additionalProps?.submitted_form) {\n eventData.submitted_form = additionalProps.submitted_form;\n }\n (window as any).dataLayer.push(eventData);\n } else {\n console.warn(\"dataLayer not available for GA tracking\");\n }\n};\n\n// ---------- Public trackEvent ----------\nconst trackEvent = (eventName: string, properties?: Partial<TrackingProperties>): void => {\n try {\n const baseProps = getPosthogTrackingProperties();\n const finalProps = properties ? { ...baseProps, ...properties } : baseProps;\n\n if ((window as any).posthog) {\n (window as any).posthog.capture(eventName, finalProps);\n }\n\n const gaProps = getGaTrackingProperties();\n const hasAIData =\n gaProps.aidata_context || gaProps.aidata_platform || gaProps.aidata_type || gaProps.aidata_detection;\n\n const isFormRelatedEvent =\n eventName.includes(\"form\") ||\n Object.keys(gaProps).length > 0 ||\n properties?.submitted_form ||\n !!hasAIData;\n\n if (isFormRelatedEvent) {\n sendToGA(eventName, gaProps, properties);\n }\n } catch (error) {\n console.error(\"Error tracking event:\", error);\n }\n};\n\n// ---------- Shared helpers ----------\nconst getParentFormName = (element: HTMLElement): string | null => {\n const parentForm = element.closest(\"form\") as HTMLFormElement | null;\n if (!parentForm) return null;\n return (\n parentForm.getAttribute(\"data-name\") ||\n parentForm.getAttribute(\"name\") ||\n parentForm.id ||\n null\n );\n};\n\n// ---------- Page lifecycle ----------\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n const props = getPosthogTrackingProperties();\n if ((window as any).posthog) {\n (window as any).posthog.capture(\"$pageview\", props);\n }\n});\n\nwindow.addEventListener(\"load\", () => {\n trackEvent(\"fynd_website.page.loaded\");\n});\n\n// ---------- Base site interactions ----------\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n const signUpButtons = document.querySelectorAll('[data-ph=\"sign-up\"]');\n const signInButtons = document.querySelectorAll('[data-ph=\"sign-in\"]');\n const scrollToFormButtons = document.querySelectorAll('[href=\"#footer-form\"]');\n const bookADemoButtons = document.querySelectorAll('[data-ph=\"book-a-demo\"]');\n const submitButtons = document.querySelectorAll('[type=\"submit\"]');\n\n submitButtons.forEach((button: Element) => {\n button.addEventListener(\"click\", function (this: HTMLElement): void {\n const formName = getParentFormName(this);\n setTimeout(() => {\n if (window.validationPassed === true) {\n const additionalProps = formName ? { submitted_form: formName } : {};\n trackEvent(\"fynd_website.form.submitted\", additionalProps);\n }\n }, 10);\n });\n });\n\n signUpButtons.forEach((button: Element) => {\n button.addEventListener(\"click\", () => trackEvent(\"fynd_website.sign_up.clicked\"));\n });\n\n signInButtons.forEach((button: Element) => {\n button.addEventListener(\"click\", () => trackEvent(\"fynd_website.sign_in.clicked\"));\n });\n\n scrollToFormButtons.forEach((button: Element) => {\n button.addEventListener(\"click\", () => trackEvent(\"fynd_website.scroll_to_form.clicked\"));\n });\n\n bookADemoButtons.forEach((button: Element) => {\n button.addEventListener(\"click\", () => trackEvent(\"fynd_website.book_a_demo.clicked\"));\n });\n\n // Form started\n const formFields = document.querySelectorAll<HTMLElement>(\"[ph-form-field]\");\n const triggeredForms = new Set<string>();\n\n const handleFormStarted = function (this: HTMLElement): void {\n const formName = getParentFormName(this);\n const formIdentifier = formName || \"unknown-form\";\n if (!triggeredForms.has(formIdentifier)) {\n triggeredForms.add(formIdentifier);\n trackEvent(\"fynd_website.form.started\");\n }\n };\n\n formFields.forEach((field) => {\n const tagName = field.tagName.toLowerCase();\n const inputType = (field as HTMLInputElement).type?.toLowerCase();\n\n if (!(tagName === \"button\" || (tagName === \"input\" && inputType === \"submit\"))) {\n field.addEventListener(\"focus\", handleFormStarted);\n }\n if (tagName === \"button\" || (tagName === \"input\" && inputType === \"submit\")) {\n field.addEventListener(\"click\", handleFormStarted);\n } else if (tagName === \"select\") {\n field.addEventListener(\"change\", handleFormStarted);\n } else {\n field.addEventListener(\"input\", handleFormStarted);\n }\n });\n});\n\n// ---------- Expose globals ----------\nwindow.getPosthogTrackingProperties = getPosthogTrackingProperties;\nwindow.trackEvent = trackEvent;\nwindow.getGaTrackingProperties = getGaTrackingProperties;\n\n// ---------- Optional: bootstrap ad tracking here ----------\nconst AD_CONFIGS: AdConfig[] = [\n { adPageSlug: \"/solutions/transport-management-system\", adEventExtension: \"tms\", adUTMCampaign: \"tms\", },\n];\ninitAdsTracking(AD_CONFIGS);\n\ninitMetaTracking({\n enableAdvancedMatching: true, // pulls user data from your journey store when available\n enableSpaPageViews: true, // fires PageView on virtual navigations\n hasConsent: () => (window as any).__ad_consent === \"granted\" || true, // replace with your consent logic\n });\n\n// ---------- Exports ----------\nexport {\n getPosthogTrackingProperties,\n getGaTrackingProperties,\n trackEvent,\n getParentFormName,\n type TrackingProperties,\n type GATrackingProperties,\n type GTMEvent,\n};"],
5
+ "mappings": "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",
6
+ "names": ["onLocationChange", "getParentFormName"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../bin/live-reload.js", "../../src/tracking/fill-form-fields.ts"],
4
- "sourcesContent": ["// Only enable live reload when running on localhost\nif (\n window.location.hostname === \"localhost\" ||\n window.location.hostname === \"127.0.0.1\"\n) {\n new EventSource(`${SERVE_ORIGIN}/esbuild`).addEventListener(\"change\", () =>\n location.reload()\n );\n} else {\n // console.log(\"Live reload disabled: not running on localhost\");\n}\n", "// formFiller.ts - Auto-fill form fields with user journey data\nimport { UserJourney, TouchPoint } from './types';\n\n/**\n * Fills form input fields with user journey data based on fynd-queryparam-name attributes\n */\nfunction fillFormWithUserJourney(): void {\n try {\n // Get user journey data from session storage\n const journey: UserJourney | null = getUserJourneyData();\n\n if (!journey || journey.userJourney.length === 0) {\n //console.log('No user journey data available to fill form fields');\n return;\n }\n\n // Get first page (landing page) and last page data\n const firstPage: TouchPoint = journey.userJourney[0];\n let lastPage: TouchPoint = journey.userJourney[journey.userJourney.length - 1];\n\n // If current page is contact-us, use the previous page as last page\n if (journey.userJourney.length > 1 &&\n journey.userJourney[journey.userJourney.length - 1].page === '/contact-us') {\n lastPage = journey.userJourney[journey.userJourney.length - 2];\n }\n\n // Define the mapping of attribute values to data\n const fieldMappings: Record<string, string> = {\n // UTM parameters\n 'utm_source': firstPage.utm.source,\n 'utm_medium': firstPage.utm.medium,\n 'utm_campaign': firstPage.utm.campaign,\n\n // First Page (Landing Page) data\n 'fp_custom_page_title': firstPage.title,\n 'fp_custom_page_category': firstPage.category.join(', '),\n 'fp_custom_page_type': firstPage.type,\n 'fp_timestamp': firstPage.time,\n 'fp_path': firstPage.page,\n\n // Last Page data\n 'lp_custom_page_title': lastPage.title,\n 'lp_custom_page_category': lastPage.category.join(', '),\n 'lp_custom_page_type': lastPage.type,\n 'lp_timestamp': lastPage.time,\n 'lp_path': lastPage.page,\n\n // Journey metadata\n 'userjourney': JSON.stringify(journey.userJourney),\n 'device': journey.deviceCategory,\n 'browser': journey.browser,\n\n // Refferer\n 'refferer_domain': window.location.hostname,\n };\n\n // Find and fill each form field\n Object.entries(fieldMappings).forEach(([attributeValue, data]) => {\n fillFormField(attributeValue, data);\n });\n\n //console.log('Form fields filled with user journey data');\n\n } catch (error: unknown) {\n console.error('Error filling form with user journey data:', error);\n }\n}\n\n/**\n * Helper function to get user journey data from session storage\n */\nfunction getUserJourneyData(): UserJourney | null {\n try {\n const storedData: string | null = sessionStorage.getItem('userJourney');\n return storedData ? JSON.parse(storedData) as UserJourney : null;\n } catch (error: unknown) {\n console.error('Error getting user journey data:', error);\n return null;\n }\n}\n\n/**\n * Helper function to find and fill a specific form field\n */\nfunction fillFormField(attributeValue: string, data: string): void {\n try {\n // Find any element with the specific fynd-queryparam-name attribute\n const selector: string = `[fynd-queryparam-name=\"${attributeValue}\"]`;\n const element: HTMLElement | null = document.querySelector(selector);\n\n if (element) {\n // Fill the element with the data\n (element as any).value = data;\n\n // Trigger input event to notify any listeners\n const inputEvent = new Event('input', { bubbles: true });\n element.dispatchEvent(inputEvent);\n\n // Trigger change event as well\n const changeEvent = new Event('change', { bubbles: true });\n element.dispatchEvent(changeEvent);\n\n //console.log(`Filled field [${attributeValue}] with:`, data);\n } else {\n //console.log(`Field with attribute [${attributeValue}] not found`);\n }\n } catch (error: unknown) {\n console.error(`Error filling field [${attributeValue}]:`, error);\n }\n}\n\n// Execute the function on DOM load with 500ms delay\ndocument.addEventListener('DOMContentLoaded', (): void => {\n setTimeout(() => {\n fillFormWithUserJourney();\n }, 500);\n});\n\n// Also execute immediately if DOM is already loaded\nif (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', (): void => {\n setTimeout(() => {\n fillFormWithUserJourney();\n }, 500);\n });\n} else {\n setTimeout(() => {\n fillFormWithUserJourney();\n }, 500);\n}\n\n// Make function globally accessible\ndeclare global {\n interface Window {\n fillFormWithUserJourney: () => void;\n }\n}\n\n// Attach function to window object for global access\nwindow.fillFormWithUserJourney = fillFormWithUserJourney;\n\n// Export function for module usage\nexport { fillFormWithUserJourney };"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Only enable live reload when running on localhost\nif (\n window.location.hostname === \"localhost\" ||\n window.location.hostname === \"127.0.0.1\"\n) {\n new EventSource(`${SERVE_ORIGIN}/esbuild`).addEventListener(\"change\", () =>\n location.reload()\n );\n} else {\n // console.log(\"Live reload disabled: not running on localhost\");\n}\n", "// formFiller.ts - Auto-fill form fields with user journey data\nimport { UserJourney, TouchPoint } from './types';\n\n/**\n * Fills form input fields with user journey data based on fynd-queryparam-name attributes\n */\nfunction fillFormWithUserJourney(): void {\n try {\n // Get user journey data from session storage\n const journey: UserJourney | null = getUserJourneyData();\n\n if (!journey || journey.userJourney.length === 0) {\n //console.log('No user journey data available to fill form fields');\n return;\n }\n\n // Get first page (landing page) and last page data\n const firstPage: TouchPoint = journey.userJourney[0];\n let lastPage: TouchPoint = journey.userJourney[journey.userJourney.length - 1];\n\n // If current page is contact-us, use the previous page as last page\n if (journey.userJourney.length > 1 &&\n journey.userJourney[journey.userJourney.length - 1].page === '/contact-us') {\n lastPage = journey.userJourney[journey.userJourney.length - 2];\n }\n\n // Define the mapping of attribute values to data\n const fieldMappings: Record<string, string> = {\n // UTM parameters\n 'utm_source': firstPage.utm.source,\n 'utm_medium': firstPage.utm.medium,\n 'utm_campaign': firstPage.utm.campaign,\n\n // First Page (Landing Page) data\n 'fp_custom_page_title': firstPage.title,\n 'fp_custom_page_category': firstPage.category.join(', '),\n 'fp_custom_page_type': firstPage.type,\n 'fp_timestamp': firstPage.time,\n 'fp_path': firstPage.page,\n\n // Last Page data\n 'lp_custom_page_title': lastPage.title,\n 'lp_custom_page_category': lastPage.category.join(', '),\n 'lp_custom_page_type': lastPage.type,\n 'lp_timestamp': lastPage.time,\n 'lp_path': lastPage.page,\n\n // Journey metadata\n 'userjourney': JSON.stringify(journey.userJourney),\n 'device': journey.deviceCategory,\n 'browser': journey.browser,\n\n // Refferer\n 'refferer_domain': window.location.hostname,\n\n //current page URL\n 'current-page-url': window.location.href,\n };\n\n // Find and fill each form field\n Object.entries(fieldMappings).forEach(([attributeValue, data]) => {\n fillFormField(attributeValue, data);\n });\n\n //console.log('Form fields filled with user journey data');\n\n } catch (error: unknown) {\n console.error('Error filling form with user journey data:', error);\n }\n}\n\n/**\n * Helper function to get user journey data from session storage\n */\nfunction getUserJourneyData(): UserJourney | null {\n try {\n const storedData: string | null = sessionStorage.getItem('userJourney');\n return storedData ? JSON.parse(storedData) as UserJourney : null;\n } catch (error: unknown) {\n console.error('Error getting user journey data:', error);\n return null;\n }\n}\n\n/**\n * Helper function to find and fill a specific form field\n */\nfunction fillFormField(attributeValue: string, data: string): void {\n try {\n // Find any element with the specific fynd-queryparam-name attribute\n const selector: string = `[fynd-queryparam-name=\"${attributeValue}\"]`;\n const element: HTMLElement | null = document.querySelector(selector);\n\n if (element) {\n // Fill the element with the data\n (element as any).value = data;\n\n // Trigger input event to notify any listeners\n const inputEvent = new Event('input', { bubbles: true });\n element.dispatchEvent(inputEvent);\n\n // Trigger change event as well\n const changeEvent = new Event('change', { bubbles: true });\n element.dispatchEvent(changeEvent);\n\n //console.log(`Filled field [${attributeValue}] with:`, data);\n } else {\n //console.log(`Field with attribute [${attributeValue}] not found`);\n }\n } catch (error: unknown) {\n console.error(`Error filling field [${attributeValue}]:`, error);\n }\n}\n\n// Execute the function on DOM load with 500ms delay\ndocument.addEventListener('DOMContentLoaded', (): void => {\n setTimeout(() => {\n fillFormWithUserJourney();\n }, 500);\n});\n\n// Also execute immediately if DOM is already loaded\nif (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', (): void => {\n setTimeout(() => {\n fillFormWithUserJourney();\n }, 500);\n });\n} else {\n setTimeout(() => {\n fillFormWithUserJourney();\n }, 500);\n}\n\n// Make function globally accessible\ndeclare global {\n interface Window {\n fillFormWithUserJourney: () => void;\n }\n}\n\n// Attach function to window object for global access\nwindow.fillFormWithUserJourney = fillFormWithUserJourney;\n\n// Export function for module usage\nexport { fillFormWithUserJourney };"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fynd-design-engineering/fynd-one-v2",
3
- "version": "3.3.23",
3
+ "version": "3.3.25",
4
4
  "description": "Updated CDN for fynd.com",
5
5
  "homepage": "https://github.com/Fynd-Design-Engineering/Fynd-Utils/blob/main/README.md",
6
6
  "license": "ISC",