let allRotations = []; let currentIndex = 0; const ITEMS_PER_PAGE = 5; let observer; window.loadHeader(function(headerContainer) { const stageButton = headerContainer.querySelector('.menu-item.stage'); if (stageButton) { stageButton.classList.add('active'); } if (typeof CONFIG !== 'undefined') { const apiBase = CONFIG.API_BASE_URL.replace(/\/$/, ""); const logoutForm = document.getElementById("logout-form"); if (logoutForm) { logoutForm.action = apiBase + "/api/v1/spfn/logout"; const originInput = document.getElementById("logout_frontend_origin"); if (originInput) originInput.value = window.location.origin; logoutForm.addEventListener('submit', () => { sessionStorage.removeItem('user_cache'); }); } const renderData = (data) => { if (typeof data === 'string') { try { data = JSON.parse(data); } catch (e) { console.error(e); } } const nameEl = document.getElementById('mii-name'); const imgEl = document.getElementById('mii-img'); if (nameEl) { nameEl.textContent = (data.mii && data.mii.name) || data.nickname || data.user_id || data.username || "User"; } if (imgEl) { const miiBlob = (data.mii && data.mii.data) || data.mii_data; if (miiBlob) { imgEl.src = `https://mii-unsecure.ariankordi.net/miis/image.png?erri=s6u7r-rsp&data=${encodeURIComponent(miiBlob)}&type=face&width=270`; imgEl.style.display = 'block'; } } }; const cached = sessionStorage.getItem('user_cache'); if (cached) renderData(JSON.parse(cached)); fetch(apiBase + "/api/v1/me", { credentials: 'include' }) .then(res => res.ok ? res.json() : Promise.reject(res)) .then(data => { sessionStorage.setItem('user_cache', JSON.stringify(data)); renderData(data); }) .catch(err => { if (!cached) { const nameEl = document.getElementById('mii-name'); if (nameEl) nameEl.textContent = "Guest"; } console.error(err); }); } renderStages(); }); const API_URL = `${CONFIG.API_BASE_URL}/api/v1/boss`; function stageNames(stages, lang = "en-US") { return stages.map(s => s.translatedNames[lang]); } function getStageClass(stageName) { const name = stageName.toLowerCase(); if (name.includes("ancho-v")) return "sprite-ancho-v"; if (name.includes("arowana")) return "sprite-arowana"; if (name.includes("blackbelly")) return "sprite-blackbelly"; if (name.includes("bluefin")) return "sprite-bluefin"; if (name.includes("camp")) return "sprite-camp"; if (name.includes("flounder")) return "sprite-flounder"; if (name.includes("hammerhead")) return "sprite-hammerhead"; if (name.includes("kelp")) return "sprite-kelp"; if (name.includes("mahi-mahi")) return "sprite-mahi-mahi"; if (name.includes("moray")) return "sprite-moray"; if (name.includes("museum")) return "sprite-museum"; if (name.includes("piranha")) return "sprite-piranha"; if (name.includes("port")) return "sprite-port"; if (name.includes("saltspray")) return "sprite-saltspray"; if (name.includes("urchin")) return "sprite-urchin"; if (name.includes("walleye")) return "sprite-walleye"; return "sprite"; } async function fetchRotations() { try { const res = await fetch(API_URL); if (!res.ok) throw new Error(`HTTP error! status: ${res.status}`); const data = await res.json(); const rotations = data?.pretendo?.rotations ?? {}; const now = new Date(); const timestamps = Object.keys(rotations).sort((a, b) => Number(a) - Number(b)); const result = []; for (const ts of timestamps) { const start = new Date(Number(ts)); const end = new Date(start.getTime() + 2 * 60 * 60 * 1000); if (end < now) continue; const r = rotations[ts]; result.push({ turf: stageNames(r.turfStages), ranked: stageNames(r.rankedStages), ranked_mode: r.rankedMode.replace(/([a-z])([A-Z])/g, "$1 $2"), startTime: start, endTime: end, }); } return result; } catch (error) { console.error(error); return []; } } async function renderStages() { const container = document.getElementById("stages-container"); const loadingOverlay = document.getElementById("loading-overlay"); try { allRotations = await fetchRotations(); if (!allRotations.length) { container.innerHTML = `

Something went wrong! Try reloading the page.

`; if (loadingOverlay) loadingOverlay.style.display = 'none'; return; } container.innerHTML = ""; const trigger = document.createElement('div'); trigger.id = 'scroll-trigger'; trigger.style.height = '2px'; container.after(trigger); loadMore(true); observer = new IntersectionObserver((entries) => { if (entries[0].isIntersecting && currentIndex < allRotations.length) { loadMore(false); } }, { rootMargin: '200px' }); observer.observe(trigger); } catch (err) { console.error(err); if (loadingOverlay) loadingOverlay.style.display = 'none'; } } function loadMore(isInitial) { const container = document.getElementById("stages-container"); const loadingOverlay = document.getElementById("loading-overlay"); if (loadingOverlay) { loadingOverlay.style.display = 'flex'; if (typeof window.animateLoadingCanvas === 'function') { window.animateLoadingCanvas(); } } const waitTime = isInitial ? 0 : 800; setTimeout(() => { const nextBatch = allRotations.slice(currentIndex, currentIndex + ITEMS_PER_PAGE); let html = ""; for (const rotation of nextBatch) { const optionsDate = { day: "2-digit", month: "2-digit" }; const optionsTime = { hour: "numeric", minute: "2-digit", hour12: true }; const timeZone = "Europe/Paris"; const formattedTime = `${rotation.startTime.toLocaleDateString("en-GB", { ...optionsDate, timeZone })} at ${rotation.startTime.toLocaleTimeString("en-GB", { ...optionsTime, timeZone })} (CEST) ~ ${rotation.endTime.toLocaleDateString("en-GB", { ...optionsDate, timeZone })} at ${rotation.endTime.toLocaleTimeString("en-GB", { ...optionsTime, timeZone })} (CEST)`; html += `
${formattedTime}
Regular Battle
Regular Battle
${rotation.turf.map(name => `
${name}
`).join("")}
Ranked Battle
Ranked Battle
Battle Mode
${rotation.ranked_mode}
${rotation.ranked.map(name => `
${name}
`).join("")}
`; } container.insertAdjacentHTML('beforeend', html); currentIndex += ITEMS_PER_PAGE; if (loadingOverlay) loadingOverlay.style.display = 'none'; if (currentIndex >= allRotations.length) { if (observer) observer.disconnect(); const trigger = document.getElementById('scroll-trigger'); if (trigger) trigger.remove(); } }, waitTime); }