@fynd-design-engineering/fynd-one-v2 3.4.63 → 3.4.65
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/accordians/dropdown.js +1 -95
- package/dist/accordians/index.js +1 -391
- package/dist/cms-listing/index.js +1 -24
- package/dist/filters/clear-search.js +1 -32
- package/dist/filters/konnect.js +1 -165
- package/dist/filters/show-count.js +1 -66
- package/dist/form/country-dropdown.css +1 -160
- package/dist/form/cs-gated-redirection.js +1 -40
- package/dist/form/download-file.js +1 -70
- package/dist/form/validation.css +1 -1019
- package/dist/form/validation.js +7 -10611
- package/dist/global/anchor-scroll.js +1 -174
- package/dist/global/auth.js +1 -87
- package/dist/global/chat.js +1 -185
- package/dist/global/console-links.js +1 -89
- package/dist/global/contact-popup.js +2 -83
- package/dist/global/css/in-page-embed.css +1 -1043
- package/dist/global/css/in-project-settings.css +1 -173
- package/dist/global/css/temp.css +1 -89
- package/dist/global/custom-bg-video.js +1 -40
- package/dist/global/footer-accordion.js +1 -44
- package/dist/global/lazy-loader.js +1 -135
- package/dist/global/loader.js +2 -166
- package/dist/global/media-card.js +1 -166
- package/dist/global/miscellaneous.js +1 -136
- package/dist/global/number-count.js +1 -82
- package/dist/global/popup-video.js +1 -276
- package/dist/global/progressive-scroll.js +1 -222
- package/dist/global/responsive-video.js +1 -321
- package/dist/global/style.css +1 -1065
- package/dist/global/video-card.js +1 -50
- package/dist/hacktimus/2025.js +1 -177
- package/dist/hacktimus/styles.css +1 -91
- package/dist/home/index.js +1 -17
- package/dist/marquee/index.js +1 -3104
- package/dist/marquee/marquee-swiper.js +1 -36
- package/dist/navigation/announcement/index.js +1 -5169
- package/dist/navigation/context-menu/index.js +1 -31
- package/dist/navigation/desktop/index.js +1 -4603
- package/dist/navigation/initialization.js +1 -602
- package/dist/navigation/main.js +1 -4911
- package/dist/navigation/mobile/index.js +1 -286
- package/dist/navigation/scroll/index.js +1 -62
- package/dist/navigation/secondary-navigation/index.js +1 -437
- package/dist/navigation/style.css +1 -154
- package/dist/navigation/temp.css +0 -2
- package/dist/navigation/theme.css +1 -69
- package/dist/navigation-v2/index.js +1 -4990
- package/dist/navigation-v2/styles.css +1 -233
- package/dist/others/feature-detail.js +1 -75
- package/dist/others/geolocation.js +1 -50
- package/dist/others/hero-aniamtion.js +1 -53
- package/dist/others/hero-india-animation-2.js +1 -70
- package/dist/others/hero-india-animation.js +1 -93
- package/dist/others/home-solution-tab.js +1 -115
- package/dist/others/storefront-chat/index.js +1 -487
- package/dist/others/storefront-chat/styles.css +1 -107
- package/dist/playbook-2026/hero-reveal.js +1 -47
- package/dist/playbook-2026/index.js +1 -536
- package/dist/playbook-2026/styles.css +1 -110
- package/dist/posthog-and-ga/attributes.js +1 -190
- package/dist/posthog-and-ga/main.js +1 -528
- package/dist/progressive-scroll/index.js +1 -147
- package/dist/quick-fix/reload.js +1 -22
- package/dist/seo/schema.js +1 -465
- package/dist/slider/freescroll.js +1 -34
- package/dist/test/sample.js +1 -15
- package/dist/testimonials/index.js +1 -2654
- package/dist/timeline/index.js +1 -160
- package/dist/timeline/style.css +1 -42
- package/dist/tracking/custom-id.js +1 -75
- package/dist/tracking/fill-form-fields.js +1 -238
- package/dist/tracking/form-tracker.js +1 -146
- package/dist/tracking/page-categories.js +1 -20
- package/dist/tracking/user-journey.js +1 -839
- package/dist/tracking/utm-links.js +1 -194
- package/dist/utils/sample.js +1 -17
- package/dist/validations/localhost.js +1 -221
- package/package.json +1 -1
|
@@ -1,839 +1 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
(() => {
|
|
3
|
-
// bin/live-reload.js
|
|
4
|
-
if (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1") {
|
|
5
|
-
new EventSource(`${"http://localhost:3000"}/esbuild`).addEventListener(
|
|
6
|
-
"change",
|
|
7
|
-
() => location.reload()
|
|
8
|
-
);
|
|
9
|
-
} else {
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// src/tracking/user-journey.ts
|
|
13
|
-
function handleAIDetection_LatestPlatform(existingAIData, newAIData) {
|
|
14
|
-
if (newAIData.platform !== "none") {
|
|
15
|
-
return newAIData;
|
|
16
|
-
}
|
|
17
|
-
return existingAIData;
|
|
18
|
-
}
|
|
19
|
-
function detectAIPlatform() {
|
|
20
|
-
const referrerObj = document.referrer;
|
|
21
|
-
const referrer = referrerObj.toLowerCase();
|
|
22
|
-
const currentURL = new URL(window.location.href);
|
|
23
|
-
const utmSource = currentURL.searchParams.get("utm_source")?.toLowerCase() || "";
|
|
24
|
-
const utmMedium = currentURL.searchParams.get("utm_medium")?.toLowerCase() || "";
|
|
25
|
-
const utmCampaign = currentURL.searchParams.get("utm_campaign")?.toLowerCase() || "";
|
|
26
|
-
const utmContent = currentURL.searchParams.get("utm_content")?.toLowerCase() || "";
|
|
27
|
-
const allSources = `${referrer} ${utmSource} ${utmMedium} ${utmCampaign} ${utmContent}`;
|
|
28
|
-
let aiData = {
|
|
29
|
-
platform: "none",
|
|
30
|
-
type: "unknown",
|
|
31
|
-
context: "unknown",
|
|
32
|
-
confidence: "low",
|
|
33
|
-
detectionMethod: "none",
|
|
34
|
-
detectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
35
|
-
};
|
|
36
|
-
const aiPlatforms = [
|
|
37
|
-
{
|
|
38
|
-
keywords: ["chatgpt", "openai", "chat.openai"],
|
|
39
|
-
platform: "ChatGPT",
|
|
40
|
-
type: "ai_chat",
|
|
41
|
-
context: "conversational_query",
|
|
42
|
-
confidence: "high"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
keywords: ["perplexity"],
|
|
46
|
-
platform: "Perplexity",
|
|
47
|
-
type: "ai_search",
|
|
48
|
-
context: "research_query",
|
|
49
|
-
confidence: "high"
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
keywords: ["claude", "anthropic"],
|
|
53
|
-
platform: "Claude",
|
|
54
|
-
type: "ai_chat",
|
|
55
|
-
context: "conversational_query",
|
|
56
|
-
confidence: "high"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
keywords: ["bing", "copilot", "microsoft-copilot"],
|
|
60
|
-
platform: "Bing_Copilot",
|
|
61
|
-
type: "ai_chat",
|
|
62
|
-
context: "conversational_query",
|
|
63
|
-
confidence: "medium"
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
keywords: ["gemini", "bard", "google-ai"],
|
|
67
|
-
platform: "Google_Gemini",
|
|
68
|
-
type: "ai_chat",
|
|
69
|
-
context: "conversational_query",
|
|
70
|
-
confidence: "high"
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
keywords: ["you.com", "you-ai"],
|
|
74
|
-
platform: "You_AI",
|
|
75
|
-
type: "ai_search",
|
|
76
|
-
context: "search_query",
|
|
77
|
-
confidence: "medium"
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
keywords: ["character.ai", "character"],
|
|
81
|
-
platform: "Character_AI",
|
|
82
|
-
type: "ai_chat",
|
|
83
|
-
context: "character_interaction",
|
|
84
|
-
confidence: "high"
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
keywords: ["poe", "quora-poe"],
|
|
88
|
-
platform: "Poe",
|
|
89
|
-
type: "ai_chat",
|
|
90
|
-
context: "conversational_query",
|
|
91
|
-
confidence: "high"
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
keywords: ["huggingface", "hf-chat"],
|
|
95
|
-
platform: "HuggingFace",
|
|
96
|
-
type: "ai_chat",
|
|
97
|
-
context: "technical_query",
|
|
98
|
-
confidence: "medium"
|
|
99
|
-
},
|
|
100
|
-
{
|
|
101
|
-
keywords: ["replika"],
|
|
102
|
-
platform: "Replika",
|
|
103
|
-
type: "ai_chat",
|
|
104
|
-
context: "personal_assistant",
|
|
105
|
-
confidence: "high"
|
|
106
|
-
}
|
|
107
|
-
];
|
|
108
|
-
for (const platform of aiPlatforms) {
|
|
109
|
-
const matchedKeyword = platform.keywords.find(
|
|
110
|
-
(keyword) => allSources.includes(keyword)
|
|
111
|
-
);
|
|
112
|
-
if (matchedKeyword) {
|
|
113
|
-
aiData = {
|
|
114
|
-
platform: platform.platform,
|
|
115
|
-
type: platform.type,
|
|
116
|
-
context: platform.context,
|
|
117
|
-
confidence: platform.confidence,
|
|
118
|
-
detectionMethod: getDetectionMethod(matchedKeyword, referrer, utmSource, utmMedium),
|
|
119
|
-
detectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
120
|
-
};
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (aiData.platform === "none") {
|
|
125
|
-
aiData = detectFromUTMPatterns(utmSource, utmMedium, utmCampaign, utmContent);
|
|
126
|
-
}
|
|
127
|
-
return aiData;
|
|
128
|
-
}
|
|
129
|
-
function getDetectionMethod(matchedKeyword, referrer, utmSource, utmMedium) {
|
|
130
|
-
if (referrer.includes(matchedKeyword)) {
|
|
131
|
-
return "referrer";
|
|
132
|
-
} else if (utmSource.includes(matchedKeyword)) {
|
|
133
|
-
return "utm_source";
|
|
134
|
-
} else if (utmMedium.includes(matchedKeyword)) {
|
|
135
|
-
return "utm_medium";
|
|
136
|
-
}
|
|
137
|
-
return "utm_other";
|
|
138
|
-
}
|
|
139
|
-
function detectFromUTMPatterns(utmSource, utmMedium, utmCampaign, utmContent) {
|
|
140
|
-
const aiUTMPatterns = [
|
|
141
|
-
{
|
|
142
|
-
condition: utmMedium.includes("ai") || utmMedium.includes("chat"),
|
|
143
|
-
platform: "AI_Generic",
|
|
144
|
-
type: "ai_unknown",
|
|
145
|
-
context: "utm_tagged",
|
|
146
|
-
confidence: "medium"
|
|
147
|
-
},
|
|
148
|
-
{
|
|
149
|
-
condition: utmCampaign.includes("ai-assistant") || utmCampaign.includes("chatbot"),
|
|
150
|
-
platform: "AI_Campaign",
|
|
151
|
-
type: "ai_chat",
|
|
152
|
-
context: "campaign_driven",
|
|
153
|
-
confidence: "medium"
|
|
154
|
-
},
|
|
155
|
-
{
|
|
156
|
-
condition: utmContent.includes("ai-generated") || utmContent.includes("llm"),
|
|
157
|
-
platform: "AI_Content",
|
|
158
|
-
type: "ai_content",
|
|
159
|
-
context: "content_discovery",
|
|
160
|
-
confidence: "medium"
|
|
161
|
-
}
|
|
162
|
-
];
|
|
163
|
-
for (const pattern of aiUTMPatterns) {
|
|
164
|
-
if (pattern.condition) {
|
|
165
|
-
return {
|
|
166
|
-
platform: pattern.platform,
|
|
167
|
-
type: pattern.type,
|
|
168
|
-
context: pattern.context,
|
|
169
|
-
confidence: pattern.confidence,
|
|
170
|
-
detectionMethod: "utm_pattern",
|
|
171
|
-
detectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return {
|
|
176
|
-
platform: "none",
|
|
177
|
-
type: "unknown",
|
|
178
|
-
context: "unknown",
|
|
179
|
-
confidence: "low",
|
|
180
|
-
detectionMethod: "none",
|
|
181
|
-
detectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
function calculateAIJourneyAnalytics(journey, aiData) {
|
|
185
|
-
const isAIUser2 = aiData.platform !== "none";
|
|
186
|
-
if (!isAIUser2) {
|
|
187
|
-
return {
|
|
188
|
-
isAIUser: false,
|
|
189
|
-
aiTouchPoints: 0,
|
|
190
|
-
aiEntryPage: null,
|
|
191
|
-
behaviorPatterns: {
|
|
192
|
-
skipsBranding: false,
|
|
193
|
-
researchIntensive: false,
|
|
194
|
-
quickDecision: false,
|
|
195
|
-
technicalFocus: false
|
|
196
|
-
},
|
|
197
|
-
platformInsights: {
|
|
198
|
-
expectedJourney: "n/a",
|
|
199
|
-
actualVsPredicted: "matched",
|
|
200
|
-
platformTypicalBehavior: "n/a"
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
const aiEntryPage = journey.userJourney.find((tp) => tp.aiContext?.isAIReferral)?.page || journey.userJourney[0]?.page || null;
|
|
205
|
-
const aiTouchPoints = journey.userJourney.filter((tp) => tp.aiContext?.aiInfluenced).length;
|
|
206
|
-
const pages = journey.userJourney.map((tp) => tp.page.toLowerCase());
|
|
207
|
-
const pageTypes = journey.userJourney.map((tp) => tp.type.toLowerCase());
|
|
208
|
-
const behaviorPatterns = {
|
|
209
|
-
skipsBranding: !pages.some((p) => p.includes("about") || p === "/") && pages.length > 1,
|
|
210
|
-
researchIntensive: journey.userJourney.length > 5 || pageTypes.filter((t) => t.includes("solution") || t.includes("blog")).length > 2,
|
|
211
|
-
quickDecision: pages.some((p) => p.includes("contact") || p.includes("demo") || p.includes("pricing")) && journey.userJourney.length <= 3,
|
|
212
|
-
technicalFocus: pageTypes.some((t) => t.toLowerCase().includes("api") || t.toLowerCase().includes("developer")) || pages.some((p) => p.includes("api") || p.includes("developer"))
|
|
213
|
-
};
|
|
214
|
-
const platformInsights = {
|
|
215
|
-
expectedJourney: predictExpectedJourney(aiData.platform, aiEntryPage),
|
|
216
|
-
actualVsPredicted: evaluateJourneyPerformance(journey, aiData.platform),
|
|
217
|
-
platformTypicalBehavior: getPlatformTypicalBehavior(aiData.platform)
|
|
218
|
-
};
|
|
219
|
-
return {
|
|
220
|
-
isAIUser: isAIUser2,
|
|
221
|
-
aiTouchPoints,
|
|
222
|
-
aiEntryPage,
|
|
223
|
-
aiConversionPath: pages,
|
|
224
|
-
aiSessionDuration: calculateSessionDuration(journey),
|
|
225
|
-
aiPageDepth: journey.userJourney.length,
|
|
226
|
-
behaviorPatterns,
|
|
227
|
-
platformInsights
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
function predictExpectedJourney(platform, entryPage) {
|
|
231
|
-
const platformJourneys = {
|
|
232
|
-
"ChatGPT": "solutions_exploration",
|
|
233
|
-
"Perplexity": "research_deep_dive",
|
|
234
|
-
"Claude": "technical_evaluation",
|
|
235
|
-
"Bing_Copilot": "quick_overview",
|
|
236
|
-
"Google_Gemini": "comparative_analysis"
|
|
237
|
-
};
|
|
238
|
-
return platformJourneys[platform] || "general_exploration";
|
|
239
|
-
}
|
|
240
|
-
function evaluateJourneyPerformance(journey, platform) {
|
|
241
|
-
const pageCount = journey.userJourney.length;
|
|
242
|
-
const hasConversion = journey.userJourney.some(
|
|
243
|
-
(tp) => tp.page.includes("contact") || tp.page.includes("demo") || tp.page.includes("pricing")
|
|
244
|
-
);
|
|
245
|
-
if (hasConversion && pageCount >= 3) return "exceeded";
|
|
246
|
-
if (pageCount >= 2) return "matched";
|
|
247
|
-
return "underperformed";
|
|
248
|
-
}
|
|
249
|
-
function getPlatformTypicalBehavior(platform) {
|
|
250
|
-
const behaviors = {
|
|
251
|
-
"ChatGPT": "Direct to solutions, conversion-focused",
|
|
252
|
-
"Perplexity": "Research-heavy, multiple page views",
|
|
253
|
-
"Claude": "Technical documentation focus",
|
|
254
|
-
"Bing_Copilot": "Quick overview, efficiency-focused",
|
|
255
|
-
"Google_Gemini": "Comparative analysis, thorough evaluation"
|
|
256
|
-
};
|
|
257
|
-
return behaviors[platform] || "General exploration pattern";
|
|
258
|
-
}
|
|
259
|
-
function calculateSessionDuration(journey) {
|
|
260
|
-
if (journey.userJourney.length < 2) return 0;
|
|
261
|
-
const firstVisit = new Date(journey.userJourney[0].time);
|
|
262
|
-
const lastVisit = new Date(journey.userJourney[journey.userJourney.length - 1].time);
|
|
263
|
-
return Math.floor((lastVisit.getTime() - firstVisit.getTime()) / 1e3);
|
|
264
|
-
}
|
|
265
|
-
async function trackUserJourney() {
|
|
266
|
-
const STORAGE_KEY = "userJourney";
|
|
267
|
-
const SESSION_TIMEOUT = 30 * 60 * 1e3;
|
|
268
|
-
function getDeviceCategory() {
|
|
269
|
-
const userAgent = navigator.userAgent;
|
|
270
|
-
if (/tablet|ipad|playbook|silk/i.test(userAgent)) return "Tablet";
|
|
271
|
-
if (/mobile|iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test(userAgent)) return "Mobile";
|
|
272
|
-
return "Desktop";
|
|
273
|
-
}
|
|
274
|
-
function getBrowser() {
|
|
275
|
-
const userAgent = navigator.userAgent;
|
|
276
|
-
if (userAgent.includes("Chrome") && !userAgent.includes("Edg")) return "Chrome";
|
|
277
|
-
if (userAgent.includes("Firefox")) return "Firefox";
|
|
278
|
-
if (userAgent.includes("Safari") && !userAgent.includes("Chrome")) return "Safari";
|
|
279
|
-
if (userAgent.includes("Edg")) return "Edge";
|
|
280
|
-
if (userAgent.includes("Opera")) return "Opera";
|
|
281
|
-
return "Unknown";
|
|
282
|
-
}
|
|
283
|
-
function getDeviceName() {
|
|
284
|
-
const userAgent = navigator.userAgent;
|
|
285
|
-
if (/iPhone/.test(userAgent)) {
|
|
286
|
-
const match = userAgent.match(/iPhone\s*([^;]*)/);
|
|
287
|
-
return match ? `iPhone ${match[1].trim()}` : "iPhone";
|
|
288
|
-
}
|
|
289
|
-
if (/iPad/.test(userAgent)) {
|
|
290
|
-
const match = userAgent.match(/iPad\s*([^;]*)/);
|
|
291
|
-
return match ? `iPad ${match[1].trim()}` : "iPad";
|
|
292
|
-
}
|
|
293
|
-
if (/Android/.test(userAgent)) {
|
|
294
|
-
const modelMatch = userAgent.match(/;\s*([^)]*)\s*\)/);
|
|
295
|
-
if (modelMatch) {
|
|
296
|
-
const deviceInfo = modelMatch[1].trim();
|
|
297
|
-
const cleanDevice = deviceInfo.replace(/wv/g, "").replace(/Build\/.*$/g, "").replace(/\s+/g, " ").trim();
|
|
298
|
-
return cleanDevice || "Android Device";
|
|
299
|
-
}
|
|
300
|
-
return "Android Device";
|
|
301
|
-
}
|
|
302
|
-
if (/Windows/.test(userAgent)) {
|
|
303
|
-
if (/Windows NT 10/.test(userAgent)) return "Windows 10/11 PC";
|
|
304
|
-
if (/Windows NT 6\.3/.test(userAgent)) return "Windows 8.1 PC";
|
|
305
|
-
if (/Windows NT 6\.2/.test(userAgent)) return "Windows 8 PC";
|
|
306
|
-
if (/Windows NT 6\.1/.test(userAgent)) return "Windows 7 PC";
|
|
307
|
-
return "Windows PC";
|
|
308
|
-
}
|
|
309
|
-
if (/Macintosh/.test(userAgent)) {
|
|
310
|
-
if (/Intel/.test(userAgent)) return "Mac (Intel)";
|
|
311
|
-
if (/Apple Silicon|ARM64/.test(userAgent)) return "Mac (Apple Silicon)";
|
|
312
|
-
return "Mac";
|
|
313
|
-
}
|
|
314
|
-
if (/Linux/.test(userAgent)) {
|
|
315
|
-
return "Linux PC";
|
|
316
|
-
}
|
|
317
|
-
if (/BlackBerry/.test(userAgent)) return "BlackBerry";
|
|
318
|
-
if (/Windows Phone/.test(userAgent)) return "Windows Phone";
|
|
319
|
-
const deviceCategory = getDeviceCategory();
|
|
320
|
-
return deviceCategory.charAt(0).toUpperCase();
|
|
321
|
-
}
|
|
322
|
-
function extractDomainFromReferrer(referrer) {
|
|
323
|
-
if (!referrer) return "Unknown";
|
|
324
|
-
try {
|
|
325
|
-
const url = new URL(referrer);
|
|
326
|
-
const hostname = url.hostname;
|
|
327
|
-
const domain = hostname.replace(/^www\./, "");
|
|
328
|
-
const domainParts = domain.split(".");
|
|
329
|
-
if (domainParts.length >= 2) {
|
|
330
|
-
return domainParts[0];
|
|
331
|
-
}
|
|
332
|
-
return domain || "Unknown";
|
|
333
|
-
} catch (error) {
|
|
334
|
-
return "Unknown";
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
function getUTMParameters(isFirstVisit, firstVisitUTM) {
|
|
338
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
339
|
-
const hasCurrentUTM = urlParams.has("utm_source") || urlParams.has("utm_medium") || urlParams.has("utm_campaign");
|
|
340
|
-
if (isFirstVisit || hasCurrentUTM) {
|
|
341
|
-
if (hasCurrentUTM) {
|
|
342
|
-
return {
|
|
343
|
-
source: urlParams.get("utm_source") || "",
|
|
344
|
-
medium: urlParams.get("utm_medium") || "",
|
|
345
|
-
campaign: urlParams.get("utm_campaign") || "",
|
|
346
|
-
content: urlParams.get("utm_content") || "",
|
|
347
|
-
term: urlParams.get("utm_term") || ""
|
|
348
|
-
};
|
|
349
|
-
} else {
|
|
350
|
-
const ref = document.referrer;
|
|
351
|
-
return {
|
|
352
|
-
source: ref && ref.trim() !== "" ? ref : "direct",
|
|
353
|
-
medium: ref && ref.trim() !== "" ? "referral" : "",
|
|
354
|
-
campaign: "",
|
|
355
|
-
content: "",
|
|
356
|
-
term: ""
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
} else {
|
|
360
|
-
return firstVisitUTM || {
|
|
361
|
-
source: "Unknown",
|
|
362
|
-
medium: "organic",
|
|
363
|
-
campaign: "unknown"
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
function getPageCategories() {
|
|
368
|
-
try {
|
|
369
|
-
if (typeof window.pageCategories !== "undefined" && Array.isArray(window.pageCategories) && window.pageCategories.length > 0) {
|
|
370
|
-
return window.pageCategories;
|
|
371
|
-
}
|
|
372
|
-
return ["Not applicable"];
|
|
373
|
-
} catch (error) {
|
|
374
|
-
console.warn("Error accessing pageCategories:", error);
|
|
375
|
-
return ["Not applicable"];
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
function hasVisibleUTM() {
|
|
379
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
380
|
-
return urlParams.has("utm_source") || urlParams.has("utm_medium") || urlParams.has("utm_campaign");
|
|
381
|
-
}
|
|
382
|
-
function getPageType(url) {
|
|
383
|
-
const path = url.split("?")[0].toLowerCase();
|
|
384
|
-
const typeConfig = {
|
|
385
|
-
exactMatches: {
|
|
386
|
-
"/": "Home",
|
|
387
|
-
"/home": "Home",
|
|
388
|
-
"/blog": "Blog listing",
|
|
389
|
-
"/about-us": "About us",
|
|
390
|
-
"/contact-us": "Contact",
|
|
391
|
-
"/privacy-policy": "Privacy policy",
|
|
392
|
-
"/terms-of-service": "Terms of service",
|
|
393
|
-
"/careers": "Careers",
|
|
394
|
-
"/customer-stories": "Customer stories listing",
|
|
395
|
-
"/events": "Events listing",
|
|
396
|
-
"/infographics": "Infographics listing",
|
|
397
|
-
"/newsroom": "Newsroom",
|
|
398
|
-
"/releases": "Releases listing"
|
|
399
|
-
},
|
|
400
|
-
pathStartsWith: [
|
|
401
|
-
{ pattern: "/blog/", type: "Blog" },
|
|
402
|
-
{ pattern: "/customer-stories/", type: "Customer story" },
|
|
403
|
-
{ pattern: "/case-studies/", type: "Case study" },
|
|
404
|
-
{ pattern: "/solutions/", type: "Solution" },
|
|
405
|
-
{ pattern: "/events/", type: "Event" },
|
|
406
|
-
{ pattern: "/news/", type: "News" },
|
|
407
|
-
{ pattern: "/press-releases/", type: "Press release" },
|
|
408
|
-
{ pattern: "/releases/", type: "Release" }
|
|
409
|
-
]
|
|
410
|
-
};
|
|
411
|
-
if (typeConfig.exactMatches[path]) {
|
|
412
|
-
return typeConfig.exactMatches[path];
|
|
413
|
-
}
|
|
414
|
-
for (const item of typeConfig.pathStartsWith) {
|
|
415
|
-
if (path.startsWith(item.pattern)) {
|
|
416
|
-
return item.type;
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
return "Other";
|
|
420
|
-
}
|
|
421
|
-
function isValidSession(journey) {
|
|
422
|
-
if (!journey.userJourney || journey.userJourney.length === 0) return false;
|
|
423
|
-
const lastVisit = new Date(journey.userJourney[journey.userJourney.length - 1].time);
|
|
424
|
-
const now = /* @__PURE__ */ new Date();
|
|
425
|
-
return now.getTime() - lastVisit.getTime() < SESSION_TIMEOUT;
|
|
426
|
-
}
|
|
427
|
-
return new Promise((resolve) => {
|
|
428
|
-
setTimeout(() => {
|
|
429
|
-
try {
|
|
430
|
-
const aiData = detectAIPlatform();
|
|
431
|
-
let journey = null;
|
|
432
|
-
const storedData = localStorage.getItem(STORAGE_KEY);
|
|
433
|
-
if (storedData) {
|
|
434
|
-
const parsedData = JSON.parse(storedData);
|
|
435
|
-
if (isValidSession(parsedData)) {
|
|
436
|
-
journey = parsedData;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
if (!journey) {
|
|
440
|
-
journey = {
|
|
441
|
-
userJourney: [],
|
|
442
|
-
origin: window.location.hostname,
|
|
443
|
-
deviceCategory: getDeviceCategory(),
|
|
444
|
-
browser: getBrowser(),
|
|
445
|
-
device: getDeviceName(),
|
|
446
|
-
formDetails: {
|
|
447
|
-
formId: "",
|
|
448
|
-
formName: "",
|
|
449
|
-
firstName: "",
|
|
450
|
-
lastName: "",
|
|
451
|
-
email: "",
|
|
452
|
-
phone: ""
|
|
453
|
-
},
|
|
454
|
-
// Initialize AI data
|
|
455
|
-
aiData,
|
|
456
|
-
aiJourneyAnalytics: {
|
|
457
|
-
isAIUser: false,
|
|
458
|
-
aiTouchPoints: 0,
|
|
459
|
-
aiEntryPage: null,
|
|
460
|
-
behaviorPatterns: {
|
|
461
|
-
skipsBranding: false,
|
|
462
|
-
researchIntensive: false,
|
|
463
|
-
quickDecision: false,
|
|
464
|
-
technicalFocus: false
|
|
465
|
-
},
|
|
466
|
-
platformInsights: {
|
|
467
|
-
expectedJourney: "n/a",
|
|
468
|
-
actualVsPredicted: "matched",
|
|
469
|
-
platformTypicalBehavior: "n/a"
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
|
-
};
|
|
473
|
-
} else {
|
|
474
|
-
const updatedAIData = handleAIDetection_LatestPlatform(journey.aiData || {
|
|
475
|
-
platform: "none",
|
|
476
|
-
type: "unknown",
|
|
477
|
-
context: "unknown",
|
|
478
|
-
confidence: "low",
|
|
479
|
-
detectionMethod: "none",
|
|
480
|
-
detectedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
481
|
-
}, aiData);
|
|
482
|
-
journey.aiData = updatedAIData;
|
|
483
|
-
journey.aiJourneyAnalytics = calculateAIJourneyAnalytics(journey, updatedAIData);
|
|
484
|
-
}
|
|
485
|
-
if (!journey.formDetails) {
|
|
486
|
-
journey.formDetails = {
|
|
487
|
-
formId: "",
|
|
488
|
-
formName: "",
|
|
489
|
-
firstName: "",
|
|
490
|
-
lastName: "",
|
|
491
|
-
email: "",
|
|
492
|
-
phone: ""
|
|
493
|
-
};
|
|
494
|
-
}
|
|
495
|
-
if (!journey.device) {
|
|
496
|
-
journey.device = getDeviceName();
|
|
497
|
-
}
|
|
498
|
-
if (!journey) {
|
|
499
|
-
console.error("Journey initialization failed");
|
|
500
|
-
resolve(null);
|
|
501
|
-
return;
|
|
502
|
-
}
|
|
503
|
-
const currentUrl = window.location.pathname;
|
|
504
|
-
const currentTime = (/* @__PURE__ */ new Date()).toISOString();
|
|
505
|
-
const lastVisit = journey.userJourney[journey.userJourney.length - 1];
|
|
506
|
-
if (lastVisit && lastVisit.page === currentUrl) {
|
|
507
|
-
lastVisit.time = currentTime;
|
|
508
|
-
} else {
|
|
509
|
-
const isFirstVisit = journey.userJourney.length === 0;
|
|
510
|
-
const firstVisitUTM = isFirstVisit ? void 0 : journey.userJourney[0].utm;
|
|
511
|
-
const isAIReferral = isFirstVisit && aiData.platform !== "none";
|
|
512
|
-
const aiInfluenced = journey.aiData.platform !== "none";
|
|
513
|
-
const touchPoint = {
|
|
514
|
-
touchPoint: journey.userJourney.length + 1,
|
|
515
|
-
page: currentUrl,
|
|
516
|
-
title: document.title || "Untitled",
|
|
517
|
-
type: getPageType(currentUrl),
|
|
518
|
-
category: getPageCategories(),
|
|
519
|
-
time: currentTime,
|
|
520
|
-
utmVisibility: hasVisibleUTM() ? "visible" : "hidden",
|
|
521
|
-
utm: getUTMParameters(isFirstVisit, firstVisitUTM),
|
|
522
|
-
// Add AI context
|
|
523
|
-
aiContext: {
|
|
524
|
-
isAIReferral,
|
|
525
|
-
aiPlatform: aiInfluenced ? aiData.platform : void 0,
|
|
526
|
-
aiInfluenced,
|
|
527
|
-
aiJourneyStage: isAIReferral ? "entry" : journey.userJourney.length === 0 ? "exploration" : currentUrl.includes("pricing") || currentUrl.includes("contact") ? "decision" : "consideration"
|
|
528
|
-
}
|
|
529
|
-
};
|
|
530
|
-
journey.userJourney.push(touchPoint);
|
|
531
|
-
}
|
|
532
|
-
journey.aiJourneyAnalytics = calculateAIJourneyAnalytics(journey, journey.aiData);
|
|
533
|
-
localStorage.setItem(STORAGE_KEY, JSON.stringify(journey));
|
|
534
|
-
initializeFormTracking();
|
|
535
|
-
if (journey.aiData.platform !== "none") {
|
|
536
|
-
sendAITrackingEvents(journey, currentUrl);
|
|
537
|
-
}
|
|
538
|
-
resolve(journey);
|
|
539
|
-
} catch (error) {
|
|
540
|
-
console.error("Error tracking user journey:", error);
|
|
541
|
-
resolve(null);
|
|
542
|
-
}
|
|
543
|
-
}, 200);
|
|
544
|
-
});
|
|
545
|
-
}
|
|
546
|
-
function sendAITrackingEvents(journey, currentPage) {
|
|
547
|
-
const aiData = journey.aiData;
|
|
548
|
-
const currentURL = new URL(window.location.href);
|
|
549
|
-
const eventData = {
|
|
550
|
-
ai_platform: aiData.platform,
|
|
551
|
-
ai_type: aiData.type,
|
|
552
|
-
ai_context: aiData.context,
|
|
553
|
-
ai_confidence: aiData.confidence,
|
|
554
|
-
detection_method: aiData.detectionMethod,
|
|
555
|
-
landing_page: currentPage,
|
|
556
|
-
page_category: getPageCategory(currentPage),
|
|
557
|
-
// UTM data
|
|
558
|
-
utm_source: currentURL.searchParams.get("utm_source") || "",
|
|
559
|
-
utm_medium: currentURL.searchParams.get("utm_medium") || "",
|
|
560
|
-
utm_campaign: currentURL.searchParams.get("utm_campaign") || "",
|
|
561
|
-
utm_content: currentURL.searchParams.get("utm_content") || "",
|
|
562
|
-
utm_term: currentURL.searchParams.get("utm_term") || "",
|
|
563
|
-
// Journey data
|
|
564
|
-
is_ai_user: journey.aiJourneyAnalytics.isAIUser,
|
|
565
|
-
ai_touchpoints: journey.aiJourneyAnalytics.aiTouchPoints,
|
|
566
|
-
session_start: aiData.detectedAt
|
|
567
|
-
};
|
|
568
|
-
console.debug("AI tracking event data:", eventData);
|
|
569
|
-
}
|
|
570
|
-
function getPageCategory(pathname) {
|
|
571
|
-
if (pathname === "/") return "Homepage";
|
|
572
|
-
if (pathname.includes("/platform")) return "Platform";
|
|
573
|
-
if (pathname.includes("/solutions")) return "Solutions";
|
|
574
|
-
if (pathname.includes("/blog")) return "Blog";
|
|
575
|
-
if (pathname.includes("/developers") || pathname.includes("/api")) return "Developer";
|
|
576
|
-
if (pathname.includes("/contact") || pathname.includes("/demo")) return "Contact";
|
|
577
|
-
if (pathname.includes("/pricing")) return "Pricing";
|
|
578
|
-
if (pathname.includes("/about") || pathname.includes("/company")) return "Company";
|
|
579
|
-
return "Other";
|
|
580
|
-
}
|
|
581
|
-
function initializeFormTracking() {
|
|
582
|
-
const existingInputs = document.querySelectorAll("input[ph-form-field], textarea[ph-form-field], select[ph-form-field]");
|
|
583
|
-
existingInputs.forEach((input) => {
|
|
584
|
-
input.removeEventListener("input", handleFormFieldChange);
|
|
585
|
-
input.removeEventListener("change", handleFormFieldChange);
|
|
586
|
-
});
|
|
587
|
-
const formFields = document.querySelectorAll("input[ph-form-field], textarea[ph-form-field], select[ph-form-field]");
|
|
588
|
-
formFields.forEach((field) => {
|
|
589
|
-
field.addEventListener("input", handleFormFieldChange);
|
|
590
|
-
field.addEventListener("change", handleFormFieldChange);
|
|
591
|
-
});
|
|
592
|
-
initializeFormData();
|
|
593
|
-
}
|
|
594
|
-
function initializeFormData() {
|
|
595
|
-
const journey = getUserJourney();
|
|
596
|
-
if (!journey) return;
|
|
597
|
-
const formContainer = document.querySelector("[ph-form-name]");
|
|
598
|
-
if (!formContainer) return;
|
|
599
|
-
const formName = formContainer.getAttribute("ph-form-name");
|
|
600
|
-
const formId = formContainer.getAttribute("ph-form-id") || "form-1";
|
|
601
|
-
if (!formName) return;
|
|
602
|
-
if (!journey.formDetails.formName) {
|
|
603
|
-
journey.formDetails.formId = formId;
|
|
604
|
-
journey.formDetails.formName = formName;
|
|
605
|
-
}
|
|
606
|
-
localStorage.setItem("userJourney", JSON.stringify(journey));
|
|
607
|
-
}
|
|
608
|
-
function handleFormFieldChange(event) {
|
|
609
|
-
const target = event.target;
|
|
610
|
-
const fieldName = target.getAttribute("ph-form-field");
|
|
611
|
-
if (!fieldName) return;
|
|
612
|
-
const formContainer = target.closest("[ph-form-name]");
|
|
613
|
-
if (!formContainer) return;
|
|
614
|
-
const formName = formContainer.getAttribute("ph-form-name");
|
|
615
|
-
const formId = formContainer.getAttribute("ph-form-id") || "form-1";
|
|
616
|
-
if (!formName) return;
|
|
617
|
-
updateFormData(formName, formId, fieldName, target.value);
|
|
618
|
-
}
|
|
619
|
-
function updateFormData(formName, formId, fieldName, value) {
|
|
620
|
-
try {
|
|
621
|
-
const journey = getUserJourney();
|
|
622
|
-
if (!journey) return false;
|
|
623
|
-
journey.formDetails.formId = formId;
|
|
624
|
-
journey.formDetails.formName = formName;
|
|
625
|
-
switch (fieldName) {
|
|
626
|
-
case "firstName":
|
|
627
|
-
journey.formDetails.firstName = value;
|
|
628
|
-
break;
|
|
629
|
-
case "lastName":
|
|
630
|
-
journey.formDetails.lastName = value;
|
|
631
|
-
break;
|
|
632
|
-
case "email":
|
|
633
|
-
journey.formDetails.email = value;
|
|
634
|
-
break;
|
|
635
|
-
case "phone":
|
|
636
|
-
journey.formDetails.phone = value;
|
|
637
|
-
break;
|
|
638
|
-
default:
|
|
639
|
-
console.warn(`Unknown field: ${fieldName}`);
|
|
640
|
-
return false;
|
|
641
|
-
}
|
|
642
|
-
localStorage.setItem("userJourney", JSON.stringify(journey));
|
|
643
|
-
return true;
|
|
644
|
-
} catch (error) {
|
|
645
|
-
console.error("Error updating form data:", error);
|
|
646
|
-
return false;
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
function getUserJourney() {
|
|
650
|
-
try {
|
|
651
|
-
const storedData = localStorage.getItem("userJourney");
|
|
652
|
-
return storedData ? JSON.parse(storedData) : null;
|
|
653
|
-
} catch (error) {
|
|
654
|
-
console.error("Error getting user journey:", error);
|
|
655
|
-
return null;
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
function clearUserJourney() {
|
|
659
|
-
localStorage.removeItem("userJourney");
|
|
660
|
-
}
|
|
661
|
-
function updatePageCategories(categories) {
|
|
662
|
-
try {
|
|
663
|
-
const journey = getUserJourney();
|
|
664
|
-
if (!journey || journey.userJourney.length === 0) return false;
|
|
665
|
-
const lastVisit = journey.userJourney[journey.userJourney.length - 1];
|
|
666
|
-
lastVisit.category = categories.length > 0 ? categories : ["Not applicable"];
|
|
667
|
-
localStorage.setItem("userJourney", JSON.stringify(journey));
|
|
668
|
-
return true;
|
|
669
|
-
} catch (error) {
|
|
670
|
-
console.error("Error updating page categories:", error);
|
|
671
|
-
return false;
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
function updatePageType(type) {
|
|
675
|
-
try {
|
|
676
|
-
const journey = getUserJourney();
|
|
677
|
-
if (!journey || journey.userJourney.length === 0) return false;
|
|
678
|
-
const lastVisit = journey.userJourney[journey.userJourney.length - 1];
|
|
679
|
-
lastVisit.type = type;
|
|
680
|
-
localStorage.setItem("userJourney", JSON.stringify(journey));
|
|
681
|
-
return true;
|
|
682
|
-
} catch (error) {
|
|
683
|
-
console.error("Error updating page type:", error);
|
|
684
|
-
return false;
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
function getJourneyStats() {
|
|
688
|
-
const journey = getUserJourney();
|
|
689
|
-
if (!journey || journey.userJourney.length === 0) return null;
|
|
690
|
-
const firstVisit = journey.userJourney[0];
|
|
691
|
-
const lastVisit = journey.userJourney[journey.userJourney.length - 1];
|
|
692
|
-
const sessionDuration = new Date(lastVisit.time).getTime() - new Date(firstVisit.time).getTime();
|
|
693
|
-
let aiStats;
|
|
694
|
-
if (journey.aiJourneyAnalytics.isAIUser) {
|
|
695
|
-
const aiEntryPoint = journey.userJourney.find((tp) => tp.aiContext?.isAIReferral);
|
|
696
|
-
const aiStartTime = aiEntryPoint ? new Date(aiEntryPoint.time) : new Date(firstVisit.time);
|
|
697
|
-
const aiSessionDuration = new Date(lastVisit.time).getTime() - aiStartTime.getTime();
|
|
698
|
-
const hasConversion = journey.userJourney.some(
|
|
699
|
-
(tp) => tp.page.includes("contact") || tp.page.includes("demo") || tp.page.includes("pricing")
|
|
700
|
-
);
|
|
701
|
-
aiStats = {
|
|
702
|
-
aiSessionDuration: Math.floor(aiSessionDuration / 1e3),
|
|
703
|
-
aiPages: journey.aiJourneyAnalytics.aiTouchPoints,
|
|
704
|
-
aiConversionTime: hasConversion ? Math.floor(aiSessionDuration / 1e3) : void 0,
|
|
705
|
-
aiEngagementScore: calculateAIEngagementScore(journey),
|
|
706
|
-
aiValueScore: calculateAIValueScore(journey)
|
|
707
|
-
};
|
|
708
|
-
}
|
|
709
|
-
return {
|
|
710
|
-
totalPages: journey.userJourney.length,
|
|
711
|
-
sessionDuration: Math.floor(sessionDuration / 1e3),
|
|
712
|
-
firstPage: firstVisit.page,
|
|
713
|
-
lastPage: lastVisit.page,
|
|
714
|
-
aiStats
|
|
715
|
-
};
|
|
716
|
-
}
|
|
717
|
-
function calculateAIEngagementScore(journey) {
|
|
718
|
-
let score = 0;
|
|
719
|
-
if (journey.aiJourneyAnalytics.isAIUser) score += 20;
|
|
720
|
-
const pageCount = journey.userJourney.length;
|
|
721
|
-
if (pageCount >= 5) score += 30;
|
|
722
|
-
else if (pageCount >= 3) score += 20;
|
|
723
|
-
else if (pageCount >= 2) score += 10;
|
|
724
|
-
const patterns = journey.aiJourneyAnalytics.behaviorPatterns;
|
|
725
|
-
if (patterns.researchIntensive) score += 25;
|
|
726
|
-
if (patterns.technicalFocus) score += 20;
|
|
727
|
-
if (patterns.quickDecision) score += 15;
|
|
728
|
-
const hasHighValuePages = journey.userJourney.some(
|
|
729
|
-
(tp) => tp.type.toLowerCase().includes("solution") || tp.type.toLowerCase().includes("pricing") || tp.type.toLowerCase().includes("demo")
|
|
730
|
-
);
|
|
731
|
-
if (hasHighValuePages) score += 15;
|
|
732
|
-
return Math.min(score, 100);
|
|
733
|
-
}
|
|
734
|
-
function calculateAIValueScore(journey) {
|
|
735
|
-
let score = 0;
|
|
736
|
-
if (journey.aiData.confidence === "high") score += 20;
|
|
737
|
-
else if (journey.aiData.confidence === "medium") score += 10;
|
|
738
|
-
const highValuePlatforms = ["ChatGPT", "Claude", "Google_Gemini"];
|
|
739
|
-
if (highValuePlatforms.includes(journey.aiData.platform)) score += 15;
|
|
740
|
-
const pages = journey.userJourney.map((tp) => tp.page.toLowerCase());
|
|
741
|
-
if (pages.some((p) => p.includes("pricing"))) score += 25;
|
|
742
|
-
if (pages.some((p) => p.includes("contact") || p.includes("demo"))) score += 30;
|
|
743
|
-
if (pages.some((p) => p.includes("api") || p.includes("developer"))) score += 20;
|
|
744
|
-
const hasFormData = journey.formDetails.email || journey.formDetails.firstName;
|
|
745
|
-
if (hasFormData) score += 20;
|
|
746
|
-
return Math.min(score, 100);
|
|
747
|
-
}
|
|
748
|
-
function getFormData() {
|
|
749
|
-
const journey = getUserJourney();
|
|
750
|
-
return journey ? journey.formDetails : null;
|
|
751
|
-
}
|
|
752
|
-
function getFormFieldValue(fieldName) {
|
|
753
|
-
const journey = getUserJourney();
|
|
754
|
-
if (!journey) return null;
|
|
755
|
-
return journey.formDetails[fieldName] || null;
|
|
756
|
-
}
|
|
757
|
-
function setFormData(fieldName, value) {
|
|
758
|
-
try {
|
|
759
|
-
const journey = getUserJourney();
|
|
760
|
-
if (!journey) return false;
|
|
761
|
-
journey.formDetails[fieldName] = value;
|
|
762
|
-
localStorage.setItem("userJourney", JSON.stringify(journey));
|
|
763
|
-
return true;
|
|
764
|
-
} catch (error) {
|
|
765
|
-
console.error("Error setting form data:", error);
|
|
766
|
-
return false;
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
function setFormDetails(formId, formName) {
|
|
770
|
-
try {
|
|
771
|
-
const journey = getUserJourney();
|
|
772
|
-
if (!journey) return false;
|
|
773
|
-
journey.formDetails.formId = formId;
|
|
774
|
-
journey.formDetails.formName = formName;
|
|
775
|
-
localStorage.setItem("userJourney", JSON.stringify(journey));
|
|
776
|
-
return true;
|
|
777
|
-
} catch (error) {
|
|
778
|
-
console.error("Error setting form details:", error);
|
|
779
|
-
return false;
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
function reinitializeFormTracking() {
|
|
783
|
-
initializeFormTracking();
|
|
784
|
-
}
|
|
785
|
-
function getAIData() {
|
|
786
|
-
const journey = getUserJourney();
|
|
787
|
-
return journey ? journey.aiData : null;
|
|
788
|
-
}
|
|
789
|
-
function getAIJourneyAnalytics() {
|
|
790
|
-
const journey = getUserJourney();
|
|
791
|
-
return journey ? journey.aiJourneyAnalytics : null;
|
|
792
|
-
}
|
|
793
|
-
function isAIUser() {
|
|
794
|
-
const journey = getUserJourney();
|
|
795
|
-
return journey ? journey.aiJourneyAnalytics.isAIUser : false;
|
|
796
|
-
}
|
|
797
|
-
function getAIPlatform() {
|
|
798
|
-
const journey = getUserJourney();
|
|
799
|
-
return journey && journey.aiData.platform !== "none" ? journey.aiData.platform : null;
|
|
800
|
-
}
|
|
801
|
-
function forceAIDetection() {
|
|
802
|
-
const aiData = detectAIPlatform();
|
|
803
|
-
const journey = getUserJourney();
|
|
804
|
-
if (journey) {
|
|
805
|
-
journey.aiData = aiData;
|
|
806
|
-
journey.aiJourneyAnalytics = calculateAIJourneyAnalytics(journey, aiData);
|
|
807
|
-
localStorage.setItem("userJourney", JSON.stringify(journey));
|
|
808
|
-
}
|
|
809
|
-
return aiData;
|
|
810
|
-
}
|
|
811
|
-
document.addEventListener("DOMContentLoaded", () => {
|
|
812
|
-
trackUserJourney();
|
|
813
|
-
});
|
|
814
|
-
if (document.readyState === "loading") {
|
|
815
|
-
document.addEventListener("DOMContentLoaded", () => {
|
|
816
|
-
trackUserJourney();
|
|
817
|
-
});
|
|
818
|
-
} else {
|
|
819
|
-
trackUserJourney();
|
|
820
|
-
}
|
|
821
|
-
window.trackUserJourney = trackUserJourney;
|
|
822
|
-
window.getUserJourney = getUserJourney;
|
|
823
|
-
window.clearUserJourney = clearUserJourney;
|
|
824
|
-
window.updatePageType = updatePageType;
|
|
825
|
-
window.updatePageCategories = updatePageCategories;
|
|
826
|
-
window.getJourneyStats = getJourneyStats;
|
|
827
|
-
window.getFormData = getFormData;
|
|
828
|
-
window.getFormFieldValue = getFormFieldValue;
|
|
829
|
-
window.setFormData = setFormData;
|
|
830
|
-
window.setFormDetails = setFormDetails;
|
|
831
|
-
window.reinitializeFormTracking = reinitializeFormTracking;
|
|
832
|
-
window.getAIData = getAIData;
|
|
833
|
-
window.getAIJourneyAnalytics = getAIJourneyAnalytics;
|
|
834
|
-
window.isAIUser = isAIUser;
|
|
835
|
-
window.getAIPlatform = getAIPlatform;
|
|
836
|
-
window.forceAIDetection = forceAIDetection;
|
|
837
|
-
window.detectAIPlatform = detectAIPlatform;
|
|
838
|
-
})();
|
|
839
|
-
//# sourceMappingURL=user-journey.js.map
|
|
1
|
+
"use strict";(()=>{function U(e,t){return t.platform!=="none"?t:e}function D(){let t=document.referrer.toLowerCase(),n=new URL(window.location.href),a=n.searchParams.get("utm_source")?.toLowerCase()||"",i=n.searchParams.get("utm_medium")?.toLowerCase()||"",s=n.searchParams.get("utm_campaign")?.toLowerCase()||"",g=n.searchParams.get("utm_content")?.toLowerCase()||"",p=`${t} ${a} ${i} ${s} ${g}`,d={platform:"none",type:"unknown",context:"unknown",confidence:"low",detectionMethod:"none",detectedAt:new Date().toISOString()},c=[{keywords:["chatgpt","openai","chat.openai"],platform:"ChatGPT",type:"ai_chat",context:"conversational_query",confidence:"high"},{keywords:["perplexity"],platform:"Perplexity",type:"ai_search",context:"research_query",confidence:"high"},{keywords:["claude","anthropic"],platform:"Claude",type:"ai_chat",context:"conversational_query",confidence:"high"},{keywords:["bing","copilot","microsoft-copilot"],platform:"Bing_Copilot",type:"ai_chat",context:"conversational_query",confidence:"medium"},{keywords:["gemini","bard","google-ai"],platform:"Google_Gemini",type:"ai_chat",context:"conversational_query",confidence:"high"},{keywords:["you.com","you-ai"],platform:"You_AI",type:"ai_search",context:"search_query",confidence:"medium"},{keywords:["character.ai","character"],platform:"Character_AI",type:"ai_chat",context:"character_interaction",confidence:"high"},{keywords:["poe","quora-poe"],platform:"Poe",type:"ai_chat",context:"conversational_query",confidence:"high"},{keywords:["huggingface","hf-chat"],platform:"HuggingFace",type:"ai_chat",context:"technical_query",confidence:"medium"},{keywords:["replika"],platform:"Replika",type:"ai_chat",context:"personal_assistant",confidence:"high"}];for(let h of c){let r=h.keywords.find(u=>p.includes(u));if(r){d={platform:h.platform,type:h.type,context:h.context,confidence:h.confidence,detectionMethod:x(r,t,a,i),detectedAt:new Date().toISOString()};break}}return d.platform==="none"&&(d=b(a,i,s,g)),d}function x(e,t,n,a){return t.includes(e)?"referrer":n.includes(e)?"utm_source":a.includes(e)?"utm_medium":"utm_other"}function b(e,t,n,a){let i=[{condition:t.includes("ai")||t.includes("chat"),platform:"AI_Generic",type:"ai_unknown",context:"utm_tagged",confidence:"medium"},{condition:n.includes("ai-assistant")||n.includes("chatbot"),platform:"AI_Campaign",type:"ai_chat",context:"campaign_driven",confidence:"medium"},{condition:a.includes("ai-generated")||a.includes("llm"),platform:"AI_Content",type:"ai_content",context:"content_discovery",confidence:"medium"}];for(let s of i)if(s.condition)return{platform:s.platform,type:s.type,context:s.context,confidence:s.confidence,detectionMethod:"utm_pattern",detectedAt:new Date().toISOString()};return{platform:"none",type:"unknown",context:"unknown",confidence:"low",detectionMethod:"none",detectedAt:new Date().toISOString()}}function J(e,t){let n=t.platform!=="none";if(!n)return{isAIUser:!1,aiTouchPoints:0,aiEntryPage:null,behaviorPatterns:{skipsBranding:!1,researchIntensive:!1,quickDecision:!1,technicalFocus:!1},platformInsights:{expectedJourney:"n/a",actualVsPredicted:"matched",platformTypicalBehavior:"n/a"}};let a=e.userJourney.find(c=>c.aiContext?.isAIReferral)?.page||e.userJourney[0]?.page||null,i=e.userJourney.filter(c=>c.aiContext?.aiInfluenced).length,s=e.userJourney.map(c=>c.page.toLowerCase()),g=e.userJourney.map(c=>c.type.toLowerCase()),p={skipsBranding:!s.some(c=>c.includes("about")||c==="/")&&s.length>1,researchIntensive:e.userJourney.length>5||g.filter(c=>c.includes("solution")||c.includes("blog")).length>2,quickDecision:s.some(c=>c.includes("contact")||c.includes("demo")||c.includes("pricing"))&&e.userJourney.length<=3,technicalFocus:g.some(c=>c.toLowerCase().includes("api")||c.toLowerCase().includes("developer"))||s.some(c=>c.includes("api")||c.includes("developer"))},d={expectedJourney:k(t.platform,a),actualVsPredicted:F(e,t.platform),platformTypicalBehavior:M(t.platform)};return{isAIUser:n,aiTouchPoints:i,aiEntryPage:a,aiConversionPath:s,aiSessionDuration:N(e),aiPageDepth:e.userJourney.length,behaviorPatterns:p,platformInsights:d}}function k(e,t){return{ChatGPT:"solutions_exploration",Perplexity:"research_deep_dive",Claude:"technical_evaluation",Bing_Copilot:"quick_overview",Google_Gemini:"comparative_analysis"}[e]||"general_exploration"}function F(e,t){let n=e.userJourney.length;return e.userJourney.some(i=>i.page.includes("contact")||i.page.includes("demo")||i.page.includes("pricing"))&&n>=3?"exceeded":n>=2?"matched":"underperformed"}function M(e){return{ChatGPT:"Direct to solutions, conversion-focused",Perplexity:"Research-heavy, multiple page views",Claude:"Technical documentation focus",Bing_Copilot:"Quick overview, efficiency-focused",Google_Gemini:"Comparative analysis, thorough evaluation"}[e]||"General exploration pattern"}function N(e){if(e.userJourney.length<2)return 0;let t=new Date(e.userJourney[0].time),n=new Date(e.userJourney[e.userJourney.length-1].time);return Math.floor((n.getTime()-t.getTime())/1e3)}async function A(){let e="userJourney";function n(){let r=navigator.userAgent;return/tablet|ipad|playbook|silk/i.test(r)?"Tablet":/mobile|iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test(r)?"Mobile":"Desktop"}function a(){let r=navigator.userAgent;return r.includes("Chrome")&&!r.includes("Edg")?"Chrome":r.includes("Firefox")?"Firefox":r.includes("Safari")&&!r.includes("Chrome")?"Safari":r.includes("Edg")?"Edge":r.includes("Opera")?"Opera":"Unknown"}function i(){let r=navigator.userAgent;if(/iPhone/.test(r)){let o=r.match(/iPhone\s*([^;]*)/);return o?`iPhone ${o[1].trim()}`:"iPhone"}if(/iPad/.test(r)){let o=r.match(/iPad\s*([^;]*)/);return o?`iPad ${o[1].trim()}`:"iPad"}if(/Android/.test(r)){let o=r.match(/;\s*([^)]*)\s*\)/);return o&&o[1].trim().replace(/wv/g,"").replace(/Build\/.*$/g,"").replace(/\s+/g," ").trim()||"Android Device"}return/Windows/.test(r)?/Windows NT 10/.test(r)?"Windows 10/11 PC":/Windows NT 6\.3/.test(r)?"Windows 8.1 PC":/Windows NT 6\.2/.test(r)?"Windows 8 PC":/Windows NT 6\.1/.test(r)?"Windows 7 PC":"Windows PC":/Macintosh/.test(r)?/Intel/.test(r)?"Mac (Intel)":/Apple Silicon|ARM64/.test(r)?"Mac (Apple Silicon)":"Mac":/Linux/.test(r)?"Linux PC":/BlackBerry/.test(r)?"BlackBerry":/Windows Phone/.test(r)?"Windows Phone":n().charAt(0).toUpperCase()}function s(r){if(!r)return"Unknown";try{let f=new URL(r).hostname.replace(/^www\./,""),l=f.split(".");return l.length>=2?l[0]:f||"Unknown"}catch{return"Unknown"}}function g(r,u){let o=new URLSearchParams(window.location.search),f=o.has("utm_source")||o.has("utm_medium")||o.has("utm_campaign");if(r||f){if(f)return{source:o.get("utm_source")||"",medium:o.get("utm_medium")||"",campaign:o.get("utm_campaign")||"",content:o.get("utm_content")||"",term:o.get("utm_term")||""};{let l=document.referrer;return{source:l&&l.trim()!==""?l:"direct",medium:l&&l.trim()!==""?"referral":"",campaign:"",content:"",term:""}}}else return u||{source:"Unknown",medium:"organic",campaign:"unknown"}}function p(){try{return typeof window.pageCategories<"u"&&Array.isArray(window.pageCategories)&&window.pageCategories.length>0?window.pageCategories:["Not applicable"]}catch(r){return console.warn("Error accessing pageCategories:",r),["Not applicable"]}}function d(){let r=new URLSearchParams(window.location.search);return r.has("utm_source")||r.has("utm_medium")||r.has("utm_campaign")}function c(r){let u=r.split("?")[0].toLowerCase(),o={exactMatches:{"/":"Home","/home":"Home","/blog":"Blog listing","/about-us":"About us","/contact-us":"Contact","/privacy-policy":"Privacy policy","/terms-of-service":"Terms of service","/careers":"Careers","/customer-stories":"Customer stories listing","/events":"Events listing","/infographics":"Infographics listing","/newsroom":"Newsroom","/releases":"Releases listing"},pathStartsWith:[{pattern:"/blog/",type:"Blog"},{pattern:"/customer-stories/",type:"Customer story"},{pattern:"/case-studies/",type:"Case study"},{pattern:"/solutions/",type:"Solution"},{pattern:"/events/",type:"Event"},{pattern:"/news/",type:"News"},{pattern:"/press-releases/",type:"Press release"},{pattern:"/releases/",type:"Release"}]};if(o.exactMatches[u])return o.exactMatches[u];for(let f of o.pathStartsWith)if(u.startsWith(f.pattern))return f.type;return"Other"}function h(r){if(!r.userJourney||r.userJourney.length===0)return!1;let u=new Date(r.userJourney[r.userJourney.length-1].time);return new Date().getTime()-u.getTime()<18e5}return new Promise(r=>{setTimeout(()=>{try{let u=D(),o=null,f=localStorage.getItem(e);if(f){let y=JSON.parse(f);h(y)&&(o=y)}if(!o)o={userJourney:[],origin:window.location.hostname,deviceCategory:n(),browser:a(),device:i(),formDetails:{formId:"",formName:"",firstName:"",lastName:"",email:"",phone:""},aiData:u,aiJourneyAnalytics:{isAIUser:!1,aiTouchPoints:0,aiEntryPage:null,behaviorPatterns:{skipsBranding:!1,researchIntensive:!1,quickDecision:!1,technicalFocus:!1},platformInsights:{expectedJourney:"n/a",actualVsPredicted:"matched",platformTypicalBehavior:"n/a"}}};else{let y=U(o.aiData||{platform:"none",type:"unknown",context:"unknown",confidence:"low",detectionMethod:"none",detectedAt:new Date().toISOString()},u);o.aiData=y,o.aiJourneyAnalytics=J(o,y)}if(o.formDetails||(o.formDetails={formId:"",formName:"",firstName:"",lastName:"",email:"",phone:""}),o.device||(o.device=i()),!o){console.error("Journey initialization failed"),r(null);return}let l=window.location.pathname,P=new Date().toISOString(),I=o.userJourney[o.userJourney.length-1];if(I&&I.page===l)I.time=P;else{let y=o.userJourney.length===0,T=y?void 0:o.userJourney[0].utm,C=y&&u.platform!=="none",v=o.aiData.platform!=="none",S={touchPoint:o.userJourney.length+1,page:l,title:document.title||"Untitled",type:c(l),category:p(),time:P,utmVisibility:d()?"visible":"hidden",utm:g(y,T),aiContext:{isAIReferral:C,aiPlatform:v?u.platform:void 0,aiInfluenced:v,aiJourneyStage:C?"entry":o.userJourney.length===0?"exploration":l.includes("pricing")||l.includes("contact")?"decision":"consideration"}};o.userJourney.push(S)}o.aiJourneyAnalytics=J(o,o.aiData),localStorage.setItem(e,JSON.stringify(o)),_(),o.aiData.platform!=="none"&&E(o,l),r(o)}catch(u){console.error("Error tracking user journey:",u),r(null)}},200)})}function E(e,t){let n=e.aiData,a=new URL(window.location.href),i={ai_platform:n.platform,ai_type:n.type,ai_context:n.context,ai_confidence:n.confidence,detection_method:n.detectionMethod,landing_page:t,page_category:L(t),utm_source:a.searchParams.get("utm_source")||"",utm_medium:a.searchParams.get("utm_medium")||"",utm_campaign:a.searchParams.get("utm_campaign")||"",utm_content:a.searchParams.get("utm_content")||"",utm_term:a.searchParams.get("utm_term")||"",is_ai_user:e.aiJourneyAnalytics.isAIUser,ai_touchpoints:e.aiJourneyAnalytics.aiTouchPoints,session_start:n.detectedAt};console.debug("AI tracking event data:",i)}function L(e){return e==="/"?"Homepage":e.includes("/platform")?"Platform":e.includes("/solutions")?"Solutions":e.includes("/blog")?"Blog":e.includes("/developers")||e.includes("/api")?"Developer":e.includes("/contact")||e.includes("/demo")?"Contact":e.includes("/pricing")?"Pricing":e.includes("/about")||e.includes("/company")?"Company":"Other"}function _(){document.querySelectorAll("input[ph-form-field], textarea[ph-form-field], select[ph-form-field]").forEach(n=>{n.removeEventListener("input",w),n.removeEventListener("change",w)}),document.querySelectorAll("input[ph-form-field], textarea[ph-form-field], select[ph-form-field]").forEach(n=>{n.addEventListener("input",w),n.addEventListener("change",w)}),O()}function O(){let e=m();if(!e)return;let t=document.querySelector("[ph-form-name]");if(!t)return;let n=t.getAttribute("ph-form-name"),a=t.getAttribute("ph-form-id")||"form-1";n&&(e.formDetails.formName||(e.formDetails.formId=a,e.formDetails.formName=n),localStorage.setItem("userJourney",JSON.stringify(e)))}function w(e){let t=e.target,n=t.getAttribute("ph-form-field");if(!n)return;let a=t.closest("[ph-form-name]");if(!a)return;let i=a.getAttribute("ph-form-name"),s=a.getAttribute("ph-form-id")||"form-1";i&&V(i,s,n,t.value)}function V(e,t,n,a){try{let i=m();if(!i)return!1;switch(i.formDetails.formId=t,i.formDetails.formName=e,n){case"firstName":i.formDetails.firstName=a;break;case"lastName":i.formDetails.lastName=a;break;case"email":i.formDetails.email=a;break;case"phone":i.formDetails.phone=a;break;default:return console.warn(`Unknown field: ${n}`),!1}return localStorage.setItem("userJourney",JSON.stringify(i)),!0}catch(i){return console.error("Error updating form data:",i),!1}}function m(){try{let e=localStorage.getItem("userJourney");return e?JSON.parse(e):null}catch(e){return console.error("Error getting user journey:",e),null}}function R(){localStorage.removeItem("userJourney")}function B(e){try{let t=m();if(!t||t.userJourney.length===0)return!1;let n=t.userJourney[t.userJourney.length-1];return n.category=e.length>0?e:["Not applicable"],localStorage.setItem("userJourney",JSON.stringify(t)),!0}catch(t){return console.error("Error updating page categories:",t),!1}}function q(e){try{let t=m();if(!t||t.userJourney.length===0)return!1;let n=t.userJourney[t.userJourney.length-1];return n.type=e,localStorage.setItem("userJourney",JSON.stringify(t)),!0}catch(t){return console.error("Error updating page type:",t),!1}}function W(){let e=m();if(!e||e.userJourney.length===0)return null;let t=e.userJourney[0],n=e.userJourney[e.userJourney.length-1],a=new Date(n.time).getTime()-new Date(t.time).getTime(),i;if(e.aiJourneyAnalytics.isAIUser){let s=e.userJourney.find(c=>c.aiContext?.isAIReferral),g=s?new Date(s.time):new Date(t.time),p=new Date(n.time).getTime()-g.getTime(),d=e.userJourney.some(c=>c.page.includes("contact")||c.page.includes("demo")||c.page.includes("pricing"));i={aiSessionDuration:Math.floor(p/1e3),aiPages:e.aiJourneyAnalytics.aiTouchPoints,aiConversionTime:d?Math.floor(p/1e3):void 0,aiEngagementScore:G(e),aiValueScore:H(e)}}return{totalPages:e.userJourney.length,sessionDuration:Math.floor(a/1e3),firstPage:t.page,lastPage:n.page,aiStats:i}}function G(e){let t=0;e.aiJourneyAnalytics.isAIUser&&(t+=20);let n=e.userJourney.length;n>=5?t+=30:n>=3?t+=20:n>=2&&(t+=10);let a=e.aiJourneyAnalytics.behaviorPatterns;return a.researchIntensive&&(t+=25),a.technicalFocus&&(t+=20),a.quickDecision&&(t+=15),e.userJourney.some(s=>s.type.toLowerCase().includes("solution")||s.type.toLowerCase().includes("pricing")||s.type.toLowerCase().includes("demo"))&&(t+=15),Math.min(t,100)}function H(e){let t=0;e.aiData.confidence==="high"?t+=20:e.aiData.confidence==="medium"&&(t+=10),["ChatGPT","Claude","Google_Gemini"].includes(e.aiData.platform)&&(t+=15);let a=e.userJourney.map(s=>s.page.toLowerCase());return a.some(s=>s.includes("pricing"))&&(t+=25),a.some(s=>s.includes("contact")||s.includes("demo"))&&(t+=30),a.some(s=>s.includes("api")||s.includes("developer"))&&(t+=20),(e.formDetails.email||e.formDetails.firstName)&&(t+=20),Math.min(t,100)}function $(){let e=m();return e?e.formDetails:null}function z(e){let t=m();return t&&t.formDetails[e]||null}function Y(e,t){try{let n=m();return n?(n.formDetails[e]=t,localStorage.setItem("userJourney",JSON.stringify(n)),!0):!1}catch(n){return console.error("Error setting form data:",n),!1}}function Q(e,t){try{let n=m();return n?(n.formDetails.formId=e,n.formDetails.formName=t,localStorage.setItem("userJourney",JSON.stringify(n)),!0):!1}catch(n){return console.error("Error setting form details:",n),!1}}function K(){_()}function X(){let e=m();return e?e.aiData:null}function Z(){let e=m();return e?e.aiJourneyAnalytics:null}function j(){let e=m();return e?e.aiJourneyAnalytics.isAIUser:!1}function ee(){let e=m();return e&&e.aiData.platform!=="none"?e.aiData.platform:null}function te(){let e=D(),t=m();return t&&(t.aiData=e,t.aiJourneyAnalytics=J(t,e),localStorage.setItem("userJourney",JSON.stringify(t))),e}document.addEventListener("DOMContentLoaded",()=>{A()});document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>{A()}):A();window.trackUserJourney=A;window.getUserJourney=m;window.clearUserJourney=R;window.updatePageType=q;window.updatePageCategories=B;window.getJourneyStats=W;window.getFormData=$;window.getFormFieldValue=z;window.setFormData=Y;window.setFormDetails=Q;window.reinitializeFormTracking=K;window.getAIData=X;window.getAIJourneyAnalytics=Z;window.isAIUser=j;window.getAIPlatform=ee;window.forceAIDetection=te;window.detectAIPlatform=D;})();
|