panchang-ts 2.4.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)
@@ -208,7 +209,10 @@ Amrit Siddhi, Sarvartha Siddhi, Ravi Pushya, Guru Pushya, **Dwipushkar**, **Trip
208
209
  Solar & lunar eclipse detection with subtype (partial / total / annular / penumbral), magnitude at peak, observer-horizon visibility, and pre-eclipse **sutak** impurity window.
209
210
 
210
211
  ### Jyotish (Vedic Astrology)
211
- 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). **Tarabala** (9-tara cycle — Janma, Sampat, Vipat, Kshema, Pratyari, Sadhaka, Vadha, Mitra, Ati-Mitra — keyed off janma nakshatra; parallel to Chandra Balam).
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).
212
216
 
213
217
  ### Astronomy
214
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.
@@ -217,7 +221,7 @@ Sunrise, Sunset, Moonrise, Moonset, Chandra Rashi (Moon sign), Surya Nakshatra.
217
221
  2 languages: **English** and **Hindi** (Devanagari). All returned display strings respect the `language` option.
218
222
 
219
223
  ### Configuration
220
- 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).
221
225
 
222
226
  ---
223
227
 
@@ -404,7 +408,6 @@ import {
404
408
  computeAbhijitMuhurta, computeBrahmaMuhurta,
405
409
  computeVijayaMuhurta, computeGodhuliMuhurta,
406
410
  computeNishitaMuhurta, computeAmritKala,
407
- // Phase 28 — daily-parity muhurtas + nakshatra-keyed inauspicious windows
408
411
  computeMadhyahna, computePratahSandhya, computeSayahnaSandhya,
409
412
  computeVarjyam, computeGandaMula,
410
413
  computeAnandadiYoga, computePanchakaRahita, computeDoGhati,
@@ -479,6 +482,113 @@ console.log(tb.quality); // "inauspicious"
479
482
 
480
483
  ---
481
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
555
+ ```
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
+
590
+ ---
591
+
482
592
  ## Types
483
593
 
484
594
  <details>
@@ -628,7 +738,7 @@ interface SpecialYogaInfo {
628
738
  name: string; // e.g. "Guru Pushya Yoga", "Dwipushkar Yoga"
629
739
  type:
630
740
  | 'amrit_siddhi' | 'sarvartha_siddhi' | 'ravi_pushya' | 'guru_pushya'
631
- // Phase 28-6 — Vara × Tithi × Nakshatra patterns + Moon-from-Sun distance yogas
741
+ // Vara × Tithi × Nakshatra patterns + Moon-from-Sun distance yogas
632
742
  | 'dwipushkar' // Bhadra-tithi + Bhadra-vara + nakshatra ∈ {Mrigashira, Chitra, Dhanishtha} — actions doubled
633
743
  | 'tripushkar' // same Bhadra-tithi/vara + nakshatra ∈ {Krittika, Punarvasu, U.Phalguni, Vishakha, U.Ashadha, P.Bhadrapada} — actions tripled
634
744
  | 'jwalamukhi' // inauspicious — tithi × nakshatra lookup per Muhurta-chintamani 6.32
@@ -836,11 +946,10 @@ InteractionManager.runAfterInteractions(() => {
836
946
 
837
947
  ## Accuracy
838
948
 
839
- 6,048 tests passing across 61 files, including fixtures cross-verified
949
+ 6,912 tests passing across 74 files, including fixtures cross-verified
840
950
  against reference panchang calculations spanning 2025–2026 across 10
841
- Indian cities (Phase 28 cross-verify) plus New York, London, Sydney,
842
- Dubai, and Singapore (diaspora fixtures cover DST transitions on
843
- `America/New_York`).
951
+ Indian cities, plus New York, London, Sydney, Dubai, and Singapore
952
+ (diaspora fixtures cover DST transitions on `America/New_York`).
844
953
 
845
954
  | Element | Accuracy | Validation |
846
955
  |---------|----------|------------|
@@ -851,14 +960,19 @@ Dubai, and Singapore (diaspora fixtures cover DST transitions on
851
960
  | Ayanamsa | ±0.005° vs Swiss Ephemeris | Unit tests |
852
961
  | Planetary positions (Sun–Saturn) | **±0.02° vs reference sidereal** | Fixtures |
853
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 |
854
964
  | Rashi / Nakshatra / Retrograde flag | Exact match vs reference | Fixtures |
855
965
  | Festival dates | 12 cross-verified festivals (2025–2026) — see caveats below | Fixtures |
856
966
  | Choghadiya / Hora / Gowri slots | Derived from sunrise/sunset — inherits ±2 min | — |
857
- | Madhyahna midpoint, Anandadi Yoga name, Ganda Mula active flag | **Exact match across 50 Drik fixtures** (10 cities × 5 dates) | [phase28-cross-verify](tests/validation/phase28-cross-verify.test.ts) |
858
- | Pratah / Sayahna Sandhya start + end | **±2 min vs Drik** across all 50 fixtures | [phase28-cross-verify](tests/validation/phase28-cross-verify.test.ts) |
859
- | Varjyam start + end | **±2 min vs Drik** on every fixture where the library emits a non-null window (≥30 of 50 emit; transition days return `null` by design) | [phase28-cross-verify](tests/validation/phase28-cross-verify.test.ts) |
860
-
861
- **Phase 28 sourcing notes** (see [phase28-cross-verify.test.ts](tests/validation/phase28-cross-verify.test.ts) for per-feature findings): **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 — Drik publishes no algorithmic rule text for these and may use the weekday rule, so the library's output may differ from Drik's Aadal/Vidaal occurrence pages by design. **Varjyam** emits the sunrise-anchored nakshatra's window only (single-window contract per [src/core/varjyam.ts:31-38](src/core/varjyam.ts#L31-L38)) — 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 drikpanchang.com/muhurat/daily/do-ghati-muhurat.html for two distinct weekdays. Sourcing is cited inline in [src/core/doGhati.ts:3-21](src/core/doGhati.ts#L3-L21).
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.
862
976
 
863
977
  ### Festival Detection — Documented Tradeoff
864
978