// Pure function retained from the supplied Meeus / NOAA implementation. // Arguments: UTC Unix milliseconds, degrees latitude, degrees longitude. const RAD=Math.PI/180,DAY_MS=86400000; const mod=(x,n)=>((x%n)+n)%n,clamp=(x,a,b)=>Math.max(a,Math.min(b,x)); export function solarPosition(ms, lat, lon) { const jd = ms / DAY_MS + 2440587.5, t = (jd - 2451545) / 36525; const L = mod(280.46646 + t * (36000.76983 + t * .0003032), 360) * RAD; const M = (357.52911 + t * (35999.05029 - .0001537 * t)) * RAD; const e = .016708634 - t * (.000042037 + .0000001267 * t); const C = Math.sin(M) * (1.914602 - t * (.004817 + .000014 * t)) + Math.sin(2 * M) * (.019993 - .000101 * t) + Math.sin(3 * M) * .000289; const omega = (125.04 - 1934.136 * t) * RAD; const lambda = L + (C - .00569 - .00478 * Math.sin(omega)) * RAD; const mean = 23 + (26 + (21.448 - t * (46.815 + t * (.00059 - t * .001813))) / 60) / 60; const obliq = (mean + .00256 * Math.cos(omega)) * RAD; const dec = Math.asin(Math.sin(obliq) * Math.sin(lambda)); const y = Math.tan(obliq / 2) ** 2; const eq = 4 / RAD * (y * Math.sin(2 * L) - 2 * e * Math.sin(M) + 4 * e * y * Math.sin(M) * Math.cos(2 * L) - .5 * y * y * Math.sin(4 * L) - 1.25 * e * e * Math.sin(2 * M)); const solarMinutes = mod(mod(ms, DAY_MS) / 60000 + eq + 4 * lon, 1440); const H = (solarMinutes / 4 - 180) * RAD, phi = lat * RAD; const elevation = Math.asin(clamp(Math.sin(phi) * Math.sin(dec) + Math.cos(phi) * Math.cos(dec) * Math.cos(H), -1, 1)) / RAD; const azimuth = mod(Math.atan2(Math.sin(H), Math.cos(H) * Math.sin(phi) - Math.tan(dec) * Math.cos(phi)) / RAD + 180, 360); return { elevation, azimuth, declination: dec / RAD, equationOfTime: eq }; }