(function () { 'use strict'; const root = window.PixelIslandModules ||= {}; const utils = root.CoreUtils || {}; const clamp = utils.clamp || ((value, min, max) => Math.max(min, Math.min(max, value))); const lerp = utils.lerp || ((a, b, t) => a + (b - a) * t); const mod = utils.mod || ((n, m) => ((n % m) + m) % m); function smooth(t) { const n = clamp(t, 0, 1); return n * n * (3 - 2 * n); } function getShadowForMinute(minute) { const m = clamp(Number(minute) || 0, 0, 10); let dirX = -0.9; let length = 1.2; let alpha = 0; let scaleY = 0.26; if (m < 0.65) { const t = smooth(m / 0.65); dirX = lerp(0.42, 0.18, t); length = lerp(1.05, 0.92, t); alpha = lerp(0.12, 0.0, t); scaleY = lerp(0.22, 0.18, t); } else if (m < 1.35) { const t = smooth((m - 0.65) / 0.70); dirX = lerp(-1.05, -0.82, t); length = lerp(1.38, 1.12, t); alpha = lerp(0.0, 0.27, t); scaleY = lerp(0.22, 0.27, t); } else if (m < 5.65) { const t = smooth((m - 1.35) / 4.30); const elevation = Math.sin(t * Math.PI); dirX = lerp(-0.82, 0.98, t); length = lerp(1.12, 1.34, t) - elevation * 0.48; alpha = lerp(0.27, 0.20, elevation); scaleY = 0.24 + 0.06 * (1 - elevation); } else if (m < 6.40) { const t = smooth((m - 5.65) / 0.75); dirX = lerp(0.98, 1.08, t); length = lerp(1.34, 1.56, t); alpha = lerp(0.20, 0.0, t); scaleY = lerp(0.28, 0.20, t); } else if (m < 7.25) { const t = smooth((m - 6.40) / 0.85); dirX = lerp(0.20, -0.36, t); length = lerp(0.92, 1.08, t); alpha = lerp(0.0, 0.12, t); scaleY = lerp(0.18, 0.23, t); } else if (m < 9.20) { const t = smooth((m - 7.25) / 1.95); dirX = lerp(-0.36, -0.58, t); length = lerp(1.08, 1.18, t); alpha = 0.12; scaleY = 0.23; } else { const t = smooth((m - 9.20) / 0.80); dirX = lerp(-0.58, 0.42, t); length = lerp(1.18, 1.05, t); alpha = lerp(0.12, 0.0, t); scaleY = lerp(0.23, 0.18, t); } return { dirX, length, skewX: dirX * (0.72 + 0.32 * length), scaleY, alpha }; } function getPhase(options) { const { dayMs, now, dayNightEnabled, mixHex } = options; if (dayNightEnabled === false) { return { key: 'day', label: 'Day', progress: 0.25, sky: '#86d5ff', darkness: 0, darkOverlay: 'rgba(12, 19, 45, 0)', tint: 'rgba(255,255,255,0)', tintAlpha: 0, shadow: getShadowForMinute(3) }; } const t = mod(now || Date.now(), dayMs); const minute = t / 60000; const stops = [ { at: 0.00, key: 'preDawn', label: 'Night', sky: '#17254e', darkness: 0.52, tint: [22, 28, 66, 0.10], overlay: [12, 19, 45] }, { at: 0.65, key: 'dawn', label: 'Morning', sky: '#5969aa', darkness: 0.30, tint: [120, 100, 150, 0.10], overlay: [40, 43, 78] }, { at: 1.35, key: 'morning', label: 'Morning', sky: '#f6b16b', darkness: 0.12, tint: [255, 195, 126, 0.13], overlay: [114, 64, 36] }, { at: 2.15, key: 'day', label: 'Day', sky: '#8ad8ff', darkness: 0.00, tint: [255, 255, 255, 0.00], overlay: [12, 19, 45] }, { at: 4.75, key: 'day', label: 'Day', sky: '#8ad8ff', darkness: 0.00, tint: [255, 255, 255, 0.00], overlay: [12, 19, 45] }, { at: 5.65, key: 'evening', label: 'Evening', sky: '#ffa153', darkness: 0.07, tint: [255, 166, 88, 0.10], overlay: [130, 48, 18] }, { at: 6.40, key: 'evening', label: 'Evening', sky: '#d55a2d', darkness: 0.20, tint: [255, 118, 62, 0.17], overlay: [118, 42, 18] }, { at: 7.25, key: 'night', label: 'Night', sky: '#1b2a58', darkness: 0.46, tint: [32, 40, 82, 0.07], overlay: [12, 19, 45] }, { at: 9.20, key: 'night', label: 'Night', sky: '#132247', darkness: 0.58, tint: [16, 24, 58, 0.10], overlay: [12, 19, 45] }, { at: 10.00, key: 'preDawn', label: 'Night', sky: '#17254e', darkness: 0.52, tint: [22, 28, 66, 0.10], overlay: [12, 19, 45] } ]; let a = stops[0], b = stops[1]; for (let i = 0; i < stops.length - 1; i++) { if (minute >= stops[i].at && minute < stops[i + 1].at) { a = stops[i]; b = stops[i + 1]; break; } } const eased = smooth((minute - a.at) / Math.max(0.0001, b.at - a.at)); const tint = a.tint.map((value, i) => lerp(value, b.tint[i], eased)); const overlay = a.overlay.map((value, i) => lerp(value, b.overlay[i], eased)); const darkness = lerp(a.darkness, b.darkness, eased); const dominantKey = darkness >= 0.34 ? 'night' : (a.key === 'evening' || b.key === 'evening' ? 'evening' : (a.key === 'morning' || b.key === 'morning' || a.key === 'dawn' || b.key === 'dawn' ? 'morning' : 'day')); return { key: dominantKey, label: dominantKey === 'night' ? 'Night' : dominantKey === 'evening' ? 'Evening' : dominantKey === 'morning' ? 'Morning' : 'Day', progress: t / dayMs, sky: mixHex(a.sky, b.sky, eased), darkness, darkOverlay: `rgba(${Math.round(overlay[0])}, ${Math.round(overlay[1])}, ${Math.round(overlay[2])}, ${darkness.toFixed(3)})`, tint: `rgba(${Math.round(tint[0])}, ${Math.round(tint[1])}, ${Math.round(tint[2])}, ${tint[3].toFixed(3)})`, tintAlpha: tint[3], shadow: getShadowForMinute(minute) }; } root.Lighting = { getPhase, getShadowForMinute }; })();