jyotish-calc 1.2.0 → 1.3.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.
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Vaara (Weekday) Calculations
3
+ * Simple weekday calculation from Julian Day
4
+ *
5
+ * IMPORTANT: Vedic day runs from sunrise to sunrise, not midnight to midnight.
6
+ * Use vedicVaara() for panchanga calculations.
7
+ */
8
+
9
+ const utils = require('./utils');
10
+ const { VAARA_NAMES, VAARA_NAMES_SANSKRIT, KALI_YUGA_JD } = require('./constants');
11
+
12
+ /**
13
+ * Get weekday for Julian Day (Gregorian - midnight to midnight)
14
+ * @param {number} jd - Julian Day Number
15
+ * @param {boolean} useAhargana - Use traditional Ahargana method (default: false)
16
+ * @returns {object} Weekday details
17
+ */
18
+ function vaara(jd, useAhargana = false) {
19
+ let dayIndex;
20
+
21
+ if (useAhargana) {
22
+ // Traditional method using days since Kali Yuga
23
+ const ahargana = jd - KALI_YUGA_JD;
24
+ dayIndex = ((Math.floor(ahargana) % 7) + 5) % 7;
25
+ } else {
26
+ // Standard method
27
+ dayIndex = Math.floor(jd + 1.5) % 7;
28
+ }
29
+
30
+ return {
31
+ number: dayIndex,
32
+ name: VAARA_NAMES[dayIndex],
33
+ nameSanskrit: VAARA_NAMES_SANSKRIT[dayIndex],
34
+ planetaryRuler: getPlanetaryRuler(dayIndex)
35
+ };
36
+ }
37
+
38
+ /**
39
+ * Get VEDIC weekday (sunrise to sunrise based)
40
+ * In Vedic astrology, the day begins at sunrise.
41
+ * If time is before sunrise, the previous day's vaara applies.
42
+ *
43
+ * @param {number} jd - Julian Day Number (local time)
44
+ * @param {object} place - {latitude, longitude, timezone}
45
+ * @param {object} sunriseData - Optional pre-calculated sunrise data
46
+ * @returns {object} Vedic weekday details with sunrise info
47
+ */
48
+ function vedicVaara(jd, place, sunriseData = null) {
49
+ // Get sunrise for this date
50
+ const sunriseSunset = require('./sunrise-sunset');
51
+
52
+ const { year, month, day, hour } = utils.jdToDate(jd);
53
+ const currentTime = hour;
54
+
55
+ // Calculate sunrise for today
56
+ const todaySunrise = sunriseData || sunriseSunset.sunrise(jd, place);
57
+
58
+ let effectiveJD = jd;
59
+ let isBeforeSunrise = false;
60
+
61
+ // If current time is before sunrise, use previous day's vaara
62
+ if (todaySunrise && currentTime < todaySunrise.hours) {
63
+ isBeforeSunrise = true;
64
+ effectiveJD = jd - 1; // Use previous day
65
+ }
66
+
67
+ // Get the Gregorian weekday for the effective date
68
+ const dayIndex = Math.floor(effectiveJD + 1.5) % 7;
69
+
70
+ // Get the previous day's sunrise (which is the start of this Vedic day)
71
+ let vedicDaySunrise;
72
+ if (isBeforeSunrise) {
73
+ vedicDaySunrise = sunriseSunset.sunrise(jd - 1, place);
74
+ } else {
75
+ vedicDaySunrise = todaySunrise;
76
+ }
77
+
78
+ return {
79
+ number: dayIndex,
80
+ name: VAARA_NAMES[dayIndex],
81
+ nameSanskrit: VAARA_NAMES_SANSKRIT[dayIndex],
82
+ planetaryRuler: getPlanetaryRuler(dayIndex),
83
+ isBeforeSunrise,
84
+ vedicDate: isBeforeSunrise ? {
85
+ year: utils.jdToDate(effectiveJD).year,
86
+ month: utils.jdToDate(effectiveJD).month,
87
+ day: Math.floor(utils.jdToDate(effectiveJD).day)
88
+ } : { year, month, day: Math.floor(day) },
89
+ sunrise: vedicDaySunrise
90
+ };
91
+ }
92
+
93
+ /**
94
+ * Get planetary ruler of the weekday
95
+ * @param {number} dayIndex - Weekday index (0=Sunday)
96
+ * @returns {object} {planet, index}
97
+ */
98
+ function getPlanetaryRuler(dayIndex) {
99
+ // Sun=0, Moon=1, Mars=2, Mercury=3, Jupiter=4, Venus=5, Saturn=6
100
+ const rulers = [
101
+ { name: 'Sun', index: 0 },
102
+ { name: 'Moon', index: 1 },
103
+ { name: 'Mars', index: 2 },
104
+ { name: 'Mercury', index: 3 },
105
+ { name: 'Jupiter', index: 4 },
106
+ { name: 'Venus', index: 5 },
107
+ { name: 'Saturn', index: 6 }
108
+ ];
109
+ return rulers[dayIndex];
110
+ }
111
+
112
+ /**
113
+ * Check if it's a specific weekday
114
+ * @param {number} jd - Julian Day Number
115
+ * @param {number|string} day - Day index or name
116
+ * @returns {boolean} True if matches
117
+ */
118
+ function isWeekday(jd, day) {
119
+ const v = vaara(jd);
120
+ if (typeof day === 'number') {
121
+ return v.number === day;
122
+ }
123
+ return v.name.toLowerCase() === day.toLowerCase() ||
124
+ v.nameSanskrit.toLowerCase() === day.toLowerCase();
125
+ }
126
+
127
+ /**
128
+ * Find next occurrence of a specific weekday
129
+ * @param {number} jd - Starting Julian Day
130
+ * @param {number} targetDay - Target weekday (0-6)
131
+ * @returns {number} Julian Day of next occurrence
132
+ */
133
+ function nextWeekday(jd, targetDay) {
134
+ const current = vaara(jd).number;
135
+ let daysToAdd = targetDay - current;
136
+ if (daysToAdd <= 0) daysToAdd += 7;
137
+ return jd + daysToAdd;
138
+ }
139
+
140
+ /**
141
+ * Find previous occurrence of a specific weekday
142
+ * @param {number} jd - Starting Julian Day
143
+ * @param {number} targetDay - Target weekday (0-6)
144
+ * @returns {number} Julian Day of previous occurrence
145
+ */
146
+ function previousWeekday(jd, targetDay) {
147
+ const current = vaara(jd).number;
148
+ let daysToSubtract = current - targetDay;
149
+ if (daysToSubtract <= 0) daysToSubtract += 7;
150
+ return jd - daysToSubtract;
151
+ }
152
+
153
+ /**
154
+ * Get day quality based on planetary rulership
155
+ * @param {number} dayIndex - Weekday index
156
+ * @returns {string} Quality description
157
+ */
158
+ function dayQuality(dayIndex) {
159
+ const qualities = {
160
+ 0: 'Authority, government matters, health', // Sunday
161
+ 1: 'Mind, emotions, travel, water activities', // Monday
162
+ 2: 'Courage, conflict, property matters', // Tuesday
163
+ 3: 'Communication, learning, commerce', // Wednesday
164
+ 4: 'Wisdom, spirituality, ceremonies', // Thursday
165
+ 5: 'Love, arts, luxury, entertainment', // Friday
166
+ 6: 'Discipline, labor, service, agriculture' // Saturday
167
+ };
168
+ return qualities[dayIndex];
169
+ }
170
+
171
+ module.exports = {
172
+ vaara,
173
+ vedicVaara,
174
+ getPlanetaryRuler,
175
+ isWeekday,
176
+ nextWeekday,
177
+ previousWeekday,
178
+ dayQuality,
179
+ VAARA_NAMES,
180
+ VAARA_NAMES_SANSKRIT
181
+ };
182
+
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Yogam (Sun-Moon Yoga) Calculations
3
+ * Yoga = ceil((Sun longitude + Moon longitude) / 13.333)
4
+ * 27 yogas from Vishkambha to Vaidhriti
5
+ */
6
+
7
+ const sunriseSunset = require('./sunrise-sunset');
8
+ const utils = require('./utils');
9
+ const { YOGA_NAMES, ONE_YOGA } = require('./constants');
10
+
11
+ /**
12
+ * Calculate yoga phase angle (Sun + Moon)
13
+ * @param {number} jdUTC - Julian Day (UTC)
14
+ * @returns {number} Combined angle (0-360)
15
+ */
16
+ function yogaPhase(jdUTC) {
17
+ const sunLong = sunriseSunset.solarLongitude(jdUTC);
18
+ const moonLong = sunriseSunset.lunarLongitude(jdUTC);
19
+ return utils.norm360(sunLong + moonLong);
20
+ }
21
+
22
+ /**
23
+ * Calculate yoga number from phase
24
+ * @param {number} phase - Combined Sun+Moon angle
25
+ * @returns {number} Yoga number (1-27)
26
+ */
27
+ function yogaFromPhase(phase) {
28
+ return Math.ceil(phase / ONE_YOGA) || 27;
29
+ }
30
+
31
+ /**
32
+ * Get yoga details for given date/time
33
+ * @param {number} jd - Julian Day Number (local)
34
+ * @param {object} place - {latitude, longitude, timezone}
35
+ * @returns {object} Yoga details
36
+ */
37
+ function yogam(jd, place) {
38
+ const jdUTC = utils.toUTC(jd, place.timezone);
39
+ const rise = sunriseSunset.sunrise(jd, place);
40
+
41
+ if (!rise) return null;
42
+
43
+ const riseJDUTC = utils.toUTC(rise.jd, place.timezone);
44
+
45
+ // Get yoga at sunrise
46
+ const phase = yogaPhase(riseJDUTC);
47
+ const yogaNo = yogaFromPhase(phase);
48
+ const degreesLeft = yogaNo * ONE_YOGA - phase;
49
+
50
+ // Calculate combined motion at intervals
51
+ const offsets = [0.0, 0.25, 0.5, 0.75, 1.0];
52
+ const sunDiffs = offsets.map(t => {
53
+ return utils.norm360(sunriseSunset.solarLongitude(riseJDUTC + t) - sunriseSunset.solarLongitude(riseJDUTC));
54
+ });
55
+ const moonDiffs = offsets.map(t => {
56
+ return utils.norm360(sunriseSunset.lunarLongitude(riseJDUTC + t) - sunriseSunset.lunarLongitude(riseJDUTC));
57
+ });
58
+ const totalMotion = sunDiffs.map((s, i) => utils.norm360(s + moonDiffs[i]));
59
+
60
+ // Find when yoga ends
61
+ let endTime;
62
+ try {
63
+ const jdAtStart = utils.dateToJD(
64
+ utils.jdToDate(jd).year,
65
+ utils.jdToDate(jd).month,
66
+ utils.jdToDate(jd).day
67
+ );
68
+ const approxEnd = utils.inverseLagrange(offsets, totalMotion, degreesLeft);
69
+ endTime = (rise.jd + approxEnd - jdAtStart) * 24;
70
+ } catch {
71
+ // Fallback using average combined motion (~14 degrees/day)
72
+ const avgCombinedMotion = 14.0;
73
+ endTime = rise.hours + (degreesLeft / avgCombinedMotion) * 24;
74
+ }
75
+
76
+ // Get start time from previous day
77
+ const prevYoga = _getYogaAtSunrise(jd - 1, place);
78
+ let startTime = prevYoga ? prevYoga.endTime : rise.hours;
79
+ if (startTime > 24) startTime -= 24;
80
+ if (startTime < 0) startTime = -startTime;
81
+
82
+ // Check for yoga change during day
83
+ let nextYoga = null;
84
+ if (endTime < 24) {
85
+ const nextYogaNo = (yogaNo % 27) + 1;
86
+ nextYoga = {
87
+ number: nextYogaNo,
88
+ name: YOGA_NAMES[nextYogaNo - 1],
89
+ startTime: endTime
90
+ };
91
+ }
92
+
93
+ // Determine if yoga is auspicious
94
+ const auspicious = isAuspiciousYoga(yogaNo);
95
+
96
+ const result = {
97
+ number: yogaNo,
98
+ name: YOGA_NAMES[yogaNo - 1],
99
+ startTime,
100
+ endTime,
101
+ startTimeString: utils.formatTime(startTime < 0 ? startTime + 24 : startTime),
102
+ endTimeString: utils.formatTime(endTime > 24 ? endTime - 24 : endTime) + (endTime > 24 ? ' (+1)' : ''),
103
+ degreesLeft,
104
+ auspicious,
105
+ yogaPhase: phase
106
+ };
107
+
108
+ if (nextYoga) {
109
+ result.nextYoga = nextYoga;
110
+ }
111
+
112
+ return result;
113
+ }
114
+
115
+ /**
116
+ * Internal helper to get yoga at sunrise
117
+ */
118
+ function _getYogaAtSunrise(jd, place) {
119
+ const rise = sunriseSunset.sunrise(jd, place);
120
+ if (!rise) return null;
121
+
122
+ const riseJDUTC = utils.toUTC(rise.jd, place.timezone);
123
+ const phase = yogaPhase(riseJDUTC);
124
+ const yogaNo = yogaFromPhase(phase);
125
+ const degreesLeft = yogaNo * ONE_YOGA - phase;
126
+
127
+ const offsets = [0.0, 0.25, 0.5, 0.75, 1.0];
128
+ const sunDiffs = offsets.map(t => {
129
+ return utils.norm360(sunriseSunset.solarLongitude(riseJDUTC + t) - sunriseSunset.solarLongitude(riseJDUTC));
130
+ });
131
+ const moonDiffs = offsets.map(t => {
132
+ return utils.norm360(sunriseSunset.lunarLongitude(riseJDUTC + t) - sunriseSunset.lunarLongitude(riseJDUTC));
133
+ });
134
+ const totalMotion = sunDiffs.map((s, i) => utils.norm360(s + moonDiffs[i]));
135
+
136
+ try {
137
+ const jdAtStart = utils.dateToJD(
138
+ utils.jdToDate(jd).year,
139
+ utils.jdToDate(jd).month,
140
+ utils.jdToDate(jd).day
141
+ );
142
+ const approxEnd = utils.inverseLagrange(offsets, totalMotion, degreesLeft);
143
+ const endTime = (rise.jd + approxEnd - jdAtStart) * 24;
144
+ return { yogaNo, endTime };
145
+ } catch {
146
+ return null;
147
+ }
148
+ }
149
+
150
+ /**
151
+ * Check if yoga is auspicious
152
+ * Auspicious: 2(Priti), 3(Ayushman), 4(Saubhagya), 5(Shobhana), 7(Sukarma),
153
+ * 8(Dhriti), 11(Vriddhi), 12(Dhruva), 14(Harshana), 16(Siddhi),
154
+ * 18(Variyan), 20(Shiva), 21(Siddha), 22(Sadhya), 23(Shubha),
155
+ * 24(Shukla), 25(Brahma), 26(Indra)
156
+ * @param {number} yogaNo - Yoga number (1-27)
157
+ * @returns {boolean} True if auspicious
158
+ */
159
+ function isAuspiciousYoga(yogaNo) {
160
+ const auspiciousYogas = [2, 3, 4, 5, 7, 8, 11, 12, 14, 16, 18, 20, 21, 22, 23, 24, 25, 26];
161
+ return auspiciousYogas.includes(yogaNo);
162
+ }
163
+
164
+ /**
165
+ * Check if yoga is inauspicious (Vishkambha, Atiganda, Shoola, Ganda, Vyaghata, Vajra, Vyatipata, Parigha, Vaidhriti)
166
+ * @param {number} yogaNo - Yoga number (1-27)
167
+ * @returns {boolean} True if inauspicious
168
+ */
169
+ function isInauspiciousYoga(yogaNo) {
170
+ const inauspiciousYogas = [1, 6, 9, 10, 13, 15, 17, 19, 27];
171
+ return inauspiciousYogas.includes(yogaNo);
172
+ }
173
+
174
+ /**
175
+ * Quick yoga lookup
176
+ * @param {number} jdUTC - Julian Day (UTC)
177
+ * @returns {object} {yoga, name}
178
+ */
179
+ function quickYoga(jdUTC) {
180
+ const phase = yogaPhase(jdUTC);
181
+ const yogaNo = yogaFromPhase(phase);
182
+ return {
183
+ number: yogaNo,
184
+ name: YOGA_NAMES[yogaNo - 1]
185
+ };
186
+ }
187
+
188
+ module.exports = {
189
+ yogam,
190
+ yogaPhase,
191
+ yogaFromPhase,
192
+ quickYoga,
193
+ isAuspiciousYoga,
194
+ isInauspiciousYoga,
195
+ YOGA_NAMES
196
+ };
@@ -1,140 +0,0 @@
1
- /**
2
- * Complete Package Result Export
3
- * Birth Chart: Sep 11, 1998, 4:30 AM, Chennai
4
- */
5
-
6
- const jyotish = require('./index');
7
-
8
- const birthData = {
9
- dateString: '1998-09-11',
10
- timeString: '04:30:00',
11
- lat: 13.0827,
12
- lng: 80.2707,
13
- timezone: 5.5
14
- };
15
-
16
- const planetMap = {
17
- 'Su': 'Sun', 'Mo': 'Moon', 'Ma': 'Mars', 'Me': 'Mercury',
18
- 'Ju': 'Jupiter', 'Ve': 'Venus', 'Sa': 'Saturn', 'Ra': 'Rahu', 'Ke': 'Ketu',
19
- 'La': 'Ascendant'
20
- };
21
-
22
- async function getFullResults() {
23
- const results = {};
24
-
25
- try {
26
- // 1. GRAHA POSITIONS
27
- results.positions = jyotish.grahas.getGrahasPosition(birthData);
28
-
29
- // Prepare data for other modules
30
- const moonLong = results.positions.Mo.longitude;
31
- const lagnaLong = results.positions.La.longitude;
32
- const planetLongitudes = {};
33
- const shadbalaPositions = [];
34
- const shadbalaOrder = ['Su', 'Mo', 'Ma', 'Me', 'Ju', 'Ve', 'Sa'];
35
-
36
- Object.entries(results.positions).forEach(([key, p]) => {
37
- if (planetMap[key]) planetLongitudes[planetMap[key]] = p.longitude;
38
- });
39
-
40
- shadbalaOrder.forEach(key => {
41
- const p = results.positions[key];
42
- shadbalaPositions.push([Math.floor(p.longitude / 30), p.longitude % 30]);
43
- });
44
-
45
- // Extract birth date/time components
46
- const [year, month, date] = birthData.dateString.split('-').map(Number);
47
- const [hour, min, sec] = birthData.timeString.split(':').map(Number);
48
-
49
- // 2. SPECIAL LAGNAS
50
- const lagnaBirthData = {
51
- year, month, date,
52
- hour, min, sec,
53
- lat: birthData.lat,
54
- lng: birthData.lng,
55
- timezone: birthData.timezone,
56
- ayanamsha: 1
57
- };
58
- results.specialLagnas = jyotish.lagnas.calculateAllSpecialLagnas(lagnaBirthData);
59
-
60
- // Add special lagnas to planet longitudes for varga calculation
61
- Object.entries(results.specialLagnas).forEach(([name, data]) => {
62
- planetLongitudes[name] = data.longitude;
63
- });
64
-
65
- // 3. UPAGRAHAS
66
- results.upagrahas = jyotish.upagrahas.calculateAllUpagrahas(lagnaBirthData, results.positions);
67
-
68
- // Add upagrahas to planet longitudes for varga calculation
69
- Object.entries(results.upagrahas).forEach(([name, data]) => {
70
- planetLongitudes[name] = data.longitude;
71
- });
72
-
73
- // 4. DASHAS (All Active Dashas)
74
- const birthDateObj = new Date(birthData.dateString);
75
- const checkDateObj = new Date();
76
- results.dashas = jyotish.dashas.getAllActiveDashas(
77
- birthDateObj,
78
- moonLong,
79
- lagnaLong,
80
- checkDateObj,
81
- planetLongitudes
82
- );
83
-
84
- // 5. VARGAS (Complete Portfolio for all standard divisions)
85
- // Now includes special lagnas and upagrahas
86
- results.vargas = {};
87
- const vargaList = jyotish.vargas.getSupportedVargas(); // D1, D2, ..., D60
88
- vargaList.forEach(vId => {
89
- results.vargas[vId] = jyotish.vargas.calculateVargaChart(planetLongitudes, vId);
90
- });
91
-
92
- // 6. STRENGTHS (Shadbala & Bhavabala)
93
- const localHourDecimal = hour + min / 60;
94
- const utHourDecimal = localHourDecimal - birthData.timezone;
95
- const jdUT = jyotish.strengths.julianDayNumber(
96
- [year, month, date],
97
- [Math.floor(utHourDecimal), (utHourDecimal % 1) * 60, 0]
98
- );
99
-
100
- results.strengths = {
101
- shadbala: jyotish.strengths.calculateShadbala(
102
- shadbalaPositions,
103
- Math.floor(lagnaLong / 30),
104
- jdUT,
105
- birthData.lat,
106
- birthData.lng
107
- ),
108
- bhavabala: jyotish.strengths.calculateBhavaBala(
109
- shadbalaPositions,
110
- Math.floor(lagnaLong / 30),
111
- jdUT,
112
- birthData.lat,
113
- birthData.lng
114
- )
115
- };
116
-
117
- // 7. ASHTAKAVARGA (BAV & SAV)
118
- const ashtakavargaPositions = {
119
- Sun: results.positions.Su.longitude,
120
- Moon: results.positions.Mo.longitude,
121
- Mars: results.positions.Ma.longitude,
122
- Mercury: results.positions.Me.longitude,
123
- Jupiter: results.positions.Ju.longitude,
124
- Venus: results.positions.Ve.longitude,
125
- Saturn: results.positions.Sa.longitude,
126
- Ascendant: results.positions.La.longitude
127
- };
128
- results.ashtakavarga = jyotish.ashtakavarga.calculateDetailedAshtakavarga(ashtakavargaPositions);
129
-
130
- // Write to file directly
131
- const fs = require('fs');
132
- fs.writeFileSync('results.json', JSON.stringify(results, null, 2), 'utf8');
133
- console.log('Results written to results.json');
134
-
135
- } catch (err) {
136
- console.error(JSON.stringify({ error: err.message, stack: err.stack }, null, 2));
137
- }
138
- }
139
-
140
- getFullResults();
@@ -1,162 +0,0 @@
1
- /**
2
- * Test script for Birth Chart: Sep 11, 1998, 4:30 AM, Chennai
3
- */
4
-
5
- const jyotish = require('./index');
6
-
7
- // ============================================================================
8
- // BIRTH DATA
9
- // ============================================================================
10
- const birthData = {
11
- dateString: '1998-09-11', // YYYY-MM-DD
12
- timeString: '04:30:00', // HH:MM:SS
13
- lat: 13.0827,
14
- lng: 80.2707,
15
- timezone: 5.5
16
- };
17
-
18
- console.log('================================================================');
19
- console.log(' BIRTH CHART ANALYSIS');
20
- console.log('================================================================');
21
- console.log(`Date: ${birthData.dateString}, ${birthData.timeString}`);
22
- console.log(`Location: Chennai (${birthData.lat}° N, ${birthData.lng}° E)`);
23
- console.log('----------------------------------------------------------------\n');
24
-
25
- (async () => {
26
- try {
27
- // 1. Calculate Planetary Positions
28
- console.log('Calculated Positions...');
29
- const positions = jyotish.grahas.getGrahasPosition(birthData);
30
-
31
- console.log('PLANETARY POSITIONS (D1 Rashi):');
32
- console.log('-------------------------------');
33
-
34
- const rashiNames = [
35
- 'Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo',
36
- 'Libra', 'Scorpio', 'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces'
37
- ];
38
-
39
- const planetMap = {
40
- 'Su': 'Sun', 'Mo': 'Moon', 'Ma': 'Mars', 'Me': 'Mercury',
41
- 'Ju': 'Jupiter', 'Ve': 'Venus', 'Sa': 'Saturn', 'Ra': 'Rahu', 'Ke': 'Ketu',
42
- 'La': 'Ascendant'
43
- };
44
-
45
- const shadbalaPositions = [];
46
- const planetLongitudes = {};
47
- const shadbalaOrder = ['Su', 'Mo', 'Ma', 'Me', 'Ju', 'Ve', 'Sa'];
48
-
49
- // Process Ascendant
50
- if (positions.La) {
51
- const asc = positions.La;
52
- const signIndex = Math.floor(asc.longitude / 30);
53
- const degree = asc.longitude % 30;
54
- console.log(`Ascendant : ${rashiNames[signIndex].padEnd(12)} ${degree.toFixed(2)}°`);
55
- }
56
-
57
- // Process Planets
58
- shadbalaOrder.forEach(key => {
59
- const p = positions[key];
60
- const name = planetMap[key];
61
- if (p) {
62
- const signIndex = Math.floor(p.longitude / 30);
63
- const degree = p.longitude % 30;
64
-
65
- planetLongitudes[name] = p.longitude;
66
- shadbalaPositions.push([signIndex, degree]);
67
-
68
- console.log(`${name.padEnd(10)}: ${rashiNames[signIndex].padEnd(12)} ${degree.toFixed(2)}°`);
69
- }
70
- });
71
-
72
- ['Ra', 'Ke'].forEach(key => {
73
- if (positions[key]) {
74
- const p = positions[key];
75
- const name = planetMap[key];
76
- const signIndex = Math.floor(p.longitude / 30);
77
- const degree = p.longitude % 30;
78
- planetLongitudes[name] = p.longitude;
79
- console.log(`${name.padEnd(10)}: ${rashiNames[signIndex].padEnd(12)} ${degree.toFixed(2)}°`);
80
- }
81
- });
82
-
83
- console.log('\n');
84
-
85
- // 2. Navamsha (D9)
86
- console.log('NAVAMSHA CHART (D9):');
87
- console.log('--------------------');
88
- try {
89
- const d9Chart = jyotish.vargas.calculateVargaChart(planetLongitudes, 'D9', { abbrev: false });
90
- shadbalaOrder.concat(['Ra', 'Ke']).forEach(key => {
91
- const name = planetMap[key];
92
- const val = d9Chart[name];
93
- const display = (typeof val === 'object' && val.sign) ? val.sign : val;
94
- console.log(`${name.padEnd(10)}: ${display}`);
95
- });
96
- } catch (e) {
97
- console.log('Error calculating Navamsha:', e.message);
98
- }
99
- console.log('\n');
100
-
101
- // 3. Current Dasha (Vimshottari)
102
- console.log('CURRENT VIMSHOTTARI DASHA:');
103
- console.log('--------------------------');
104
- try {
105
- const moonLong = positions.Mo.longitude;
106
- const checkDateObj = new Date();
107
- const birthDateObj = new Date(birthData.dateString);
108
-
109
- const currentDasha = jyotish.dashas.vimshottari.getDashasForDate(birthDateObj, moonLong, checkDateObj);
110
-
111
- const checkDateStr = checkDateObj.toISOString().split('T')[0];
112
- console.log(`Current Date: ${checkDateStr}`);
113
- // Use endDate instead of end
114
- console.log(`Mahadasha: ${currentDasha.mahadasha.lord} (ends ${currentDasha.mahadasha.endDate ? new Date(currentDasha.mahadasha.endDate).toLocaleDateString() : 'N/A'})`);
115
- console.log(`Antardasha: ${currentDasha.antardasha.lord} (ends ${currentDasha.antardasha.endDate ? new Date(currentDasha.antardasha.endDate).toLocaleDateString() : 'N/A'})`);
116
- console.log(`Pratyantardasha: ${currentDasha.pratyantardasha.lord} (ends ${currentDasha.pratyantardasha.endDate ? new Date(currentDasha.pratyantardasha.endDate).toLocaleDateString() : 'N/A'})`);
117
- } catch (e) {
118
- console.log('Error calculating Dasha:', e.message);
119
- }
120
-
121
- // 4. Shadbala Strength
122
- console.log('\nSHADBALA STRENGTHS:');
123
- console.log('-------------------');
124
- try {
125
- const [year, month, date] = birthData.dateString.split('-').map(Number);
126
- const [hour, min, sec] = birthData.timeString.split(':').map(Number);
127
-
128
- const localHourDecimal = hour + min / 60;
129
- const utHourDecimal = localHourDecimal - birthData.timezone;
130
-
131
- const jdUT = jyotish.strengths.julianDayNumber(
132
- [year, month, date],
133
- [Math.floor(utHourDecimal), (utHourDecimal % 1) * 60, 0]
134
- );
135
-
136
- const ascSignIndex = positions.La ? Math.floor(positions.La.longitude / 30) : 0;
137
-
138
- const strengths = jyotish.strengths.calculateShadbala(
139
- shadbalaPositions,
140
- ascSignIndex,
141
- jdUT,
142
- birthData.lat,
143
- birthData.lng
144
- );
145
-
146
- console.log('Planet | Total (Virupas) | Ratio (Status)');
147
- console.log('-----------|-----------------|---------------');
148
- shadbalaOrder.forEach((key, i) => {
149
- const name = planetMap[key];
150
- const total = strengths.total[i].toFixed(1);
151
- const ratio = strengths.strength[i].toFixed(2);
152
- const status = strengths.strength[i] >= 1.0 ? 'Strong' : 'Weak';
153
- console.log(`${name.padEnd(10)} | ${total.padStart(15)} | ${ratio} (${status})`);
154
- });
155
- } catch (e) {
156
- console.log('Error calculating Strengths:', e.message);
157
- }
158
-
159
- } catch (err) {
160
- console.error("Critical Error:", err);
161
- }
162
- })();