(function () { "use strict"; const { DAY_IN_MS, getDateKey, getDecanForDate, getMoonPhaseName, calcPlanetaryHoursForDayAndLocation } = window.TarotCalc; const nowUiHelpers = window.NowUiHelpers || {}; if ( typeof nowUiHelpers.findNextDecanTransition !== "function" || typeof nowUiHelpers.findNextMoonPhaseTransition !== "function" || typeof nowUiHelpers.formatCountdown !== "function" || typeof nowUiHelpers.getSignStartDate !== "function" || typeof nowUiHelpers.getDisplayTarotName !== "function" || typeof nowUiHelpers.setNowCardImage !== "function" || typeof nowUiHelpers.updateNowStats !== "function" ) { throw new Error("NowUiHelpers module must load before ui-now.js"); } let moonCountdownCache = null; let decanCountdownCache = null; function updateNowPanel(referenceData, geo, elements, timeFormat = "minutes") { if (!referenceData || !geo || !elements) { return { dayKey: getDateKey(new Date()), skyRefreshKey: "" }; } const now = new Date(); const dayKey = getDateKey(now); const todayHours = calcPlanetaryHoursForDayAndLocation(now, geo); const yesterday = new Date(now.getTime() - DAY_IN_MS); const yesterdayHours = calcPlanetaryHoursForDayAndLocation(yesterday, geo); const tomorrow = new Date(now.getTime() + DAY_IN_MS); const tomorrowHours = calcPlanetaryHoursForDayAndLocation(tomorrow, geo); const allHours = [...yesterdayHours, ...todayHours, ...tomorrowHours].sort( (a, b) => a.start.getTime() - b.start.getTime() ); const currentHour = allHours.find((entry) => now >= entry.start && now < entry.end); const currentHourSkyKey = currentHour ? `${currentHour.planetId}-${currentHour.start.toISOString()}` : "no-hour"; if (currentHour) { const planet = referenceData.planets[currentHour.planetId]; elements.nowHourEl.textContent = planet ? `${planet.symbol} ${planet.name}` : currentHour.planetId; if (elements.nowHourTarotEl) { const hourCardName = planet?.tarot?.majorArcana || ""; const hourTrumpNumber = planet?.tarot?.number; elements.nowHourTarotEl.textContent = hourCardName ? nowUiHelpers.getDisplayTarotName(hourCardName, hourTrumpNumber) : "--"; } const msLeft = Math.max(0, currentHour.end.getTime() - now.getTime()); elements.nowCountdownEl.textContent = nowUiHelpers.formatCountdown(msLeft, timeFormat); if (elements.nowHourNextEl) { const nextHour = allHours.find( (entry) => entry.start.getTime() >= currentHour.end.getTime() - 1000 ); if (nextHour) { const nextPlanet = referenceData.planets[nextHour.planetId]; elements.nowHourNextEl.textContent = nextPlanet ? `> ${nextPlanet.name}` : `> ${nextHour.planetId}`; } else { elements.nowHourNextEl.textContent = "> --"; } } nowUiHelpers.setNowCardImage( elements.nowHourCardEl, planet?.tarot?.majorArcana, "Current planetary hour card", planet?.tarot?.number ); } else { elements.nowHourEl.textContent = "--"; elements.nowCountdownEl.textContent = "--"; if (elements.nowHourTarotEl) { elements.nowHourTarotEl.textContent = "--"; } if (elements.nowHourNextEl) { elements.nowHourNextEl.textContent = "> --"; } nowUiHelpers.setNowCardImage(elements.nowHourCardEl, null, "Current planetary hour card"); } const moonIllum = window.SunCalc.getMoonIllumination(now); const moonPhase = getMoonPhaseName(moonIllum.phase); const moonTarot = referenceData.planets.luna?.tarot?.majorArcana || "The High Priestess"; elements.nowMoonEl.textContent = `${moonPhase} (${Math.round(moonIllum.fraction * 100)}%)`; elements.nowMoonTarotEl.textContent = nowUiHelpers.getDisplayTarotName(moonTarot, referenceData.planets.luna?.tarot?.number); nowUiHelpers.setNowCardImage( elements.nowMoonCardEl, moonTarot, "Current moon phase card", referenceData.planets.luna?.tarot?.number ); if (!moonCountdownCache || moonCountdownCache.fromPhase !== moonPhase || now >= moonCountdownCache.changeAt) { moonCountdownCache = nowUiHelpers.findNextMoonPhaseTransition(now); } if (elements.nowMoonCountdownEl) { if (moonCountdownCache?.changeAt) { const remaining = moonCountdownCache.changeAt.getTime() - now.getTime(); elements.nowMoonCountdownEl.textContent = nowUiHelpers.formatCountdown(remaining, timeFormat); if (elements.nowMoonNextEl) { elements.nowMoonNextEl.textContent = `> ${moonCountdownCache.nextPhase}`; } } else { elements.nowMoonCountdownEl.textContent = "--"; if (elements.nowMoonNextEl) { elements.nowMoonNextEl.textContent = "> --"; } } } const sunInfo = getDecanForDate(now, referenceData.signs, referenceData.decansBySign); const decanSkyKey = sunInfo?.sign ? `${sunInfo.sign.id}-${sunInfo.decan?.index || 1}` : "no-decan"; if (sunInfo?.sign) { const signStartDate = nowUiHelpers.getSignStartDate(now, sunInfo.sign); const daysSinceSignStart = (now.getTime() - signStartDate.getTime()) / DAY_IN_MS; const signDegree = Math.min(29.9, Math.max(0, daysSinceSignStart)); const signMajorName = nowUiHelpers.getDisplayTarotName(sunInfo.sign.tarot.majorArcana, sunInfo.sign.tarot.trumpNumber); elements.nowDecanEl.textContent = `${sunInfo.sign.symbol} ${sunInfo.sign.name} · ${signMajorName} (${signDegree.toFixed(1)}°)`; const currentDecanKey = `${sunInfo.sign.id}-${sunInfo.decan?.index || 1}`; if (!decanCountdownCache || decanCountdownCache.key !== currentDecanKey || now >= decanCountdownCache.changeAt) { decanCountdownCache = nowUiHelpers.findNextDecanTransition(now, referenceData.signs, referenceData.decansBySign); } if (sunInfo.decan) { const decanCardName = sunInfo.decan.tarotMinorArcana; elements.nowDecanTarotEl.textContent = nowUiHelpers.getDisplayTarotName(decanCardName); nowUiHelpers.setNowCardImage(elements.nowDecanCardEl, sunInfo.decan.tarotMinorArcana, "Current decan card"); } else { const signTarotName = sunInfo.sign.tarot?.majorArcana || "--"; elements.nowDecanTarotEl.textContent = signTarotName === "--" ? "--" : nowUiHelpers.getDisplayTarotName(signTarotName, sunInfo.sign.tarot?.trumpNumber); nowUiHelpers.setNowCardImage( elements.nowDecanCardEl, sunInfo.sign.tarot?.majorArcana, "Current decan card", sunInfo.sign.tarot?.trumpNumber ); } if (elements.nowDecanCountdownEl) { if (decanCountdownCache?.changeAt) { const remaining = decanCountdownCache.changeAt.getTime() - now.getTime(); elements.nowDecanCountdownEl.textContent = nowUiHelpers.formatCountdown(remaining, timeFormat); if (elements.nowDecanNextEl) { elements.nowDecanNextEl.textContent = `> ${nowUiHelpers.getDisplayTarotName(decanCountdownCache.nextLabel)}`; } } else { elements.nowDecanCountdownEl.textContent = "--"; if (elements.nowDecanNextEl) { elements.nowDecanNextEl.textContent = "> --"; } } } } else { elements.nowDecanEl.textContent = "--"; elements.nowDecanTarotEl.textContent = "--"; nowUiHelpers.setNowCardImage(elements.nowDecanCardEl, null, "Current decan card"); if (elements.nowDecanCountdownEl) { elements.nowDecanCountdownEl.textContent = "--"; } if (elements.nowDecanNextEl) { elements.nowDecanNextEl.textContent = "> --"; } } nowUiHelpers.updateNowStats(referenceData, elements, now); return { dayKey, skyRefreshKey: `${currentHourSkyKey}|${decanSkyKey}|${moonPhase}` }; } window.TarotNowUi = { updateNowPanel }; })();