*/ (function () { if (typeof window === 'undefined') return; // Endpoint-Resolution: dataset-Attribut > Default. // Snippets in alten Sites haben kein data-endpoint und nutzen den Default. function resolveEndpoint() { try { var scripts = document.getElementsByTagName('script'); for (var i = scripts.length - 1; i >= 0; i--) { var s = scripts[i]; if (s.src && s.src.indexOf('tracking-snippet') !== -1 && s.dataset && s.dataset.endpoint) { return s.dataset.endpoint; } } } catch (e) {} return 'https://api.pstudio.care/api/kunden-track'; } var ENDPOINT = resolveEndpoint(); var SITE = location.hostname; // Bail-Outs: Prefetch, Background-Tab, kein Document function shouldTrack() { try { // Browser-Prefetch (Google, manche Browser) -> kein Track if (typeof performance !== 'undefined' && performance.getEntriesByType) { var nav = performance.getEntriesByType('navigation')[0]; if (nav && (nav.type === 'prerender' || nav.type === 'prefetch')) return false; } // Background-Tab beim Snippet-Start -> kein initial pageview if (document.visibilityState === 'hidden' || document.visibilityState === 'prerender') { return false; } return true; } catch (e) { return true; // fail-open } } if (!shouldTrack()) return; // Ephemeral Session-ID (sessionStorage, kein Cookie, kein Cross-Site) var sid; try { sid = sessionStorage.getItem('_bw_sid'); if (!sid) { sid = 'b' + Math.random().toString(36).slice(2, 14); sessionStorage.setItem('_bw_sid', sid); } } catch (e) { sid = 'nocookie-' + Math.random().toString(36).slice(2, 8); } function send(event_type, metadata) { try { fetch(ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ site: SITE, event_type: event_type, path: location.pathname, referrer: document.referrer || null, session_id: sid, metadata: metadata || null, }), keepalive: true, credentials: 'omit', }).catch(function () {}); } catch (e) {} } // Pageview send('pageview'); // Form-Submit (Event only, KEIN Form-Inhalt) document.addEventListener('submit', function (e) { var form = e.target; if (!form || form.tagName !== 'FORM') return; // Honeypot: hidden input mit name='website' oder data-honeypot. // Wenn gefuellt -> als Spam markiert. var honeypotFilled = false; try { var hp1 = form.querySelector('input[name="website"]'); var hp2 = form.querySelector('input[data-honeypot]'); if ((hp1 && hp1.value) || (hp2 && hp2.value)) honeypotFilled = true; } catch (ignored) {} send('form_submit', { form_id: form.id || form.name || form.getAttribute('data-form') || 'unknown', honeypot: honeypotFilled, }); }, true); // Outbound-Clicks (tel:, mailto:, externe Links) var pageStartTs = Date.now(); document.addEventListener('click', function (e) { var a = e.target.closest && e.target.closest('a'); if (!a || !a.href) return; var href = a.href.toLowerCase(); var target = null; if (href.indexOf('tel:') === 0) target = 'tel'; else if (href.indexOf('mailto:') === 0) target = 'mailto'; else if (href.indexOf('http') === 0 && a.hostname !== location.hostname) target = 'external'; if (target) { send('outbound_click', { click_target: target, click_after_load_ms: Date.now() - pageStartTs, }); } }, true); // Scroll-Milestones (25/50/75/100%) var milestones = [25, 50, 75, 100]; var sent = {}; function checkScroll() { var doc = document.documentElement; var scrolled = (window.scrollY + window.innerHeight) / Math.max(doc.scrollHeight, 1) * 100; for (var i = 0; i < milestones.length; i++) { var m = milestones[i]; if (scrolled >= m && !sent[m]) { sent[m] = true; send('scroll_milestone', { scroll_percent: m }); } } } var scrollTimeout; window.addEventListener('scroll', function () { clearTimeout(scrollTimeout); scrollTimeout = setTimeout(checkScroll, 200); }, { passive: true }); })();