Identidad
Jugador: ${escapeHtml(playerName)}
-ID: ${escapeHtml(playerIdText)}
Partidas semanales: ${safeInt(weeklyData?.matches_considered, 0)}
Partidas mensuales: ${safeInt(monthlyData?.matches_considered, 0)}
Identidad
Jugador: ${escapeHtml(playerName)}
-ID: ${escapeHtml(playerIdText)}
Partidas semanales: ${safeInt(weeklyData?.matches_considered, 0)}
Partidas mensuales: ${safeInt(monthlyData?.matches_considered, 0)}
Kills/partida: ${killsPerMatch} @@ -718,6 +743,13 @@ const monthlyKillsPerMatch = safeParseNumber(monthlyData?.kills_per_match); const weeklyKd = safeParseNumber(weeklyData?.kd_ratio); const monthlyKd = safeParseNumber(monthlyData?.kd_ratio); + const weeklyKpm = safeParseNumber(weeklyData?.kpm); + const monthlyKpm = safeParseNumber(monthlyData?.kpm); + const hasReadyKpm = + weeklyData?.kpm_status === "ready" && + monthlyData?.kpm_status === "ready" && + Number.isFinite(weeklyKpm) && + Number.isFinite(monthlyKpm); const killsDelta = safeInt(monthlyData?.kills, 0) - safeInt(weeklyData?.kills, 0); const matchesDelta = safeInt(monthlyData?.matches_considered, 0) - safeInt(weeklyData?.matches_considered, 0); @@ -746,6 +778,20 @@ KD mensual ${safeDecimal(monthlyKd, 2, "0.00")} + ${ + hasReadyKpm + ? ` +
Delta de kills: ${formatSignedNumber(killsDelta)} @@ -854,7 +900,7 @@ } function formatWindowRange(ranking) { - const windowLabel = String(ranking?.window_kind || "").trim(); + const windowLabel = labelForStatsWindowKind(ranking?.window_kind); const windowStart = formatDateTime(ranking?.window_start); const windowEnd = formatDateTime(ranking?.window_end); if (windowLabel) { @@ -875,6 +921,113 @@ return labels[String(metric || "").trim()] || "Kills"; } + function labelForStatsWindowKind(windowKind) { + const labels = { + "current-week": "Semana actual", + "current-month": "Mes actual", + "previous-closed-week-fallback": "Semana cerrada anterior", + "previous-closed-month-fallback": "Mes cerrado anterior", + "previous-week": "Semana anterior", + "previous-month": "Mes anterior", + }; + const normalized = String(windowKind || "").trim(); + return labels[normalized] || normalized; + } + + function renderStatsKpmMetric(data) { + if (data?.kpm_status !== "ready") { + return ""; + } + const kpmValue = safeParseNumber(data?.kpm); + if (!Number.isFinite(kpmValue)) { + return ""; + } + return ` +
Perfiles externos
+ ${ + links.length + ? ` +Perfiles externos no disponibles.
" + } +