// --- Utility: Random Color (seeded) --- function getRandomColor() { const hue = seededRandom(); const saturation = 0.6 + seededRandom() * 0.4; const lightness = 0.3 + seededRandom() * 0.4; return new THREE.Color().setHSL(hue, saturation, lightness).getHex(); } /** * Converts degrees to radians. * @param {number} degrees * @returns {number} */ function degToRad(degrees) { return degrees * (Math.PI / 180); } // --- Seedable Random Number Generator (Mulberry32) --- function seededRandom() { let t = seed += 0x6D2B79F5; t = Math.imul(t ^ t >>> 15, t | 1); t ^= t + Math.imul(t ^ t >>> 7, t | 61); return ((t ^ t >>> 14) >>> 0) / 4294967296; } // --- Helper function to format seconds into MM:SS --- function formatTime(seconds) { if (isNaN(seconds) || seconds === Infinity || seconds < 0) return '--:--'; const minutes = Math.floor(seconds / 60); const remainingSeconds = Math.floor(seconds % 60); const paddedMinutes = String(minutes).padStart(2, '0'); const paddedSeconds = String(remainingSeconds).padStart(2, '0'); return `${paddedMinutes}:${paddedSeconds}`; }