jyotish-calc 1.1.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 ADDED
@@ -0,0 +1,140 @@
1
+
2
+ # Jyotish Calculations
3
+
4
+ A comprehensive JavaScript library for Vedic Astrology (Jyotish) calculations and interpretations.
5
+
6
+ ## Overview
7
+
8
+ This package provides tools and utilities for performing various Vedic Astrology calculations, including planetary positions, nakshatras (lunar mansions), rashis (zodiac signs), bhavas (houses), planetary periods (dashas), divisional charts (vargas), and planetary strengths (shadbala). It leverages the Swiss Ephemeris for precise astronomical calculations.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install jyotish-calc
14
+ ```
15
+
16
+ ## Features
17
+
18
+ - **Graha Calculations**: Calculate positions and aspects of the nine planets (grahas)
19
+ - **Nakshatra Determinations**: Calculate and interpret the 27 lunar mansions
20
+ - **Rashi Calculations**: Determine zodiac sign positions and interpretations
21
+ - **Bhava Analysis**: House system calculations and interpretations
22
+ - **Dasha Systems**: Full support for 7 dasha systems (Vimshottari, Ashtottari, Yogini, etc.) with 5-level sub-periods
23
+ - **Divisional Charts (Vargas)**: Precise calculations for all 21 divisional charts (D1-D60)
24
+ - **Shadbala & Bhavabala**: Comprehensive 6-fold planetary strength and house strength calculations
25
+
26
+ ## Project Structure
27
+
28
+ ```
29
+ jyotish
30
+ ├── index.js # Main entry point
31
+ ├── package.json # Package configuration
32
+ └── src
33
+ ├── bhavas # House calculations
34
+ ├── dashas # Dasha periods (Vimshottari, Jaimini, etc.)
35
+ ├── grahas # Planetary calculations
36
+ ├── nakshatras # Lunar mansion calculations
37
+ ├── rashis # Zodiac sign calculations
38
+ ├── strengths # Shadbala and Bhavabala
39
+ ├── vargas # Divisional charts (D1-D60)
40
+ └── utils # Helper utilities
41
+ ```
42
+
43
+ ## Usage
44
+
45
+ ### Basic Planetary Positions
46
+
47
+ ```javascript
48
+ const jyotish = require('jyotish-calc');
49
+
50
+ const date = new Date('1990-01-01T12:00:00Z');
51
+ const location = {
52
+ latitude: 28.6139, // Delhi, India
53
+ longitude: 77.2090,
54
+ altitude: 0
55
+ };
56
+
57
+ // Calculate planet positions
58
+ const planetPositions = jyotish.grahas.calculatePositions(date, location);
59
+ console.log(planetPositions);
60
+ ```
61
+
62
+ ### Dasha Calculations
63
+
64
+ Calculate planetary periods for any of the 7 supported systems (Vimshottari, Ashtottari, Yogini, Kalachakra, Chara, Sthira, Narayana).
65
+
66
+ ```javascript
67
+ const { dashas } = require('jyotish-calc');
68
+
69
+ const moonLongitude = 280.5; // Capricorn 10.5 degrees
70
+ const birthDate = '1990-01-01';
71
+
72
+ // Calculate Vimshottari Dasha
73
+ const vimshottari = dashas.getDashas(moonLongitude, 'Vimshottari', birthDate);
74
+ console.log(vimshottari);
75
+
76
+ // Get dashas running on a specific date
77
+ const currentDasha = dashas.getDashasForDate(moonLongitude, 'Vimshottari', birthDate, '2025-01-01');
78
+ /* Output:
79
+ {
80
+ mahadasha: { lord: 'Jupiter', end: '2026-05-12' },
81
+ antardasha: { lord: 'Saturn', end: '2024-11-20' },
82
+ pratyantardasha: { lord: 'Mercury', end: '2025-03-25' },
83
+ ...
84
+ }
85
+ */
86
+ ```
87
+
88
+ ### Divisional Charts (Vargas)
89
+
90
+ Calculate any of the 21 standard divisional charts (D1, D2, D3, D4, D7, D9, D10, D12, D16, D20, D24, D27, D30, D40, D45, D60).
91
+
92
+ ```javascript
93
+ const { vargas } = require('jyotish-calc');
94
+
95
+ const sunLongitude = 45.5; // Taurus 15.5 degrees
96
+
97
+ // Calculate single varga (e.g. Navamsha D9)
98
+ const navamsha = vargas.calculateVarga(sunLongitude, 'D9');
99
+ console.log(navamsha.sign); // "Taurus"
100
+
101
+ // Calculate full varga chart for all planets
102
+ const planetLongitudes = { Sun: 45.5, Moon: 120.3, /* ... */ };
103
+ const navamshaChart = vargas.calculateVargaChart(planetLongitudes, 'D9');
104
+ ```
105
+
106
+ ### Shadbala & Bhavabala (Strengths)
107
+
108
+ Calculate the comprehensive six-fold strength (Shadbala) of planets and house strengths (Bhavabala).
109
+
110
+ ```javascript
111
+ const { strengths } = require('jyotish-calc');
112
+
113
+ // Planet positions: [[signIndex, degree], ...] for Sun(0) to Saturn(6)
114
+ // Sign Index: 0=Aries, 1=Taurus, ... 11=Pisces
115
+ const positions = [
116
+ [0, 15], // Sun in Aries 15°
117
+ [1, 20], // Moon in Taurus 20°
118
+ // ... Mars, Mercury, Jupiter, Venus, Saturn
119
+ ];
120
+ const ascendant = 0; // Aries
121
+ const jd = 2451545; // Julian Day Number
122
+
123
+ // Calculate complete Shadbala
124
+ const result = strengths.calculateShadbala(positions, ascendant, jd, 28.6, 77.2);
125
+
126
+ console.log(result.strength); // Array of relative strength ratios (1.0 = minimum requirement)
127
+ console.log(result.total); // Array of total virupas (points)
128
+
129
+ // Calculate House Strengths (Bhavabala)
130
+ const bhavaStrength = strengths.calculateBhavaBala(positions, ascendant, jd, 28.6, 77.2);
131
+ console.log(bhavaStrength.total);
132
+ ```
133
+
134
+ ## Dependencies
135
+
136
+ - [swisseph-v2](https://www.npmjs.com/package/swisseph-v2): v1.0.4 - Swiss Ephemeris library for astronomical calculations
137
+
138
+ ## License
139
+
140
+ ISC
package/index.js ADDED
@@ -0,0 +1,17 @@
1
+ const grahas = require('./src/grahas/index');
2
+ const nakshatras = require('./src/nakshatras/index');
3
+ const rashis = require('./src/rashis/index');
4
+ const utils = require('./src/utils/index');
5
+ const dashas = require('./src/dashas/index');
6
+ const vargas = require('./src/vargas/index');
7
+ const strengths = require('./src/strengths/index');
8
+
9
+ module.exports = {
10
+ grahas,
11
+ nakshatras,
12
+ rashis,
13
+ utils,
14
+ dashas,
15
+ vargas,
16
+ strengths
17
+ }
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "jyotish-calc",
3
+ "version": "1.1.0",
4
+ "description": "Comprehensive Vedic Astrology library with Planet Positions, Dashas, Vargas (Divisional Charts), and Shadbala (Strengths)",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "jest",
8
+ "test:unit": "jest --watch"
9
+ },
10
+ "repository": {
11
+ "type": "git"
12
+ },
13
+ "author": "",
14
+ "license": "ISC",
15
+ "dependencies": {
16
+ "swisseph-v2": "^1.0.4"
17
+ },
18
+ "devDependencies": {
19
+ "jest": "^26.0.1"
20
+ }
21
+ }
@@ -0,0 +1,5 @@
1
+ const calculateLagna = (tt, {lat, lng}, lagna_type) => {
2
+ let Houses = swisseph.swe_houses_ex(tt, swisseph.SEFLG_SIDEREAL, lat, lng, lagna_type);
3
+ console.log('Houses', Houses);
4
+ return Houses.ascendant;
5
+ }
@@ -0,0 +1,409 @@
1
+ /**
2
+ * Ashtottari Dasha - 108-year planetary dasha system
3
+ * Uses 8 planets (excludes Ketu)
4
+ * Applied under specific conditions based on Rahu placement
5
+ *
6
+ * Supports 5 levels of sub-periods:
7
+ * 1. Mahadasha (major period)
8
+ * 2. Antardasha (sub-period)
9
+ * 3. Pratyantardasha (sub-sub-period)
10
+ * 4. Sookshmadasha (subtle period)
11
+ * 5. Pranadasha (breath period)
12
+ */
13
+
14
+ const {
15
+ ASHTOTTARI_PERIODS,
16
+ ASHTOTTARI_LORDS,
17
+ ASHTOTTARI_NAKSHATRA_MAPPING,
18
+ ASHTOTTARI_TOTAL_YEARS,
19
+ NAKSHATRAS
20
+ } = require('./constants');
21
+
22
+ const {
23
+ getNakshatraDetails,
24
+ addDays,
25
+ yearsToDays,
26
+ createDashaPeriod,
27
+ validateMoonLongitude,
28
+ validateBirthDate
29
+ } = require('./utils');
30
+
31
+ /**
32
+ * Get the Ashtottari dasha lord for a given nakshatra
33
+ * Ashtottari uses a different nakshatra mapping than Vimshottari
34
+ * @param {number} nakshatraIndex - Nakshatra index (0-26)
35
+ * @returns {string} Planet name (lord of the nakshatra in Ashtottari)
36
+ */
37
+ function getDashaLordFromNakshatra(nakshatraIndex) {
38
+ const normalizedIndex = ((nakshatraIndex % 27) + 27) % 27;
39
+
40
+ // Find which lord rules this nakshatra
41
+ for (const [lord, nakshatras] of Object.entries(ASHTOTTARI_NAKSHATRA_MAPPING)) {
42
+ if (nakshatras.includes(normalizedIndex)) {
43
+ return lord;
44
+ }
45
+ }
46
+
47
+ // Fallback - calculate based on sequence
48
+ // Ashtottari nakshatras start from Ardra (5)
49
+ const offset = (normalizedIndex - 5 + 27) % 27;
50
+ const lordIndex = Math.floor(offset / 3) % 8;
51
+ return ASHTOTTARI_LORDS[lordIndex];
52
+ }
53
+
54
+ /**
55
+ * Get the index of a lord in the Ashtottari sequence
56
+ * @param {string} lord - Planet name
57
+ * @returns {number} Index (0-7)
58
+ */
59
+ function getLordIndex(lord) {
60
+ const index = ASHTOTTARI_LORDS.indexOf(lord);
61
+ if (index === -1) {
62
+ throw new Error(`Invalid Ashtottari lord: ${lord}. Valid: ${ASHTOTTARI_LORDS.join(', ')}`);
63
+ }
64
+ return index;
65
+ }
66
+
67
+ /**
68
+ * Check if Ashtottari dasha is applicable for a chart
69
+ * Traditional conditions for Ashtottari applicability:
70
+ * - Rahu in kendra/trikona from lagna lord
71
+ * - Born in Krishna Paksha (waning Moon)
72
+ * - Night birth with Moon in dark half
73
+ *
74
+ * @param {Object} chartData - Chart data with planet positions and birth details
75
+ * @returns {Object} { applicable: boolean, reason: string }
76
+ */
77
+ function isApplicable(chartData) {
78
+ // Simple check - always return true with note about manual verification
79
+ // Full implementation would check Rahu's position relative to lagna lord
80
+
81
+ if (!chartData) {
82
+ return {
83
+ applicable: true,
84
+ reason: 'No chart data provided - applicability not determined. Ashtottari can be calculated but verify conditions.'
85
+ };
86
+ }
87
+
88
+ // TODO: Implement full applicability check when chart data structure is defined
89
+ // Check: Rahu in kendra (1,4,7,10) or trikona (1,5,9) from lagna lord's sign
90
+
91
+ return {
92
+ applicable: true,
93
+ reason: 'Ashtottari applicability requires manual verification of Rahu placement and lunar phase.'
94
+ };
95
+ }
96
+
97
+ /**
98
+ * Calculate the balance of dasha at birth
99
+ * @param {number} moonLongitude - Moon's longitude in degrees (0-360)
100
+ * @returns {Object} { lord, totalYears, remainingYears, consumedYears, consumedFraction }
101
+ */
102
+ function calculateBalanceAtBirth(moonLongitude) {
103
+ moonLongitude = validateMoonLongitude(moonLongitude);
104
+
105
+ const nakshatraDetails = getNakshatraDetails(moonLongitude);
106
+ const lord = getDashaLordFromNakshatra(nakshatraDetails.nakshatraIndex);
107
+ const totalYears = ASHTOTTARI_PERIODS[lord];
108
+
109
+ const consumedFraction = nakshatraDetails.consumedFraction;
110
+ const consumedYears = totalYears * consumedFraction;
111
+ const remainingYears = totalYears - consumedYears;
112
+
113
+ return {
114
+ lord,
115
+ nakshatraIndex: nakshatraDetails.nakshatraIndex,
116
+ nakshatraName: NAKSHATRAS[nakshatraDetails.nakshatraIndex],
117
+ pada: nakshatraDetails.pada,
118
+ totalYears,
119
+ remainingYears,
120
+ consumedYears,
121
+ consumedFraction,
122
+ remainingDays: yearsToDays(remainingYears)
123
+ };
124
+ }
125
+
126
+ /**
127
+ * Calculate all 8 Mahadasha periods starting from birth
128
+ * @param {Date} birthDate - Date of birth
129
+ * @param {number} moonLongitude - Moon's longitude in degrees
130
+ * @returns {Array} Array of 8 mahadasha period objects
131
+ */
132
+ function calculateMahadashas(birthDate, moonLongitude) {
133
+ birthDate = validateBirthDate(birthDate);
134
+ moonLongitude = validateMoonLongitude(moonLongitude);
135
+
136
+ const balance = calculateBalanceAtBirth(moonLongitude);
137
+ const startingLordIndex = getLordIndex(balance.lord);
138
+
139
+ const mahadashas = [];
140
+ let currentDate = new Date(birthDate);
141
+
142
+ for (let i = 0; i < 8; i++) {
143
+ const lordIndex = (startingLordIndex + i) % 8;
144
+ const lord = ASHTOTTARI_LORDS[lordIndex];
145
+
146
+ let periodYears;
147
+ if (i === 0) {
148
+ periodYears = balance.remainingYears;
149
+ } else {
150
+ periodYears = ASHTOTTARI_PERIODS[lord];
151
+ }
152
+
153
+ const periodDays = yearsToDays(periodYears);
154
+ const endDate = addDays(currentDate, periodDays);
155
+
156
+ const mahaDasha = createDashaPeriod(lord, currentDate, endDate, 1, null);
157
+ mahaDasha.isFirstPeriod = (i === 0);
158
+ mahaDasha.fullPeriodYears = ASHTOTTARI_PERIODS[lord];
159
+ mahaDasha.dashaSystem = 'Ashtottari';
160
+
161
+ mahadashas.push(mahaDasha);
162
+ currentDate = endDate;
163
+ }
164
+
165
+ return mahadashas;
166
+ }
167
+
168
+ /**
169
+ * Calculate Antardasha (sub-periods) within a Mahadasha
170
+ * @param {Object} mahadasha - Mahadasha period object
171
+ * @returns {Array} Array of 8 antardasha period objects
172
+ */
173
+ function calculateAntardashas(mahadasha) {
174
+ const mahaLord = mahadasha.lord;
175
+ const startingLordIndex = getLordIndex(mahaLord);
176
+
177
+ const mahaDurationDays = mahadasha.durationDays;
178
+ const antardashas = [];
179
+ let currentDate = new Date(mahadasha.startDate);
180
+
181
+ for (let i = 0; i < 8; i++) {
182
+ const lordIndex = (startingLordIndex + i) % 8;
183
+ const lord = ASHTOTTARI_LORDS[lordIndex];
184
+ const lordYears = ASHTOTTARI_PERIODS[lord];
185
+
186
+ const antarDays = (mahaDurationDays * lordYears) / ASHTOTTARI_TOTAL_YEARS;
187
+ const endDate = addDays(currentDate, antarDays);
188
+
189
+ const antardasha = createDashaPeriod(lord, currentDate, endDate, 2, mahaLord);
190
+ antardasha.mahaLord = mahaLord;
191
+ antardasha.dashaSystem = 'Ashtottari';
192
+
193
+ antardashas.push(antardasha);
194
+ currentDate = endDate;
195
+ }
196
+
197
+ return antardashas;
198
+ }
199
+
200
+ /**
201
+ * Calculate Pratyantardasha within an Antardasha
202
+ * @param {Object} antardasha - Antardasha period object
203
+ * @returns {Array} Array of 8 pratyantardasha period objects
204
+ */
205
+ function calculatePratyantardashas(antardasha) {
206
+ const antarLord = antardasha.lord;
207
+ const startingLordIndex = getLordIndex(antarLord);
208
+
209
+ const antarDurationDays = antardasha.durationDays;
210
+ const pratyantardashas = [];
211
+ let currentDate = new Date(antardasha.startDate);
212
+
213
+ for (let i = 0; i < 8; i++) {
214
+ const lordIndex = (startingLordIndex + i) % 8;
215
+ const lord = ASHTOTTARI_LORDS[lordIndex];
216
+ const lordYears = ASHTOTTARI_PERIODS[lord];
217
+
218
+ const pratyantarDays = (antarDurationDays * lordYears) / ASHTOTTARI_TOTAL_YEARS;
219
+ const endDate = addDays(currentDate, pratyantarDays);
220
+
221
+ const pratyantardasha = createDashaPeriod(lord, currentDate, endDate, 3, antarLord);
222
+ pratyantardasha.mahaLord = antardasha.mahaLord;
223
+ pratyantardasha.antarLord = antarLord;
224
+ pratyantardasha.dashaSystem = 'Ashtottari';
225
+
226
+ pratyantardashas.push(pratyantardasha);
227
+ currentDate = endDate;
228
+ }
229
+
230
+ return pratyantardashas;
231
+ }
232
+
233
+ /**
234
+ * Calculate Sookshmadasha within a Pratyantardasha
235
+ * @param {Object} pratyantardasha - Pratyantardasha period object
236
+ * @returns {Array} Array of 8 sookshmadasha period objects
237
+ */
238
+ function calculateSookshmadashas(pratyantardasha) {
239
+ const pratyantarLord = pratyantardasha.lord;
240
+ const startingLordIndex = getLordIndex(pratyantarLord);
241
+
242
+ const pratyantarDurationDays = pratyantardasha.durationDays;
243
+ const sookshmadashas = [];
244
+ let currentDate = new Date(pratyantardasha.startDate);
245
+
246
+ for (let i = 0; i < 8; i++) {
247
+ const lordIndex = (startingLordIndex + i) % 8;
248
+ const lord = ASHTOTTARI_LORDS[lordIndex];
249
+ const lordYears = ASHTOTTARI_PERIODS[lord];
250
+
251
+ const sookshmaDays = (pratyantarDurationDays * lordYears) / ASHTOTTARI_TOTAL_YEARS;
252
+ const endDate = addDays(currentDate, sookshmaDays);
253
+
254
+ const sookshmadasha = createDashaPeriod(lord, currentDate, endDate, 4, pratyantarLord);
255
+ sookshmadasha.mahaLord = pratyantardasha.mahaLord;
256
+ sookshmadasha.antarLord = pratyantardasha.antarLord;
257
+ sookshmadasha.pratyantarLord = pratyantarLord;
258
+ sookshmadasha.dashaSystem = 'Ashtottari';
259
+
260
+ sookshmadashas.push(sookshmadasha);
261
+ currentDate = endDate;
262
+ }
263
+
264
+ return sookshmadashas;
265
+ }
266
+
267
+ /**
268
+ * Calculate Pranadasha within a Sookshmadasha
269
+ * @param {Object} sookshmadasha - Sookshmadasha period object
270
+ * @returns {Array} Array of 8 pranadasha period objects
271
+ */
272
+ function calculatePranadashas(sookshmadasha) {
273
+ const sookshmaLord = sookshmadasha.lord;
274
+ const startingLordIndex = getLordIndex(sookshmaLord);
275
+
276
+ const sookshmaDurationDays = sookshmadasha.durationDays;
277
+ const pranadashas = [];
278
+ let currentDate = new Date(sookshmadasha.startDate);
279
+
280
+ for (let i = 0; i < 8; i++) {
281
+ const lordIndex = (startingLordIndex + i) % 8;
282
+ const lord = ASHTOTTARI_LORDS[lordIndex];
283
+ const lordYears = ASHTOTTARI_PERIODS[lord];
284
+
285
+ const pranaDays = (sookshmaDurationDays * lordYears) / ASHTOTTARI_TOTAL_YEARS;
286
+ const endDate = addDays(currentDate, pranaDays);
287
+
288
+ const pranadasha = createDashaPeriod(lord, currentDate, endDate, 5, sookshmaLord);
289
+ pranadasha.mahaLord = sookshmadasha.mahaLord;
290
+ pranadasha.antarLord = sookshmadasha.antarLord;
291
+ pranadasha.pratyantarLord = sookshmadasha.pratyantarLord;
292
+ pranadasha.sookshmaLord = sookshmaLord;
293
+ pranadasha.dashaSystem = 'Ashtottari';
294
+
295
+ pranadashas.push(pranadasha);
296
+ currentDate = endDate;
297
+ }
298
+
299
+ return pranadashas;
300
+ }
301
+
302
+ /**
303
+ * Get all active dasha periods for a specific date
304
+ * @param {Date} birthDate - Date of birth
305
+ * @param {number} moonLongitude - Moon's longitude in degrees
306
+ * @param {Date} targetDate - Date to find active periods for
307
+ * @returns {Object} Active periods at all 5 levels
308
+ */
309
+ function getDashasForDate(birthDate, moonLongitude, targetDate) {
310
+ birthDate = validateBirthDate(birthDate);
311
+ targetDate = validateBirthDate(targetDate);
312
+ moonLongitude = validateMoonLongitude(moonLongitude);
313
+
314
+ if (targetDate < birthDate) {
315
+ throw new Error('Target date cannot be before birth date');
316
+ }
317
+
318
+ const mahadashas = calculateMahadashas(birthDate, moonLongitude);
319
+ const activeMaha = mahadashas.find(m =>
320
+ targetDate >= m.startDate && targetDate < m.endDate
321
+ );
322
+
323
+ if (!activeMaha) return null;
324
+
325
+ const antardashas = calculateAntardashas(activeMaha);
326
+ const activeAntar = antardashas.find(a =>
327
+ targetDate >= a.startDate && targetDate < a.endDate
328
+ );
329
+
330
+ if (!activeAntar) return { mahadasha: activeMaha };
331
+
332
+ const pratyantardashas = calculatePratyantardashas(activeAntar);
333
+ const activePratyantar = pratyantardashas.find(p =>
334
+ targetDate >= p.startDate && targetDate < p.endDate
335
+ );
336
+
337
+ if (!activePratyantar) return { mahadasha: activeMaha, antardasha: activeAntar };
338
+
339
+ const sookshmadashas = calculateSookshmadashas(activePratyantar);
340
+ const activeSookshma = sookshmadashas.find(s =>
341
+ targetDate >= s.startDate && targetDate < s.endDate
342
+ );
343
+
344
+ if (!activeSookshma) return {
345
+ mahadasha: activeMaha,
346
+ antardasha: activeAntar,
347
+ pratyantardasha: activePratyantar
348
+ };
349
+
350
+ const pranadashas = calculatePranadashas(activeSookshma);
351
+ const activePrana = pranadashas.find(pr =>
352
+ targetDate >= pr.startDate && targetDate < pr.endDate
353
+ );
354
+
355
+ return {
356
+ mahadasha: activeMaha,
357
+ antardasha: activeAntar,
358
+ pratyantardasha: activePratyantar,
359
+ sookshmadasha: activeSookshma,
360
+ pranadasha: activePrana || null
361
+ };
362
+ }
363
+
364
+ /**
365
+ * Get a compact string representation of active dashas
366
+ * @param {Date} birthDate - Date of birth
367
+ * @param {number} moonLongitude - Moon's longitude in degrees
368
+ * @param {Date} targetDate - Date to find active periods for
369
+ * @param {number} levels - Number of levels to include (1-5)
370
+ * @returns {string} e.g., "Venus-Mars-Jupiter"
371
+ */
372
+ function getDashaString(birthDate, moonLongitude, targetDate, levels = 3) {
373
+ const dashas = getDashasForDate(birthDate, moonLongitude, targetDate);
374
+
375
+ if (!dashas) return null;
376
+
377
+ const parts = [];
378
+ if (levels >= 1 && dashas.mahadasha) parts.push(dashas.mahadasha.lord);
379
+ if (levels >= 2 && dashas.antardasha) parts.push(dashas.antardasha.lord);
380
+ if (levels >= 3 && dashas.pratyantardasha) parts.push(dashas.pratyantardasha.lord);
381
+ if (levels >= 4 && dashas.sookshmadasha) parts.push(dashas.sookshmadasha.lord);
382
+ if (levels >= 5 && dashas.pranadasha) parts.push(dashas.pranadasha.lord);
383
+
384
+ return parts.join('-');
385
+ }
386
+
387
+ module.exports = {
388
+ // Core functions
389
+ getDashaLordFromNakshatra,
390
+ getLordIndex,
391
+ isApplicable,
392
+ calculateBalanceAtBirth,
393
+
394
+ // Period calculations
395
+ calculateMahadashas,
396
+ calculateAntardashas,
397
+ calculatePratyantardashas,
398
+ calculateSookshmadashas,
399
+ calculatePranadashas,
400
+
401
+ // Query functions
402
+ getDashasForDate,
403
+ getDashaString,
404
+
405
+ // Constants
406
+ ASHTOTTARI_PERIODS,
407
+ ASHTOTTARI_LORDS,
408
+ ASHTOTTARI_TOTAL_YEARS
409
+ };