<script>
(function () {
  // Same-origin on clearnet and onion (nginx proxies both to GoatCounter).
  // Sessions are server-side (IP+UA → ephemeral UUID); no tracking cookies.
  window.goatcounter = { endpoint: "/count" };

  const s = document.createElement("script");
  s.async = true;
  s.src = "/js/count.js";
  document.head.appendChild(s);
})();
</script>

<script>
(function () {
  // Tor + clearnet share one GoatCounter site → one TOTAL.
  const GC = "";
  const nf = new Intl.NumberFormat();
  const SING = "visit";
  const PLUR = "visits";

  function ready(fn) {
    if (document.readyState === "complete" || document.readyState === "interactive") setTimeout(fn, 0);
    else document.addEventListener("DOMContentLoaded", fn);
  }

  function gcPath() {
    try {
      return window.goatcounter && window.goatcounter.get_data
        ? window.goatcounter.get_data().p
        : location.pathname;
    } catch (_) {
      return location.pathname;
    }
  }

  async function fetchCount(path, period) {
    try {
      const q = new URLSearchParams({ t: String(Date.now()) });
      if (period) q.set("start", period);
      const url = `${GC}/counter/${encodeURIComponent(path)}.json?${q}`;
      const r = await fetch(url, { credentials: "omit" });
      if (r.status === 404) return 0;
      if (!r.ok) throw 0;
      const j = await r.json();
      // GoatCounter "count" is visits (session-deduped), not raw pageviews.
      const n = Number(String(j.count).replace(/,/g, ""));
      return Number.isFinite(n) ? n : 0;
    } catch {
      return null;
    }
  }

  const labelVisits = (n) =>
    n === null ? "—" : `${nf.format(n)} ${n === 1 ? SING : PLUR}`;

  ready(async function () {
    const post = document.querySelector(".post-single");
    if (post) {
      const meta = post.querySelector(
        ".post-header .post-meta, .post-header .entry-meta, .post-meta"
      );
      const visits = await fetchCount(gcPath());
      if (meta) {
        let span = meta.querySelector(".post-views");
        if (!span) {
          span = document.createElement("span");
          span.className = "post-views";
          meta.appendChild(span);
        }
        span.textContent = labelVisits(visits ?? 0);
      }
    }

    const cards = document.querySelectorAll("article.post-entry");
    await Promise.all(
      Array.from(cards).map(async (card) => {
        const meta = card.querySelector(".entry-footer, .post-meta");
        const link = card.querySelector("a.entry-link, h2 a, .entry-title a");
        if (!meta || !link) return;
        try {
          const u = new URL(link.getAttribute("href"), location.origin);
          if (u.origin !== location.origin) return;
          let span = meta.querySelector(".post-views");
          if (!span) {
            span = document.createElement("span");
            span.className = "post-views";
            meta.appendChild(span);
          }
          span.textContent = labelVisits((await fetchCount(u.pathname)) ?? 0);
        } catch {}
      })
    );

    const uvEl = document.getElementById("gc_site_visitors_week");
    if (uvEl) {
      const n = await fetchCount("TOTAL", "week");
      uvEl.textContent = n === null ? "—" : nf.format(n);
    }
  });
})();
</script>
