@orrery/core 0.2.1 → 0.4.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/dist/types.d.ts CHANGED
@@ -4,6 +4,8 @@ type Element = 'tree' | 'fire' | 'earth' | 'metal' | 'water';
4
4
  type YinYang = '+' | '-';
5
5
  /** 성별 */
6
6
  type Gender = 'M' | 'F';
7
+ /** 자시법 (子時法) — 23:00~01:00 구간 일주 처리 방식 */
8
+ type JasiMethod = 'split' | 'unified';
7
9
  /** 생년월일시 입력 */
8
10
  interface BirthInput {
9
11
  year: number;
@@ -14,6 +16,8 @@ interface BirthInput {
14
16
  gender: Gender;
15
17
  /** 시간 모름 여부 */
16
18
  unknownTime?: boolean;
19
+ /** 자시법 (기본값: 'unified' 통자시) */
20
+ jasiMethod?: JasiMethod;
17
21
  /** 위도 (기본값: 37.5194 서울) */
18
22
  latitude?: number;
19
23
  /** 경도 (기본값: 127.0992 서울) */
@@ -75,6 +79,8 @@ interface DaewoonItem {
75
79
  unseong: string;
76
80
  /** 12신살 (연지 기준) */
77
81
  sinsal: string;
82
+ /** 공망 여부 */
83
+ isGongmang: boolean;
78
84
  }
79
85
  /** 관계 분석 결과 */
80
86
  interface RelationResult {
@@ -97,6 +103,32 @@ interface SpecialSals {
97
103
  yangin: number[];
98
104
  baekho: boolean;
99
105
  goegang: boolean;
106
+ dohwa: number[];
107
+ cheonul: number[];
108
+ cheonduk: number[];
109
+ wolduk: number[];
110
+ munchang: number[];
111
+ hongyeom: boolean;
112
+ geumyeo: number[];
113
+ }
114
+ /** 공망 정보 */
115
+ interface Gongmang {
116
+ /** 공망 지지 2개 */
117
+ branches: [string, string];
118
+ /** 공망에 든 주의 인덱스 (0=시, 1=일, 2=월, 3=년) */
119
+ pillarIndices: number[];
120
+ }
121
+ /** 좌법 항목 (지장간 → 일지 운성) */
122
+ interface JwaEntry {
123
+ stem: string;
124
+ sipsin: string;
125
+ unseong: string;
126
+ }
127
+ /** 인종법 항목 (일지에 없는 십성 카테고리) */
128
+ interface InjongEntry {
129
+ category: string;
130
+ yangStem: string;
131
+ unseong: string;
100
132
  }
101
133
  /** 트랜짓 항목 */
102
134
  interface TransitItem {
@@ -120,6 +152,12 @@ interface SajuResult {
120
152
  relations: AllRelations;
121
153
  /** 신살 */
122
154
  specialSals: SpecialSals;
155
+ /** 공망 */
156
+ gongmang: Gongmang;
157
+ /** 좌법 (각 주 지장간 → 일지 운성) — 4주×N지장간 */
158
+ jwabeop: JwaEntry[][];
159
+ /** 인종법 (일지에 없는 십성 카테고리 인종) */
160
+ injongbeop: InjongEntry[];
123
161
  }
124
162
  /** 오행국 */
125
163
  interface WuXingJu {
@@ -185,7 +223,7 @@ interface LiuNianInfo {
185
223
  /** 12궁 별자리 */
186
224
  type ZodiacSign = 'Aries' | 'Taurus' | 'Gemini' | 'Cancer' | 'Leo' | 'Virgo' | 'Libra' | 'Scorpio' | 'Sagittarius' | 'Capricorn' | 'Aquarius' | 'Pisces';
187
225
  /** 행성 ID */
188
- type PlanetId = 'Sun' | 'Moon' | 'Mercury' | 'Venus' | 'Mars' | 'Jupiter' | 'Saturn' | 'Uranus' | 'Neptune' | 'Pluto' | 'Chiron' | 'NorthNode' | 'SouthNode';
226
+ type PlanetId = 'Sun' | 'Moon' | 'Mercury' | 'Venus' | 'Mars' | 'Jupiter' | 'Saturn' | 'Uranus' | 'Neptune' | 'Pluto' | 'Chiron' | 'NorthNode' | 'SouthNode' | 'Fortuna';
189
227
  /** 행성 위치 */
190
228
  interface PlanetPosition {
191
229
  id: PlanetId;
@@ -195,7 +233,8 @@ interface PlanetPosition {
195
233
  sign: ZodiacSign;
196
234
  degreeInSign: number;
197
235
  isRetrograde: boolean;
198
- house: number;
236
+ /** 하우스 번호 (시간 모름이면 undefined) */
237
+ house?: number;
199
238
  }
200
239
  /** 하우스 cusp */
201
240
  interface NatalHouse {
@@ -242,8 +281,9 @@ interface NatalChart {
242
281
  input: BirthInput;
243
282
  planets: PlanetPosition[];
244
283
  houses: NatalHouse[];
245
- angles: NatalAngles;
284
+ /** 앵글 (시간 모름이면 null) */
285
+ angles: NatalAngles | null;
246
286
  aspects: NatalAspect[];
247
287
  }
248
288
 
249
- export type { AllRelations, AspectType, BirthInput, DaewoonItem, Element, Gender, LiuNianInfo, LiuYueInfo, Meteor, NatalAngles, NatalAspect, NatalChart, NatalHouse, PairRelation, Pillar, PillarDetail, PlanetId, PlanetPosition, Relation, RelationResult, SajuResult, SpecialSals, Spirit, StemInfo, TransitItem, WuXingJu, YinYang, ZiweiChart, ZiweiPalace, ZiweiStar, ZodiacSign };
289
+ export type { AllRelations, AspectType, BirthInput, DaewoonItem, Element, Gender, Gongmang, InjongEntry, JasiMethod, JwaEntry, LiuNianInfo, LiuYueInfo, Meteor, NatalAngles, NatalAspect, NatalChart, NatalHouse, PairRelation, Pillar, PillarDetail, PlanetId, PlanetPosition, Relation, RelationResult, SajuResult, SpecialSals, Spirit, StemInfo, TransitItem, WuXingJu, YinYang, ZiweiChart, ZiweiPalace, ZiweiStar, ZodiacSign };
package/dist/ziwei.js CHANGED
@@ -2,8 +2,9 @@ import {
2
2
  calculateLiunian,
3
3
  createChart,
4
4
  getDaxianList
5
- } from "./chunk-KD6TCTRW.js";
6
- import "./chunk-VJDUZB5T.js";
5
+ } from "./chunk-APL4STY7.js";
6
+ import "./chunk-TW4ADZCX.js";
7
+ import "./chunk-EXYPMSUR.js";
7
8
  import "./chunk-JSBRDJBE.js";
8
9
  export {
9
10
  calculateLiunian,
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@orrery/core",
3
- "version": "0.2.1",
3
+ "version": "0.4.0",
4
+ "license": "AGPL-3.0-only",
4
5
  "type": "module",
5
6
  "keywords": [
6
7
  "saju",
@@ -60,14 +61,6 @@
60
61
  "dependencies": {
61
62
  "lunar-javascript": "^1.7.7"
62
63
  },
63
- "peerDependencies": {
64
- "swisseph-wasm": "^0.0.4"
65
- },
66
- "peerDependenciesMeta": {
67
- "swisseph-wasm": {
68
- "optional": true
69
- }
70
- },
71
64
  "devDependencies": {
72
65
  "tsup": "^8.5.0",
73
66
  "typescript": "~5.9.3",
@@ -1,292 +0,0 @@
1
- // src/natal.ts
2
- import SwissEph from "swisseph-wasm";
3
- var DEFAULT_LAT = 37.5194;
4
- var DEFAULT_LON = 127.0992;
5
- var ZODIAC_SIGNS = [
6
- "Aries",
7
- "Taurus",
8
- "Gemini",
9
- "Cancer",
10
- "Leo",
11
- "Virgo",
12
- "Libra",
13
- "Scorpio",
14
- "Sagittarius",
15
- "Capricorn",
16
- "Aquarius",
17
- "Pisces"
18
- ];
19
- var ZODIAC_SYMBOLS = {
20
- Aries: "\u2648",
21
- Taurus: "\u2649",
22
- Gemini: "\u264A",
23
- Cancer: "\u264B",
24
- Leo: "\u264C",
25
- Virgo: "\u264D",
26
- Libra: "\u264E",
27
- Scorpio: "\u264F",
28
- Sagittarius: "\u2650",
29
- Capricorn: "\u2651",
30
- Aquarius: "\u2652",
31
- Pisces: "\u2653"
32
- };
33
- var ZODIAC_KO = {
34
- Aries: "\uC591\uC790\uB9AC",
35
- Taurus: "\uD669\uC18C\uC790\uB9AC",
36
- Gemini: "\uC30D\uB465\uC774\uC790\uB9AC",
37
- Cancer: "\uAC8C\uC790\uB9AC",
38
- Leo: "\uC0AC\uC790\uC790\uB9AC",
39
- Virgo: "\uCC98\uB140\uC790\uB9AC",
40
- Libra: "\uCC9C\uCE6D\uC790\uB9AC",
41
- Scorpio: "\uC804\uAC08\uC790\uB9AC",
42
- Sagittarius: "\uAD81\uC218\uC790\uB9AC",
43
- Capricorn: "\uC5FC\uC18C\uC790\uB9AC",
44
- Aquarius: "\uBB3C\uBCD1\uC790\uB9AC",
45
- Pisces: "\uBB3C\uACE0\uAE30\uC790\uB9AC"
46
- };
47
- var PLANET_SYMBOLS = {
48
- Sun: "\u2609",
49
- Moon: "\u263D",
50
- Mercury: "\u263F",
51
- Venus: "\u2640",
52
- Mars: "\u2642",
53
- Jupiter: "\u2643",
54
- Saturn: "\u2644",
55
- Uranus: "\u2645",
56
- Neptune: "\u2646",
57
- Pluto: "\u2647",
58
- Chiron: "\u26B7",
59
- NorthNode: "\u260A",
60
- SouthNode: "\u260B"
61
- };
62
- var PLANET_KO = {
63
- Sun: "\uD0DC\uC591",
64
- Moon: "\uB2EC",
65
- Mercury: "\uC218\uC131",
66
- Venus: "\uAE08\uC131",
67
- Mars: "\uD654\uC131",
68
- Jupiter: "\uBAA9\uC131",
69
- Saturn: "\uD1A0\uC131",
70
- Uranus: "\uCC9C\uC655\uC131",
71
- Neptune: "\uD574\uC655\uC131",
72
- Pluto: "\uBA85\uC655\uC131",
73
- Chiron: "\uD0A4\uB860",
74
- NorthNode: "\uBD81\uAD50\uC810",
75
- SouthNode: "\uB0A8\uAD50\uC810"
76
- };
77
- var PLANET_BODIES = [
78
- ["Sun", 0],
79
- // SE_SUN
80
- ["Moon", 1],
81
- // SE_MOON
82
- ["Mercury", 2],
83
- // SE_MERCURY
84
- ["Venus", 3],
85
- // SE_VENUS
86
- ["Mars", 4],
87
- // SE_MARS
88
- ["Jupiter", 5],
89
- // SE_JUPITER
90
- ["Saturn", 6],
91
- // SE_SATURN
92
- ["Uranus", 7],
93
- // SE_URANUS
94
- ["Neptune", 8],
95
- // SE_NEPTUNE
96
- ["Pluto", 9],
97
- // SE_PLUTO
98
- ["Chiron", 15],
99
- // SE_CHIRON
100
- ["NorthNode", 10]
101
- // SE_MEAN_NODE
102
- ];
103
- var ASPECT_SYMBOLS = {
104
- conjunction: "\u260C",
105
- sextile: "\u26B9",
106
- square: "\u25A1",
107
- trine: "\u25B3",
108
- opposition: "\u260D"
109
- };
110
- var ASPECT_DEFS = [
111
- { type: "conjunction", angle: 0, maxOrb: 8 },
112
- { type: "sextile", angle: 60, maxOrb: 6 },
113
- { type: "square", angle: 90, maxOrb: 8 },
114
- { type: "trine", angle: 120, maxOrb: 8 },
115
- { type: "opposition", angle: 180, maxOrb: 8 }
116
- ];
117
- var ROMAN = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII"];
118
- var HOUSE_SYSTEMS = [
119
- ["P", "Placidus"],
120
- ["K", "Koch"],
121
- ["O", "Porphyrius"],
122
- ["R", "Regiomontanus"],
123
- ["C", "Campanus"],
124
- ["E", "Equal"],
125
- ["W", "Whole Sign"],
126
- ["B", "Alcabitus"],
127
- ["M", "Morinus"],
128
- ["T", "Topocentric"]
129
- ];
130
- var sweInstance = null;
131
- var initPromise = null;
132
- async function getSwissEph() {
133
- if (sweInstance) return sweInstance;
134
- if (initPromise) return initPromise;
135
- initPromise = (async () => {
136
- const swe = new SwissEph();
137
- await swe.initSwissEph();
138
- sweInstance = swe;
139
- return swe;
140
- })();
141
- return initPromise;
142
- }
143
- function lonToSign(lon) {
144
- return ZODIAC_SIGNS[Math.trunc(normalizeDeg(lon) / 30)];
145
- }
146
- function normalizeDeg(deg) {
147
- return (deg % 360 + 360) % 360;
148
- }
149
- function degreeInSign(lon) {
150
- return normalizeDeg(lon) % 30;
151
- }
152
- function angularDifference(lon1, lon2) {
153
- let diff = Math.abs(normalizeDeg(lon1) - normalizeDeg(lon2));
154
- if (diff > 180) diff = 360 - diff;
155
- return diff;
156
- }
157
- function formatDegree(lon) {
158
- const d = degreeInSign(lon);
159
- const deg = Math.trunc(d);
160
- const min = Math.trunc((d - deg) * 60);
161
- return `${deg}\xB0${String(min).padStart(2, "0")}'`;
162
- }
163
- function findHouse(planetLon, cusps) {
164
- const lon = normalizeDeg(planetLon);
165
- for (let i = 1; i <= 12; i++) {
166
- const start = normalizeDeg(cusps[i]);
167
- const end = normalizeDeg(cusps[i === 12 ? 1 : i + 1]);
168
- if (start < end) {
169
- if (lon >= start && lon < end) return i;
170
- } else {
171
- if (lon >= start || lon < end) return i;
172
- }
173
- }
174
- return 1;
175
- }
176
- function calculateAspects(planets) {
177
- const aspects = [];
178
- for (let i = 0; i < planets.length; i++) {
179
- for (let j = i + 1; j < planets.length; j++) {
180
- const p1 = planets[i];
181
- const p2 = planets[j];
182
- const diff = angularDifference(p1.longitude, p2.longitude);
183
- for (const def of ASPECT_DEFS) {
184
- const orb = Math.abs(diff - def.angle);
185
- if (orb <= def.maxOrb) {
186
- aspects.push({
187
- planet1: p1.id,
188
- planet2: p2.id,
189
- type: def.type,
190
- angle: def.angle,
191
- orb: Math.round(orb * 10) / 10
192
- });
193
- }
194
- }
195
- }
196
- }
197
- aspects.sort((a, b) => a.orb - b.orb);
198
- return aspects;
199
- }
200
- async function calculateNatal(input, houseSystem = "P") {
201
- const swe = await getSwissEph();
202
- const lat = input.latitude ?? DEFAULT_LAT;
203
- const lon = input.longitude ?? DEFAULT_LON;
204
- const utHourDecimal = input.hour + input.minute / 60 - 9;
205
- let utYear = input.year;
206
- let utMonth = input.month;
207
- let utDay = input.day;
208
- let utHour = utHourDecimal;
209
- if (utHour < 0) {
210
- utHour += 24;
211
- const d = new Date(utYear, utMonth - 1, utDay - 1);
212
- utYear = d.getFullYear();
213
- utMonth = d.getMonth() + 1;
214
- utDay = d.getDate();
215
- } else if (utHour >= 24) {
216
- utHour -= 24;
217
- const d = new Date(utYear, utMonth - 1, utDay + 1);
218
- utYear = d.getFullYear();
219
- utMonth = d.getMonth() + 1;
220
- utDay = d.getDate();
221
- }
222
- const jd = swe.julday(utYear, utMonth, utDay, utHour);
223
- const housesEx = swe.houses_ex.bind(swe);
224
- const { cusps, ascmc } = housesEx(jd, 0, lat, lon, houseSystem);
225
- const calcFlags = swe.SEFLG_SWIEPH | swe.SEFLG_SPEED;
226
- const planets = [];
227
- for (const [id, bodyNum] of PLANET_BODIES) {
228
- const pos = swe.calc_ut(jd, bodyNum, calcFlags);
229
- const longitude = pos[0];
230
- planets.push({
231
- id,
232
- longitude,
233
- latitude: pos[1],
234
- speed: pos[3],
235
- sign: lonToSign(longitude),
236
- degreeInSign: degreeInSign(longitude),
237
- isRetrograde: pos[3] < 0,
238
- house: findHouse(longitude, cusps)
239
- });
240
- }
241
- const northNode = planets.find((p) => p.id === "NorthNode");
242
- const southLon = normalizeDeg(northNode.longitude + 180);
243
- planets.push({
244
- id: "SouthNode",
245
- longitude: southLon,
246
- latitude: -northNode.latitude,
247
- speed: northNode.speed,
248
- sign: lonToSign(southLon),
249
- degreeInSign: degreeInSign(southLon),
250
- isRetrograde: false,
251
- house: findHouse(southLon, cusps)
252
- });
253
- const houses = [];
254
- for (let i = 1; i <= 12; i++) {
255
- const cuspLon = cusps[i];
256
- houses.push({
257
- number: i,
258
- cuspLongitude: cuspLon,
259
- sign: lonToSign(cuspLon),
260
- degreeInSign: degreeInSign(cuspLon)
261
- });
262
- }
263
- const ascLon = ascmc[0];
264
- const mcLon = ascmc[1];
265
- const descLon = normalizeDeg(ascLon + 180);
266
- const icLon = normalizeDeg(mcLon + 180);
267
- const angles = {
268
- asc: { longitude: ascLon, sign: lonToSign(ascLon), degreeInSign: degreeInSign(ascLon) },
269
- mc: { longitude: mcLon, sign: lonToSign(mcLon), degreeInSign: degreeInSign(mcLon) },
270
- desc: { longitude: descLon, sign: lonToSign(descLon), degreeInSign: degreeInSign(descLon) },
271
- ic: { longitude: icLon, sign: lonToSign(icLon), degreeInSign: degreeInSign(icLon) }
272
- };
273
- const aspectPlanets = planets.filter((p) => p.id !== "SouthNode");
274
- const aspects = calculateAspects(aspectPlanets);
275
- return { input, planets, houses, angles, aspects };
276
- }
277
-
278
- export {
279
- ZODIAC_SIGNS,
280
- ZODIAC_SYMBOLS,
281
- ZODIAC_KO,
282
- PLANET_SYMBOLS,
283
- PLANET_KO,
284
- ASPECT_SYMBOLS,
285
- ROMAN,
286
- HOUSE_SYSTEMS,
287
- getSwissEph,
288
- lonToSign,
289
- normalizeDeg,
290
- formatDegree,
291
- calculateNatal
292
- };