panchang-ts 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -20,6 +20,7 @@ Works offline in React Native (Hermes), Node.js, and browsers.
20
20
  - [When to use `getInstantPanchang` vs `getDailyPanchang`](#when-to-use-getinstantpanchang-vs-getdailypanchang)
21
21
  - [Options](#options)
22
22
  - [Low-level Utilities](#low-level-utilities)
23
+ - [Birth Chart (Kundli) API](#birth-chart-kundli-api)
23
24
  - [Types](#types)
24
25
  - [React Native / Hermes](#react-native--hermes)
25
26
  - [Accuracy](#accuracy)
@@ -72,7 +73,11 @@ console.log(result.moonrise); // Date | null
72
73
 
73
74
  // Muhurta & inauspicious periods
74
75
  console.log(result.brahmaMuhurta); // { start: Date, end: Date }
76
+ console.log(result.madhyahna); // solar noon ±24 min
75
77
  console.log(result.rahuKalam); // { start: Date, end: Date }
78
+ console.log(result.anandadiYoga.name); // "Ananda" (Vara × Nakshatra cycle)
79
+ console.log(result.gandaMula.active); // false (or true with severity)
80
+ console.log(result.varjyam); // { start, end } | null
76
81
 
77
82
  // Choghadiya — 8 daytime slots
78
83
  result.choghadiya.day.forEach(slot => {
@@ -181,13 +186,13 @@ Tithi, Nakshatra, Yoga, Karana, Vara — with transition times throughout the da
181
186
  Chandra Masa with Adhika (leap month) detection, both **Purnimanta** (North Indian, default) and **Amanta** (South Indian) systems, Vikram Samvat, Shaka Samvat.
182
187
 
183
188
  ### Muhurta & Auspicious Timing
184
- Brahma Muhurta, Abhijit Muhurta, Vijaya Muhurta (11th day-muhurta), Godhuli (sunset muhurta), Nishita (midnight muhurta, used for Shivaratri), nakshatra-keyed Amrit Kala. Choghadiya (16 slots), Gowri Panchangam / Nalla Neram (16 slots), Hora (24 planetary hours), Dur Muhurta (2 inauspicious windows).
189
+ Brahma Muhurta, Abhijit Muhurta, Vijaya Muhurta (11th day-muhurta), Godhuli (sunset muhurta), Nishita (midnight muhurta, used for Shivaratri), **Madhyahna** (solar noon ±24 min ritual window), **Pratah Sandhya** / **Sayahna Sandhya** (asymmetric dawn / dusk twilight windows, width = `nightDuration / 10` — ~62–81 min depending on season, ending *at* sunrise / starting *at* sunset; matches DrikPanchang within ±2 min), classical aliases `dinamanaMinutes` / `ratrimanaMinutes`, nakshatra-keyed Amrit Kala. Choghadiya (16 slots), Gowri Panchangam / Nalla Neram (16 slots), Hora (24 planetary hours), Dur Muhurta (2 inauspicious windows), **Do Ghati Muhurta** (15 day + 15 night ~48-min slots, deity-keyed, no vara rotation), **Panchaka Rahita Muhurta** (slices of the day free of Panchaka), **Anandadi Yoga** (28-name Vara × Nakshatra cycle).
185
190
 
186
191
  ### Inauspicious Periods
187
- Rahu Kalam, Gulika Kalam, Yamaganda, Panchaka detection, Bhadra Kala (Vishti karana window with earth / heaven / paatal location).
192
+ Rahu Kalam, Gulika Kalam, Yamaganda, Panchaka detection, Bhadra Kala (Vishti karana window with earth / heaven / paatal location), **Varjyam** (BPHS-keyed forbidden ~96-min window per nakshatra), **Ganda Mula** (Moon in the 6 root nakshatras — Ashwini / Ashlesha / Magha / Jyeshtha / Mula / Revati — with `mild` / `severe` severity).
188
193
 
189
194
  ### Special Yogas & Festivals
190
- Amrit Siddhi, Sarvartha Siddhi, Ravi Pushya, Guru Pushya yoga detection.
195
+ Amrit Siddhi, Sarvartha Siddhi, Ravi Pushya, Guru Pushya, **Dwipushkar**, **Tripushkar**, **Jwalamukhi**, **Aadal**, **Vidaal**, **Ravi** yoga detection.
191
196
 
192
197
  **80+ festivals** spanning pan-Indian, regional, and classical observances:
193
198
 
@@ -204,7 +209,10 @@ Amrit Siddhi, Sarvartha Siddhi, Ravi Pushya, Guru Pushya yoga detection.
204
209
  Solar & lunar eclipse detection with subtype (partial / total / annular / penumbral), magnitude at peak, observer-horizon visibility, and pre-eclipse **sutak** impurity window.
205
210
 
206
211
  ### Jyotish (Vedic Astrology)
207
- All 9 graha positions (geocentric, sidereal) with rashi, nakshatra, pada, and retrograde status. Vimshottari Dasha with Antardasha breakdown — from a birth moment alone or from an explicit Moon longitude. Chandra Balam (transit-Moon favorability relative to janma rashi).
212
+ All 9 graha positions (geocentric, sidereal) with rashi, nakshatra, pada, and retrograde status. Vimshottari Dasha with Antardasha and **Pratyantar** (third-level) breakdown — from a birth moment alone or from an explicit Moon longitude. Chandra Balam (transit-Moon favorability relative to janma rashi). **Tarabala** (9-tara cycle — Janma, Sampat, Vipat, Kshema, Pratyari, Sadhaka, Vadha, Mitra, Ati-Mitra — keyed off janma nakshatra; parallel to Chandra Balam). Optional `nodeType: 'true'` for Rahu/Ketu replaces the mean-node default with Meeus's dominant periodic correction (~±0.6° vs ±2° worst-case for the mean node).
213
+
214
+ ### Birth Chart (Kundli)
215
+ Full natal-chart foundation built on top of the planetary engine: sidereal **Lagna** (ascendant) via Meeus eq. 13.6 (atan2 form); **Bhava** (12 houses) under three configurable house systems — `'whole-sign'` (default classical Vedic), `'equal'`, or `'placidus-kp'`; full **D1 (Rashi)** and **D9 (Navamsa)** charts placing all 9 grahas with house assignments; **Ashtakoot Guna Milan** (36-point marriage compatibility); **Mangal Dosha** (Manglik affliction with cancellations); **Sade Sati** (current Saturn-arc phase + arc start/end dates within ±2 days); **Planetary dignity** (exalted / debilitated / moolatrikona / own / friend / neutral / enemy per BPHS Ch.3-4).
208
216
 
209
217
  ### Astronomy
210
218
  Sunrise, Sunset, Moonrise, Moonset, Chandra Rashi (Moon sign), Surya Nakshatra. Cross-verified across diaspora locations (New York, London, Sydney, Dubai, Singapore) including DST transitions via IANA timezone strings.
@@ -213,7 +221,7 @@ Sunrise, Sunset, Moonrise, Moonset, Chandra Rashi (Moon sign), Surya Nakshatra.
213
221
  2 languages: **English** and **Hindi** (Devanagari). All returned display strings respect the `language` option.
214
222
 
215
223
  ### Configuration
216
- 3 ayanamsa systems (Lahiri, B.V. Raman, KP), 2 masa systems (Purnimanta, Amanta), adjustable precision, optional fast mode (`computeEndTimes: false` for ~5x speedup).
224
+ 5 ayanamsa systems (Lahiri, B.V. Raman, KP, **True Chitrapaksha**, **Thirukanitham**), 2 masa systems (Purnimanta, Amanta), 3 house systems (whole-sign, equal, Placidus-KP), adjustable precision, optional fast mode (`computeEndTimes: false` for ~5x speedup).
217
225
 
218
226
  ---
219
227
 
@@ -268,16 +276,27 @@ const result = getDailyPanchang(
268
276
  | `moonrise` | `Date \| null` | Moonrise; `null` if none that day |
269
277
  | `moonset` | `Date \| null` | Moonset; `null` if none that day |
270
278
  | `panchaka` | `boolean` | `true` when Moon is in last 5 nakshatras |
279
+ | `panchakaRahita` | `TimePeriod[]` | Slices of the Hindu day FREE of Panchaka; `[]` when Panchaka pervades the entire day |
280
+ | `doGhatiMuhurta` | `DoGhatiInfo` | 15 day + 15 night ~48-min deity-keyed slots covering sunrise→sunset and sunset→nextSunrise |
281
+ | `gandaMula` | `GandaMulaInfo` | Moon-in-root-nakshatra detection at sunrise; `active: false` for the 21 non-root nakshatras |
282
+ | `anandadiYoga` | `AnandadiYogaInfo` | Vara × Nakshatra 28-name cycle yoga at sunrise |
271
283
  | `specialYogas` | `SpecialYogaInfo[]` | Auspicious yogas active today |
272
284
  | `durMuhurta` | `[TimePeriod, TimePeriod]` | Two inauspicious ~48-min windows |
273
285
  | `vijayaMuhurta` | `TimePeriod` | Vijaya Muhurta — 11th day-muhurta, auspicious for success |
274
286
  | `godhuliMuhurta` | `TimePeriod` | Godhuli ("cow-dust") — sunset muhurta, auspicious for ceremonies |
275
287
  | `nishitaMuhurta` | `TimePeriod` | Nishita — midnight muhurta, used for Shivaratri and nocturnal rites |
288
+ | `madhyahna` | `TimePeriod` | Madhyahna — solar noon as a ±24-min ritual window (one classical muhurta wide) |
289
+ | `pratahSandhya` | `TimePeriod` | Dawn-twilight ritual window — three nighttime ghatikas ending *at* sunrise (asymmetric; width = `nightDuration / 10` ≈ 62–81 min) |
290
+ | `sayahnaSandhya` | `TimePeriod` | Dusk-twilight ritual window — three nighttime ghatikas starting *at* sunset (asymmetric; width = `nightDuration / 10`) |
291
+ | `dinamanaMinutes` | `number` | Classical alias of `dayDurationMinutes` (sunrise → sunset) |
292
+ | `ratrimanaMinutes` | `number` | Classical alias of `nightDurationMinutes` (sunset → next sunrise) |
276
293
  | `amritKala` | `TimePeriod \| null` | Amrit Kala — nakshatra-specific auspicious window (null when nakshatra has none) |
294
+ | `varjyam` | `TimePeriod \| null` | Varjyam (Vishaghati / Nakshatra Thyajyam) — BPHS-keyed forbidden ~96-min window; `null` when none overlaps the Hindu day |
277
295
  | `bhadra` | `BhadraInfo \| null` | Bhadra Kala (Vishti karana) window overlapping this Hindu day, or `null` |
278
296
  | `eclipse` | `EclipseInfo \| null` | Solar/lunar eclipse overlapping this Hindu day with sutak window, or `null` |
279
297
  | `festivals` | `FestivalInfo[]` | Festivals / observances today (filtered by `region` option) |
280
298
  | `chandraBalam` | `ChandraBalamInfo?` | Transit-Moon favorability — only present when `janmaRashi` option is passed |
299
+ | `tarabala` | `TarabalaInfo?` | 9-tara cycle position — only present when `janmaNakshatra` option is passed |
281
300
  | `ayanamsa` | `number` | Ayanamsa in degrees at sunrise |
282
301
  | `siderealSunAtSunrise` | `number` | Sun sidereal longitude at sunrise (degrees) |
283
302
  | `siderealMoonAtSunrise` | `number` | Moon sidereal longitude at sunrise (degrees) |
@@ -323,9 +342,12 @@ console.log(result.panchaka); // false
323
342
  | `chandraRashi` | `RashiInfo` | Moon's zodiac sign |
324
343
  | `suryaNakshatra` | `RashiInfo` | Sun's nakshatra |
325
344
  | `panchaka` | `boolean` | `true` when Moon is in last 5 nakshatras |
345
+ | `gandaMula` | `GandaMulaInfo` | Moon-in-root-nakshatra detection at the queried instant |
346
+ | `anandadiYoga` | `AnandadiYogaInfo` | Vara × Nakshatra 28-name cycle yoga at the queried instant |
326
347
  | `specialYogas` | `SpecialYogaInfo[]` | Auspicious yogas at this moment |
327
348
  | `festivals` | `FestivalInfo[]` | Festivals / observances at this moment (see caveat below) |
328
349
  | `chandraBalam` | `ChandraBalamInfo?` | Transit-Moon favorability — only present when `janmaRashi` option is passed |
350
+ | `tarabala` | `TarabalaInfo?` | 9-tara cycle position — only present when `janmaNakshatra` option is passed |
329
351
  | `ayanamsa` | `number` | Ayanamsa in degrees |
330
352
  | `siderealSun` | `number` | Sun sidereal longitude (degrees) |
331
353
  | `siderealMoon` | `number` | Moon sidereal longitude (degrees) |
@@ -366,6 +388,7 @@ Both functions share the same core astronomy, but `getDailyPanchang` operates on
366
388
  | `masaSystem` | `'purnimanta' \| 'amanta'` | `'purnimanta'` | Lunar month naming system. Purnimanta (North Indian) or Amanta (South Indian). |
367
389
  | `region` | `FestivalRegion` | `'all'` | Scopes regional festival variants (Pongal, Vishu, Gudi Padwa, Lohri, Govardhan Puja, Bonalu, …) to a specific Indian state. See [`FestivalRegion`](#types) for the full list. Pre-v2.1 values (`'tamil'`, `'bengal'`, `'north-india'`) are still accepted but emit a deprecation warning; removal in v3. Pan-Indian festivals and the canonical `sankranti` event emit regardless of this setting. |
368
390
  | `janmaRashi` | `number` | _(omitted)_ | Native's birth Moon rashi index (0 = Mesha … 11 = Meena). When provided, the result includes `chandraBalam`. |
391
+ | `janmaNakshatra` | `number` | _(omitted)_ | Native's birth Moon nakshatra index (0 = Ashwini … 26 = Revati). When provided, the result includes `tarabala`. |
369
392
 
370
393
  **`InstantPanchangOptions`** (optional for `getInstantPanchang`): same as above but without `timezone` (instant mode works in UTC).
371
394
 
@@ -385,6 +408,9 @@ import {
385
408
  computeAbhijitMuhurta, computeBrahmaMuhurta,
386
409
  computeVijayaMuhurta, computeGodhuliMuhurta,
387
410
  computeNishitaMuhurta, computeAmritKala,
411
+ computeMadhyahna, computePratahSandhya, computeSayahnaSandhya,
412
+ computeVarjyam, computeGandaMula,
413
+ computeAnandadiYoga, computePanchakaRahita, computeDoGhati,
388
414
  computeGowriPanchangam,
389
415
  // Eclipses (signature: (fromUtc, location, withinDays))
390
416
  getUpcomingSolarEclipse, getUpcomingLunarEclipse, getEclipseDuringDay,
@@ -392,6 +418,7 @@ import {
392
418
  computePlanetaryPositions,
393
419
  computeVimshottariDasha, computeVimshottariDashaFromBirth,
394
420
  computeChandraBalam,
421
+ computeTarabala,
395
422
  GRAHA_ABBR,
396
423
  } from 'panchang-ts';
397
424
 
@@ -444,8 +471,122 @@ const cb = computeChandraBalam(3 /* Karka */, 6 /* Tula */);
444
471
  console.log(cb.house); // 4
445
472
  console.log(cb.quality); // "weak"
446
473
  console.log(cb.englishName); // "Ashubha"
474
+
475
+ // Tarabala — 9-tara cycle from janma nakshatra → transit Moon nakshatra.
476
+ // Inputs are 0-indexed nakshatra (0 = Ashwini ... 26 = Revati).
477
+ const tb = computeTarabala(0 /* janma: Ashwini */, 4 /* transit: Mrigashira */);
478
+ console.log(tb.taraIndex); // 4
479
+ console.log(tb.englishName); // "Pratyari"
480
+ console.log(tb.quality); // "inauspicious"
481
+ ```
482
+
483
+ ---
484
+
485
+ ### Birth Chart (Kundli) API
486
+
487
+ Vedic kundli foundation. Each helper is independent — calling birth-chart APIs
488
+ does **not** add any work to `getDailyPanchang`.
489
+
490
+ ```typescript
491
+ import {
492
+ computeLagna, computeBhava,
493
+ computeRashiChart, computeNavamsa,
494
+ computeAshtakoot, computeMangalDosha, computeSadeSati,
495
+ computeDignity, computeVimshottariPratyantar,
496
+ computeVimshottariDashaFromBirth,
497
+ } from 'panchang-ts';
498
+
499
+ const birth = new Date('1995-08-15T05:30:00Z'); // 11:00 IST
500
+ const loc = { latitude: 28.6139, longitude: 77.2090 }; // New Delhi
501
+
502
+ // 1. Lagna (sidereal ascendant)
503
+ const lagna = computeLagna(birth, loc, 'lahiri', 'en');
504
+ // → { siderealLongitude, rashi: { index, name }, degreeInRashi,
505
+ // nakshatra: { index, name }, pada }
506
+
507
+ // 2. Bhava (12 houses) under any of three systems
508
+ const houses = computeBhava(birth, loc, { houseSystem: 'whole-sign' });
509
+ // → { system, houses: HouseInfo[12], ascendantLongitude, mcLongitude }
510
+ // - 'whole-sign' (default) — each rashi is one house, cusps at 0°
511
+ // - 'equal' — each house spans 30° starting at lagna's exact degree
512
+ // - 'placidus-kp' — true cuspal positions; throws PanchangError('CIRCUMPOLAR')
513
+ // above ~|66.5°| latitude
514
+
515
+ // 3. D1 (Rashi) chart — lagna + bhava + 9 grahas with house placement
516
+ const d1 = computeRashiChart(birth, loc, { houseSystem: 'whole-sign' });
517
+ // → { divisional: 'D1', lagna, bhava, planets: PlanetPlacement[9] }
518
+ d1.planets.find((p) => p.planet === 'Jupiter')?.house; // e.g. 5
519
+ d1.planets.find((p) => p.planet === 'Saturn')?.isRetrograde;
520
+
521
+ // 4. D9 (Navamsa) chart — classical sign-based per-rashi-type rule
522
+ const d9 = computeNavamsa(birth, loc);
523
+ // → { divisional: 'D9', lagnaRashi, planets: PlanetPlacement[9] }
524
+
525
+ // 5. Ashtakoot Guna Milan — 36-point marriage compatibility from natal Moons
526
+ const ashtakoot = computeAshtakoot(
527
+ { rashi: 4, nakshatra: 9 }, // boy: Simha / Magha
528
+ { rashi: 0, nakshatra: 1 }, // girl: Mesha / Bharani
529
+ );
530
+ // → { totalScore: 0..36, koots: KootScore[8], cancellations: string[] }
531
+ // koots in canonical order: Varna, Vashya, Tara, Yoni, Graha Maitri, Gana,
532
+ // Bhakoot, Nadi (max scores 1, 2, 3, 4, 5, 6, 7, 8 respectively)
533
+
534
+ // 6. Mangal Dosha (Manglik) — checks Mars from lagna, Moon, and Venus
535
+ const mangal = computeMangalDosha(d1);
536
+ // → { afflicted: boolean,
537
+ // fromLagna: { afflicted, house }, fromMoon: ..., fromVenus: ...,
538
+ // cancellations: string[] }
539
+
540
+ // 7. Sade Sati — Saturn currently transiting 12th, 1st, or 2nd from natal Moon
541
+ const sadeSati = computeSadeSati(d1.planets[1]!.rashi.index, new Date());
542
+ // → { active, phase: 1|2|3|null, currentArcStart, currentArcEnd, nextArcStart }
543
+
544
+ // 8. Planetary dignity (BPHS Ch.3-4)
545
+ computeDignity('Mars', 0); // 'moolatrikona' (Aries)
546
+ computeDignity('Mars', 9); // 'exalted' (Capricorn)
547
+ computeDignity('Sun', 6); // 'debilitated' (Libra)
548
+ computeDignity('Saturn', 10); // 'moolatrikona' (Aquarius)
549
+
550
+ // 9. Pratyantar (3rd-level) Vimshottari sub-sub-periods
551
+ const dasha = computeVimshottariDashaFromBirth(birth);
552
+ const firstAntar = dasha.mahaDashas[0]!.antarDashas[0]!;
553
+ const pratyantars = computeVimshottariPratyantar(firstAntar);
554
+ // → PratyantarDasha[9] — 9 sub-sub-periods covering the antardasha proportionally
447
555
  ```
448
556
 
557
+ **Ayanamsa options** — any birth-chart helper accepts the new
558
+ `'true-chitra'` (True Chitrapaksha — Spica-anchored) or `'thirukanitham'`
559
+ (South Indian Tamil-Vakya tradition) ayanamsas in addition to the original
560
+ `'lahiri'`, `'raman'`, `'krishnamurti'`. Pass via the `options.ayanamsa`
561
+ field on `BirthChartOptions`.
562
+
563
+ **True Rahu/Ketu node** — `computePlanetaryPositions(date, ayanamsa, …, 'true')`
564
+ or `options.nodeType: 'true'` on the chart helpers replaces the mean-node
565
+ default with Meeus's dominant periodic correction (`-1.4979°·sin(2D-2F)`).
566
+ Typical accuracy improves from ±0.5° (worst ±2°) on the mean node to
567
+ ±0.6° on the true node.
568
+
569
+ **Documented limitations:**
570
+
571
+ - **Mangal Dosha cancellations**: only Mars in own sign (Aries/Scorpio) or
572
+ exalted (Capricorn). Other classical cancellations — mutual Mangalik,
573
+ Mars-Jupiter aspect, Mars-Saturn conjunction — are not applied.
574
+ - **Sade Sati boundary precision**: ±1-2 days. Saturn retrograde re-crossings
575
+ of a rashi boundary within a 90-day window are absorbed; longer dips are
576
+ treated as boundary events. Both first-touch and permanent-ingress
577
+ conventions are within tolerance.
578
+ - **Placidus-KP**: throws `PanchangError('CIRCUMPOLAR')` at high latitudes
579
+ where the cusp's semi-diurnal arc doesn't exist. Use `'whole-sign'` or
580
+ `'equal'` north of the Arctic Circle / south of the Antarctic Circle.
581
+ - **Navamsa (D9)**: longitude is scaled (3°20' source arc → 30° D9 arc) so
582
+ `degreeInRashi` is meaningful within the navamsa rashi. Houses are
583
+ whole-sign relative to the navamsa lagna (the classical Vedic convention).
584
+ - **Ashtakoot Vashya koot**: simplified single-vashya per rashi (half-sign
585
+ nuance — e.g. Sagittarius's centaur first half — is collapsed).
586
+ - **True node**: only the dominant Meeus Ch.47 perturbation term is applied.
587
+ Higher-order (sub-arcminute) corrections are omitted; for KP-style
588
+ sub-arcminute work, use a dedicated KP node calculator.
589
+
449
590
  ---
450
591
 
451
592
  ## Types
@@ -594,8 +735,16 @@ interface HoraInfo {
594
735
 
595
736
  ```typescript
596
737
  interface SpecialYogaInfo {
597
- name: string; // e.g. "Guru Pushya Yoga"
598
- type: 'amrit_siddhi' | 'sarvartha_siddhi' | 'ravi_pushya' | 'guru_pushya';
738
+ name: string; // e.g. "Guru Pushya Yoga", "Dwipushkar Yoga"
739
+ type:
740
+ | 'amrit_siddhi' | 'sarvartha_siddhi' | 'ravi_pushya' | 'guru_pushya'
741
+ // Vara × Tithi × Nakshatra patterns + Moon-from-Sun distance yogas
742
+ | 'dwipushkar' // Bhadra-tithi + Bhadra-vara + nakshatra ∈ {Mrigashira, Chitra, Dhanishtha} — actions doubled
743
+ | 'tripushkar' // same Bhadra-tithi/vara + nakshatra ∈ {Krittika, Punarvasu, U.Phalguni, Vishakha, U.Ashadha, P.Bhadrapada} — actions tripled
744
+ | 'jwalamukhi' // inauspicious — tithi × nakshatra lookup per Muhurta-chintamani 6.32
745
+ | 'aadal' // auspicious — Moon-from-Sun nakshatra-distance (28-scheme) ∈ {2,7,9,14,16,21,23,28}
746
+ | 'vidaal' // inauspicious — Moon-from-Sun nakshatra-distance (28-scheme) ∈ {3,6,10,13,17,20,24,27}
747
+ | 'ravi'; // auspicious — Moon-from-Sun nakshatra-distance (27-scheme) ∈ {4,6,9,10,13,20}
599
748
  }
600
749
 
601
750
  interface FestivalInfo {
@@ -753,6 +902,15 @@ interface ChandraBalamInfo {
753
902
  englishName: string; // "Shubha" | "Ashubha"
754
903
  name: string; // localized
755
904
  }
905
+
906
+ interface TarabalaInfo {
907
+ taraIndex: number; // 0..8 — position in the 9-tara cycle from janma nakshatra
908
+ englishName: string; // "Janma" | "Sampat" | "Vipat" | "Kshema" | "Pratyari"
909
+ // | "Sadhaka" | "Vadha" | "Mitra" | "Ati-Mitra"
910
+ name: string; // localized
911
+ quality: 'auspicious' | 'inauspicious';
912
+ // 'inauspicious' for Vipat (2) / Pratyari (4) / Vadha (6); rest auspicious
913
+ }
756
914
  ```
757
915
  </details>
758
916
 
@@ -788,10 +946,10 @@ InteractionManager.runAfterInteractions(() => {
788
946
 
789
947
  ## Accuracy
790
948
 
791
- 5,073 tests passing, including fixtures cross-verified against
792
- reference panchang calculations spanning 2025–2026 across Delhi, Chennai,
793
- New York, London, Sydney, Dubai, and Singapore (diaspora fixtures cover
794
- DST transitions on `America/New_York`).
949
+ 6,912 tests passing across 74 files, including fixtures cross-verified
950
+ against reference panchang calculations spanning 2025–2026 across 10
951
+ Indian cities, plus New York, London, Sydney, Dubai, and Singapore
952
+ (diaspora fixtures cover DST transitions on `America/New_York`).
795
953
 
796
954
  | Element | Accuracy | Validation |
797
955
  |---------|----------|------------|
@@ -802,9 +960,19 @@ DST transitions on `America/New_York`).
802
960
  | Ayanamsa | ±0.005° vs Swiss Ephemeris | Unit tests |
803
961
  | Planetary positions (Sun–Saturn) | **±0.02° vs reference sidereal** | Fixtures |
804
962
  | Planetary positions (Rahu/Ketu, mean node) | ≤0.5° typical; ±2° tolerance to absorb mean-vs-true drift | Fixtures |
963
+ | Planetary positions (Rahu/Ketu, true node — `nodeType: 'true'`) | ≤0.6° typical (Meeus periodic correction) | Fixtures |
805
964
  | Rashi / Nakshatra / Retrograde flag | Exact match vs reference | Fixtures |
806
965
  | Festival dates | 12 cross-verified festivals (2025–2026) — see caveats below | Fixtures |
807
966
  | Choghadiya / Hora / Gowri slots | Derived from sunrise/sunset — inherits ±2 min | — |
967
+ | Madhyahna midpoint, Anandadi Yoga name, Ganda Mula active flag | **Exact match across 50 reference fixtures** (10 cities × 5 dates) | Cross-verify suite |
968
+ | Pratah / Sayahna Sandhya start + end | **±2 min** across all 50 fixtures | Cross-verify suite |
969
+ | Varjyam start + end | **±2 min** on every fixture where the library emits a non-null window (≥30 of 50 emit; transition days return `null` by design) | Cross-verify suite |
970
+ | Lagna (ascendant) sidereal longitude | Cross-checked against Jagannath Hora reference charts | Birth-chart fixtures |
971
+ | D1 (Rashi) & D9 (Navamsa) house placements | Exact match vs reference for 9-graha placement | Birth-chart fixtures |
972
+ | Ashtakoot Guna Milan total score | ±1 point per pair across 30+ matched pairs | Match fixtures |
973
+ | Sade Sati arc start / end | ±1–2 days vs authoritative ephemerides | Saturn-transit fixtures |
974
+
975
+ **Detection sourcing notes.** **Aadal / Vidaal** follow the classical Moon-from-Sun nakshatra-distance rule (AstroShastra, HoraSarvam, Ernst Wilhelm), NOT the popular Tamil-Vakya weekday rule used by some online panchangs — output may therefore differ from sites that use the weekday rule. **Varjyam** emits the sunrise-anchored nakshatra's window only — printed panchangs may show a second window on nakshatra-transition days. **Do Ghati Muhurta** does not rotate by weekday: the same 30-name deity-keyed sequence applies every day, verified against multiple reference sources for distinct weekdays.
808
976
 
809
977
  ### Festival Detection — Documented Tradeoff
810
978