mingpan 0.1.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 (231) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +118 -0
  3. package/dist/core/bazi/BaziCore.d.ts +112 -0
  4. package/dist/core/bazi/BaziCore.d.ts.map +1 -0
  5. package/dist/core/bazi/BaziCore.js +606 -0
  6. package/dist/core/bazi/BaziCore.js.map +1 -0
  7. package/dist/core/bazi/SolarTermCalculator.d.ts +46 -0
  8. package/dist/core/bazi/SolarTermCalculator.d.ts.map +1 -0
  9. package/dist/core/bazi/SolarTermCalculator.js +452 -0
  10. package/dist/core/bazi/SolarTermCalculator.js.map +1 -0
  11. package/dist/core/bazi/TrueSolarTime.d.ts +64 -0
  12. package/dist/core/bazi/TrueSolarTime.d.ts.map +1 -0
  13. package/dist/core/bazi/TrueSolarTime.js +210 -0
  14. package/dist/core/bazi/TrueSolarTime.js.map +1 -0
  15. package/dist/core/bazi/ephemerisData.d.ts +10 -0
  16. package/dist/core/bazi/ephemerisData.d.ts.map +1 -0
  17. package/dist/core/bazi/ephemerisData.js +88 -0
  18. package/dist/core/bazi/ephemerisData.js.map +1 -0
  19. package/dist/core/bazi/index.d.ts +8 -0
  20. package/dist/core/bazi/index.d.ts.map +1 -0
  21. package/dist/core/bazi/index.js +30 -0
  22. package/dist/core/bazi/index.js.map +1 -0
  23. package/dist/core/bazi/types.d.ts +116 -0
  24. package/dist/core/bazi/types.d.ts.map +1 -0
  25. package/dist/core/bazi/types.js +7 -0
  26. package/dist/core/bazi/types.js.map +1 -0
  27. package/dist/core/calendar/SolarTermsCalculator.d.ts +33 -0
  28. package/dist/core/calendar/SolarTermsCalculator.d.ts.map +1 -0
  29. package/dist/core/calendar/SolarTermsCalculator.js +111 -0
  30. package/dist/core/calendar/SolarTermsCalculator.js.map +1 -0
  31. package/dist/core/calendar/astronomicalCalendar.d.ts +74 -0
  32. package/dist/core/calendar/astronomicalCalendar.d.ts.map +1 -0
  33. package/dist/core/calendar/astronomicalCalendar.js +276 -0
  34. package/dist/core/calendar/astronomicalCalendar.js.map +1 -0
  35. package/dist/core/calendar/calendar.d.ts +81 -0
  36. package/dist/core/calendar/calendar.d.ts.map +1 -0
  37. package/dist/core/calendar/calendar.js +223 -0
  38. package/dist/core/calendar/calendar.js.map +1 -0
  39. package/dist/core/calendar/constants.d.ts +151 -0
  40. package/dist/core/calendar/constants.d.ts.map +1 -0
  41. package/dist/core/calendar/constants.js +97 -0
  42. package/dist/core/calendar/constants.js.map +1 -0
  43. package/dist/core/calendar/julian.d.ts +54 -0
  44. package/dist/core/calendar/julian.d.ts.map +1 -0
  45. package/dist/core/calendar/julian.js +142 -0
  46. package/dist/core/calendar/julian.js.map +1 -0
  47. package/dist/core/calendar/lunarCalendar.d.ts +79 -0
  48. package/dist/core/calendar/lunarCalendar.d.ts.map +1 -0
  49. package/dist/core/calendar/lunarCalendar.js +164 -0
  50. package/dist/core/calendar/lunarCalendar.js.map +1 -0
  51. package/dist/core/calendar/solarTerms.d.ts +105 -0
  52. package/dist/core/calendar/solarTerms.d.ts.map +1 -0
  53. package/dist/core/calendar/solarTerms.js +487 -0
  54. package/dist/core/calendar/solarTerms.js.map +1 -0
  55. package/dist/core/constants/bazi.d.ts +138 -0
  56. package/dist/core/constants/bazi.d.ts.map +1 -0
  57. package/dist/core/constants/bazi.js +332 -0
  58. package/dist/core/constants/bazi.js.map +1 -0
  59. package/dist/core/constants/index.d.ts +6 -0
  60. package/dist/core/constants/index.d.ts.map +1 -0
  61. package/dist/core/constants/index.js +37 -0
  62. package/dist/core/constants/index.js.map +1 -0
  63. package/dist/core/constants/positions.d.ts +27 -0
  64. package/dist/core/constants/positions.d.ts.map +1 -0
  65. package/dist/core/constants/positions.js +39 -0
  66. package/dist/core/constants/positions.js.map +1 -0
  67. package/dist/core/ziwei/BrightnessSystem.d.ts +53 -0
  68. package/dist/core/ziwei/BrightnessSystem.d.ts.map +1 -0
  69. package/dist/core/ziwei/BrightnessSystem.js +278 -0
  70. package/dist/core/ziwei/BrightnessSystem.js.map +1 -0
  71. package/dist/core/ziwei/IztroAdapter.d.ts +78 -0
  72. package/dist/core/ziwei/IztroAdapter.d.ts.map +1 -0
  73. package/dist/core/ziwei/IztroAdapter.js +314 -0
  74. package/dist/core/ziwei/IztroAdapter.js.map +1 -0
  75. package/dist/core/ziwei/MutagenCore.d.ts +81 -0
  76. package/dist/core/ziwei/MutagenCore.d.ts.map +1 -0
  77. package/dist/core/ziwei/MutagenCore.js +246 -0
  78. package/dist/core/ziwei/MutagenCore.js.map +1 -0
  79. package/dist/index.d.ts +13 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +1101 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/output/fortuneTextRenderer.d.ts +63 -0
  84. package/dist/output/fortuneTextRenderer.d.ts.map +1 -0
  85. package/dist/output/fortuneTextRenderer.js +384 -0
  86. package/dist/output/fortuneTextRenderer.js.map +1 -0
  87. package/dist/output/listTextRenderer.d.ts +298 -0
  88. package/dist/output/listTextRenderer.d.ts.map +1 -0
  89. package/dist/output/listTextRenderer.js +942 -0
  90. package/dist/output/listTextRenderer.js.map +1 -0
  91. package/dist/services/bazi/BaziService.d.ts +83 -0
  92. package/dist/services/bazi/BaziService.d.ts.map +1 -0
  93. package/dist/services/bazi/BaziService.js +635 -0
  94. package/dist/services/bazi/BaziService.js.map +1 -0
  95. package/dist/services/bazi/analyzers/ClimateAnalyzer.d.ts +31 -0
  96. package/dist/services/bazi/analyzers/ClimateAnalyzer.d.ts.map +1 -0
  97. package/dist/services/bazi/analyzers/ClimateAnalyzer.js +194 -0
  98. package/dist/services/bazi/analyzers/ClimateAnalyzer.js.map +1 -0
  99. package/dist/services/bazi/analyzers/HiddenStemsAnalyzer.d.ts +16 -0
  100. package/dist/services/bazi/analyzers/HiddenStemsAnalyzer.d.ts.map +1 -0
  101. package/dist/services/bazi/analyzers/HiddenStemsAnalyzer.js +60 -0
  102. package/dist/services/bazi/analyzers/HiddenStemsAnalyzer.js.map +1 -0
  103. package/dist/services/bazi/analyzers/NaYinAnalyzer.d.ts +33 -0
  104. package/dist/services/bazi/analyzers/NaYinAnalyzer.d.ts.map +1 -0
  105. package/dist/services/bazi/analyzers/NaYinAnalyzer.js +209 -0
  106. package/dist/services/bazi/analyzers/NaYinAnalyzer.js.map +1 -0
  107. package/dist/services/bazi/analyzers/PatternAnalyzer.d.ts +159 -0
  108. package/dist/services/bazi/analyzers/PatternAnalyzer.d.ts.map +1 -0
  109. package/dist/services/bazi/analyzers/PatternAnalyzer.js +1150 -0
  110. package/dist/services/bazi/analyzers/PatternAnalyzer.js.map +1 -0
  111. package/dist/services/bazi/analyzers/RelationsAnalyzer.d.ts +114 -0
  112. package/dist/services/bazi/analyzers/RelationsAnalyzer.d.ts.map +1 -0
  113. package/dist/services/bazi/analyzers/RelationsAnalyzer.js +704 -0
  114. package/dist/services/bazi/analyzers/RelationsAnalyzer.js.map +1 -0
  115. package/dist/services/bazi/analyzers/ShenShaAnalyzer.d.ts +236 -0
  116. package/dist/services/bazi/analyzers/ShenShaAnalyzer.d.ts.map +1 -0
  117. package/dist/services/bazi/analyzers/ShenShaAnalyzer.js +2079 -0
  118. package/dist/services/bazi/analyzers/ShenShaAnalyzer.js.map +1 -0
  119. package/dist/services/bazi/analyzers/StrengthAnalyzer.d.ts +181 -0
  120. package/dist/services/bazi/analyzers/StrengthAnalyzer.d.ts.map +1 -0
  121. package/dist/services/bazi/analyzers/StrengthAnalyzer.js +1119 -0
  122. package/dist/services/bazi/analyzers/StrengthAnalyzer.js.map +1 -0
  123. package/dist/services/bazi/analyzers/TenGodsAnalyzer.d.ts +78 -0
  124. package/dist/services/bazi/analyzers/TenGodsAnalyzer.d.ts.map +1 -0
  125. package/dist/services/bazi/analyzers/TenGodsAnalyzer.js +383 -0
  126. package/dist/services/bazi/analyzers/TenGodsAnalyzer.js.map +1 -0
  127. package/dist/services/bazi/analyzers/TraditionalAnalyzer.d.ts +46 -0
  128. package/dist/services/bazi/analyzers/TraditionalAnalyzer.d.ts.map +1 -0
  129. package/dist/services/bazi/analyzers/TraditionalAnalyzer.js +260 -0
  130. package/dist/services/bazi/analyzers/TraditionalAnalyzer.js.map +1 -0
  131. package/dist/services/bazi/analyzers/YongShenAnalyzer.d.ts +70 -0
  132. package/dist/services/bazi/analyzers/YongShenAnalyzer.d.ts.map +1 -0
  133. package/dist/services/bazi/analyzers/YongShenAnalyzer.js +858 -0
  134. package/dist/services/bazi/analyzers/YongShenAnalyzer.js.map +1 -0
  135. package/dist/services/bazi/calculators/DaYunCalculator.d.ts +71 -0
  136. package/dist/services/bazi/calculators/DaYunCalculator.d.ts.map +1 -0
  137. package/dist/services/bazi/calculators/DaYunCalculator.js +496 -0
  138. package/dist/services/bazi/calculators/DaYunCalculator.js.map +1 -0
  139. package/dist/services/bazi/calculators/LiuNianCalculator.d.ts +88 -0
  140. package/dist/services/bazi/calculators/LiuNianCalculator.d.ts.map +1 -0
  141. package/dist/services/bazi/calculators/LiuNianCalculator.js +546 -0
  142. package/dist/services/bazi/calculators/LiuNianCalculator.js.map +1 -0
  143. package/dist/services/bazi/calculators/LiuRiCalculator.d.ts +66 -0
  144. package/dist/services/bazi/calculators/LiuRiCalculator.d.ts.map +1 -0
  145. package/dist/services/bazi/calculators/LiuRiCalculator.js +497 -0
  146. package/dist/services/bazi/calculators/LiuRiCalculator.js.map +1 -0
  147. package/dist/services/bazi/calculators/LiuYueCalculator.d.ts +50 -0
  148. package/dist/services/bazi/calculators/LiuYueCalculator.d.ts.map +1 -0
  149. package/dist/services/bazi/calculators/LiuYueCalculator.js +338 -0
  150. package/dist/services/bazi/calculators/LiuYueCalculator.js.map +1 -0
  151. package/dist/services/bazi/calculators/LuckCycleCalculator.d.ts +123 -0
  152. package/dist/services/bazi/calculators/LuckCycleCalculator.d.ts.map +1 -0
  153. package/dist/services/bazi/calculators/LuckCycleCalculator.js +414 -0
  154. package/dist/services/bazi/calculators/LuckCycleCalculator.js.map +1 -0
  155. package/dist/services/bazi/index.d.ts +21 -0
  156. package/dist/services/bazi/index.d.ts.map +1 -0
  157. package/dist/services/bazi/index.js +83 -0
  158. package/dist/services/bazi/index.js.map +1 -0
  159. package/dist/services/bazi/types.d.ts +597 -0
  160. package/dist/services/bazi/types.d.ts.map +1 -0
  161. package/dist/services/bazi/types.js +123 -0
  162. package/dist/services/bazi/types.js.map +1 -0
  163. package/dist/services/ziwei/ZiweiService.d.ts +86 -0
  164. package/dist/services/ziwei/ZiweiService.d.ts.map +1 -0
  165. package/dist/services/ziwei/ZiweiService.js +343 -0
  166. package/dist/services/ziwei/ZiweiService.js.map +1 -0
  167. package/dist/services/ziwei/calculators/BrightnessCalculator.d.ts +38 -0
  168. package/dist/services/ziwei/calculators/BrightnessCalculator.d.ts.map +1 -0
  169. package/dist/services/ziwei/calculators/BrightnessCalculator.js +142 -0
  170. package/dist/services/ziwei/calculators/BrightnessCalculator.js.map +1 -0
  171. package/dist/services/ziwei/calculators/DailyCalculator.d.ts +27 -0
  172. package/dist/services/ziwei/calculators/DailyCalculator.d.ts.map +1 -0
  173. package/dist/services/ziwei/calculators/DailyCalculator.js +55 -0
  174. package/dist/services/ziwei/calculators/DailyCalculator.js.map +1 -0
  175. package/dist/services/ziwei/calculators/DecadeCalculator.d.ts +46 -0
  176. package/dist/services/ziwei/calculators/DecadeCalculator.d.ts.map +1 -0
  177. package/dist/services/ziwei/calculators/DecadeCalculator.js +181 -0
  178. package/dist/services/ziwei/calculators/DecadeCalculator.js.map +1 -0
  179. package/dist/services/ziwei/calculators/HoroscopeStarsCalculator.d.ts +28 -0
  180. package/dist/services/ziwei/calculators/HoroscopeStarsCalculator.d.ts.map +1 -0
  181. package/dist/services/ziwei/calculators/HoroscopeStarsCalculator.js +84 -0
  182. package/dist/services/ziwei/calculators/HoroscopeStarsCalculator.js.map +1 -0
  183. package/dist/services/ziwei/calculators/HourlyCalculator.d.ts +41 -0
  184. package/dist/services/ziwei/calculators/HourlyCalculator.d.ts.map +1 -0
  185. package/dist/services/ziwei/calculators/HourlyCalculator.js +139 -0
  186. package/dist/services/ziwei/calculators/HourlyCalculator.js.map +1 -0
  187. package/dist/services/ziwei/calculators/MinorLimitCalculator.d.ts +30 -0
  188. package/dist/services/ziwei/calculators/MinorLimitCalculator.d.ts.map +1 -0
  189. package/dist/services/ziwei/calculators/MinorLimitCalculator.js +90 -0
  190. package/dist/services/ziwei/calculators/MinorLimitCalculator.js.map +1 -0
  191. package/dist/services/ziwei/calculators/MonthlyCalculator.d.ts +39 -0
  192. package/dist/services/ziwei/calculators/MonthlyCalculator.d.ts.map +1 -0
  193. package/dist/services/ziwei/calculators/MonthlyCalculator.js +128 -0
  194. package/dist/services/ziwei/calculators/MonthlyCalculator.js.map +1 -0
  195. package/dist/services/ziwei/calculators/MutagenCalculator.d.ts +20 -0
  196. package/dist/services/ziwei/calculators/MutagenCalculator.d.ts.map +1 -0
  197. package/dist/services/ziwei/calculators/MutagenCalculator.js +121 -0
  198. package/dist/services/ziwei/calculators/MutagenCalculator.js.map +1 -0
  199. package/dist/services/ziwei/calculators/PalaceDynamicCalculator.d.ts +35 -0
  200. package/dist/services/ziwei/calculators/PalaceDynamicCalculator.d.ts.map +1 -0
  201. package/dist/services/ziwei/calculators/PalaceDynamicCalculator.js +55 -0
  202. package/dist/services/ziwei/calculators/PalaceDynamicCalculator.js.map +1 -0
  203. package/dist/services/ziwei/calculators/YearlyCalculator.d.ts +35 -0
  204. package/dist/services/ziwei/calculators/YearlyCalculator.d.ts.map +1 -0
  205. package/dist/services/ziwei/calculators/YearlyCalculator.js +119 -0
  206. package/dist/services/ziwei/calculators/YearlyCalculator.js.map +1 -0
  207. package/dist/services/ziwei/index.d.ts +15 -0
  208. package/dist/services/ziwei/index.d.ts.map +1 -0
  209. package/dist/services/ziwei/index.js +48 -0
  210. package/dist/services/ziwei/index.js.map +1 -0
  211. package/dist/services/ziwei/transformers/PalaceTransformer.d.ts +62 -0
  212. package/dist/services/ziwei/transformers/PalaceTransformer.d.ts.map +1 -0
  213. package/dist/services/ziwei/transformers/PalaceTransformer.js +153 -0
  214. package/dist/services/ziwei/transformers/PalaceTransformer.js.map +1 -0
  215. package/dist/services/ziwei/types.d.ts +185 -0
  216. package/dist/services/ziwei/types.d.ts.map +1 -0
  217. package/dist/services/ziwei/types.js +54 -0
  218. package/dist/services/ziwei/types.js.map +1 -0
  219. package/dist/shared/logger.d.ts +51 -0
  220. package/dist/shared/logger.d.ts.map +1 -0
  221. package/dist/shared/logger.js +136 -0
  222. package/dist/shared/logger.js.map +1 -0
  223. package/dist/shared/types.d.ts +91 -0
  224. package/dist/shared/types.d.ts.map +1 -0
  225. package/dist/shared/types.js +7 -0
  226. package/dist/shared/types.js.map +1 -0
  227. package/dist/utils/ageCalculator.d.ts +30 -0
  228. package/dist/utils/ageCalculator.d.ts.map +1 -0
  229. package/dist/utils/ageCalculator.js +51 -0
  230. package/dist/utils/ageCalculator.js.map +1 -0
  231. package/package.json +54 -0
@@ -0,0 +1,942 @@
1
+ "use strict";
2
+ /**
3
+ * 運勢列表文本渲染器
4
+ * 遵循 fortune-list-api-design.md v1.1.0 設計規範
5
+ *
6
+ * 核心區分:
7
+ * - 八字流月 = 干支月(節氣月):以節氣為邊界,寅月~丑月
8
+ * - 紫微流月 = 農曆月:以農曆初一為邊界,正月~臘月
9
+ *
10
+ * 統一輸出頭設計原則(v1.3.0):
11
+ * - 所有工具首先輸出 === 命主資料 === 和 === 命盤 === 基礎資訊
12
+ * - 命主資料包含公曆和農曆生日信息
13
+ * - 每個工具根據時間層級(大運/大限 → 流年 → 流月 → 流日)分區塊輸出上層資訊
14
+ * - 保持與 fortuneTextRenderer.ts 的格式一致性
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.renderBaziDaYunList = renderBaziDaYunList;
18
+ exports.renderBaziLiuNianList = renderBaziLiuNianList;
19
+ exports.renderBaziLiuYueList = renderBaziLiuYueList;
20
+ exports.renderBaziLiuRiList = renderBaziLiuRiList;
21
+ exports.renderZiweiDaXianList = renderZiweiDaXianList;
22
+ exports.renderZiweiXiaoXianList = renderZiweiXiaoXianList;
23
+ exports.renderZiweiLiuNianList = renderZiweiLiuNianList;
24
+ exports.renderZiweiLiuYueList = renderZiweiLiuYueList;
25
+ exports.renderZiweiLiuRiList = renderZiweiLiuRiList;
26
+ const types_1 = require("../services/ziwei/types");
27
+ const lunar_javascript_1 = require("lunar-javascript");
28
+ const MutagenCore_1 = require("../core/ziwei/MutagenCore");
29
+ // ==================== 輔助函數 ====================
30
+ /**
31
+ * 格式化日期為 YYYY-MM-DD
32
+ */
33
+ function formatDate(date) {
34
+ const year = date.getFullYear();
35
+ const month = (date.getMonth() + 1).toString().padStart(2, '0');
36
+ const day = date.getDate().toString().padStart(2, '0');
37
+ return `${year}-${month}-${day}`;
38
+ }
39
+ /**
40
+ * 格式化日期時間(包含時分)
41
+ */
42
+ function formatDateTime(date) {
43
+ const dateStr = formatDate(date);
44
+ const hour = date.getHours().toString().padStart(2, '0');
45
+ const minute = date.getMinutes().toString().padStart(2, '0');
46
+ return `${dateStr} ${hour}:${minute}`;
47
+ }
48
+ /**
49
+ * 根據公曆年份計算干支年
50
+ */
51
+ function getGanzhi(year) {
52
+ const STEMS = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'];
53
+ const BRANCHES = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];
54
+ // 1984年是甲子年
55
+ const baseYear = 1984;
56
+ const yearDiff = year - baseYear;
57
+ const stemIndex = ((yearDiff % 10) + 10) % 10;
58
+ const branchIndex = ((yearDiff % 12) + 12) % 12;
59
+ return STEMS[stemIndex] + BRANCHES[branchIndex];
60
+ }
61
+ /**
62
+ * 農曆月份名稱
63
+ */
64
+ const LUNAR_MONTH_NAMES = [
65
+ '', '正月', '二月', '三月', '四月', '五月', '六月',
66
+ '七月', '八月', '九月', '十月', '冬月', '臘月'
67
+ ];
68
+ /**
69
+ * 農曆日期名稱
70
+ */
71
+ function getLunarDayName(day) {
72
+ const DAYS1 = ['初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十'];
73
+ const DAYS2 = ['十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十'];
74
+ const DAYS3 = ['廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十'];
75
+ if (day <= 10)
76
+ return DAYS1[day - 1];
77
+ if (day <= 20)
78
+ return DAYS2[day - 11];
79
+ return DAYS3[day - 21];
80
+ }
81
+ /**
82
+ * 時辰名稱映射(小時 -> 時辰)
83
+ */
84
+ const HOUR_TO_SHICHEN = {
85
+ 23: '子時', 0: '子時',
86
+ 1: '丑時', 2: '丑時',
87
+ 3: '寅時', 4: '寅時',
88
+ 5: '卯時', 6: '卯時',
89
+ 7: '辰時', 8: '辰時',
90
+ 9: '巳時', 10: '巳時',
91
+ 11: '午時', 12: '午時',
92
+ 13: '未時', 14: '未時',
93
+ 15: '申時', 16: '申時',
94
+ 17: '酉時', 18: '酉時',
95
+ 19: '戌時', 20: '戌時',
96
+ 21: '亥時', 22: '亥時'
97
+ };
98
+ /**
99
+ * 獲取時辰名稱
100
+ */
101
+ function getShichenName(hour) {
102
+ return HOUR_TO_SHICHEN[hour] || '未知時';
103
+ }
104
+ /**
105
+ * 格式化農曆生日信息
106
+ * 格式:干支年+農曆月+農曆日+時辰(如:乙丑年正月廿三午時)
107
+ */
108
+ function formatLunarBirthday(birthYear, birthMonth, birthDay, birthHour) {
109
+ try {
110
+ const solar = lunar_javascript_1.Solar.fromYmd(birthYear, birthMonth, birthDay);
111
+ const lunar = solar.getLunar();
112
+ const yearGanzhi = lunar.getYearInGanZhi();
113
+ const lunarMonth = lunar.getMonth();
114
+ const lunarDay = lunar.getDay();
115
+ const isLeapMonth = lunar.getMonth() < 0;
116
+ const monthName = LUNAR_MONTH_NAMES[Math.abs(lunarMonth)] || `${Math.abs(lunarMonth)}月`;
117
+ const leapPrefix = isLeapMonth ? '閏' : '';
118
+ const dayName = getLunarDayName(lunarDay);
119
+ const shichen = getShichenName(birthHour);
120
+ return `${yearGanzhi}年${leapPrefix}${monthName}${dayName}${shichen}`;
121
+ }
122
+ catch (e) {
123
+ return '';
124
+ }
125
+ }
126
+ /**
127
+ * 節氣起止資訊
128
+ */
129
+ const SOLAR_TERM_MONTHS = {
130
+ 1: { term: '立春', nextTerm: '惊蛰' },
131
+ 2: { term: '惊蛰', nextTerm: '清明' },
132
+ 3: { term: '清明', nextTerm: '立夏' },
133
+ 4: { term: '立夏', nextTerm: '芒种' },
134
+ 5: { term: '芒种', nextTerm: '小暑' },
135
+ 6: { term: '小暑', nextTerm: '立秋' },
136
+ 7: { term: '立秋', nextTerm: '白露' },
137
+ 8: { term: '白露', nextTerm: '寒露' },
138
+ 9: { term: '寒露', nextTerm: '立冬' },
139
+ 10: { term: '立冬', nextTerm: '大雪' },
140
+ 11: { term: '大雪', nextTerm: '小寒' },
141
+ 12: { term: '小寒', nextTerm: '立春' }
142
+ };
143
+ /**
144
+ * 渲染八字統一頭部
145
+ * 格式:=== 命主資料 === + === 八字命盤 ===
146
+ */
147
+ function renderBaziBaseHeader(options) {
148
+ const lines = [];
149
+ const genderText = options.gender === 'male' ? '男' : '女';
150
+ const pad = (n) => String(n).padStart(2, '0');
151
+ const dateTimeStr = `${options.birthYear}-${pad(options.birthMonth)}-${pad(options.birthDay)} ${pad(options.birthHour)}:${pad(options.birthMinute || 0)}:00`;
152
+ const lunarBirthday = formatLunarBirthday(options.birthYear, options.birthMonth, options.birthDay, options.birthHour);
153
+ lines.push('=== 命主資料 ===');
154
+ lines.push(`性別:${genderText}`);
155
+ lines.push(`公曆:${dateTimeStr}`);
156
+ if (lunarBirthday) {
157
+ lines.push(`農曆:${lunarBirthday}`);
158
+ }
159
+ lines.push('');
160
+ lines.push('=== 八字命盤 ===');
161
+ if (options.yearPillar && options.monthPillar && options.dayPillar && options.hourPillar) {
162
+ lines.push(`年柱:${options.yearPillar.stem}${options.yearPillar.branch} 月柱:${options.monthPillar.stem}${options.monthPillar.branch} 日柱:${options.dayPillar.stem}${options.dayPillar.branch} 時柱:${options.hourPillar.stem}${options.hourPillar.branch}`);
163
+ }
164
+ lines.push(`日主:${options.dayMaster}`);
165
+ lines.push('');
166
+ return lines;
167
+ }
168
+ /**
169
+ * 渲染紫微統一頭部
170
+ * 格式:=== 命主資料 === + === 紫微命盘 ===
171
+ */
172
+ function renderZiweiBaseHeader(options) {
173
+ const lines = [];
174
+ const genderText = options.gender === 'male' ? '男' : '女';
175
+ const pad = (n) => String(n).padStart(2, '0');
176
+ const dateTimeStr = `${options.birthYear}-${pad(options.birthMonth)}-${pad(options.birthDay)} ${pad(options.birthHour)}:${pad(options.birthMinute || 0)}:00`;
177
+ const lunarBirthday = formatLunarBirthday(options.birthYear, options.birthMonth, options.birthDay, options.birthHour);
178
+ lines.push('=== 命主資料 ===');
179
+ lines.push(`性別:${genderText}`);
180
+ lines.push(`公曆:${dateTimeStr}`);
181
+ if (lunarBirthday) {
182
+ lines.push(`農曆:${lunarBirthday}`);
183
+ }
184
+ lines.push('');
185
+ lines.push('=== 紫微命盘 ===');
186
+ const hb = (options.mingGongHeavenlyStem && options.mingGongEarthlyBranch)
187
+ ? ` ${options.mingGongHeavenlyStem}${options.mingGongEarthlyBranch}`
188
+ : '';
189
+ const starsText = options.mingGongStars.length > 0
190
+ ? options.mingGongStars.join('、')
191
+ : '無主星';
192
+ lines.push(`本命命宮${hb}:${starsText}`);
193
+ lines.push(`本命身宮:${options.shenGong || '命宮'}`);
194
+ lines.push('');
195
+ return lines;
196
+ }
197
+ /**
198
+ * 格式化四化資訊為文本行(用於統一頭部)
199
+ */
200
+ function formatMutagenLineForHeader(label, info) {
201
+ if (!info)
202
+ return '';
203
+ const parts = [];
204
+ if (info.lu)
205
+ parts.push(`化祿-${info.lu}`);
206
+ if (info.quan)
207
+ parts.push(`化權-${info.quan}`);
208
+ if (info.ke)
209
+ parts.push(`化科-${info.ke}`);
210
+ if (info.ji)
211
+ parts.push(`化忌-${info.ji}`);
212
+ return parts.length ? `${label}:${parts.join(' ')}` : '';
213
+ }
214
+ /**
215
+ * 渲染八字大運列表
216
+ * 統一頭部格式:=== 命主資料 === + === 八字命盤 === + === 大運資訊 ===
217
+ */
218
+ function renderBaziDaYunList(daYunList, options) {
219
+ const lines = [];
220
+ if (options.yearPillar && options.monthPillar && options.dayPillar && options.hourPillar) {
221
+ lines.push(...renderBaziBaseHeader(options));
222
+ }
223
+ else {
224
+ const genderText = options.gender === 'male' ? '男' : '女';
225
+ const pad = (n) => String(n).padStart(2, '0');
226
+ const dateTimeStr = `${options.birthYear}-${pad(options.birthMonth)}-${pad(options.birthDay)} ${pad(options.birthHour)}:${pad(options.birthMinute || 0)}:00`;
227
+ const lunarBirthday = formatLunarBirthday(options.birthYear, options.birthMonth, options.birthDay, options.birthHour);
228
+ lines.push('=== 命主資料 ===');
229
+ lines.push(`性別:${genderText}`);
230
+ lines.push(`公曆:${dateTimeStr}`);
231
+ if (lunarBirthday) {
232
+ lines.push(`農曆:${lunarBirthday}`);
233
+ }
234
+ lines.push('');
235
+ lines.push('=== 八字命盤 ===');
236
+ lines.push(`日主:${options.dayMaster}`);
237
+ lines.push('');
238
+ }
239
+ lines.push('=== 大運資訊 ===');
240
+ lines.push(`大運方向:${options.direction}`);
241
+ lines.push(`起運年齡:${options.startAge}周歲(${options.startYear}年起運)`);
242
+ lines.push('');
243
+ lines.push('序號 | 大運干支 | 起止虛歲 | 起止公曆年');
244
+ lines.push('-----|---------|---------|----------');
245
+ for (const daYun of daYunList) {
246
+ const index = (daYun.index + 1).toString().padStart(3, ' ');
247
+ const ganzhi = daYun.stem + daYun.branch;
248
+ const ageRange = `${daYun.startAge}-${daYun.endAge}歲`;
249
+ const yearRange = `${daYun.startYear}-${daYun.endYear}年`;
250
+ lines.push(`${index} | ${ganzhi.padEnd(6, ' ')} | ${ageRange.padEnd(8, ' ')} | ${yearRange}`);
251
+ }
252
+ return lines.join('\n');
253
+ }
254
+ /**
255
+ * 渲染八字流年列表
256
+ * 統一頭部格式:=== 命主資料 === + === 八字命盤 === + === 流年資訊 ===
257
+ */
258
+ function renderBaziLiuNianList(liuNianList, options) {
259
+ const lines = [];
260
+ if (options.yearPillar && options.monthPillar && options.dayPillar && options.hourPillar) {
261
+ lines.push(...renderBaziBaseHeader(options));
262
+ }
263
+ else {
264
+ const genderText = options.gender === 'male' ? '男' : '女';
265
+ const pad = (n) => String(n).padStart(2, '0');
266
+ const dateTimeStr = `${options.birthYear}-${pad(options.birthMonth)}-${pad(options.birthDay)} ${pad(options.birthHour)}:${pad(options.birthMinute || 0)}:00`;
267
+ const lunarBirthday = formatLunarBirthday(options.birthYear, options.birthMonth, options.birthDay, options.birthHour);
268
+ lines.push('=== 命主資料 ===');
269
+ lines.push(`性別:${genderText}`);
270
+ lines.push(`公曆:${dateTimeStr}`);
271
+ if (lunarBirthday) {
272
+ lines.push(`農曆:${lunarBirthday}`);
273
+ }
274
+ lines.push('');
275
+ lines.push('=== 八字命盤 ===');
276
+ lines.push(`日主:${options.dayMaster}`);
277
+ lines.push('');
278
+ }
279
+ lines.push('=== 流年資訊 ===');
280
+ lines.push(`查詢範圍:${options.startYear}-${options.endYear}年`);
281
+ lines.push('');
282
+ lines.push('公曆年 | 干支年 | 虛歲 | 所屬大運');
283
+ lines.push('-------|-------|------|--------');
284
+ for (const liuNian of liuNianList) {
285
+ const year = `${liuNian.year}年`;
286
+ const ganzhi = `${liuNian.stem}${liuNian.branch}年`;
287
+ const age = `${liuNian.age}歲`;
288
+ let daYunLabel = '-';
289
+ if (options.daYunList && options.daYunList.length > 0) {
290
+ const matchedDaYun = options.daYunList.find(dy => liuNian.age >= dy.startAge && liuNian.age <= dy.endAge);
291
+ if (matchedDaYun) {
292
+ daYunLabel = `${matchedDaYun.stem}${matchedDaYun.branch}(${matchedDaYun.startAge}-${matchedDaYun.endAge}歲)`;
293
+ }
294
+ }
295
+ lines.push(`${year} | ${ganzhi} | ${age.padEnd(5, ' ')} | ${daYunLabel}`);
296
+ }
297
+ return lines.join('\n');
298
+ }
299
+ /**
300
+ * 渲染八字流月列表(干支月/節氣月)
301
+ * 統一頭部格式:=== 命主資料 === + === 八字命盤 === + === 大運資訊 === + === 流年資訊 === + === 流月列表 ===
302
+ */
303
+ function renderBaziLiuYueList(liuYueList, options) {
304
+ const lines = [];
305
+ if (options.yearPillar && options.monthPillar && options.dayPillar && options.hourPillar) {
306
+ lines.push(...renderBaziBaseHeader(options));
307
+ }
308
+ else {
309
+ const genderText = options.gender === 'male' ? '男' : '女';
310
+ const pad = (n) => String(n).padStart(2, '0');
311
+ const dateTimeStr = `${options.birthYear}-${pad(options.birthMonth)}-${pad(options.birthDay)} ${pad(options.birthHour)}:${pad(options.birthMinute || 0)}:00`;
312
+ const lunarBirthday = formatLunarBirthday(options.birthYear, options.birthMonth, options.birthDay, options.birthHour);
313
+ lines.push('=== 命主資料 ===');
314
+ lines.push(`性別:${genderText}`);
315
+ lines.push(`公曆:${dateTimeStr}`);
316
+ if (lunarBirthday) {
317
+ lines.push(`農曆:${lunarBirthday}`);
318
+ }
319
+ lines.push('');
320
+ lines.push('=== 八字命盤 ===');
321
+ lines.push(`日主:${options.dayMaster}`);
322
+ lines.push('');
323
+ }
324
+ if (options.currentDaYun) {
325
+ lines.push('=== 大運資訊 ===');
326
+ lines.push(`當前大運:${options.currentDaYun.stem}${options.currentDaYun.branch}(${options.currentDaYun.startAge}-${options.currentDaYun.endAge}歲)`);
327
+ lines.push('');
328
+ }
329
+ if (options.currentLiuNian) {
330
+ lines.push('=== 流年資訊 ===');
331
+ lines.push(`當前流年:${options.currentLiuNian.stem}${options.currentLiuNian.branch}年(${options.currentLiuNian.age}歲)`);
332
+ lines.push(`干支年:${options.ganzhiYear}年(公曆${options.gregorianYear}年)`);
333
+ lines.push('');
334
+ }
335
+ lines.push('=== 流月列表 ===');
336
+ lines.push('');
337
+ lines.push('序號 | 干支月 | 節氣起止 | 公曆日期範圍');
338
+ lines.push('-----|-------|---------|-------------');
339
+ for (const liuYue of liuYueList) {
340
+ const index = liuYue.month.toString().padStart(3, ' ');
341
+ const ganzhi = `${liuYue.stem}${liuYue.branch}月`;
342
+ const solarTermInfo = SOLAR_TERM_MONTHS[liuYue.month] || { term: '-', nextTerm: '-' };
343
+ const solarTermRange = `${solarTermInfo.term}-${solarTermInfo.nextTerm}`;
344
+ const dateRange = `${formatDate(liuYue.startDate)} ~ ${formatDate(liuYue.endDate)}`;
345
+ lines.push(`${index} | ${ganzhi.padEnd(5, ' ')} | ${solarTermRange.padEnd(8, ' ')} | ${dateRange}`);
346
+ }
347
+ const lastMonth = liuYueList[liuYueList.length - 1];
348
+ if (lastMonth && lastMonth.endDate.getFullYear() > options.gregorianYear) {
349
+ lines.push('');
350
+ lines.push(`注:${lastMonth.stem}${lastMonth.branch}月雖然公曆日期在${lastMonth.endDate.getFullYear()}年,但仍屬於${options.ganzhiYear}干支年。`);
351
+ }
352
+ return lines.join('\n');
353
+ }
354
+ /**
355
+ * 渲染八字流日列表
356
+ * 統一頭部格式:=== 命主資料 === + === 八字命盤 === + === 大運資訊 === + === 流年資訊 === + === 流月資訊 === + === 流日列表 ===
357
+ */
358
+ function renderBaziLiuRiList(liuRiList, options) {
359
+ const lines = [];
360
+ if (options.yearPillar && options.monthPillar && options.dayPillar && options.hourPillar) {
361
+ lines.push(...renderBaziBaseHeader(options));
362
+ }
363
+ else {
364
+ const genderText = options.gender === 'male' ? '男' : '女';
365
+ const pad = (n) => String(n).padStart(2, '0');
366
+ const dateTimeStr = `${options.birthYear}-${pad(options.birthMonth)}-${pad(options.birthDay)} ${pad(options.birthHour)}:${pad(options.birthMinute || 0)}:00`;
367
+ const lunarBirthday = formatLunarBirthday(options.birthYear, options.birthMonth, options.birthDay, options.birthHour);
368
+ lines.push('=== 命主資料 ===');
369
+ lines.push(`性別:${genderText}`);
370
+ lines.push(`公曆:${dateTimeStr}`);
371
+ if (lunarBirthday) {
372
+ lines.push(`農曆:${lunarBirthday}`);
373
+ }
374
+ lines.push('');
375
+ lines.push('=== 八字命盤 ===');
376
+ lines.push(`日主:${options.dayMaster}`);
377
+ lines.push('');
378
+ }
379
+ if (options.currentDaYun) {
380
+ lines.push('=== 大運資訊 ===');
381
+ lines.push(`當前大運:${options.currentDaYun.stem}${options.currentDaYun.branch}(${options.currentDaYun.startAge}-${options.currentDaYun.endAge}歲)`);
382
+ lines.push('');
383
+ }
384
+ if (options.currentLiuNian) {
385
+ lines.push('=== 流年資訊 ===');
386
+ lines.push(`當前流年:${options.currentLiuNian.stem}${options.currentLiuNian.branch}年(${options.currentLiuNian.age}歲)`);
387
+ lines.push('');
388
+ }
389
+ if (options.currentLiuYue) {
390
+ lines.push('=== 流月資訊 ===');
391
+ lines.push(`當前流月:${options.currentLiuYue.stem}${options.currentLiuYue.branch}月(第${options.currentLiuYue.month}月)`);
392
+ lines.push(`干支月:${options.ganzhiMonth}月(${options.ganzhiYear}年,公曆${formatDate(options.startDate)} ~ ${formatDate(options.endDate)})`);
393
+ lines.push('');
394
+ }
395
+ lines.push('=== 流日列表 ===');
396
+ lines.push('');
397
+ lines.push('公曆日期 | 干支日');
398
+ lines.push('---------|-------');
399
+ for (const liuRi of liuRiList) {
400
+ const dateStr = formatDate(liuRi.date);
401
+ const ganzhi = `${liuRi.stem}${liuRi.branch}日`;
402
+ lines.push(`${dateStr} | ${ganzhi}`);
403
+ }
404
+ lines.push('');
405
+ lines.push(`共${liuRiList.length}日`);
406
+ return lines.join('\n');
407
+ }
408
+ /**
409
+ * 根據palaceIndex獲取宮位主星
410
+ * 更健壯的查找邏輯:先嘗試index匹配,再嘗試陣列索引
411
+ */
412
+ function getPalaceStars(palaces, palaceIndex) {
413
+ if (!palaces || palaces.length === 0)
414
+ return '-';
415
+ // 方法1:通過index屬性匹配
416
+ let palace = palaces.find(p => p.index === palaceIndex);
417
+ // 方法2:如果沒找到,直接使用陣列索引
418
+ if (!palace && palaceIndex >= 0 && palaceIndex < palaces.length) {
419
+ palace = palaces[palaceIndex];
420
+ }
421
+ // 方法3:如果還沒找到,嘗試通過地支匹配(備用方案)
422
+ if (!palace) {
423
+ const BRANCHES = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];
424
+ const branch = BRANCHES[palaceIndex % 12];
425
+ palace = palaces.find(p => p.earthlyBranch === branch);
426
+ }
427
+ if (!palace)
428
+ return '-';
429
+ // 獲取主星
430
+ if (palace.majorStars && palace.majorStars.length > 0) {
431
+ return palace.majorStars.map((s) => typeof s === 'string' ? s : s.name).join('、');
432
+ }
433
+ // 空宮標記
434
+ return '空宮';
435
+ }
436
+ /**
437
+ * 格式化四化資訊為文本行
438
+ */
439
+ function formatMutagenLine(label, info) {
440
+ if (!info)
441
+ return '';
442
+ const parts = [];
443
+ if (info.lu)
444
+ parts.push(`化祿-${info.lu}`);
445
+ if (info.quan)
446
+ parts.push(`化權-${info.quan}`);
447
+ if (info.ke)
448
+ parts.push(`化科-${info.ke}`);
449
+ if (info.ji)
450
+ parts.push(`化忌-${info.ji}`);
451
+ return parts.length ? `${label}:${parts.join(' ')}` : '';
452
+ }
453
+ /**
454
+ * 渲染紫微大限列表
455
+ * 統一頭部格式:=== 命主資料 === + === 紫微命盤 === + === 大限資訊 ===
456
+ */
457
+ function renderZiweiDaXianList(decades, options) {
458
+ const lines = [];
459
+ lines.push(...renderZiweiBaseHeader({
460
+ name: options.name,
461
+ birthYear: options.birthYear,
462
+ birthMonth: options.birthMonth,
463
+ birthDay: options.birthDay,
464
+ birthHour: options.birthHour,
465
+ birthMinute: options.birthMinute,
466
+ gender: options.gender,
467
+ mingGong: options.mingGong,
468
+ mingGongStars: options.mingGongStars,
469
+ mingGongHeavenlyStem: options.mingGongHeavenlyStem,
470
+ mingGongEarthlyBranch: options.mingGongEarthlyBranch,
471
+ shenGong: options.shenGong,
472
+ shenGongStars: options.shenGongStars,
473
+ palaces: options.palaces,
474
+ mutagenInfo: options.mutagenInfo,
475
+ }));
476
+ lines.push('=== 大限資訊 ===');
477
+ lines.push(`大限方向:${options.direction}`);
478
+ lines.push('');
479
+ lines.push('序號 | 虛歲範圍 | 公曆年範圍 | 大限宮位 | 宮內主星 | 大限四化');
480
+ lines.push('-----|---------|-----------|---------|--------|--------');
481
+ for (const decade of decades) {
482
+ const index = (decade.index + 1).toString().padStart(3, ' ');
483
+ const ageRange = `${decade.startAge}-${decade.endAge}歲`;
484
+ const yearRange = `${options.birthYear + decade.startAge - 1}-${options.birthYear + decade.endAge - 1}`;
485
+ const palaceName = decade.palaceName || types_1.PALACE_NAMES[decade.palaceIndex] || '-';
486
+ const stars = getPalaceStars(options.palaces, decade.palaceIndex);
487
+ let decadeMutagenStr = '-';
488
+ if (decade.heavenlyStem) {
489
+ const mutagen = MutagenCore_1.MutagenCore.getMutagen(decade.heavenlyStem);
490
+ if (mutagen) {
491
+ const parts = [];
492
+ if (mutagen.lu)
493
+ parts.push(`祿${mutagen.lu}`);
494
+ if (mutagen.quan)
495
+ parts.push(`權${mutagen.quan}`);
496
+ if (mutagen.ke)
497
+ parts.push(`科${mutagen.ke}`);
498
+ if (mutagen.ji)
499
+ parts.push(`忌${mutagen.ji}`);
500
+ decadeMutagenStr = parts.join(' ');
501
+ }
502
+ }
503
+ lines.push(`${index} | ${ageRange.padEnd(8, ' ')} | ${yearRange.padEnd(10, ' ')} | ${palaceName.padEnd(6, ' ')} | ${stars.padEnd(15, ' ')} | ${decadeMutagenStr}`);
504
+ }
505
+ if (options.mutagenInfo) {
506
+ lines.push('');
507
+ const natalLine = formatMutagenLine('本命四化', options.mutagenInfo.natal);
508
+ if (natalLine)
509
+ lines.push(natalLine);
510
+ }
511
+ return lines.join('\n');
512
+ }
513
+ /**
514
+ * 渲染紫微小限列表
515
+ * 統一頭部格式:=== 命主資料 === + === 紫微命盤 === + === 大限資訊 === + === 小限列表 ===
516
+ */
517
+ function renderZiweiXiaoXianList(minorLimitList, options) {
518
+ const lines = [];
519
+ lines.push(...renderZiweiBaseHeader({
520
+ name: options.name,
521
+ birthYear: options.birthYear,
522
+ birthMonth: options.birthMonth,
523
+ birthDay: options.birthDay,
524
+ birthHour: options.birthHour,
525
+ birthMinute: options.birthMinute,
526
+ gender: options.gender,
527
+ mingGong: options.mingGong,
528
+ mingGongStars: options.mingGongStars,
529
+ mingGongHeavenlyStem: options.mingGongHeavenlyStem,
530
+ mingGongEarthlyBranch: options.mingGongEarthlyBranch,
531
+ shenGong: options.shenGong,
532
+ shenGongStars: options.shenGongStars,
533
+ palaces: options.palaces,
534
+ mutagenInfo: options.mutagenInfo,
535
+ }));
536
+ if (options.currentDecade) {
537
+ lines.push('=== 大限資訊 ===');
538
+ lines.push(`當前大限:${options.currentDecade.palaceName}限(${options.currentDecade.startAge}-${options.currentDecade.endAge}歲)`);
539
+ lines.push('');
540
+ }
541
+ lines.push('=== 小限列表 ===');
542
+ lines.push(`查詢範圍:${options.startAge}-${options.endAge}歲`);
543
+ lines.push('');
544
+ lines.push('虛歲 | 公曆年 | 小限干支 | 小限宮位 | 宮內主星 | 所屬大限 | 小限四化');
545
+ lines.push('-----|-------|---------|---------|---------|--------|--------');
546
+ for (const minorLimit of minorLimitList) {
547
+ const age = `${minorLimit.age}歲`;
548
+ const year = `${minorLimit.year}年`;
549
+ const ganzhi = `${minorLimit.heavenlyStem}${minorLimit.earthlyBranch}`;
550
+ let palaceName = '-';
551
+ if (options.palaces && minorLimit.palaceIndex >= 0 && minorLimit.palaceIndex < options.palaces.length) {
552
+ palaceName = options.palaces[minorLimit.palaceIndex]?.name || '-';
553
+ }
554
+ const stars = getPalaceStars(options.palaces, minorLimit.palaceIndex);
555
+ let decadeLabel = '-';
556
+ if (options.decades && options.decades.length > 0) {
557
+ const matchedDecade = options.decades.find(d => minorLimit.age >= d.startAge && minorLimit.age <= d.endAge);
558
+ if (matchedDecade) {
559
+ decadeLabel = `${matchedDecade.palaceName}(${matchedDecade.startAge}-${matchedDecade.endAge}歲)`;
560
+ }
561
+ }
562
+ let mutagenStr = '-';
563
+ if (minorLimit.heavenlyStem) {
564
+ const mutagen = MutagenCore_1.MutagenCore.getMutagen(minorLimit.heavenlyStem);
565
+ if (mutagen) {
566
+ const parts = [];
567
+ if (mutagen.lu)
568
+ parts.push(`祿${mutagen.lu}`);
569
+ if (mutagen.quan)
570
+ parts.push(`權${mutagen.quan}`);
571
+ if (mutagen.ke)
572
+ parts.push(`科${mutagen.ke}`);
573
+ if (mutagen.ji)
574
+ parts.push(`忌${mutagen.ji}`);
575
+ mutagenStr = parts.join(' ');
576
+ }
577
+ }
578
+ lines.push(`${age.padEnd(5, ' ')} | ${year} | ${ganzhi.padEnd(6, ' ')} | ${palaceName.padEnd(6, ' ')} | ${stars.padEnd(15, ' ')} | ${decadeLabel} | ${mutagenStr}`);
579
+ }
580
+ lines.push('');
581
+ if (options.mutagenInfo) {
582
+ const natalLine = formatMutagenLine('本命四化', options.mutagenInfo.natal);
583
+ if (natalLine)
584
+ lines.push(natalLine);
585
+ }
586
+ if (options.decades && options.decades.length > 0) {
587
+ const involvedDecades = new Map();
588
+ for (const minorLimit of minorLimitList) {
589
+ const matchedDecade = options.decades.find(d => minorLimit.age >= d.startAge && minorLimit.age <= d.endAge);
590
+ if (matchedDecade && !involvedDecades.has(matchedDecade.index)) {
591
+ involvedDecades.set(matchedDecade.index, matchedDecade);
592
+ }
593
+ }
594
+ const sortedDecades = Array.from(involvedDecades.values()).sort((a, b) => a.index - b.index);
595
+ for (const decade of sortedDecades) {
596
+ if (decade.heavenlyStem) {
597
+ const mutagen = MutagenCore_1.MutagenCore.getMutagen(decade.heavenlyStem);
598
+ if (mutagen) {
599
+ const parts = [];
600
+ if (mutagen.lu)
601
+ parts.push(`化祿-${mutagen.lu}`);
602
+ if (mutagen.quan)
603
+ parts.push(`化權-${mutagen.quan}`);
604
+ if (mutagen.ke)
605
+ parts.push(`化科-${mutagen.ke}`);
606
+ if (mutagen.ji)
607
+ parts.push(`化忌-${mutagen.ji}`);
608
+ if (parts.length > 0) {
609
+ const label = `大限四化(${decade.palaceName}限 ${decade.startAge}-${decade.endAge}歲)`;
610
+ lines.push(`${label}:${parts.join(' ')}`);
611
+ }
612
+ }
613
+ }
614
+ }
615
+ }
616
+ lines.push('');
617
+ lines.push('注:');
618
+ lines.push('1. 小限以虛歲計算,每年一宮。');
619
+ lines.push('2. 小限起宮根據出生年支決定,男順女逆行進。');
620
+ lines.push('3. 小限四化為該年小限天干所化。');
621
+ return lines.join('\n');
622
+ }
623
+ /**
624
+ * 渲染紫微流年列表
625
+ * 統一頭部格式:=== 命主資料 === + === 紫微命盤 === + === 流年資訊 ===
626
+ */
627
+ function renderZiweiLiuNianList(yearlyList, options) {
628
+ const lines = [];
629
+ lines.push(...renderZiweiBaseHeader({
630
+ name: options.name,
631
+ birthYear: options.birthYear,
632
+ birthMonth: options.birthMonth,
633
+ birthDay: options.birthDay,
634
+ birthHour: options.birthHour,
635
+ birthMinute: options.birthMinute,
636
+ gender: options.gender,
637
+ mingGong: options.mingGong,
638
+ mingGongStars: options.mingGongStars,
639
+ mingGongHeavenlyStem: options.mingGongHeavenlyStem,
640
+ mingGongEarthlyBranch: options.mingGongEarthlyBranch,
641
+ shenGong: options.shenGong,
642
+ shenGongStars: options.shenGongStars,
643
+ palaces: options.palaces,
644
+ mutagenInfo: options.mutagenInfo,
645
+ }));
646
+ lines.push('=== 流年資訊 ===');
647
+ lines.push(`查詢範圍:${options.startYear}-${options.endYear}年`);
648
+ lines.push('');
649
+ lines.push('公曆年 | 干支年 | 虛歲 | 流年宮位 | 宮內主星 | 所屬大限 | 流年四化');
650
+ lines.push('-------|-------|------|---------|---------|--------|--------');
651
+ for (const yearly of yearlyList) {
652
+ const year = `${yearly.year}年`;
653
+ const ganzhi = `${yearly.heavenlyStem}${yearly.earthlyBranch}年`;
654
+ const age = `${yearly.age}歲`;
655
+ // 流年宫位:通过 palaceIndex 从 palaces 数组获取宫位名称
656
+ // 注意:palaceIndex 是地支位置索引,需要直接从 palaces 数组获取对应的宫位名
657
+ let palaceName = '-';
658
+ if (options.palaces && yearly.palaceIndex >= 0 && yearly.palaceIndex < options.palaces.length) {
659
+ palaceName = options.palaces[yearly.palaceIndex]?.name || '-';
660
+ }
661
+ const stars = getPalaceStars(options.palaces, yearly.palaceIndex);
662
+ let decadeLabel = '-';
663
+ if (options.decades && options.decades.length > 0) {
664
+ const matchedDecade = options.decades.find(d => yearly.age >= d.startAge && yearly.age <= d.endAge);
665
+ if (matchedDecade) {
666
+ decadeLabel = `${matchedDecade.palaceName}(${matchedDecade.startAge}-${matchedDecade.endAge}歲)`;
667
+ }
668
+ }
669
+ else if (options.currentDecade?.palaceName) {
670
+ decadeLabel = `${options.currentDecade.palaceName}限`;
671
+ }
672
+ let yearlyMutagenStr = '-';
673
+ if (yearly.heavenlyStem) {
674
+ const mutagen = MutagenCore_1.MutagenCore.getMutagen(yearly.heavenlyStem);
675
+ if (mutagen) {
676
+ const parts = [];
677
+ if (mutagen.lu)
678
+ parts.push(`祿${mutagen.lu}`);
679
+ if (mutagen.quan)
680
+ parts.push(`權${mutagen.quan}`);
681
+ if (mutagen.ke)
682
+ parts.push(`科${mutagen.ke}`);
683
+ if (mutagen.ji)
684
+ parts.push(`忌${mutagen.ji}`);
685
+ yearlyMutagenStr = parts.join(' ');
686
+ }
687
+ }
688
+ lines.push(`${year} | ${ganzhi} | ${age.padEnd(5, ' ')} | ${palaceName.padEnd(6, ' ')} | ${stars.padEnd(15, ' ')} | ${decadeLabel} | ${yearlyMutagenStr}`);
689
+ }
690
+ lines.push('');
691
+ if (options.mutagenInfo) {
692
+ const natalLine = formatMutagenLine('本命四化', options.mutagenInfo.natal);
693
+ if (natalLine)
694
+ lines.push(natalLine);
695
+ }
696
+ if (options.decades && options.decades.length > 0) {
697
+ const involvedDecades = new Map();
698
+ for (const yearly of yearlyList) {
699
+ const matchedDecade = options.decades.find(d => yearly.age >= d.startAge && yearly.age <= d.endAge);
700
+ if (matchedDecade && !involvedDecades.has(matchedDecade.index)) {
701
+ involvedDecades.set(matchedDecade.index, matchedDecade);
702
+ }
703
+ }
704
+ const sortedDecades = Array.from(involvedDecades.values()).sort((a, b) => a.index - b.index);
705
+ for (const decade of sortedDecades) {
706
+ if (decade.heavenlyStem) {
707
+ const mutagen = MutagenCore_1.MutagenCore.getMutagen(decade.heavenlyStem);
708
+ if (mutagen) {
709
+ const parts = [];
710
+ if (mutagen.lu)
711
+ parts.push(`化祿-${mutagen.lu}`);
712
+ if (mutagen.quan)
713
+ parts.push(`化權-${mutagen.quan}`);
714
+ if (mutagen.ke)
715
+ parts.push(`化科-${mutagen.ke}`);
716
+ if (mutagen.ji)
717
+ parts.push(`化忌-${mutagen.ji}`);
718
+ if (parts.length > 0) {
719
+ const label = `大限四化(${decade.palaceName}限 ${decade.startAge}-${decade.endAge}歲)`;
720
+ lines.push(`${label}:${parts.join(' ')}`);
721
+ }
722
+ }
723
+ }
724
+ }
725
+ }
726
+ return lines.join('\n');
727
+ }
728
+ /**
729
+ * 渲染紫微流月列表(農曆月)
730
+ * 統一頭部格式:=== 命主資料 === + === 紫微命盤 === + === 大限資訊 === + === 小限資訊 === + === 流年資訊 === + === 流月列表 ===
731
+ */
732
+ function renderZiweiLiuYueList(monthlyList, options) {
733
+ const lines = [];
734
+ const ganzhiYear = getGanzhi(options.gregorianYear);
735
+ lines.push(...renderZiweiBaseHeader({
736
+ name: options.name,
737
+ birthYear: options.birthYear,
738
+ birthMonth: options.birthMonth,
739
+ birthDay: options.birthDay,
740
+ birthHour: options.birthHour,
741
+ birthMinute: options.birthMinute,
742
+ gender: options.gender,
743
+ mingGong: options.mingGong,
744
+ mingGongStars: options.mingGongStars,
745
+ mingGongHeavenlyStem: options.mingGongHeavenlyStem,
746
+ mingGongEarthlyBranch: options.mingGongEarthlyBranch,
747
+ shenGong: options.shenGong,
748
+ shenGongStars: options.shenGongStars,
749
+ palaces: options.palaces,
750
+ mutagenInfo: options.mutagenInfo,
751
+ }));
752
+ if (options.currentDecade) {
753
+ lines.push('=== 大限資訊 ===');
754
+ lines.push(`當前大限:${options.currentDecade.palaceName}限(${options.currentDecade.startAge}-${options.currentDecade.endAge}歲)`);
755
+ lines.push('');
756
+ }
757
+ if (options.currentMinorLimit) {
758
+ lines.push('=== 小限資訊 ===');
759
+ lines.push(`當前小限:${options.currentMinorLimit.heavenlyStem}${options.currentMinorLimit.earthlyBranch} ${options.currentMinorLimit.palaceName}(${options.currentMinorLimit.age}歲)`);
760
+ lines.push('');
761
+ }
762
+ if (options.currentYearly) {
763
+ lines.push('=== 流年資訊 ===');
764
+ lines.push(`當前流年:${options.currentYearly.heavenlyStem}${options.currentYearly.earthlyBranch}年 ${options.currentYearly.palaceName}(${options.currentYearly.age}歲)`);
765
+ lines.push(`農曆年:${ganzhiYear}年(公曆${options.gregorianYear}年)`);
766
+ if (options.yearlyPalace) {
767
+ lines.push(`流年宮位:${options.yearlyPalace}`);
768
+ }
769
+ lines.push('');
770
+ }
771
+ lines.push('=== 流月列表 ===');
772
+ lines.push('');
773
+ lines.push('序號 | 農曆月 | 公曆日期範圍 | 流月宮位 | 宮內主星 | 流月四化');
774
+ lines.push('-----|-------|-------------|---------|---------|--------');
775
+ let monthIndex = 0;
776
+ for (const monthly of monthlyList) {
777
+ monthIndex++;
778
+ const index = monthIndex.toString().padStart(3, ' ');
779
+ // 处理闰月名称
780
+ const baseName = LUNAR_MONTH_NAMES[monthly.month] || `${monthly.month}月`;
781
+ const lunarMonthName = monthly.isLeapMonth ? `閏${baseName}` : baseName;
782
+ let dateRange = '-';
783
+ if (monthly.startDate && monthly.endDate) {
784
+ dateRange = `${formatDate(monthly.startDate)} ~ ${formatDate(monthly.endDate)}`;
785
+ }
786
+ // 流月宫位:通过 palaceIndex 从 palaces 数组获取宫位名称
787
+ let palaceName = '-';
788
+ if (options.palaces && monthly.palaceIndex >= 0 && monthly.palaceIndex < options.palaces.length) {
789
+ palaceName = options.palaces[monthly.palaceIndex]?.name || '-';
790
+ }
791
+ const stars = getPalaceStars(options.palaces, monthly.palaceIndex);
792
+ let monthlyMutagenStr = '-';
793
+ if (monthly.heavenlyStem) {
794
+ const mutagen = MutagenCore_1.MutagenCore.getMutagen(monthly.heavenlyStem);
795
+ if (mutagen) {
796
+ const parts = [];
797
+ if (mutagen.lu)
798
+ parts.push(`祿${mutagen.lu}`);
799
+ if (mutagen.quan)
800
+ parts.push(`權${mutagen.quan}`);
801
+ if (mutagen.ke)
802
+ parts.push(`科${mutagen.ke}`);
803
+ if (mutagen.ji)
804
+ parts.push(`忌${mutagen.ji}`);
805
+ monthlyMutagenStr = parts.join(' ');
806
+ }
807
+ }
808
+ lines.push(`${index} | ${lunarMonthName.padEnd(4, ' ')} | ${dateRange.padEnd(25, ' ')} | ${palaceName.padEnd(6, ' ')} | ${stars.padEnd(15, ' ')} | ${monthlyMutagenStr}`);
809
+ }
810
+ if (options.mutagenInfo) {
811
+ lines.push('');
812
+ const natalLine = formatMutagenLine('本命四化', options.mutagenInfo.natal);
813
+ if (natalLine)
814
+ lines.push(natalLine);
815
+ const decadalLine = formatMutagenLine('大限四化', options.mutagenInfo.decadal);
816
+ if (decadalLine)
817
+ lines.push(decadalLine);
818
+ const minorLimitLine = formatMutagenLine('小限四化', options.mutagenInfo.minorLimit);
819
+ if (minorLimitLine)
820
+ lines.push(minorLimitLine);
821
+ const yearlyLine = formatMutagenLine('流年四化', options.mutagenInfo.yearly);
822
+ if (yearlyLine)
823
+ lines.push(yearlyLine);
824
+ }
825
+ lines.push('');
826
+ lines.push('注:');
827
+ lines.push('1. 紫微流月以農曆月為準,非節氣月。');
828
+ if (options.leapMonth) {
829
+ lines.push(`2. 闰月歸入前一月計算,闰${LUNAR_MONTH_NAMES[options.leapMonth]}按${LUNAR_MONTH_NAMES[options.leapMonth]}論。`);
830
+ }
831
+ lines.push('3. 公曆日期僅供參考,精確邊界以農曆初一為準。');
832
+ return lines.join('\n');
833
+ }
834
+ /**
835
+ * 渲染紫微流日列表(農曆日)
836
+ * 統一頭部格式:=== 命主資料 === + === 紫微命盤 === + === 大限資訊 === + === 小限資訊 === + === 流年資訊 === + === 流月資訊 === + === 流日列表 ===
837
+ */
838
+ function renderZiweiLiuRiList(dailyList, options) {
839
+ const lines = [];
840
+ const ganzhiYear = getGanzhi(options.lunarYear);
841
+ const monthName = LUNAR_MONTH_NAMES[options.lunarMonth] || `${options.lunarMonth}月`;
842
+ const leapPrefix = options.isLeapMonth ? '閏' : '';
843
+ lines.push(...renderZiweiBaseHeader({
844
+ name: options.name,
845
+ birthYear: options.birthYear,
846
+ birthMonth: options.birthMonth,
847
+ birthDay: options.birthDay,
848
+ birthHour: options.birthHour,
849
+ birthMinute: options.birthMinute,
850
+ gender: options.gender,
851
+ mingGong: options.mingGong,
852
+ mingGongStars: options.mingGongStars,
853
+ mingGongHeavenlyStem: options.mingGongHeavenlyStem,
854
+ mingGongEarthlyBranch: options.mingGongEarthlyBranch,
855
+ shenGong: options.shenGong,
856
+ shenGongStars: options.shenGongStars,
857
+ palaces: options.palaces,
858
+ mutagenInfo: options.mutagenInfo,
859
+ }));
860
+ if (options.currentDecade) {
861
+ lines.push('=== 大限資訊 ===');
862
+ lines.push(`當前大限:${options.currentDecade.palaceName}限(${options.currentDecade.startAge}-${options.currentDecade.endAge}歲)`);
863
+ lines.push('');
864
+ }
865
+ if (options.currentMinorLimit) {
866
+ lines.push('=== 小限資訊 ===');
867
+ lines.push(`當前小限:${options.currentMinorLimit.heavenlyStem}${options.currentMinorLimit.earthlyBranch} ${options.currentMinorLimit.palaceName}(${options.currentMinorLimit.age}歲)`);
868
+ lines.push('');
869
+ }
870
+ if (options.currentYearly) {
871
+ lines.push('=== 流年資訊 ===');
872
+ lines.push(`當前流年:${options.currentYearly.heavenlyStem}${options.currentYearly.earthlyBranch}年 ${options.currentYearly.palaceName}(${options.currentYearly.age}歲)`);
873
+ lines.push('');
874
+ }
875
+ if (options.currentMonthly) {
876
+ lines.push('=== 流月資訊 ===');
877
+ const monthLabel = LUNAR_MONTH_NAMES[options.currentMonthly.month] || `${options.currentMonthly.month}月`;
878
+ lines.push(`當前流月:${monthLabel} ${options.currentMonthly.palaceName}`);
879
+ lines.push(`農曆月:${ganzhiYear}年${leapPrefix}${monthName}(公曆${formatDate(options.gregorianStartDate)} ~ ${formatDate(options.gregorianEndDate)})`);
880
+ if (options.monthlyPalace) {
881
+ lines.push(`流月宮位:${options.monthlyPalace}`);
882
+ }
883
+ lines.push('');
884
+ }
885
+ lines.push('=== 流日列表 ===');
886
+ lines.push('');
887
+ lines.push('農曆日期 | 公曆日期 | 干支日 | 流日宮位 | 宮內主星 | 流日四化');
888
+ lines.push('--------|---------|-------|--------|--------|--------');
889
+ for (const daily of dailyList) {
890
+ const lunarDate = `${leapPrefix}${monthName}${getLunarDayName(daily.lunarDay)}`;
891
+ const gregorianDate = formatDate(daily.gregorianDate);
892
+ const ganzhiDay = daily.ganzhi + '日';
893
+ // 流日宫位:通过 palaceIndex 从 palaces 数组获取宫位名称
894
+ let palaceName = '-';
895
+ if (options.palaces && daily.palaceIndex >= 0 && daily.palaceIndex < options.palaces.length) {
896
+ palaceName = options.palaces[daily.palaceIndex]?.name || '-';
897
+ }
898
+ const stars = getPalaceStars(options.palaces, daily.palaceIndex);
899
+ let dailyMutagenStr = '-';
900
+ if (daily.ganzhi && daily.ganzhi.length >= 1) {
901
+ const dayStem = daily.ganzhi.charAt(0);
902
+ const mutagen = MutagenCore_1.MutagenCore.getMutagen(dayStem);
903
+ if (mutagen) {
904
+ const parts = [];
905
+ if (mutagen.lu)
906
+ parts.push(`祿${mutagen.lu}`);
907
+ if (mutagen.quan)
908
+ parts.push(`權${mutagen.quan}`);
909
+ if (mutagen.ke)
910
+ parts.push(`科${mutagen.ke}`);
911
+ if (mutagen.ji)
912
+ parts.push(`忌${mutagen.ji}`);
913
+ dailyMutagenStr = parts.join(' ');
914
+ }
915
+ }
916
+ lines.push(`${lunarDate.padEnd(10, ' ')} | ${gregorianDate} | ${ganzhiDay} | ${palaceName.padEnd(6, ' ')} | ${stars.padEnd(15, ' ')} | ${dailyMutagenStr}`);
917
+ }
918
+ if (options.mutagenInfo) {
919
+ lines.push('');
920
+ const natalLine = formatMutagenLine('本命四化', options.mutagenInfo.natal);
921
+ if (natalLine)
922
+ lines.push(natalLine);
923
+ const decadalLine = formatMutagenLine('大限四化', options.mutagenInfo.decadal);
924
+ if (decadalLine)
925
+ lines.push(decadalLine);
926
+ const minorLimitLine = formatMutagenLine('小限四化', options.mutagenInfo.minorLimit);
927
+ if (minorLimitLine)
928
+ lines.push(minorLimitLine);
929
+ const yearlyLine = formatMutagenLine('流年四化', options.mutagenInfo.yearly);
930
+ if (yearlyLine)
931
+ lines.push(yearlyLine);
932
+ const monthlyLine = formatMutagenLine('流月四化', options.mutagenInfo.monthly);
933
+ if (monthlyLine)
934
+ lines.push(monthlyLine);
935
+ }
936
+ lines.push('');
937
+ lines.push(`共${dailyList.length}日`);
938
+ lines.push('');
939
+ lines.push('注:紫微流日以農曆日為準,流日宮位按日支定位。');
940
+ return lines.join('\n');
941
+ }
942
+ //# sourceMappingURL=listTextRenderer.js.map