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.
- package/README.md +25 -0
- package/index.js +4 -1
- package/package.json +2 -2
- package/src/panchanga/constants.js +266 -0
- package/src/panchanga/index.js +330 -0
- package/src/panchanga/karana.js +185 -0
- package/src/panchanga/lunar-calendar.js +207 -0
- package/src/panchanga/muhurtas.js +370 -0
- package/src/panchanga/nakshatra.js +180 -0
- package/src/panchanga/solar-calendar.js +301 -0
- package/src/panchanga/sunrise-sunset.js +400 -0
- package/src/panchanga/tithi.js +234 -0
- package/src/panchanga/utils.js +320 -0
- package/src/panchanga/vaara.js +182 -0
- package/src/panchanga/yogam.js +196 -0
- package/get-full-results.js +0 -140
- package/test-chennai-1998.js +0 -162
|
@@ -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
|
+
};
|
package/get-full-results.js
DELETED
|
@@ -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();
|
package/test-chennai-1998.js
DELETED
|
@@ -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
|
-
})();
|