{
  "version": 3,
  "sources": ["/cdn/shop/t/19/assets/so-search-tracking.js?cb=1784728340974"],
  "sourcesContent": ["/**\n * SolarOutlet \u2013 Such-Tracking (Theme-Teil)\n * Erfasst: getippte Suchbegriffe (via Predictive-Search-Fetch), abgeschickte Suchen,\n * 0-Treffer und Klicks auf Suchergebnisse. Sendet an den Cloudflare Worker.\n *\n * Der Conversion-Funnel (Produktansicht, Warenkorb, Kauf) kommt aus dem Shopify Web Pixel.\n *\n * Konfiguration ueber window.__soTrack (im Snippet so-search-tracking.liquid gesetzt):\n *   window.__soTrack = { url: 'https://<worker>/collect' };\n */\n(function () {\n  'use strict';\n  var CFG = window.__soTrack || {};\n  var ENDPOINT = CFG.url;\n  if (!ENDPOINT) return;\n\n  // --- Consent: nur senden, wenn Analytics erlaubt -------------------------\n  // Quelle ist die Shopify Consent Tracking API. Das Consent-Tool des Shops\n  // (aktuell Complianz, technisch iubenda) meldet die Entscheidung des\n  // Besuchers dorthin. Dadurch haengt hier nichts an einem Herstellernamen:\n  // ein Toolwechsel erfordert keine Aenderung mehr an dieser Datei.\n  // Die Pruefung laeuft pro Event, nicht einmalig beim Laden, damit sie auch\n  // dann stimmt, wenn die API beim Seitenaufbau noch nicht bereit war.\n  function consentOK() {\n    try {\n      var cp = window.Shopify && window.Shopify.customerPrivacy;\n      if (cp && typeof cp.analyticsProcessingAllowed === 'function') {\n        return cp.analyticsProcessingAllowed();\n      }\n    } catch (e) {}\n    // API nicht geladen oder kein Consent-Tool aktiv -> im Zweifel NICHT\n    // tracken (DSGVO-sicher).\n    return CFG.assumeConsent === true;\n  }\n\n  // --- Anonyme IDs (First-Party-Cookies) -----------------------------------\n  function uuid() {\n    if (window.crypto && crypto.randomUUID) return crypto.randomUUID();\n    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n      var r = (Math.random() * 16) | 0, v = c === 'x' ? r : (r & 0x3) | 0x8;\n      return v.toString(16);\n    });\n  }\n  function getCookie(name) {\n    var m = document.cookie.match('(?:^|; )' + name + '=([^;]*)');\n    return m ? decodeURIComponent(m[1]) : null;\n  }\n  function setCookie(name, val, maxAgeSec) {\n    document.cookie = name + '=' + encodeURIComponent(val) +\n      '; path=/; max-age=' + maxAgeSec + '; SameSite=Lax; Secure';\n  }\n  function sid() {\n    var v = getCookie('so_sid');\n    if (!v) { v = uuid(); setCookie('so_sid', v, 60 * 60 * 24 * 180); } // 180 Tage\n    return v;\n  }\n  function vid() {\n    var v = getCookie('so_vid');\n    if (!v) { v = uuid(); setCookie('so_vid', v, 60 * 30); } // 30 Min Session\n    else { setCookie('so_vid', v, 60 * 30); } // Sliding-Fenster\n    return v;\n  }\n\n  // --- Senden --------------------------------------------------------------\n  function send(ev) {\n    if (!consentOK()) return;\n    ev.sid = sid();\n    ev.vid = vid();\n    ev.ts_client = new Date().toISOString();\n    ev.path = location.pathname;\n    ev.source = 'theme';\n    try {\n      var payload = JSON.stringify(ev);\n      // text/plain = CORS-safelisted -> kein Preflight, wird auch in Safari/iOS zuverlaessig\n      // gesendet. Der Worker parst den Body ohnehin als JSON (unabhaengig vom Content-Type).\n      if (navigator.sendBeacon) {\n        navigator.sendBeacon(ENDPOINT, new Blob([payload], { type: 'text/plain;charset=UTF-8' }));\n      } else {\n        fetch(ENDPOINT, { method: 'POST', body: payload, headers: { 'Content-Type': 'text/plain;charset=UTF-8' }, keepalive: true });\n      }\n    } catch (e) {}\n  }\n\n  // --- Predictive-Search-Fetch abfangen (= getippte Begriffe + Trefferzahl) -\n  // Nur das FERTIG getippte Wort loggen, nicht jede Zwischenstufe: der zuletzt\n  // getippte Stand wird gemerkt und erst nach einer Tipp-Pause gesendet\n  // (bzw. beim Ergebnis-Klick / Seitenwechsel). Wird geloescht und neu getippt,\n  // entsteht nach der Pause automatisch ein eigener Eintrag.\n  var pending = null;        // { q, count } \u2013 zuletzt getippter Stand\n  var flushTimer = null;\n  var lastQuery = '';        // fuer die Zuordnung des Ergebnis-Klicks\n  var FLUSH_MS = 1200;\n\n  function flushSearch() {\n    if (flushTimer) { clearTimeout(flushTimer); flushTimer = null; }\n    if (!pending) return;\n    var p = pending; pending = null;\n    send({ type: 'search_input', q: p.q, results_count: p.count });\n    if (p.count === 0) send({ type: 'search_no_results', q: p.q, results_count: 0 });\n  }\n  function scheduleFlush() {\n    if (flushTimer) clearTimeout(flushTimer);\n    flushTimer = setTimeout(flushSearch, FLUSH_MS);\n  }\n\n  var origFetch = window.fetch;\n  window.fetch = function (input, init) {\n    var urlStr = typeof input === 'string' ? input : (input && input.url) || '';\n    var isSuggest = urlStr.indexOf('/search/suggest') !== -1 || urlStr.indexOf('section_id=predictive-search') !== -1;\n    // Immer mit window als this aufrufen (sonst \"Illegal invocation\" bei native fetch).\n    var p = origFetch.apply(window, arguments);\n    if (!isSuggest) return p;\n    var q = decodeURIComponent((urlStr.match(/[?&]q=([^&]*)/) || [])[1] || '').replace(/\\+/g, ' ').trim();\n    if (!q) return p;\n    lastQuery = q;\n    return p.then(function (res) {\n      try {\n        var clone = res.clone();\n        clone.text().then(function (html) {\n          var count = (html.match(/<product-card-small[\\s>]/g) || []).length;\n          // Nur merken \u2013 gesendet wird erst nach der Tipp-Pause.\n          pending = { q: q, count: count };\n          scheduleFlush();\n        });\n      } catch (e) {}\n      return res;\n    });\n  };\n\n  // Letzten getippten Stand nicht verlieren, wenn die Seite verlassen/versteckt wird.\n  window.addEventListener('pagehide', flushSearch);\n  document.addEventListener('visibilitychange', function () {\n    if (document.visibilityState === 'hidden') flushSearch();\n  });\n\n  // --- Abgeschickte Suche (Enter / Button) ---------------------------------\n  document.addEventListener('submit', function (e) {\n    var form = e.target;\n    if (!form || form.getAttribute('action') == null) return;\n    if ((form.getAttribute('action') || '').indexOf('/search') === -1) return;\n    var input = form.querySelector('input[type=\"search\"], input[name=\"q\"], .search-field');\n    var q = input && input.value ? input.value.trim() : '';\n    flushSearch(); // den fertig getippten Begriff sichern\n    if (q) send({ type: 'search_submit', q: q });\n  }, true);\n\n  // --- Klick auf ein Suchergebnis ------------------------------------------\n  document.addEventListener('click', function (e) {\n    var a = e.target.closest && e.target.closest('a[href*=\"/products/\"]');\n    if (!a) return;\n    // Nur innerhalb eines Such-Kontexts zaehlen\n    var inSearch = a.closest('.thb-predictive-search, .search-drawer, .header-mobile-search, [id*=\"predictive-search\"], #shopify-section-main-search');\n    if (!inSearch) return;\n    var card = a.closest('[data-product-handle], product-card-small, product-card');\n    var handle = (card && card.getAttribute('data-product-handle')) ||\n      (a.getAttribute('href').match(/\\/products\\/([^?#]+)/) || [])[1] || null;\n    flushSearch(); // zuerst den fertig getippten Suchbegriff loggen\n    send({\n      type: 'search_result_click',\n      q: lastQuery,\n      product_handle: handle,\n      product_id: card && card.getAttribute('data-id') || null,\n    });\n  }, true);\n})();\n"],
  "mappings": "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",
  "names": []
}
