@gracefullight/saju 0.7.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +54 -43
- package/README.md +54 -43
- package/dist/__tests__/four-pillars.test.js +55 -37
- package/dist/__tests__/saju.test.js +19 -9
- package/dist/__tests__/solar-terms.test.js +12 -12
- package/dist/core/four-pillars.d.ts +12 -5
- package/dist/core/four-pillars.d.ts.map +1 -1
- package/dist/core/four-pillars.js +14 -11
- package/dist/core/luck.d.ts +2 -1
- package/dist/core/luck.d.ts.map +1 -1
- package/dist/core/luck.js +2 -2
- package/dist/core/solar-terms.d.ts +7 -2
- package/dist/core/solar-terms.d.ts.map +1 -1
- package/dist/core/solar-terms.js +2 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/package.json +1 -1
|
@@ -43,91 +43,92 @@ describe("Four Pillars Core", () => {
|
|
|
43
43
|
describe("yearPillar", () => {
|
|
44
44
|
it("should calculate year pillar for 1984 (甲子)", () => {
|
|
45
45
|
const dt = DateTime.fromObject({ year: 1984, month: 3, day: 1 }, { zone: "Asia/Seoul" });
|
|
46
|
-
const result = yearPillar(
|
|
46
|
+
const result = yearPillar(dt, { adapter });
|
|
47
47
|
expect(result.pillar).toBe("甲子");
|
|
48
48
|
expect(result.solarYear).toBe(1984);
|
|
49
49
|
});
|
|
50
50
|
it("should calculate year pillar for 1985 (乙丑)", () => {
|
|
51
51
|
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15 }, { zone: "Asia/Seoul" });
|
|
52
|
-
const result = yearPillar(
|
|
52
|
+
const result = yearPillar(dt, { adapter });
|
|
53
53
|
expect(result.pillar).toBe("乙丑");
|
|
54
54
|
expect(result.solarYear).toBe(1985);
|
|
55
55
|
});
|
|
56
56
|
it("should handle date before Lichun (立春)", () => {
|
|
57
57
|
const dt = DateTime.fromObject({ year: 1985, month: 1, day: 15 }, { zone: "Asia/Seoul" });
|
|
58
|
-
const result = yearPillar(
|
|
58
|
+
const result = yearPillar(dt, { adapter });
|
|
59
59
|
expect(result.solarYear).toBe(1984);
|
|
60
60
|
});
|
|
61
61
|
it("should handle date after Lichun", () => {
|
|
62
62
|
const dt = DateTime.fromObject({ year: 1985, month: 3, day: 1 }, { zone: "Asia/Seoul" });
|
|
63
|
-
const result = yearPillar(
|
|
63
|
+
const result = yearPillar(dt, { adapter });
|
|
64
64
|
expect(result.solarYear).toBe(1985);
|
|
65
65
|
});
|
|
66
66
|
it("should follow 60-year cycle", () => {
|
|
67
67
|
const dt1 = DateTime.fromObject({ year: 1984, month: 3, day: 1 }, { zone: "Asia/Seoul" });
|
|
68
68
|
const dt2 = DateTime.fromObject({ year: 2044, month: 3, day: 1 }, { zone: "Asia/Seoul" });
|
|
69
|
-
const result1 = yearPillar(
|
|
70
|
-
const result2 = yearPillar(
|
|
69
|
+
const result1 = yearPillar(dt1, { adapter });
|
|
70
|
+
const result2 = yearPillar(dt2, { adapter });
|
|
71
71
|
expect(result1.pillar).toBe(result2.pillar);
|
|
72
72
|
});
|
|
73
73
|
});
|
|
74
74
|
describe("monthPillar", () => {
|
|
75
75
|
it("should calculate month pillar for test case (1985-05-15)", () => {
|
|
76
76
|
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15 }, { zone: "Asia/Seoul" });
|
|
77
|
-
const result = monthPillar(
|
|
77
|
+
const result = monthPillar(dt, { adapter });
|
|
78
78
|
expect(result.pillar).toBe("辛巳");
|
|
79
79
|
});
|
|
80
80
|
it("should return valid stem-branch combination", () => {
|
|
81
81
|
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15 }, { zone: "Asia/Seoul" });
|
|
82
|
-
const result = monthPillar(
|
|
82
|
+
const result = monthPillar(dt, { adapter });
|
|
83
83
|
expect(result.pillar).toMatch(/^[甲乙丙丁戊己庚辛壬癸][子丑寅卯辰巳午未申酉戌亥]$/);
|
|
84
84
|
});
|
|
85
85
|
it("should include sun longitude in result", () => {
|
|
86
86
|
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15 }, { zone: "Asia/Seoul" });
|
|
87
|
-
const result = monthPillar(
|
|
87
|
+
const result = monthPillar(dt, { adapter });
|
|
88
88
|
expect(result.sunLonDeg).toBeGreaterThanOrEqual(0);
|
|
89
89
|
expect(result.sunLonDeg).toBeLessThan(360);
|
|
90
90
|
});
|
|
91
91
|
it("should calculate different months correctly", () => {
|
|
92
92
|
const jan = DateTime.fromObject({ year: 1985, month: 1, day: 15 }, { zone: "Asia/Seoul" });
|
|
93
93
|
const jul = DateTime.fromObject({ year: 1985, month: 7, day: 15 }, { zone: "Asia/Seoul" });
|
|
94
|
-
const result1 = monthPillar(
|
|
95
|
-
const result2 = monthPillar(
|
|
94
|
+
const result1 = monthPillar(jan, { adapter });
|
|
95
|
+
const result2 = monthPillar(jul, { adapter });
|
|
96
96
|
expect(result1.pillar).not.toBe(result2.pillar);
|
|
97
97
|
});
|
|
98
98
|
});
|
|
99
99
|
describe("effectiveDayDate", () => {
|
|
100
100
|
it("should return same date for midnight boundary before 23:00", () => {
|
|
101
101
|
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15, hour: 22, minute: 30 }, { zone: "Asia/Seoul" });
|
|
102
|
-
const result = effectiveDayDate(
|
|
102
|
+
const result = effectiveDayDate(dt, { adapter, dayBoundary: "midnight" });
|
|
103
103
|
expect(result.year).toBe(1985);
|
|
104
104
|
expect(result.month).toBe(5);
|
|
105
105
|
expect(result.day).toBe(15);
|
|
106
106
|
});
|
|
107
107
|
it("should advance date for zi23 boundary after 23:00", () => {
|
|
108
108
|
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15, hour: 23, minute: 30 }, { zone: "Asia/Seoul" });
|
|
109
|
-
const result = effectiveDayDate(
|
|
109
|
+
const result = effectiveDayDate(dt, { adapter, dayBoundary: "zi23" });
|
|
110
110
|
expect(result.year).toBe(1985);
|
|
111
111
|
expect(result.month).toBe(5);
|
|
112
112
|
expect(result.day).toBe(16);
|
|
113
113
|
});
|
|
114
114
|
it("should not advance date for zi23 boundary before 23:00", () => {
|
|
115
115
|
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15, hour: 22, minute: 59 }, { zone: "Asia/Seoul" });
|
|
116
|
-
const result = effectiveDayDate(
|
|
116
|
+
const result = effectiveDayDate(dt, { adapter, dayBoundary: "zi23" });
|
|
117
117
|
expect(result.year).toBe(1985);
|
|
118
118
|
expect(result.month).toBe(5);
|
|
119
119
|
expect(result.day).toBe(15);
|
|
120
120
|
});
|
|
121
121
|
it("should handle month boundary with zi23", () => {
|
|
122
122
|
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 31, hour: 23, minute: 30 }, { zone: "Asia/Seoul" });
|
|
123
|
-
const result = effectiveDayDate(
|
|
123
|
+
const result = effectiveDayDate(dt, { adapter, dayBoundary: "zi23" });
|
|
124
124
|
expect(result.year).toBe(1985);
|
|
125
125
|
expect(result.month).toBe(6);
|
|
126
126
|
expect(result.day).toBe(1);
|
|
127
127
|
});
|
|
128
128
|
it("should apply mean solar time correction when enabled", () => {
|
|
129
129
|
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15, hour: 23, minute: 50 }, { zone: "Asia/Seoul" });
|
|
130
|
-
const result = effectiveDayDate(
|
|
130
|
+
const result = effectiveDayDate(dt, {
|
|
131
|
+
adapter,
|
|
131
132
|
dayBoundary: "zi23",
|
|
132
133
|
longitudeDeg: 126.9,
|
|
133
134
|
useMeanSolarTimeForBoundary: true,
|
|
@@ -138,28 +139,30 @@ describe("Four Pillars Core", () => {
|
|
|
138
139
|
describe("hourPillar", () => {
|
|
139
140
|
it("should calculate hour pillar for test case (2000-01-01 18:00)", () => {
|
|
140
141
|
const dt = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 18, minute: 0 }, { zone: "Asia/Seoul" });
|
|
141
|
-
const result = hourPillar(
|
|
142
|
+
const result = hourPillar(dt, { adapter });
|
|
142
143
|
expect(result.pillar).toBe("辛酉");
|
|
143
144
|
});
|
|
144
145
|
it("should return valid stem-branch combination", () => {
|
|
145
146
|
const dt = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 18, minute: 0 }, { zone: "Asia/Seoul" });
|
|
146
|
-
const result = hourPillar(
|
|
147
|
+
const result = hourPillar(dt, { adapter });
|
|
147
148
|
expect(result.pillar).toMatch(/^[甲乙丙丁戊己庚辛壬癸][子丑寅卯辰巳午未申酉戌亥]$/);
|
|
148
149
|
});
|
|
149
150
|
it("should calculate different hours correctly", () => {
|
|
150
151
|
const morning = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 8, minute: 0 }, { zone: "Asia/Seoul" });
|
|
151
152
|
const evening = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 20, minute: 0 }, { zone: "Asia/Seoul" });
|
|
152
|
-
const result1 = hourPillar(
|
|
153
|
-
const result2 = hourPillar(
|
|
153
|
+
const result1 = hourPillar(morning, { adapter });
|
|
154
|
+
const result2 = hourPillar(evening, { adapter });
|
|
154
155
|
expect(result1.pillar).not.toBe(result2.pillar);
|
|
155
156
|
});
|
|
156
157
|
it("should apply mean solar time correction when enabled", () => {
|
|
157
158
|
const dt = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 18, minute: 0 }, { zone: "Asia/Seoul" });
|
|
158
|
-
const withCorrection = hourPillar(
|
|
159
|
+
const withCorrection = hourPillar(dt, {
|
|
160
|
+
adapter,
|
|
159
161
|
longitudeDeg: 126.9,
|
|
160
162
|
useMeanSolarTimeForHour: true,
|
|
161
163
|
});
|
|
162
|
-
const withoutCorrection = hourPillar(
|
|
164
|
+
const withoutCorrection = hourPillar(dt, {
|
|
165
|
+
adapter,
|
|
163
166
|
longitudeDeg: 126.9,
|
|
164
167
|
useMeanSolarTimeForHour: false,
|
|
165
168
|
});
|
|
@@ -169,7 +172,8 @@ describe("Four Pillars Core", () => {
|
|
|
169
172
|
describe("getFourPillars - Preset A", () => {
|
|
170
173
|
it("should calculate four pillars with preset A", () => {
|
|
171
174
|
const dt = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 18, minute: 0 }, { zone: "Asia/Seoul" });
|
|
172
|
-
const result = getFourPillars(
|
|
175
|
+
const result = getFourPillars(dt, {
|
|
176
|
+
adapter,
|
|
173
177
|
longitudeDeg: 126.9,
|
|
174
178
|
preset: presetA,
|
|
175
179
|
});
|
|
@@ -180,7 +184,8 @@ describe("Four Pillars Core", () => {
|
|
|
180
184
|
});
|
|
181
185
|
it("should include metadata", () => {
|
|
182
186
|
const dt = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 18, minute: 0 }, { zone: "Asia/Seoul" });
|
|
183
|
-
const result = getFourPillars(
|
|
187
|
+
const result = getFourPillars(dt, {
|
|
188
|
+
adapter,
|
|
184
189
|
longitudeDeg: 126.9,
|
|
185
190
|
preset: presetA,
|
|
186
191
|
});
|
|
@@ -191,7 +196,8 @@ describe("Four Pillars Core", () => {
|
|
|
191
196
|
});
|
|
192
197
|
it("should include lunar date information", () => {
|
|
193
198
|
const dt = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 18, minute: 0 }, { zone: "Asia/Seoul" });
|
|
194
|
-
const result = getFourPillars(
|
|
199
|
+
const result = getFourPillars(dt, {
|
|
200
|
+
adapter,
|
|
195
201
|
longitudeDeg: 126.9,
|
|
196
202
|
preset: presetA,
|
|
197
203
|
});
|
|
@@ -205,7 +211,8 @@ describe("Four Pillars Core", () => {
|
|
|
205
211
|
describe("getFourPillars - Preset B", () => {
|
|
206
212
|
it("should calculate four pillars with preset B", () => {
|
|
207
213
|
const dt = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 18, minute: 0 }, { zone: "Asia/Seoul" });
|
|
208
|
-
const result = getFourPillars(
|
|
214
|
+
const result = getFourPillars(dt, {
|
|
215
|
+
adapter,
|
|
209
216
|
longitudeDeg: 126.9,
|
|
210
217
|
preset: presetB,
|
|
211
218
|
});
|
|
@@ -216,11 +223,13 @@ describe("Four Pillars Core", () => {
|
|
|
216
223
|
});
|
|
217
224
|
it("should apply solar time corrections with preset B", () => {
|
|
218
225
|
const dt = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 18, minute: 0 }, { zone: "Asia/Seoul" });
|
|
219
|
-
const resultA = getFourPillars(
|
|
226
|
+
const resultA = getFourPillars(dt, {
|
|
227
|
+
adapter,
|
|
220
228
|
longitudeDeg: 126.9,
|
|
221
229
|
preset: presetA,
|
|
222
230
|
});
|
|
223
|
-
const resultB = getFourPillars(
|
|
231
|
+
const resultB = getFourPillars(dt, {
|
|
232
|
+
adapter,
|
|
224
233
|
longitudeDeg: 126.9,
|
|
225
234
|
preset: presetB,
|
|
226
235
|
});
|
|
@@ -230,11 +239,13 @@ describe("Four Pillars Core", () => {
|
|
|
230
239
|
describe("getFourPillars - Edge cases", () => {
|
|
231
240
|
it("should handle date near 23:00 boundary", () => {
|
|
232
241
|
const dt = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 23, minute: 30 }, { zone: "Asia/Seoul" });
|
|
233
|
-
const resultA = getFourPillars(
|
|
242
|
+
const resultA = getFourPillars(dt, {
|
|
243
|
+
adapter,
|
|
234
244
|
longitudeDeg: 126.9,
|
|
235
245
|
preset: presetA,
|
|
236
246
|
});
|
|
237
|
-
const _resultB = getFourPillars(
|
|
247
|
+
const _resultB = getFourPillars(dt, {
|
|
248
|
+
adapter,
|
|
238
249
|
longitudeDeg: 126.9,
|
|
239
250
|
preset: presetB,
|
|
240
251
|
});
|
|
@@ -242,7 +253,8 @@ describe("Four Pillars Core", () => {
|
|
|
242
253
|
});
|
|
243
254
|
it("should use default longitude from timezone offset when longitudeDeg is omitted", () => {
|
|
244
255
|
const dt = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 18, minute: 0 }, { zone: "Asia/Seoul" });
|
|
245
|
-
const result = getFourPillars(
|
|
256
|
+
const result = getFourPillars(dt, {
|
|
257
|
+
adapter,
|
|
246
258
|
preset: presetA,
|
|
247
259
|
});
|
|
248
260
|
expect(result.year).toBeDefined();
|
|
@@ -252,7 +264,8 @@ describe("Four Pillars Core", () => {
|
|
|
252
264
|
});
|
|
253
265
|
it("should handle leap year dates", () => {
|
|
254
266
|
const dt = DateTime.fromObject({ year: 2000, month: 2, day: 29 }, { zone: "UTC" });
|
|
255
|
-
const result = getFourPillars(
|
|
267
|
+
const result = getFourPillars(dt, {
|
|
268
|
+
adapter,
|
|
256
269
|
longitudeDeg: 0,
|
|
257
270
|
preset: presetA,
|
|
258
271
|
});
|
|
@@ -263,7 +276,8 @@ describe("Four Pillars Core", () => {
|
|
|
263
276
|
});
|
|
264
277
|
it("should handle year boundary", () => {
|
|
265
278
|
const dt = DateTime.fromObject({ year: 1999, month: 12, day: 31, hour: 23, minute: 59 }, { zone: "UTC" });
|
|
266
|
-
const result = getFourPillars(
|
|
279
|
+
const result = getFourPillars(dt, {
|
|
280
|
+
adapter,
|
|
267
281
|
longitudeDeg: 0,
|
|
268
282
|
preset: presetA,
|
|
269
283
|
});
|
|
@@ -274,11 +288,13 @@ describe("Four Pillars Core", () => {
|
|
|
274
288
|
it("should handle different timezones", () => {
|
|
275
289
|
const seoul = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 18, minute: 0 }, { zone: "Asia/Seoul" });
|
|
276
290
|
const tokyo = DateTime.fromObject({ year: 2000, month: 1, day: 1, hour: 18, minute: 0 }, { zone: "Asia/Tokyo" });
|
|
277
|
-
const resultSeoul = getFourPillars(
|
|
291
|
+
const resultSeoul = getFourPillars(seoul, {
|
|
292
|
+
adapter,
|
|
278
293
|
longitudeDeg: 126.9,
|
|
279
294
|
preset: presetA,
|
|
280
295
|
});
|
|
281
|
-
const resultTokyo = getFourPillars(
|
|
296
|
+
const resultTokyo = getFourPillars(tokyo, {
|
|
297
|
+
adapter,
|
|
282
298
|
longitudeDeg: 139.7,
|
|
283
299
|
preset: presetA,
|
|
284
300
|
});
|
|
@@ -288,11 +304,13 @@ describe("Four Pillars Core", () => {
|
|
|
288
304
|
});
|
|
289
305
|
it("should handle different longitudes affecting hour pillar", () => {
|
|
290
306
|
const dt = DateTime.fromObject({ year: 1985, month: 5, day: 15, hour: 0, minute: 30 }, { zone: "UTC" });
|
|
291
|
-
const westLong = getFourPillars(
|
|
307
|
+
const westLong = getFourPillars(dt, {
|
|
308
|
+
adapter,
|
|
292
309
|
longitudeDeg: -120,
|
|
293
310
|
preset: presetB,
|
|
294
311
|
});
|
|
295
|
-
const eastLong = getFourPillars(
|
|
312
|
+
const eastLong = getFourPillars(dt, {
|
|
313
|
+
adapter,
|
|
296
314
|
longitudeDeg: 120,
|
|
297
315
|
preset: presetB,
|
|
298
316
|
});
|
|
@@ -6,7 +6,8 @@ describe("getSaju integration", () => {
|
|
|
6
6
|
it("returns complete saju analysis with all required fields", async () => {
|
|
7
7
|
const adapter = await createLuxonAdapter();
|
|
8
8
|
const dt = DateTime.fromObject({ year: 1990, month: 2, day: 1, hour: 12, minute: 10 }, { zone: "Asia/Seoul" });
|
|
9
|
-
const result = getSaju(
|
|
9
|
+
const result = getSaju(dt, {
|
|
10
|
+
adapter,
|
|
10
11
|
longitudeDeg: 126.9778,
|
|
11
12
|
gender: "male",
|
|
12
13
|
preset: STANDARD_PRESET,
|
|
@@ -27,7 +28,8 @@ describe("getSaju integration", () => {
|
|
|
27
28
|
it("includes solar terms with current and next term info", async () => {
|
|
28
29
|
const adapter = await createLuxonAdapter();
|
|
29
30
|
const dt = DateTime.fromObject({ year: 2024, month: 1, day: 15, hour: 12 }, { zone: "Asia/Seoul" });
|
|
30
|
-
const result = getSaju(
|
|
31
|
+
const result = getSaju(dt, {
|
|
32
|
+
adapter,
|
|
31
33
|
longitudeDeg: 126.9778,
|
|
32
34
|
gender: "female",
|
|
33
35
|
preset: STANDARD_PRESET,
|
|
@@ -42,7 +44,8 @@ describe("getSaju integration", () => {
|
|
|
42
44
|
it("includes major luck by default", async () => {
|
|
43
45
|
const adapter = await createLuxonAdapter();
|
|
44
46
|
const dt = DateTime.fromObject({ year: 1990, month: 2, day: 1, hour: 12, minute: 10 }, { zone: "Asia/Seoul" });
|
|
45
|
-
const result = getSaju(
|
|
47
|
+
const result = getSaju(dt, {
|
|
48
|
+
adapter,
|
|
46
49
|
longitudeDeg: 126.9778,
|
|
47
50
|
gender: "male",
|
|
48
51
|
preset: STANDARD_PRESET,
|
|
@@ -54,7 +57,8 @@ describe("getSaju integration", () => {
|
|
|
54
57
|
it("includes yearly luck by default with custom range", async () => {
|
|
55
58
|
const adapter = await createLuxonAdapter();
|
|
56
59
|
const dt = DateTime.fromObject({ year: 1990, month: 2, day: 1, hour: 12, minute: 10 }, { zone: "Asia/Seoul" });
|
|
57
|
-
const result = getSaju(
|
|
60
|
+
const result = getSaju(dt, {
|
|
61
|
+
adapter,
|
|
58
62
|
longitudeDeg: 126.9778,
|
|
59
63
|
gender: "female",
|
|
60
64
|
preset: STANDARD_PRESET,
|
|
@@ -68,9 +72,11 @@ describe("getSaju integration", () => {
|
|
|
68
72
|
it("uses default yearly luck range when not specified", async () => {
|
|
69
73
|
const adapter = await createLuxonAdapter();
|
|
70
74
|
const dt = DateTime.fromObject({ year: 1990, month: 2, day: 1, hour: 12, minute: 10 }, { zone: "Asia/Seoul" });
|
|
71
|
-
const result = getSaju(
|
|
75
|
+
const result = getSaju(dt, {
|
|
76
|
+
adapter,
|
|
72
77
|
longitudeDeg: 126.9778,
|
|
73
78
|
gender: "male",
|
|
79
|
+
preset: STANDARD_PRESET,
|
|
74
80
|
currentYear: 2024,
|
|
75
81
|
});
|
|
76
82
|
expect(result.yearlyLuck.length).toBe(16);
|
|
@@ -80,7 +86,8 @@ describe("getSaju integration", () => {
|
|
|
80
86
|
it("calculates known test case correctly", async () => {
|
|
81
87
|
const adapter = await createLuxonAdapter();
|
|
82
88
|
const dt = DateTime.fromObject({ year: 1990, month: 2, day: 1, hour: 12, minute: 10 }, { zone: "Asia/Seoul" });
|
|
83
|
-
const result = getSaju(
|
|
89
|
+
const result = getSaju(dt, {
|
|
90
|
+
adapter,
|
|
84
91
|
longitudeDeg: 126.9778,
|
|
85
92
|
gender: "male",
|
|
86
93
|
preset: STANDARD_PRESET,
|
|
@@ -93,7 +100,8 @@ describe("getSaju integration", () => {
|
|
|
93
100
|
it("identifies day master in ten gods analysis", async () => {
|
|
94
101
|
const adapter = await createLuxonAdapter();
|
|
95
102
|
const dt = DateTime.fromObject({ year: 1990, month: 2, day: 1, hour: 12, minute: 10 }, { zone: "Asia/Seoul" });
|
|
96
|
-
const result = getSaju(
|
|
103
|
+
const result = getSaju(dt, {
|
|
104
|
+
adapter,
|
|
97
105
|
longitudeDeg: 126.9778,
|
|
98
106
|
gender: "female",
|
|
99
107
|
preset: STANDARD_PRESET,
|
|
@@ -104,7 +112,8 @@ describe("getSaju integration", () => {
|
|
|
104
112
|
it("calculates major luck start age based on actual solar terms (not fixed 10)", async () => {
|
|
105
113
|
const adapter = await createLuxonAdapter();
|
|
106
114
|
const dt = DateTime.fromObject({ year: 1990, month: 2, day: 1, hour: 12, minute: 10 }, { zone: "Asia/Seoul" });
|
|
107
|
-
const result = getSaju(
|
|
115
|
+
const result = getSaju(dt, {
|
|
116
|
+
adapter,
|
|
108
117
|
longitudeDeg: 126.9778,
|
|
109
118
|
gender: "male",
|
|
110
119
|
preset: STANDARD_PRESET,
|
|
@@ -118,7 +127,8 @@ describe("getSaju integration", () => {
|
|
|
118
127
|
it("includes Jie (節) solar term info for major luck calculation", async () => {
|
|
119
128
|
const adapter = await createLuxonAdapter();
|
|
120
129
|
const dt = DateTime.fromObject({ year: 2024, month: 3, day: 15, hour: 12 }, { zone: "Asia/Seoul" });
|
|
121
|
-
const result = getSaju(
|
|
130
|
+
const result = getSaju(dt, {
|
|
131
|
+
adapter,
|
|
122
132
|
longitudeDeg: 126.9778,
|
|
123
133
|
gender: "female",
|
|
124
134
|
preset: STANDARD_PRESET,
|
|
@@ -35,7 +35,7 @@ describe("solar-terms", async () => {
|
|
|
35
35
|
describe("analyzeSolarTerms", () => {
|
|
36
36
|
it("should return current and next solar terms for mid-January", () => {
|
|
37
37
|
const dt = DateTime.fromObject({ year: 2024, month: 1, day: 15 }, { zone: "Asia/Seoul" });
|
|
38
|
-
const result = analyzeSolarTerms(
|
|
38
|
+
const result = analyzeSolarTerms(dt, { adapter });
|
|
39
39
|
expect(result.current.korean).toBe("소한");
|
|
40
40
|
expect(result.next.korean).toBe("대한");
|
|
41
41
|
expect(result.daysSinceCurrent).toBeGreaterThanOrEqual(0);
|
|
@@ -43,39 +43,39 @@ describe("solar-terms", async () => {
|
|
|
43
43
|
});
|
|
44
44
|
it("should return current and next solar terms for early February", () => {
|
|
45
45
|
const dt = DateTime.fromObject({ year: 2024, month: 2, day: 3 }, { zone: "Asia/Seoul" });
|
|
46
|
-
const result = analyzeSolarTerms(
|
|
46
|
+
const result = analyzeSolarTerms(dt, { adapter });
|
|
47
47
|
expect(result.current.korean).toBe("대한");
|
|
48
48
|
expect(result.next.korean).toBe("입춘");
|
|
49
49
|
});
|
|
50
50
|
it("should return current and next solar terms for summer solstice period", () => {
|
|
51
51
|
const dt = DateTime.fromObject({ year: 2024, month: 6, day: 25 }, { zone: "Asia/Seoul" });
|
|
52
|
-
const result = analyzeSolarTerms(
|
|
52
|
+
const result = analyzeSolarTerms(dt, { adapter });
|
|
53
53
|
expect(result.current.korean).toBe("하지");
|
|
54
54
|
expect(result.next.korean).toBe("소서");
|
|
55
55
|
});
|
|
56
56
|
it("should return current and next solar terms for winter solstice period", () => {
|
|
57
57
|
const dt = DateTime.fromObject({ year: 2024, month: 12, day: 25 }, { zone: "Asia/Seoul" });
|
|
58
|
-
const result = analyzeSolarTerms(
|
|
58
|
+
const result = analyzeSolarTerms(dt, { adapter });
|
|
59
59
|
expect(result.current.korean).toBe("동지");
|
|
60
60
|
expect(result.next.korean).toBe("소한");
|
|
61
61
|
});
|
|
62
62
|
it("should calculate days since current term correctly", () => {
|
|
63
63
|
const dt = DateTime.fromObject({ year: 2024, month: 3, day: 25 }, { zone: "Asia/Seoul" });
|
|
64
|
-
const result = analyzeSolarTerms(
|
|
64
|
+
const result = analyzeSolarTerms(dt, { adapter });
|
|
65
65
|
expect(result.current.korean).toBe("춘분");
|
|
66
66
|
expect(result.daysSinceCurrent).toBeGreaterThanOrEqual(0);
|
|
67
67
|
expect(result.daysSinceCurrent).toBeLessThan(16);
|
|
68
68
|
});
|
|
69
69
|
it("should calculate days until next term correctly", () => {
|
|
70
70
|
const dt = DateTime.fromObject({ year: 2024, month: 4, day: 1 }, { zone: "Asia/Seoul" });
|
|
71
|
-
const result = analyzeSolarTerms(
|
|
71
|
+
const result = analyzeSolarTerms(dt, { adapter });
|
|
72
72
|
expect(result.next.korean).toBe("청명");
|
|
73
73
|
expect(result.daysUntilNext).toBeGreaterThan(0);
|
|
74
74
|
expect(result.daysUntilNext).toBeLessThan(16);
|
|
75
75
|
});
|
|
76
76
|
it("should include date information for current and next terms", () => {
|
|
77
77
|
const dt = DateTime.fromObject({ year: 2024, month: 5, day: 10 }, { zone: "Asia/Seoul" });
|
|
78
|
-
const result = analyzeSolarTerms(
|
|
78
|
+
const result = analyzeSolarTerms(dt, { adapter });
|
|
79
79
|
expect(result.currentDate).toHaveProperty("year");
|
|
80
80
|
expect(result.currentDate).toHaveProperty("month");
|
|
81
81
|
expect(result.currentDate).toHaveProperty("day");
|
|
@@ -90,11 +90,11 @@ describe("solar-terms", async () => {
|
|
|
90
90
|
});
|
|
91
91
|
describe("getSolarTermsForYear", () => {
|
|
92
92
|
it("should return 24 terms for a year", () => {
|
|
93
|
-
const terms = getSolarTermsForYear(
|
|
93
|
+
const terms = getSolarTermsForYear(2024, { adapter, timezone: "Asia/Seoul" });
|
|
94
94
|
expect(terms).toHaveLength(24);
|
|
95
95
|
});
|
|
96
96
|
it("should have all terms in order", () => {
|
|
97
|
-
const terms = getSolarTermsForYear(
|
|
97
|
+
const terms = getSolarTermsForYear(2024, { adapter, timezone: "Asia/Seoul" });
|
|
98
98
|
const names = terms.map((t) => t.term.korean);
|
|
99
99
|
expect(names[0]).toBe("소한");
|
|
100
100
|
expect(names[2]).toBe("입춘");
|
|
@@ -104,7 +104,7 @@ describe("solar-terms", async () => {
|
|
|
104
104
|
expect(names[23]).toBe("동지");
|
|
105
105
|
});
|
|
106
106
|
it("should have dates in chronological order within months", () => {
|
|
107
|
-
const terms = getSolarTermsForYear(
|
|
107
|
+
const terms = getSolarTermsForYear(2024, { adapter, timezone: "Asia/Seoul" });
|
|
108
108
|
for (const term of terms) {
|
|
109
109
|
expect(term.date.year).toBe(2024);
|
|
110
110
|
expect(term.date.month).toBeGreaterThanOrEqual(1);
|
|
@@ -114,14 +114,14 @@ describe("solar-terms", async () => {
|
|
|
114
114
|
}
|
|
115
115
|
});
|
|
116
116
|
it("should have 입춘 around February 4", () => {
|
|
117
|
-
const terms = getSolarTermsForYear(
|
|
117
|
+
const terms = getSolarTermsForYear(2024, { adapter, timezone: "Asia/Seoul" });
|
|
118
118
|
const ipchun = terms.find((t) => t.term.korean === "입춘");
|
|
119
119
|
expect(ipchun?.date.month).toBe(2);
|
|
120
120
|
expect(ipchun?.date.day).toBeGreaterThanOrEqual(3);
|
|
121
121
|
expect(ipchun?.date.day).toBeLessThanOrEqual(5);
|
|
122
122
|
});
|
|
123
123
|
it("should have 하지 around June 21", () => {
|
|
124
|
-
const terms = getSolarTermsForYear(
|
|
124
|
+
const terms = getSolarTermsForYear(2024, { adapter, timezone: "Asia/Seoul" });
|
|
125
125
|
const haji = terms.find((t) => t.term.korean === "하지");
|
|
126
126
|
expect(haji?.date.month).toBe(6);
|
|
127
127
|
expect(haji?.date.day).toBeGreaterThanOrEqual(20);
|
|
@@ -31,16 +31,21 @@ export declare function dayPillarFromDate({ year, month, day, }: {
|
|
|
31
31
|
pillar: string;
|
|
32
32
|
};
|
|
33
33
|
export declare function applyMeanSolarTime<T>(adapter: DateAdapter<T>, dtLocal: T, longitudeDeg: number, tzOffsetHours?: number): T;
|
|
34
|
-
export declare function yearPillar<T>(
|
|
34
|
+
export declare function yearPillar<T>(dtLocal: T, { adapter }: {
|
|
35
|
+
adapter: DateAdapter<T>;
|
|
36
|
+
}): {
|
|
35
37
|
idx60: number;
|
|
36
38
|
pillar: string;
|
|
37
39
|
solarYear: number;
|
|
38
40
|
};
|
|
39
|
-
export declare function monthPillar<T>(
|
|
41
|
+
export declare function monthPillar<T>(dtLocal: T, { adapter }: {
|
|
42
|
+
adapter: DateAdapter<T>;
|
|
43
|
+
}): {
|
|
40
44
|
pillar: string;
|
|
41
45
|
sunLonDeg: number;
|
|
42
46
|
};
|
|
43
|
-
export declare function effectiveDayDate<T>(
|
|
47
|
+
export declare function effectiveDayDate<T>(dtLocal: T, { adapter, dayBoundary, longitudeDeg, tzOffsetHours, useMeanSolarTimeForBoundary, }: {
|
|
48
|
+
adapter: DateAdapter<T>;
|
|
44
49
|
dayBoundary?: "midnight" | "zi23";
|
|
45
50
|
longitudeDeg?: number;
|
|
46
51
|
tzOffsetHours?: number;
|
|
@@ -50,7 +55,8 @@ export declare function effectiveDayDate<T>(adapter: DateAdapter<T>, dtLocal: T,
|
|
|
50
55
|
month: number;
|
|
51
56
|
day: number;
|
|
52
57
|
};
|
|
53
|
-
export declare function hourPillar<T>(
|
|
58
|
+
export declare function hourPillar<T>(dtLocal: T, { adapter, longitudeDeg, tzOffsetHours, useMeanSolarTimeForHour, dayBoundary, useMeanSolarTimeForBoundary, }: {
|
|
59
|
+
adapter: DateAdapter<T>;
|
|
54
60
|
longitudeDeg?: number;
|
|
55
61
|
tzOffsetHours?: number;
|
|
56
62
|
useMeanSolarTimeForHour?: boolean;
|
|
@@ -65,7 +71,8 @@ export declare function hourPillar<T>(adapter: DateAdapter<T>, dtLocal: T, { lon
|
|
|
65
71
|
day: number;
|
|
66
72
|
};
|
|
67
73
|
};
|
|
68
|
-
export declare function getFourPillars<T>(
|
|
74
|
+
export declare function getFourPillars<T>(dtLocal: T, { adapter, longitudeDeg, tzOffsetHours, preset, }: {
|
|
75
|
+
adapter: DateAdapter<T>;
|
|
69
76
|
longitudeDeg?: number;
|
|
70
77
|
tzOffsetHours?: number;
|
|
71
78
|
preset?: typeof presetA | typeof presetB;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"four-pillars.d.ts","sourceRoot":"","sources":["../../src/core/four-pillars.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAgC,KAAK,EAAE,MAAM,SAAS,CAAC;AAExE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;AAE3B,eAAO,MAAM,eAAe;;;;CAI3B,CAAC;AAEF,eAAO,MAAM,kBAAkB;;;;CAI9B,CAAC;AAEF,eAAO,MAAM,OAAO;;;;CAAkB,CAAC;AACvC,eAAO,MAAM,OAAO;;;;CAAqB,CAAC;AAO1C,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,KAAK,EACL,GAAG,GACJ,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,GAAG;IACF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAIA;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,EACvB,OAAO,EAAE,CAAC,EACV,YAAY,EAAE,MAAM,EACpB,aAAa,SAAI,GAChB,CAAC,CAGH;AAiFD,wBAAgB,UAAU,CAAC,CAAC,EAC1B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"four-pillars.d.ts","sourceRoot":"","sources":["../../src/core/four-pillars.ts"],"names":[],"mappings":"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"}
|
|
@@ -91,7 +91,7 @@ function lichunUtc(adapter, year) {
|
|
|
91
91
|
const end = adapter.createUTC(year, 2, 7, 0, 0, 0);
|
|
92
92
|
return findTermUtc(adapter, 315.0, start, end);
|
|
93
93
|
}
|
|
94
|
-
export function yearPillar(
|
|
94
|
+
export function yearPillar(dtLocal, { adapter }) {
|
|
95
95
|
const y = adapter.getYear(dtLocal);
|
|
96
96
|
const lichunLocal = adapter.setZone(lichunUtc(adapter, y), adapter.getZoneName(dtLocal));
|
|
97
97
|
const solarYear = adapter.isGreaterThanOrEqual(dtLocal, lichunLocal) ? y : y - 1;
|
|
@@ -116,8 +116,8 @@ function firstMonthStemIndex(yearStemIdx) {
|
|
|
116
116
|
]);
|
|
117
117
|
return map.get(yearStemIdx) ?? 0;
|
|
118
118
|
}
|
|
119
|
-
export function monthPillar(
|
|
120
|
-
const { idx60: yIdx60 } = yearPillar(
|
|
119
|
+
export function monthPillar(dtLocal, { adapter }) {
|
|
120
|
+
const { idx60: yIdx60 } = yearPillar(dtLocal, { adapter });
|
|
121
121
|
const yearStemIdx = yIdx60 % 10;
|
|
122
122
|
const lon = sunApparentLongitude(adapter, adapter.toUTC(dtLocal));
|
|
123
123
|
const mBranchIdx = monthBranchIndexFromSunLon(lon);
|
|
@@ -125,7 +125,7 @@ export function monthPillar(adapter, dtLocal) {
|
|
|
125
125
|
const mStemIdx = (firstMonthStemIndex(yearStemIdx) + monthNo) % 10;
|
|
126
126
|
return { pillar: STEMS[mStemIdx] + BRANCHES[mBranchIdx], sunLonDeg: lon };
|
|
127
127
|
}
|
|
128
|
-
export function effectiveDayDate(
|
|
128
|
+
export function effectiveDayDate(dtLocal, { adapter, dayBoundary = "midnight", longitudeDeg, tzOffsetHours = 9, useMeanSolarTimeForBoundary = false, }) {
|
|
129
129
|
let dtChk = dtLocal;
|
|
130
130
|
if (useMeanSolarTimeForBoundary) {
|
|
131
131
|
if (typeof longitudeDeg !== "number")
|
|
@@ -150,14 +150,15 @@ function hourBranchIndexFromHour(h) {
|
|
|
150
150
|
// Examples: 0->0(子), 1->1(丑), 3->2(寅), 23->0(子)
|
|
151
151
|
return Math.floor((h + 1) / 2) % 12;
|
|
152
152
|
}
|
|
153
|
-
export function hourPillar(
|
|
153
|
+
export function hourPillar(dtLocal, { adapter, longitudeDeg, tzOffsetHours = 9, useMeanSolarTimeForHour = false, dayBoundary = "midnight", useMeanSolarTimeForBoundary = false, }) {
|
|
154
154
|
let dtUsed = dtLocal;
|
|
155
155
|
if (useMeanSolarTimeForHour) {
|
|
156
156
|
if (typeof longitudeDeg !== "number")
|
|
157
157
|
throw new Error("longitudeDeg required when useMeanSolarTimeForHour=true");
|
|
158
158
|
dtUsed = applyMeanSolarTime(adapter, dtLocal, longitudeDeg, tzOffsetHours);
|
|
159
159
|
}
|
|
160
|
-
const effDate = effectiveDayDate(
|
|
160
|
+
const effDate = effectiveDayDate(dtLocal, {
|
|
161
|
+
adapter,
|
|
161
162
|
dayBoundary,
|
|
162
163
|
longitudeDeg,
|
|
163
164
|
tzOffsetHours,
|
|
@@ -169,21 +170,23 @@ export function hourPillar(adapter, dtLocal, { longitudeDeg, tzOffsetHours = 9,
|
|
|
169
170
|
const hs = (dayStemIdx * 2 + hb) % 10;
|
|
170
171
|
return { pillar: STEMS[hs] + BRANCHES[hb], adjustedDt: dtUsed, effectiveDate: effDate };
|
|
171
172
|
}
|
|
172
|
-
export function getFourPillars(
|
|
173
|
+
export function getFourPillars(dtLocal, { adapter, longitudeDeg, tzOffsetHours = 9, preset = presetA, }) {
|
|
173
174
|
const effectiveLongitude = longitudeDeg ?? tzOffsetHours * 15;
|
|
174
175
|
const dayBoundary = preset.dayBoundary ?? "midnight";
|
|
175
176
|
const useMeanSolarTimeForHour = preset.useMeanSolarTimeForHour ?? false;
|
|
176
177
|
const useMeanSolarTimeForBoundary = preset.useMeanSolarTimeForBoundary ?? false;
|
|
177
|
-
const y = yearPillar(
|
|
178
|
-
const m = monthPillar(
|
|
179
|
-
const effDate = effectiveDayDate(
|
|
178
|
+
const y = yearPillar(dtLocal, { adapter });
|
|
179
|
+
const m = monthPillar(dtLocal, { adapter });
|
|
180
|
+
const effDate = effectiveDayDate(dtLocal, {
|
|
181
|
+
adapter,
|
|
180
182
|
dayBoundary,
|
|
181
183
|
longitudeDeg: effectiveLongitude,
|
|
182
184
|
tzOffsetHours,
|
|
183
185
|
useMeanSolarTimeForBoundary,
|
|
184
186
|
});
|
|
185
187
|
const d = dayPillarFromDate(effDate);
|
|
186
|
-
const h = hourPillar(
|
|
188
|
+
const h = hourPillar(dtLocal, {
|
|
189
|
+
adapter,
|
|
187
190
|
longitudeDeg: effectiveLongitude,
|
|
188
191
|
tzOffsetHours,
|
|
189
192
|
useMeanSolarTimeForHour,
|
package/dist/core/luck.d.ts
CHANGED
|
@@ -23,7 +23,8 @@ export interface MajorLuckResult {
|
|
|
23
23
|
daysToTerm: number;
|
|
24
24
|
pillars: LuckPillar[];
|
|
25
25
|
}
|
|
26
|
-
export declare function calculateMajorLuck<T>(
|
|
26
|
+
export declare function calculateMajorLuck<T>(birthDateTime: T, gender: Gender, yearPillar: string, monthPillar: string, options: {
|
|
27
|
+
adapter: DateAdapter<T>;
|
|
27
28
|
count?: number;
|
|
28
29
|
nextJieMillis?: number;
|
|
29
30
|
prevJieMillis?: number;
|
package/dist/core/luck.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"luck.d.ts","sourceRoot":"","sources":["../../src/core/luck.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGhD,YAAY,EAAE,MAAM,EAAE,CAAC;AAEvB,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,QAAQ,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,
|
|
1
|
+
{"version":3,"file":"luck.d.ts","sourceRoot":"","sources":["../../src/core/luck.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGhD,YAAY,EAAE,MAAM,EAAE,CAAC;AAEvB,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,QAAQ,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,aAAa,EAAE,CAAC,EAChB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE;IACP,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACA,eAAe,CA4DjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,gBAAgB,EAAE,CAkBpB;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAO9F;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,iBAAiB,EAAE,CA4BrB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ,eAAe,EAAE,CAqBnB;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAI7E;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAWlE"}
|
package/dist/core/luck.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getStemPolarity } from "../core/ten-gods";
|
|
2
2
|
import { BRANCHES, getPillarIndex, jdnFromDate, pillarFromIndex, STEMS } from "../utils";
|
|
3
|
-
export function calculateMajorLuck(
|
|
4
|
-
const { count = 8 } = options;
|
|
3
|
+
export function calculateMajorLuck(birthDateTime, gender, yearPillar, monthPillar, options) {
|
|
4
|
+
const { adapter, count = 8 } = options;
|
|
5
5
|
const yearStem = yearPillar[0];
|
|
6
6
|
const yearStemPolarity = getStemPolarity(yearStem);
|
|
7
7
|
const isForward = (yearStemPolarity === "yang" && gender === "male") ||
|