// Formatiert Sekunden als m:ss. Bei ungültigem Wert wird ein Platzhalter angezeigt. function formatTime(seconds) { if (typeof seconds !== "number" || Number.isNaN(seconds)) { return "-"; } const minutes = Math.floor(seconds / 60); const remainingSeconds = Math.floor(seconds % 60); return `${minutes}:${String(remainingSeconds).padStart(2, "0")}`; } // Liefert den aktuellen Login-Kontext, falls Auth global verfügbar ist. function getLoggedInAuth() { if (!window.AppAuth || typeof window.AppAuth.getAuth !== "function") { return null; } const auth = window.AppAuth.getAuth(); if (!auth || !auth.username) { return null; } return auth; } // Vereinheitlicht Benutzernamen für robuste Vergleiche (z. B. Groß-/Kleinschreibung). function normalizeUsername(username) { return String(username ?? "").trim().toLowerCase(); } function getLoggedInUsername() { const auth = getLoggedInAuth(); if (!auth) { return null; } return normalizeUsername(auth.username); } // Nutzt den vom Backend gelieferten Rang, fallback auf die aktuelle Listenposition. function getDisplayedRank(entry, index) { const place = Number(entry?.place); if (!Number.isNaN(place) && place > 0) { return place; } return index + 1; } // Bestes Ergebnis: höchste Punktzahl, bei Gleichstand die geringere Zeit. function getBestScoreEntry(entries) { return entries .slice() .sort((a, b) => { const scoreA = Number(a.score ?? 0); const scoreB = Number(b.score ?? 0); if (scoreB !== scoreA) { return scoreB - scoreA; } const timeA = Number(a.time ?? Number.MAX_SAFE_INTEGER); const timeB = Number(b.time ?? Number.MAX_SAFE_INTEGER); return timeA - timeB; })[0] ?? null; } async function getCurrentUserLeaderboardEntry(username) { if (!window.ScoreService || !username) { return null; } const scoreService = new window.ScoreService(window.config); const result = await scoreService.getScoreByName(username); if (!result.ok || !Array.isArray(result.body) || result.body.length === 0) { return null; } return getBestScoreEntry(result.body); } // Rendert die Top-Liste und markiert den eingeloggten Nutzer visuell. function renderLeaderboard(entries, extraUserEntry = null) { const tableBody = document.getElementById("leaderboard-body"); if (!tableBody) { return; } const loggedInUsername = getLoggedInUsername(); tableBody.innerHTML = ""; entries.forEach((entry, index) => { const row = document.createElement("tr"); const rowUsername = normalizeUsername(entry.username); if (loggedInUsername && rowUsername === loggedInUsername) { row.classList.add("leaderboard-row-current-user"); } row.innerHTML = `