panchang-ts 2.0.1 → 2.4.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
@@ -72,7 +72,11 @@ console.log(result.moonrise); // Date | null
72
72
 
73
73
  // Muhurta & inauspicious periods
74
74
  console.log(result.brahmaMuhurta); // { start: Date, end: Date }
75
+ console.log(result.madhyahna); // solar noon ±24 min
75
76
  console.log(result.rahuKalam); // { start: Date, end: Date }
77
+ console.log(result.anandadiYoga.name); // "Ananda" (Vara × Nakshatra cycle)
78
+ console.log(result.gandaMula.active); // false (or true with severity)
79
+ console.log(result.varjyam); // { start, end } | null
76
80
 
77
81
  // Choghadiya — 8 daytime slots
78
82
  result.choghadiya.day.forEach(slot => {
@@ -139,6 +143,37 @@ console.log(amanta.chandramasa.name); // Amanta month name
139
143
  console.log(amanta.chandramasa.system); // "amanta"
140
144
  ```
141
145
 
146
+ ### Regional Festival Filtering
147
+
148
+ The `region` option scopes regional festival variants to one Indian state.
149
+ Pan-Indian festivals (Diwali, Holi, Raksha Bandhan, the canonical
150
+ `sankranti` event, …) emit regardless.
151
+
152
+ ```typescript
153
+ // Default — every regional variant emits on Makar Sankranti day:
154
+ const all = getDailyPanchang(jan14, chennai, { timezone: 330 });
155
+ all.festivals.map(f => f.name);
156
+ // → ["Sankranti", "Makar Sankranti", "Pongal", "Uttarayan",
157
+ // "Magh Bihu", "Ayyappa Makara Jyothi"]
158
+
159
+ // Scope to Tamil Nadu — drops Bihu/Ayyappa/Uttarayan:
160
+ const tn = getDailyPanchang(jan14, chennai, { timezone: 330, region: 'tamil-nadu' });
161
+ tn.festivals.map(f => f.name);
162
+ // → ["Sankranti", "Makar Sankranti", "Pongal"]
163
+
164
+ // Lohri fires on the Hindu day BEFORE Makara transit, scoped to Punjab/
165
+ // Haryana/Himachal — no extra wiring required, just the region option:
166
+ const lohri = getDailyPanchang(jan13, amritsar, { timezone: 330, region: 'punjab' });
167
+ lohri.festivals.some(f => f.name === 'Lohri'); // true
168
+
169
+ // Pre-v2.1 region values still work but log a one-shot deprecation warning:
170
+ getDailyPanchang(date, loc, { timezone: 330, region: 'tamil' });
171
+ // console.warn: [panchang-ts] FestivalRegion 'tamil' is deprecated;
172
+ // use 'tamil-nadu'. Legacy value will be removed in v3.
173
+ ```
174
+
175
+ See [`FestivalRegion`](#types) for the full state-slug list (21 states + `'nepal'`).
176
+
142
177
  ---
143
178
 
144
179
  ## Features
@@ -150,20 +185,21 @@ Tithi, Nakshatra, Yoga, Karana, Vara — with transition times throughout the da
150
185
  Chandra Masa with Adhika (leap month) detection, both **Purnimanta** (North Indian, default) and **Amanta** (South Indian) systems, Vikram Samvat, Shaka Samvat.
151
186
 
152
187
  ### Muhurta & Auspicious Timing
153
- 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).
188
+ 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).
154
189
 
155
190
  ### Inauspicious Periods
156
- Rahu Kalam, Gulika Kalam, Yamaganda, Panchaka detection, Bhadra Kala (Vishti karana window with earth / heaven / paatal location).
191
+ 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).
157
192
 
158
193
  ### Special Yogas & Festivals
159
- Amrit Siddhi, Sarvartha Siddhi, Ravi Pushya, Guru Pushya yoga detection.
194
+ Amrit Siddhi, Sarvartha Siddhi, Ravi Pushya, Guru Pushya, **Dwipushkar**, **Tripushkar**, **Jwalamukhi**, **Aadal**, **Vidaal**, **Ravi** yoga detection.
160
195
 
161
- **60+ festivals** spanning pan-Indian, regional, and classical observances:
196
+ **80+ festivals** spanning pan-Indian, regional, and classical observances:
162
197
 
163
198
  - **Ekadashi** — 26 named variants (Putrada, Shat Tila, Nirjala, Devshayani, etc.) with **Smarta / Vaishnava split** via Dashami-viddha rule; Smarta fast emits a `deferralDate` for Dwadashi.
164
199
  - **Pradosha** — 7 weekday-qualified variants (Som Pradosh, Bhauma Pradosh, Shani Pradosh, etc.) firing on both Shukla & Krishna paksha.
165
- - **Sankranti** — transit-based solar-month boundary detection plus regional variants (**Pongal**, **Vishu**, **Baisakhi**, **Magh Bihu**, **Ayyappa Makara Jyothi**) scoped by the `region` option.
200
+ - **Sankranti** — transit-based solar-month boundary detection plus regional variants (**Pongal**, **Vishu**, **Baisakhi**, **Pohela Boishakh**, **Bohag Bihu**, **Magh Bihu**, **Kati Bihu**, **Uttarayan**, **Ayyappa Makara Jyothi**, **Raja Sankranti**, **Harela**, **Sair**, **Singh Sankranti**) scoped by the `region` option. **Lohri** fires on the Hindu day immediately preceding Makara Sankranti under Punjab/Haryana/Himachal scopes.
166
201
  - **Canonical-time classical festivals** — Ganesh Chaturthi (madhyahna), Shivaratri (nishita), Diwali, Holi, Raksha Bandhan (Bhadra-aware, suppressed when Bhadra straddles Purnima), Karva Chauth (chandrodaya), Janmashtami, Dussehra, Navaratri, Ram Navami, Hanuman Jayanti, **Akshaya Tritiya & Parashurama Jayanti** (madhyahna-vyapini, co-emitted on Vaishakha Shukla Tritiya), Makar Sankranti.
202
+ - **Regional festivals (v2.1)** — **Gudi Padwa** (Maharashtra/Goa), **Gangaur** (Rajasthan), **Karaga** (Karnataka), **Bonalu** (Telangana, recurring Sundays in Ashadha), **Varamahalakshmi** (last Friday of Shravana Shukla before Purnima, Karnataka/AP/Telangana/Tamil Nadu), **Bathukamma** (Telangana — Engili Pula + Saddula markers), **Hariyali / Kajari / Hartalika Teej**, **Govardhan Puja**, **Bhai Dooj**, **Phagli** (Himachal), **Jagannath Rath Yatra** (pan-Indian, Ashadha Shukla Dwitiya), **Raja Parba** 3-day arc (Odisha — Pahili / Sankranti / Basi) — all filtered by per-state allow-lists on the rule.
167
203
  - **Regional & seasonal** — Chhath (4-day sequence), Vat Savitri, Upakarma (3 shakha variants via nakshatra+chandraMasa), Onam (nakshatra+solarMasa).
168
204
  - **Monthly observances** — Masik Shivaratri, Vinayaka Chaturthi (suppressed in Maha-month), **Masik Karthigai** (any day Krittika nakshatra prevails — sampled at sunrise / midday / sunset / nishita), Pushya days, Shravan Somvar and other month+weekday patterns.
169
205
  - Adhika (leap) months auto-skipped for tithi-based rules; Purnimanta naming respected.
@@ -172,7 +208,7 @@ Amrit Siddhi, Sarvartha Siddhi, Ravi Pushya, Guru Pushya yoga detection.
172
208
  Solar & lunar eclipse detection with subtype (partial / total / annular / penumbral), magnitude at peak, observer-horizon visibility, and pre-eclipse **sutak** impurity window.
173
209
 
174
210
  ### Jyotish (Vedic Astrology)
175
- 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).
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).
176
212
 
177
213
  ### Astronomy
178
214
  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.
@@ -236,16 +272,27 @@ const result = getDailyPanchang(
236
272
  | `moonrise` | `Date \| null` | Moonrise; `null` if none that day |
237
273
  | `moonset` | `Date \| null` | Moonset; `null` if none that day |
238
274
  | `panchaka` | `boolean` | `true` when Moon is in last 5 nakshatras |
275
+ | `panchakaRahita` | `TimePeriod[]` | Slices of the Hindu day FREE of Panchaka; `[]` when Panchaka pervades the entire day |
276
+ | `doGhatiMuhurta` | `DoGhatiInfo` | 15 day + 15 night ~48-min deity-keyed slots covering sunrise→sunset and sunset→nextSunrise |
277
+ | `gandaMula` | `GandaMulaInfo` | Moon-in-root-nakshatra detection at sunrise; `active: false` for the 21 non-root nakshatras |
278
+ | `anandadiYoga` | `AnandadiYogaInfo` | Vara × Nakshatra 28-name cycle yoga at sunrise |
239
279
  | `specialYogas` | `SpecialYogaInfo[]` | Auspicious yogas active today |
240
280
  | `durMuhurta` | `[TimePeriod, TimePeriod]` | Two inauspicious ~48-min windows |
241
281
  | `vijayaMuhurta` | `TimePeriod` | Vijaya Muhurta — 11th day-muhurta, auspicious for success |
242
282
  | `godhuliMuhurta` | `TimePeriod` | Godhuli ("cow-dust") — sunset muhurta, auspicious for ceremonies |
243
283
  | `nishitaMuhurta` | `TimePeriod` | Nishita — midnight muhurta, used for Shivaratri and nocturnal rites |
284
+ | `madhyahna` | `TimePeriod` | Madhyahna — solar noon as a ±24-min ritual window (one classical muhurta wide) |
285
+ | `pratahSandhya` | `TimePeriod` | Dawn-twilight ritual window — three nighttime ghatikas ending *at* sunrise (asymmetric; width = `nightDuration / 10` ≈ 62–81 min) |
286
+ | `sayahnaSandhya` | `TimePeriod` | Dusk-twilight ritual window — three nighttime ghatikas starting *at* sunset (asymmetric; width = `nightDuration / 10`) |
287
+ | `dinamanaMinutes` | `number` | Classical alias of `dayDurationMinutes` (sunrise → sunset) |
288
+ | `ratrimanaMinutes` | `number` | Classical alias of `nightDurationMinutes` (sunset → next sunrise) |
244
289
  | `amritKala` | `TimePeriod \| null` | Amrit Kala — nakshatra-specific auspicious window (null when nakshatra has none) |
290
+ | `varjyam` | `TimePeriod \| null` | Varjyam (Vishaghati / Nakshatra Thyajyam) — BPHS-keyed forbidden ~96-min window; `null` when none overlaps the Hindu day |
245
291
  | `bhadra` | `BhadraInfo \| null` | Bhadra Kala (Vishti karana) window overlapping this Hindu day, or `null` |
246
292
  | `eclipse` | `EclipseInfo \| null` | Solar/lunar eclipse overlapping this Hindu day with sutak window, or `null` |
247
293
  | `festivals` | `FestivalInfo[]` | Festivals / observances today (filtered by `region` option) |
248
294
  | `chandraBalam` | `ChandraBalamInfo?` | Transit-Moon favorability — only present when `janmaRashi` option is passed |
295
+ | `tarabala` | `TarabalaInfo?` | 9-tara cycle position — only present when `janmaNakshatra` option is passed |
249
296
  | `ayanamsa` | `number` | Ayanamsa in degrees at sunrise |
250
297
  | `siderealSunAtSunrise` | `number` | Sun sidereal longitude at sunrise (degrees) |
251
298
  | `siderealMoonAtSunrise` | `number` | Moon sidereal longitude at sunrise (degrees) |
@@ -291,9 +338,12 @@ console.log(result.panchaka); // false
291
338
  | `chandraRashi` | `RashiInfo` | Moon's zodiac sign |
292
339
  | `suryaNakshatra` | `RashiInfo` | Sun's nakshatra |
293
340
  | `panchaka` | `boolean` | `true` when Moon is in last 5 nakshatras |
341
+ | `gandaMula` | `GandaMulaInfo` | Moon-in-root-nakshatra detection at the queried instant |
342
+ | `anandadiYoga` | `AnandadiYogaInfo` | Vara × Nakshatra 28-name cycle yoga at the queried instant |
294
343
  | `specialYogas` | `SpecialYogaInfo[]` | Auspicious yogas at this moment |
295
344
  | `festivals` | `FestivalInfo[]` | Festivals / observances at this moment (see caveat below) |
296
345
  | `chandraBalam` | `ChandraBalamInfo?` | Transit-Moon favorability — only present when `janmaRashi` option is passed |
346
+ | `tarabala` | `TarabalaInfo?` | 9-tara cycle position — only present when `janmaNakshatra` option is passed |
297
347
  | `ayanamsa` | `number` | Ayanamsa in degrees |
298
348
  | `siderealSun` | `number` | Sun sidereal longitude (degrees) |
299
349
  | `siderealMoon` | `number` | Moon sidereal longitude (degrees) |
@@ -332,8 +382,9 @@ Both functions share the same core astronomy, but `getDailyPanchang` operates on
332
382
  | `computeEndTimes` | `boolean` | `true` | Set `false` for ~5x faster, names-only output |
333
383
  | `precision` | `'standard' \| 'high'` | `'standard'` | Binary-search iterations (15 vs 25). High precision is rarely needed. |
334
384
  | `masaSystem` | `'purnimanta' \| 'amanta'` | `'purnimanta'` | Lunar month naming system. Purnimanta (North Indian) or Amanta (South Indian). |
335
- | `region` | `FestivalRegion` | `'all'` | Scopes regional festival variants (Pongal, Vishu, Baisakhi, Bihu, Ayyappa, etc.). See [`FestivalRegion`](#types) for supported values. The canonical pan-Indian `sankranti` event is always emitted regardless. |
385
+ | `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. |
336
386
  | `janmaRashi` | `number` | _(omitted)_ | Native's birth Moon rashi index (0 = Mesha … 11 = Meena). When provided, the result includes `chandraBalam`. |
387
+ | `janmaNakshatra` | `number` | _(omitted)_ | Native's birth Moon nakshatra index (0 = Ashwini … 26 = Revati). When provided, the result includes `tarabala`. |
337
388
 
338
389
  **`InstantPanchangOptions`** (optional for `getInstantPanchang`): same as above but without `timezone` (instant mode works in UTC).
339
390
 
@@ -353,6 +404,10 @@ import {
353
404
  computeAbhijitMuhurta, computeBrahmaMuhurta,
354
405
  computeVijayaMuhurta, computeGodhuliMuhurta,
355
406
  computeNishitaMuhurta, computeAmritKala,
407
+ // Phase 28 — daily-parity muhurtas + nakshatra-keyed inauspicious windows
408
+ computeMadhyahna, computePratahSandhya, computeSayahnaSandhya,
409
+ computeVarjyam, computeGandaMula,
410
+ computeAnandadiYoga, computePanchakaRahita, computeDoGhati,
356
411
  computeGowriPanchangam,
357
412
  // Eclipses (signature: (fromUtc, location, withinDays))
358
413
  getUpcomingSolarEclipse, getUpcomingLunarEclipse, getEclipseDuringDay,
@@ -360,6 +415,7 @@ import {
360
415
  computePlanetaryPositions,
361
416
  computeVimshottariDasha, computeVimshottariDashaFromBirth,
362
417
  computeChandraBalam,
418
+ computeTarabala,
363
419
  GRAHA_ABBR,
364
420
  } from 'panchang-ts';
365
421
 
@@ -412,6 +468,13 @@ const cb = computeChandraBalam(3 /* Karka */, 6 /* Tula */);
412
468
  console.log(cb.house); // 4
413
469
  console.log(cb.quality); // "weak"
414
470
  console.log(cb.englishName); // "Ashubha"
471
+
472
+ // Tarabala — 9-tara cycle from janma nakshatra → transit Moon nakshatra.
473
+ // Inputs are 0-indexed nakshatra (0 = Ashwini ... 26 = Revati).
474
+ const tb = computeTarabala(0 /* janma: Ashwini */, 4 /* transit: Mrigashira */);
475
+ console.log(tb.taraIndex); // 4
476
+ console.log(tb.englishName); // "Pratyari"
477
+ console.log(tb.quality); // "inauspicious"
415
478
  ```
416
479
 
417
480
  ---
@@ -562,8 +625,16 @@ interface HoraInfo {
562
625
 
563
626
  ```typescript
564
627
  interface SpecialYogaInfo {
565
- name: string; // e.g. "Guru Pushya Yoga"
566
- type: 'amrit_siddhi' | 'sarvartha_siddhi' | 'ravi_pushya' | 'guru_pushya';
628
+ name: string; // e.g. "Guru Pushya Yoga", "Dwipushkar Yoga"
629
+ type:
630
+ | 'amrit_siddhi' | 'sarvartha_siddhi' | 'ravi_pushya' | 'guru_pushya'
631
+ // Phase 28-6 — Vara × Tithi × Nakshatra patterns + Moon-from-Sun distance yogas
632
+ | 'dwipushkar' // Bhadra-tithi + Bhadra-vara + nakshatra ∈ {Mrigashira, Chitra, Dhanishtha} — actions doubled
633
+ | 'tripushkar' // same Bhadra-tithi/vara + nakshatra ∈ {Krittika, Punarvasu, U.Phalguni, Vishakha, U.Ashadha, P.Bhadrapada} — actions tripled
634
+ | 'jwalamukhi' // inauspicious — tithi × nakshatra lookup per Muhurta-chintamani 6.32
635
+ | 'aadal' // auspicious — Moon-from-Sun nakshatra-distance (28-scheme) ∈ {2,7,9,14,16,21,23,28}
636
+ | 'vidaal' // inauspicious — Moon-from-Sun nakshatra-distance (28-scheme) ∈ {3,6,10,13,17,20,24,27}
637
+ | 'ravi'; // auspicious — Moon-from-Sun nakshatra-distance (27-scheme) ∈ {4,6,9,10,13,20}
567
638
  }
568
639
 
569
640
  interface FestivalInfo {
@@ -582,17 +653,56 @@ interface FestivalInfo {
582
653
  deferralDate?: Date;
583
654
  }
584
655
 
656
+ // State-slug scheme. A caller sets `region` to limit regional variants to
657
+ // their state; pan-Indian festivals (Holi, Diwali, Sankranti itself, …)
658
+ // emit regardless.
585
659
  type FestivalRegion =
586
- | 'all' // default — emits every regional variant
587
- | 'north-india'
588
- | 'tamil'
589
- | 'kerala'
590
- | 'bengal'
591
- | 'punjab'
592
- | 'gujarat'
593
- | 'assam'
594
- | 'maharashtra';
660
+ | 'all' // default — emits every regional variant
661
+ // South
662
+ | 'tamil-nadu' | 'kerala' | 'karnataka' | 'andhra-pradesh' | 'telangana'
663
+ // East
664
+ | 'west-bengal' | 'odisha' | 'assam' | 'bihar' | 'jharkhand'
665
+ // West
666
+ | 'gujarat' | 'maharashtra' | 'goa' | 'rajasthan'
667
+ // North / Central
668
+ | 'punjab' | 'haryana' | 'himachal-pradesh' | 'uttarakhand'
669
+ | 'uttar-pradesh' | 'madhya-pradesh'
670
+ // Neighbour
671
+ | 'nepal';
672
+
673
+ // Pre-v2.1 identifiers. Accepted as input and mapped at call time; a
674
+ // one-shot console warning fires per distinct legacy value. Removal in v3.
675
+ // 'tamil' → 'tamil-nadu'
676
+ // 'bengal' → 'west-bengal'
677
+ // 'north-india' → 'all' (Makar Sankranti is pan-Indian; use state
678
+ // slugs for Lohri / Govardhan / Bhai Dooj)
679
+ type LegacyFestivalRegion = 'tamil' | 'bengal' | 'north-india';
595
680
  ```
681
+
682
+ **Region-scoped festivals** (non-exhaustive — see `src/core/festivals.ts`):
683
+
684
+ | Region | Festival names (keys) |
685
+ |---|---|
686
+ | `tamil-nadu` | pongal, puthandu, varamahalakshmi |
687
+ | `kerala` | vishu, ayyappa_makara_jyothi, onam *(solar-nakshatra)* |
688
+ | `karnataka` | karaga, varamahalakshmi |
689
+ | `andhra-pradesh` | varamahalakshmi |
690
+ | `telangana` | bonalu, varamahalakshmi, bathukamma_start, bathukamma_saddula |
691
+ | `west-bengal` | pohela_boishakh, bhai_dooj |
692
+ | `odisha` | singh_sankranti, raja_pahili, raja_sankranti, raja_basi |
693
+ | `assam` | bohag_bihu, magh_bihu, kati_bihu |
694
+ | `bihar` | singh_sankranti, hariyali_teej, govardhan_puja, bhai_dooj |
695
+ | `gujarat` | uttarayan, govardhan_puja, bhai_dooj |
696
+ | `maharashtra` | gudi_padwa, hartalika_teej, bhai_dooj |
697
+ | `goa` | gudi_padwa |
698
+ | `rajasthan` | gangaur, hariyali_teej, kajari_teej, hartalika_teej, govardhan_puja, bhai_dooj |
699
+ | `punjab` | baisakhi, lohri, govardhan_puja |
700
+ | `haryana` | baisakhi, lohri, govardhan_puja, bhai_dooj |
701
+ | `himachal-pradesh` | sair, phagli, lohri |
702
+ | `uttarakhand` | harela |
703
+ | `uttar-pradesh` | hariyali_teej, kajari_teej, hartalika_teej, govardhan_puja, bhai_dooj |
704
+ | `madhya-pradesh` | hariyali_teej, kajari_teej, hartalika_teej |
705
+ | `nepal` | singh_sankranti, bhai_dooj |
596
706
  </details>
597
707
 
598
708
  <details>
@@ -682,6 +792,15 @@ interface ChandraBalamInfo {
682
792
  englishName: string; // "Shubha" | "Ashubha"
683
793
  name: string; // localized
684
794
  }
795
+
796
+ interface TarabalaInfo {
797
+ taraIndex: number; // 0..8 — position in the 9-tara cycle from janma nakshatra
798
+ englishName: string; // "Janma" | "Sampat" | "Vipat" | "Kshema" | "Pratyari"
799
+ // | "Sadhaka" | "Vadha" | "Mitra" | "Ati-Mitra"
800
+ name: string; // localized
801
+ quality: 'auspicious' | 'inauspicious';
802
+ // 'inauspicious' for Vipat (2) / Pratyari (4) / Vadha (6); rest auspicious
803
+ }
685
804
  ```
686
805
  </details>
687
806
 
@@ -717,10 +836,11 @@ InteractionManager.runAfterInteractions(() => {
717
836
 
718
837
  ## Accuracy
719
838
 
720
- 5,073 tests passing, including fixtures cross-verified against
721
- reference panchang calculations spanning 2025–2026 across Delhi, Chennai,
722
- New York, London, Sydney, Dubai, and Singapore (diaspora fixtures cover
723
- DST transitions on `America/New_York`).
839
+ 6,048 tests passing across 61 files, including fixtures cross-verified
840
+ 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`).
724
844
 
725
845
  | Element | Accuracy | Validation |
726
846
  |---------|----------|------------|
@@ -734,6 +854,11 @@ DST transitions on `America/New_York`).
734
854
  | Rashi / Nakshatra / Retrograde flag | Exact match vs reference | Fixtures |
735
855
  | Festival dates | 12 cross-verified festivals (2025–2026) — see caveats below | Fixtures |
736
856
  | 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).
737
862
 
738
863
  ### Festival Detection — Documented Tradeoff
739
864