@gracefullight/saju 0.3.0 → 0.4.1

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.
Files changed (62) hide show
  1. package/README.en.md +6 -10
  2. package/README.md +6 -10
  3. package/dist/__tests__/date-fns-adapter.test.js +1 -1
  4. package/dist/__tests__/four-pillars.test.js +10 -9
  5. package/dist/__tests__/luck.test.js +2 -2
  6. package/dist/__tests__/lunar.test.js +1 -1
  7. package/dist/__tests__/luxon-adapter.test.js +1 -1
  8. package/dist/__tests__/relations.test.js +2 -2
  9. package/dist/__tests__/saju.test.js +3 -3
  10. package/dist/__tests__/sinsals.test.d.ts +2 -0
  11. package/dist/__tests__/sinsals.test.d.ts.map +1 -0
  12. package/dist/__tests__/sinsals.test.js +64 -0
  13. package/dist/__tests__/solar-terms.test.js +2 -2
  14. package/dist/__tests__/strength.test.js +2 -2
  15. package/dist/__tests__/ten-gods.test.js +4 -4
  16. package/dist/__tests__/twelve-stages.test.d.ts +2 -0
  17. package/dist/__tests__/twelve-stages.test.d.ts.map +1 -0
  18. package/dist/__tests__/twelve-stages.test.js +86 -0
  19. package/dist/__tests__/utils.test.d.ts +2 -0
  20. package/dist/__tests__/utils.test.d.ts.map +1 -0
  21. package/dist/__tests__/utils.test.js +130 -0
  22. package/dist/__tests__/yongshen.test.js +2 -2
  23. package/dist/adapters/date-fns.d.ts +1 -1
  24. package/dist/adapters/luxon.d.ts +1 -1
  25. package/dist/core/four-pillars.d.ts +6 -6
  26. package/dist/core/four-pillars.d.ts.map +1 -1
  27. package/dist/core/four-pillars.js +10 -26
  28. package/dist/core/luck.d.ts +22 -3
  29. package/dist/core/luck.d.ts.map +1 -1
  30. package/dist/core/luck.js +60 -19
  31. package/dist/core/relations.d.ts.map +1 -1
  32. package/dist/core/relations.js +5 -1
  33. package/dist/core/sinsals.d.ts +19 -0
  34. package/dist/core/sinsals.d.ts.map +1 -0
  35. package/dist/core/sinsals.js +339 -0
  36. package/dist/core/solar-terms.d.ts +1 -1
  37. package/dist/core/strength.d.ts.map +1 -1
  38. package/dist/core/strength.js +1 -1
  39. package/dist/core/ten-gods.d.ts +4 -7
  40. package/dist/core/ten-gods.d.ts.map +1 -1
  41. package/dist/core/ten-gods.js +2 -6
  42. package/dist/core/twelve-stages.d.ts +17 -0
  43. package/dist/core/twelve-stages.d.ts.map +1 -0
  44. package/dist/core/twelve-stages.js +77 -0
  45. package/dist/core/yongshen.d.ts.map +1 -1
  46. package/dist/core/yongshen.js +2 -2
  47. package/dist/index.d.ts +26 -19
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +23 -15
  50. package/dist/types/common.d.ts +12 -0
  51. package/dist/types/common.d.ts.map +1 -0
  52. package/dist/types/common.js +1 -0
  53. package/dist/types/index.d.ts +2 -0
  54. package/dist/types/index.d.ts.map +1 -0
  55. package/dist/types/index.js +1 -0
  56. package/dist/utils/constants.d.ts +13 -0
  57. package/dist/utils/constants.d.ts.map +1 -0
  58. package/dist/utils/constants.js +59 -0
  59. package/dist/utils/index.d.ts +2 -0
  60. package/dist/utils/index.d.ts.map +1 -0
  61. package/dist/utils/index.js +1 -0
  62. package/package.json +3 -2
@@ -1,9 +1,9 @@
1
- import { getLunarDate } from "@/core/lunar";
2
- export const STEMS = ["甲", "乙", "丙", "丁", "戊", "己", "", "辛", "壬", "癸"];
3
- export const BRANCHES = ["子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"];
1
+ import { getLunarDate } from "../core/lunar";
2
+ import { BRANCHES, jdnFromDate, pillarFromIndex, STEMS } from "../utils";
3
+ export { STEMS, BRANCHES };
4
4
  export const STANDARD_PRESET = {
5
5
  dayBoundary: "midnight",
6
- useMeanSolarTimeForHour: false,
6
+ useMeanSolarTimeForHour: true,
7
7
  useMeanSolarTimeForBoundary: false,
8
8
  };
9
9
  export const TRADITIONAL_PRESET = {
@@ -17,25 +17,10 @@ function normDeg(x) {
17
17
  x %= 360;
18
18
  return x < 0 ? x + 360 : x;
19
19
  }
20
- function pillarFrom60(idx60) {
21
- return STEMS[idx60 % 10] + BRANCHES[idx60 % 12];
22
- }
23
- function jdnFromDate(y, m, d) {
24
- const a = Math.floor((14 - m) / 12);
25
- const y2 = y + 4800 - a;
26
- const m2 = m + 12 * a - 3;
27
- return (d +
28
- Math.floor((153 * m2 + 2) / 5) +
29
- 365 * y2 +
30
- Math.floor(y2 / 4) -
31
- Math.floor(y2 / 100) +
32
- Math.floor(y2 / 400) -
33
- 32045);
34
- }
35
20
  export function dayPillarFromDate({ year, month, day, }) {
36
21
  const jdn = jdnFromDate(year, month, day);
37
22
  const idx60 = (((jdn - 11) % 60) + 60) % 60;
38
- return { idx60, pillar: pillarFrom60(idx60) };
23
+ return { idx60, pillar: pillarFromIndex(idx60) };
39
24
  }
40
25
  export function applyMeanSolarTime(adapter, dtLocal, longitudeDeg, tzOffsetHours = 9) {
41
26
  const deltaMinutes = 4 * (longitudeDeg - 15 * tzOffsetHours);
@@ -111,7 +96,7 @@ export function yearPillar(adapter, dtLocal) {
111
96
  const lichunLocal = adapter.setZone(lichunUtc(adapter, y), adapter.getZoneName(dtLocal));
112
97
  const solarYear = adapter.isGreaterThanOrEqual(dtLocal, lichunLocal) ? y : y - 1;
113
98
  const idx60 = (((solarYear - 1984) % 60) + 60) % 60;
114
- return { idx60, pillar: pillarFrom60(idx60), solarYear };
99
+ return { idx60, pillar: pillarFromIndex(idx60), solarYear };
115
100
  }
116
101
  function monthBranchIndexFromSunLon(lon) {
117
102
  return (Math.floor(((lon + 45) % 360) / 30) + 2) % 12;
@@ -184,9 +169,8 @@ export function hourPillar(adapter, dtLocal, { longitudeDeg, tzOffsetHours = 9,
184
169
  const hs = (dayStemIdx * 2 + hb) % 10;
185
170
  return { pillar: STEMS[hs] + BRANCHES[hb], adjustedDt: dtUsed, effectiveDate: effDate };
186
171
  }
187
- export function getFourPillars(adapter, dtLocal, { longitudeDeg, tzOffsetHours = 9, preset = presetA, }) {
188
- if (typeof longitudeDeg !== "number")
189
- throw new Error("longitudeDeg is required");
172
+ export function getFourPillars(adapter, dtLocal, { longitudeDeg, tzOffsetHours = 9, preset = presetA, } = {}) {
173
+ const effectiveLongitude = longitudeDeg ?? tzOffsetHours * 15;
190
174
  const dayBoundary = preset.dayBoundary ?? "midnight";
191
175
  const useMeanSolarTimeForHour = preset.useMeanSolarTimeForHour ?? false;
192
176
  const useMeanSolarTimeForBoundary = preset.useMeanSolarTimeForBoundary ?? false;
@@ -194,13 +178,13 @@ export function getFourPillars(adapter, dtLocal, { longitudeDeg, tzOffsetHours =
194
178
  const m = monthPillar(adapter, dtLocal);
195
179
  const effDate = effectiveDayDate(adapter, dtLocal, {
196
180
  dayBoundary,
197
- longitudeDeg,
181
+ longitudeDeg: effectiveLongitude,
198
182
  tzOffsetHours,
199
183
  useMeanSolarTimeForBoundary,
200
184
  });
201
185
  const d = dayPillarFromDate(effDate);
202
186
  const h = hourPillar(adapter, dtLocal, {
203
- longitudeDeg,
187
+ longitudeDeg: effectiveLongitude,
204
188
  tzOffsetHours,
205
189
  useMeanSolarTimeForHour,
206
190
  dayBoundary,
@@ -1,6 +1,6 @@
1
- import type { DateAdapter } from "@/adapters/date-adapter";
2
- import { type Polarity } from "./ten-gods";
3
- export type Gender = "male" | "female";
1
+ import type { DateAdapter } from "../adapters/date-adapter";
2
+ import type { Gender, Polarity } from "../types";
3
+ export type { Gender };
4
4
  export interface LuckPillar {
5
5
  index: number;
6
6
  startAge: number;
@@ -38,4 +38,23 @@ export interface YearlyLuckResult {
38
38
  export declare function calculateYearlyLuck(birthYear: number, fromYear: number, toYear: number): YearlyLuckResult[];
39
39
  export declare function getYearPillar(year: number): string;
40
40
  export declare function getCurrentMajorLuck(majorLuck: MajorLuckResult, age: number): LuckPillar | null;
41
+ export interface MonthlyLuckResult {
42
+ year: number;
43
+ month: number;
44
+ stem: string;
45
+ branch: string;
46
+ pillar: string;
47
+ }
48
+ export declare function calculateMonthlyLuck(year: number, fromMonth: number, toMonth: number): MonthlyLuckResult[];
49
+ export interface DailyLuckResult {
50
+ year: number;
51
+ month: number;
52
+ day: number;
53
+ stem: string;
54
+ branch: string;
55
+ pillar: string;
56
+ }
57
+ export declare function calculateDailyLuck(year: number, month: number, fromDay: number, toDay: number): DailyLuckResult[];
58
+ export declare function getDayPillar(year: number, month: number, day: number): string;
59
+ export declare function getMonthPillar(year: number, month: number): string;
41
60
  //# sourceMappingURL=luck.d.ts.map
@@ -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,EAAmB,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE5D,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEvC,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;AAqBD,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,EACvB,aAAa,EAAE,CAAC,EAChB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE;IACP,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACnB,GACL,eAAe,CA2DjB;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"}
1
+ {"version":3,"file":"luck.d.ts","sourceRoot":"","sources":["../../src/core/luck.ts"],"names":[],"mappings":"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"}
package/dist/core/luck.js CHANGED
@@ -1,21 +1,5 @@
1
- import { STEMS, BRANCHES } from "./four-pillars";
2
- import { getStemPolarity } from "./ten-gods";
3
- function getMonthPillarIndex(monthPillar) {
4
- const stem = monthPillar[0];
5
- const branch = monthPillar[1];
6
- const stemIdx = STEMS.indexOf(stem);
7
- const branchIdx = BRANCHES.indexOf(branch);
8
- for (let i = 0; i < 60; i++) {
9
- if (i % 10 === stemIdx && i % 12 === branchIdx) {
10
- return i;
11
- }
12
- }
13
- return 0;
14
- }
15
- function pillarFromIndex(idx60) {
16
- const normalized = ((idx60 % 60) + 60) % 60;
17
- return STEMS[normalized % 10] + BRANCHES[normalized % 12];
18
- }
1
+ import { getStemPolarity } from "../core/ten-gods";
2
+ import { BRANCHES, getPillarIndex, jdnFromDate, pillarFromIndex, STEMS } from "../utils";
19
3
  export function calculateMajorLuck(adapter, birthDateTime, gender, yearPillar, monthPillar, options = {}) {
20
4
  const { count = 8 } = options;
21
5
  const yearStem = yearPillar[0];
@@ -42,7 +26,7 @@ export function calculateMajorLuck(adapter, birthDateTime, gender, yearPillar, m
42
26
  const days = Math.round(((daysToTerm / 3) * 12 - totalMonths) * 30);
43
27
  const startAge = years;
44
28
  const startAgeDetail = { years, months, days: Math.abs(days) };
45
- const monthIdx60 = getMonthPillarIndex(monthPillar);
29
+ const monthIdx60 = getPillarIndex(monthPillar);
46
30
  const pillars = [];
47
31
  for (let i = 1; i <= count; i++) {
48
32
  const pillarIdx = isForward ? monthIdx60 + i : monthIdx60 - i;
@@ -94,3 +78,60 @@ export function getCurrentMajorLuck(majorLuck, age) {
94
78
  }
95
79
  return null;
96
80
  }
81
+ export function calculateMonthlyLuck(year, fromMonth, toMonth) {
82
+ const results = [];
83
+ const yearIdx60 = (((year - 1984) % 60) + 60) % 60;
84
+ const yearStem = STEMS[yearIdx60 % 10];
85
+ const yearStemIdx = STEMS.indexOf(yearStem);
86
+ const baseMonthStemIdx = (yearStemIdx * 2 + 2) % 10;
87
+ for (let month = fromMonth; month <= toMonth; month++) {
88
+ const monthOffset = month - 1;
89
+ const stemIdx = (baseMonthStemIdx + monthOffset) % 10;
90
+ const branchIdx = (monthOffset + 2) % 12;
91
+ const stem = STEMS[stemIdx];
92
+ const branch = BRANCHES[branchIdx];
93
+ const pillar = stem + branch;
94
+ results.push({
95
+ year,
96
+ month,
97
+ stem,
98
+ branch,
99
+ pillar,
100
+ });
101
+ }
102
+ return results;
103
+ }
104
+ export function calculateDailyLuck(year, month, fromDay, toDay) {
105
+ const results = [];
106
+ for (let day = fromDay; day <= toDay; day++) {
107
+ const jdn = jdnFromDate(year, month, day);
108
+ const idx60 = (((jdn + 49) % 60) + 60) % 60;
109
+ const stem = STEMS[idx60 % 10];
110
+ const branch = BRANCHES[idx60 % 12];
111
+ const pillar = stem + branch;
112
+ results.push({
113
+ year,
114
+ month,
115
+ day,
116
+ stem,
117
+ branch,
118
+ pillar,
119
+ });
120
+ }
121
+ return results;
122
+ }
123
+ export function getDayPillar(year, month, day) {
124
+ const jdn = jdnFromDate(year, month, day);
125
+ const idx60 = (((jdn + 49) % 60) + 60) % 60;
126
+ return STEMS[idx60 % 10] + BRANCHES[idx60 % 12];
127
+ }
128
+ export function getMonthPillar(year, month) {
129
+ const yearIdx60 = (((year - 1984) % 60) + 60) % 60;
130
+ const yearStem = STEMS[yearIdx60 % 10];
131
+ const yearStemIdx = STEMS.indexOf(yearStem);
132
+ const baseMonthStemIdx = (yearStemIdx * 2 + 2) % 10;
133
+ const monthOffset = month - 1;
134
+ const stemIdx = (baseMonthStemIdx + monthOffset) % 10;
135
+ const branchIdx = (monthOffset + 2) % 12;
136
+ return STEMS[stemIdx] + BRANCHES[branchIdx];
137
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"relations.d.ts","sourceRoot":"","sources":["../../src/core/relations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"relations.d.ts","sourceRoot":"","sources":["../../src/core/relations.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { getStemElement, getBranchElement } from "./ten-gods";
1
+ import { getBranchElement, getStemElement } from "./ten-gods";
2
2
  export const STEM_COMBINATIONS = [
3
3
  { stems: ["甲", "己"], resultElement: "earth" },
4
4
  { stems: ["乙", "庚"], resultElement: "metal" },
@@ -199,6 +199,7 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
199
199
  for (const combo of BRANCH_TRIPLE_COMBINATIONS) {
200
200
  const matched = combo.branches.filter((b) => branchChars.includes(b));
201
201
  if (matched.length >= 2) {
202
+ // biome-ignore lint/style/noNonNullAssertion: matched is filtered from branchChars, find is guaranteed
202
203
  const positions = matched.map((m) => branches.find((b) => b.char === m).position);
203
204
  const isComplete = matched.length === 3;
204
205
  const transform = checkTransformationCondition(combo.resultElement, monthBranch, allBranchChars, isComplete);
@@ -216,6 +217,7 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
216
217
  for (const combo of BRANCH_DIRECTIONAL_COMBINATIONS) {
217
218
  const matched = combo.branches.filter((b) => branchChars.includes(b));
218
219
  if (matched.length >= 2) {
220
+ // biome-ignore lint/style/noNonNullAssertion: matched is filtered from branchChars, find is guaranteed
219
221
  const positions = matched.map((m) => branches.find((b) => b.char === m).position);
220
222
  const isComplete = matched.length === 3;
221
223
  const transform = checkTransformationCondition(combo.resultElement, monthBranch, allBranchChars, isComplete);
@@ -248,6 +250,7 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
248
250
  }
249
251
  }
250
252
  else if (isTriple && matched.length >= 2) {
253
+ // biome-ignore lint/style/noNonNullAssertion: matched is filtered from branchChars, find is guaranteed
251
254
  const positions = matched.map((m) => branches.find((b) => b.char === m).position);
252
255
  punishments.push({
253
256
  type: "형",
@@ -257,6 +260,7 @@ export function analyzeRelations(yearPillar, monthPillar, dayPillar, hourPillar)
257
260
  });
258
261
  }
259
262
  else if (!isTriple && matched.length === 2) {
263
+ // biome-ignore lint/style/noNonNullAssertion: matched is filtered from branchChars, find is guaranteed
260
264
  const positions = matched.map((m) => branches.find((b) => b.char === m).position);
261
265
  punishments.push({
262
266
  type: "형",
@@ -0,0 +1,19 @@
1
+ import type { PillarPosition } from "../types";
2
+ export declare const SINSALS: readonly ["peachBlossom", "skyHorse", "floweryCanopy", "ghostGate", "solitaryStar", "widowStar", "heavenlyVirtue", "monthlyVirtue", "skyNoble", "moonNoble", "literaryNoble", "academicHall", "bloodKnife", "sixHarms", "whiteCloth", "heavenlyDoctor"];
3
+ export type Sinsal = (typeof SINSALS)[number];
4
+ export interface SinsalMatch {
5
+ sinsal: Sinsal;
6
+ position: PillarPosition;
7
+ }
8
+ export interface SinsalResult {
9
+ matches: SinsalMatch[];
10
+ summary: Partial<Record<Sinsal, PillarPosition[]>>;
11
+ }
12
+ export declare function analyzeSinsals(yearPillar: string, monthPillar: string, dayPillar: string, hourPillar: string): SinsalResult;
13
+ export declare const SINSAL_INFO: Record<Sinsal, {
14
+ korean: string;
15
+ hanja: string;
16
+ meaning: string;
17
+ type: "auspicious" | "inauspicious" | "neutral";
18
+ }>;
19
+ //# sourceMappingURL=sinsals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sinsals.d.ts","sourceRoot":"","sources":["../../src/core/sinsals.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,eAAO,MAAM,OAAO,yPAiBV,CAAC;AAEX,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AA+L9C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;CACpD;AA6CD,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,YAAY,CAoId;AAED,eAAO,MAAM,WAAW,EAAE,MAAM,CAC9B,MAAM,EACN;IACE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,YAAY,GAAG,cAAc,GAAG,SAAS,CAAC;CACjD,CAmFF,CAAC"}
@@ -0,0 +1,339 @@
1
+ export const SINSALS = [
2
+ "peachBlossom",
3
+ "skyHorse",
4
+ "floweryCanopy",
5
+ "ghostGate",
6
+ "solitaryStar",
7
+ "widowStar",
8
+ "heavenlyVirtue",
9
+ "monthlyVirtue",
10
+ "skyNoble",
11
+ "moonNoble",
12
+ "literaryNoble",
13
+ "academicHall",
14
+ "bloodKnife",
15
+ "sixHarms",
16
+ "whiteCloth",
17
+ "heavenlyDoctor",
18
+ ];
19
+ const PEACH_BLOSSOM_MAP = {
20
+ 寅: "卯",
21
+ 午: "卯",
22
+ 戌: "卯",
23
+ 申: "酉",
24
+ 子: "酉",
25
+ 辰: "酉",
26
+ 巳: "午",
27
+ 酉: "午",
28
+ 丑: "午",
29
+ 亥: "子",
30
+ 卯: "子",
31
+ 未: "子",
32
+ };
33
+ const SKY_HORSE_MAP = {
34
+ 寅: "申",
35
+ 午: "申",
36
+ 戌: "申",
37
+ 申: "寅",
38
+ 子: "寅",
39
+ 辰: "寅",
40
+ 巳: "亥",
41
+ 酉: "亥",
42
+ 丑: "亥",
43
+ 亥: "巳",
44
+ 卯: "巳",
45
+ 未: "巳",
46
+ };
47
+ const FLOWERY_CANOPY_MAP = {
48
+ 寅: "戌",
49
+ 午: "戌",
50
+ 戌: "戌",
51
+ 申: "辰",
52
+ 子: "辰",
53
+ 辰: "辰",
54
+ 巳: "丑",
55
+ 酉: "丑",
56
+ 丑: "丑",
57
+ 亥: "未",
58
+ 卯: "未",
59
+ 未: "未",
60
+ };
61
+ const GHOST_GATE_MAP = {
62
+ 子: "卯",
63
+ 丑: "寅",
64
+ 寅: "丑",
65
+ 卯: "子",
66
+ 辰: "亥",
67
+ 巳: "戌",
68
+ 午: "酉",
69
+ 未: "申",
70
+ 申: "未",
71
+ 酉: "午",
72
+ 戌: "巳",
73
+ 亥: "辰",
74
+ };
75
+ const SOLITARY_STAR_MAP = {
76
+ 子: "寅",
77
+ 丑: "寅",
78
+ 寅: "巳",
79
+ 卯: "巳",
80
+ 辰: "巳",
81
+ 巳: "申",
82
+ 午: "申",
83
+ 未: "申",
84
+ 申: "亥",
85
+ 酉: "亥",
86
+ 戌: "亥",
87
+ 亥: "寅",
88
+ };
89
+ const WIDOW_STAR_MAP = {
90
+ 子: "戌",
91
+ 丑: "戌",
92
+ 寅: "丑",
93
+ 卯: "丑",
94
+ 辰: "丑",
95
+ 巳: "辰",
96
+ 午: "辰",
97
+ 未: "辰",
98
+ 申: "未",
99
+ 酉: "未",
100
+ 戌: "未",
101
+ 亥: "戌",
102
+ };
103
+ const HEAVENLY_VIRTUE_MAP = {
104
+ 寅: "丁",
105
+ 卯: "申",
106
+ 辰: "壬",
107
+ 巳: "辛",
108
+ 午: "亥",
109
+ 未: "甲",
110
+ 申: "癸",
111
+ 酉: "寅",
112
+ 戌: "丙",
113
+ 亥: "乙",
114
+ 子: "巳",
115
+ 丑: "庚",
116
+ };
117
+ const MONTHLY_VIRTUE_MAP = {
118
+ 寅: "丙",
119
+ 卯: "甲",
120
+ 辰: "壬",
121
+ 巳: "庚",
122
+ 午: "丙",
123
+ 未: "甲",
124
+ 申: "壬",
125
+ 酉: "庚",
126
+ 戌: "丙",
127
+ 亥: "甲",
128
+ 子: "壬",
129
+ 丑: "庚",
130
+ };
131
+ const SKY_NOBLE_MAP = {
132
+ 甲: ["丑", "未"],
133
+ 戊: ["丑", "未"],
134
+ 庚: ["丑", "未"],
135
+ 乙: ["子", "申"],
136
+ 己: ["子", "申"],
137
+ 丙: ["亥", "酉"],
138
+ 丁: ["亥", "酉"],
139
+ 壬: ["卯", "巳"],
140
+ 癸: ["卯", "巳"],
141
+ 辛: ["午", "寅"],
142
+ };
143
+ const LITERARY_NOBLE_MAP = {
144
+ 甲: "巳",
145
+ 乙: "午",
146
+ 丙: "申",
147
+ 丁: "酉",
148
+ 戊: "申",
149
+ 己: "酉",
150
+ 庚: "亥",
151
+ 辛: "子",
152
+ 壬: "寅",
153
+ 癸: "卯",
154
+ };
155
+ const ACADEMIC_HALL_MAP = {
156
+ 甲: "亥",
157
+ 乙: "子",
158
+ 丙: "寅",
159
+ 丁: "卯",
160
+ 戊: "寅",
161
+ 己: "卯",
162
+ 庚: "巳",
163
+ 辛: "午",
164
+ 壬: "申",
165
+ 癸: "酉",
166
+ };
167
+ const BLOOD_KNIFE_MAP = {
168
+ 子: "酉",
169
+ 丑: "戌",
170
+ 寅: "亥",
171
+ 卯: "子",
172
+ 辰: "丑",
173
+ 巳: "寅",
174
+ 午: "卯",
175
+ 未: "辰",
176
+ 申: "巳",
177
+ 酉: "午",
178
+ 戌: "未",
179
+ 亥: "申",
180
+ };
181
+ const HEAVENLY_DOCTOR_MAP = {
182
+ 子: "亥",
183
+ 丑: "子",
184
+ 寅: "丑",
185
+ 卯: "寅",
186
+ 辰: "卯",
187
+ 巳: "辰",
188
+ 午: "巳",
189
+ 未: "午",
190
+ 申: "未",
191
+ 酉: "申",
192
+ 戌: "酉",
193
+ 亥: "戌",
194
+ };
195
+ function checkBranchBasedSinsal(baseBranch, targetBranches, positions, map, sinsal) {
196
+ const matches = [];
197
+ const targetSinsal = map[baseBranch];
198
+ if (targetSinsal) {
199
+ targetBranches.forEach((branch, idx) => {
200
+ if (branch === targetSinsal) {
201
+ matches.push({ sinsal, position: positions[idx] });
202
+ }
203
+ });
204
+ }
205
+ return matches;
206
+ }
207
+ function checkStemBasedSinsal(baseStem, targetBranches, positions, map, sinsal) {
208
+ const matches = [];
209
+ const targetSinsal = map[baseStem];
210
+ if (targetSinsal) {
211
+ const targets = Array.isArray(targetSinsal) ? targetSinsal : [targetSinsal];
212
+ targetBranches.forEach((branch, idx) => {
213
+ if (targets.includes(branch)) {
214
+ matches.push({ sinsal, position: positions[idx] });
215
+ }
216
+ });
217
+ }
218
+ return matches;
219
+ }
220
+ export function analyzeSinsals(yearPillar, monthPillar, dayPillar, hourPillar) {
221
+ const yearBranch = yearPillar[1];
222
+ const monthBranch = monthPillar[1];
223
+ const dayBranch = dayPillar[1];
224
+ const hourBranch = hourPillar[1];
225
+ const dayStem = dayPillar[0];
226
+ const yearStem = yearPillar[0];
227
+ const allBranches = [yearBranch, monthBranch, dayBranch, hourBranch];
228
+ const positions = ["year", "month", "day", "hour"];
229
+ const matches = [];
230
+ matches.push(...checkBranchBasedSinsal(yearBranch, allBranches, positions, PEACH_BLOSSOM_MAP, "peachBlossom"));
231
+ matches.push(...checkBranchBasedSinsal(dayBranch, allBranches, positions, PEACH_BLOSSOM_MAP, "peachBlossom"));
232
+ matches.push(...checkBranchBasedSinsal(yearBranch, allBranches, positions, SKY_HORSE_MAP, "skyHorse"));
233
+ matches.push(...checkBranchBasedSinsal(dayBranch, allBranches, positions, SKY_HORSE_MAP, "skyHorse"));
234
+ matches.push(...checkBranchBasedSinsal(yearBranch, allBranches, positions, FLOWERY_CANOPY_MAP, "floweryCanopy"));
235
+ matches.push(...checkBranchBasedSinsal(dayBranch, allBranches, positions, FLOWERY_CANOPY_MAP, "floweryCanopy"));
236
+ matches.push(...checkBranchBasedSinsal(dayBranch, allBranches, positions, GHOST_GATE_MAP, "ghostGate"));
237
+ matches.push(...checkBranchBasedSinsal(yearBranch, allBranches, positions, SOLITARY_STAR_MAP, "solitaryStar"));
238
+ matches.push(...checkBranchBasedSinsal(yearBranch, allBranches, positions, WIDOW_STAR_MAP, "widowStar"));
239
+ matches.push(...checkBranchBasedSinsal(monthBranch, [yearPillar[0], monthPillar[0], dayPillar[0], hourPillar[0]].map((s) => s), positions, HEAVENLY_VIRTUE_MAP, "heavenlyVirtue"));
240
+ matches.push(...checkBranchBasedSinsal(monthBranch, [yearPillar[0], monthPillar[0], dayPillar[0], hourPillar[0]].map((s) => s), positions, MONTHLY_VIRTUE_MAP, "monthlyVirtue"));
241
+ matches.push(...checkStemBasedSinsal(dayStem, allBranches, positions, SKY_NOBLE_MAP, "skyNoble"));
242
+ matches.push(...checkStemBasedSinsal(yearStem, allBranches, positions, SKY_NOBLE_MAP, "moonNoble"));
243
+ matches.push(...checkStemBasedSinsal(dayStem, allBranches, positions, LITERARY_NOBLE_MAP, "literaryNoble"));
244
+ matches.push(...checkStemBasedSinsal(dayStem, allBranches, positions, ACADEMIC_HALL_MAP, "academicHall"));
245
+ matches.push(...checkBranchBasedSinsal(dayBranch, allBranches, positions, BLOOD_KNIFE_MAP, "bloodKnife"));
246
+ matches.push(...checkBranchBasedSinsal(monthBranch, allBranches, positions, HEAVENLY_DOCTOR_MAP, "heavenlyDoctor"));
247
+ const uniqueMatches = matches.filter((match, index, self) => index === self.findIndex((m) => m.sinsal === match.sinsal && m.position === match.position));
248
+ const summary = {};
249
+ for (const match of uniqueMatches) {
250
+ if (!summary[match.sinsal]) {
251
+ summary[match.sinsal] = [];
252
+ }
253
+ summary[match.sinsal]?.push(match.position);
254
+ }
255
+ return { matches: uniqueMatches, summary };
256
+ }
257
+ export const SINSAL_INFO = {
258
+ peachBlossom: {
259
+ korean: "도화살",
260
+ hanja: "桃花煞",
261
+ meaning: "이성 인연, 매력, 색정",
262
+ type: "neutral",
263
+ },
264
+ skyHorse: { korean: "역마살", hanja: "驛馬煞", meaning: "이동, 변화, 해외", type: "neutral" },
265
+ floweryCanopy: {
266
+ korean: "화개살",
267
+ hanja: "華蓋煞",
268
+ meaning: "예술, 종교, 고독",
269
+ type: "neutral",
270
+ },
271
+ ghostGate: {
272
+ korean: "귀문관살",
273
+ hanja: "鬼門關煞",
274
+ meaning: "귀신, 영적 감각, 불안",
275
+ type: "inauspicious",
276
+ },
277
+ solitaryStar: {
278
+ korean: "고진살",
279
+ hanja: "孤辰煞",
280
+ meaning: "고독, 독립, 자립",
281
+ type: "inauspicious",
282
+ },
283
+ widowStar: {
284
+ korean: "과숙살",
285
+ hanja: "寡宿煞",
286
+ meaning: "외로움, 배우자 인연 약함",
287
+ type: "inauspicious",
288
+ },
289
+ heavenlyVirtue: {
290
+ korean: "천덕귀인",
291
+ hanja: "天德貴人",
292
+ meaning: "하늘의 덕, 재난 해소",
293
+ type: "auspicious",
294
+ },
295
+ monthlyVirtue: {
296
+ korean: "월덕귀인",
297
+ hanja: "月德貴人",
298
+ meaning: "달의 덕, 흉화 해소",
299
+ type: "auspicious",
300
+ },
301
+ skyNoble: {
302
+ korean: "천을귀인",
303
+ hanja: "天乙貴人",
304
+ meaning: "귀인의 도움, 위기 극복",
305
+ type: "auspicious",
306
+ },
307
+ moonNoble: { korean: "월을귀인", hanja: "月乙貴人", meaning: "귀인의 도움", type: "auspicious" },
308
+ literaryNoble: {
309
+ korean: "문창귀인",
310
+ hanja: "文昌貴人",
311
+ meaning: "학업, 시험, 문서",
312
+ type: "auspicious",
313
+ },
314
+ academicHall: {
315
+ korean: "학당귀인",
316
+ hanja: "學堂貴人",
317
+ meaning: "학문, 교육, 지식",
318
+ type: "auspicious",
319
+ },
320
+ bloodKnife: {
321
+ korean: "혈인살",
322
+ hanja: "血刃煞",
323
+ meaning: "수술, 출혈, 부상",
324
+ type: "inauspicious",
325
+ },
326
+ sixHarms: { korean: "육해살", hanja: "六害煞", meaning: "인관계 해침", type: "inauspicious" },
327
+ whiteCloth: {
328
+ korean: "백호살",
329
+ hanja: "白虎煞",
330
+ meaning: "상해, 사고, 흉사",
331
+ type: "inauspicious",
332
+ },
333
+ heavenlyDoctor: {
334
+ korean: "천의성",
335
+ hanja: "天醫星",
336
+ meaning: "치료, 의료, 건강 회복",
337
+ type: "auspicious",
338
+ },
339
+ };
@@ -1,4 +1,4 @@
1
- import type { DateAdapter } from "@/adapters/date-adapter";
1
+ import type { DateAdapter } from "../adapters/date-adapter";
2
2
  /**
3
3
  * 24 Solar Terms (二十四節氣)
4
4
  * Each term corresponds to a specific solar longitude
@@ -1 +1 @@
1
- {"version":3,"file":"strength.d.ts","sourceRoot":"","sources":["../../src/core/strength.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,aAAa,GACrB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,MAAM,GACN,IAAI,GACJ,MAAM,GACN,IAAI,GACJ,IAAI,GACJ,IAAI,CAAC;AAET,eAAO,MAAM,eAAe,EAAE,aAAa,EAU1C,CAAC;AAsKF,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,cAAc,CAsGhB"}
1
+ {"version":3,"file":"strength.d.ts","sourceRoot":"","sources":["../../src/core/strength.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GACrB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,MAAM,GACN,IAAI,GACJ,MAAM,GACN,IAAI,GACJ,IAAI,GACJ,IAAI,CAAC;AAET,eAAO,MAAM,eAAe,EAAE,aAAa,EAU1C,CAAC;AAsKF,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,eAAe,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,cAAc,CAsGhB"}
@@ -1,4 +1,4 @@
1
- import { getStemElement, getBranchElement, getHiddenStems, getTenGod, getStemPolarity, } from "./ten-gods";
1
+ import { getStemElement, getStemPolarity, getTenGod } from "./ten-gods";
2
2
  export const STRENGTH_LEVELS = [
3
3
  "극약",
4
4
  "태약",
@@ -1,10 +1,7 @@
1
- /**
2
- * 십신(十神) 분석 모듈
3
- * Ten Gods analysis based on the relationship between Day Master and other elements
4
- */
5
- export type Element = "wood" | "fire" | "earth" | "metal" | "water";
6
- export declare const ELEMENTS: Element[];
7
- export type Polarity = "yang" | "yin";
1
+ import type { Element, Polarity } from "../types";
2
+ import { ELEMENTS } from "../utils";
3
+ export type { Element, Polarity };
4
+ export { ELEMENTS };
8
5
  export type TenGod = "비견" | "겁재" | "식신" | "상관" | "편재" | "정재" | "편관" | "정관" | "편인" | "정인";
9
6
  export declare const TEN_GODS: TenGod[];
10
7
  export declare const TEN_GOD_HANJA: Record<TenGod, string>;