1(function () { 2 "use strict"; 3 4 var beaconUrl = "https://os-api.bati.ai/api/public/analytics/beacon"; 5 var storageKey = "__a_fp"; 6 var isPublicBatiHost = /(^|\.)bati\.ai$/i.test(window.location.hostname); 7 var clicksBound = false; 8 9 function getFingerprint() { 10 var existing = ""; 11 try { 12 existing = sessionStorage.getItem(storageKey) || ""; 13 } catch (_) { 14 // Storage can be blocked in private or hardened browser contexts. 15 } 16 if (existing) return existing; 17 18 var fingerprint = 19 typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" 20 ? crypto.randomUUID() 21 : "r-" + Math.random().toString(36).slice(2) + "-" + Date.now().toString(36); 22 try { 23 sessionStorage.setItem(storageKey, fingerprint); 24 } catch (_) { 25 // Analytics is intentionally best-effort. 26 } 27 return fingerprint; 28 } 29 30 var fingerprint = getFingerprint(); 31 32 /* 33 * ì´ë ì¬ì´í¸ë¡ ì§ê³í ì§. 34 * 35 * ì´ ì¤í¬ë¦½í¸ë bati.ai ì ì²´ê° ì´ë¤(ë£¨í¸ Â· /about-us/ · /batioffice/). ì§ê¸ê¹ì§ ì ë¶ 36 * "landing" ì¼ë¡ ë³´ëëë°, admin-os ì ê·¸ í목ì **bati.so** ë¼ë²¨ì´ë¼ ë¤ë¥¸ ëë©ì¸ 37 * ì«ìì ìì¬ ììë¤. BatiOffice ì ì ì´ ì¼ë§ì¸ì§ ë³¼ ìê° ììë ì´ì ë¤. 38 * 39 * /batioffice/ ë§ ë°ë¡ ëë¤. ë머ì§(루í¸Â·about-us)ê° ì¬ì í bati.so ì ìì´ë ê²ì 40 * ë³ê±´ì¼ë¡ ë¨ëë¤ â ì¬ê¸°ì í꺼ë²ì ë°ê¾¸ë©´ 기존 ì§ê³ê° ë긴ë¤. 41 */ 42 function resolveSite() { 43 return /^\/batioffice(\/|$)/i.test(window.location.pathname) ? "batioffice" : "landing"; 44 } 45 46 function send(eventType, eventName, locale) { 47 var payload = { 48 site: resolveSite(), 49 // ìë² ì¤í¤ë§ê° page 를 /^\/[a-z0-9-\/]*$/ ë¡ ì ííë¤. ë문ìë ê·¸ ë°ì 문ìê° 50 // ìì¼ë©´ íµì§¸ë¡ ê±°ë¶ëëë° ìëµì´ 204 ë¼ ì¡°ì©í ì¬ë¼ì§ë¤ â ì¬ê¸°ì ë§ì¶° ë³´ë¸ë¤. 51 page: window.location.pathname.toLowerCase().replace(/[^a-z0-9\-/]/g, "").slice(0, 255) || "/", 52 eventType: eventType, 53 fingerprint: fingerprint, 54 }; 55 if (eventName) payload.eventName = eventName; 56 57 window.dataLayer = window.dataLayer || []; 58 window.dataLayer.push({ 59 event: eventName || "batioffice_landing_view", 60 event_type: eventType, 61 page_path: window.location.pathname, 62 page_locale: locale || document.documentElement.lang || "ko", 63 }); 64 65 // dataLayer ë§ì¼ë¡ë GA4 ì ì´ë²¤í¸ê° ë¤ì´ê°ì§ ìëë¤ â ì´ ì¬ì´í¸ë GTM 컨í ì´ëê° ìëë¼ 66 // gtag.js 를 ì§ì ì£ê¸° ë문ì´ë¤(index.html ì gtag('config', ...)). ê·¸ëì ë¤ì´ë¡ë·ë°ëª¨í· 67 // ì¸ì´ì í ê°ì ì í ì´ë²¤í¸ê° íëë 기ë¡ëì§ ìê³ page_view ë§ ë¨ìë¤. 68 // dataLayer.push ë í¥í GTM ëì ëë¹ë¡ ê·¸ëë¡ ëë¤. 69 if (typeof window.gtag === "function") { 70 window.gtag("event", eventName || "batioffice_landing_view", { 71 event_type: eventType, 72 page_path: window.location.pathname, 73 page_locale: locale || document.documentElement.lang || "ko", 74 }); 75 } 76 77 if (!isPublicBatiHost || !navigator.sendBeacon) return; 78 try { 79 navigator.sendBeacon(beaconUrl, new Blob([JSON.stringify(payload)], { 80 type: "text/plain;charset=UTF-8", 81 })); 82 } catch (_) { 83 // Tracking must never block a navigation or product download. 84 } 85 } 86 87 function bindTrackedClicks(locale) { 88 if (clicksBound) return; 89 clicksBound = true; 90 document.addEventListener("click", function (event) { 91 var target = event.target.closest("[data-track]"); 92 var eventName = target && target.dataset.track; 93 if (target && target.getAttribute("aria-disabled") === "true") return; 94 if (!eventName || !/^batioffice_[a-z0-9_]+$/.test(eventName)) return; 95 send("click", eventName, locale); 96 }, true); 97 } 98 99 window.BatiLandingAnalytics = Object.freeze({ 100 trackPageView: function (locale) { send("pageview", "", locale); }, 101 bindTrackedClicks: bindTrackedClicks, 102 }); 103})();
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.