lichta 1.0.1 → 2.0.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.
@@ -1,437 +0,0 @@
1
- <script lang="ts">
2
- import { LichTa } from '../core/lunar.js';
3
- import { getYearDetails } from '../core/feng-shui.js';
4
- import type { LunarDate } from '../core/types.js';
5
- import type { Snippet } from 'svelte';
6
-
7
- import type { Locale } from '../constants/i18n.js';
8
-
9
- /**
10
- * Dữ liệu cho mỗi ô ngày trong lưới lịch
11
- */
12
- interface DayCellData {
13
- solar: Date;
14
- lunar: LunarDate;
15
- isToday: boolean;
16
- isSelected: boolean;
17
- isCurrentMonth: boolean;
18
- }
19
-
20
- interface Props {
21
- /** Tháng hiển thị (1-12). Mặc định: tháng hiện tại */
22
- month?: number;
23
- /** Năm hiển thị. Mặc định: năm hiện tại */
24
- year?: number;
25
- /** Ngày được chọn */
26
- selectedDate?: Date | null;
27
- /** Callback khi chọn ngày */
28
- onSelect?: (date: Date, lunar: LunarDate) => void;
29
- /** Hiển thị ngày âm lịch bên dưới ngày dương */
30
- showLunar?: boolean;
31
- /** Locale (vi | en | ja | ko) */
32
- locale?: Locale;
33
- /** Custom snippet cho mỗi ô ngày */
34
- dayCell?: Snippet<[DayCellData]>;
35
- children?: Snippet;
36
- }
37
-
38
- let {
39
- month = new Date().getMonth() + 1,
40
- year = new Date().getFullYear(),
41
- selectedDate = null,
42
- onSelect,
43
- showLunar = true,
44
- locale = 'vi',
45
- dayCell,
46
- children,
47
- }: Props = $props();
48
-
49
- // State nội bộ cho navigation (khởi tạo từ props hoặc giá trị mặc định)
50
- let currentMonth = $state(month ?? new Date().getMonth() + 1);
51
- let currentYear = $state(year ?? new Date().getFullYear());
52
-
53
- // Tên thứ trong tuần
54
- const weekDayLabels = $derived(
55
- locale === 'vi'
56
- ? ['CN', 'T2', 'T3', 'T4', 'T5', 'T6', 'T7']
57
- : ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
58
- );
59
-
60
- // Tên tháng hiển thị
61
- const monthNames = [
62
- 'Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6',
63
- 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12',
64
- ];
65
-
66
- // Can Chi năm hiển thị
67
- let yearInfo = $derived(getYearDetails(currentYear));
68
-
69
- // Ngày hôm nay
70
- const today = new Date();
71
- const todayStr = `${today.getFullYear()}-${today.getMonth() + 1}-${today.getDate()}`;
72
-
73
- // Tính grid lịch 6x7 = 42 ô
74
- let calendarGrid = $derived.by((): DayCellData[] => {
75
- const grid: DayCellData[] = [];
76
-
77
- // Ngày đầu tiên của tháng
78
- const firstDay = new Date(currentYear, currentMonth - 1, 1);
79
- // Thứ của ngày đầu tiên (0=CN, 1=T2, ...)
80
- const startDayOfWeek = firstDay.getDay();
81
- // Số ngày trong tháng
82
- const daysInMonth = new Date(currentYear, currentMonth, 0).getDate();
83
-
84
- // Padding ngày tháng trước
85
- const prevMonthDays = new Date(currentYear, currentMonth - 1, 0).getDate();
86
- for (let i = startDayOfWeek - 1; i >= 0; i--) {
87
- const d = prevMonthDays - i;
88
- const m = currentMonth - 1 <= 0 ? 12 : currentMonth - 1;
89
- const y = currentMonth - 1 <= 0 ? currentYear - 1 : currentYear;
90
- const solar = new Date(y, m - 1, d);
91
- const lunar = LichTa.toLunar(d, m, y);
92
- const dateStr = `${y}-${m}-${d}`;
93
- const selStr = selectedDate
94
- ? `${selectedDate.getFullYear()}-${selectedDate.getMonth() + 1}-${selectedDate.getDate()}`
95
- : '';
96
-
97
- grid.push({
98
- solar,
99
- lunar,
100
- isToday: dateStr === todayStr,
101
- isSelected: dateStr === selStr,
102
- isCurrentMonth: false,
103
- });
104
- }
105
-
106
- // Ngày trong tháng hiện tại
107
- for (let d = 1; d <= daysInMonth; d++) {
108
- const solar = new Date(currentYear, currentMonth - 1, d);
109
- const lunar = LichTa.toLunar(d, currentMonth, currentYear);
110
- const dateStr = `${currentYear}-${currentMonth}-${d}`;
111
- const selStr = selectedDate
112
- ? `${selectedDate.getFullYear()}-${selectedDate.getMonth() + 1}-${selectedDate.getDate()}`
113
- : '';
114
-
115
- grid.push({
116
- solar,
117
- lunar,
118
- isToday: dateStr === todayStr,
119
- isSelected: dateStr === selStr,
120
- isCurrentMonth: true,
121
- });
122
- }
123
-
124
- // Padding ngày tháng sau
125
- const remaining = 42 - grid.length;
126
- for (let d = 1; d <= remaining; d++) {
127
- const m = currentMonth + 1 > 12 ? 1 : currentMonth + 1;
128
- const y = currentMonth + 1 > 12 ? currentYear + 1 : currentYear;
129
- const solar = new Date(y, m - 1, d);
130
- const lunar = LichTa.toLunar(d, m, y);
131
- const dateStr = `${y}-${m}-${d}`;
132
- const selStr = selectedDate
133
- ? `${selectedDate.getFullYear()}-${selectedDate.getMonth() + 1}-${selectedDate.getDate()}`
134
- : '';
135
-
136
- grid.push({
137
- solar,
138
- lunar,
139
- isToday: dateStr === todayStr,
140
- isSelected: dateStr === selStr,
141
- isCurrentMonth: false,
142
- });
143
- }
144
-
145
- return grid;
146
- });
147
-
148
- // Navigation
149
- function prevMonth() {
150
- if (currentMonth === 1) {
151
- currentMonth = 12;
152
- currentYear -= 1;
153
- } else {
154
- currentMonth -= 1;
155
- }
156
- }
157
-
158
- function nextMonth() {
159
- if (currentMonth === 12) {
160
- currentMonth = 1;
161
- currentYear += 1;
162
- } else {
163
- currentMonth += 1;
164
- }
165
- }
166
-
167
- function handleDayClick(cell: DayCellData) {
168
- onSelect?.(cell.solar, cell.lunar);
169
- }
170
-
171
- function handleKeydown(event: KeyboardEvent, cell: DayCellData) {
172
- if (event.key === 'Enter' || event.key === ' ') {
173
- event.preventDefault();
174
- handleDayClick(cell);
175
- }
176
- }
177
- </script>
178
-
179
- <div class="lich-ta-calendar">
180
- <!-- Header: Navigation + Tháng/Năm -->
181
- <div class="lich-ta-calendar-header">
182
- <button class="lich-ta-calendar-nav" onclick={prevMonth} aria-label="Tháng trước">◀</button>
183
- <div class="lich-ta-calendar-title">
184
- <span class="lich-ta-calendar-month-year">
185
- {monthNames[currentMonth - 1]}, {currentYear}
186
- </span>
187
- <span class="lich-ta-calendar-canchi">
188
- {yearInfo.can} {yearInfo.chi}
189
- </span>
190
- </div>
191
- <button class="lich-ta-calendar-nav" onclick={nextMonth} aria-label="Tháng sau">▶</button>
192
- </div>
193
-
194
- <!-- Tên thứ -->
195
- <div class="lich-ta-calendar-weekdays">
196
- {#each weekDayLabels as label}
197
- <div class="lich-ta-calendar-weekday">{label}</div>
198
- {/each}
199
- </div>
200
-
201
- <!-- Grid ngày -->
202
- <div class="lich-ta-calendar-grid">
203
- {#each calendarGrid as cell}
204
- {#if dayCell}
205
- {@render dayCell(cell)}
206
- {:else}
207
- <button
208
- class="lich-ta-calendar-day"
209
- class:is-today={cell.isToday}
210
- class:is-selected={cell.isSelected}
211
- class:is-other-month={!cell.isCurrentMonth}
212
- class:is-first-lunar={cell.lunar.day === 1}
213
- onclick={() => handleDayClick(cell)}
214
- onkeydown={(e) => handleKeydown(e, cell)}
215
- tabindex={cell.isCurrentMonth ? 0 : -1}
216
- >
217
- <span class="solar-day">{cell.solar.getDate()}</span>
218
- {#if showLunar}
219
- <span class="lunar-day">
220
- {#if cell.lunar.day === 1}
221
- {cell.lunar.day}/{cell.lunar.month}{cell.lunar.isLeap ? '*' : ''}
222
- {:else}
223
- {cell.lunar.day}
224
- {/if}
225
- </span>
226
- {/if}
227
- </button>
228
- {/if}
229
- {/each}
230
- </div>
231
-
232
- <!-- Slot cho nội dung tùy chỉnh bên dưới lịch -->
233
- {#if children}
234
- <div class="lich-ta-calendar-footer">
235
- {@render children()}
236
- </div>
237
- {/if}
238
- </div>
239
-
240
- <style>
241
- .lich-ta-calendar {
242
- --lichta-primary: #d4a373;
243
- --lichta-primary-light: #f5e6d3;
244
- --lichta-bg: #fffcf7;
245
- --lichta-surface: #ffffff;
246
- --lichta-text: #2c1810;
247
- --lichta-text-muted: #8b7355;
248
- --lichta-text-dim: #c4b5a0;
249
- --lichta-border: #e8ddd0;
250
- --lichta-today-bg: #d4a373;
251
- --lichta-today-text: #ffffff;
252
- --lichta-selected-bg: #a0522d;
253
- --lichta-selected-text: #ffffff;
254
- --lichta-hover-bg: #f5e6d3;
255
- --lichta-lunar-text: #b08968;
256
- --lichta-first-lunar: #c2185b;
257
- --lichta-radius: 8px;
258
- --lichta-font: inherit;
259
-
260
- font-family: var(--lichta-font);
261
- background: var(--lichta-bg);
262
- border: 1px solid var(--lichta-border);
263
- border-radius: calc(var(--lichta-radius) * 2);
264
- padding: 16px;
265
- max-width: 420px;
266
- width: 100%;
267
- box-sizing: border-box;
268
- user-select: none;
269
- }
270
-
271
- /* Header */
272
- .lich-ta-calendar-header {
273
- display: flex;
274
- align-items: center;
275
- justify-content: space-between;
276
- margin-bottom: 16px;
277
- }
278
-
279
- .lich-ta-calendar-nav {
280
- background: none;
281
- border: 1px solid var(--lichta-border);
282
- border-radius: var(--lichta-radius);
283
- width: 36px;
284
- height: 36px;
285
- display: flex;
286
- align-items: center;
287
- justify-content: center;
288
- cursor: pointer;
289
- color: var(--lichta-text);
290
- font-size: 0.85rem;
291
- transition: all 0.15s ease;
292
- }
293
-
294
- .lich-ta-calendar-nav:hover {
295
- background: var(--lichta-hover-bg);
296
- border-color: var(--lichta-primary);
297
- }
298
-
299
- .lich-ta-calendar-title {
300
- text-align: center;
301
- }
302
-
303
- .lich-ta-calendar-month-year {
304
- display: block;
305
- font-size: 1.1rem;
306
- font-weight: 600;
307
- color: var(--lichta-text);
308
- }
309
-
310
- .lich-ta-calendar-canchi {
311
- display: block;
312
- font-size: 0.8rem;
313
- color: var(--lichta-text-muted);
314
- margin-top: 2px;
315
- }
316
-
317
- /* Weekdays */
318
- .lich-ta-calendar-weekdays {
319
- display: grid;
320
- grid-template-columns: repeat(7, 1fr);
321
- margin-bottom: 4px;
322
- }
323
-
324
- .lich-ta-calendar-weekday {
325
- text-align: center;
326
- font-size: 0.75rem;
327
- font-weight: 600;
328
- color: var(--lichta-text-muted);
329
- padding: 6px 0;
330
- text-transform: uppercase;
331
- letter-spacing: 0.05em;
332
- }
333
-
334
- /* Grid */
335
- .lich-ta-calendar-grid {
336
- display: grid;
337
- grid-template-columns: repeat(7, 1fr);
338
- gap: 2px;
339
- }
340
-
341
- .lich-ta-calendar-day {
342
- display: flex;
343
- flex-direction: column;
344
- align-items: center;
345
- justify-content: center;
346
- padding: 6px 2px;
347
- min-height: 48px;
348
- border: none;
349
- border-radius: var(--lichta-radius);
350
- background: transparent;
351
- cursor: pointer;
352
- transition: all 0.15s ease;
353
- font-family: inherit;
354
- }
355
-
356
- .lich-ta-calendar-day:hover {
357
- background: var(--lichta-hover-bg);
358
- }
359
-
360
- .lich-ta-calendar-day:focus-visible {
361
- outline: 2px solid var(--lichta-primary);
362
- outline-offset: 1px;
363
- }
364
-
365
- .solar-day {
366
- font-size: 0.95rem;
367
- font-weight: 500;
368
- color: var(--lichta-text);
369
- line-height: 1.2;
370
- }
371
-
372
- .lunar-day {
373
- font-size: 0.65rem;
374
- color: var(--lichta-lunar-text);
375
- line-height: 1.2;
376
- margin-top: 1px;
377
- }
378
-
379
- /* States */
380
- .is-other-month .solar-day {
381
- color: var(--lichta-text-dim);
382
- }
383
-
384
- .is-other-month .lunar-day {
385
- color: var(--lichta-text-dim);
386
- }
387
-
388
- .is-today {
389
- background: var(--lichta-today-bg);
390
- }
391
-
392
- .is-today .solar-day {
393
- color: var(--lichta-today-text);
394
- font-weight: 700;
395
- }
396
-
397
- .is-today .lunar-day {
398
- color: var(--lichta-today-text);
399
- opacity: 0.85;
400
- }
401
-
402
- .is-today:hover {
403
- background: var(--lichta-today-bg);
404
- opacity: 0.9;
405
- }
406
-
407
- .is-selected {
408
- background: var(--lichta-selected-bg);
409
- }
410
-
411
- .is-selected .solar-day {
412
- color: var(--lichta-selected-text);
413
- font-weight: 700;
414
- }
415
-
416
- .is-selected .lunar-day {
417
- color: var(--lichta-selected-text);
418
- opacity: 0.85;
419
- }
420
-
421
- .is-first-lunar .lunar-day {
422
- color: var(--lichta-first-lunar);
423
- font-weight: 600;
424
- }
425
-
426
- .is-today.is-first-lunar .lunar-day,
427
- .is-selected.is-first-lunar .lunar-day {
428
- color: var(--lichta-today-text);
429
- }
430
-
431
- /* Footer */
432
- .lich-ta-calendar-footer {
433
- margin-top: 12px;
434
- padding-top: 12px;
435
- border-top: 1px solid var(--lichta-border);
436
- }
437
- </style>
@@ -1,33 +0,0 @@
1
- import type { LunarDate } from '../core/types.js';
2
- import type { Snippet } from 'svelte';
3
- import type { Locale } from '../constants/i18n.js';
4
- /**
5
- * Dữ liệu cho mỗi ô ngày trong lưới lịch
6
- */
7
- interface DayCellData {
8
- solar: Date;
9
- lunar: LunarDate;
10
- isToday: boolean;
11
- isSelected: boolean;
12
- isCurrentMonth: boolean;
13
- }
14
- interface Props {
15
- /** Tháng hiển thị (1-12). Mặc định: tháng hiện tại */
16
- month?: number;
17
- /** Năm hiển thị. Mặc định: năm hiện tại */
18
- year?: number;
19
- /** Ngày được chọn */
20
- selectedDate?: Date | null;
21
- /** Callback khi chọn ngày */
22
- onSelect?: (date: Date, lunar: LunarDate) => void;
23
- /** Hiển thị ngày âm lịch bên dưới ngày dương */
24
- showLunar?: boolean;
25
- /** Locale (vi | en | ja | ko) */
26
- locale?: Locale;
27
- /** Custom snippet cho mỗi ô ngày */
28
- dayCell?: Snippet<[DayCellData]>;
29
- children?: Snippet;
30
- }
31
- declare const Calendar: import("svelte").Component<Props, {}, "">;
32
- type Calendar = ReturnType<typeof Calendar>;
33
- export default Calendar;
@@ -1,57 +0,0 @@
1
- <script lang="ts">
2
- import { LichTa } from '../core/lunar.js';
3
- import type { LunarDate } from '../core/types.js';
4
- import type { Snippet } from 'svelte';
5
-
6
- // Props nhận vào từ consumer ứng dụng
7
- interface Props {
8
- date?: Date;
9
- children?: Snippet;
10
- }
11
- let { date = new Date(), children }: Props = $props();
12
-
13
- // Khai báo biến reactive tự động tính toán lại khi `date` thay đổi
14
- let lunar: LunarDate = $derived.by(() => {
15
- const d = date.getDate();
16
- const m = date.getMonth() + 1; // Tháng trong JS tính từ 0
17
- const y = date.getFullYear();
18
- return LichTa.toLunar(d, m, y);
19
- });
20
- </script>
21
-
22
- <div class="lich-ta-formatter">
23
- <div class="lunar-display-banner">
24
- <span class="lunar-date">Ngày {lunar.day} tháng {lunar.month} (Âm lịch)</span>
25
- <span class="can-chi-details">Năm {lunar.yearCanChi}</span>
26
- </div>
27
-
28
- <div class="control-slot-wrapper">
29
- {@render children?.()}
30
- </div>
31
- </div>
32
-
33
- <style>
34
- .lich-ta-formatter {
35
- display: block;
36
- width: 100%;
37
- box-sizing: border-box;
38
- }
39
- .lunar-display-banner {
40
- padding: 12px;
41
- background-color: #fcfaf7;
42
- border-left: 4px solid #d4a373;
43
- margin-bottom: 16px;
44
- }
45
- .lunar-date {
46
- display: block;
47
- font-weight: bold;
48
- font-size: 1.1rem;
49
- color: #1a1a1a;
50
- }
51
- .can-chi-details {
52
- display: block;
53
- font-size: 0.9rem;
54
- color: #666666;
55
- margin-top: 4px;
56
- }
57
- </style>
@@ -1,8 +0,0 @@
1
- import type { Snippet } from 'svelte';
2
- interface Props {
3
- date?: Date;
4
- children?: Snippet;
5
- }
6
- declare const Formatter: import("svelte").Component<Props, {}, "">;
7
- type Formatter = ReturnType<typeof Formatter>;
8
- export default Formatter;
@@ -1,31 +0,0 @@
1
- /**
2
- * Earthly Branches (Địa Chi - 12 con giáp)
3
- * Tý | Rat (Chuột)
4
- * Sửu | Ox (Trâu)
5
- * Dần | Tiger (Cọp)
6
- * Mão | Rabbit (Thỏ)
7
- * Thìn | Dragon (Rồng)
8
- * Tỵ | Snake (Rắn)
9
- * Ngọ | Horse (Ngựa)
10
- * Mùi | Goat (Dê)
11
- * Thân | Monkey (Khỉ)
12
- * Dậu | Rooster (Gà)
13
- * Tuất | Dog (Chó)
14
- * Hợi | Pig (Heo)
15
- */
16
- export declare const EARTHLY_BRANCHES: readonly ["Tý", "Sửu", "Dần", "Mão", "Thìn", "Tỵ", "Ngọ", "Mùi", "Thân", "Dậu", "Tuất", "Hợi"];
17
- /**
18
- * Tính trọng số của Địa Chi (dùng để tính Ngũ Hành)
19
- * Chu kỳ lặp lại sau mỗi 6 Chi (index % 6)
20
- */
21
- export declare function getBranchWeight(index: number): number;
22
- /**
23
- * Tính Dương - Âm (Yin - Yang) cho Địa Chi
24
- * Index: 0 -> 1 (Dương) | 1 -> 0 (Âm) | ...
25
- */
26
- export declare function getBranchYinYang(index: number): 1 | 0;
27
- /**
28
- * Tính Ngũ Hành cho Địa Chi
29
- * Tý: 1 (Thủy Dương), Sửu: 12 (Thổ Âm), Dần: 3 (Mộc Dương), ...
30
- */
31
- export declare function getBranchElement(index: number): number;
@@ -1,42 +0,0 @@
1
- /**
2
- * Earthly Branches (Địa Chi - 12 con giáp)
3
- * Tý | Rat (Chuột)
4
- * Sửu | Ox (Trâu)
5
- * Dần | Tiger (Cọp)
6
- * Mão | Rabbit (Thỏ)
7
- * Thìn | Dragon (Rồng)
8
- * Tỵ | Snake (Rắn)
9
- * Ngọ | Horse (Ngựa)
10
- * Mùi | Goat (Dê)
11
- * Thân | Monkey (Khỉ)
12
- * Dậu | Rooster (Gà)
13
- * Tuất | Dog (Chó)
14
- * Hợi | Pig (Heo)
15
- */
16
- export const EARTHLY_BRANCHES = [
17
- 'Tý', 'Sửu', 'Dần', 'Mão', 'Thìn', 'Tỵ',
18
- 'Ngọ', 'Mùi', 'Thân', 'Dậu', 'Tuất', 'Hợi'
19
- ];
20
- /**
21
- * Tính trọng số của Địa Chi (dùng để tính Ngũ Hành)
22
- * Chu kỳ lặp lại sau mỗi 6 Chi (index % 6)
23
- */
24
- export function getBranchWeight(index) {
25
- const normalizedIndex = index % 6;
26
- return Math.floor(normalizedIndex / 2);
27
- }
28
- /**
29
- * Tính Dương - Âm (Yin - Yang) cho Địa Chi
30
- * Index: 0 -> 1 (Dương) | 1 -> 0 (Âm) | ...
31
- */
32
- export function getBranchYinYang(index) {
33
- return (index % 2 === 0) ? 1 : 0;
34
- }
35
- /**
36
- * Tính Ngũ Hành cho Địa Chi
37
- * Tý: 1 (Thủy Dương), Sửu: 12 (Thổ Âm), Dần: 3 (Mộc Dương), ...
38
- */
39
- export function getBranchElement(index) {
40
- const weight = Math.floor(index / 2) + 1;
41
- return weight === 5 ? 1 : weight;
42
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * Five Elements (Ngũ Hành)
3
- * Kim | Metal
4
- * Mộc | Wood
5
- * Thủy | Water
6
- * Hỏa | Fire
7
- * Thổ | Earth
8
- */
9
- export declare const FIVE_ELEMENTS: string[];
@@ -1,9 +0,0 @@
1
- /**
2
- * Five Elements (Ngũ Hành)
3
- * Kim | Metal
4
- * Mộc | Wood
5
- * Thủy | Water
6
- * Hỏa | Fire
7
- * Thổ | Earth
8
- */
9
- export const FIVE_ELEMENTS = ['Kim', 'Mộc', 'Thủy', 'Hỏa', 'Thổ'];
@@ -1,19 +0,0 @@
1
- /**
2
- * Heavenly Stems (Thiên Can)
3
- * Giáp (Dương) | Wood
4
- * Ất (Âm) | Wood
5
- * Bính (Dương) | Fire
6
- * Đinh (Âm) | Fire
7
- * Mậu (Dương) | Earth
8
- * Kỷ (Âm) | Earth
9
- * Canh (Dương) | Metal
10
- * Tân (Âm) | Metal
11
- * Nhâm (Dương) | Water
12
- * Quý (Âm) | Water
13
- */
14
- export declare const HEAVENLY_STEMS: readonly ["Giáp", "Ất", "Bính", "Đinh", "Mậu", "Kỷ", "Canh", "Tân", "Nhâm", "Quý"];
15
- /**
16
- * Tính trọng số của Thiên Can (dùng để tính Ngũ Hành)
17
- * Index: 0, 1 -> 1 | 2, 3 -> 2 | ... | 8, 9 -> 5
18
- */
19
- export declare function getStemWeight(index: number): number;
@@ -1,24 +0,0 @@
1
- /**
2
- * Heavenly Stems (Thiên Can)
3
- * Giáp (Dương) | Wood
4
- * Ất (Âm) | Wood
5
- * Bính (Dương) | Fire
6
- * Đinh (Âm) | Fire
7
- * Mậu (Dương) | Earth
8
- * Kỷ (Âm) | Earth
9
- * Canh (Dương) | Metal
10
- * Tân (Âm) | Metal
11
- * Nhâm (Dương) | Water
12
- * Quý (Âm) | Water
13
- */
14
- export const HEAVENLY_STEMS = [
15
- 'Giáp', 'Ất', 'Bính', 'Đinh', 'Mậu',
16
- 'Kỷ', 'Canh', 'Tân', 'Nhâm', 'Quý'
17
- ];
18
- /**
19
- * Tính trọng số của Thiên Can (dùng để tính Ngũ Hành)
20
- * Index: 0, 1 -> 1 | 2, 3 -> 2 | ... | 8, 9 -> 5
21
- */
22
- export function getStemWeight(index) {
23
- return Math.floor(index / 2) + 1;
24
- }