${this.renderBirthBalance(d)}
${this.period === 'current' ? this.renderCurrent(d) : nothing}
${
periods.length > 0
? html`
${periods.map((p) => this.renderBar(p, maxYears))}
`
: nothing
}
${this.renderActiveInterpretation(periods)}
`;
}
private renderBirthBalance(d: DashaData) {
if (!('birthDashaBalance' in d) || !d.birthDashaBalance) return nothing;
const b = d.birthDashaBalance;
const lord = 'nakshatraLord' in d && d.nakshatraLord ? d.nakshatraLord : '';
const yrs = b.years ?? 0;
const mo = b.months ?? 0;
const da = b.days ?? 0;
const parts: string[] = [];
if (yrs) parts.push(`${yrs}y`);
if (mo) parts.push(`${mo}m`);
if (da) parts.push(`${da}d`);
const remaining = parts.length ? parts.join(' ') : '0d';
return html`
${
'mahadasha' in d && d.mahadasha
? html`
Mahadasha
${d.mahadasha.planet}
${
'remainingInMahadasha' in d && d.remainingInMahadasha
? html`${formatNumber(d.remainingInMahadasha.years + d.remainingInMahadasha.months / 12, 1)} years left`
: nothing
}
`
: nothing
}
${
'antardasha' in d && d.antardasha
? html`
Antardasha
${d.antardasha.planet}
${
'remainingInAntardasha' in d && d.remainingInAntardasha
? html`${formatNumber(d.remainingInAntardasha.years + d.remainingInAntardasha.months / 12, 1)} years left`
: nothing
}
`
: nothing
}
${
'pratyantardasha' in d && d.pratyantardasha
? html`
Pratyantardasha
${d.pratyantardasha.planet}
${
'remainingInPratyantardasha' in d && d.remainingInPratyantardasha
? html`${formatNumber(d.remainingInPratyantardasha.years + d.remainingInPratyantardasha.months / 12, 1)} years left`
: nothing
}
`
: nothing
}
`;
}
private collectPeriods(d: DashaData): DashaPeriod[] {
if ('mahadashas' in d && d.mahadashas?.length) return d.mahadashas;
if ('antardashas' in d && d.antardashas?.length) return d.antardashas;
return [];
}
/** True when the current wall-clock time falls between the period's start and end. */
private isCurrent(p: DashaPeriod): boolean {
if (!p.startDate || !p.endDate) return false;
const now = Date.now();
const start = Date.parse(p.startDate);
const end = Date.parse(p.endDate);
if (Number.isNaN(start) || Number.isNaN(end)) return false;
return now >= start && now < end;
}
/**
* Fractional progress (0..1) through a period at the current time. Used to
* draw a vertical "now" marker inside the active bar. Returns -1 outside the
* period so the caller can skip the marker.
*/
private progressIn(p: DashaPeriod): number {
if (!p.startDate || !p.endDate) return -1;
const start = Date.parse(p.startDate);
const end = Date.parse(p.endDate);
const now = Date.now();
if (
Number.isNaN(start) ||
Number.isNaN(end) ||
now < start ||
now >= end ||
end <= start
) {
return -1;
}
return (now - start) / (end - start);
}
private renderBar(p: DashaPeriod, max: number) {
const years = p.durationYears;
const width = max > 0 ? (years / max) * 100 : 0;
const current = this.isCurrent(p);
const progress = current ? this.progressIn(p) : -1;
const trackClass = current ? 'bar-track bar-now' : 'bar-track';
return html`