1// Production hosts 2const productionHosts = [ 3 "www.boldreports.com", 4 "help.boldreports.com", 5 "demos.boldreports.com", 6 "solutions.boldreports.com" 7]; 8 9// Cookie and Expire dates 10const cookieDomain = productionHosts.includes(location.host) ? ".boldreports.com" : location.hostname; 11const defaultCookieExpireDays = 30; // 30 days 12const uuidCookieExpireDays = 365; // 1 year 13 14// Tracking Parameter Names 15const uuidName = "_uid"; 16const sidName = "_sid"; 17const gclidName = "gclid"; 18const utmCampaignName = "utm_campaign"; 19const utmAdgroupName = "utm_adgroup"; 20const utmSourceName = "utm_source"; 21const leadSourceName = "lead_source"; 22const leadCategoryName = "lead_category"; 23const referralUrlName = "referral_url"; 24const secondaryReferralUrlName = "secondary_referral_url"; 25const pageCountName = "_pageCount"; 26const lastVisitedUrlName = "last_visited_url"; 27 28// Tracking Parameter values 29const uuidValue = getUuid() || ""; 30const gclidValue = getGclid() || ""; 31const sidValue = getTrackingValue(sidName) || ""; 32const leadSourceValue = getLeadSource() || ""; 33const leadCategoryValue = getLeadCategory() || ""; 34const referrerUrlValue = getReferrerUrl() || ""; 35const referrerOriginUrlValue = getCleanUrl(referrerUrlValue) || ""; 36const secondaryReferrerUrlValue = getSecondaryReferrerUrl() || ""; 37const secondaryReferrerOriginUrlValue = getCleanUrl(secondaryReferrerUrlValue) || ""; 38const currentPageUrlValue = getCleanUrl(window.location.href) || ""; 39const pageCountValue = getPageCount() || ""; 40const lastVisitedPageUrlValue = lastVisitedUrl() || ""; 41 42// Set tracking values in cookies 43setTrackingValue(uuidName, uuidValue, uuidCookieExpireDays); 44setTrackingValue(gclidName, gclidValue); 45setTrackingValue(leadSourceName, leadSourceValue); 46setTrackingValue(leadCategoryName, leadCategoryValue); 47setTrackingValue(referralUrlName, referrerUrlValue); 48setTrackingValue(secondaryReferralUrlName, secondaryReferrerUrlValue); 49setTrackingValue(lastVisitedUrlName, lastVisitedPageUrlValue); 50 51// Query parameter 52const appendQueryParam = 53 "&leadsource=" + leadSourceValue + 54 "&leadcategory=" + leadCategoryValue + 55 "&opportunitysource=" + leadSourceValue + 56 "&opportunitycategory=" + leadCategoryValue + 57 "&uuid=" + uuidValue + 58 "&gclid=" + gclidValue + 59 "&referrerroriginurl=" + referrerOriginUrlValue + 60 "&secondaryreferraloriginurl=" + secondaryReferrerOriginUrlValue + 61 "&lastvisitedurl=" + currentPageUrlValue + 62 "&secondaryleadsource=Bold_Reports_Trial"; 63 64// Get cookie value 65function getTrackingValue(name) { 66 const nameEQ = name + "="; 67 const cookies = document.cookie.split(";"); 68 for (let cookie of cookies) { 69 cookie = cookie.trim(); 70 if (cookie.indexOf(nameEQ) === 0) { 71 return decodeURIComponent(cookie.substring(nameEQ.length)); 72 } 73 } 74 return null; 75} 76 77// Set cookie value 78function setTrackingValue(name, value, expiryDays) { 79 // Only set if value exists 80 if (!value) { 81 return; 82 } 83 84 const existingValue = getTrackingValue(name); 85 86 // Only set new expiry date if cookie doesn't exist or value is changing 87 if (existingValue !== null && existingValue === value) { 88 return; 89 } 90 91 var cookieString = `${name}=${encodeURIComponent(value)}; path=/; domain=${cookieDomain}`; 92 93 // Session cookie only when explicitly 0 94 if (expiryDays !== 0) { 95 const expiryDate = new Date(); 96 expiryDate.setTime( 97 expiryDate.getTime() + 98 (expiryDays ?? defaultCookieExpireDays) * 24 * 60 * 60 * 1000 99 ); 100 101 cookieString += `; expires=${expiryDate.toUTCString()}`; 102 } 103 104 document.cookie = cookieString; 105} 106 107// Get Clean Urls 108function getCleanUrl(url) { 109 if (!url) { 110 return ""; 111 } 112 113 try { 114 const parsedUrl = new URL(url); 115 return parsedUrl.origin + parsedUrl.pathname; 116 } catch { 117 // Fallback for invalid/relative URLs 118 return url.split(/[?#]/)[0]; 119 } 120} 121 122// Get UUID 123function getUuid() { 124 const cookieUuid = getTrackingValue(uuidName); 125 126 // Cookie exists 127 if (cookieUuid) { 128 return cookieUuid; 129 } 130 131 // Neither exists 132 const newUuid = generateUuid(); 133 134 setTrackingValue(uuidName, newUuid, uuidCookieExpireDays); 135 136 return newUuid; 137} 138 139// Uuid Generator 140function generateUuid() { 141 const now = new Date(); 142 const jan = new Date(now.getFullYear(), 0, 1); 143 const jul = new Date(now.getFullYear(), 6, 1); 144 145 const estOffset = (Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()) <= now.getTimezoneOffset() ? -4 : -5) * 3600000; 146 147 const loadTimeOffset = now.getTimezoneOffset() * 60000; 148 149 const timestamp = now.getTime() + loadTimeOffset + estOffset; 150 const random = Math.floor(Math.random() * 1000) + 1; 151 152 return `${random}${timestamp}`; 153} 154 155// Get Query Parameter 156function getQueryParameter(parameterName) { 157 if (!parameterName) { 158 return null; 159 } 160 161 var queryString = window.location.search.substring(1); 162 var parameters = queryString.split("&"); 163 164 for (var i = 0; i < parameters.length; i++) { 165 var pair = parameters[i].split("="); 166 167 if (pair[0] === parameterName) { 168 return decodeURIComponent(pair[1] || "").trim(); 169 } 170 } 171 172 return null; 173} 174 175// Get Gclid 176function getGclid() { 177 return getQueryParameter(gclidName) || getTrackingValue(gclidName) || null; 178} 179 180// Get lead source 181function getLeadSource() { 182 // 1. Check UTM campaign and Ad group present 183 const utmCampaign = getQueryParameter(utmCampaignName); 184 const utmAdgroup = getQueryParameter(utmAdgroupName); 185 186 if (utmCampaign && utmAdgroup) { 187 return utmCampaign + "_" + utmAdgroup; 188 } 189 190 // 2. Check UTM campaign 191 if (utmCampaign) { 192 return utmCampaign; 193 } 194 195 // 3. Check Google Ads click ID 196 const gclid = getQueryParameter(gclidName); 197 if (gclid) { 198 return gclid; 199 } 200
201 // 4. Check stored lead source and not a organic 202 const storedLeadSource = getTrackingValue(leadSourceName); 203 if (storedLeadSource && storedLeadSource !== "www.google.com") { 204 return storedLeadSource; 205 } 206 207 // 5. Return referrer domain or current hostname 208 const referrer = getReferrerUrl(); 209 return referrer?.split("/")[2] || location.hostname; 210}; 211 212// Get lead category 213function getLeadCategory() { 214 // 1. Check UTM source 215 const utmSource = getQueryParameter(utmSourceName); 216 217 if (utmSource) { 218 return utmSource; 219 } 220 221 // 2. Check Google Ads 222 if (getQueryParameter(gclidName)) { 223 return "Google_Ads"; 224 } 225 226 // 3. Check Bing Ads 227 const utmCampaign = getQueryParameter(utmCampaignName); 228 229 if (utmCampaign && utmCampaign.includes("_biad")) { 230 return "Bing_Ads"; 231 } 232 233 // 4. Check YouTube Ads 234 if (utmSource?.toLowerCase().includes("youtube_ads") || utmCampaign?.toLowerCase().includes("youtube_ads")) { 235 return "Youtube_Ads"; 236 } 237 238 // 5. Check stored lead category 239 const storedLeadCategory = getTrackingValue(leadCategoryName); 240 if (storedLeadCategory) { 241 return storedLeadCategory; 242 } 243 244 // 6. Check referrer URL 245 const referrer = getReferrerUrl(); 246 const referrerDomain = referrer?.split("/")[2] || ""; 247 248 const referrerMappings = { 249 "medium.com": "medium", 250 "nuget.org": "nuget", 251 "npmjs.com": "npm", 252 "github.com": "github", 253 "facebook.com": "facebook", 254 "linkedin.com": "linkedin", 255 "twitter.com": "twitter", 256 "x.com": "twitter", 257 "claude.ai":"ClaudeAI", 258 "anthropic.com":"Claude", 259 "gemini.google.com":"GeminiAI", 260 "aistudio.google.com":"GeminiAI", 261 "bard.google.com":"GeminiAI", 262 "grok.com":"GrokAI", 263 "x.ai":"GrokAI", 264 "deepseek.com":"DeepSeek", 265 "deepseek.ai":"DeepSeekAI", 266 "you.com":"You.com", 267 "poe.com":"Poe", 268 "mistral.ai":"MistralAI", 269 "chat.mistral.ai":"MistralAI", 270 "character.ai":"CharacterAI", 271 "pi.ai":"PiAI", 272 "writesonic.com":"Writesonic", 273 "huggingface.co":"Hugging Face", 274 "blackbox.ai":"BlackboxAI", 275 "qwen.ai":"QwenAI", 276 "kimi.com":"Kimi", 277 "phind.com":"Phind", 278 "komo.ai":"KomoAI", 279 "andi.ai":"AndiAI", 280 "discord.com":"Discord", 281 "whatsapp.com":"WhatsApp", 282 "telegram.org":"Telegram", 283 "t.me":"Telegram", 284 "news.ycombinator.com":"HackerNews", 285 "dev.to":"DevTo", 286 "hashnode.com":"Hashnode", 287 "bing.com":"Bing", 288 "yahoo.com":"Yahoo", 289 "duckduckgo.com":"Duckduckgo", 290 "baidu.com":"Baidu", 291 "yandex.com":"Yandex", 292 "ecosia.org":"Ecosia", 293 "search.brave.com":"Brave", 294 "startpage.com":"Startpage", 295 "x.com":"Twitter", 296 "tiktok.com":"TikTok", 297 "threads.net":"Threads", 298 "perplexity":"PerplexityAI", 299 "copilot.com":"Copilot", 300 "seektool.ai":"SeektoolAI", 301 "openai":"OpenAI" 302 }; 303 304 for (const key in referrerMappings) { 305 if (referrerDomain.includes(key)) { 306 return referrerMappings[key]; 307 } 308 } 309 310 // 7. Default category 311 return "Site_Visitors"; 312} 313 314// Get referrer URL 315function getReferrerUrl() { 316 // 1. Stored referral URL 317 // 2. Check browser referrer URL 318 // 3. Fallback to current page URL 319 return getTrackingValue(referralUrlName) || document.referrer || window.location.href; 320} 321 322// Get secondary referrer URL 323function getSecondaryReferrerUrl() { 324 // 1. Stored secondary referrer 325 // 2. Fallback to current page URL 326 return getTrackingValue(secondaryReferralUrlName) || window.location.href; 327}; 328 329// Get last visited page URL 330function lastVisitedUrl() { 331 const isConversionPage = [ 332 'contact', 333 'request-quote', 334 'schedule-free-demo' 335 ].some(page => 336 window.location.pathname.toLowerCase().includes(page) 337 ); 338 339 return isConversionPage 340 ? (document.referrer || window.location.href) 341 : window.location.href; 342} 343 344// Page Count 345function getPageCount() { 346 var count = getTrackingValue(pageCountName); 347 var pageCount = Number(count); 348 349 if (!pageCount || isNaN(pageCount)) { 350 pageCount = 1; 351 } else { 352 pageCount = pageCount + 1; 353 } 354 355 setTrackingValue(pageCountName, pageCount, 0); 356 357 return pageCount; 358} 359 360// Append query string to URLs -- STARTS HERE 361function appendQueryString(appendQueryParam) { 362 const modificationurl = [ 363 "https://www.boldreports.com/", 364 "https://app.boldid.net/", 365 "https://staging-app.boldreports.com/" 366 ]; 367 368 modificationurl.forEach((url) => { 369 document.querySelectorAll(`a[href^="${url}"]`).forEach((link) => { 370 if (link.href.includes("evaluation=v2")) { 371 link.href = link.href.split("evaluation=v2")[0] + "evaluation=v2" + appendQueryParam; 372 } 373 }); 374 }); 375} 376 377appendQueryString(appendQueryParam); 378 379document.addEventListener("DOMContentLoaded", () => { 380 appendQueryString(appendQueryParam); 381}); 382// Append query string to URLs -- ENDS HERE 383 384// Form tracking injector -- STARTS HERE 385function setFormInputFieldValue(selector, value) { 386 var inputs = document.querySelectorAll(selector); 387 for (var i = 0; i < inputs.length; i++) { 388 inputs[i].value = value; 389 } 390} 391 392function appendTrackingParamInForms() { 393 setFormInputFieldValue('input[name="PageURL"]', window.location.href); 394 setFormInputFieldValue('input[name="Uuid"]', uuidValue); 395 setFormInputFieldValue('input[name="Gclid"]', gclidValue); 396 setFormInputFieldValue('input[name="LeadSource"]', leadSourceValue); 397 setFormInputFieldValue('input[name="LeadCategory"]', leadCategoryValue); 398 setFormInputFieldValue('input[name="ReferrerUrl"]', referrerUrlValue); 399 setFormInputFieldValue('input[name="ReferralOriginUrl"]', referrerOriginUrlValue); 400 setFormInputFieldValue('input[name="SecondaryReferrerUrl"]', secondaryReferrerUrlValue); 401 setFormInputFieldValue('input[name="SecondaryReferralOriginurl"]', secondaryReferrerOriginUrlValue); 402 setFormInputFieldValue('input[name="LastVisitedPageUrl"]', lastVisitedPageUrlValue); 403} 404 405appendTrackingParamInForms(); 406// Form tracking injector -- ENDS HERE 407 408// Page Visit logs -- STARTS HERE 409async function sendToPageVisitLog() { 410 411 try { 412 413 // Get IP address 414 const response = await fetch("https://api64.ipify.org?format=json"); 415 const data = await response.json(); 416 417 const ipAddress = data.ip || ""; 418 419 setFormInputFieldValue('input[name="IpAddress"]', ipAddress); 420 421 const payload = { 422 UUID: uuidValue || "", 423 PageUrl: window.location.href, 424 CurrentTime: new Date().toISOString(), 425 PageCount: pageCountValue || 0, 426 CustomerIP: ipAddress, 427 CustomerID: sidValue || "", 428 ReferrerUrl: document.referrer || "", 429 Queue: "Bold Reports" 430 }; 431 432 const apiUrl = "https://www.boldreports.com/account/page-visit-logs/"; 433 434 fetch(apiUrl, { 435 method: "POST", 436 headers: { 437 "Content-Type": "application/json" 438 }, 439 body: JSON.stringify(payload) 440 }) 441 .catch(error => { 442 console.error("Error:", error); 443 }); 444 445 } catch (error) { 446 console.error("IP fetch failed:", error); 447 } 448} 449 450if (location.host == "www.boldreports.com") { 451 sendToPageVisitLog(); 452} 453// Page Visit logs -- ENDS HERE 454 455// Removes unwanted tracking parameters (like _gl) from all anchor links -- STARTS HERE 456function removeTrackingParams(event) { 457 const link = event.target.closest("a"); 458 if (!link) return; 459 460 let href = link.getAttribute("href"); 461 if (!href) return; 462 463 // Process only external links 464 const isInternal = 465 href.startsWith(location.origin) || 466 href.startsWith("/") || 467 href.startsWith("#"); 468 469 if (!isInternal) { 470 // Remove `_gl` parameter 471 const modifiedHref = href 472 .replace(/\&_gl=[^#]*/, '') // remove &_gl=... 473 .replace(/\?_gl=[^#]*/, ''); // remove ?_gl=... 474 475 link.setAttribute("href", modifiedHref); 476 } 477} 478 479// Attach events 480["mouseover", "click", "contextmenu"].forEach(evt => 481 document.addEventListener(evt, removeTrackingParams) 482); 483// Removes unwanted tracking parameters (like _gl) from all anchor links -- ENDS HERE
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.