/**
* Lara Kiesewetter – Live Schachturnier
* Data fetching, PGN loading, standings, auto-refresh
*/
/* global parsePGN, filterLaraGames, getLiveGame, getTodaysGames, getLatestGame */
async function fetchRoundPGN(round) {
const res = await fetch(`https://www.deutsche-schachjugend.de/2026/odjm-d/partien/${round}.pgn?t=${Date.now()}`);
if (!res.ok) return null;
const buf = await res.arrayBuffer();
let text = new TextDecoder('utf-8').decode(buf);
if (text.includes('\uFFFD')) {
text = new TextDecoder('iso-8859-1').decode(buf);
}
return text;
}
async function loadPGN(showOverlay = true) {
const currentPollId = pollId;
if (showOverlay) showLoading(true);
hideError();
try {
if (currentRound === 0) {
if (showOverlay) showLoading(false);
return;
}
const maxRound = currentRound + 1;
const isFirstLoad = Object.keys(roundPgns).length === 0;
const startRound = isFirstLoad ? 1 : currentRound;
for (let r = startRound; r <= maxRound; r++) {
const text = await fetchRoundPGN(r);
if (currentPollId !== pollId) return;
if (text !== null) roundPgns[r] = text;
}
const combinedPgn = Object.values(roundPgns).join('\n\n');
const allGames = parsePGN(combinedPgn);
allLaraGames = filterLaraGames(allGames);
if (allLaraGames.length === 0) {
return;
}
if (!userSelectedGame) {
const liveGame = getLiveGame(allLaraGames);
const todaysGames = getTodaysGames(allLaraGames);
currentGame = liveGame || (todaysGames.length > 0 ? getLatestGame(todaysGames) : getLatestGame(allLaraGames));
}
updateBoard();
updatePlayerInfo();
updateMovesList();
updateAllGamesList();
updatePGNDisplay();
updateTimestamp();
showLoading(false);
} catch (error) {
if (currentPollId !== pollId) return;
console.error('Fehler beim Laden:', error);
showLoading(false);
}
}
async function updateStandings() {
try {
const res = await fetch(`https://www.deutsche-schachjugend.de/2026/odjm-d/tabelle/?t=${Date.now()}`);
if (!res.ok) throw new Error('Fehler beim Laden');
const html = await res.text();
const roundMatch = html.match(/Tabellenstand\s+nach\s+der\s+(\d+)\.\s*Runde/);
if (roundMatch) {
currentRound = parseInt(roundMatch[1]);
}
const rows = html.matchAll(/
]*>(.*?)<\/tr>/gs);
for (const row of rows) {
if (!row[1].includes('Lara Kiesewetter')) continue;
const cells = row[1].matchAll(/| ]*>(.*?)<\/td>/gs);
const clean = [];
for (const cell of cells) {
clean.push(cell[1].replace(/<[^>]+>/g, '').trim());
}
if (clean.length >= 9) {
const data = {
rank: clean[0],
player: 'Lara Kiesewetter',
wins: clean[5],
draws: clean[6],
losses: clean[7],
points: clean[8],
round_info: roundMatch ? `nach der ${roundMatch[1]}. Runde` : '',
round: currentRound,
};
const container = document.getElementById('standings-content');
container.innerHTML = `
${data.rank}.
${data.round_info || 'nach Runde 1'}
Punkte
${data.points}
Siege
${data.wins}
Unentschieden
${data.draws}
Niederlagen
${data.losses}
`;
return;
}
}
document.getElementById('standings-content').innerHTML = 'Daten nicht verfügbar ';
} catch {
document.getElementById('standings-content').innerHTML = 'Daten nicht verfügbar ';
}
}
function updateTimestamp() {
const time = new Date();
document.getElementById('last-update').textContent =
`Letztes Update: ${time.toLocaleTimeString('de-DE')}`;
}
async function startAutoRefresh() {
clearInterval(pollInterval);
clearInterval(updateTimer);
clearInterval(standingsInterval);
const myId = ++pollId;
let lastUpdate = Date.now();
document.getElementById('refresh-timer').textContent = '0s';
document.getElementById('refresh-timer').style.color = '#4ade80';
await updateStandings();
loadPGN(true);
pollInterval = setInterval(() => {
if (pollId !== myId) { clearInterval(pollInterval); clearInterval(updateTimer); clearInterval(standingsInterval); return; }
loadPGN(false);
lastUpdate = Date.now();
}, 15000);
updateTimer = setInterval(() => {
if (pollId !== myId) { clearInterval(pollInterval); clearInterval(updateTimer); clearInterval(standingsInterval); return; }
const elapsed = Date.now() - lastUpdate;
const remaining = Math.max(0, 15000 - elapsed);
const s = Math.floor(remaining / 1000);
document.getElementById('refresh-timer').textContent = `${s}s`;
}, 1000);
standingsInterval = setInterval(() => {
if (pollId !== myId) { clearInterval(pollInterval); clearInterval(updateTimer); clearInterval(standingsInterval); return; }
updateStandings();
}, 1800000);
} |