dsh-metaphysics 0.38.2 → 0.46.5
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/CHANGELOG.md +215 -8
- package/README.md +348 -342
- package/client.js +2134 -129
- package/engine/bazi-words.js +174 -0
- package/engine/classics.js +136 -7
- package/engine/fengshui.js +197 -11
- package/engine/followup.js +29 -5
- package/engine/geju.js +41 -0
- package/engine/index.js +96 -8
- package/engine/interpret-knowledge.js +31 -4
- package/engine/interpret-plain.js +367 -322
- package/engine/interpret.js +288 -32
- package/engine/liuyao.js +85 -0
- package/engine/name-data.js +229 -0
- package/engine/name.js +234 -9
- package/engine/ziwei-words.js +245 -0
- package/engine/ziwei.js +254 -26
- package/index.js +65 -9
- package/package.json +2 -2
- package//345/221/275/347/220/206/346/216/222/347/233/230.html +2933 -487
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
--shadow:0 1px 2px rgba(0,0,0,.5),0 18px 40px -30px rgba(0,0,0,.9);--ring:0 0 0 3px rgba(226,117,95,.2)}
|
|
22
22
|
/* 深色下强调色是浅色,这些实心底上的文字得反过来 */
|
|
23
23
|
.tab.on,.seg button.on,.go{color:#14130f}
|
|
24
|
+
.tool.on,.tool.on b{color:#14130f}
|
|
25
|
+
.tool.on span{color:rgba(20,19,15,.72)}
|
|
24
26
|
.mb-o.on b,.mb-o.on span,.mb-btn.primary{color:#14130f}
|
|
25
27
|
.err{background:rgba(226,117,95,.14)}
|
|
26
28
|
}
|
|
@@ -37,6 +39,7 @@ body{margin:0;color:var(--ink);font:16px/1.65 "Microsoft YaHei","PingFang SC",sy
|
|
|
37
39
|
.wrap{max-width:1180px;margin:0 auto;padding:22px 26px 60px}
|
|
38
40
|
/* 抬头竖排:品牌在上,tab 条独占一行。19 个 tab 横排在品牌右侧会把末行挤成「起名 人格」孤零零两个 */
|
|
39
41
|
header{display:flex;flex-direction:column;align-items:stretch;gap:12px;margin-bottom:18px;padding-bottom:14px;border-bottom:1px solid var(--line)}
|
|
42
|
+
.brand-row{display:flex;align-items:center;justify-content:space-between;gap:10px 16px;flex-wrap:wrap}
|
|
40
43
|
.brand{display:flex;align-items:center;gap:12px;font-size:22px;font-weight:700;letter-spacing:.14em;color:var(--gold);line-height:1.3}
|
|
41
44
|
.brand .seal{display:inline-flex;align-items:center;justify-content:center;flex:none;width:40px;height:40px;border-radius:11px;
|
|
42
45
|
background:linear-gradient(145deg,var(--gold),var(--gold-deep));color:#fff;font:700 20px/1 "Songti SC","SimSun",serif;letter-spacing:0;
|
|
@@ -51,6 +54,46 @@ header{display:flex;flex-direction:column;align-items:stretch;gap:12px;margin-bo
|
|
|
51
54
|
transition:background .16s ease,color .16s ease,border-color .16s ease,box-shadow .16s ease}
|
|
52
55
|
.tab:hover{background:var(--panel);border-color:var(--line);color:var(--ink)}
|
|
53
56
|
.tab.on{background:linear-gradient(145deg,var(--gold),var(--gold-deep));border-color:transparent;color:#fff;font-weight:600;box-shadow:0 8px 18px -12px var(--gold)}
|
|
57
|
+
/* 首屏按「想干什么」分组:19 个 tab 平铺时,第一次来的人得先猜「梅花」「称骨」是什么。
|
|
58
|
+
卡片只是另一套入口,点击仍走同一个 setTab;熟练用户可一键回到平铺(19 个 tab 原样保留)。 */
|
|
59
|
+
.view-switch{display:flex;align-items:center;gap:8px}
|
|
60
|
+
.view-switch .hint{font-size:12px;color:var(--dim)}
|
|
61
|
+
.view-switch .seg button{padding:5px 11px;font-size:12.5px}
|
|
62
|
+
.start{margin-bottom:20px}
|
|
63
|
+
.recent{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 12px}
|
|
64
|
+
/* .recent 自带 display:flex,会盖掉 [hidden] 的 UA 样式:没有记录时必须显式收起,否则只剩一个空标签 */
|
|
65
|
+
.recent[hidden]{display:none}
|
|
66
|
+
.recent-lbl{font-size:12px;font-weight:600;letter-spacing:.1em;color:var(--gold)}
|
|
67
|
+
.recent-list{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
|
|
68
|
+
.rc{display:inline-flex;align-items:center;gap:6px;padding:5px 12px;border-radius:999px;border:1px solid var(--line);
|
|
69
|
+
background:color-mix(in srgb,var(--panel) 72%,transparent);color:var(--ink);font:inherit;font-size:13.5px;cursor:pointer;
|
|
70
|
+
transition:border-color .14s ease,background .14s ease}
|
|
71
|
+
.rc:hover{border-color:var(--gold);background:var(--panel)}
|
|
72
|
+
.rc i{font-style:normal;font-size:11.5px;color:var(--dim)}
|
|
73
|
+
.groups{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
|
|
74
|
+
.tgroup{padding:14px 14px 12px;border:1px solid var(--line);border-radius:14px;
|
|
75
|
+
background:linear-gradient(180deg,var(--panel),color-mix(in srgb,var(--panel) 88%,var(--bg)));box-shadow:var(--shadow)}
|
|
76
|
+
.tgroup-head h2{display:flex;align-items:center;gap:8px;margin:0;font-size:15.5px;font-weight:600;color:var(--ink);letter-spacing:.06em}
|
|
77
|
+
.tgroup-head h2::before{content:"";flex:none;width:7px;height:7px;border-radius:2px;background:var(--gold)}
|
|
78
|
+
.tgroup-head p{margin:4px 0 11px;font-size:12.5px;line-height:1.6;color:var(--dim)}
|
|
79
|
+
.ttools{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px}
|
|
80
|
+
.tool{display:flex;flex-direction:column;gap:1px;padding:8px 10px;text-align:left;border:1px solid var(--line);border-radius:9px;
|
|
81
|
+
background:color-mix(in srgb,var(--panel2) 72%,transparent);color:var(--ink);font-family:inherit;cursor:pointer;
|
|
82
|
+
transition:border-color .14s ease,background .14s ease,box-shadow .14s ease}
|
|
83
|
+
.tool b{font-size:13.5px;font-weight:600;letter-spacing:.02em}
|
|
84
|
+
.tool span{font-size:11.5px;line-height:1.4;color:var(--dim)}
|
|
85
|
+
.tool:hover{border-color:var(--gold);background:var(--panel)}
|
|
86
|
+
.tool.on{border-color:transparent;background:linear-gradient(145deg,var(--gold),var(--gold-deep));box-shadow:0 8px 18px -12px var(--gold)}
|
|
87
|
+
.tool.on b{color:#fff}
|
|
88
|
+
.tool.on span{color:rgba(255,255,255,.84)}
|
|
89
|
+
/* 奇数个的那一组:末项铺满整行,避免右下留一个孤格 */
|
|
90
|
+
.tool.wide{grid-column:1/-1}
|
|
91
|
+
/* 手机端每组先露 4 个,其余折在「还有 N 个」后面:三组全展开会把表单挤到第二屏 */
|
|
92
|
+
.tmore{display:none;grid-column:1/-1;align-items:center;justify-content:center;gap:6px;padding:8px;border:1px dashed var(--line);border-radius:9px;
|
|
93
|
+
background:transparent;color:var(--dim);font-family:inherit;font-size:12.5px;cursor:pointer}
|
|
94
|
+
.tmore:hover{color:var(--gold);border-color:var(--gold)}
|
|
95
|
+
body.view-group .tabs{display:none}
|
|
96
|
+
body.view-flat .start{display:none}
|
|
54
97
|
.bar{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px 14px;align-items:start;padding:18px 20px;margin-bottom:20px;
|
|
55
98
|
background:linear-gradient(180deg,var(--panel),color-mix(in srgb,var(--panel) 90%,var(--bg)));border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow)}
|
|
56
99
|
.grp{display:contents}
|
|
@@ -170,12 +213,25 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
170
213
|
.mp-rect-cand{font-size:12.5px;padding:5px 8px;border-radius:6px;background:var(--panel2);margin-top:4px;color:var(--dim)}
|
|
171
214
|
.mp-rect-cand.best{border-left:3px solid var(--gold);color:var(--ink)}
|
|
172
215
|
.mp-rect-err{color:var(--bad);font-size:12.5px}
|
|
216
|
+
/* 验前事 / 生时校正的按钮与输入框只有 .mp-btn/.mp-input 类名,样式却写在 DSH 宿主的 app.js 里,
|
|
217
|
+
离线页借不到 → 退回原生控件(年份框 21px、按钮灰底且 31px 高)。页面层补一套同变量的小号控件,
|
|
218
|
+
深浅两色都只跟着变量走,不另写颜色。 */
|
|
219
|
+
.mp-verify .mp-btn,.mp-rect .mp-btn{min-height:36px;padding:7px 14px;border-radius:8px;border:1px solid var(--line);background:var(--panel2);color:var(--ink);font-family:inherit;font-size:13px;cursor:pointer}
|
|
220
|
+
.mp-verify .mp-btn:hover,.mp-rect .mp-btn:hover{border-color:var(--gold);background:var(--panel)}
|
|
221
|
+
.mp-verify .mp-input,.mp-rect .mp-input{min-height:36px;padding:7px 10px;border-radius:8px;border:1px solid var(--line);background:var(--panel2);color:var(--ink);font-family:inherit;font-size:14px;outline:none}
|
|
222
|
+
.mp-verify .mp-input:focus,.mp-rect .mp-input:focus{border-color:var(--gold);box-shadow:var(--ring)}
|
|
173
223
|
.exp{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:14px 0 0}
|
|
174
224
|
.exp button{padding:9px 16px;border-radius:9px;border:1px solid var(--line);background:var(--panel);color:var(--ink);font-family:inherit;font-size:14px;cursor:pointer;
|
|
175
225
|
transition:background .14s ease,border-color .14s ease,transform .14s ease}
|
|
176
226
|
.exp button:hover{background:var(--panel2);border-color:var(--gold);transform:translateY(-1px)}
|
|
177
227
|
.exp .hint{font-size:13px;color:var(--dim)}
|
|
178
228
|
|
|
229
|
+
/* 中屏:三列会把每格压到 130px 上下,标题与一行白话都放不下,改成一列铺开 */
|
|
230
|
+
@media (min-width:641px) and (max-width:1000px){
|
|
231
|
+
.groups{grid-template-columns:1fr}
|
|
232
|
+
.ttools{grid-template-columns:repeat(auto-fit,minmax(158px,1fr))}
|
|
233
|
+
}
|
|
234
|
+
|
|
179
235
|
/* —— 竖屏(≤640px):整页不横向滚动,输入区整行堆叠,盘面交给 panel-kit 的同名媒体查询 —— */
|
|
180
236
|
@media (max-width:640px){
|
|
181
237
|
body{font-size:15.5px}
|
|
@@ -186,6 +242,19 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
186
242
|
.brand{font-size:19px;letter-spacing:.1em}
|
|
187
243
|
.brand .seal{width:34px;height:34px;border-radius:9px;font-size:17px}
|
|
188
244
|
.brand-txt small{font-size:11.5px;line-height:1.5}
|
|
245
|
+
/* 分组卡片:每组先露 4 个,其余折起来;否则三组铺完,表单要滚过一整屏才见到 */
|
|
246
|
+
.view-switch{gap:6px}
|
|
247
|
+
.view-switch .hint{display:none}
|
|
248
|
+
.view-switch .seg button{min-height:36px;padding:6px 10px}
|
|
249
|
+
.groups{grid-template-columns:1fr}
|
|
250
|
+
.tgroup{padding:12px}
|
|
251
|
+
.ttools{grid-template-columns:repeat(2,minmax(0,1fr))}
|
|
252
|
+
.tool{padding:9px 10px;min-height:52px}
|
|
253
|
+
.tool b{font-size:14px}
|
|
254
|
+
.tool span{font-size:11px}
|
|
255
|
+
.tgroup:not(.open) .ttools>.tool:nth-child(n+5){display:none}
|
|
256
|
+
.tmore{display:flex}
|
|
257
|
+
.rc{min-height:36px}
|
|
189
258
|
/* 19 个 tab 铺网格要占掉大半个首屏,改成单行横滑:44px 触摸目标、滚动条藏起来、
|
|
190
259
|
左右各留 12px 呼吸位(padding 与 .wrap 等宽,首尾 tab 不会被切口)*/
|
|
191
260
|
.tabs{display:flex;flex-wrap:nowrap;gap:8px;overflow-x:auto;overscroll-behavior-x:contain;
|
|
@@ -215,6 +284,18 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
215
284
|
.go{grid-column:2}
|
|
216
285
|
/* 性别只有一格,留在半幅会空出右边半格;出生地同理,独占一行好填 */
|
|
217
286
|
#for-gender,#for-bazi .field:not(.check){grid-column:1/-1}
|
|
287
|
+
/* 验前事 / 生时校正:标签独占一行,三档判断按钮等分成 44px 触摸格;
|
|
288
|
+
年份与类型输入同样抬到 44px(原先在离线页是 21px 的原生控件) */
|
|
289
|
+
.mp-verify,.mp-rect{padding:10px}
|
|
290
|
+
.mp-verify-row{flex-wrap:wrap;gap:6px;padding:5px 0}
|
|
291
|
+
.mp-verify-txt{flex:1 1 100%}
|
|
292
|
+
.mp-verify-btns{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;width:100%}
|
|
293
|
+
.mp-chip{min-height:44px;min-width:44px;font-size:14px;padding:10px 6px}
|
|
294
|
+
.mp-verify .mp-btn,.mp-rect .mp-btn{min-height:44px;font-size:14px;padding:10px 14px}
|
|
295
|
+
.mp-verify .mp-input,.mp-rect .mp-input{min-height:44px;font-size:16px}
|
|
296
|
+
/* 追问框与导出条同样抬到 44px:原先输入 37px、按钮 39px,是结果区最后几处矮控件 */
|
|
297
|
+
.askbox input,.askbox button,.exp button{min-height:44px}
|
|
298
|
+
.askbox input{font-size:16px}
|
|
218
299
|
.tip{font-size:13px}
|
|
219
300
|
.tip .auto-note{font-size:13px}
|
|
220
301
|
.cast-at{font-size:13px}
|
|
@@ -233,6 +314,7 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
233
314
|
body{background:#fff;padding:0;font-size:12pt}
|
|
234
315
|
.wrap{max-width:none;padding:0}
|
|
235
316
|
.tabs,.bar,.tip,.go,.no-print,.exp{display:none!important}
|
|
317
|
+
.start,.view-switch{display:none!important}
|
|
236
318
|
header{margin:0 0 10px;padding-bottom:6px;border-bottom:1px solid #bbb}
|
|
237
319
|
.brand{font-size:15pt}
|
|
238
320
|
.brand small{display:block}
|
|
@@ -255,7 +337,16 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
255
337
|
<body>
|
|
256
338
|
<div class="wrap">
|
|
257
339
|
<header>
|
|
258
|
-
<div class="brand
|
|
340
|
+
<div class="brand-row">
|
|
341
|
+
<div class="brand"><span class="seal" aria-hidden="true">命</span><span class="brand-txt">命理排盘<span class="ver">v0.46.5</span><small>八字 · 紫微 · 六爻 · 梅花 · 六壬 · 奇门 · 合盘 · 塔罗 全部在本机计算</small></span></div>
|
|
342
|
+
<div class="view-switch">
|
|
343
|
+
<span class="hint">熟练了可以换回平铺</span>
|
|
344
|
+
<span class="seg" role="group" aria-label="首屏样式">
|
|
345
|
+
<button type="button" data-view="group" class="on">分组</button>
|
|
346
|
+
<button type="button" data-view="flat">平铺</button>
|
|
347
|
+
</span>
|
|
348
|
+
</div>
|
|
349
|
+
</div>
|
|
259
350
|
<div class="tabs">
|
|
260
351
|
<button class="tab" data-tab="ziwei">紫微</button>
|
|
261
352
|
<button class="tab" data-tab="bazi">八字</button>
|
|
@@ -279,6 +370,53 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
279
370
|
</div>
|
|
280
371
|
</header>
|
|
281
372
|
|
|
373
|
+
<!-- 首屏分组:同一批入口按「想干什么」重排,点击走 web-ui 的 setTab;平铺视图下整块收起 -->
|
|
374
|
+
<section class="start" id="start" aria-label="选择要算的事">
|
|
375
|
+
<div class="recent" id="recent" hidden>
|
|
376
|
+
<span class="recent-lbl">最近用过</span>
|
|
377
|
+
<span class="recent-list" id="recent-list"></span>
|
|
378
|
+
</div>
|
|
379
|
+
<div class="groups" id="groups">
|
|
380
|
+
<section class="tgroup">
|
|
381
|
+
<div class="tgroup-head"><h2>问一件事</h2><p>心里有一件具体的事,起一卦再决定</p></div>
|
|
382
|
+
<div class="ttools">
|
|
383
|
+
<button type="button" class="tool" data-tab="liuyao"><b>六爻</b><span>摇六次,问一件事</span></button>
|
|
384
|
+
<button type="button" class="tool" data-tab="meihua"><b>梅花</b><span>见闻起卦,看当下</span></button>
|
|
385
|
+
<button type="button" class="tool" data-tab="tarot"><b>塔罗</b><span>抽牌,看关系与选择</span></button>
|
|
386
|
+
<button type="button" class="tool" data-tab="qimen"><b>奇门</b><span>看方位、时机与取舍</span></button>
|
|
387
|
+
<button type="button" class="tool" data-tab="daliuren"><b>六壬</b><span>占事,断来意与结果</span></button>
|
|
388
|
+
<button type="button" class="tool" data-tab="xiaoliuren"><b>小六壬</b><span>掐指一算,快速断</span></button>
|
|
389
|
+
<button type="button" class="tmore" aria-expanded="false"></button>
|
|
390
|
+
</div>
|
|
391
|
+
</section>
|
|
392
|
+
<section class="tgroup">
|
|
393
|
+
<div class="tgroup-head"><h2>看一个人</h2><p>看自己或身边人的性情、格局与运程</p></div>
|
|
394
|
+
<div class="ttools">
|
|
395
|
+
<button type="button" class="tool" data-tab="bazi"><b>八字</b><span>四柱看一生格局</span></button>
|
|
396
|
+
<button type="button" class="tool" data-tab="ziwei"><b>紫微</b><span>十二宫细看</span></button>
|
|
397
|
+
<button type="button" class="tool" data-tab="hepan"><b>合盘</b><span>两个人合不合</span></button>
|
|
398
|
+
<button type="button" class="tool" data-tab="mbti"><b>人格</b><span>16 型性格问卷</span></button>
|
|
399
|
+
<button type="button" class="tool" data-tab="chenggu"><b>称骨</b><span>按生辰称命重</span></button>
|
|
400
|
+
<button type="button" class="tool" data-tab="numerology"><b>数字</b><span>生日数字看性格</span></button>
|
|
401
|
+
<button type="button" class="tool wide" data-tab="trend"><b>人生K</b><span>一生高低走势</span></button>
|
|
402
|
+
<button type="button" class="tmore" aria-expanded="false"></button>
|
|
403
|
+
</div>
|
|
404
|
+
</section>
|
|
405
|
+
<section class="tgroup">
|
|
406
|
+
<div class="tgroup-head"><h2>查日子</h2><p>挑时间、换农历,顺带看看家里和名字</p></div>
|
|
407
|
+
<div class="ttools">
|
|
408
|
+
<button type="button" class="tool" data-tab="almanac"><b>黄历</b><span>今天宜忌、时辰吉凶</span></button>
|
|
409
|
+
<button type="button" class="tool" data-tab="zeri"><b>择日</b><span>挑个办事的好日子</span></button>
|
|
410
|
+
<button type="button" class="tool" data-tab="convert"><b>农历</b><span>公历农历互转</span></button>
|
|
411
|
+
<button type="button" class="tool" data-tab="star"><b>星座</b><span>星座性格与今日运</span></button>
|
|
412
|
+
<button type="button" class="tool" data-tab="fengshui"><b>风水</b><span>房屋朝向与布置</span></button>
|
|
413
|
+
<button type="button" class="tool" data-tab="name"><b>起名</b><span>按八字选字</span></button>
|
|
414
|
+
<button type="button" class="tmore" aria-expanded="false"></button>
|
|
415
|
+
</div>
|
|
416
|
+
</section>
|
|
417
|
+
</div>
|
|
418
|
+
</section>
|
|
419
|
+
|
|
282
420
|
<div class="bar">
|
|
283
421
|
<!-- 初始值是「命盘类(紫微/八字)」的示例默认:出生时间必然是过去,不取当前时刻。
|
|
284
422
|
切到六爻/梅花/六壬等起卦类 tab 时,web-ui.js 会自动把这两个框换成你的本机当前时刻。 -->
|
|
@@ -415,10 +553,12 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
415
553
|
<div class="seg" id="fsmode">
|
|
416
554
|
<button data-mode="natal" class="on">命卦</button>
|
|
417
555
|
<button data-mode="advise">门主灶</button>
|
|
556
|
+
<button data-mode="xuankong">玄空</button>
|
|
418
557
|
</div>
|
|
419
558
|
</div>
|
|
420
559
|
<label class="field" id="fs-advise" style="display:none">坐山<input id="sitting" placeholder="如 子 / 乾" value="子"></label>
|
|
421
560
|
<label class="field" id="fs-advise2" style="display:none">朝向<input id="facing" placeholder="如 午 / 巽" value="午"></label>
|
|
561
|
+
<label class="field" id="fs-period" style="display:none">运(1–9)<input id="fsperiod" type="number" min="1" max="9" value="9"></label>
|
|
422
562
|
</div>
|
|
423
563
|
<!-- 人格问卷:4 题一页、1–5 打分。题目与 1–5 的说明由 web-ui 从引擎取,
|
|
424
564
|
这里只放容器与翻页骨架,避免题目在页面和引擎里各抄一份 -->
|
|
@@ -467,7 +607,7 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
|
|
|
467
607
|
<h3>对拍:把典籍当期望值</h3>
|
|
468
608
|
<ul><li>六爻:京房八宫卦序与世应,64 卦全表;旬空六旬表</li><li>六壬:日干寄宫、中气换将;紫微:纳音定五行局、紫微天府相照</li><li>卦例:《增删卜易》9 条 +《卜筮正宗》128 条(93 成对 + 35 静卦),核本变卦 / 动爻数 / 卦宫 / 缺爻 / 旬空</li></ul>
|
|
469
609
|
<h3>工程验证</h3>
|
|
470
|
-
<ul><li>测试:
|
|
610
|
+
<ul><li>测试:94 个测试文件 / 3643 条断言;七道闸(回归 · 断言基线 · 测试可失败自检 · HTML 注入面 · 工程约定 · 产物宿主形态 · 随机扫射)</li><li>可复现:seed / asOf 显式;同一输入同一输出</li><li>口径:晚子时、真太阳时、奇门三流派、闰月归月都可切换,并有字段级差异对照</li></ul>
|
|
471
611
|
<h3>已知边界(不猜)</h3>
|
|
472
612
|
<ul><li>六爻应期(具体哪天应验)不做;卦例只录动爻个数,不录爻位</li><li>财富/健康只给结构判断与档位,不给金额区间、不作诊断</li><li>紫微飞星已做「单一支化逐宫追到成环」与「三方四正 16 条按落宫归堆」,但都未叠大限流年四化、不折吉凶;八字交运日已能算到日/时,但未与第三方排盘案例批量对拍</li></ul>
|
|
473
613
|
<p class="note">内容用于传统文化学习与自我探索,不构成医疗、投资、法律或人事决策依据。</p>
|
|
@@ -3287,6 +3427,8 @@ return { QT_BRANCHES, QT_MONTHS, QT_BASE_URL, QT_NOTE, QT, qtOf, qtLine };
|
|
|
3287
3427
|
|
|
3288
3428
|
__mods.classics = (function () {
|
|
3289
3429
|
// 古籍原文库:《子平真诠》《滴天髓》《三命通会》里与「格局取用」「十神喜忌」「寒暖燥湿」直接相关的条目。
|
|
3430
|
+
// 三命通会另收专旺五格与弃命从财/从煞七篇——这是三书里仅有的「专旺 / 从格」可整段照录的专章。
|
|
3431
|
+
// 十神篇里正财、偏财分开立章,故两格各取本格一条;七杀没有单列专章,取卷五「官煞去留杂论」。
|
|
3290
3432
|
// 原文照录(公共版权:清·沈孝瞻《子平真诠》、明·京图《滴天髓》、明·万民英《三命通会》通行本),仅供文化研究与参考。
|
|
3291
3433
|
// 出处以中华典藏网在线本为准(逐条给 url),异文处不合并、不改写;plain 是本站自撰白话,不是原文。
|
|
3292
3434
|
|
|
@@ -3322,7 +3464,7 @@ const CLASSICS = [
|
|
|
3322
3464
|
book: 'ziping',
|
|
3323
3465
|
chapter: '三十三、论财',
|
|
3324
3466
|
scene: '格局',
|
|
3325
|
-
tags: ['财'],
|
|
3467
|
+
tags: ['财', '正财', '偏财'],
|
|
3326
3468
|
quote: '财为我克,使用之物也,以能生官,所以为美。为财帛,为妻妾,为才能,为驿马,皆财类也。',
|
|
3327
3469
|
plain: '财是我所克、能为我用之物,因能生官而美;它同时代表钱财、配偶、才能、走动,不只「钱」一项。',
|
|
3328
3470
|
url: 'https://www.diancang.xyz/xuanxuewushu/zipingzhenquan/53653.html',
|
|
@@ -3507,6 +3649,16 @@ const CLASSICS = [
|
|
|
3507
3649
|
plain: '看精神不能偏执一端,要在损益之间求其中。',
|
|
3508
3650
|
url: 'https://www.diancang.xyz/xuanxuewushu/ditiansui/153091.html',
|
|
3509
3651
|
},
|
|
3652
|
+
{
|
|
3653
|
+
id: 'dt-tongguan',
|
|
3654
|
+
book: 'ditian',
|
|
3655
|
+
chapter: '通神论·通关',
|
|
3656
|
+
scene: '用神',
|
|
3657
|
+
tags: [],
|
|
3658
|
+
quote: '关内有织女,关外有牛郎,此关若通也,相邀入洞房。',
|
|
3659
|
+
plain: '两股力隔着一道关相望:一边织女、一边牛郎,中间若有一行能把两边接上(一方生它、它再生另一方),对峙就化成相生。原文只给取象,哪一行为关要按五行生克定。',
|
|
3660
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/ditiansui/153091.html',
|
|
3661
|
+
},
|
|
3510
3662
|
// —— 三命通会(明·万民英):同一组十神,子平真诠说「怎么用」,三命通会说「怎么取、怕什么」。
|
|
3511
3663
|
// 两书并列取用,按同一 tag 各取一条对照读,不合并、不裁定谁对。
|
|
3512
3664
|
{
|
|
@@ -3524,11 +3676,21 @@ const CLASSICS = [
|
|
|
3524
3676
|
book: 'sanming',
|
|
3525
3677
|
chapter: '卷六·论正财',
|
|
3526
3678
|
scene: '格局',
|
|
3527
|
-
tags: ['财'],
|
|
3679
|
+
tags: ['财', '正财'],
|
|
3528
3680
|
quote: '正财者,乃甲见己、乙见戊之例。受我克制,为我之妻,譬人娶妻,妻赍财嫁我,我必精神康强,而后可享用,若衰微不振,虽妻财丰厚,但能目视,终不得用。',
|
|
3529
3681
|
plain: '正财是我克制之物,古人以「娶妻带财」作比:自身精神康强才受用得起,身弱不振,财再厚也只是看着。',
|
|
3530
3682
|
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7645.html',
|
|
3531
3683
|
},
|
|
3684
|
+
{
|
|
3685
|
+
id: 'smt-piancai',
|
|
3686
|
+
book: 'sanming',
|
|
3687
|
+
chapter: '卷六·论偏财',
|
|
3688
|
+
scene: '格局',
|
|
3689
|
+
tags: ['财', '偏财'],
|
|
3690
|
+
quote: '何谓偏财?乃甲见戊、乙见己之例。非妻所带,乃众人之财也。切忌有姊妹兄弟分夺,柱无官星,祸患百出。',
|
|
3691
|
+
plain: '偏财取「我克而阴阳不同」:不是妻家带来的私财,而是众人之财,宜流通不宜独占。原文最忌比肩劫财来分夺,又说柱中无官星则多事(旧说的重话照录,本插件只记原文、不作断语)。',
|
|
3692
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7650.html',
|
|
3693
|
+
},
|
|
3532
3694
|
{
|
|
3533
3695
|
id: 'smt-yinshou',
|
|
3534
3696
|
book: 'sanming',
|
|
@@ -3579,6 +3741,90 @@ const CLASSICS = [
|
|
|
3579
3741
|
plain: '月令建禄是日主临官之地,身旺而财官难取:古说难承祖业、见财不聚,但病少寿长;再走比肩运,古书说克妻妨父损子(属于旧说的重话,本插件只记原文、不作断语)。',
|
|
3580
3742
|
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7672.html',
|
|
3581
3743
|
},
|
|
3744
|
+
// 此本三命通会没有单列的「论偏官」章,七煞与正官混见的情形收在卷五「官煞去留杂论」;
|
|
3745
|
+
// 七杀格的三命对照取这一篇,章名照录,不改写成「论偏官」。
|
|
3746
|
+
{
|
|
3747
|
+
id: 'smt-guansha-liu',
|
|
3748
|
+
book: 'sanming',
|
|
3749
|
+
chapter: '卷五·官煞去留杂论',
|
|
3750
|
+
scene: '格局',
|
|
3751
|
+
tags: ['七杀', '偏官'],
|
|
3752
|
+
quote: '凡看去留,要详柱中官煞孰重孰轻,天干透者易去,月支所藏者难去,须伤官食神去官煞之物众而有力,方才去得。',
|
|
3753
|
+
plain: '官煞混见时先比谁重谁轻:天干透出的容易去,月支藏着的难去;用来去官煞的伤官食神要成众、有根有力,才真去得掉。七杀格遇正官混杂,就按这一篇看取舍。',
|
|
3754
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7599.html',
|
|
3755
|
+
},
|
|
3756
|
+
// —— 三命通会 · 专旺五格与弃命从格:单章原文,专供「专旺格 / 从格」直接在结果里读。
|
|
3757
|
+
// 原文的条件比「身强」二字细:要局全、要带印或带火炼金、要防冲刑死绝。照录不分拆。
|
|
3758
|
+
{
|
|
3759
|
+
id: 'smt-quzhi',
|
|
3760
|
+
book: 'sanming',
|
|
3761
|
+
chapter: '卷六·曲直',
|
|
3762
|
+
scene: '格局',
|
|
3763
|
+
tags: ['曲直格', '专旺'],
|
|
3764
|
+
quote: '甲乙日得亥卯未局,柱中须有亥字带印为入格,若无亥有卯,止是木之本气,却要见金土为贵,既无亥字,又无金土,则木不秀不实,难以言贵。',
|
|
3765
|
+
plain: '曲直格要木局成方(亥卯未)且带亥字为印,才算入格;只有卯、没有亥,只是木的本气,得另见金土才谈得上贵;两样都没有,木虽旺而无成,难称贵格。',
|
|
3766
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7630.html',
|
|
3767
|
+
},
|
|
3768
|
+
{
|
|
3769
|
+
id: 'smt-yanshang',
|
|
3770
|
+
book: 'sanming',
|
|
3771
|
+
chapter: '卷六·炎上',
|
|
3772
|
+
scene: '格局',
|
|
3773
|
+
tags: ['炎上格', '专旺'],
|
|
3774
|
+
quote: '丙丁日遇寅午戌局,柱中须有寅字带印为入格,无寅止是九流近贵之命,若火自旺,无亥水相济,不贵。喜东北方运,忌见辰丑戊己,晦火光明,多主眼疾,或患风气,柱有木制成贵,忌水金乡,怕冲。',
|
|
3775
|
+
plain: '炎上格要火局成方(寅午戌)且带寅字为印才入格;无寅只是偏贵的命。火自旺还要一点水相济,过燥不贵;行运喜东北、忌湿土晦火,也怕冲。原文另带「多主眼疾」一句,属于旧说,本插件只记原文、不作健康判断。',
|
|
3776
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7631.html',
|
|
3777
|
+
},
|
|
3778
|
+
{
|
|
3779
|
+
id: 'smt-congge',
|
|
3780
|
+
book: 'sanming',
|
|
3781
|
+
chapter: '卷六·从革',
|
|
3782
|
+
scene: '格局',
|
|
3783
|
+
tags: ['从革格', '专旺'],
|
|
3784
|
+
quote: '庚辛日见巳酉丑局,须带丙丁巳午一二位方成其器,但不可火多。如辛巳、辛酉、辛丑三日不喜五月生,被火所伤,宜八月或水土养育食神印绶为吉。',
|
|
3785
|
+
plain: '从革格是金局成方(巳酉丑),但金要火炼才成器:须带丙丁或巳午一二位,火又不能多。辛巳、辛酉、辛丑三日出身在五月(火旺)被伤,原文说宜八月或水土养育。',
|
|
3786
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7632.html',
|
|
3787
|
+
},
|
|
3788
|
+
{
|
|
3789
|
+
id: 'smt-runxia',
|
|
3790
|
+
book: 'sanming',
|
|
3791
|
+
chapter: '卷六·润下',
|
|
3792
|
+
scene: '格局',
|
|
3793
|
+
tags: ['润下格', '专旺'],
|
|
3794
|
+
quote: '壬癸日见申子辰全,忌引卯巳死绝之地,三刑四冲之乡,死绝则不流,冲刑则横流,岁运同。或曰水太泛须柱有土神一两位制之,得成堤岸,既有土怕会木为凶,如有木伤土要金印救解,终是一生成败。',
|
|
3795
|
+
plain: '润下格是水局三合全(申子辰),最忌卯巳死绝与三刑四冲:死绝水不流,冲刑水横流,行运也一样看。水太泛要一两位土作堤,有土又怕木来破堤,木伤土再用金印解救——原文把成败条件摊开讲。',
|
|
3796
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7633.html',
|
|
3797
|
+
},
|
|
3798
|
+
{
|
|
3799
|
+
id: 'smt-jiasi',
|
|
3800
|
+
book: 'sanming',
|
|
3801
|
+
chapter: '卷六·稼穑',
|
|
3802
|
+
scene: '格局',
|
|
3803
|
+
tags: ['稼穑格', '专旺'],
|
|
3804
|
+
quote: '赋云:戊己忻逢四季,乃为稼穑之名。是戊己生逢季月,喜见木为官,止得一木为妙,木多则土虚,主虚诈为破家不仁之人。',
|
|
3805
|
+
plain: '稼穑格取戊己生于四季月(辰戌丑未)。原文说喜见一木为官,木多则土虚;后半对木多之人的评语是旧说的重话,本插件只照录条件、不拿来评价人。',
|
|
3806
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7634.html',
|
|
3807
|
+
},
|
|
3808
|
+
{
|
|
3809
|
+
id: 'smt-congsha',
|
|
3810
|
+
book: 'sanming',
|
|
3811
|
+
chapter: '卷五·弃命从煞',
|
|
3812
|
+
scene: '格局',
|
|
3813
|
+
tags: ['从杀格'],
|
|
3814
|
+
quote: '《独步》云:弃命从煞,须要会煞从财,忌煞从煞。盖言从煞格,以煞神太重,身无所归,不得已从之,要行煞旺及财乡,四柱无一点比肩印绶方论,如遇运扶身旺,与煞为敌,从煞不专,故为祸患。',
|
|
3815
|
+
plain: '从煞格是煞太重、日主无所归才「弃命」相从:条件是四柱没有一点比肩印绶扶身,行运喜煞旺与财乡;一旦走扶身之运,与煞为敌,就从得不专。本插件只作结构说明,不据此断寿夭。',
|
|
3816
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7598.html',
|
|
3817
|
+
},
|
|
3818
|
+
{
|
|
3819
|
+
id: 'smt-congcai',
|
|
3820
|
+
book: 'sanming',
|
|
3821
|
+
chapter: '卷六·弃命从财',
|
|
3822
|
+
scene: '格局',
|
|
3823
|
+
tags: ['从财格'],
|
|
3824
|
+
quote: '《独步》云:弃命从财,须要会财,若逢根气,命损无猜。假如丁生酉月,柱多庚辛,日干无气,只得弃命相从,运入北方财官旺地,乃为入格,南行灾。',
|
|
3825
|
+
plain: '从财格要财会成局、日干无气;一见根气就破格,原文用「命损无猜」这种重话写明。以丁生酉月、柱多庚辛为例:只能弃命相从,行北方财官旺地为入格,南行则灾。',
|
|
3826
|
+
url: 'https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7652.html',
|
|
3827
|
+
},
|
|
3582
3828
|
];
|
|
3583
3829
|
|
|
3584
3830
|
const BY_ID = CLASSICS.reduce((m, e) => { m[e.id] = e; return m; }, {});
|
|
@@ -3588,8 +3834,8 @@ const GEJU_KEY = {
|
|
|
3588
3834
|
正官格: '正官',
|
|
3589
3835
|
七杀格: '七杀',
|
|
3590
3836
|
偏官格: '偏官',
|
|
3591
|
-
正财格: '
|
|
3592
|
-
偏财格: '
|
|
3837
|
+
正财格: '正财',
|
|
3838
|
+
偏财格: '偏财',
|
|
3593
3839
|
正印格: '印',
|
|
3594
3840
|
偏印格: '印',
|
|
3595
3841
|
食神格: '食神',
|
|
@@ -3599,6 +3845,18 @@ const GEJU_KEY = {
|
|
|
3599
3845
|
建禄格: '建禄',
|
|
3600
3846
|
};
|
|
3601
3847
|
|
|
3848
|
+
// 特殊结构 → 三命通会单章:专旺五格与弃命从财/从煞。
|
|
3849
|
+
// 从儿(食伤)、从强(印/比劫)三书里没有可整段照录的专章,故不登记、不硬凑。
|
|
3850
|
+
const SPECIAL_CLASSIC = {
|
|
3851
|
+
曲直格: 'smt-quzhi',
|
|
3852
|
+
炎上格: 'smt-yanshang',
|
|
3853
|
+
从革格: 'smt-congge',
|
|
3854
|
+
润下格: 'smt-runxia',
|
|
3855
|
+
稼穑格: 'smt-jiasi',
|
|
3856
|
+
从财格: 'smt-congcai',
|
|
3857
|
+
从杀格: 'smt-congsha',
|
|
3858
|
+
};
|
|
3859
|
+
|
|
3602
3860
|
function classicOf(id) {
|
|
3603
3861
|
return BY_ID[id] || null;
|
|
3604
3862
|
}
|
|
@@ -3620,8 +3878,8 @@ function chapterTitle(e) {
|
|
|
3620
3878
|
return e.chapter.replace(/^.*[、·]/, '').replace(/^论/, '');
|
|
3621
3879
|
}
|
|
3622
3880
|
|
|
3623
|
-
//
|
|
3624
|
-
//
|
|
3881
|
+
// 根据一张八字结果挑原文:特殊结构(专旺/从格)先取单章,再月令格(子平真诠 + 三命通会对照),
|
|
3882
|
+
// 再调候(寒暖/燥湿),最后「用神总纲」一位按盘取:有化气格取论用神变化、见组合取论用神成败救应、其余取通用总纲;去重、限量。
|
|
3625
3883
|
function classicsFor(r, limit = 5) {
|
|
3626
3884
|
if (!r) return [];
|
|
3627
3885
|
const out = [];
|
|
@@ -3632,6 +3890,11 @@ function classicsFor(r, limit = 5) {
|
|
|
3632
3890
|
out.push({ ...entry, why });
|
|
3633
3891
|
};
|
|
3634
3892
|
const gejuList = Array.isArray(r.geju) ? r.geju : (r.frame && Array.isArray(r.frame.geju) ? r.frame.geju : []);
|
|
3893
|
+
// 专旺或从格是这张盘的定义性结构,先占位;命中的单章原文在 5 条上限里不被气候/总纲挤掉。
|
|
3894
|
+
for (const g of gejuList) {
|
|
3895
|
+
const entry = g && SPECIAL_CLASSIC[g.name] ? classicOf(SPECIAL_CLASSIC[g.name]) : null;
|
|
3896
|
+
if (entry) push(entry, `本盘列有「${g.name}」,故取${CLASSIC_BOOKS[entry.book].name}「${chapterTitle(entry)}」一条`);
|
|
3897
|
+
}
|
|
3635
3898
|
for (const g of gejuList) {
|
|
3636
3899
|
if (!g || (g.kind && g.kind !== '月令格')) continue;
|
|
3637
3900
|
const tag = tagOf(g.name);
|
|
@@ -3641,13 +3904,19 @@ function classicsFor(r, limit = 5) {
|
|
|
3641
3904
|
if (alt) push(alt, `同是「${g.name}」,${CLASSIC_BOOKS[alt.book].name}「${chapterTitle(alt)}」另有取法,可对照读`);
|
|
3642
3905
|
}
|
|
3643
3906
|
const cli = r.climate || (r.frame && r.frame.yongshen && (r.frame.yongshen.climate || r.frame.yongshen.tiaohou));
|
|
3907
|
+
const tg = r.frame && r.frame.yongshen && r.frame.yongshen.tongguan;
|
|
3908
|
+
const tgEntry = tg && tg.usable ? classicOf('dt-tongguan') : null;
|
|
3644
3909
|
if (cli && cli.kind && cli.kind !== '平和') {
|
|
3645
3910
|
const cold = !!(cli.cold || cli.kind.indexOf('寒') >= 0);
|
|
3646
3911
|
const hot = !!(cli.hot || cli.kind.indexOf('热') >= 0);
|
|
3647
3912
|
push(classicOf(cold ? 'dt-hannuan' : 'dt-zaoshi'), `本盘气候判为「${cli.kind}」,故取${CLASSIC_BOOKS.ditian.name}寒暖燥湿一条`);
|
|
3648
|
-
|
|
3913
|
+
// 「用神配气候」是泛论;有可通的通关结构时把这一位让给具体的通关,气候本身仍由寒暖/燥湿条承担
|
|
3914
|
+
if (!tgEntry) push(classicOf('zp-qihou'), '气候与月令用神要互参,故取子平真诠「用神配气候」一条');
|
|
3649
3915
|
if (hot) push(classicOf('dt-hannuan'), '本盘偏热,寒暖一条正对');
|
|
3650
3916
|
}
|
|
3917
|
+
if (tgEntry) {
|
|
3918
|
+
push(tgEntry, `本盘忌${tg.foe}克用${tg.use},局中${tg.bridge}${tg.weight}分可作通关,故取${CLASSIC_BOOKS.ditian.name}「通关」一条`);
|
|
3919
|
+
}
|
|
3651
3920
|
// 用神总纲位只放一条:同一个格,化气看「变化」、有组合看「成败救应」,都没有才回到四吉四凶总纲。
|
|
3652
3921
|
// 不另加位次,是因为格局两条 + 气候两条正好占满 5 条上限;总纲与具体结构二选一,避免泛论挤掉针对这张盘的话。
|
|
3653
3922
|
const huagi = gejuList.find((g) => g && g.kind === '化气格');
|
|
@@ -3871,6 +4140,36 @@ function specialPatterns(pillars, dayStem, monthBranch, strength, wuxing, gods)
|
|
|
3871
4140
|
return out;
|
|
3872
4141
|
}
|
|
3873
4142
|
|
|
4143
|
+
// ── 通关 ────────────────────────────────────────────────────
|
|
4144
|
+
// 滴天髓「通关」只给取象(织女、牛郎),这里把结构说清:
|
|
4145
|
+
// 用神与忌神两行在局中都真有分量、且相克时,五行里恰有一行能接上——克方所生、且能生被克方。
|
|
4146
|
+
// 只报这一行在局中的分量,不判「关通了就吉」。
|
|
4147
|
+
const TONGGUAN_MIN = 1.5;
|
|
4148
|
+
function tongguanOf(favor = [], avoid = [], wuxing = {}) {
|
|
4149
|
+
const w = (el) => Math.round((Number(wuxing[el]) || 0) * 10) / 10;
|
|
4150
|
+
for (const use of favor) {
|
|
4151
|
+
if (w(use) < TONGGUAN_MIN) continue;
|
|
4152
|
+
for (const foe of avoid) {
|
|
4153
|
+
if (OVERCOMES[foe] !== use || w(foe) < TONGGUAN_MIN) continue;
|
|
4154
|
+
const bridge = GENERATES[foe];
|
|
4155
|
+
if (!bridge || GENERATES[bridge] !== use) continue;
|
|
4156
|
+
const weight = w(bridge);
|
|
4157
|
+
const bridgeIsAvoid = avoid.includes(bridge) && !favor.includes(bridge);
|
|
4158
|
+
const level = bridgeIsAvoid ? '为忌' : weight >= TONGGUAN_MIN ? '可通' : weight > 0 ? '关弱' : '未通';
|
|
4159
|
+
return {
|
|
4160
|
+
use, foe, bridge,
|
|
4161
|
+
weight,
|
|
4162
|
+
present: weight > 0,
|
|
4163
|
+
bridgeIsAvoid,
|
|
4164
|
+
level,
|
|
4165
|
+
usable: level === '可通',
|
|
4166
|
+
note: '相战=用神与忌神两行各在局中 ≥1.5 分且相克;通关一行=克方所生、又能生用神的那一行(五行里唯一),只报局中分量,不据此断吉凶',
|
|
4167
|
+
};
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
return null;
|
|
4171
|
+
}
|
|
4172
|
+
|
|
3874
4173
|
// ── 用神 / 喜忌 ──────────────────────────────────────────────
|
|
3875
4174
|
|
|
3876
4175
|
|
|
@@ -3905,6 +4204,7 @@ function yongshenOf(dayStem, monthBranch, strength, wuxing, branches = []) {
|
|
|
3905
4204
|
};
|
|
3906
4205
|
const favorTenGods = Array.from(new Set(favor.flatMap((el) => expand[roleName(el)] || [])));
|
|
3907
4206
|
const avoidTenGods = Array.from(new Set(avoid.flatMap((el) => expand[roleName(el)] || [])));
|
|
4207
|
+
const tongguan = tongguanOf(favor, avoid, wuxing);
|
|
3908
4208
|
|
|
3909
4209
|
const detail = [
|
|
3910
4210
|
`日主${dayStem}${me},${strength.level}(${strength.score} 分):`,
|
|
@@ -3915,6 +4215,15 @@ function yongshenOf(dayStem, monthBranch, strength, wuxing, branches = []) {
|
|
|
3915
4215
|
: '身中和,先取调候与通关,喜忌随大运流年动态变化。',
|
|
3916
4216
|
`调候:${climate.label}(${(climate.evidence || []).join('、')})${climate.need ? `,取${climate.need.stem}${climate.need.element},忌${climate.avoidElement}` : ',气候平和'}。`,
|
|
3917
4217
|
qt ? `穷通宝鉴:${qt.month}${dayStem}${me},用神${qt.yong.join('、')}(首取${qt.primary})。` : '',
|
|
4218
|
+
tongguan
|
|
4219
|
+
? `通关:忌${tongguan.foe}克用${tongguan.use},五行以${tongguan.bridge}为关;局中${tongguan.level === '可通'
|
|
4220
|
+
? `${tongguan.bridge} ${tongguan.weight} 分,关可通`
|
|
4221
|
+
: tongguan.level === '关弱'
|
|
4222
|
+
? `仅 ${tongguan.bridge} ${tongguan.weight} 分,关弱`
|
|
4223
|
+
: tongguan.level === '为忌'
|
|
4224
|
+
? `${tongguan.bridge} ${tongguan.weight} 分但此行为忌,通关力打折`
|
|
4225
|
+
: `未见${tongguan.bridge},关未通`}(只作结构提示,不据此断吉凶)。`
|
|
4226
|
+
: '',
|
|
3918
4227
|
arb.text,
|
|
3919
4228
|
arb.clash ? '取舍:本盘按「调候优先、扶抑次之」取用;若你更认同扶抑派,可把调候当环境偏好,强弱判断不受影响。' : '',
|
|
3920
4229
|
].filter(Boolean).join('');
|
|
@@ -3931,6 +4240,7 @@ function yongshenOf(dayStem, monthBranch, strength, wuxing, branches = []) {
|
|
|
3931
4240
|
tiaohou: { ...climate, ...arb, element: climate.need ? climate.need.element : null },
|
|
3932
4241
|
climate,
|
|
3933
4242
|
qt,
|
|
4243
|
+
tongguan,
|
|
3934
4244
|
detail,
|
|
3935
4245
|
};
|
|
3936
4246
|
}
|
|
@@ -4042,7 +4352,7 @@ function analyzeBaziFrame({ pillars, dayStem, monthBranch, strength, wuxing }) {
|
|
|
4042
4352
|
};
|
|
4043
4353
|
}
|
|
4044
4354
|
|
|
4045
|
-
return { tenGod, elementRoles, scoreLuck, analyzeBaziFrame };
|
|
4355
|
+
return { tenGod, elementRoles, tongguanOf, scoreLuck, analyzeBaziFrame };
|
|
4046
4356
|
})();
|
|
4047
4357
|
|
|
4048
4358
|
__mods.bazi = (function () {
|
|
@@ -5341,6 +5651,91 @@ function yongshenStrength(result, useGod, opts = {}) {
|
|
|
5341
5651
|
};
|
|
5342
5652
|
}
|
|
5343
5653
|
|
|
5654
|
+
// ── 伏神出伏:飞伏生克 + 月建日辰,只判条件、不出应期 ─────────────────
|
|
5655
|
+
// 知识卡只承诺四件事:飞神生伏、伏神克飞、日月生扶算得力,飞神克伏算受压。
|
|
5656
|
+
// 这里把「助」与「压」分开列,再按四档归并;不排各家优先级,也不推日期。
|
|
5657
|
+
const FUSHEN_VERDICTS = ['可出', '有助有压', '受压难出', '未得助'];
|
|
5658
|
+
|
|
5659
|
+
/**
|
|
5660
|
+
* 伏神出不出得来:先看飞伏生克,再叠月建与日辰。
|
|
5661
|
+
* 助:飞生伏、伏克飞、日辰生/比和、月建旺/相;
|
|
5662
|
+
* 压:飞克伏、日辰克、月破。旬空只标出,不并入档位。
|
|
5663
|
+
* @param {object} result buildLiuyao 的结果
|
|
5664
|
+
* @param {object} useGod yongshenOf 的结果
|
|
5665
|
+
* @param {{monthBranch?: string, dayBranch?: string}} opts
|
|
5666
|
+
*/
|
|
5667
|
+
function fushenAccess(result, useGod, opts = {}) {
|
|
5668
|
+
if (!useGod || !Array.isArray(useGod.fushen) || !useGod.fushen.length) return null;
|
|
5669
|
+
const monthBranch = opts.monthBranch || null;
|
|
5670
|
+
const dayBranch = opts.dayBranch || (result && result.dayGanZhi ? result.dayGanZhi.branch : null);
|
|
5671
|
+
const monthElement = monthBranch ? zhiElementOf(monthBranch) : null;
|
|
5672
|
+
const dayElement = dayBranch ? zhiElementOf(dayBranch) : null;
|
|
5673
|
+
const kong = Array.isArray(result && result.xunKong)
|
|
5674
|
+
? result.xunKong
|
|
5675
|
+
: (result && typeof result.xunKong === 'string' ? result.xunKong.split('') : []);
|
|
5676
|
+
|
|
5677
|
+
const items = useGod.fushen.map((f) => {
|
|
5678
|
+
const element = f.element || zhiElementOf(f.branch);
|
|
5679
|
+
const relation = f.relation || null;
|
|
5680
|
+
const monthState = monthStateOf(element, monthElement);
|
|
5681
|
+
const monthChong = !!(monthBranch && CHONG_OF[f.branch] === monthBranch);
|
|
5682
|
+
const dayRelation = dayRelationOf(element, dayElement);
|
|
5683
|
+
const kongz = kong.includes(f.branch);
|
|
5684
|
+
|
|
5685
|
+
const supports = [];
|
|
5686
|
+
if (relation === '飞生伏') supports.push('飞神生伏');
|
|
5687
|
+
if (relation === '伏克飞') supports.push('伏神克飞');
|
|
5688
|
+
if (dayRelation === '日生') supports.push('日辰生伏');
|
|
5689
|
+
if (dayRelation === '比和') supports.push('日辰比和');
|
|
5690
|
+
if (monthState === '旺') supports.push('月建同气');
|
|
5691
|
+
if (monthState === '相') supports.push('月建相生');
|
|
5692
|
+
|
|
5693
|
+
const pressures = [];
|
|
5694
|
+
if (relation === '飞克伏') pressures.push('飞神克伏');
|
|
5695
|
+
if (dayRelation === '日克') pressures.push('日辰克伏');
|
|
5696
|
+
if (monthChong) pressures.push('月破');
|
|
5697
|
+
|
|
5698
|
+
const verdict = !relation ? '飞伏未知'
|
|
5699
|
+
: supports.length && pressures.length ? '有助有压'
|
|
5700
|
+
: supports.length ? '可出'
|
|
5701
|
+
: pressures.length ? '受压难出' : '未得助';
|
|
5702
|
+
const basis = monthBranch && dayBranch ? '月建日辰' : monthBranch ? '月建' : dayBranch ? '日辰' : '飞伏';
|
|
5703
|
+
|
|
5704
|
+
const facts = [];
|
|
5705
|
+
if (relation) facts.push(`飞伏${relation}`);
|
|
5706
|
+
if (monthBranch) facts.push(`月建${monthBranch}(${monthElement})${monthState}${monthChong ? '、月破' : ''}`);
|
|
5707
|
+
if (dayBranch) facts.push(`日辰${dayBranch}(${dayElement})${dayRelation}`);
|
|
5708
|
+
if (kongz) facts.push('伏神旬空');
|
|
5709
|
+
const say = `第${f.position}爻${f.branch}${element}:${facts.join(',')} → ${verdict}` +
|
|
5710
|
+
`(助:${supports.join('、') || '无'};压:${pressures.join('、') || '无'})`;
|
|
5711
|
+
|
|
5712
|
+
return {
|
|
5713
|
+
position: f.position,
|
|
5714
|
+
branch: f.branch,
|
|
5715
|
+
element,
|
|
5716
|
+
relation,
|
|
5717
|
+
fei: f.fei || null,
|
|
5718
|
+
monthState,
|
|
5719
|
+
monthChong,
|
|
5720
|
+
dayRelation,
|
|
5721
|
+
kong: kongz,
|
|
5722
|
+
basis,
|
|
5723
|
+
supports,
|
|
5724
|
+
pressures,
|
|
5725
|
+
verdict,
|
|
5726
|
+
say,
|
|
5727
|
+
};
|
|
5728
|
+
});
|
|
5729
|
+
|
|
5730
|
+
return {
|
|
5731
|
+
month: monthBranch ? { branch: monthBranch, element: monthElement } : null,
|
|
5732
|
+
day: dayBranch ? { branch: dayBranch, element: dayElement } : null,
|
|
5733
|
+
items,
|
|
5734
|
+
labels: items.map((it) => `第${it.position}爻${it.verdict}`),
|
|
5735
|
+
note: '出伏只看「有没有助、有没有压」两件事:飞生伏、伏克飞、日辰生/比和、月建旺/相算助;飞克伏、日辰克、月破算压。四档只把条件并列,不排各家优先级;旬空只标出,不并入档位,也不出应期。',
|
|
5736
|
+
};
|
|
5737
|
+
}
|
|
5738
|
+
|
|
5344
5739
|
// ── 全卦逐爻旺衰:月建日辰落到六爻全部 ──────────────────────────────
|
|
5345
5740
|
// 与用神旺衰同一套判定(月令五态、日辰五关系、三种冲法),区别只在不挑用神:
|
|
5346
5741
|
// 六爻每一爻都给一次,世应、动爻、旬空另标,看得出整张卦的气压在哪一头。
|
|
@@ -5486,7 +5881,7 @@ function jinTuiPower(result, opts = {}) {
|
|
|
5486
5881
|
};
|
|
5487
5882
|
}
|
|
5488
5883
|
|
|
5489
|
-
return { jinTuiOf, hexBody, bodyRelations, bodyLabels, HEXAGRAM_COUNT, hexagramFromBits, YONGSHEN_RULES, yongshenOf, tossLines, buildLiuyao, zhiElementOf, monthStateOf, dayRelationOf, yongshenStrength, hexagramStrength, jinTuiPower };
|
|
5884
|
+
return { jinTuiOf, hexBody, bodyRelations, bodyLabels, HEXAGRAM_COUNT, hexagramFromBits, YONGSHEN_RULES, yongshenOf, tossLines, buildLiuyao, zhiElementOf, monthStateOf, dayRelationOf, yongshenStrength, FUSHEN_VERDICTS, fushenAccess, hexagramStrength, jinTuiPower };
|
|
5490
5885
|
})();
|
|
5491
5886
|
|
|
5492
5887
|
__mods.ziwei = (function () {
|
|
@@ -5566,12 +5961,182 @@ const MUTAGEN = {
|
|
|
5566
5961
|
癸: { 破军: '禄', 巨门: '权', 太阴: '科', 贪狼: '忌' },
|
|
5567
5962
|
};
|
|
5568
5963
|
|
|
5964
|
+
// ── 流派开关 ──────────────────────────────────────────────────
|
|
5965
|
+
// 默认值对齐本插件既有盘面:亮度用内置通行表,庚干用阳武阴同,
|
|
5966
|
+
// 天马按年支、魁钺用全书理解一、天使天伤不换、长生按现有五行局表、
|
|
5967
|
+
// 晚子时仍算当日;天空/截空旬空默认不排(旧盘没有这两组星,保持 49 颗)。
|
|
5968
|
+
// 其余选项只在显式指定时改变盘面,不影响默认输出。
|
|
5969
|
+
const ZIWEI_SCHOOL_DEFAULTS = Object.freeze({
|
|
5970
|
+
brightnessSchool: 'default',
|
|
5971
|
+
gengYearSihua: 'GYWYT',
|
|
5972
|
+
tianmaSchool: 'year-branch',
|
|
5973
|
+
tiankongSchool: 'off',
|
|
5974
|
+
jiekongSchool: 'off',
|
|
5975
|
+
kuiyueSchool: 'qs1',
|
|
5976
|
+
tianshiTianshang: 'normal',
|
|
5977
|
+
changshengSchool: 'yin-yang-shun-ni',
|
|
5978
|
+
lateZishi: 'current-day',
|
|
5979
|
+
});
|
|
5980
|
+
|
|
5981
|
+
const ZIWEI_SCHOOL_OPTIONS = Object.freeze({
|
|
5982
|
+
brightnessSchool: ['default', 'QS', 'XD1', 'ZZ', 'XD2'],
|
|
5983
|
+
gengYearSihua: ['GYWYT', 'GYWTY', 'GYWFT', 'GYWFX', 'GYWTX'],
|
|
5984
|
+
tianmaSchool: ['year-branch', 'month-branch'],
|
|
5985
|
+
tiankongSchool: ['off', 'normal', 'shun-jia-shi'],
|
|
5986
|
+
jiekongSchool: ['off', 'double', 'single', 'zhanyan'],
|
|
5987
|
+
kuiyueSchool: ['qs1', 'qs2', 'zhong-yiming', 'network'],
|
|
5988
|
+
tianshiTianshang: ['normal', 'zhongzhou'],
|
|
5989
|
+
changshengSchool: ['yin-yang-shun-ni', 'shui-tu', 'huo-tu'],
|
|
5990
|
+
lateZishi: ['current-day', 'next-day', 'all-current', 'day-cur-time-next'],
|
|
5991
|
+
});
|
|
5992
|
+
|
|
5993
|
+
function ziweiSchoolsOf(input = {}) {
|
|
5994
|
+
const nested = input.schools && typeof input.schools === 'object' ? input.schools : {};
|
|
5995
|
+
const out = {};
|
|
5996
|
+
for (const [key, allowed] of Object.entries(ZIWEI_SCHOOL_OPTIONS)) {
|
|
5997
|
+
const raw = input[key] !== undefined ? input[key] : nested[key];
|
|
5998
|
+
out[key] = allowed.includes(raw) ? raw : ZIWEI_SCHOOL_DEFAULTS[key];
|
|
5999
|
+
}
|
|
6000
|
+
return out;
|
|
6001
|
+
}
|
|
6002
|
+
|
|
6003
|
+
// 亮度表按流派取值:数值 1–7 按各派档位换成中文。
|
|
6004
|
+
// QS / XD1 为七档(1庙…7陷),ZZ / XD2 为五档(1庙 2旺 3平 4闲 5陷)。
|
|
6005
|
+
const BRIGHTNESS_LEVELS_7 = ['', '庙', '旺', '得', '利', '平', '不', '陷'];
|
|
6006
|
+
const BRIGHTNESS_LEVELS_5 = ['', '庙', '旺', '平', '闲', '陷'];
|
|
6007
|
+
const BRIGHTNESS_SCHOOLS = {
|
|
6008
|
+
QS: {
|
|
6009
|
+
levels: BRIGHTNESS_LEVELS_7,
|
|
6010
|
+
rows: {
|
|
6011
|
+
紫微: [5, 1, 2, 2, 3, 2, 1, 1, 2, 2, 3, 2],
|
|
6012
|
+
天机: [1, 7, 3, 2, 4, 5, 1, 7, 3, 2, 4, 5],
|
|
6013
|
+
太阳: [7, 6, 2, 1, 2, 2, 2, 3, 3, 5, 6, 7],
|
|
6014
|
+
武曲: [2, 1, 3, 4, 1, 5, 2, 1, 3, 4, 1, 5],
|
|
6015
|
+
天同: [2, 6, 4, 5, 5, 1, 7, 6, 2, 5, 5, 1],
|
|
6016
|
+
廉贞: [5, 4, 1, 5, 4, 7, 5, 4, 1, 5, 4, 7],
|
|
6017
|
+
天府: [1, 1, 1, 3, 1, 3, 2, 1, 3, 2, 1, 3],
|
|
6018
|
+
太阴: [1, 1, 2, 7, 7, 7, 6, 6, 4, 2, 2, 1],
|
|
6019
|
+
贪狼: [2, 1, 5, 4, 1, 7, 2, 1, 5, 4, 1, 7],
|
|
6020
|
+
巨门: [2, 6, 1, 1, 7, 2, 2, 6, 1, 1, 7, 2],
|
|
6021
|
+
天相: [1, 1, 1, 7, 3, 3, 1, 3, 1, 7, 3, 3],
|
|
6022
|
+
天梁: [1, 2, 1, 1, 1, 3, 1, 2, 7, 3, 1, 7],
|
|
6023
|
+
七杀: [2, 1, 1, 2, 1, 5, 2, 1, 1, 2, 1, 5],
|
|
6024
|
+
破军: [1, 2, 3, 7, 2, 5, 1, 2, 3, 7, 2, 5],
|
|
6025
|
+
},
|
|
6026
|
+
},
|
|
6027
|
+
XD1: {
|
|
6028
|
+
levels: BRIGHTNESS_LEVELS_7,
|
|
6029
|
+
rows: {
|
|
6030
|
+
紫微: [5, 1, 1, 2, 3, 2, 1, 1, 2, 2, 3, 2],
|
|
6031
|
+
天机: [1, 7, 3, 2, 4, 5, 1, 7, 3, 2, 4, 5],
|
|
6032
|
+
太阳: [7, 6, 2, 1, 2, 2, 1, 3, 4, 5, 7, 7],
|
|
6033
|
+
武曲: [2, 1, 3, 4, 1, 5, 2, 1, 3, 4, 1, 5],
|
|
6034
|
+
天同: [2, 6, 4, 1, 5, 1, 7, 6, 2, 5, 5, 1],
|
|
6035
|
+
廉贞: [5, 4, 1, 5, 4, 7, 5, 4, 1, 5, 4, 7],
|
|
6036
|
+
天府: [1, 1, 1, 3, 2, 3, 2, 1, 3, 2, 2, 3],
|
|
6037
|
+
太阴: [1, 1, 6, 7, 7, 7, 7, 5, 4, 2, 2, 1],
|
|
6038
|
+
贪狼: [2, 1, 5, 3, 1, 7, 2, 1, 5, 4, 1, 7],
|
|
6039
|
+
巨门: [2, 6, 1, 1, 5, 5, 2, 5, 1, 1, 5, 2],
|
|
6040
|
+
天相: [1, 1, 1, 7, 5, 3, 3, 3, 1, 7, 3, 3],
|
|
6041
|
+
天梁: [1, 2, 1, 2, 1, 7, 1, 2, 7, 3, 1, 7],
|
|
6042
|
+
七杀: [2, 1, 1, 2, 3, 5, 2, 1, 1, 2, 1, 5],
|
|
6043
|
+
破军: [1, 2, 3, 7, 2, 5, 1, 2, 3, 7, 2, 5],
|
|
6044
|
+
},
|
|
6045
|
+
},
|
|
6046
|
+
ZZ: {
|
|
6047
|
+
levels: BRIGHTNESS_LEVELS_5,
|
|
6048
|
+
rows: {
|
|
6049
|
+
紫微: [3, 1, 1, 2, 5, 2, 1, 1, 2, 3, 4, 2],
|
|
6050
|
+
天机: [1, 5, 2, 2, 1, 3, 1, 5, 3, 2, 1, 3],
|
|
6051
|
+
太阳: [5, 5, 2, 1, 2, 2, 1, 3, 4, 4, 5, 5],
|
|
6052
|
+
武曲: [2, 1, 4, 5, 1, 3, 2, 1, 3, 2, 1, 3],
|
|
6053
|
+
天同: [2, 5, 4, 1, 3, 1, 5, 5, 2, 3, 3, 1],
|
|
6054
|
+
廉贞: [3, 2, 1, 4, 2, 5, 3, 1, 1, 3, 2, 5],
|
|
6055
|
+
天府: [1, 1, 1, 3, 1, 3, 2, 1, 3, 5, 1, 2],
|
|
6056
|
+
太阴: [1, 1, 4, 5, 4, 5, 5, 3, 3, 2, 2, 1],
|
|
6057
|
+
贪狼: [2, 1, 3, 4, 1, 5, 2, 1, 3, 3, 1, 5],
|
|
6058
|
+
巨门: [2, 2, 1, 1, 3, 3, 2, 5, 1, 1, 2, 2],
|
|
6059
|
+
天相: [1, 1, 1, 5, 2, 3, 2, 4, 1, 5, 4, 3],
|
|
6060
|
+
天梁: [1, 2, 1, 1, 2, 5, 1, 2, 5, 4, 2, 5],
|
|
6061
|
+
七杀: [2, 1, 1, 5, 2, 3, 2, 2, 1, 4, 1, 3],
|
|
6062
|
+
破军: [1, 2, 5, 2, 2, 4, 1, 1, 5, 5, 2, 3],
|
|
6063
|
+
},
|
|
6064
|
+
},
|
|
6065
|
+
XD2: {
|
|
6066
|
+
levels: BRIGHTNESS_LEVELS_5,
|
|
6067
|
+
rows: {
|
|
6068
|
+
紫微: [4, 1, 1, 2, 4, 2, 1, 1, 2, 3, 5, 2],
|
|
6069
|
+
天机: [1, 5, 2, 2, 2, 3, 1, 5, 2, 2, 2, 3],
|
|
6070
|
+
太阳: [5, 5, 2, 1, 2, 2, 1, 2, 3, 3, 5, 5],
|
|
6071
|
+
武曲: [2, 1, 3, 5, 1, 3, 2, 1, 3, 2, 1, 3],
|
|
6072
|
+
天同: [2, 5, 3, 1, 2, 1, 5, 5, 2, 3, 3, 1],
|
|
6073
|
+
廉贞: [3, 2, 1, 4, 2, 5, 3, 1, 1, 3, 2, 5],
|
|
6074
|
+
天府: [2, 1, 1, 3, 1, 2, 2, 1, 2, 3, 1, 2],
|
|
6075
|
+
太阴: [1, 1, 5, 5, 5, 5, 5, 5, 2, 2, 1, 1],
|
|
6076
|
+
贪狼: [2, 1, 3, 2, 1, 5, 2, 1, 3, 2, 1, 5],
|
|
6077
|
+
巨门: [2, 5, 1, 2, 5, 1, 2, 5, 1, 2, 5, 1],
|
|
6078
|
+
天相: [1, 1, 1, 5, 2, 3, 2, 3, 1, 5, 5, 3],
|
|
6079
|
+
天梁: [1, 2, 1, 1, 2, 5, 1, 2, 5, 3, 2, 5],
|
|
6080
|
+
七杀: [2, 2, 1, 5, 1, 3, 2, 2, 1, 3, 1, 3],
|
|
6081
|
+
破军: [1, 1, 5, 2, 2, 3, 1, 1, 5, 5, 2, 3],
|
|
6082
|
+
},
|
|
6083
|
+
},
|
|
6084
|
+
};
|
|
6085
|
+
|
|
6086
|
+
function schoolBrightness(name, branchIndex, school = 'default') {
|
|
6087
|
+
const table = BRIGHTNESS_SCHOOLS[school];
|
|
6088
|
+
if (!table || !table.rows[name]) return BRIGHTNESS[name] ? BRIGHTNESS[name][fix(branchIndex)] : undefined;
|
|
6089
|
+
const level = table.rows[name][fix(branchIndex)];
|
|
6090
|
+
return level ? table.levels[level] : undefined;
|
|
6091
|
+
}
|
|
6092
|
+
|
|
6093
|
+
// 庚干四化五变体
|
|
6094
|
+
const GENG_MUTAGEN = {
|
|
6095
|
+
GYWYT: { 太阳: '禄', 武曲: '权', 太阴: '科', 天同: '忌' },
|
|
6096
|
+
GYWTY: { 太阳: '禄', 武曲: '权', 天同: '科', 太阴: '忌' },
|
|
6097
|
+
GYWFT: { 太阳: '禄', 武曲: '权', 天府: '科', 天同: '忌' },
|
|
6098
|
+
GYWFX: { 太阳: '禄', 武曲: '权', 天府: '科', 天相: '忌' },
|
|
6099
|
+
GYWTX: { 太阳: '禄', 武曲: '权', 天同: '科', 天相: '忌' },
|
|
6100
|
+
};
|
|
6101
|
+
|
|
6102
|
+
function mutagenOf(stem, schools) {
|
|
6103
|
+
if (stem === '庚') return GENG_MUTAGEN[schools.gengYearSihua] || MUTAGEN.庚;
|
|
6104
|
+
return MUTAGEN[stem] ?? {};
|
|
6105
|
+
}
|
|
6106
|
+
|
|
6107
|
+
// 安魁钺四派:差异集中在庚辛壬癸年
|
|
6108
|
+
const KUI_YUE_SCHOOLS = {
|
|
6109
|
+
qs2: {
|
|
6110
|
+
甲: [1, 7], 戊: [1, 7], 庚: [6, 2], 乙: [0, 8], 己: [0, 8],
|
|
6111
|
+
丙: [11, 9], 丁: [11, 9], 辛: [6, 2], 壬: [5, 3], 癸: [5, 3],
|
|
6112
|
+
},
|
|
6113
|
+
'zhong-yiming': {
|
|
6114
|
+
甲: [1, 7], 戊: [1, 7], 庚: [2, 6], 乙: [0, 8], 己: [0, 8],
|
|
6115
|
+
丙: [11, 9], 丁: [11, 9], 辛: [2, 6], 壬: [5, 3], 癸: [5, 3],
|
|
6116
|
+
},
|
|
6117
|
+
network: {
|
|
6118
|
+
甲: [1, 7], 戊: [1, 7], 庚: [1, 7], 乙: [0, 8], 己: [0, 8],
|
|
6119
|
+
丙: [11, 9], 丁: [11, 9], 辛: [6, 2], 壬: [3, 5], 癸: [3, 5],
|
|
6120
|
+
},
|
|
6121
|
+
};
|
|
6122
|
+
|
|
6123
|
+
// 截空(按生年干):single 单星、double 正副双星、zhanyan 占验派
|
|
6124
|
+
const JIEKONG = {
|
|
6125
|
+
single: { 甲: 8, 乙: 6, 丙: 4, 丁: 2, 戊: 0, 己: 9, 庚: 7, 辛: 5, 壬: 3, 癸: 1 },
|
|
6126
|
+
double: {
|
|
6127
|
+
甲: [8, 9], 乙: [7, 6], 丙: [4, 5], 丁: [3, 2], 戊: [0, 1],
|
|
6128
|
+
己: [9, 8], 庚: [6, 7], 辛: [5, 4], 壬: [2, 3], 癸: [1, 0],
|
|
6129
|
+
},
|
|
6130
|
+
zhanyan: { 甲: 8, 乙: 6, 丙: 4, 丁: 2, 戊: 10, 己: 9, 庚: 7, 辛: 5, 壬: 3, 癸: 11 },
|
|
6131
|
+
};
|
|
6132
|
+
|
|
5569
6133
|
// 年干系
|
|
5570
6134
|
const LUCUN = { 甲: 2, 乙: 3, 丙: 5, 丁: 6, 戊: 5, 己: 6, 庚: 8, 辛: 9, 壬: 11, 癸: 0 };
|
|
5571
6135
|
const KUI_YUE = {
|
|
5572
6136
|
甲: [1, 7], 戊: [1, 7], 庚: [1, 7], 乙: [0, 8], 己: [0, 8],
|
|
5573
6137
|
丙: [11, 9], 丁: [11, 9], 辛: [6, 2], 壬: [3, 5], 癸: [3, 5],
|
|
5574
6138
|
};
|
|
6139
|
+
KUI_YUE_SCHOOLS.qs1 = KUI_YUE;
|
|
5575
6140
|
|
|
5576
6141
|
/** 命主:按命宫地支 */
|
|
5577
6142
|
const MING_ZHU = {
|
|
@@ -5684,12 +6249,31 @@ function xiaoxianAge(branchIndex, triad, gender) {
|
|
|
5684
6249
|
|
|
5685
6250
|
// ── 主流程 ────────────────────────────────────────────────────
|
|
5686
6251
|
|
|
6252
|
+
/**
|
|
6253
|
+
* 闰月口径:split 按日切分(1–15 归本月、16 起归次月,主流排盘默认)、
|
|
6254
|
+
* next 整月归次月、prev 整月归本月。`leapAsNext: true` 是 next 的旧写法。
|
|
6255
|
+
*/
|
|
6256
|
+
const LEAP_POLICIES = ['split', 'next', 'prev'];
|
|
6257
|
+
|
|
6258
|
+
function leapPolicyOf(input) {
|
|
6259
|
+
if (input && LEAP_POLICIES.includes(input.leapMonth)) return input.leapMonth;
|
|
6260
|
+
return input && input.leapAsNext ? 'next' : 'split';
|
|
6261
|
+
}
|
|
6262
|
+
|
|
6263
|
+
function effectiveLunarMonth(raw, policy) {
|
|
6264
|
+
if (!raw || !raw.isLeap) return raw ? raw.month : 0;
|
|
6265
|
+
if (policy === 'next') return (raw.month % 12) + 1;
|
|
6266
|
+
if (policy === 'split') return raw.day <= 15 ? raw.month : (raw.month % 12) + 1;
|
|
6267
|
+
return raw.month;
|
|
6268
|
+
}
|
|
6269
|
+
|
|
5687
6270
|
/**
|
|
5688
6271
|
* 排紫微斗数命盘
|
|
5689
|
-
* @param {object} input { year,month,day,hour,minute, gender,
|
|
6272
|
+
* @param {object} input { year,month,day,hour,minute, gender, leapMonth? }
|
|
5690
6273
|
*/
|
|
5691
6274
|
function buildZiwei(input) {
|
|
5692
6275
|
assertCivil(input);
|
|
6276
|
+
const schools = ziweiSchoolsOf(input);
|
|
5693
6277
|
const { year: cy, month: cm, day: cd, hour: ch = 0, minute: cmin = 0, gender = 'male' } = input;
|
|
5694
6278
|
const useTrueSolar = input.trueSolar !== false;
|
|
5695
6279
|
const geo = input.geo || (input.address ? resolveAddress(input.address) : null);
|
|
@@ -5704,7 +6288,9 @@ function buildZiwei(input) {
|
|
|
5704
6288
|
? applyTrueSolar(civilJd, longitude)
|
|
5705
6289
|
: { offsetMinutes: 0, jd: civilJd, note: '未启用真太阳时' };
|
|
5706
6290
|
// 紫微按「时辰」起盘:真太阳时若跨时辰/跨日,命盘随之改变
|
|
5707
|
-
|
|
6291
|
+
// 晚子时 next-day:23:00 后起盘日顺延一日,只改起盘日,不改真太阳时显示
|
|
6292
|
+
let eff = jdToParts(solar.jd);
|
|
6293
|
+
if (schools.lateZishi === 'next-day' && eff.hour >= 23) eff = jdToParts(solar.jd + 1);
|
|
5708
6294
|
const year = eff.year;
|
|
5709
6295
|
const month = eff.month;
|
|
5710
6296
|
const day = eff.day;
|
|
@@ -5712,9 +6298,8 @@ function buildZiwei(input) {
|
|
|
5712
6298
|
const minute = eff.minute;
|
|
5713
6299
|
|
|
5714
6300
|
const lunarRaw = solarToLunar(year, month, day);
|
|
5715
|
-
const
|
|
5716
|
-
|
|
5717
|
-
: lunarRaw.month;
|
|
6301
|
+
const leapPolicy = leapPolicyOf(input);
|
|
6302
|
+
const lunarMonth = effectiveLunarMonth(lunarRaw, leapPolicy);
|
|
5718
6303
|
const lunarDay = lunarRaw.day;
|
|
5719
6304
|
|
|
5720
6305
|
const hb = hourBranchIndex(hour, minute);
|
|
@@ -5724,6 +6309,10 @@ function buildZiwei(input) {
|
|
|
5724
6309
|
const yearStem = yearGanzhi.stem;
|
|
5725
6310
|
const yb = BRANCHES.indexOf(yearGanzhi.branch);
|
|
5726
6311
|
const triad = triadOf(yb);
|
|
6312
|
+
// 大限顺逆:阳男阴女顺行、阴男阳女逆行(天伤天使的中州派互换也要用它)
|
|
6313
|
+
const yearYang = STEMS.indexOf(yearStem) % 2 === 0;
|
|
6314
|
+
const forward = (yearYang && gender === 'male') || (!yearYang && gender === 'female');
|
|
6315
|
+
const kuiyueTable = KUI_YUE_SCHOOLS[schools.kuiyueSchool] || KUI_YUE;
|
|
5727
6316
|
|
|
5728
6317
|
// 命宫 / 身宫
|
|
5729
6318
|
const soulIndex = fix(2 + (lunarMonth - 1) - hb);
|
|
@@ -5739,12 +6328,12 @@ function buildZiwei(input) {
|
|
|
5739
6328
|
|
|
5740
6329
|
// 星曜落宫
|
|
5741
6330
|
const starsByBranch = Array.from({ length: 12 }, () => []);
|
|
5742
|
-
//
|
|
6331
|
+
// 安星:主星顺带记下所在宫的庙旺得利平不陷(亮度可按流派切换,默认用内置通行表)
|
|
5743
6332
|
const put = (branch, name, type) => {
|
|
5744
6333
|
const idx = fix(branch);
|
|
5745
6334
|
const star = { name, type };
|
|
5746
6335
|
if (type === '主星' && BRIGHTNESS[name]) {
|
|
5747
|
-
const b =
|
|
6336
|
+
const b = schoolBrightness(name, idx, schools.brightnessSchool);
|
|
5748
6337
|
if (b) star.brightness = b;
|
|
5749
6338
|
}
|
|
5750
6339
|
starsByBranch[idx].push(star);
|
|
@@ -5770,7 +6359,7 @@ function buildZiwei(input) {
|
|
|
5770
6359
|
put(lucun, '禄存', '吉星');
|
|
5771
6360
|
put(lucun + 1, '擎羊', '煞星');
|
|
5772
6361
|
put(lucun - 1, '陀罗', '煞星');
|
|
5773
|
-
const [kui, yue] =
|
|
6362
|
+
const [kui, yue] = kuiyueTable[yearStem];
|
|
5774
6363
|
put(kui, '天魁', '吉星');
|
|
5775
6364
|
put(yue, '天钺', '吉星');
|
|
5776
6365
|
|
|
@@ -5782,7 +6371,11 @@ function buildZiwei(input) {
|
|
|
5782
6371
|
put(6 + yb, '天虚', '煞星');
|
|
5783
6372
|
put(4 + yb, '龙池', '吉星');
|
|
5784
6373
|
put(10 - yb, '凤阁', '吉星');
|
|
5785
|
-
|
|
6374
|
+
// 天马:默认按年支三合,可切生月三合(正月起寅)
|
|
6375
|
+
const maTriad = schools.tianmaSchool === 'month-branch'
|
|
6376
|
+
? triadOf(fix(2 + (lunarMonth - 1)))
|
|
6377
|
+
: triad;
|
|
6378
|
+
put(TIANMA[maTriad], '天马', '吉星');
|
|
5786
6379
|
put(XIANCHI[triad], '咸池', '煞星');
|
|
5787
6380
|
put(HUAGAI[triad], '华盖', '杂曜');
|
|
5788
6381
|
const dirGroup = directionOf(yb);
|
|
@@ -5790,6 +6383,25 @@ function buildZiwei(input) {
|
|
|
5790
6383
|
put(GUASU[dirGroup], '寡宿', '煞星');
|
|
5791
6384
|
put(posuIndex(yb), '破碎', '煞星');
|
|
5792
6385
|
|
|
6386
|
+
// 空曜(默认不排,旧盘保持 49 颗)
|
|
6387
|
+
if (schools.tiankongSchool !== 'off') {
|
|
6388
|
+
put(schools.tiankongSchool === 'shun-jia-shi' ? yb + hb : yb + 1, '天空', '杂曜');
|
|
6389
|
+
}
|
|
6390
|
+
if (schools.jiekongSchool !== 'off') {
|
|
6391
|
+
const jk = JIEKONG[schools.jiekongSchool][yearStem];
|
|
6392
|
+
if (Array.isArray(jk)) {
|
|
6393
|
+
put(jk[0], '截空', '杂曜');
|
|
6394
|
+
put(jk[1], '副截', '杂曜');
|
|
6395
|
+
} else {
|
|
6396
|
+
put(jk, '截空', '杂曜');
|
|
6397
|
+
}
|
|
6398
|
+
// 旬空:本旬十日所空两支(年干支所在旬的末两位)
|
|
6399
|
+
const nianIndex = (((lunarRaw.lunarYear - 4) % 60) + 60) % 60;
|
|
6400
|
+
const decadeStart = nianIndex - (nianIndex % 10);
|
|
6401
|
+
put(decadeStart + 10, '旬空', '杂曜');
|
|
6402
|
+
put(decadeStart + 11, '副旬', '杂曜');
|
|
6403
|
+
}
|
|
6404
|
+
|
|
5793
6405
|
// 月系
|
|
5794
6406
|
put(9 + (lunarMonth - 1), '天刑', '煞星'); // 酉起正月顺行
|
|
5795
6407
|
put(1 + (lunarMonth - 1), '天姚', '煞星'); // 丑起正月顺行
|
|
@@ -5806,12 +6418,13 @@ function buildZiwei(input) {
|
|
|
5806
6418
|
put(11 + hb, '地劫', '煞星'); // 亥宫起子时,顺行
|
|
5807
6419
|
put(11 - hb, '地空', '煞星'); // 亥宫起子时,逆行
|
|
5808
6420
|
|
|
5809
|
-
//
|
|
5810
|
-
|
|
5811
|
-
put(soulIndex - 5, '
|
|
6421
|
+
// 固定宫位:天伤恒在交友、天使恒在疾厄;中州派阴男阳女互换
|
|
6422
|
+
const swapTianshi = schools.tianshiTianshang === 'zhongzhou' && !forward;
|
|
6423
|
+
put(soulIndex - (swapTianshi ? 5 : 7), '天伤', '杂曜');
|
|
6424
|
+
put(soulIndex - (swapTianshi ? 7 : 5), '天使', '杂曜');
|
|
5812
6425
|
|
|
5813
|
-
//
|
|
5814
|
-
const mutagenMap =
|
|
6426
|
+
// 生年四化(庚干按所选变体)
|
|
6427
|
+
const mutagenMap = mutagenOf(yearStem, schools);
|
|
5815
6428
|
for (const list of starsByBranch) {
|
|
5816
6429
|
for (const star of list) {
|
|
5817
6430
|
if (mutagenMap[star.name]) star.mutagen = mutagenMap[star.name];
|
|
@@ -5822,13 +6435,14 @@ function buildZiwei(input) {
|
|
|
5822
6435
|
const palaceNames = [];
|
|
5823
6436
|
for (let i = 0; i < 12; i++) palaceNames[fix(soulIndex - i)] = PALACE_NAMES[i];
|
|
5824
6437
|
|
|
5825
|
-
//
|
|
5826
|
-
const yearYang = STEMS.indexOf(yearStem) % 2 === 0;
|
|
5827
|
-
const forward = (yearYang && gender === 'male') || (!yearYang && gender === 'female');
|
|
6438
|
+
// 大限:阳男阴女顺行、阴男阳女逆行(forward 已在安星前算好)
|
|
5828
6439
|
const startAge = bureau.number;
|
|
5829
6440
|
|
|
5830
6441
|
// 十二神(长生/博士 随大限顺逆,将前/岁前 恒顺行)
|
|
5831
|
-
|
|
6442
|
+
// 土五局长生起点按流派:默认申,河洛/火土派取寅
|
|
6443
|
+
const csStart = schools.changshengSchool === 'huo-tu' && bureau.number === 5
|
|
6444
|
+
? 2
|
|
6445
|
+
: CHANGSHENG_START[bureau.number];
|
|
5832
6446
|
const shenshaAt = (branch) => {
|
|
5833
6447
|
const d = forward ? 1 : -1;
|
|
5834
6448
|
return {
|
|
@@ -5934,8 +6548,8 @@ function buildZiwei(input) {
|
|
|
5934
6548
|
liulu: BRANCHES[lu],
|
|
5935
6549
|
liuyang: BRANCHES[fix(lu + 1)],
|
|
5936
6550
|
liutuo: BRANCHES[fix(lu - 1)],
|
|
5937
|
-
liukui: BRANCHES[
|
|
5938
|
-
liuyue: BRANCHES[
|
|
6551
|
+
liukui: BRANCHES[kuiyueTable[gz.stem][0]],
|
|
6552
|
+
liuyue: BRANCHES[kuiyueTable[gz.stem][1]],
|
|
5939
6553
|
mutagen: Object.entries(MUTAGEN[gz.stem] ?? {}).map(([s, k]) => `${s}化${k}`),
|
|
5940
6554
|
daxian: dxPalace
|
|
5941
6555
|
? { palace: dxPalace.palace, start: dxPalace.daxian.start, end: dxPalace.daxian.end }
|
|
@@ -5949,13 +6563,16 @@ function buildZiwei(input) {
|
|
|
5949
6563
|
input: {
|
|
5950
6564
|
year: cy, month: cm, day: cd, hour: ch, minute: cmin,
|
|
5951
6565
|
gender,
|
|
5952
|
-
|
|
6566
|
+
leapMonth: leapPolicy,
|
|
6567
|
+
leapAsNext: leapPolicy === 'next',
|
|
5953
6568
|
longitude: longitude ?? null,
|
|
5954
6569
|
address: input.address || null,
|
|
5955
6570
|
geo,
|
|
5956
6571
|
trueSolar: useTrueSolar,
|
|
5957
6572
|
dst: { applied: !!dst.applied, note: dst.note || null },
|
|
6573
|
+
schools: { ...schools },
|
|
5958
6574
|
},
|
|
6575
|
+
schools: { ...schools },
|
|
5959
6576
|
solarTime: {
|
|
5960
6577
|
civilText: `${cy}-${String(cm).padStart(2, '0')}-${String(cd).padStart(2, '0')} ${String(ch).padStart(2, '0')}:${String(cmin).padStart(2, '0')}`,
|
|
5961
6578
|
trueSolarText: formatJd(solar.jd),
|
|
@@ -5965,10 +6582,16 @@ function buildZiwei(input) {
|
|
|
5965
6582
|
lunar: {
|
|
5966
6583
|
year: lunarRaw.lunarYear,
|
|
5967
6584
|
month: lunarMonth,
|
|
6585
|
+
monthRaw: lunarRaw.month,
|
|
5968
6586
|
day: lunarDay,
|
|
5969
6587
|
isLeap: lunarRaw.isLeap,
|
|
6588
|
+
leapPolicy,
|
|
5970
6589
|
monthStart: lunarRaw.monthStart,
|
|
5971
|
-
...(lunarRaw.isLeap ? {
|
|
6590
|
+
...(lunarRaw.isLeap ? {
|
|
6591
|
+
note: leapPolicy === 'split'
|
|
6592
|
+
? `闰${lunarRaw.month}月按日切分:1–15 按本月、16 起按次月;本盘闰月${lunarDay}日按${lunarMonth}月`
|
|
6593
|
+
: leapPolicy === 'next' ? '闰月整月按次月起盘' : '闰月整月按本月起盘',
|
|
6594
|
+
} : {}),
|
|
5972
6595
|
},
|
|
5973
6596
|
hourBranch,
|
|
5974
6597
|
yearGanzhi: yearGanzhi.name,
|
|
@@ -6004,8 +6627,9 @@ function buildZiwei(input) {
|
|
|
6004
6627
|
},
|
|
6005
6628
|
rules: {
|
|
6006
6629
|
ziweiPlacement: '借数法:局数除日数取商,商数自寅宫顺行,借数奇逆偶顺',
|
|
6007
|
-
mutagen: '
|
|
6008
|
-
|
|
6630
|
+
mutagen: '生年四化用中州派常用表;庚干可按流派切换(默认阳武阴同,另有同科阴忌、府科、府科相忌、同科相忌)',
|
|
6631
|
+
schools: `流派开关:亮度 ${schools.brightnessSchool}、庚干四化 ${schools.gengYearSihua}、天马 ${schools.tianmaSchool}、天空 ${schools.tiankongSchool}、截空 ${schools.jiekongSchool}、魁钺 ${schools.kuiyueSchool}、天伤天使 ${schools.tianshiTianshang}、长生 ${schools.changshengSchool}、晚子时 ${schools.lateZishi};庚干四化只作用于生年四化`,
|
|
6632
|
+
leapMonth: '闰月默认按日切分(1–15 归本月、16 起归次月,主流排盘口径);可传 leapMonth: next(整月归次月)或 prev(整月归本月),leapAsNext: true 等同 next',
|
|
6009
6633
|
auxStars: '火铃按年支三合起点顺数至生时;羊陀夹禄存;魁钺按年干;地空亥起子时逆行、地劫顺行;三台八座随辅弼;恩光天贵随昌曲退一位;台辅封诰按时支',
|
|
6010
6634
|
shensha: '长生、博士随大限顺逆;将前、岁前恒顺行;天伤恒在交友、天使恒在疾厄',
|
|
6011
6635
|
masters: '命主按命宫地支,身主按生年地支',
|
|
@@ -6442,8 +7066,7 @@ function flowOf(chart, asOf) {
|
|
|
6442
7066
|
const MI = a.minute === undefined ? now.getMinutes() : a.minute;
|
|
6443
7067
|
|
|
6444
7068
|
const lr = solarToLunar(Y, M, D);
|
|
6445
|
-
const
|
|
6446
|
-
const natalMonth = chart.lunar.isLeap && leapAsNext ? (chart.lunar.month % 12) + 1 : chart.lunar.month;
|
|
7069
|
+
const natalMonth = chart.lunar.month; // 已在起盘时按闰月口径换算过,这里不再二次换月
|
|
6447
7070
|
const natalHB = BRANCHES.indexOf(chart.hourBranch);
|
|
6448
7071
|
const hbNow = hourBranchIndex(H, MI);
|
|
6449
7072
|
|
|
@@ -6502,7 +7125,7 @@ function flowOf(chart, asOf) {
|
|
|
6502
7125
|
};
|
|
6503
7126
|
}
|
|
6504
7127
|
|
|
6505
|
-
return { PALACE_NAMES, BRIGHTNESS, MUTAGEN, LUCUN, KUI_YUE, MING_ZHU, SHEN_ZHU, triadOf, HUO_START, LING_START, TIANMA, XIANCHI, HUAGAI, JIANGXING, GUCHEN, GUASU, posuIndex, XIAOXIAN_START, CHANGSHENG_NAMES, BOSHI_NAMES, JIANGQIAN_NAMES, SUIQI_NAMES, CHANGSHENG_START, hourBranchIndex, ziweiTianfuIndex, xiaoxianAge, buildZiwei, detectPatterns, PATTERN_TONE, daxianList, FLY_TYPES, flyStarOf, flyStars, flyChain, flyChains, flyComposite, enrichLiunian, asOfParts, flowOf };
|
|
7128
|
+
return { PALACE_NAMES, BRIGHTNESS, MUTAGEN, ZIWEI_SCHOOL_DEFAULTS, ZIWEI_SCHOOL_OPTIONS, ziweiSchoolsOf, BRIGHTNESS_SCHOOLS, schoolBrightness, KUI_YUE_SCHOOLS, LUCUN, KUI_YUE, MING_ZHU, SHEN_ZHU, triadOf, HUO_START, LING_START, TIANMA, XIANCHI, HUAGAI, JIANGXING, GUCHEN, GUASU, posuIndex, XIAOXIAN_START, CHANGSHENG_NAMES, BOSHI_NAMES, JIANGQIAN_NAMES, SUIQI_NAMES, CHANGSHENG_START, hourBranchIndex, ziweiTianfuIndex, xiaoxianAge, LEAP_POLICIES, leapPolicyOf, effectiveLunarMonth, buildZiwei, detectPatterns, PATTERN_TONE, daxianList, FLY_TYPES, flyStarOf, flyStars, flyChain, flyChains, flyComposite, enrichLiunian, asOfParts, flowOf };
|
|
6506
7129
|
})();
|
|
6507
7130
|
|
|
6508
7131
|
__mods.tarot = (function () {
|
|
@@ -7832,6 +8455,7 @@ __mods.fengshui = (function () {
|
|
|
7832
8455
|
// 参照公开通行表实现(与常见八宅/玄空入门资料一致),年紫白用纯公式,不依赖任何第三方历法库。
|
|
7833
8456
|
const { partsToJd, termInstantJd } = __mods.calendar;
|
|
7834
8457
|
const { applyDst } = __mods.dst;
|
|
8458
|
+
const { fail } = __mods.fail;
|
|
7835
8459
|
|
|
7836
8460
|
/** 九星名称表:数 → {name, color, element, star(北斗名), lucky}。 */
|
|
7837
8461
|
const NINE_STARS = {
|
|
@@ -7885,7 +8509,7 @@ const MOUNTAIN_INDEX = new Map(MOUNTAINS_24.map((x, i) => [x.m, i]));
|
|
|
7885
8509
|
function mountainInfo(name) {
|
|
7886
8510
|
const i = MOUNTAIN_INDEX.get(name);
|
|
7887
8511
|
if (i === undefined) {
|
|
7888
|
-
throw
|
|
8512
|
+
throw fail('E_INPUT', `坐向必须是 24 山之一(${MOUNTAINS_24.map((x) => x.m).join('')}),收到「${name}」——请按罗盘 24 山报坐或报向,不要自造方位词。`);
|
|
7889
8513
|
}
|
|
7890
8514
|
return { ...MOUNTAINS_24[i], index: i };
|
|
7891
8515
|
}
|
|
@@ -7972,6 +8596,127 @@ function yearlyFlying(year) {
|
|
|
7972
8596
|
|
|
7973
8597
|
const pad2 = (n) => String(n).padStart(2, '0');
|
|
7974
8598
|
|
|
8599
|
+
// ── 玄空飞星(下卦) ─────────────────────────────────────────────
|
|
8600
|
+
// 口径:三元九运每运 20 年,1864 年起一运;运盘当运星入中顺飞。
|
|
8601
|
+
// 山盘/向盘:取坐宫/向宫的运星入中,按「入中运星本宫同元龙」的阴阳定顺逆(五黄入中按本山阴阳)。
|
|
8602
|
+
// 这一步是玄空挨星的关键:不是按坐山本身的阴阳,而是按入中运星原宫对应元龙的阴阳;
|
|
8603
|
+
// 按本山阴阳会把旺山旺向算成每运固定的六局,与通行二十四山旺山旺向表对不上。
|
|
8604
|
+
|
|
8605
|
+
/** 三元九运:1864 起每 20 年一运,九运一轮(180 年)。 */
|
|
8606
|
+
function periodOfYear(year) {
|
|
8607
|
+
const k = Math.floor((year - 1864) / 20);
|
|
8608
|
+
const period = ((k % 9) + 9) % 9 + 1;
|
|
8609
|
+
const start = 1864 + 20 * k;
|
|
8610
|
+
return { period, start, end: start + 19, label: `${period}运(${start}–${start + 19})` };
|
|
8611
|
+
}
|
|
8612
|
+
|
|
8613
|
+
/** 三元龙阴阳:天元/人元四隅为阳、四正为阴;地元四正为阳、四隅为阴。 */
|
|
8614
|
+
const YANG_MOUNTAINS = new Set(['乾', '巽', '艮', '坤', '甲', '庚', '壬', '丙', '寅', '申', '巳', '亥']);
|
|
8615
|
+
const YUAN_NAME = ['地元', '天元', '人元'];
|
|
8616
|
+
|
|
8617
|
+
/** 24 山 → 三元龙 + 阴阳(MOUNTAINS_24 每卦三山依次为 地元/天元/人元)。 */
|
|
8618
|
+
const MOUNTAIN_META = {};
|
|
8619
|
+
MOUNTAINS_24.forEach((x, i) => {
|
|
8620
|
+
MOUNTAIN_META[x.m] = { ...x, yuan: YUAN_NAME[i % 3], yinYang: YANG_MOUNTAINS.has(x.m) ? '阳' : '阴' };
|
|
8621
|
+
});
|
|
8622
|
+
|
|
8623
|
+
/** 飞星轨迹:中 → 乾 → 兑 → 艮 → 离 → 坎 → 坤 → 震 → 巽(即洛书 5→6→7→8→9→1→2→3→4)。 */
|
|
8624
|
+
const FLY_SEQ = ['中', '乾', '兑', '艮', '离', '坎', '坤', '震', '巽'];
|
|
8625
|
+
const NUM_TO_GUA = ['坎', '坤', '震', '巽', '中', '乾', '兑', '艮', '离']; // 洛书数 1–9 本位卦
|
|
8626
|
+
const YUAN_INDEX = { 地元: 0, 天元: 1, 人元: 2 };
|
|
8627
|
+
|
|
8628
|
+
const mountainsOfGua = (gua) => MOUNTAINS_24.filter((x) => x.gua === gua).map((x) => MOUNTAIN_META[x.m]);
|
|
8629
|
+
|
|
8630
|
+
/** 入中星按轨迹飞布:forward=true 顺飞,false 逆飞。返回 宫 → 星数。 */
|
|
8631
|
+
function fly(center, forward) {
|
|
8632
|
+
const out = {};
|
|
8633
|
+
for (let i = 0; i < 9; i++) {
|
|
8634
|
+
const v = ((center - 1 + (forward ? i : -i)) % 9 + 9) % 9 + 1;
|
|
8635
|
+
out[FLY_SEQ[i]] = v;
|
|
8636
|
+
}
|
|
8637
|
+
return out;
|
|
8638
|
+
}
|
|
8639
|
+
|
|
8640
|
+
/** 入中运星定顺逆:取本宫(运星本位卦)同元龙之山的阴阳;五黄入中按本山阴阳。 */
|
|
8641
|
+
function flightOf(mount, center) {
|
|
8642
|
+
if (center === 5) {
|
|
8643
|
+
return { forward: mount.yinYang === '阳', basis: `五黄入中,按${mount.m}本山${mount.yuan}${mount.yinYang}论` };
|
|
8644
|
+
}
|
|
8645
|
+
const home = NUM_TO_GUA[center - 1];
|
|
8646
|
+
const hm = mountainsOfGua(home)[YUAN_INDEX[mount.yuan]];
|
|
8647
|
+
return { forward: hm.yinYang === '阳', basis: `${center}${home}宫取${mount.yuan}${hm.m}(${hm.yinYang})` };
|
|
8648
|
+
}
|
|
8649
|
+
|
|
8650
|
+
/** 通行二十四山旺山旺向表(每项含正反两向;一运、九运无局)。 */
|
|
8651
|
+
const WANG_SHAN_WANG_XIANG = {
|
|
8652
|
+
1: [],
|
|
8653
|
+
2: [['乾', '巽'], ['亥', '巳'], ['丑', '未']],
|
|
8654
|
+
3: [['卯', '酉'], ['乙', '辛'], ['辰', '戌']],
|
|
8655
|
+
4: [['艮', '坤'], ['寅', '申'], ['甲', '庚']],
|
|
8656
|
+
5: [['子', '午'], ['癸', '丁'], ['卯', '酉'], ['乙', '辛'], ['丑', '未'], ['辰', '戌']],
|
|
8657
|
+
6: [['艮', '坤'], ['寅', '申'], ['甲', '庚']],
|
|
8658
|
+
7: [['卯', '酉'], ['乙', '辛'], ['辰', '戌']],
|
|
8659
|
+
8: [['乾', '巽'], ['亥', '巳'], ['丑', '未']],
|
|
8660
|
+
9: [],
|
|
8661
|
+
};
|
|
8662
|
+
|
|
8663
|
+
const XUANKONG_SOURCES = [
|
|
8664
|
+
'三元九运(1864 年起一运、每运 20 年,九运 180 年一轮)',
|
|
8665
|
+
'玄空下卦挨星(运盘顺飞;山盘/向盘以入中运星本宫同元龙阴阳定顺逆,五黄入中按本山阴阳)',
|
|
8666
|
+
'二十四山旺山旺向通行表(每项含正反两向;一运、九运无局)',
|
|
8667
|
+
];
|
|
8668
|
+
|
|
8669
|
+
const XUANKONG_DISCLAIMER = '玄空下卦为传统通行口径的本地排盘,属民俗参考,不构成现场勘舆结论,仅供娱乐;替卦/兼向、年月日时飞星与形峦不在本工具范围内。';
|
|
8670
|
+
|
|
8671
|
+
/** 玄空下卦排盘:运盘 + 山盘 + 向盘 + 当运星 + 合十 + 表法旺山旺向。 */
|
|
8672
|
+
function xuankongChart(period, sitting, facing) {
|
|
8673
|
+
const sit = MOUNTAIN_META[sitting];
|
|
8674
|
+
const face = MOUNTAIN_META[facing];
|
|
8675
|
+
const yun = fly(period, true);
|
|
8676
|
+
const sCenter = yun[sit.gua];
|
|
8677
|
+
const fCenter = yun[face.gua];
|
|
8678
|
+
const sFly = flightOf(sit, sCenter);
|
|
8679
|
+
const fFly = flightOf(face, fCenter);
|
|
8680
|
+
const shan = fly(sCenter, sFly.forward);
|
|
8681
|
+
const xiang = fly(fCenter, fFly.forward);
|
|
8682
|
+
const palaces = PALACE_ORDER.map((palace, i) => ({
|
|
8683
|
+
palace,
|
|
8684
|
+
direction: palace === '中' ? '中宫' : PALACE_DIRECTION[palace],
|
|
8685
|
+
luoshu: i + 1,
|
|
8686
|
+
yun: yun[palace],
|
|
8687
|
+
shan: shan[palace],
|
|
8688
|
+
xiang: xiang[palace],
|
|
8689
|
+
}));
|
|
8690
|
+
const wheres = (map) => PALACE_ORDER.filter((p) => map[p] === period);
|
|
8691
|
+
const pairs = WANG_SHAN_WANG_XIANG[period];
|
|
8692
|
+
const hit = pairs.find(([a, b]) => (sit.m === a && face.m === b) || (sit.m === b && face.m === a));
|
|
8693
|
+
const byChart = shan[sit.gua] === period && xiang[face.gua] === period;
|
|
8694
|
+
const note = byChart && hit
|
|
8695
|
+
? '盘面与表法一致:本局到山到向。'
|
|
8696
|
+
: byChart
|
|
8697
|
+
? '盘面到山到向,但不在通行表法所列之局(表法与盘面口径不同,并列不合并)。'
|
|
8698
|
+
: hit
|
|
8699
|
+
? '通行表法列为旺山旺向,但本盘当运山星/向星未同时落坐向(表法与盘面口径不同,并列不合并)。'
|
|
8700
|
+
: '本局既未到山到向,也不在表法旺山旺向之列。';
|
|
8701
|
+
return {
|
|
8702
|
+
palaces,
|
|
8703
|
+
sitting: sit,
|
|
8704
|
+
facing: face,
|
|
8705
|
+
yun,
|
|
8706
|
+
shan,
|
|
8707
|
+
xiang,
|
|
8708
|
+
yunCenter: period,
|
|
8709
|
+
shanCenter: { star: sCenter, ...sFly },
|
|
8710
|
+
xiangCenter: { star: fCenter, ...fFly },
|
|
8711
|
+
dangYun: { shan: wheres(shan), xiang: wheres(xiang) },
|
|
8712
|
+
heshi: {
|
|
8713
|
+
shan: PALACE_ORDER.filter((p) => shan[p] + yun[p] === 10),
|
|
8714
|
+
xiang: PALACE_ORDER.filter((p) => xiang[p] + yun[p] === 10),
|
|
8715
|
+
},
|
|
8716
|
+
wangShanWangXiang: { byChart, byTable: Boolean(hit), table: pairs.map(([a, b]) => `${a}${b}`), note },
|
|
8717
|
+
};
|
|
8718
|
+
}
|
|
8719
|
+
|
|
7975
8720
|
/** DST 校正出生日期(1986–1991),返回校正后的年月日。 */
|
|
7976
8721
|
function civilDate(input) {
|
|
7977
8722
|
const dst = input.dst === false
|
|
@@ -7990,19 +8735,21 @@ const DISCLAIMER = '八宅与飞星为传统通行口径的本地计算,属民
|
|
|
7990
8735
|
|
|
7991
8736
|
/**
|
|
7992
8737
|
* 风水主函数。
|
|
7993
|
-
* @param {{action?:'natal'|'advise', year?:number, month?:number, day?:number, gender?:'male'|'female',
|
|
7994
|
-
* fortuneYear?:number, sitting?:string, facing?:string, dst?:boolean}} input
|
|
8738
|
+
* @param {{action?:'natal'|'advise'|'xuankong', year?:number, month?:number, day?:number, gender?:'male'|'female',
|
|
8739
|
+
* fortuneYear?:number, sitting?:string, facing?:string, period?:number, dst?:boolean}} input
|
|
7995
8740
|
* natal(默认):要生日 + 性别 + 流年(缺流年则只算命卦与八星)。
|
|
7996
8741
|
* advise:要坐山或向山(24 山,给一即可);出生信息可选,给了才做命宅配。
|
|
8742
|
+
* xuankong:要坐山或向山;运由 period(1–9)或 fortuneYear 定,缺省按九运并注明。
|
|
7997
8743
|
*/
|
|
7998
8744
|
function buildFengshui(input) {
|
|
7999
8745
|
if (input.action === 'advise') return buildAdvise(input);
|
|
8746
|
+
if (input.action === 'xuankong') return buildXuankong(input);
|
|
8000
8747
|
const gender = input.gender;
|
|
8001
8748
|
if (gender !== 'male' && gender !== 'female') {
|
|
8002
|
-
throw
|
|
8749
|
+
throw fail('E_INPUT', '风水命卦需要性别:男女命卦算法不同,不可缺省');
|
|
8003
8750
|
}
|
|
8004
8751
|
if (!Number.isInteger(input.year) || !Number.isInteger(input.month) || !Number.isInteger(input.day)) {
|
|
8005
|
-
throw
|
|
8752
|
+
throw fail('E_INPUT', '风水命卦需要完整出生年月日(公历)——只知道年份不够:命卦按立春界划分出生年');
|
|
8006
8753
|
}
|
|
8007
8754
|
const civil = civilDate(input);
|
|
8008
8755
|
const guaYear = guaYearOf(civil.year, civil.month, civil.day);
|
|
@@ -8020,7 +8767,7 @@ function buildFengshui(input) {
|
|
|
8020
8767
|
fortuneYear,
|
|
8021
8768
|
...(civil.dst.applied ? { dst: civil.dst.note } : {}),
|
|
8022
8769
|
...(fortuneYear === null ? { note: '未给流年:未算年紫白飞星(需要时补 fortuneYear)。' } : {}),
|
|
8023
|
-
scope: '八宅命卦 + 大游年八星 +
|
|
8770
|
+
scope: '八宅命卦 + 大游年八星 + 年紫白;玄空飞星见 action=xuankong;不含形峦与现场勘舆。',
|
|
8024
8771
|
},
|
|
8025
8772
|
mingGua: {
|
|
8026
8773
|
num,
|
|
@@ -8037,22 +8784,28 @@ function buildFengshui(input) {
|
|
|
8037
8784
|
};
|
|
8038
8785
|
}
|
|
8039
8786
|
|
|
8040
|
-
/**
|
|
8041
|
-
function
|
|
8787
|
+
/** 坐向解析:至少给坐或向;两者都给则必须对宫。 */
|
|
8788
|
+
function resolveSittingFacing(input) {
|
|
8042
8789
|
const hasSitting = typeof input.sitting === 'string' && input.sitting.trim() !== '';
|
|
8043
8790
|
const hasFacing = typeof input.facing === 'string' && input.facing.trim() !== '';
|
|
8044
8791
|
if (!hasSitting && !hasFacing) {
|
|
8045
|
-
throw
|
|
8792
|
+
throw fail('E_INPUT', '缺少坐向:sitting(坐山)或 facing(向山)至少给一个——按罗盘 24 山报坐或报向,例如「坐北朝南」对应坐子向午');
|
|
8046
8793
|
}
|
|
8047
8794
|
if (hasSitting && hasFacing) {
|
|
8048
8795
|
const s = mountainInfo(input.sitting.trim());
|
|
8049
8796
|
const f = mountainInfo(input.facing.trim());
|
|
8050
8797
|
if ((s.index + 12) % 24 !== f.index) {
|
|
8051
|
-
throw
|
|
8798
|
+
throw fail('E_INPUT', `坐向不自洽:坐${s.m}(${s.deg}°)与向${f.m}(${f.deg}°)不是对宫(相差应 180°,实测 ${((f.deg - s.deg) + 360) % 360}°)——请核对罗盘读数。`);
|
|
8052
8799
|
}
|
|
8053
8800
|
}
|
|
8054
8801
|
const sitting = hasSitting ? mountainInfo(input.sitting.trim()) : sittingFromFacing(input.facing.trim());
|
|
8055
8802
|
const facing = MOUNTAINS_24[(sitting.index + 12) % 24];
|
|
8803
|
+
return { sitting, facing };
|
|
8804
|
+
}
|
|
8805
|
+
|
|
8806
|
+
/** 宅卦坐向 + 门主灶厕布局倾向 + 命宅配。 */
|
|
8807
|
+
function buildAdvise(input) {
|
|
8808
|
+
const { sitting, facing } = resolveSittingFacing(input);
|
|
8056
8809
|
const houseGua = sitting.gua;
|
|
8057
8810
|
const stars = eightStars(houseGua);
|
|
8058
8811
|
const lucky = LUCKY_STARS.map((s) => stars[s]);
|
|
@@ -8106,7 +8859,7 @@ function buildAdvise(input) {
|
|
|
8106
8859
|
facing: `${facing.m}山(罗盘 ${facing.deg}°)`,
|
|
8107
8860
|
houseGua,
|
|
8108
8861
|
houseGroup: `${guaGroup(houseGua)}宅`,
|
|
8109
|
-
scope: '
|
|
8862
|
+
scope: '门主灶厕走向按八宅通行口径给倾向,玄空飞星见 action=xuankong;不含形峦、不是现场勘舆结论。',
|
|
8110
8863
|
},
|
|
8111
8864
|
houseStars: starChart,
|
|
8112
8865
|
layout,
|
|
@@ -8116,16 +8869,308 @@ function buildAdvise(input) {
|
|
|
8116
8869
|
};
|
|
8117
8870
|
}
|
|
8118
8871
|
|
|
8119
|
-
|
|
8872
|
+
/** 玄空下卦:坐向 + 运 → 九宫盘、当运星、合十、表法旺山旺向。 */
|
|
8873
|
+
function buildXuankong(input) {
|
|
8874
|
+
const { sitting, facing } = resolveSittingFacing(input);
|
|
8875
|
+
let period;
|
|
8876
|
+
let yearInfo = null;
|
|
8877
|
+
let note;
|
|
8878
|
+
if (input.period !== undefined && input.period !== null && !Number.isInteger(input.period)) {
|
|
8879
|
+
throw fail('E_INPUT', `运必须是 1–9 的整数(三元九运),收到「${input.period}」——一运 1864 起、九运 2024–2043。`);
|
|
8880
|
+
}
|
|
8881
|
+
if (Number.isInteger(input.period)) {
|
|
8882
|
+
if (input.period < 1 || input.period > 9) {
|
|
8883
|
+
throw fail('E_INPUT', `运必须是 1–9 的整数(三元九运),收到「${input.period}」——一运 1864 起、九运 2024–2043。`);
|
|
8884
|
+
}
|
|
8885
|
+
period = input.period;
|
|
8886
|
+
} else if (Number.isInteger(input.fortuneYear)) {
|
|
8887
|
+
yearInfo = periodOfYear(input.fortuneYear);
|
|
8888
|
+
period = yearInfo.period;
|
|
8889
|
+
} else {
|
|
8890
|
+
period = 9;
|
|
8891
|
+
note = '未给运:默认按九运(2024–2043)排盘;可传 period(1–9)或 fortuneYear 指定。';
|
|
8892
|
+
}
|
|
8893
|
+
const chart = xuankongChart(period, sitting.m, facing.m);
|
|
8894
|
+
const sitMeta = MOUNTAIN_META[sitting.m];
|
|
8895
|
+
const faceMeta = MOUNTAIN_META[facing.m];
|
|
8896
|
+
const center = (c) => ({ star: c.star, name: NINE_STARS[c.star].name, fly: c.forward ? '顺飞' : '逆飞', basis: c.basis });
|
|
8897
|
+
const where = (list) => list.map((p) => `${p}宫${PALACE_DIRECTION[p]}`).join('、') || '无';
|
|
8898
|
+
return {
|
|
8899
|
+
system: 'fengshui',
|
|
8900
|
+
meta: {
|
|
8901
|
+
action: 'xuankong',
|
|
8902
|
+
period,
|
|
8903
|
+
periodLabel: yearInfo ? yearInfo.label : `${period}运`,
|
|
8904
|
+
...(yearInfo ? { year: input.fortuneYear, periodStart: yearInfo.start, periodEnd: yearInfo.end } : {}),
|
|
8905
|
+
sitting: `${sitting.m}山(罗盘 ${sitting.deg}°)`,
|
|
8906
|
+
facing: `${facing.m}山(罗盘 ${facing.deg}°)`,
|
|
8907
|
+
sittingGua: sitting.gua,
|
|
8908
|
+
facingGua: facing.gua,
|
|
8909
|
+
sittingYuan: `${sitMeta.yuan}${sitMeta.yinYang}`,
|
|
8910
|
+
facingYuan: `${faceMeta.yuan}${faceMeta.yinYang}`,
|
|
8911
|
+
shanCenter: center(chart.shanCenter),
|
|
8912
|
+
xiangCenter: center(chart.xiangCenter),
|
|
8913
|
+
...(note ? { note } : {}),
|
|
8914
|
+
scope: '玄空下卦:运盘 + 山盘 + 向盘 + 当运星 + 合十 + 表法旺山旺向;不含替卦/兼向、不含年月日时飞星、不含形峦与现场勘舆。',
|
|
8915
|
+
},
|
|
8916
|
+
palaces: chart.palaces,
|
|
8917
|
+
dangYun: {
|
|
8918
|
+
shan: { palaces: chart.dangYun.shan, text: where(chart.dangYun.shan) },
|
|
8919
|
+
xiang: { palaces: chart.dangYun.xiang, text: where(chart.dangYun.xiang) },
|
|
8920
|
+
},
|
|
8921
|
+
heshi: { shan: chart.heshi.shan, xiang: chart.heshi.xiang },
|
|
8922
|
+
wangShanWangXiang: chart.wangShanWangXiang,
|
|
8923
|
+
sources: XUANKONG_SOURCES,
|
|
8924
|
+
disclaimer: XUANKONG_DISCLAIMER,
|
|
8925
|
+
};
|
|
8926
|
+
}
|
|
8927
|
+
|
|
8928
|
+
return { NINE_STARS, PALACE_DIRECTION, DAYOUTIAN, LUCKY_STARS, UNLUCKY_STARS, MOUNTAINS_24, mountainInfo, sittingFromFacing, STAR_LAYOUT_ROLE, mingGua, eightStars, guaYearOf, yearZibaiStar, yearlyFlying, periodOfYear, MOUNTAIN_META, WANG_SHAN_WANG_XIANG, XUANKONG_SOURCES, XUANKONG_DISCLAIMER, xuankongChart, buildFengshui };
|
|
8929
|
+
})();
|
|
8930
|
+
|
|
8931
|
+
__mods['name-data'] = (function () {
|
|
8932
|
+
// 起名用字的数据层:读音(声调用数字另存)+ 康熙笔画、常见姓氏笔画与读音、81 数理。
|
|
8933
|
+
//
|
|
8934
|
+
// 笔画口径(写清楚,别让人猜):
|
|
8935
|
+
// - 按康熙字典的繁体字形计。简体字取对应繁体:华→華14、马→馬10、荣→榮14、宁→寧14、
|
|
8936
|
+
// 灵→靈24、兰→蘭23、丰→豐18、书→書10、画→畫12、云→雲12、风→風9、阳→陽17、涛→濤18。
|
|
8937
|
+
// - 偏旁按本字计:氵→水(4)、艹→艸(6)、辶→辵(7)、忄→心(4)、扌→手(4)、
|
|
8938
|
+
// 阝(左)→阜(8)、阝(右)→邑(7)、王/玉旁→玉(5)、衤→衣(6)、礻→示(5)、
|
|
8939
|
+
// 讠→言(7)、钅→金(8)、纟→糸(6)、饣→食(9)。
|
|
8940
|
+
// - 各派五格工具对个别字取法不一(如 沈、蒋),这里取最常见的一种;
|
|
8941
|
+
// 调用方可以用 strokeOverrides 覆盖任意字的笔画,覆盖值会被标注为「用户指定」。
|
|
8942
|
+
//
|
|
8943
|
+
// 读数口径:拼音只写声母韵母(ü 写作 v),声调 1–4 单独一列;轻声不收录(人名用字几乎不读轻声)。
|
|
8944
|
+
|
|
8945
|
+
/** [字, 拼音(无声调), 声调, 康熙笔画] */
|
|
8946
|
+
const READING = [
|
|
8947
|
+
// ── 木 ──
|
|
8948
|
+
['梓', 'zi', 3, 11], ['桐', 'tong', 2, 10], ['楠', 'nan', 2, 13], ['楷', 'kai', 3, 13],
|
|
8949
|
+
['松', 'song', 1, 8], ['柏', 'bai', 3, 9], ['枫', 'feng', 1, 13], ['榕', 'rong', 2, 14],
|
|
8950
|
+
['槿', 'jin', 3, 15], ['棠', 'tang', 2, 12], ['楚', 'chu', 3, 13], ['柯', 'ke', 1, 9],
|
|
8951
|
+
['桓', 'huan', 2, 10], ['榆', 'yu', 2, 13], ['栩', 'xu', 3, 10], ['榛', 'zhen', 1, 14],
|
|
8952
|
+
['芸', 'yun', 2, 10], ['芷', 'zhi', 3, 10], ['芮', 'rui', 4, 10], ['若', 'ruo', 4, 11],
|
|
8953
|
+
['茜', 'qian', 4, 12], ['茵', 'yin', 1, 12], ['茗', 'ming', 2, 12], ['莎', 'sha', 1, 13],
|
|
8954
|
+
['茉', 'mo', 4, 11], ['筱', 'xiao', 3, 13], ['蓉', 'rong', 2, 16], ['萱', 'xuan', 1, 15],
|
|
8955
|
+
['蕙', 'hui', 4, 18], ['蕊', 'rui', 3, 18], ['菲', 'fei', 1, 14], ['蔓', 'man', 4, 17],
|
|
8956
|
+
['荣', 'rong', 2, 14], ['茂', 'mao', 4, 11], ['栋', 'dong', 4, 12], ['梁', 'liang', 2, 11],
|
|
8957
|
+
['朴', 'pu', 3, 6], ['本', 'ben', 3, 5], ['林', 'lin', 2, 8], ['森', 'sen', 1, 12],
|
|
8958
|
+
['枝', 'zhi', 1, 8], ['果', 'guo', 3, 8], ['禾', 'he', 2, 5], ['秀', 'xiu', 4, 7],
|
|
8959
|
+
['穗', 'sui', 4, 17], ['稼', 'jia', 4, 15], ['颖', 'ying', 3, 16], ['苗', 'miao', 2, 8],
|
|
8960
|
+
['菁', 'jing', 1, 14], ['菡', 'han', 4, 14], ['蕴', 'yun', 4, 22], ['蕾', 'lei', 3, 19],
|
|
8961
|
+
['薇', 'wei', 1, 19], ['薏', 'yi', 4, 19], ['菀', 'wan', 3, 14], ['荷', 'he', 2, 13],
|
|
8962
|
+
['莲', 'lian', 2, 17], ['菱', 'ling', 2, 14], ['苇', 'wei', 3, 15], ['荻', 'di', 2, 13],
|
|
8963
|
+
['筠', 'yun', 2, 13], ['笛', 'di', 2, 11], ['杉', 'shan', 1, 7], ['柠', 'ning', 2, 18],
|
|
8964
|
+
['桢', 'zhen', 1, 13], ['樾', 'yue', 4, 16], ['柘', 'zhe', 4, 9], ['权', 'quan', 2, 22],
|
|
8965
|
+
['材', 'cai', 2, 7], ['杭', 'hang', 2, 8], ['枚', 'mei', 2, 8], ['梧', 'wu', 2, 11],
|
|
8966
|
+
['竹', 'zhu', 2, 6], ['简', 'jian', 3, 18], ['策', 'ce', 4, 12], ['筹', 'chou', 2, 20],
|
|
8967
|
+
['芬', 'fen', 1, 10], ['芳', 'fang', 1, 10], ['花', 'hua', 1, 10], ['菊', 'ju', 2, 14],
|
|
8968
|
+
['兰', 'lan', 2, 23], ['芝', 'zhi', 1, 10], ['芹', 'qin', 2, 10], ['荃', 'quan', 2, 12],
|
|
8969
|
+
['萃', 'cui', 4, 14], ['蓁', 'zhen', 1, 16], ['荞', 'qiao', 2, 18], ['莞', 'wan', 3, 13],
|
|
8970
|
+
['萦', 'ying', 2, 16], ['蔚', 'wei', 4, 17], ['芃', 'peng', 2, 9], ['芩', 'qin', 2, 10],
|
|
8971
|
+
['苡', 'yi', 3, 11], ['莱', 'lai', 2, 14], ['萌', 'meng', 2, 14], ['葆', 'bao', 3, 15],
|
|
8972
|
+
['萧', 'xiao', 1, 18], ['樟', 'zhang', 1, 15], ['樱', 'ying', 1, 21], ['栎', 'li', 4, 19],
|
|
8973
|
+
['棹', 'zhao', 4, 12], ['楸', 'qiu', 1, 13], ['槐', 'huai', 2, 14], ['橙', 'cheng', 2, 16],
|
|
8974
|
+
['檀', 'tan', 2, 17],
|
|
8975
|
+
// ── 火 ──
|
|
8976
|
+
['炎', 'yan', 2, 8], ['灿', 'can', 4, 17], ['炫', 'xuan', 4, 9], ['炜', 'wei', 3, 13],
|
|
8977
|
+
['烨', 'ye', 4, 14], ['煜', 'yu', 4, 13], ['熙', 'xi', 1, 13], ['煊', 'xuan', 1, 13],
|
|
8978
|
+
['焕', 'huan', 4, 13], ['熠', 'yi', 4, 15], ['炅', 'jiong', 3, 8], ['昱', 'yu', 4, 9],
|
|
8979
|
+
['晗', 'han', 2, 11], ['旭', 'xu', 4, 6], ['昊', 'hao', 4, 8], ['晟', 'sheng', 4, 11],
|
|
8980
|
+
['晨', 'chen', 2, 11], ['景', 'jing', 3, 12], ['曜', 'yao', 4, 18], ['曦', 'xi', 1, 20],
|
|
8981
|
+
['朗', 'lang', 3, 11], ['昭', 'zhao', 1, 9], ['昕', 'xin', 1, 8], ['昀', 'yun', 2, 8],
|
|
8982
|
+
['暖', 'nuan', 3, 13], ['灵', 'ling', 2, 24], ['丹', 'dan', 1, 4], ['彤', 'tong', 2, 7],
|
|
8983
|
+
['冉', 'ran', 3, 5], ['南', 'nan', 2, 9], ['丰', 'feng', 1, 18], ['日', 'ri', 4, 4],
|
|
8984
|
+
['阳', 'yang', 2, 17], ['光', 'guang', 1, 6], ['亮', 'liang', 4, 9], ['明', 'ming', 2, 8],
|
|
8985
|
+
['晶', 'jing', 1, 12], ['晴', 'qing', 2, 12], ['夏', 'xia', 4, 10], ['智', 'zhi', 4, 12],
|
|
8986
|
+
['卓', 'zhuo', 2, 8], ['乐', 'le', 4, 15], ['恺', 'kai', 3, 14], ['恬', 'tian', 2, 10],
|
|
8987
|
+
['甜', 'tian', 2, 11], ['亭', 'ting', 2, 9], ['俊', 'jun', 4, 9], ['丙', 'bing', 3, 5],
|
|
8988
|
+
['丁', 'ding', 1, 2], ['鼎', 'ding', 3, 13], ['陶', 'tao', 2, 16], ['熹', 'xi', 1, 16],
|
|
8989
|
+
['炀', 'yang', 2, 13], ['烜', 'xuan', 3, 10], ['暻', 'jing', 3, 16], ['晖', 'hui', 1, 13],
|
|
8990
|
+
['晔', 'ye', 4, 16], ['旻', 'min', 2, 8], ['晏', 'yan', 4, 10], ['晓', 'xiao', 3, 16],
|
|
8991
|
+
['暄', 'xuan', 1, 13], ['昆', 'kun', 1, 8], ['伶', 'ling', 2, 7],
|
|
8992
|
+
// ── 土 ──
|
|
8993
|
+
['坤', 'kun', 1, 8], ['垚', 'yao', 2, 9], ['培', 'pei', 2, 11], ['城', 'cheng', 2, 10],
|
|
8994
|
+
['域', 'yu', 4, 11], ['坚', 'jian', 1, 11], ['墨', 'mo', 4, 15], ['均', 'jun', 1, 7],
|
|
8995
|
+
['坦', 'tan', 3, 8], ['基', 'ji', 1, 11], ['堂', 'tang', 2, 11], ['圣', 'sheng', 4, 13],
|
|
8996
|
+
['在', 'zai', 4, 6], ['岳', 'yue', 4, 8], ['峰', 'feng', 1, 10], ['峻', 'jun', 4, 10],
|
|
8997
|
+
['岚', 'lan', 2, 12], ['岩', 'yan', 2, 8], ['崇', 'chong', 2, 11], ['岐', 'qi', 2, 7],
|
|
8998
|
+
['屿', 'yu', 3, 17], ['磊', 'lei', 3, 15], ['尧', 'yao', 2, 12], ['圆', 'yuan', 2, 13],
|
|
8999
|
+
['恩', 'en', 1, 10], ['惟', 'wei', 2, 11], ['轩', 'xuan', 1, 10], ['逸', 'yi', 4, 15],
|
|
9000
|
+
['山', 'shan', 1, 3], ['岸', 'an', 4, 8], ['岑', 'cen', 2, 7], ['巍', 'wei', 1, 21],
|
|
9001
|
+
['嵩', 'song', 1, 13], ['岭', 'ling', 3, 17], ['奥', 'ao', 4, 13], ['宜', 'yi', 2, 8],
|
|
9002
|
+
['容', 'rong', 2, 10], ['意', 'yi', 4, 13], ['依', 'yi', 1, 8], ['悠', 'you', 1, 11],
|
|
9003
|
+
['维', 'wei', 2, 14], ['纬', 'wei', 3, 15], ['永', 'yong', 3, 5], ['远', 'yuan', 3, 17],
|
|
9004
|
+
['辰', 'chen', 2, 7], ['壁', 'bi', 4, 16], ['田', 'tian', 2, 5], ['由', 'you', 2, 5],
|
|
9005
|
+
['画', 'hua', 4, 12], ['延', 'yan', 2, 7], ['建', 'jian', 4, 9], ['音', 'yin', 1, 9],
|
|
9006
|
+
['韵', 'yun', 4, 19], ['玮', 'wei', 3, 14], ['雍', 'yong', 1, 13], ['懿', 'yi', 4, 22],
|
|
9007
|
+
['宇', 'yu', 3, 6], ['亦', 'yi', 4, 6], ['安', 'an', 1, 6], ['宁', 'ning', 2, 14],
|
|
9008
|
+
// ── 金 ──
|
|
9009
|
+
['锋', 'feng', 1, 15], ['钢', 'gang', 1, 16], ['钧', 'jun', 1, 12], ['铭', 'ming', 2, 14],
|
|
9010
|
+
['锐', 'rui', 4, 15], ['锡', 'xi', 1, 16], ['锦', 'jin', 3, 16], ['鑫', 'xin', 1, 24],
|
|
9011
|
+
['键', 'jian', 4, 17], ['鉴', 'jian', 4, 22], ['钦', 'qin', 1, 12], ['镇', 'zhen', 4, 18],
|
|
9012
|
+
['铮', 'zheng', 1, 16], ['钰', 'yu', 4, 13], ['铠', 'kai', 3, 18], ['珊', 'shan', 1, 10],
|
|
9013
|
+
['珠', 'zhu', 1, 10], ['琳', 'lin', 2, 13], ['琦', 'qi', 2, 13], ['琪', 'qi', 2, 13],
|
|
9014
|
+
['瑜', 'yu', 2, 14], ['瑞', 'rui', 4, 14], ['瑄', 'xuan', 1, 14], ['璇', 'xuan', 2, 16],
|
|
9015
|
+
['璟', 'jing', 3, 17], ['璐', 'lu', 4, 18], ['瑾', 'jin', 3, 16], ['珏', 'jue', 2, 9],
|
|
9016
|
+
['环', 'huan', 2, 18], ['玲', 'ling', 2, 10], ['珑', 'long', 2, 21], ['瑶', 'yao', 2, 15],
|
|
9017
|
+
['莹', 'ying', 2, 15], ['铎', 'duo', 2, 21], ['金', 'jin', 1, 8], ['秋', 'qiu', 1, 9],
|
|
9018
|
+
['书', 'shu', 1, 10], ['舒', 'shu', 1, 12], ['善', 'shan', 4, 12], ['信', 'xin', 4, 9],
|
|
9019
|
+
['修', 'xiu', 1, 10], ['素', 'su', 4, 10], ['静', 'jing', 4, 16], ['心', 'xin', 1, 4],
|
|
9020
|
+
['新', 'xin', 1, 13], ['正', 'zheng', 4, 5], ['世', 'shi', 4, 5], ['少', 'shao', 3, 4],
|
|
9021
|
+
['西', 'xi', 1, 6], ['白', 'bai', 2, 5], ['辛', 'xin', 1, 7], ['成', 'cheng', 2, 7],
|
|
9022
|
+
['利', 'li', 4, 7], ['剑', 'jian', 4, 15], ['刚', 'gang', 1, 10], ['则', 'ze', 2, 9],
|
|
9023
|
+
['初', 'chu', 1, 7], ['硕', 'shuo', 4, 14], ['尚', 'shang', 4, 8], ['臣', 'chen', 2, 6],
|
|
9024
|
+
['川', 'chuan', 1, 3], ['舟', 'zhou', 1, 6], ['州', 'zhou', 1, 6], ['祖', 'zu', 3, 10],
|
|
9025
|
+
['祥', 'xiang', 2, 11], ['禄', 'lu', 4, 13], ['禧', 'xi', 3, 17], ['珍', 'zhen', 1, 10],
|
|
9026
|
+
['宣', 'xuan', 1, 9], ['序', 'xu', 4, 7], ['谦', 'qian', 1, 17], ['赞', 'zan', 4, 19],
|
|
9027
|
+
['超', 'chao', 1, 12], ['锴', 'kai', 3, 17], ['承', 'cheng', 2, 8], ['语', 'yu', 3, 14],
|
|
9028
|
+
['诺', 'nuo', 4, 16], ['诗', 'shi', 1, 13], ['梦', 'meng', 4, 14], ['思', 'si', 1, 9],
|
|
9029
|
+
['悦', 'yue', 4, 11], ['欣', 'xin', 1, 8], ['嘉', 'jia', 1, 14], ['佳', 'jia', 1, 8],
|
|
9030
|
+
['博', 'bo', 2, 12], ['睿', 'rui', 4, 14], ['知', 'zhi', 1, 8], ['星', 'xing', 1, 9],
|
|
9031
|
+
['言', 'yan', 2, 7], ['和', 'he', 2, 8],
|
|
9032
|
+
// ── 水 ──
|
|
9033
|
+
['江', 'jiang', 1, 7], ['河', 'he', 2, 9], ['海', 'hai', 3, 11], ['洋', 'yang', 2, 10],
|
|
9034
|
+
['波', 'bo', 1, 9], ['涛', 'tao', 1, 18], ['涵', 'han', 2, 12], ['清', 'qing', 1, 12],
|
|
9035
|
+
['澈', 'che', 4, 16], ['澄', 'cheng', 2, 16], ['润', 'run', 4, 16], ['泽', 'ze', 2, 17],
|
|
9036
|
+
['沛', 'pei', 4, 8], ['沁', 'qin', 4, 8], ['泓', 'hong', 2, 9], ['泉', 'quan', 2, 9],
|
|
9037
|
+
['汐', 'xi', 1, 7], ['淇', 'qi', 2, 12], ['鸿', 'hong', 2, 17], ['滋', 'zi', 1, 13],
|
|
9038
|
+
['淼', 'miao', 3, 12], ['雨', 'yu', 3, 8], ['雪', 'xue', 3, 11], ['霖', 'lin', 2, 16],
|
|
9039
|
+
['霏', 'fei', 1, 16], ['露', 'lu', 4, 21], ['霆', 'ting', 2, 15], ['雯', 'wen', 2, 12],
|
|
9040
|
+
['霓', 'ni', 2, 16], ['湉', 'tian', 2, 13], ['沐', 'mu', 4, 8], ['宸', 'chen', 2, 10],
|
|
9041
|
+
['然', 'ran', 2, 12], ['文', 'wen', 2, 4], ['月', 'yue', 4, 4], ['水', 'shui', 3, 4],
|
|
9042
|
+
['冰', 'bing', 1, 6], ['洁', 'jie', 2, 16], ['浩', 'hao', 4, 11], ['瀚', 'han', 4, 20],
|
|
9043
|
+
['渊', 'yuan', 1, 12], ['澜', 'lan', 2, 21], ['潮', 'chao', 2, 16], ['溪', 'xi', 1, 14],
|
|
9044
|
+
['湘', 'xiang', 1, 13], ['渝', 'yu', 2, 13], ['深', 'shen', 1, 12], ['湛', 'zhan', 4, 13],
|
|
9045
|
+
['汇', 'hui', 4, 13], ['洲', 'zhou', 1, 10], ['湾', 'wan', 1, 26], ['云', 'yun', 2, 12],
|
|
9046
|
+
['风', 'feng', 1, 9], ['北', 'bei', 3, 5], ['冬', 'dong', 1, 5], ['玄', 'xuan', 2, 5],
|
|
9047
|
+
['子', 'zi', 3, 3], ['平', 'ping', 2, 5], ['方', 'fang', 1, 4], ['帆', 'fan', 1, 6],
|
|
9048
|
+
['航', 'hang', 2, 10], ['敏', 'min', 3, 11], ['慧', 'hui', 4, 15], ['惠', 'hui', 4, 12],
|
|
9049
|
+
['霈', 'pei', 4, 15], ['灏', 'hao', 4, 25], ['湄', 'mei', 2, 13], ['滨', 'bin', 1, 18],
|
|
9050
|
+
['洛', 'luo', 4, 10], ['津', 'jin', 1, 10], ['泊', 'bo', 2, 9], ['沧', 'cang', 1, 14],
|
|
9051
|
+
['浦', 'pu', 3, 11],
|
|
9052
|
+
];
|
|
9053
|
+
|
|
9054
|
+
/** 常见单姓的康熙笔画(复姓见 DOUBLE_SURNAMES)。没有的姓可用 surnameStrokes 传入。 */
|
|
9055
|
+
const SURNAME_STROKES = {
|
|
9056
|
+
王: 4, 李: 7, 张: 11, 刘: 15, 陈: 16, 杨: 13, 黄: 12, 赵: 14, 吴: 7, 周: 8,
|
|
9057
|
+
徐: 10, 孙: 10, 马: 10, 朱: 6, 胡: 11, 郭: 15, 何: 7, 高: 10, 林: 8, 罗: 20,
|
|
9058
|
+
郑: 19, 梁: 11, 谢: 17, 宋: 7, 唐: 10, 许: 11, 韩: 17, 冯: 12, 曹: 11, 彭: 12,
|
|
9059
|
+
曾: 12, 萧: 18, 田: 5, 董: 15, 潘: 16, 袁: 10, 蔡: 17, 余: 7, 于: 3, 杜: 7,
|
|
9060
|
+
叶: 15, 程: 12, 魏: 18, 吕: 7, 丁: 2, 任: 6, 姚: 9, 卢: 16, 姜: 9, 崔: 11,
|
|
9061
|
+
钟: 17, 谭: 19, 陆: 16, 范: 15, 金: 8, 石: 5, 廖: 14, 贾: 13, 夏: 10, 韦: 9,
|
|
9062
|
+
付: 5, 方: 4, 白: 5, 邹: 17, 孟: 8, 熊: 14, 秦: 10, 邱: 12, 江: 7, 尹: 4,
|
|
9063
|
+
薛: 19, 段: 9, 雷: 13, 侯: 9, 龙: 16, 史: 5, 陶: 16, 黎: 15, 贺: 12, 顾: 21,
|
|
9064
|
+
毛: 4, 郝: 14, 龚: 22, 邵: 12, 钱: 16, 严: 20, 武: 8, 戴: 18, 莫: 13, 孔: 4,
|
|
9065
|
+
向: 6, 常: 11, 康: 11, 易: 8, 文: 4, 施: 9, 洪: 10, 安: 6, 颜: 18, 温: 13,
|
|
9066
|
+
章: 11, 鲁: 15, 葛: 15, 伍: 6, 申: 5, 尤: 4, 焦: 12, 柳: 9, 邢: 11, 路: 13,
|
|
9067
|
+
岳: 8, 乔: 12, 赖: 20, 万: 15, 苏: 22, 蒋: 17, 沈: 8, 汪: 8, 邓: 19, 覃: 12,
|
|
9068
|
+
房: 8, 边: 22, 辛: 7, 涂: 11, 甘: 5, 封: 9, 储: 18, 邬: 17, 路: 13, 詹: 13,
|
|
9069
|
+
};
|
|
9070
|
+
|
|
9071
|
+
/** 常见单姓读音:[拼音, 声调] */
|
|
9072
|
+
const SURNAME_READING = {
|
|
9073
|
+
王: ['wang', 2], 李: ['li', 3], 张: ['zhang', 1], 刘: ['liu', 2], 陈: ['chen', 2],
|
|
9074
|
+
杨: ['yang', 2], 黄: ['huang', 2], 赵: ['zhao', 4], 吴: ['wu', 2], 周: ['zhou', 1],
|
|
9075
|
+
徐: ['xu', 2], 孙: ['sun', 1], 马: ['ma', 3], 朱: ['zhu', 1], 胡: ['hu', 2],
|
|
9076
|
+
郭: ['guo', 1], 何: ['he', 2], 高: ['gao', 1], 林: ['lin', 2], 罗: ['luo', 2],
|
|
9077
|
+
郑: ['zheng', 4], 梁: ['liang', 2], 谢: ['xie', 4], 宋: ['song', 4], 唐: ['tang', 2],
|
|
9078
|
+
许: ['xu', 3], 韩: ['han', 2], 冯: ['feng', 2], 曹: ['cao', 2], 彭: ['peng', 2],
|
|
9079
|
+
曾: ['zeng', 1], 萧: ['xiao', 1], 田: ['tian', 2], 董: ['dong', 3], 潘: ['pan', 1],
|
|
9080
|
+
袁: ['yuan', 2], 蔡: ['cai', 4], 余: ['yu', 2], 于: ['yu', 2], 杜: ['du', 4],
|
|
9081
|
+
叶: ['ye', 4], 程: ['cheng', 2], 魏: ['wei', 4], 吕: ['lv', 3], 丁: ['ding', 1],
|
|
9082
|
+
任: ['ren', 2], 姚: ['yao', 2], 卢: ['lu', 2], 姜: ['jiang', 1], 崔: ['cui', 1],
|
|
9083
|
+
钟: ['zhong', 1], 谭: ['tan', 2], 陆: ['lu', 4], 范: ['fan', 4], 金: ['jin', 1],
|
|
9084
|
+
石: ['shi', 2], 廖: ['liao', 4], 贾: ['jia', 3], 夏: ['xia', 4], 韦: ['wei', 2],
|
|
9085
|
+
付: ['fu', 4], 方: ['fang', 1], 白: ['bai', 2], 邹: ['zou', 1], 孟: ['meng', 4],
|
|
9086
|
+
熊: ['xiong', 2], 秦: ['qin', 2], 邱: ['qiu', 1], 江: ['jiang', 1], 尹: ['yin', 3],
|
|
9087
|
+
薛: ['xue', 1], 段: ['duan', 4], 雷: ['lei', 2], 侯: ['hou', 2], 龙: ['long', 2],
|
|
9088
|
+
史: ['shi', 3], 陶: ['tao', 2], 黎: ['li', 2], 贺: ['he', 4], 顾: ['gu', 4],
|
|
9089
|
+
毛: ['mao', 2], 郝: ['hao', 3], 龚: ['gong', 1], 邵: ['shao', 4], 钱: ['qian', 2],
|
|
9090
|
+
严: ['yan', 2], 武: ['wu', 3], 戴: ['dai', 4], 莫: ['mo', 4], 孔: ['kong', 3],
|
|
9091
|
+
向: ['xiang', 4], 常: ['chang', 2], 康: ['kang', 1], 易: ['yi', 4], 文: ['wen', 2],
|
|
9092
|
+
施: ['shi', 1], 洪: ['hong', 2], 安: ['an', 1], 颜: ['yan', 2], 温: ['wen', 1],
|
|
9093
|
+
章: ['zhang', 1], 鲁: ['lu', 3], 葛: ['ge', 3], 伍: ['wu', 3], 申: ['shen', 1],
|
|
9094
|
+
尤: ['you', 2], 焦: ['jiao', 1], 柳: ['liu', 3], 邢: ['xing', 2], 路: ['lu', 4],
|
|
9095
|
+
岳: ['yue', 4], 乔: ['qiao', 2], 赖: ['lai', 4], 万: ['wan', 4], 苏: ['su', 1],
|
|
9096
|
+
蒋: ['jiang', 3], 沈: ['shen', 3], 汪: ['wang', 1], 邓: ['deng', 4], 覃: ['tan', 2],
|
|
9097
|
+
房: ['fang', 2], 边: ['bian', 1], 辛: ['xin', 1], 涂: ['tu', 2], 甘: ['gan', 1],
|
|
9098
|
+
封: ['feng', 1], 储: ['chu', 3], 邬: ['wu', 1], 詹: ['zhan', 1],
|
|
9099
|
+
欧: ['ou', 1],
|
|
9100
|
+
阳: ['yang', 2],
|
|
9101
|
+
司: ['si', 1],
|
|
9102
|
+
上: ['shang', 4],
|
|
9103
|
+
官: ['guan', 1],
|
|
9104
|
+
诸: ['zhu', 1],
|
|
9105
|
+
东: ['dong', 1],
|
|
9106
|
+
皇: ['huang', 2],
|
|
9107
|
+
甫: ['fu', 3],
|
|
9108
|
+
尉: ['yu', 4],
|
|
9109
|
+
迟: ['chi', 2],
|
|
9110
|
+
令: ['ling', 4],
|
|
9111
|
+
狐: ['hu', 2],
|
|
9112
|
+
慕: ['mu', 4],
|
|
9113
|
+
徒: ['tu', 2],
|
|
9114
|
+
公: ['gong', 1],
|
|
9115
|
+
};
|
|
9116
|
+
|
|
9117
|
+
/** 常见复姓:两字各自的康熙笔画(s)与读音(首字拼音连写,声调取首字) */
|
|
9118
|
+
const DOUBLE_SURNAMES = {
|
|
9119
|
+
欧阳: { s: [15, 17], py: 'ouyang', tone: 1 },
|
|
9120
|
+
司马: { s: [5, 10], py: 'sima', tone: 1 },
|
|
9121
|
+
上官: { s: [3, 8], py: 'shangguan', tone: 4 },
|
|
9122
|
+
诸葛: { s: [15, 15], py: 'zhuge', tone: 1 },
|
|
9123
|
+
东方: { s: [8, 4], py: 'dongfang', tone: 1 },
|
|
9124
|
+
皇甫: { s: [9, 7], py: 'huangfu', tone: 2 },
|
|
9125
|
+
尉迟: { s: [11, 19], py: 'yuchi', tone: 4 },
|
|
9126
|
+
令狐: { s: [5, 8], py: 'linghu', tone: 4 },
|
|
9127
|
+
慕容: { s: [14, 10], py: 'murong', tone: 4 },
|
|
9128
|
+
宇文: { s: [6, 4], py: 'yuwen', tone: 3 },
|
|
9129
|
+
司徒: { s: [5, 10], py: 'situ', tone: 1 },
|
|
9130
|
+
夏侯: { s: [10, 9], py: 'xiahou', tone: 4 },
|
|
9131
|
+
公孙: { s: [4, 10], py: 'gongsun', tone: 1 },
|
|
9132
|
+
};
|
|
9133
|
+
|
|
9134
|
+
/**
|
|
9135
|
+
* 81 数理(通行本):索引即数,[吉凶, 意象]。
|
|
9136
|
+
* 吉凶分三档:吉 / 半吉 / 凶。各派工具对少数数取法有出入,这里取通行本,页面会标明。
|
|
9137
|
+
*/
|
|
9138
|
+
const SHULI_81 = [null,
|
|
9139
|
+
['吉', '太极之数'], ['凶', '两仪之数'], ['吉', '三才之数'], ['凶', '四象之数'],
|
|
9140
|
+
['吉', '五行之数'], ['吉', '六爻之数'], ['吉', '七政之数'], ['吉', '八卦之数'],
|
|
9141
|
+
['凶', '大成之数'], ['凶', '终结之数'], ['吉', '旱苗逢雨'], ['凶', '掘井无泉'],
|
|
9142
|
+
['吉', '春日牡丹'], ['凶', '破兆之数'], ['吉', '福寿之数'], ['吉', '厚重之数'],
|
|
9143
|
+
['吉', '刚强之数'], ['吉', '铁镜重磨'], ['凶', '多难之数'], ['凶', '屋下藏金'],
|
|
9144
|
+
['吉', '明月中天'], ['凶', '秋草逢霜'], ['吉', '壮丽之数'], ['吉', '掘藏得金'],
|
|
9145
|
+
['吉', '荣俊之数'], ['凶', '变怪之数'], ['半吉', '增长之数'], ['凶', '阔水浮萍'],
|
|
9146
|
+
['吉', '智谋之数'], ['半吉', '非运之数'], ['吉', '春日花开'], ['吉', '宝马金鞍'],
|
|
9147
|
+
['吉', '旭日升天'], ['凶', '破家之数'], ['吉', '高楼望月'], ['凶', '波澜重叠'],
|
|
9148
|
+
['吉', '猛虎出林'], ['半吉', '磨铁成针'], ['吉', '富贵荣华'], ['半吉', '退安之数'],
|
|
9149
|
+
['吉', '有德之数'], ['半吉', '寒蝉在柳'], ['凶', '散财破产'], ['凶', '烦闷之数'],
|
|
9150
|
+
['吉', '顺风之数'], ['凶', '浪里淘金'], ['吉', '点石成金'], ['吉', '古松立鹤'],
|
|
9151
|
+
['半吉', '转变之数'], ['半吉', '小舟入海'], ['半吉', '沉浮之数'], ['吉', '先见之明'],
|
|
9152
|
+
['半吉', '曲卷难星'], ['凶', '石上栽花'], ['半吉', '善恶之数'], ['凶', '浪里行舟'],
|
|
9153
|
+
['吉', '日照春松'], ['半吉', '晚行遇月'], ['凶', '寒蝉悲风'], ['凶', '无谋之数'],
|
|
9154
|
+
['吉', '牡丹芙蓉'], ['凶', '衰败之数'], ['吉', '舟归平海'], ['凶', '非命之数'],
|
|
9155
|
+
['吉', '巨流归海'], ['凶', '岩头步马'], ['吉', '通达之数'], ['吉', '顺风吹帆'],
|
|
9156
|
+
['凶', '非业之数'], ['凶', '残菊经霜'], ['半吉', '石上金花'], ['凶', '劳苦之数'],
|
|
9157
|
+
['半吉', '志高力微'], ['凶', '残菊逢霜'], ['半吉', '退守之数'], ['凶', '离散之数'],
|
|
9158
|
+
['半吉', '半吉之数'], ['半吉', '晚苦之数'], ['凶', '云头望月'], ['半吉', '遁吉之数'],
|
|
9159
|
+
['吉', '万物回春'],
|
|
9160
|
+
];
|
|
9161
|
+
|
|
9162
|
+
return { READING, SURNAME_STROKES, SURNAME_READING, DOUBLE_SURNAMES, SHULI_81 };
|
|
8120
9163
|
})();
|
|
8121
9164
|
|
|
8122
9165
|
__mods.name = (function () {
|
|
8123
|
-
// 起名:字库五行匹配 +
|
|
9166
|
+
// 起名:字库五行匹配 + 候选组合(纯本地确定性),另附五格剖象与音韵检查。
|
|
8124
9167
|
// 口径:字之五行按通行字义/偏旁归类(自建常用字库,未收录的字如实标注,不猜);
|
|
8125
9168
|
// 喜用倾向取八字旺衰的简化判定(偏强喜克泄耗、偏弱喜生扶、中和不筛)。
|
|
8126
|
-
//
|
|
9169
|
+
// 五格按康熙字典繁体笔画计(见 name-data.js 的口径说明),81 数理取通行本;
|
|
9170
|
+
// 音韵只做机械检查(同调、相邻同声母/同韵母、叠字),不做语义谐音判断。
|
|
8127
9171
|
const { buildBazi } = __mods.bazi;
|
|
8128
9172
|
const { assertCivil } = __mods.validate;
|
|
9173
|
+
const { READING, SURNAME_STROKES, SURNAME_READING, DOUBLE_SURNAMES, SHULI_81 } = __mods['name-data'];
|
|
8129
9174
|
|
|
8130
9175
|
const SHENG = { 木: '火', 火: '土', 土: '金', 金: '水', 水: '木' };
|
|
8131
9176
|
const KE = { 木: '土', 土: '水', 水: '火', 火: '金', 金: '木' };
|
|
@@ -8350,51 +9395,238 @@ const CHAR_LIB = [
|
|
|
8350
9395
|
];
|
|
8351
9396
|
|
|
8352
9397
|
const EL_INDEX = new Map();
|
|
9398
|
+
const EXTRA_INDEX = new Map();
|
|
9399
|
+
for (const [c, py, tone, st] of READING) {
|
|
9400
|
+
if (!EXTRA_INDEX.has(c)) EXTRA_INDEX.set(c, { py, tone, st });
|
|
9401
|
+
}
|
|
8353
9402
|
for (const c of CHAR_LIB) {
|
|
8354
|
-
if (!EL_INDEX.has(c[0]))
|
|
9403
|
+
if (!EL_INDEX.has(c[0])) {
|
|
9404
|
+
const x = EXTRA_INDEX.get(c[0]) || {};
|
|
9405
|
+
EL_INDEX.set(c[0], {
|
|
9406
|
+
c: c[0], el: c[1], meaning: c[2], g: c[3], order: EL_INDEX.size,
|
|
9407
|
+
py: x.py || null, tone: x.tone || null, strokes: x.st || null,
|
|
9408
|
+
});
|
|
9409
|
+
}
|
|
8355
9410
|
}
|
|
8356
9411
|
|
|
8357
|
-
|
|
8358
|
-
|
|
8359
|
-
|
|
8360
|
-
|
|
8361
|
-
|
|
8362
|
-
|
|
9412
|
+
const NUM_ELEMENT = { 1: '木', 2: '木', 3: '火', 4: '火', 5: '土', 6: '土', 7: '金', 8: '金', 9: '水', 0: '水' };
|
|
9413
|
+
const WX_REL = (a, b) => (a === b ? '同' : SHENG[a] === b ? '生' : KE[a] === b ? '克' : SHENG[b] === a ? '被生' : '被克');
|
|
9414
|
+
|
|
9415
|
+
/** 数理超过 81 按传统「减 80 循环」取(如 104 → 24)。 */
|
|
9416
|
+
function shuliOf(n) {
|
|
9417
|
+
let x = n;
|
|
9418
|
+
while (x > 81) x -= 80;
|
|
9419
|
+
if (!(x >= 1)) return null;
|
|
9420
|
+
const row = SHULI_81[x];
|
|
9421
|
+
return row ? { num: x, level: row[0], name: row[1] } : null;
|
|
8363
9422
|
}
|
|
8364
9423
|
|
|
8365
|
-
/**
|
|
8366
|
-
function
|
|
8367
|
-
const
|
|
8368
|
-
|
|
8369
|
-
|
|
8370
|
-
|
|
8371
|
-
|
|
8372
|
-
|
|
9424
|
+
/** 合并两处笔画覆盖:surnameStrokes(按姓给的)+ strokeOverrides(逐字覆盖),后者优先。 */
|
|
9425
|
+
function overridesOf(input) {
|
|
9426
|
+
const out = {};
|
|
9427
|
+
for (const src of [input && input.surnameStrokes, input && input.strokeOverrides]) {
|
|
9428
|
+
if (!src || typeof src !== 'object') continue;
|
|
9429
|
+
for (const [k, v] of Object.entries(src)) {
|
|
9430
|
+
if (Number.isInteger(v) && v > 0) out[k] = v;
|
|
9431
|
+
}
|
|
9432
|
+
}
|
|
9433
|
+
return Object.keys(out).length ? out : undefined;
|
|
8373
9434
|
}
|
|
8374
9435
|
|
|
8375
|
-
|
|
9436
|
+
function strokeOf(ch, overrides, kind) {
|
|
9437
|
+
if (overrides && Number.isInteger(overrides[ch]) && overrides[ch] > 0) {
|
|
9438
|
+
return { strokes: overrides[ch], source: 'user' };
|
|
9439
|
+
}
|
|
9440
|
+
const info = EL_INDEX.get(ch);
|
|
9441
|
+
if (info && info.strokes) return { strokes: info.strokes, source: 'lib' };
|
|
9442
|
+
if (kind === 'surname' && SURNAME_STROKES[ch]) return { strokes: SURNAME_STROKES[ch], source: 'surname' };
|
|
9443
|
+
return null;
|
|
9444
|
+
}
|
|
8376
9445
|
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
8381
|
-
|
|
8382
|
-
if (level === '身强' || level === '偏强') {
|
|
8383
|
-
return {
|
|
8384
|
-
list: [KE_BY[dayEl], SHENG[dayEl], KE[dayEl]].filter(Boolean),
|
|
8385
|
-
basis: `${level}(${dayEl}):宜克、泄、耗——用${KE_BY[dayEl]}(克我)、${SHENG[dayEl]}(我生)、${KE[dayEl]}(我克)`,
|
|
8386
|
-
};
|
|
9446
|
+
function readingOf(ch, kind) { const info = EL_INDEX.get(ch);
|
|
9447
|
+
if (info && info.py) return { py: info.py, tone: info.tone };
|
|
9448
|
+
if (kind === 'surname' && SURNAME_READING[ch]) {
|
|
9449
|
+
const [py, tone] = SURNAME_READING[ch];
|
|
9450
|
+
return { py, tone };
|
|
8387
9451
|
}
|
|
8388
|
-
|
|
9452
|
+
return null;
|
|
9453
|
+
}
|
|
9454
|
+
|
|
9455
|
+
/**
|
|
9456
|
+
* 五格剖象:天格 / 人格 / 地格 / 外格 / 总格 + 81 数理 + 三才。
|
|
9457
|
+
* 单姓单名、单姓双名、复姓都按通行算法;任一字缺笔画就整体返回 uncomputable,不半算。
|
|
9458
|
+
* @param {string} surname
|
|
9459
|
+
* @param {string} given
|
|
9460
|
+
* @param {Object<string, number>} [overrides] 字 → 康熙笔画,覆盖数据表(会被标为「用户指定」)
|
|
9461
|
+
*/
|
|
9462
|
+
function wuge(surname, given, overrides) {
|
|
9463
|
+
const s = [...String(surname || '')];
|
|
9464
|
+
const g = [...String(given || '')];
|
|
9465
|
+
if (!s.length || !g.length) return { available: false, reason: '需要姓与名才能排五格' };
|
|
9466
|
+
if (s.length > 2) return { available: false, reason: '姓超过两字:五格只算单姓与常见复姓' };
|
|
9467
|
+
|
|
9468
|
+
// 复姓两字的笔画取自复姓表(逐字存,人格要用姓末字);表里有但用户又覆盖时以用户为准
|
|
9469
|
+
const dbl = s.length === 2 ? DOUBLE_SURNAMES[surname] : null;
|
|
9470
|
+
const useDbl = dbl && !s.some((ch) => overrides && overrides[ch]);
|
|
9471
|
+
const sInfo = useDbl
|
|
9472
|
+
? dbl.s.map((n) => ({ strokes: n, source: 'table' }))
|
|
9473
|
+
: s.map((ch) => strokeOf(ch, overrides, 'surname'));
|
|
9474
|
+
const gInfo = g.map((ch) => strokeOf(ch, overrides, 'given'));
|
|
9475
|
+
const missing = [...s, ...g].filter((ch, i) => !(i < s.length ? sInfo[i] : gInfo[i - s.length]));
|
|
9476
|
+
if (missing.length) {
|
|
8389
9477
|
return {
|
|
8390
|
-
|
|
8391
|
-
|
|
9478
|
+
available: false,
|
|
9479
|
+
reason: `这些字没有康熙笔画数据,五格算不了:${missing.join('、')}——可用 strokeOverrides 传入笔画后再算`,
|
|
9480
|
+
missing,
|
|
8392
9481
|
};
|
|
8393
9482
|
}
|
|
8394
|
-
return { list: ALL.slice(), basis: `${level}:中和不偏,五行皆可用,以字义与音形为先` };
|
|
8395
|
-
}
|
|
8396
9483
|
|
|
8397
|
-
|
|
9484
|
+
const sStroke = sInfo.map((x) => x.strokes);
|
|
9485
|
+
const gStroke = gInfo.map((x) => x.strokes);
|
|
9486
|
+
const sum = (a) => a.reduce((x, y) => x + y, 0);
|
|
9487
|
+
const isDouble = s.length === 2;
|
|
9488
|
+
const tian = isDouble ? sum(sStroke) : sStroke[0] + 1;
|
|
9489
|
+
const ren = sStroke[s.length - 1] + gStroke[0];
|
|
9490
|
+
const di = sum(gStroke) + (g.length === 1 ? 1 : 0);
|
|
9491
|
+
const zong = sum(sStroke) + sum(gStroke);
|
|
9492
|
+
// 单姓单名没有「外侧」,通行本固定记 2;其余情形(单姓双名 / 复姓单名 / 复姓双名)都是 总−人+1
|
|
9493
|
+
const wai = s.length === 1 && g.length === 1 ? 2 : zong - ren + 1;
|
|
9494
|
+
|
|
9495
|
+
const rows = [['天格', tian], ['人格', ren], ['地格', di], ['外格', wai], ['总格', zong]].map(([key, n]) => ({
|
|
9496
|
+
key, strokes: n, ...shuliOf(n),
|
|
9497
|
+
}));
|
|
9498
|
+
const sancaiNums = [tian, ren, di].map((n) => n % 10);
|
|
9499
|
+
const sancaiEl = sancaiNums.map((n) => NUM_ELEMENT[n]);
|
|
9500
|
+
const rels = [
|
|
9501
|
+
{ pair: '天与人', rel: WX_REL(sancaiEl[0], sancaiEl[1]) },
|
|
9502
|
+
{ pair: '人与地', rel: WX_REL(sancaiEl[1], sancaiEl[2]) },
|
|
9503
|
+
];
|
|
9504
|
+
const ordered = sancaiEl[0] === sancaiEl[1] && sancaiEl[1] === sancaiEl[2]
|
|
9505
|
+
? '三才同气,气脉集中'
|
|
9506
|
+
: rels.every((x) => x.rel === '生' || x.rel === '同')
|
|
9507
|
+
? '一路相生,传统看作顺遂'
|
|
9508
|
+
: rels.every((x) => x.rel === '克' || x.rel === '被克')
|
|
9509
|
+
? '相连相克,传统看作内外拉扯'
|
|
9510
|
+
: `${rels.map((x) => `${x.pair}${x.rel}`).join('、')},吉凶各派看法不一`;
|
|
9511
|
+
|
|
9512
|
+
const source = [...sInfo, ...gInfo].some((x) => x.source === 'user') ? 'mixed' : 'table';
|
|
9513
|
+
return {
|
|
9514
|
+
available: true,
|
|
9515
|
+
surnameStyle: isDouble ? '复姓' : '单姓',
|
|
9516
|
+
strokes: [
|
|
9517
|
+
...s.map((ch, i) => ({ char: ch, strokes: sInfo[i].strokes, source: sInfo[i].source, kind: '姓' })),
|
|
9518
|
+
...g.map((ch, i) => ({ char: ch, strokes: gInfo[i].strokes, source: gInfo[i].source, kind: '名' })),
|
|
9519
|
+
],
|
|
9520
|
+
rows,
|
|
9521
|
+
sancai: {
|
|
9522
|
+
elements: sancaiEl,
|
|
9523
|
+
text: `${sancaiEl.join('')}(${ordered})`,
|
|
9524
|
+
relations: rels,
|
|
9525
|
+
},
|
|
9526
|
+
summary: rows.map((r) => `${r.key}${r.strokes}${r.level}`).join(' '),
|
|
9527
|
+
source,
|
|
9528
|
+
};
|
|
9529
|
+
}
|
|
9530
|
+
|
|
9531
|
+
const INITIALS = ['zh', 'ch', 'sh', 'b', 'p', 'm', 'f', 'd', 't', 'n', 'l', 'g', 'k', 'h', 'j', 'q', 'x', 'r', 'z', 'c', 's', 'y', 'w'];
|
|
9532
|
+
|
|
9533
|
+
/** 按拼写切声母韵母:先匹配双字母声母(zh/ch/sh),其余取单字母;y/w 按拼写当声母处理。 */
|
|
9534
|
+
function splitPinyin(py) {
|
|
9535
|
+
const p = String(py || '').toLowerCase();
|
|
9536
|
+
for (const ini of INITIALS) {
|
|
9537
|
+
if (p.startsWith(ini)) return { ini, fin: p.slice(ini.length) };
|
|
9538
|
+
}
|
|
9539
|
+
return { ini: '', fin: p };
|
|
9540
|
+
}
|
|
9541
|
+
|
|
9542
|
+
const TONE_LABEL = { 1: '一', 2: '二', 3: '三', 4: '四' };
|
|
9543
|
+
|
|
9544
|
+
/**
|
|
9545
|
+
* 音韵的机械检查:全名同调 / 相邻同声母 / 相邻同韵母 / 相邻同音(叠字)。
|
|
9546
|
+
* 只报可数的事实,不替人判断好不好听,也不查语义谐音(那需要词库,没做就说没做)。
|
|
9547
|
+
*/
|
|
9548
|
+
function phonetics(fullName) {
|
|
9549
|
+
const chars = [...String(fullName || '')];
|
|
9550
|
+
if (chars.length < 2) return { available: false, reason: '至少两个字才谈得上音韵' };
|
|
9551
|
+
const items = chars.map((ch, i) => {
|
|
9552
|
+
const r = readingOf(ch, i === 0 ? 'surname' : 'given');
|
|
9553
|
+
return r ? { char: ch, py: r.py, tone: r.tone, ...splitPinyin(r.py) } : { char: ch, py: null, tone: null, ini: null, fin: null };
|
|
9554
|
+
});
|
|
9555
|
+
const missing = items.filter((x) => !x.py).map((x) => x.char);
|
|
9556
|
+
if (missing.length) {
|
|
9557
|
+
return { available: false, reason: `这些字没有读音数据:${missing.join('、')}`, missing };
|
|
9558
|
+
}
|
|
9559
|
+
|
|
9560
|
+
const issues = [];
|
|
9561
|
+
const tones = new Set(items.map((x) => x.tone));
|
|
9562
|
+
if (tones.size === 1 && items.length >= 2) {
|
|
9563
|
+
issues.push({ type: 'tone', text: `全名都是${TONE_LABEL[items[0].tone]}声,声调没有起伏` });
|
|
9564
|
+
}
|
|
9565
|
+
for (let i = 1; i < items.length; i++) {
|
|
9566
|
+
const a = items[i - 1];
|
|
9567
|
+
const b = items[i];
|
|
9568
|
+
if (a.py === b.py && a.tone === b.tone) {
|
|
9569
|
+
issues.push({ type: 'same', text: `「${a.char}${b.char}」同音同调(叠字或撞音)` });
|
|
9570
|
+
continue;
|
|
9571
|
+
}
|
|
9572
|
+
if (a.ini && a.ini === b.ini) issues.push({ type: 'initial', text: `「${a.char}${b.char}」同声母 ${a.ini}` });
|
|
9573
|
+
if (a.fin === b.fin) issues.push({ type: 'final', text: `「${a.char}${b.char}」同韵母 ${a.fin}` });
|
|
9574
|
+
}
|
|
9575
|
+
const inis = new Set(items.map((x) => x.ini).filter(Boolean));
|
|
9576
|
+
if (items.length >= 3 && inis.size === 1) {
|
|
9577
|
+
issues.push({ type: 'initial', text: `三字同声母 ${[...inis][0]},连着读容易黏在一起` });
|
|
9578
|
+
}
|
|
9579
|
+
const level = issues.length === 0 ? '顺口' : issues.length === 1 ? '略拗' : '拗口';
|
|
9580
|
+
return {
|
|
9581
|
+
available: true,
|
|
9582
|
+
chars: items.map((x) => ({ char: x.char, py: x.py, tone: x.tone })),
|
|
9583
|
+
tonePattern: items.map((x) => x.tone).join('-'),
|
|
9584
|
+
issues,
|
|
9585
|
+
level,
|
|
9586
|
+
};
|
|
9587
|
+
}
|
|
9588
|
+
|
|
9589
|
+
/** 用户可自带某字的五行(字库未收时用,按你信的那派算;传了就算「用户指定」)。 */
|
|
9590
|
+
function userElement(input, ch) {
|
|
9591
|
+
const map = input && input.charElements;
|
|
9592
|
+
if (!map || typeof map !== 'object') return null;
|
|
9593
|
+
const v = map[ch];
|
|
9594
|
+
return ALL.includes(v) ? v : null;
|
|
9595
|
+
}
|
|
9596
|
+
|
|
9597
|
+
/** 喜用五行里挑几个可替换的常用字(同性别倾向优先),给未收录字一个落点。 */
|
|
9598
|
+
function suggestFor(element, genderPref, exclude, count = 3) {
|
|
9599
|
+
const pool = CHAR_LIB.filter((c) => c[1] === element && !exclude.has(c[0]));
|
|
9600
|
+
pool.sort((a, b) => {
|
|
9601
|
+
const fit = (x) => (x[3] === genderPref || x[3] === 'n' ? 1 : 0);
|
|
9602
|
+
return fit(b) - fit(a);
|
|
9603
|
+
});
|
|
9604
|
+
return pool.slice(0, count).map((c) => ({ char: c[0], element: c[1], meaning: c[2] }));
|
|
9605
|
+
}
|
|
9606
|
+
|
|
9607
|
+
const KIND_LABEL = { m: '男', f: '女', n: '中' };
|
|
9608
|
+
|
|
9609
|
+
/** 喜用五行(简化判定:旺衰 + 生克泄耗)。 */
|
|
9610
|
+
function favorableElements(strength) {
|
|
9611
|
+
const level = strength && strength.level ? strength.level : null;
|
|
9612
|
+
const dayEl = strength && strength.dayElement ? strength.dayElement : null;
|
|
9613
|
+
if (!dayEl || !level) return { list: ALL.slice(), basis: '未取得旺衰:不筛五行,只做用字与字义建议' };
|
|
9614
|
+
if (level === '身强' || level === '偏强') {
|
|
9615
|
+
return {
|
|
9616
|
+
list: [KE_BY[dayEl], SHENG[dayEl], KE[dayEl]].filter(Boolean),
|
|
9617
|
+
basis: `${level}(${dayEl}):宜克、泄、耗——用${KE_BY[dayEl]}(克我)、${SHENG[dayEl]}(我生)、${KE[dayEl]}(我克)`,
|
|
9618
|
+
};
|
|
9619
|
+
}
|
|
9620
|
+
if (level === '身弱' || level === '偏弱') {
|
|
9621
|
+
return {
|
|
9622
|
+
list: [dayEl, SHENG_BY[dayEl]].filter(Boolean),
|
|
9623
|
+
basis: `${level}(${dayEl}):宜生、扶——用${dayEl}(同我)、${SHENG_BY[dayEl]}(生我)`,
|
|
9624
|
+
};
|
|
9625
|
+
}
|
|
9626
|
+
return { list: ALL.slice(), basis: `${level}:中和不偏,五行皆可用,以字义与音形为先` };
|
|
9627
|
+
}
|
|
9628
|
+
|
|
9629
|
+
function charInfo(ch) {
|
|
8398
9630
|
return EL_INDEX.get(ch) || null;
|
|
8399
9631
|
}
|
|
8400
9632
|
|
|
@@ -8467,6 +9699,10 @@ function assessName(input) {
|
|
|
8467
9699
|
else if (favCount > 0) verdict = `部分用字合喜用(${favCount}/${judged}),其余可再斟酌;喜用为 ${favorable.list.join('、')}。`;
|
|
8468
9700
|
else verdict = `用字未落在喜用(${favorable.list.join('、')})上;不必然是坏名,但若想贴合命局可换字再看。`;
|
|
8469
9701
|
|
|
9702
|
+
const ov = overridesOf(input);
|
|
9703
|
+
const wu = wuge(surname, given, ov);
|
|
9704
|
+
const ph = phonetics(surname + given);
|
|
9705
|
+
|
|
8470
9706
|
return {
|
|
8471
9707
|
system: 'name',
|
|
8472
9708
|
action: 'assess',
|
|
@@ -8482,11 +9718,14 @@ function assessName(input) {
|
|
|
8482
9718
|
},
|
|
8483
9719
|
} : {}),
|
|
8484
9720
|
chars,
|
|
8485
|
-
|
|
9721
|
+
wuge: wu,
|
|
9722
|
+
phonetics: ph,
|
|
9723
|
+
stats: { chars: chars.length, known, unknown, favorableCount: favCount, libSize: CHAR_LIB.length, wugeReady: wu.available === true },
|
|
8486
9724
|
verdict,
|
|
8487
9725
|
notes: [
|
|
8488
9726
|
`字之五行按通行字义/偏旁归类,自建字库共 ${CHAR_LIB.length} 字(常用名用字为主);未收录的字不猜五行,如实标注,「用户指定」是你传入的归类。`,
|
|
8489
|
-
'
|
|
9727
|
+
'五格按康熙字典繁体笔画计(氵→水4、艹→艸6、华→華14 这类换算),81 数理取通行本、各派对少数数取法有出入;姓氏笔画表没覆盖的姓或你想按别派算,可传 strokeOverrides 覆盖。',
|
|
9728
|
+
'音韵只做机械检查(全名同调、相邻同声母/同韵母、叠字),不做语义谐音判断——谐音、方言读法还得自己读三遍。',
|
|
8490
9729
|
'起名只做用字参考,不替父母做决定。',
|
|
8491
9730
|
],
|
|
8492
9731
|
};
|
|
@@ -8519,6 +9758,15 @@ function generateNames(input) {
|
|
|
8519
9758
|
const fav = favorableElements(strength);
|
|
8520
9759
|
const pool = CHAR_LIB.filter((c) => fav.list.includes(c[1]) && c[0] !== surname);
|
|
8521
9760
|
const gPref = gender === 'male' ? 'm' : 'f';
|
|
9761
|
+
// 五格只影响排序:姓的笔画整轮不变,先备好;每个候选只做四次取数与查表
|
|
9762
|
+
const sChars = [...surname];
|
|
9763
|
+
const ov = overridesOf(input);
|
|
9764
|
+
const sStroke = sChars.map((ch) => strokeOf(ch, ov, 'surname'));
|
|
9765
|
+
const sReady = sChars.length <= 2 && sStroke.every(Boolean);
|
|
9766
|
+
const sSum = sReady ? sStroke.reduce((x, y) => x + y.strokes, 0) : 0;
|
|
9767
|
+
const sLast = sReady ? sStroke[sStroke.length - 1].strokes : 0;
|
|
9768
|
+
const lv = (n) => { const r = shuliOf(n); return r ? (r.level === '吉' ? 2 : r.level === '半吉' ? 1 : 0) : 0; };
|
|
9769
|
+
const poolStroke = new Map(pool.map((c) => [c[0], (strokeOf(c[0], ov, 'given') || {}).strokes || 0]));
|
|
8522
9770
|
const scored = [];
|
|
8523
9771
|
for (let i = 0; i < pool.length; i++) {
|
|
8524
9772
|
for (let j = 0; j < pool.length; j++) {
|
|
@@ -8528,6 +9776,15 @@ function generateNames(input) {
|
|
|
8528
9776
|
// 性别倾向:优先本性别与中性,避免两个字都强烈偏另一性别
|
|
8529
9777
|
const fit = (x) => (x[3] === gPref || x[3] === 'n' ? 1 : 0);
|
|
8530
9778
|
const gScore = fit(a) + fit(b) - (a[3] !== gPref && a[3] !== 'n' && b[3] !== gPref && b[3] !== 'n' ? 2 : 0);
|
|
9779
|
+
const aSt = poolStroke.get(a[0]);
|
|
9780
|
+
const bSt = poolStroke.get(b[0]);
|
|
9781
|
+
let wuScore = 0;
|
|
9782
|
+
if (sReady && aSt && bSt) {
|
|
9783
|
+
const ren = sLast + aSt;
|
|
9784
|
+
const di = aSt + bSt;
|
|
9785
|
+
const zong = sSum + aSt + bSt;
|
|
9786
|
+
wuScore = lv(ren) + lv(di) + lv(zong) + lv(zong - ren + 1);
|
|
9787
|
+
}
|
|
8531
9788
|
scored.push({
|
|
8532
9789
|
name: a[0] + b[0],
|
|
8533
9790
|
chars: [
|
|
@@ -8537,12 +9794,14 @@ function generateNames(input) {
|
|
|
8537
9794
|
elements: [a[1], b[1]],
|
|
8538
9795
|
allFavorable: fav.list.includes(a[1]) && fav.list.includes(b[1]),
|
|
8539
9796
|
genderScore: gScore,
|
|
9797
|
+
wugeScore: wuScore,
|
|
8540
9798
|
order: (i * 7 + j * 13) % 9973, // 打散字库顺序,避免候选清一色都是前几个字
|
|
8541
9799
|
});
|
|
8542
9800
|
}
|
|
8543
9801
|
}
|
|
8544
9802
|
const mixed = (c) => (c.elements[0] !== c.elements[1] ? 1 : 0); // 两字异行,比同气堆叠更有层次
|
|
8545
|
-
scored.sort((x, y) => (y.allFavorable - x.allFavorable) || (mixed(y) - mixed(x))
|
|
9803
|
+
scored.sort((x, y) => (y.allFavorable - x.allFavorable) || (mixed(y) - mixed(x))
|
|
9804
|
+
|| (y.wugeScore - x.wugeScore) || (y.genderScore - x.genderScore) || (x.order - y.order));
|
|
8546
9805
|
// 去重 + 用字轮换:先收「两个字都没出现过」的候选,再放宽——避免 20 个候选里 13 个都用同一个「梓」
|
|
8547
9806
|
const out = [];
|
|
8548
9807
|
const usedNames = new Set();
|
|
@@ -8557,7 +9816,11 @@ function generateNames(input) {
|
|
|
8557
9816
|
usedNames.add(key);
|
|
8558
9817
|
usedPairs.add(pair);
|
|
8559
9818
|
cand.chars.forEach((x) => usedChars.add(x.char));
|
|
8560
|
-
out.push({
|
|
9819
|
+
out.push({
|
|
9820
|
+
rank: out.length + 1, name: surname + cand.name, given: cand.name, chars: cand.chars,
|
|
9821
|
+
wuge: wuge(surname, cand.name, ov),
|
|
9822
|
+
phonetics: phonetics(surname + cand.name),
|
|
9823
|
+
});
|
|
8561
9824
|
return true;
|
|
8562
9825
|
};
|
|
8563
9826
|
// 三轮:①新字 + 新五行组合 ②新字 ③放开——先保证候选之间不撞字、不撞组合
|
|
@@ -8582,8 +9845,11 @@ function generateNames(input) {
|
|
|
8582
9845
|
candidates: out,
|
|
8583
9846
|
notes: [
|
|
8584
9847
|
`字库共 ${CHAR_LIB.length} 字,只在喜用五行(${fav.list.join('、')})里选字;未覆盖的生僻好字可用 charElements 指定五行后评估。`,
|
|
8585
|
-
'
|
|
8586
|
-
|
|
9848
|
+
'候选排序依次看:合喜用 → 两字异行 → 五格(人格/地格/总格/外格 吉多者先)→ 性别倾向 → 字库序,是排序不是「吉名」判定。',
|
|
9849
|
+
sReady
|
|
9850
|
+
? '五格按康熙字典繁体笔画与通行本 81 数理算;姓的笔画取自内置姓氏表,没覆盖的姓可传 surnameStrokes 或 strokeOverrides。'
|
|
9851
|
+
: '姓的笔画不在内置姓氏表里,这一轮没按五格排序(不半算);可传 surnameStrokes 或 strokeOverrides 后重算。',
|
|
9852
|
+
'音韵只做机械检查(同调、相邻同声母/同韵母、叠字),不做语义谐音判断——候选的音韵结果随每条一起给出。',
|
|
8587
9853
|
],
|
|
8588
9854
|
};
|
|
8589
9855
|
}
|
|
@@ -8594,7 +9860,7 @@ function buildName(input) {
|
|
|
8594
9860
|
return assessName(input);
|
|
8595
9861
|
}
|
|
8596
9862
|
|
|
8597
|
-
return { CHAR_LIB, favorableElements, assessName, generateNames, buildName };
|
|
9863
|
+
return { CHAR_LIB, shuliOf, wuge, splitPinyin, phonetics, favorableElements, assessName, generateNames, buildName };
|
|
8598
9864
|
})();
|
|
8599
9865
|
|
|
8600
9866
|
__mods['ziwei-hepan'] = (function () {
|
|
@@ -11276,328 +12542,373 @@ return { buildConvert };
|
|
|
11276
12542
|
})();
|
|
11277
12543
|
|
|
11278
12544
|
__mods['interpret-plain'] = (function () {
|
|
11279
|
-
// 白话层:把「专业表述」翻译成「问的人能读懂的话」
|
|
11280
|
-
//
|
|
11281
|
-
// 设计原则:
|
|
11282
|
-
// · 只从盘面已有字段推导,不编造盘上没有的东西;
|
|
11283
|
-
// · 一律用倾向性措辞(避讳「一定/必然/注定」这类绝对化表述);
|
|
11284
|
-
// · 每个字段都可能缺失(海外盘、静卦、缺资料),取不到就整句不出,绝不输出 undefined;
|
|
11285
|
-
// · 与 interpret.js 无循环依赖:需要的外部常量(档位文案等)由调用方通过 ctx 传入。
|
|
11286
|
-
|
|
11287
|
-
const s = (v, fallback = '') => (v === undefined || v === null || v === '' ? fallback : String(v));
|
|
11288
|
-
const join = (arr) => (Array.isArray(arr) ? arr.filter(Boolean).join('') : '');
|
|
11289
|
-
const has = (v) => (Array.isArray(v) ? v.length > 0 : v !== undefined && v !== null && v !== '');
|
|
11290
|
-
|
|
11291
|
-
// 旺衰 → 生活化比喻(这是「说人话」的核心:把分数讲成体感)
|
|
11292
|
-
const STRENGTH_PLAIN = {
|
|
11293
|
-
身强: '底子偏足、抗压能力好,但容易自己给自己加码,学会收力比使劲更重要',
|
|
11294
|
-
偏强: '底子略足,扛得住事,也容易把事都往自己身上揽',
|
|
11295
|
-
中和: '力量比较匀,属于「给什么环境就长出什么样子」的类型',
|
|
11296
|
-
偏弱: '底子偏薄,靠外部支援比硬扛有效,选对圈子与节奏很关键',
|
|
11297
|
-
身弱: '底子偏薄,先修恢复力再谈冲刺,硬撑的性价比最低',
|
|
11298
|
-
};
|
|
11299
|
-
|
|
11300
|
-
// 卦体关系 → 生活化一句话(六冲六合讲聚散,伏吟讲原地,反吟讲反复)
|
|
11301
|
-
const PLAIN_BODY = {
|
|
11302
|
-
六冲卦: '这一卦是「六冲」,事情起落快,急事反而好办,拖久了的人事容易散。',
|
|
11303
|
-
六合卦: '这一卦是「六合」,容易谈成,也容易黏住不放。',
|
|
11304
|
-
变六冲: '往下走会散,收尾别拖。',
|
|
11305
|
-
变六合: '往下走会合,事情倾向于延续下去。',
|
|
11306
|
-
内卦伏吟: '事情卡在原地打转,想动但动不了。',
|
|
11307
|
-
外卦伏吟: '外面那层没变,看起来在动,其实格局照旧。',
|
|
11308
|
-
内卦反吟: '反复在自己这一头,改了又改回来。',
|
|
11309
|
-
外卦反吟: '外面反复,对方或环境会来回拉扯。',
|
|
11310
|
-
化进神: '有一爻在往上走,顺着这股劲推比往回拉顺。',
|
|
11311
|
-
化退神: '有一爻在往后退,别按原来的势头硬推。',
|
|
11312
|
-
};
|
|
11313
|
-
|
|
11314
|
-
|
|
11315
|
-
|
|
11316
|
-
|
|
11317
|
-
|
|
11318
|
-
|
|
11319
|
-
|
|
11320
|
-
|
|
11321
|
-
|
|
11322
|
-
|
|
11323
|
-
|
|
11324
|
-
|
|
11325
|
-
|
|
11326
|
-
|
|
11327
|
-
|
|
11328
|
-
|
|
11329
|
-
|
|
11330
|
-
|
|
11331
|
-
|
|
11332
|
-
|
|
11333
|
-
|
|
11334
|
-
|
|
11335
|
-
|
|
11336
|
-
|
|
11337
|
-
|
|
11338
|
-
|
|
11339
|
-
|
|
11340
|
-
|
|
11341
|
-
|
|
11342
|
-
|
|
11343
|
-
|
|
11344
|
-
|
|
11345
|
-
|
|
11346
|
-
|
|
11347
|
-
function
|
|
11348
|
-
|
|
11349
|
-
|
|
11350
|
-
const
|
|
11351
|
-
|
|
11352
|
-
|
|
11353
|
-
|
|
11354
|
-
|
|
11355
|
-
|
|
11356
|
-
|
|
11357
|
-
|
|
11358
|
-
|
|
11359
|
-
|
|
11360
|
-
|
|
11361
|
-
|
|
11362
|
-
|
|
11363
|
-
|
|
11364
|
-
|
|
11365
|
-
|
|
11366
|
-
|
|
11367
|
-
|
|
11368
|
-
|
|
11369
|
-
|
|
11370
|
-
|
|
11371
|
-
|
|
11372
|
-
|
|
11373
|
-
|
|
11374
|
-
|
|
11375
|
-
const
|
|
11376
|
-
const
|
|
11377
|
-
|
|
11378
|
-
|
|
11379
|
-
if (
|
|
11380
|
-
return
|
|
11381
|
-
}
|
|
11382
|
-
|
|
11383
|
-
|
|
11384
|
-
|
|
11385
|
-
|
|
11386
|
-
|
|
11387
|
-
|
|
11388
|
-
|
|
11389
|
-
|
|
11390
|
-
|
|
11391
|
-
|
|
11392
|
-
|
|
11393
|
-
|
|
11394
|
-
|
|
11395
|
-
|
|
11396
|
-
|
|
11397
|
-
|
|
11398
|
-
|
|
11399
|
-
|
|
11400
|
-
const
|
|
11401
|
-
|
|
11402
|
-
|
|
11403
|
-
|
|
11404
|
-
|
|
11405
|
-
|
|
11406
|
-
|
|
11407
|
-
|
|
11408
|
-
}
|
|
11409
|
-
|
|
11410
|
-
|
|
11411
|
-
|
|
11412
|
-
|
|
11413
|
-
|
|
11414
|
-
|
|
11415
|
-
|
|
11416
|
-
|
|
11417
|
-
|
|
11418
|
-
|
|
11419
|
-
|
|
11420
|
-
|
|
11421
|
-
|
|
11422
|
-
|
|
11423
|
-
|
|
11424
|
-
|
|
11425
|
-
|
|
11426
|
-
|
|
11427
|
-
|
|
11428
|
-
|
|
11429
|
-
|
|
11430
|
-
|
|
11431
|
-
|
|
11432
|
-
|
|
11433
|
-
|
|
11434
|
-
|
|
11435
|
-
|
|
11436
|
-
|
|
11437
|
-
|
|
11438
|
-
|
|
11439
|
-
|
|
11440
|
-
|
|
11441
|
-
|
|
11442
|
-
|
|
11443
|
-
|
|
11444
|
-
|
|
11445
|
-
|
|
11446
|
-
|
|
11447
|
-
|
|
11448
|
-
return
|
|
11449
|
-
|
|
11450
|
-
|
|
11451
|
-
|
|
11452
|
-
|
|
11453
|
-
|
|
11454
|
-
|
|
11455
|
-
|
|
11456
|
-
|
|
11457
|
-
|
|
11458
|
-
|
|
11459
|
-
|
|
11460
|
-
|
|
11461
|
-
|
|
11462
|
-
|
|
11463
|
-
|
|
11464
|
-
|
|
11465
|
-
|
|
11466
|
-
|
|
11467
|
-
|
|
11468
|
-
|
|
11469
|
-
|
|
11470
|
-
|
|
11471
|
-
|
|
11472
|
-
|
|
11473
|
-
|
|
11474
|
-
|
|
11475
|
-
|
|
11476
|
-
|
|
11477
|
-
|
|
11478
|
-
|
|
11479
|
-
|
|
11480
|
-
|
|
11481
|
-
|
|
11482
|
-
|
|
11483
|
-
|
|
11484
|
-
|
|
11485
|
-
|
|
11486
|
-
|
|
11487
|
-
|
|
11488
|
-
|
|
11489
|
-
|
|
11490
|
-
|
|
11491
|
-
return
|
|
11492
|
-
|
|
11493
|
-
|
|
11494
|
-
|
|
11495
|
-
|
|
11496
|
-
|
|
11497
|
-
|
|
11498
|
-
|
|
11499
|
-
|
|
11500
|
-
|
|
11501
|
-
|
|
11502
|
-
|
|
11503
|
-
|
|
11504
|
-
|
|
11505
|
-
|
|
11506
|
-
|
|
11507
|
-
|
|
11508
|
-
|
|
11509
|
-
|
|
11510
|
-
|
|
11511
|
-
|
|
11512
|
-
|
|
11513
|
-
|
|
11514
|
-
|
|
11515
|
-
|
|
11516
|
-
|
|
11517
|
-
|
|
11518
|
-
|
|
11519
|
-
|
|
11520
|
-
|
|
11521
|
-
|
|
11522
|
-
|
|
11523
|
-
|
|
11524
|
-
|
|
11525
|
-
|
|
11526
|
-
|
|
11527
|
-
|
|
11528
|
-
|
|
11529
|
-
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
|
|
11533
|
-
|
|
11534
|
-
|
|
11535
|
-
|
|
11536
|
-
|
|
11537
|
-
|
|
11538
|
-
|
|
11539
|
-
|
|
11540
|
-
|
|
11541
|
-
|
|
11542
|
-
|
|
11543
|
-
|
|
11544
|
-
|
|
11545
|
-
|
|
11546
|
-
|
|
11547
|
-
|
|
11548
|
-
|
|
11549
|
-
|
|
11550
|
-
|
|
11551
|
-
|
|
11552
|
-
|
|
11553
|
-
|
|
11554
|
-
|
|
11555
|
-
|
|
11556
|
-
|
|
11557
|
-
|
|
11558
|
-
|
|
11559
|
-
const
|
|
11560
|
-
|
|
11561
|
-
|
|
11562
|
-
|
|
11563
|
-
|
|
11564
|
-
|
|
11565
|
-
|
|
11566
|
-
|
|
11567
|
-
|
|
11568
|
-
|
|
11569
|
-
|
|
11570
|
-
|
|
11571
|
-
|
|
11572
|
-
|
|
11573
|
-
|
|
11574
|
-
|
|
11575
|
-
|
|
11576
|
-
|
|
11577
|
-
|
|
11578
|
-
|
|
11579
|
-
|
|
11580
|
-
|
|
11581
|
-
|
|
11582
|
-
|
|
11583
|
-
|
|
11584
|
-
|
|
11585
|
-
|
|
11586
|
-
|
|
11587
|
-
|
|
11588
|
-
|
|
11589
|
-
|
|
11590
|
-
|
|
11591
|
-
|
|
11592
|
-
|
|
11593
|
-
|
|
11594
|
-
|
|
11595
|
-
|
|
11596
|
-
|
|
11597
|
-
|
|
11598
|
-
|
|
11599
|
-
|
|
11600
|
-
|
|
12545
|
+
// 白话层:把「专业表述」翻译成「问的人能读懂的话」
|
|
12546
|
+
//
|
|
12547
|
+
// 设计原则:
|
|
12548
|
+
// · 只从盘面已有字段推导,不编造盘上没有的东西;
|
|
12549
|
+
// · 一律用倾向性措辞(避讳「一定/必然/注定」这类绝对化表述);
|
|
12550
|
+
// · 每个字段都可能缺失(海外盘、静卦、缺资料),取不到就整句不出,绝不输出 undefined;
|
|
12551
|
+
// · 与 interpret.js 无循环依赖:需要的外部常量(档位文案等)由调用方通过 ctx 传入。
|
|
12552
|
+
|
|
12553
|
+
const s = (v, fallback = '') => (v === undefined || v === null || v === '' ? fallback : String(v));
|
|
12554
|
+
const join = (arr) => (Array.isArray(arr) ? arr.filter(Boolean).join('') : '');
|
|
12555
|
+
const has = (v) => (Array.isArray(v) ? v.length > 0 : v !== undefined && v !== null && v !== '');
|
|
12556
|
+
|
|
12557
|
+
// 旺衰 → 生活化比喻(这是「说人话」的核心:把分数讲成体感)
|
|
12558
|
+
const STRENGTH_PLAIN = {
|
|
12559
|
+
身强: '底子偏足、抗压能力好,但容易自己给自己加码,学会收力比使劲更重要',
|
|
12560
|
+
偏强: '底子略足,扛得住事,也容易把事都往自己身上揽',
|
|
12561
|
+
中和: '力量比较匀,属于「给什么环境就长出什么样子」的类型',
|
|
12562
|
+
偏弱: '底子偏薄,靠外部支援比硬扛有效,选对圈子与节奏很关键',
|
|
12563
|
+
身弱: '底子偏薄,先修恢复力再谈冲刺,硬撑的性价比最低',
|
|
12564
|
+
};
|
|
12565
|
+
|
|
12566
|
+
// 卦体关系 → 生活化一句话(六冲六合讲聚散,伏吟讲原地,反吟讲反复)
|
|
12567
|
+
const PLAIN_BODY = {
|
|
12568
|
+
六冲卦: '这一卦是「六冲」,事情起落快,急事反而好办,拖久了的人事容易散。',
|
|
12569
|
+
六合卦: '这一卦是「六合」,容易谈成,也容易黏住不放。',
|
|
12570
|
+
变六冲: '往下走会散,收尾别拖。',
|
|
12571
|
+
变六合: '往下走会合,事情倾向于延续下去。',
|
|
12572
|
+
内卦伏吟: '事情卡在原地打转,想动但动不了。',
|
|
12573
|
+
外卦伏吟: '外面那层没变,看起来在动,其实格局照旧。',
|
|
12574
|
+
内卦反吟: '反复在自己这一头,改了又改回来。',
|
|
12575
|
+
外卦反吟: '外面反复,对方或环境会来回拉扯。',
|
|
12576
|
+
化进神: '有一爻在往上走,顺着这股劲推比往回拉顺。',
|
|
12577
|
+
化退神: '有一爻在往后退,别按原来的势头硬推。',
|
|
12578
|
+
};
|
|
12579
|
+
|
|
12580
|
+
// 伏神出伏的四档 → 一句白话;只讲条件,不把它说成应期
|
|
12581
|
+
const FUSHEN_PLAIN = {
|
|
12582
|
+
可出: '眼下的条件算是有助无压,属于「出得来」的一档——这是条件,不等于马上应验。',
|
|
12583
|
+
有助有压: '眼下是一边有助、一边有压,出得来,但得费点劲。',
|
|
12584
|
+
受压难出: '眼下被上面的力量压着,不太容易露头,先别急着硬推。',
|
|
12585
|
+
未得助: '眼下暂时没借到力,还得等条件转过来。',
|
|
12586
|
+
飞伏未知: '飞伏关系看不全,这一层先不下判断。',
|
|
12587
|
+
};
|
|
12588
|
+
|
|
12589
|
+
/**
|
|
12590
|
+
* 用神 → 一句白话。
|
|
12591
|
+
* 只说「用神落在哪、有没有动、要不要往深处找」,不替人断成败。
|
|
12592
|
+
*/
|
|
12593
|
+
function usePlainOf(ug, fa) {
|
|
12594
|
+
if (!ug || !ug.liuqin) return '';
|
|
12595
|
+
if (ug.found.length) {
|
|
12596
|
+
const pos = ug.found.map((f) => `第${f.position}爻`).join('、');
|
|
12597
|
+
const moving = ug.found.some((f) => f.moving);
|
|
12598
|
+
const who = ug.byShi ? '代表你自己' : `就是「${ug.liuqin}」这一类事`;
|
|
12599
|
+
return `你问的这件事,在卦里对应${pos}${who}——${moving ? '这一爻还在动,说明事情正在推进' : '这一爻没动,先按现状看'}。`;
|
|
12600
|
+
}
|
|
12601
|
+
if (ug.fushen.length) {
|
|
12602
|
+
const f = ug.fushen[0];
|
|
12603
|
+
const hit = fa && Array.isArray(fa.items) ? fa.items.find((x) => x.position === f.position) : null;
|
|
12604
|
+
const tail = hit ? ` ${FUSHEN_PLAIN[hit.verdict] || ''}` : '';
|
|
12605
|
+
return `你问的这件事,卦面上没有直接露出来,得往深处找:它藏在第${f.position}爻下面(伏神),与上面的关系是「${f.relation || '—'}」,要借力才出得来。${tail}`;
|
|
12606
|
+
}
|
|
12607
|
+
return '';
|
|
12608
|
+
}
|
|
12609
|
+
|
|
12610
|
+
/**
|
|
12611
|
+
* 用神旺衰 → 一句白话。
|
|
12612
|
+
*/
|
|
12613
|
+
function useStrengthPlain(st) {
|
|
12614
|
+
if (!st || !st.lines || !st.lines.length) return '';
|
|
12615
|
+
const dead = st.lines.filter((l) => /死|囚/.test(l.monthState) || l.monthChong);
|
|
12616
|
+
const live = st.lines.filter((l) => /旺|相/.test(l.monthState));
|
|
12617
|
+
const when = st.month && st.month.branch ? `眼下这阵子(${st.month.branch}月)` : '起卦这段日子';
|
|
12618
|
+
if (dead.length && !live.length) return `${when}对这件事不太帮忙,气有点被压着——先别急着硬推,等风向转。`;
|
|
12619
|
+
if (live.length && !dead.length) return `${when}对这件事是帮着的,气正在往上走,能推就趁现在。`;
|
|
12620
|
+
return `${when}对这件事有帮有压,一半的力要自己挣——结果更看你怎么走。`;
|
|
12621
|
+
}
|
|
12622
|
+
|
|
12623
|
+
// 化进 / 化退的力重 → 一句白话:方向之外,时令托不托着
|
|
12624
|
+
function jinTuiPlain(r) {
|
|
12625
|
+
const jp = r && r.jinTuiPower;
|
|
12626
|
+
if (!jp || !Array.isArray(jp.lines) || !jp.lines.length) return '';
|
|
12627
|
+
const sayOf = (l) => (l.verdict === '后劲足' ? '时令托着,后劲足'
|
|
12628
|
+
: l.verdict === '后劲有限' ? '时令不太托,后劲有限'
|
|
12629
|
+
: l.verdict === '进得虚' ? '时令最背,进也是虚进'
|
|
12630
|
+
: l.verdict === '退得缓' ? '时令还托着,退得慢'
|
|
12631
|
+
: l.verdict === '退得实' ? '时令也不托,退得实'
|
|
12632
|
+
: l.verdict === '月破失据' ? '又正好逢月破,进退都站不稳'
|
|
12633
|
+
: '缺月建,先只当方向看');
|
|
12634
|
+
return `动爻的进退还要看时令:${jp.lines.map((l) => `${l.position}爻${l.from}→${l.to}${l.type},${sayOf(l)}`).join(';')}。`;
|
|
12635
|
+
}
|
|
12636
|
+
|
|
12637
|
+
// 全卦逐爻旺衰 → 一句白话:整张卦的气偏在哪一头(与用神那一句分开说)
|
|
12638
|
+
function hexStrengthPlain(hs) {
|
|
12639
|
+
if (!hs || !hs.counts) return '';
|
|
12640
|
+
const up = (hs.counts.旺 || 0) + (hs.counts.相 || 0);
|
|
12641
|
+
const down = (hs.counts.囚 || 0) + (hs.counts.死 || 0);
|
|
12642
|
+
const when = hs.month && hs.month.branch ? `按${hs.month.branch}月这段时令看` : '按起卦这天看';
|
|
12643
|
+
const shi = hs.shi && hs.shi.monthState !== 'unknown' ? `代表你的世爻在${hs.shi.monthState}` : '';
|
|
12644
|
+
if (up >= 4 && down === 0) return `${when},整张卦六爻的气多数是顺的,${shi},眼下算是好推的时候。`;
|
|
12645
|
+
if (down >= 4 && up === 0) return `${when},整张卦六爻的气多数被压着,${shi},这几天更适合等而不是冲。`;
|
|
12646
|
+
return `${when},整张卦六爻有顺有逆(旺相 ${up} 爻、囚死 ${down} 爻)${shi ? `,${shi}` : ''},成不成要看具体哪一爻在动。`;
|
|
12647
|
+
}
|
|
12648
|
+
|
|
12649
|
+
// 三方四正复合飞化 → 一句白话:四股力有没有挤到同一处
|
|
12650
|
+
function flyCompositePlain(fc) {
|
|
12651
|
+
if (!fc || !Array.isArray(fc.targets)) return '';
|
|
12652
|
+
const hub = fc.targets.find((t) => t.count >= 2);
|
|
12653
|
+
const self = fc.groups && fc.groups.selfHua && fc.groups.selfHua.length
|
|
12654
|
+
? '其中有的宫自己化出去又落回自己,容易表现为「想得多、落得少」。'
|
|
12655
|
+
: '';
|
|
12656
|
+
if (!hub) return `把命宫连同对宫、两个三合宫一起看,四股力飞出去没有挤到同一处,这几件事之间牵连不深。${self}`;
|
|
12657
|
+
return `把命宫连同对宫与两个三合宫一起看,${hub.incoming.length} 股力最后挤在「${String(hub.palace).replace(/宫$/, '')}」这件事上——这件事会把好几个方面的劲都吸过来。${self}`;
|
|
12658
|
+
}
|
|
12659
|
+
|
|
12660
|
+
/**
|
|
12661
|
+
* 六爻卦体 → 一句白话。
|
|
12662
|
+
* 标签可能带爻位(「化进神 5」),所以按前缀匹配;
|
|
12663
|
+
* 主句取标签顺序里第一个能说的,化进/化退作为补充句跟在后面(它们只说某一爻,不覆盖全局)。
|
|
12664
|
+
*/
|
|
12665
|
+
function bodyPlainOf(labels) {
|
|
12666
|
+
const keyOf = (l) => Object.keys(PLAIN_BODY).find((k) => l === k || l.startsWith(`${k} `)) || '';
|
|
12667
|
+
const primary = labels.find((l) => keyOf(l));
|
|
12668
|
+
const main = primary ? PLAIN_BODY[keyOf(primary)] : '';
|
|
12669
|
+
const extra = labels
|
|
12670
|
+
.filter((l) => l !== primary && /^化[进退]神 /.test(l))
|
|
12671
|
+
.map((l) => PLAIN_BODY[keyOf(l)])
|
|
12672
|
+
.filter(Boolean);
|
|
12673
|
+
return main + extra.join('');
|
|
12674
|
+
}
|
|
12675
|
+
|
|
12676
|
+
// 询问方向 → 该往哪一节看
|
|
12677
|
+
const DIR_SECTION = {
|
|
12678
|
+
wealth: '「工作与职业选择」与「时间窗」',
|
|
12679
|
+
career: '「事业发展」与「时间窗」',
|
|
12680
|
+
love: '「爱情与感情」',
|
|
12681
|
+
health: '「健康状况」',
|
|
12682
|
+
study: '「事业发展」与「时间窗」',
|
|
12683
|
+
travel: '「整体运势」与「时间窗」',
|
|
12684
|
+
general: '「整体运势」与「看盘顺序」',
|
|
12685
|
+
};
|
|
12686
|
+
|
|
12687
|
+
/** 一句话直答:先回答「你问的事」,再指路到具体小节 */
|
|
12688
|
+
function buildAnswer(r, ask, ctx = {}) {
|
|
12689
|
+
if (!r || !r.system) return '';
|
|
12690
|
+
const q = s(ask && ask.question).trim();
|
|
12691
|
+
const dir = (ask && ask.direction) || 'general';
|
|
12692
|
+
// 只有八字的维度与「时间窗」是固定名称,其余体系用中性说法,避免指向不存在的小节
|
|
12693
|
+
const where = r.system === 'bazi'
|
|
12694
|
+
? (DIR_SECTION[dir] || DIR_SECTION.general)
|
|
12695
|
+
: '下面与你的问题最贴近的那一节';
|
|
12696
|
+
const head = q ? `你问的是「${q}」。` : '';
|
|
12697
|
+
|
|
12698
|
+
if (r.system === 'bazi') {
|
|
12699
|
+
const dm = r.dayMaster || {};
|
|
12700
|
+
const st = r.strength || {};
|
|
12701
|
+
const ys = (r.frame && r.frame.yongshen) || {};
|
|
12702
|
+
const favor = join(ys.favor);
|
|
12703
|
+
const avoid = join(ys.avoid);
|
|
12704
|
+
const ln = (r.liunian || [])[0];
|
|
12705
|
+
const parts = [
|
|
12706
|
+
head + `先说结论:你是${s(dm.stem)}${s(dm.element)}日主,命局${s(st.level, '待定')}` +
|
|
12707
|
+
`${favor ? `,顺${favor}、忌${avoid}——往${favor}的方向安排事情会更省力` : ''}。`,
|
|
12708
|
+
ln && ln.ganzhi
|
|
12709
|
+
? `${s(ln.year)} 年是${ln.ganzhi}年(${s(ln.luck && ln.luck.tier, '平')}),这是「大环境」这一层。`
|
|
12710
|
+
: '',
|
|
12711
|
+
`具体到你问的这件事,重点看${where}。`,
|
|
12712
|
+
];
|
|
12713
|
+
if (!q) parts[parts.length - 1] = `没指定问题,就按${where}的顺序往下看。`;
|
|
12714
|
+
return parts.filter(Boolean).join('');
|
|
12715
|
+
}
|
|
12716
|
+
|
|
12717
|
+
if (r.system === 'ziwei') {
|
|
12718
|
+
const soul = r.soul || {};
|
|
12719
|
+
const body = r.body || {};
|
|
12720
|
+
const bureau = r.bureau || {};
|
|
12721
|
+
const md = r.lifeMaster || '';
|
|
12722
|
+
const ji = r.flyChains && r.flyChains.忌;
|
|
12723
|
+
const plainFly = ji && ji.steps.length
|
|
12724
|
+
? `还有一条线值得留意:${ji.path.map((p) => p.replace(/宫$/, '')).join(' → ')}——这几件事在你身上是连着转的,一件卡住,容易牵动下一件。`
|
|
12725
|
+
: '';
|
|
12726
|
+
return [
|
|
12727
|
+
head + `先说结论:你的命宫落${s(soul.branch, '—')}宫` +
|
|
12728
|
+
`${bureau.name ? `、${bureau.name}` : ''}${md ? `,命主${md}` : ''}` +
|
|
12729
|
+
`${body.lands ? `,身宫落在「${body.lands}」——这张盘的重心在这件事上` : ''}。`,
|
|
12730
|
+
plainFly,
|
|
12731
|
+
flyCompositePlain(r.flyComposite),
|
|
12732
|
+
q ? `具体到你问的这件事,重点看${where}。` : `没指定问题,就按${where}的顺序往下看。`,
|
|
12733
|
+
].filter(Boolean).join('');
|
|
12734
|
+
}
|
|
12735
|
+
|
|
12736
|
+
if (r.system === 'liuyao') {
|
|
12737
|
+
const ben = r.ben || {};
|
|
12738
|
+
const moving = (r.cast && r.cast.movingPositions) || [];
|
|
12739
|
+
const bian = r.bian || {};
|
|
12740
|
+
const labels = (r.body && Array.isArray(r.body.labels)) ? r.body.labels : [];
|
|
12741
|
+
// 六冲六合伏吟反吟里挑最贴近当下局面的一句,避免四句叠着说
|
|
12742
|
+
const plainBody = bodyPlainOf(labels);
|
|
12743
|
+
return [
|
|
12744
|
+
head + `先说结论:本卦是${s(ben.name, '—')}` +
|
|
12745
|
+
`${ben.palace ? `(${ben.palace})` : ''}` +
|
|
12746
|
+
`${moving.length ? `,第 ${moving.join('、')} 爻动,变为${s(bian.name, '—')}` : ',六爻安静没有动爻'}。` +
|
|
12747
|
+
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${hexStrengthPlain(r.hexStrength)}`,
|
|
12748
|
+
'断卦的落点在「世爻」(代表你)和「动爻」(事情的推动点),下面「看盘顺序」就按这个次序展开。',
|
|
12749
|
+
].join('');
|
|
12750
|
+
}
|
|
12751
|
+
|
|
12752
|
+
// 其余体系没有固定小节名:有问才指路;没问就按顺序读,别假装知道「你的问题」
|
|
12753
|
+
if (head) return `${head}下面按五个维度拆开看,重点看${where}。`;
|
|
12754
|
+
// 奇门没有五维,内容按排盘事实/用神/宫位条件几节走,不能跟着说「五个维度」
|
|
12755
|
+
if (r.system === 'qimen') {
|
|
12756
|
+
const dirTip = dir !== 'general' && ask && ask.directionLabel ? `,取「${ask.directionLabel}」方向的用神` : '';
|
|
12757
|
+
return `下面按排盘事实、用神、宫位条件几节展开${dirTip}。`;
|
|
12758
|
+
}
|
|
12759
|
+
if (dir !== 'general' && ask && ask.directionLabel) {
|
|
12760
|
+
return `下面按五个维度拆开看,重点看与「${ask.directionLabel}」方向最贴近的那一节。`;
|
|
12761
|
+
}
|
|
12762
|
+
return '下面按五个维度拆开看,没指定问题,就从头依次读。';
|
|
12763
|
+
}
|
|
12764
|
+
|
|
12765
|
+
/** 说人话整段:去掉术语,用生活语言讲这张盘的整体气质 */
|
|
12766
|
+
function buildPlain(r, ask, ctx = {}) {
|
|
12767
|
+
if (!r || !r.system) return '';
|
|
12768
|
+
if (r.system === 'bazi') {
|
|
12769
|
+
const st = r.strength || {};
|
|
12770
|
+
const ys = (r.frame && r.frame.yongshen) || {};
|
|
12771
|
+
const favor = join(ys.favor);
|
|
12772
|
+
const avoid = join(ys.avoid);
|
|
12773
|
+
const strength = STRENGTH_PLAIN[st.level] || '力量偏中性';
|
|
12774
|
+
const tiaohou = ys.tiaohou && ys.tiaohou.note ? `另外,${ys.tiaohou.note},所以「暖一点、亮一点」的环境通常更舒服。` : '';
|
|
12775
|
+
const sy = (r.liunian || []).find((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
12776
|
+
const syPlain = sy
|
|
12777
|
+
? `再往后看,${sy.year} 年${sy.ganzhi}是${sy.suiyun.signals.map((x) => x.type).join('、')}——传统上把它当作「变化感强一点」的提示,既不是好消息也不是坏消息,遇上时多留个心眼就好。`
|
|
12778
|
+
: '';
|
|
12779
|
+
return `你的命局属于「${s(st.level, '中性')}」:${strength}。` +
|
|
12780
|
+
`${favor ? `能补${favor}的环境(行业、方位、作息、相处的人)会让你省力;${avoid ? `而${avoid}偏重的场合容易空耗,能绕就绕。` : ''}` : ''}` +
|
|
12781
|
+
tiaohou + syPlain;
|
|
12782
|
+
}
|
|
12783
|
+
if (r.system === 'ziwei') {
|
|
12784
|
+
const body = r.body || {};
|
|
12785
|
+
const ji = r.flyChains && r.flyChains.忌;
|
|
12786
|
+
// 只挑忌这一条白话:它最能说「你反复在哪几件事上使劲」
|
|
12787
|
+
// 上面「先答所问」已经报过忌链与飞化的原句,这里换个说法只讲感受,避免同一句念两遍
|
|
12788
|
+
const feltChain = ji && ji.steps.length
|
|
12789
|
+
? '你身上有个绕不开的规律:几件事是连着转的,一件卡住,后面就跟着慢下来。'
|
|
12790
|
+
: '';
|
|
12791
|
+
const fc = r.flyComposite;
|
|
12792
|
+
const hub = fc && Array.isArray(fc.targets) ? fc.targets.find((t) => t.count >= 2) : null;
|
|
12793
|
+
const feltComposite = !fc || !Array.isArray(fc.targets)
|
|
12794
|
+
? ''
|
|
12795
|
+
: hub
|
|
12796
|
+
? `再往深一层,四股力最后也压在「${String(hub.palace).replace(/宫$/, '')}」上——几个方面的劲都往这儿聚。`
|
|
12797
|
+
: '再往深一层,四股的力没有全挤到一处,这几件事之间牵连不深。';
|
|
12798
|
+
const focus = body.lands
|
|
12799
|
+
? `真正让你上心的,多半是「${body.lands}」这件事,做别的总会分心。`
|
|
12800
|
+
: '';
|
|
12801
|
+
return [
|
|
12802
|
+
`紫微讲的是「你与环境怎么互动」,不是谁好谁坏——同一件事换个环境、换个人配合,结果就不一样。`,
|
|
12803
|
+
focus,
|
|
12804
|
+
feltChain,
|
|
12805
|
+
feltComposite,
|
|
12806
|
+
].filter(Boolean).join('');
|
|
12807
|
+
}
|
|
12808
|
+
if (r.system === 'liuyao') {
|
|
12809
|
+
const ben = r.ben || {};
|
|
12810
|
+
const moving = (r.cast && r.cast.movingPositions) || [];
|
|
12811
|
+
const labels = (r.body && Array.isArray(r.body.labels)) ? r.body.labels : [];
|
|
12812
|
+
const plainBody = bodyPlainOf(labels);
|
|
12813
|
+
return `${s(ben.name, '这一卦')}讲的是一个「${moving.length ? '正在动、还会变' : '暂时不动、先看清'}」的局面——` +
|
|
12814
|
+
`${moving.length ? '有动爻,说明事情还有转圜空间,不是死局。' : '六爻安静,说明当下更该观察而不是硬推。'}` +
|
|
12815
|
+
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${hexStrengthPlain(r.hexStrength)}`;
|
|
12816
|
+
}
|
|
12817
|
+
return '';
|
|
12818
|
+
}
|
|
12819
|
+
|
|
12820
|
+
/** 每维一句白话(仅在有盘面数据支撑时给出,避免空话) */
|
|
12821
|
+
function dimensionPlain(key, r, ctx = {}) {
|
|
12822
|
+
if (!r || r.system !== 'bazi') return '';
|
|
12823
|
+
const ys = (r.frame && r.frame.yongshen) || {};
|
|
12824
|
+
const favor = join(ys.favor);
|
|
12825
|
+
const avoid = join(ys.avoid);
|
|
12826
|
+
const st = r.strength || {};
|
|
12827
|
+
if (key === 'overall') return `一句话:底子${s(st.level, '中性')},往${favor || '有利方向'}走省力。`;
|
|
12828
|
+
if (key === 'work') return `一句话:挑${favor || '喜用'}属性的活儿,比硬碰${avoid || '忌神'}省力。`;
|
|
12829
|
+
if (key === 'career') return `一句话:你的上升方式,偏向把${favor || '长处'}做成看得见的成果。`;
|
|
12830
|
+
if (key === 'love') return '一句话:关系里先看清自己要什么,再决定推进速度。';
|
|
12831
|
+
if (key === 'health') return '一句话:作息稳定比任何调理都优先。';
|
|
12832
|
+
return '';
|
|
12833
|
+
}
|
|
12834
|
+
|
|
12835
|
+
// 术语白话表:只解释本篇真正出现的词
|
|
12836
|
+
const GLOSSARY = [
|
|
12837
|
+
['日主', '你出生那天对应的天干,代表「你自己」,整张盘都围着它转。'],
|
|
12838
|
+
['用神', '这张盘里最需要补的那一类力量,顺着它做事更省力。'],
|
|
12839
|
+
['忌神', '补得越多越别扭的那一类力量,不是坏东西,只是对你性价比低。'],
|
|
12840
|
+
['调候', '按出生季节调温补缺:冬天的盘怕冷,夏天的盘怕燥。'],
|
|
12841
|
+
['格局', '把整张盘的结构归成一个类型,用来看「你适合怎么打」。'],
|
|
12842
|
+
['十神', '把五行关系翻译成人事:财=资源、官杀=规则与压力、印=支持、食伤=表达、比劫=同伴。'],
|
|
12843
|
+
['月令', '出生的月份,是判断强弱最关键的一个位置。'],
|
|
12844
|
+
['日支', '日柱的地支,也叫「配偶宫」,看亲密关系的第一落点。'],
|
|
12845
|
+
['大运', '十年一换的大阶段,决定这十年顺不顺手。'],
|
|
12846
|
+
['流年', '每一年的干支,看当年的具体环境。'],
|
|
12847
|
+
['空亡', '落到空亡的字,力量打折,事情容易「看着有、抓不住」。'],
|
|
12848
|
+
['伏神', '卦里没出现的六亲,藏在同宫首卦的对应爻下,用时才看得见。'],
|
|
12849
|
+
['世应', '世爻代表你,应爻代表对方或外部环境。'],
|
|
12850
|
+
['动爻', '会变的爻,是事情「往哪走」的推动点。'],
|
|
12851
|
+
['纳甲', '给六个爻配上天干地支,六亲与生克才有依据。'],
|
|
12852
|
+
['四化', '禄权科忌四种变化,标记星曜在这一步运里扮演什么角色。'],
|
|
12853
|
+
['大限', '紫微里的十年阶段,作用类似八字的「大运」。'],
|
|
12854
|
+
['庙旺', '星曜落在某宫时的力量档位:庙、旺最强,得、利、平居中,不、陷最弱。'],
|
|
12855
|
+
['三方四正', '从命宫出发的三合三方加对宫,共四个宫位,是全盘最核心的势力范围。'],
|
|
12856
|
+
['命主', '紫微里另有一颗命主星,补命宫看不到的那一层底色。'],
|
|
12857
|
+
['身主', '紫微里另有一颗身主星,管后天的行动与身体那一面。'],
|
|
12858
|
+
['五行局', '用纳音给整张盘定一个局(水二局、木三局等),大限的起法以此为准。'],
|
|
12859
|
+
['自化', '宫干让本宫星曜自己生出四化,代表这一宫的事容易自己发酵。'],
|
|
12860
|
+
['飞星', '拿一个宫的宫干去四化别的宫,看事情从哪来、往哪走。'],
|
|
12861
|
+
['正曜', '十四主星。「无正曜」指命宫没有主星,要借对宫来看。'],
|
|
12862
|
+
['借对宫', '命宫无主星时借对宫主星来读,性格更依赖环境与身边的人。'],
|
|
12863
|
+
['双星', '两主星同宫,按组合读,不能只看其中一颗。'],
|
|
12864
|
+
['墓库', '地支里的仓库。五行入墓代表这股力量收着,不是没有。'],
|
|
12865
|
+
['伏吟', '干支重复出现,事情容易原地打转、反复。'],
|
|
12866
|
+
['反吟', '天克地冲,变动与对撞的意味更明显。'],
|
|
12867
|
+
];
|
|
12868
|
+
|
|
12869
|
+
/** 同一个术语在不同体系里含义不同,必须分体系解释,否则会给出错误定义 */
|
|
12870
|
+
const GLOSSARY_BY_SYSTEM = {
|
|
12871
|
+
liuyao: {
|
|
12872
|
+
用神: '你问的这件事对应的那一类六亲,断卦先把它找出来。',
|
|
12873
|
+
月令: '起卦时的月份,用来看各爻旺不旺。',
|
|
12874
|
+
日支: '起卦当天的地支,与月建一起决定爻的力量。',
|
|
12875
|
+
大运: '六爻不看大运,这里只取当前这一件事的象。',
|
|
12876
|
+
流年: '六爻一般不看流年,看的是眼下这一卦的时段。',
|
|
12877
|
+
},
|
|
12878
|
+
ziwei: {
|
|
12879
|
+
用神: '紫微斗数以「用神宫」的强弱看事情,不取五行喜忌那套。',
|
|
12880
|
+
日主: '紫微斗数不看日主,看的是命宫与星曜组合。',
|
|
12881
|
+
十神: '紫微斗数用四化与星情,不用十神。',
|
|
12882
|
+
},
|
|
12883
|
+
};
|
|
12884
|
+
|
|
12885
|
+
/** 术语白话:只列正文里真出现过的词;同名词按体系取对应释义 */
|
|
12886
|
+
function buildGlossary(texts, system) {
|
|
12887
|
+
const body = (Array.isArray(texts) ? texts : [texts]).filter(Boolean).join('');
|
|
12888
|
+
if (!body) return [];
|
|
12889
|
+
const override = GLOSSARY_BY_SYSTEM[system] || {};
|
|
12890
|
+
return GLOSSARY
|
|
12891
|
+
.filter(([term]) => body.includes(term))
|
|
12892
|
+
.map(([term, plain]) => ({ term, plain: override[term] || plain }))
|
|
12893
|
+
.slice(0, 10);
|
|
12894
|
+
}
|
|
12895
|
+
|
|
12896
|
+
const FOLLOWUPS = {
|
|
12897
|
+
career: ['这份工作要不要动,明年哪几个月是窗口?', '和上级的关系该硬碰还是绕开?', '现在转方向,代价主要在哪儿?'],
|
|
12898
|
+
wealth: ['这笔钱现在投出去合适吗?', '我的财主要来自工资还是副业?', '今年哪段时间最容易破财?'],
|
|
12899
|
+
love: ['这段关系能走到哪一步?', '什么时候适合把关系定下来?', '我在关系里最容易忽略什么?'],
|
|
12900
|
+
health: ['哪段时间身体最需要留意?', '作息怎么调最划算?', '查体和作息之外,还有什么是能自己控制的?'],
|
|
12901
|
+
study: ['今年再考一次,胜算在哪、短板在哪?', '复习节奏该怎么排?', '要不要换目标院校或岗位?'],
|
|
12902
|
+
travel: ['这次出门顺不顺,哪天走更好?', '换个城市生活,合不合适?'],
|
|
12903
|
+
general: ['今年最该抓的一件事是什么?', '最该避开的坑在哪?', '接下来三个月,什么时间点值得留意?'],
|
|
12904
|
+
};
|
|
12905
|
+
|
|
12906
|
+
/** 追问建议:把「还能问什么」具体化,降低二次提问的门槛 */
|
|
12907
|
+
function buildFollowups(r, ask) {
|
|
12908
|
+
const dir = (ask && ask.direction) || 'general';
|
|
12909
|
+
const list = FOLLOWUPS[dir] || FOLLOWUPS.general;
|
|
12910
|
+
return list.slice(0, 3);
|
|
12911
|
+
}
|
|
11601
12912
|
|
|
11602
12913
|
return { buildAnswer, buildPlain, dimensionPlain, buildGlossary, buildFollowups };
|
|
11603
12914
|
})();
|
|
@@ -11707,8 +13018,8 @@ const KNOWLEDGE = [
|
|
|
11707
13018
|
id: 'bazi-sanming-duizhao',
|
|
11708
13019
|
system: 'bazi', dims: ['overall', 'career'],
|
|
11709
13020
|
gist: '同一个格,子平真诠讲怎么用,三命通会讲怎么取。',
|
|
11710
|
-
detail: '
|
|
11711
|
-
source: '
|
|
13021
|
+
detail: '两书不是谁替代谁:子平真诠以月令取用神、论顺逆成败,重「用」;三命通会按十神逐格立论,重「取」与「忌」。同看正官格,前者问财印护官、伤煞混杂,后者先说「止许一位,多则不宜」。此本正财、偏财分章,两格各取本格一条;七杀没有单列「论偏官」,取卷五「官煞去留杂论」讲混杂时的去留。本插件把两条并列,不合并成一句断语。',
|
|
13022
|
+
source: '《子平真诠》论正官等篇;《三命通会》卷五、卷六论十神与官煞去留',
|
|
11712
13023
|
status: 'variant',
|
|
11713
13024
|
note: '两书成书年代与流派不同,用语有出入;本插件照录通行本,不做校勘改字,也不替两家调和。',
|
|
11714
13025
|
},
|
|
@@ -11730,6 +13041,33 @@ const KNOWLEDGE = [
|
|
|
11730
13041
|
status: 'variant',
|
|
11731
13042
|
note: '化气格成立条件各家宽严不一(是否要求月令为化神、日主是否允许有根),本插件只列条件、附原文,不据此断定化气已成。',
|
|
11732
13043
|
},
|
|
13044
|
+
{
|
|
13045
|
+
id: 'bazi-zhuanwang-yuanwen',
|
|
13046
|
+
system: 'bazi', dims: ['overall', 'career'],
|
|
13047
|
+
gist: '专旺五格各有专章:成格要看局全带印,不只看身强。',
|
|
13048
|
+
detail: '三命通会卷六曲直、炎上、从革、润下、稼穑五篇各立一格:曲直须亥卯未带亥,炎上须寅午戌带寅,从革须巳酉丑带丙丁巳午,润下须申子辰全,稼穑取四季土。原文的条件都比「身强」细:要局全、要带印或带火炼金,还要防冲刑死绝。本插件把命中的那一篇附在结果里,只作结构说明。',
|
|
13049
|
+
source: '《三命通会》卷六·曲直、炎上、从革、润下、稼穑',
|
|
13050
|
+
status: 'variant',
|
|
13051
|
+
note: '专旺是否必须成方局、是否允许一点官杀财,各家宽严不一;原文五篇之间条件也不齐(润下重忌冲刑、稼穑重四季土)。本插件只按「同类+印 ≥5、官杀财皆弱」列出并附原文,不据此断贵贱,也不补专旺的破格条件。',
|
|
13052
|
+
},
|
|
13053
|
+
{
|
|
13054
|
+
id: 'bazi-congge-yuanwen',
|
|
13055
|
+
system: 'bazi', dims: ['overall', 'career'],
|
|
13056
|
+
gist: '从格是身无归处才「弃命」相从:一见根气就破格。',
|
|
13057
|
+
detail: '三命通会卷五弃命从煞、卷六弃命从财各有一篇:从煞要煞重身柔、四柱无一点比肩印绶;从财要财会成局、日干无气,原文说「若逢根气,命损无猜」。两篇都说行运喜财煞旺地、忌扶身。本插件只在盘面出现从财格或从杀格时附上对应原文;从儿、从强没有单章,不硬凑。',
|
|
13058
|
+
source: '《三命通会》卷五·弃命从煞;卷六·弃命从财',
|
|
13059
|
+
status: 'variant',
|
|
13060
|
+
note: '从格成立条件各家分歧很大:是否允许日主有微根、阴阳干从与不从(原文说阳木不能从)、从儿与从强算不算正从,说法不一。本插件只列结构与原文,不据此断吉凶,也不补从儿、从强的原文。',
|
|
13061
|
+
},
|
|
13062
|
+
{
|
|
13063
|
+
id: 'bazi-tongguan',
|
|
13064
|
+
system: 'bazi', dims: ['overall', 'career'],
|
|
13065
|
+
gist: '两神相战要有中间一行接上,对峙才化成相生。',
|
|
13066
|
+
detail: '用神与忌神两行在局中各 ≥1.5 分、又正好相克时,五行里只有一行能接上:克方生它、它再生被克方(金克木则以水为关,土克水则以金为关)。滴天髓用织女、牛郎隔关相望作比,说「此关若通也,相邀入洞房」。本插件只按局中分量点出这一行,并写明它是不是忌神。',
|
|
13067
|
+
source: '《滴天髓》通神论·通关;五行生克为通行说',
|
|
13068
|
+
status: 'variant',
|
|
13069
|
+
note: '各家对「两神相战」取哪两神不一(有取日主与官杀、有取用神与忌神、有取局中最旺两行),本插件固定取「用神与克它的忌神,且两行各 ≥1.5 分」;通关一行只按五行生克唯一确定,不据此断吉凶,也不判通关之力是否够用。',
|
|
13070
|
+
},
|
|
11733
13071
|
|
|
11734
13072
|
// ── 紫微 ──────────────────────────────────────────────
|
|
11735
13073
|
{
|
|
@@ -11841,10 +13179,10 @@ const KNOWLEDGE = [
|
|
|
11841
13179
|
id: 'liuyao-fushen',
|
|
11842
13180
|
system: 'liuyao', dims: ['overall'],
|
|
11843
13181
|
gist: '用神不上卦,就去本宫首卦的同位取伏神。',
|
|
11844
|
-
detail: '
|
|
13182
|
+
detail: '本卦六爻里没有用神那一类六亲,就叫用神不上卦。取法是回到本卦所属宫的首卦(八纯卦),找出该六亲所在的爻位,那一爻即伏神,本卦同一爻位上的爻叫飞神。伏神要「得出」才有用:飞神生伏神、伏神克飞神、日月生扶都算得力;飞神克伏神则受压难出。本插件给出伏神爻位、干支五行、飞伏生克,并按月建日辰归成四档出伏条件(可出 / 有助有压 / 受压难出 / 未得助);只判条件,不出应期日期。',
|
|
11845
13183
|
source: '《卜筮正宗》伏神章;《增删卜易》伏神篇',
|
|
11846
13184
|
status: 'variant',
|
|
11847
|
-
note: '
|
|
13185
|
+
note: '首卦里同一六亲也可能出现两次(如乾宫乾为天的父母在三爻与上爻),此时取哪一爻为伏神各家不一;本插件把候选都列出并标「伏神两现」,不代选。出伏条件的归并口径:飞生伏、伏克飞、日辰生/比和、月建旺/相算助,飞克伏、日辰克、月破算压;有助无压为「可出」,有助有压为「有助有压」,有压无助为「受压难出」,两者都无为「未得助」。四档只并列条件、不排各家优先级;旬空只标出,不并入档位。应期各家分歧更大,仍不输出日期。',
|
|
11848
13186
|
},
|
|
11849
13187
|
{
|
|
11850
13188
|
id: 'liuyao-yongshen-shuai',
|
|
@@ -12055,6 +13393,435 @@ const STATUS_LABEL = {
|
|
|
12055
13393
|
return { KNOWLEDGE, knowledgeFor, caveatsFor, STATUS_LABEL };
|
|
12056
13394
|
})();
|
|
12057
13395
|
|
|
13396
|
+
__mods['ziwei-words'] = (function () {
|
|
13397
|
+
// 紫微解读词库:宫位取象 / 主星细节 / 双星组合 / 煞星辅星 / 四化落宫 / 庙旺措辞 / 格局读法
|
|
13398
|
+
//
|
|
13399
|
+
// 分工:ziwei.js 只负责「算出什么星落在哪一宫」,这里只负责「这件事怎么说」。
|
|
13400
|
+
// 词库不含任何判断条件,换个排盘引擎结论也不会跟着变——凡是需要看星位才能定的,都留在引擎里。
|
|
13401
|
+
//
|
|
13402
|
+
// 取词的三条口径:
|
|
13403
|
+
// · 只说倾向与做法,不下断语(「容易」「多半」「宜」而不是「一定」「必然」)
|
|
13404
|
+
// · 吉星不吹、煞星不吓:煞星写「这一宫会怎样」,再补一句可以怎么做
|
|
13405
|
+
// · 星曜亮度只调语气,不改结论:庙旺是「长处放得开」,落陷是「长处不容易使上」,都不是好坏判决
|
|
13406
|
+
|
|
13407
|
+
// ── 十二宫:这一宫管什么、回答什么问题、被引动时表现成什么 ──────────
|
|
13408
|
+
const PALACE_FIELD = {
|
|
13409
|
+
命宫: { field: '你自己、性格与选择的出发点', ask: '我是个什么样的人、遇事怎么反应', drift: '整个人的状态与主见', huaJi: '容易对自己不满意,反复琢磨「是不是还不够好」' },
|
|
13410
|
+
兄弟: { field: '手足、同辈与合作', ask: '和同辈人怎么相处', drift: '同辈之间的支持与较劲', huaJi: '同辈之间容易有拉扯,合作前先把账算清楚' },
|
|
13411
|
+
夫妻: { field: '亲密关系与伴侣', ask: '感情里怎么相处', drift: '关系的温度与相处方式', huaJi: '感情里容易反复计较,越在意越觉得累' },
|
|
13412
|
+
子女: { field: '子女、晚辈与作品', ask: '和晚辈、和自己的创作怎么相处', drift: '照顾与创造', huaJi: '对子女或作品容易操心过头,投入多而见效慢' },
|
|
13413
|
+
财帛: { field: '赚钱方式与现金流', ask: '钱从哪来、留不留得住', drift: '进项与花销', huaJi: '钱上容易反复,进得来也容易散,先管现金再谈收益' },
|
|
13414
|
+
疾厄: { field: '身体底子与情绪出口', ask: '身体哪里要多留意', drift: '作息与身体的信号', huaJi: '情绪容易往身体上走,压力最先反映在睡眠与肠胃' },
|
|
13415
|
+
迁移: { field: '出门、环境与人缘', ask: '在外发展顺不顺', drift: '外部环境与人际机会', huaJi: '在外容易遇到消耗,换环境前先把代价想清楚' },
|
|
13416
|
+
交友: { field: '朋友、同事与部属', ask: '怎么识人、怎么带人', drift: '身边的人际圈', huaJi: '容易替别人操心、被人情拖住,帮人之前先给自己留余地' },
|
|
13417
|
+
官禄: { field: '事业方向与做事方式', ask: '做什么工作、怎么做事', drift: '工作与身份感', huaJi: '工作上容易反复调整方向,先把一件事做完再谈换' },
|
|
13418
|
+
田宅: { field: '家庭、住所与积累', ask: '安家、置产与家底', drift: '居住环境与家庭气氛', huaJi: '家里的事容易牵扯精力,置产与搬迁宜缓不宜急' },
|
|
13419
|
+
福德: { field: '精神享受与内在节奏', ask: '怎么让自己舒服、怎么放松', drift: '心境、兴趣与休息', huaJi: '想得多、放不下,休息也休息不踏实' },
|
|
13420
|
+
父母: { field: '长辈、上司与文书', ask: '和长辈上级的关系、文书合约', drift: '长辈缘与合同文书', huaJi: '与长辈上级容易有隔阂,文书合约要逐条看清' },
|
|
13421
|
+
};
|
|
13422
|
+
|
|
13423
|
+
// ── 十四主星:别称、关键词、得地/失地两种语气、长处与要留意的点 ──────
|
|
13424
|
+
// bright 用在庙旺得利,dim 用在平不陷;gift 是「可以拿去用」,watch 是「用过头会出事」。
|
|
13425
|
+
const STAR_EXTRA = {
|
|
13426
|
+
紫微: { alias: '帝星', key: '尊', bright: '心里像有根定海针,遇事敢拍板,也压得住场面', dim: '容易端着架子,想法很多却不肯先低头', gift: '定方向、分主次、把人组织起来', watch: '面子与身段' },
|
|
13427
|
+
天机: { alias: '智星', key: '动', bright: '脑子快、点子多,变化里反而找得到路', dim: '想法多过行动,容易在犹豫里把时间耗掉', gift: '策划、推演、把复杂的事拆成步骤', watch: '想太多、坐不住' },
|
|
13428
|
+
太阳: { alias: '日主', key: '公', bright: '外放热心,愿意担事,也容易被看见', dim: '付出多、回报少,容易觉得不被认可', gift: '对外沟通、带头做事、把光照到别人身上', watch: '用力过度、忘了照顾自己' },
|
|
13429
|
+
武曲: { alias: '财星', key: '实', bright: '务实果决,认结果、扛得住硬活', dim: '容易只认数字,人情上显得生硬', gift: '算账、执行、把事做扎实', watch: '太硬、不给缓冲' },
|
|
13430
|
+
天同: { alias: '福星', key: '柔', bright: '脾气温和,能把紧张的气氛化开', dim: '容易贪舒服、事情拖着不动', gift: '协调、服务、让人放松下来', watch: '安逸与拖延' },
|
|
13431
|
+
廉贞: { alias: '囚星', key: '细', bright: '细腻又讲原则,做事有分寸', dim: '容易较真到钻牛角尖,情绪起伏也大', gift: '抓细节、守规矩、做需要精度的活', watch: '情绪郁结、过度执着' },
|
|
13432
|
+
天府: { alias: '库星', key: '稳', bright: '稳得住、会存会调度,是团队的压舱石', dim: '偏保守,机会来了也不敢动', gift: '守成、管资源、把局面稳住', watch: '求稳到错过时机' },
|
|
13433
|
+
太阴: { alias: '月主', key: '藏', bright: '心思细、耐得住,静下来能做深事', dim: '敏感多虑,情绪都藏在心里', gift: '研究、文案、需要长期专注的活', watch: '内耗与睡眠' },
|
|
13434
|
+
贪狼: { alias: '桃花', key: '贪', bright: '好奇、活络、人缘好,学什么都快', dim: '什么都想要,结果哪样都没做透', gift: '开拓、交际、把资源变成机会', watch: '边界与节制' },
|
|
13435
|
+
巨门: { alias: '暗星', key: '辩', bright: '口才与逻辑都好,靠说理就能服人', dim: '容易多疑,一句话能听出三层意思', gift: '谈判、教学、法务、需要辨析的活', watch: '言语是非与疑心' },
|
|
13436
|
+
天相: { alias: '印星', key: '辅', bright: '讲规矩、会协调,是让人放心的副手', dim: '容易迁就别人,委屈自己也不说', gift: '协调、执行、把流程跑顺', watch: '太在意别人怎么看' },
|
|
13437
|
+
天梁: { alias: '荫星', key: '荫', bright: '有长者气,能扛事、也愿意护着人', dim: '操心过度,替别人背了不该背的', gift: '顾问、教育、医护、替人排忧', watch: '管太多、放不下' },
|
|
13438
|
+
七杀: { alias: '将星', key: '决', bright: '果断敢冲,压力越大越顶得住', dim: '容易硬碰硬,把关系撞出裂痕', gift: '开拓、攻坚、从零打出一块地', watch: '急与硬' },
|
|
13439
|
+
破军: { alias: '耗星', key: '破', bright: '敢破敢立,旧局推得动、新局立得起', dim: '推翻了却重建不了,反复折腾', gift: '变革、重组、做从零到一的事', watch: '冲动与耗损' },
|
|
13440
|
+
};
|
|
13441
|
+
|
|
13442
|
+
// ── 双星同宫:两颗主星挤在一宫时怎么读 ────────────────────────────
|
|
13443
|
+
// 一句话说清「两股力叠在一起是什么味道」,watch 说明它最容易走偏的方向。
|
|
13444
|
+
const STAR_PAIR = {
|
|
13445
|
+
紫微天府: { gist: '尊贵加稳重:既想有位置,也守得住家底,适合在体系里往上走', watch: '别把稳做成不动' },
|
|
13446
|
+
紫微贪狼: { gist: '帝星带桃花:有格局也有玩心,门路多、欲望也多', watch: '兴趣铺太开,主次容易乱' },
|
|
13447
|
+
紫微天相: { gist: '帝星配印:权力与规矩并存,做事讲体面,也讲章法', watch: '太要好看,容易被形式拖住' },
|
|
13448
|
+
紫微七杀: { gist: '帝星加将星:气魄大、手腕硬,开得了局面', watch: '压得住人也容易压伤人' },
|
|
13449
|
+
紫微破军: { gist: '帝星带耗:敢于推倒重来,一生常有大的转身', watch: '代价是先破后立,破之前先备好退路' },
|
|
13450
|
+
天机太阴: { gist: '机月同宫:心思细、筹划深,适合幕后与会动脑子的活', watch: '算得太细,反而迟迟不动手' },
|
|
13451
|
+
天机巨门: { gist: '机巨同宫:头脑快、嘴也利,论辩是强项', watch: '话多容易生是非' },
|
|
13452
|
+
天机天梁: { gist: '机梁同宫:善谋又讲原则,常是出主意又担责任的人', watch: '替人想太多,累的是自己' },
|
|
13453
|
+
太阳太阴: { gist: '日月同宫:外放与内敛同时在身上,两种节奏互相拉扯', watch: '别自己跟自己打架' },
|
|
13454
|
+
太阳巨门: { gist: '日巨同宫:靠一张嘴把事说成,适合以表达与说服为业', watch: '说话直,容易得罪人' },
|
|
13455
|
+
太阳天梁: { gist: '阳梁同宫:热心又有长者气,助人型,容易被人依赖', watch: '别把别人的事全揽过来' },
|
|
13456
|
+
武曲天府: { gist: '武府同宫:会算也会守,财务与执行双强,稳中有实', watch: '只算眼前账,容易错过长线' },
|
|
13457
|
+
武曲贪狼: { gist: '武贪同宫:务实与欲望并存,传统说三十岁以后越走越开', watch: '先把本事磨厚,别急着要结果' },
|
|
13458
|
+
武曲天相: { gist: '武相同宫:讲效率也讲规矩,适合在大机构里做执行', watch: '规矩压得太死,手脚会绑住' },
|
|
13459
|
+
武曲七杀: { gist: '武杀同宫:硬碰硬的组合,冲劲足、压力也大', watch: '成事快,耗得也快' },
|
|
13460
|
+
武曲破军: { gist: '武破同宫:能打也能拆,适合攻坚与改革', watch: '聚散都快,留不住的要认' },
|
|
13461
|
+
天同太阴: { gist: '同阴同宫:温和细腻,重感受,适合安静一点的环境', watch: '太舒服就不想动' },
|
|
13462
|
+
天同巨门: { gist: '同巨同宫:想得软、说得直,容易在亲近的人面前失控', watch: '把话说软一点' },
|
|
13463
|
+
天同天梁: { gist: '同梁同宫:有福气也有长者缘,遇事常有人替你说句话', watch: '依赖久了会长不大' },
|
|
13464
|
+
廉贞天府: { gist: '廉府同宫:精细配稳重,守得住规矩也管得住资源', watch: '过分谨慎会错过窗口' },
|
|
13465
|
+
廉贞贪狼: { gist: '廉贪同宫:欲望与原则拉扯,才艺多、诱惑也多', watch: '重心要自己定,别被带着走' },
|
|
13466
|
+
廉贞天相: { gist: '廉相同宫:讲分寸、重体面,做事有章法', watch: '被规矩绑住手脚' },
|
|
13467
|
+
廉贞七杀: { gist: '廉杀同宫:刚烈果决,抗压强,敢碰难事', watch: '硬碰硬伤的是关系' },
|
|
13468
|
+
廉贞破军: { gist: '廉破同宫:敢于破局,变动多,适合在动荡里做事', watch: '变动要有节奏,别一直重来' },
|
|
13469
|
+
};
|
|
13470
|
+
|
|
13471
|
+
// ── 煞星:这一宫会怎样、可以怎么应对 ──────────────────────────────
|
|
13472
|
+
const SHA_STAR = {
|
|
13473
|
+
擎羊: { nature: '锐、直接、带冲撞', inPalace: '让这一宫的事来得急,容易有竞争与对抗', remind: '慢半拍再回应,别用人身去硬碰' },
|
|
13474
|
+
陀罗: { nature: '拖、磨、反复', inPalace: '让这一宫的事拖得久,越急越推不动', remind: '把大目标切成小段,靠节奏推进而不是靠爆发' },
|
|
13475
|
+
火星: { nature: '急、爆、来得快去得快', inPalace: '让这一宫的事突然发生,情绪也容易点着', remind: '起的当下先别做决定,隔一天再看' },
|
|
13476
|
+
铃星: { nature: '闷、记、往里烧', inPalace: '让这一宫的事闷着发酵,不说并不代表没有', remind: '把不满讲出来,比憋着省事' },
|
|
13477
|
+
地空: { nature: '抽离、落空', inPalace: '让这一宫的努力容易「看着有、抓不住」', remind: '重要的事留书面凭证,别只靠口头约定' },
|
|
13478
|
+
地劫: { nature: '耗、变动', inPalace: '让这一宫的资源容易在变动里流失', remind: '先设止损线,再谈投入' },
|
|
13479
|
+
天刑: { nature: '约束、规矩', inPalace: '这一宫容易受规则或外力约束', remind: '照流程走,别找捷径' },
|
|
13480
|
+
天姚: { nature: '吸引、暧昧', inPalace: '这一宫容易有人情与暧昧的牵扯', remind: '边界说清楚,别用含糊换方便' },
|
|
13481
|
+
咸池: { nature: '情欲、外缘', inPalace: '这一宫容易被外在的吸引牵动', remind: '分清一时心动与长期相处' },
|
|
13482
|
+
孤辰: { nature: '孤、独', inPalace: '这一宫的事常要自己扛', remind: '主动开口求援,不丢人' },
|
|
13483
|
+
寡宿: { nature: '淡、疏', inPalace: '这一宫的关系容易偏淡', remind: '关系要靠主动经营' },
|
|
13484
|
+
破碎: { nature: '碎、不整', inPalace: '这一宫的成果容易零散、难成整块', remind: '把事收尾收完整' },
|
|
13485
|
+
天哭: { nature: '忧、敏感', inPalace: '这一宫容易让人心里发紧', remind: '情绪来了先照顾好身体' },
|
|
13486
|
+
天虚: { nature: '虚、不实', inPalace: '这一宫容易雷声大雨点小', remind: '看落地证据,不看承诺' },
|
|
13487
|
+
};
|
|
13488
|
+
|
|
13489
|
+
// 六煞:只有这六颗在维度文案里单独点名;其余煞星(天刑天姚咸池孤辰寡宿破碎天哭天虚)
|
|
13490
|
+
// 影响更细,放在逐宫分析里出现,不往五维度上叠,免得把小事说成大事。
|
|
13491
|
+
const MAIN_SHA = ['擎羊', '陀罗', '火星', '铃星', '地空', '地劫'];
|
|
13492
|
+
|
|
13493
|
+
// ── 吉星与辅星:这一宫的白送项 ──────────────────────────────────
|
|
13494
|
+
const FU_STAR = {
|
|
13495
|
+
左辅: { nature: '助力、帮手', gift: '这一宫容易有人搭把手', note: '多把事交出去,别一个人扛' },
|
|
13496
|
+
右弼: { nature: '援手、缓和', gift: '这一宫容易在关键处被接住', note: '接受帮助,也记得回礼' },
|
|
13497
|
+
文昌: { nature: '文书、条理', gift: '这一宫的书面与规划能力强', note: '把想法落成文档' },
|
|
13498
|
+
文曲: { nature: '才艺、口才', gift: '这一宫的表达与感受力好', note: '用表达换机会' },
|
|
13499
|
+
天魁: { nature: '明文贵人', gift: '这一宫容易遇到明面上的提携', note: '该争取的位置直接开口' },
|
|
13500
|
+
天钺: { nature: '暗助贵人', gift: '这一宫常有人在背后帮忙', note: '人情记着,早晚用得上' },
|
|
13501
|
+
禄存: { nature: '守财、积存', gift: '这一宫的东西守得住', note: '先存后花' },
|
|
13502
|
+
天马: { nature: '动、驿马', gift: '这一宫的事常与移动、外地有关', note: '动起来比原地等更有利' },
|
|
13503
|
+
台辅: { nature: '台面、名分', gift: '这一宫容易被摆到台面上', note: '露脸的机会别推' },
|
|
13504
|
+
封诰: { nature: '封赏、认证', gift: '这一宫的资质与头衔有用', note: '该考的证早点考' },
|
|
13505
|
+
红鸾: { nature: '喜事', gift: '这一宫容易有喜庆与好消息', note: '好消息要说出来' },
|
|
13506
|
+
天喜: { nature: '喜庆、人缘', gift: '这一宫的人缘与气氛好', note: '多参加场合' },
|
|
13507
|
+
龙池: { nature: '雅、工整', gift: '这一宫有审美与工整的一面', note: '把细节做好' },
|
|
13508
|
+
凤阁: { nature: '华、体面', gift: '这一宫讲究排场与观感', note: '该有的体面别省' },
|
|
13509
|
+
三台: { nature: '地位、层级', gift: '这一宫容易有位置感', note: '按层级办事' },
|
|
13510
|
+
八座: { nature: '席位、稳定', gift: '这一宫坐得稳', note: '守住已有的位置' },
|
|
13511
|
+
恩光: { nature: '恩、被赏识', gift: '这一宫容易被赏识', note: '把成果让人看见' },
|
|
13512
|
+
天贵: { nature: '贵气、身份', gift: '这一宫带一点贵气', note: '抬头挺胸,别自轻' },
|
|
13513
|
+
};
|
|
13514
|
+
|
|
13515
|
+
// ── 四化:一支化代表什么态度,落到具体宫位又是哪件事 ─────────────────
|
|
13516
|
+
const HUA_READ = {
|
|
13517
|
+
禄: { key: '得', gist: '顺手、有人帮,做起来不费劲' },
|
|
13518
|
+
权: { key: '掌', gist: '要自己拿主意,也容易用力过猛' },
|
|
13519
|
+
科: { key: '名', gist: '带一层体面与名声,遇事多能收得漂亮' },
|
|
13520
|
+
忌: { key: '执', gist: '容易在意、反复,是心里放不下的那一块' },
|
|
13521
|
+
};
|
|
13522
|
+
|
|
13523
|
+
// ── 庙旺得利平不陷:同一条结论的七种语气 ──────────────────────────
|
|
13524
|
+
const BRIGHT_READ = {
|
|
13525
|
+
庙: { word: '得地', tone: 'good', plain: '长处放得开,几乎是本色出演' },
|
|
13526
|
+
旺: { word: '有力', tone: 'good', plain: '特点容易显出来,做事有底气' },
|
|
13527
|
+
得: { word: '尚可', tone: 'neutral', plain: '能用,需要一点外力配合' },
|
|
13528
|
+
利: { word: '中平', tone: 'neutral', plain: '长处与短板都在,看怎么用' },
|
|
13529
|
+
平: { word: '偏弱', tone: 'neutral', plain: '不太争得到位置,宜借势' },
|
|
13530
|
+
不: { word: '不得地', tone: 'bad', plain: '长处不容易使上,得多绕一步' },
|
|
13531
|
+
陷: { word: '失地', tone: 'bad', plain: '容易往负面走,更需要自觉' },
|
|
13532
|
+
};
|
|
13533
|
+
|
|
13534
|
+
// ── 三十四条格局:一句人话 + 一条做法 ─────────────────────────────
|
|
13535
|
+
const PATTERN_READ = {
|
|
13536
|
+
紫府同宫: { gist: '帝星与库星同坐命宫:格局稳、底气足,天生适合做统筹', advice: '别把稳做成保守,该出手时出手' },
|
|
13537
|
+
紫府朝垣: { gist: '紫微天府会照命宫:有贵气也有实力,环境一般不会太差', advice: '靠结构做事,别只靠个人硬撑' },
|
|
13538
|
+
君臣庆会: { gist: '紫微或天府坐命,又得左辅右弼魁钺会照:有人帮、有位置', advice: '把团队搭起来,别一个人扛' },
|
|
13539
|
+
极向离明: { gist: '紫微在午守命:处在最亮的位置,格局与声势都强', advice: '光环大,注意别把人压住' },
|
|
13540
|
+
七杀朝斗: { gist: '七杀在子午守命:杀伐果断,能在压力下成事', advice: '硬气用在事上,不用在关系上' },
|
|
13541
|
+
英星入庙: { gist: '破军在子午守命:敢破敢立,常能从零打出一片', advice: '破之后要有立,别只破不立' },
|
|
13542
|
+
石中隐玉: { gist: '巨门在子午守命:本事藏在里面,要靠机会慢慢磨出来', advice: '别因为一时不被看见就放弃' },
|
|
13543
|
+
巨日同宫: { gist: '巨门太阳同宫:靠表达与说服开路,越抛头露面越有利', advice: '话多的时候注意分寸' },
|
|
13544
|
+
日月夹命: { gist: '太阳太阴分居命宫两侧:内外两种力量都来帮你', advice: '一快一慢,别自己跟自己打架' },
|
|
13545
|
+
日月对照: { gist: '太阳太阴分守命迁:外放与内敛互为表里', advice: '换环境对你是加分项' },
|
|
13546
|
+
左右夹命: { gist: '左辅右弼夹命:关键处总有人搭手', advice: '主动求助,贵人才好使力' },
|
|
13547
|
+
昌曲夹命: { gist: '文昌文曲夹命:文书、考试、表达上占便宜', advice: '把才华落到作品与证书上' },
|
|
13548
|
+
魁钺夹命: { gist: '天魁天钺夹命:明暗两路都有人提携', advice: '机会来了别客气' },
|
|
13549
|
+
三奇嘉会: { gist: '化禄化权化科会于命宫三方:三样都到位,是标准的顺局', advice: '别把顺境当常态,留一手' },
|
|
13550
|
+
双禄朝垣: { gist: '禄存与化禄同会命宫三方:进项与积累两头都有', advice: '存下来的才算数' },
|
|
13551
|
+
府相朝垣: { gist: '天府天相会于命宫三方:稳当、讲规矩,适合体系内发展', advice: '按流程走,别嫌慢' },
|
|
13552
|
+
禄马交驰: { gist: '禄存与天马同宫或对照:动中得财,越跑越有', advice: '别在原地等机会' },
|
|
13553
|
+
月朗天门: { gist: '太阴在亥守命:心思澄明,适合做需要静气的事', advice: '把敏感用在专业上,别用在揣测上' },
|
|
13554
|
+
日出扶桑: { gist: '太阳在卯守命:正当升起的位置,势头好、人也敞亮', advice: '趁势做事,别等' },
|
|
13555
|
+
机月同梁: { gist: '天机太阴天梁会命:动脑、静气、长者缘齐备,适合稳定的专业路线', advice: '少折腾,深耕一门' },
|
|
13556
|
+
武贪同行: { gist: '武曲贪狼同宫:务实与欲望并存,传统说三十岁后越走越开', advice: '先把本事磨厚,别急着要结果' },
|
|
13557
|
+
命无正曜: { gist: '命宫无主星:性格由环境与对宫塑造,适应力是你的长处', advice: '选对环境比选对方法更要紧' },
|
|
13558
|
+
杀破狼: { gist: '七杀破军贪狼会命:一生变动多、节奏快,适合在动荡里做事', advice: '把变动变成主动选择,而不是被动应付' },
|
|
13559
|
+
双禄交流: { gist: '禄存与化禄相对:财路两头通', advice: '现金流要管好,小心两头都花' },
|
|
13560
|
+
火贪铃贪: { gist: '贪狼遇火星或铃星:爆发型的组合,机会来得猛', advice: '机会来时别犹豫,走时别恋战' },
|
|
13561
|
+
火铃夹命: { gist: '火星铃星分居命宫两侧:情绪容易被点着,也容易被消耗', advice: '先把火气压一压,事就顺一半' },
|
|
13562
|
+
羊陀夹命: { gist: '禄存守命、擎羊陀罗前后夹之:位置稳,但四周都是压力', advice: '守得住就别急着动' },
|
|
13563
|
+
羊陀夹忌: { gist: '化忌与禄存同宫、羊陀夹之:传统里最需要留意的一类结构', advice: '那件事慢一点,让别人先动' },
|
|
13564
|
+
铃昌陀武: { gist: '铃星文昌陀罗武曲会于命宫三方:想法多、爱走弯路,容易自己把自己绊住', advice: '做决定前先写下来,隔一夜再定' },
|
|
13565
|
+
命里逢空: { gist: '地空地劫会命:计划常有意外的抽离,落袋才算数', advice: '留凭证、留退路' },
|
|
13566
|
+
马头带箭: { gist: '擎羊在午守命:锋芒极盛,成事快、伤人也不慢', advice: '冲劲用在攻坚,不用在争输赢' },
|
|
13567
|
+
天罗地网: { gist: '命宫在辰戌:天罗地网,走的是有限制的路', advice: '在框里做出成绩,别硬撞框' },
|
|
13568
|
+
刑囚夹印: { gist: '廉贞天相同守命宫于子午又遇擎羊:规则与冲撞同时压过来', advice: '循规蹈矩是保命符' },
|
|
13569
|
+
泛水桃花: { gist: '贪狼在子守命:才情与情缘都旺,重心容易散', advice: '给自己立一条不越的线' },
|
|
13570
|
+
};
|
|
13571
|
+
|
|
13572
|
+
/** 宫名 → 取象;盘面上偶尔出现别名(如「交友」也写作「奴仆」),一并认 */
|
|
13573
|
+
const PALACE_ALIAS = { 奴仆: '交友', 奴仆宫: '交友', 事业: '官禄', 事业宫: '官禄' };
|
|
13574
|
+
function palaceFieldOf(name) {
|
|
13575
|
+
const key = PALACE_ALIAS[String(name || '')] || String(name || '');
|
|
13576
|
+
return PALACE_FIELD[key] || null;
|
|
13577
|
+
}
|
|
13578
|
+
|
|
13579
|
+
/** 亮度字符 → 措辞;没有亮度(辅星或未标)时返回 null,调用方各自决定怎么略过 */
|
|
13580
|
+
function brightRead(level) {
|
|
13581
|
+
return BRIGHT_READ[String(level || '')] || null;
|
|
13582
|
+
}
|
|
13583
|
+
|
|
13584
|
+
/** 星名 → 细节;不在表里返回 null,绝不临时造词 */
|
|
13585
|
+
function starExtraOf(name) {
|
|
13586
|
+
return STAR_EXTRA[String(name || '')] || null;
|
|
13587
|
+
}
|
|
13588
|
+
|
|
13589
|
+
/** 一宫里两颗主星 → 双星组合读法;单星或三颗以上返回 null */
|
|
13590
|
+
function starPairOf(mainStars) {
|
|
13591
|
+
const list = (Array.isArray(mainStars) ? mainStars : []).filter(Boolean);
|
|
13592
|
+
if (list.length !== 2) return null;
|
|
13593
|
+
return STAR_PAIR[list.join('')] || STAR_PAIR[list.slice().reverse().join('')] || null;
|
|
13594
|
+
}
|
|
13595
|
+
|
|
13596
|
+
/** 四化落到某一宫的一句话;宫名不认识就返回空串,由调用方退回通用说法 */
|
|
13597
|
+
function huaInLine(type, palace) {
|
|
13598
|
+
const f = palaceFieldOf(palace);
|
|
13599
|
+
const h = HUA_READ[type];
|
|
13600
|
+
if (!f || !h) return '';
|
|
13601
|
+
if (type === '忌') return `化忌入${palace}:${f.huaJi}`;
|
|
13602
|
+
const tail = {
|
|
13603
|
+
禄: `${f.field}上来路顺、有人递梯子`,
|
|
13604
|
+
权: `${f.field}上你会想自己拿主意,也容易用力过猛`,
|
|
13605
|
+
科: `${f.field}上体面与名声会帮到你`,
|
|
13606
|
+
}[type];
|
|
13607
|
+
return tail ? `化${type}入${palace}:${tail}` : '';
|
|
13608
|
+
}
|
|
13609
|
+
|
|
13610
|
+
/** 煞星清单 → 一句「这一宫哪里容易卡住」;清单空则返回空串 */
|
|
13611
|
+
function shaLineOf(names) {
|
|
13612
|
+
const list = (Array.isArray(names) ? names : []).filter((n) => SHA_STAR[n]);
|
|
13613
|
+
if (!list.length) return '';
|
|
13614
|
+
const parts = list.slice(0, 3).map((n) => `${n}(${SHA_STAR[n].nature})${SHA_STAR[n].inPalace}`);
|
|
13615
|
+
const remind = list.length === 1 ? SHA_STAR[list[0]].remind : '先处理最急的那一件,其余的会跟着松动';
|
|
13616
|
+
return `${parts.join(';')}。做法上:${remind}。`;
|
|
13617
|
+
}
|
|
13618
|
+
|
|
13619
|
+
/** 煞星清单 → 只取星情(不含落宫说法);健康这类不宜展开的维度用这一条 */
|
|
13620
|
+
function shaNatureOf(names) {
|
|
13621
|
+
return (Array.isArray(names) ? names : [])
|
|
13622
|
+
.map((n) => SHA_STAR[n] && SHA_STAR[n].nature)
|
|
13623
|
+
.filter(Boolean)
|
|
13624
|
+
.join('、');
|
|
13625
|
+
}
|
|
13626
|
+
|
|
13627
|
+
/** 吉星清单 → 一句「这一宫的白送项」;清单空则返回空串 */
|
|
13628
|
+
function fuLineOf(names) {
|
|
13629
|
+
const list = (Array.isArray(names) ? names : []).filter((n) => FU_STAR[n]);
|
|
13630
|
+
if (!list.length) return '';
|
|
13631
|
+
return list.slice(0, 3).map((n) => `${n}${FU_STAR[n].gift.replace(/^这一宫/, '')}`).join(',');
|
|
13632
|
+
}
|
|
13633
|
+
|
|
13634
|
+
/** 格局名 → 读法;词库里没有的格局只回落到 tone 决定的通用句,不编内容 */
|
|
13635
|
+
function patternReadOf(name, tone) {
|
|
13636
|
+
const hit = PATTERN_READ[String(name || '')];
|
|
13637
|
+
if (hit) return hit;
|
|
13638
|
+
if (tone === 'good') return { gist: '结构偏向有利,具体落在哪件事,要看它牵动的是哪一宫', advice: '顺势把事情做完整' };
|
|
13639
|
+
if (tone === 'bad') return { gist: '结构偏向消耗,提示这一块值得多一分留意', advice: '先把节奏放缓,再谈取舍' };
|
|
13640
|
+
return { gist: '结构中性,成事与否更多看后天怎么用', advice: '当成提醒,不当成结论' };
|
|
13641
|
+
}
|
|
13642
|
+
|
|
13643
|
+
return { PALACE_FIELD, STAR_EXTRA, STAR_PAIR, SHA_STAR, MAIN_SHA, FU_STAR, HUA_READ, BRIGHT_READ, PATTERN_READ, palaceFieldOf, brightRead, starExtraOf, starPairOf, huaInLine, shaLineOf, shaNatureOf, fuLineOf, patternReadOf };
|
|
13644
|
+
})();
|
|
13645
|
+
|
|
13646
|
+
__mods['bazi-words'] = (function () {
|
|
13647
|
+
// 八字解读词库:十日主取象 / 十神画像 / 命局基调 / 地支关系措辞
|
|
13648
|
+
//
|
|
13649
|
+
// 与 ziwei-words 同一个分工:引擎只管算出日主、旺衰、十神权重与干支关系,
|
|
13650
|
+
// 这里只管「这个人大概是什么样子」。所有条目都按传统取象写,措辞留余地:
|
|
13651
|
+
// 外形、性格都写「多半」「常」,不写成判决。
|
|
13652
|
+
|
|
13653
|
+
// ── 十日主:一张画面、一个体貌取象、一种性情、一处长处、一个坑 ──────
|
|
13654
|
+
const STEM_PORTRAIT = {
|
|
13655
|
+
甲: {
|
|
13656
|
+
image: '参天之木',
|
|
13657
|
+
look: '身形多半偏修长,肩背挺,站着有股站相',
|
|
13658
|
+
temper: '直、有担当,认定的事不太会转弯',
|
|
13659
|
+
gift: '扛得起事,适合把一摊子组织起来',
|
|
13660
|
+
trap: '不会转弯,撞上南墙也硬顶',
|
|
13661
|
+
},
|
|
13662
|
+
乙: {
|
|
13663
|
+
image: '藤萝之木',
|
|
13664
|
+
look: '身形柔韧,气质亲和,不太有攻击性',
|
|
13665
|
+
temper: '柔中带韧,擅长借力,能屈能伸',
|
|
13666
|
+
gift: '协调、渗透,在缝隙里也能生长',
|
|
13667
|
+
trap: '太依赖环境,环境一换就慌',
|
|
13668
|
+
},
|
|
13669
|
+
丙: {
|
|
13670
|
+
image: '太阳之火',
|
|
13671
|
+
look: '面色偏红润,精神足,进门容易被注意到',
|
|
13672
|
+
temper: '外放热情,心里想什么脸上就写着什么',
|
|
13673
|
+
gift: '感染人、带动气氛,适合站到台前',
|
|
13674
|
+
trap: '三分钟热度,来得快去得也快',
|
|
13675
|
+
},
|
|
13676
|
+
丁: {
|
|
13677
|
+
image: '灯烛之火',
|
|
13678
|
+
look: '偏清瘦,眼神亮,动静之间有点静气',
|
|
13679
|
+
temper: '内敛细腻,认准一件事能守很久',
|
|
13680
|
+
gift: '专注、耐得住,适合做需要磨的活',
|
|
13681
|
+
trap: '敏感,容易在心里反复内耗',
|
|
13682
|
+
},
|
|
13683
|
+
戊: {
|
|
13684
|
+
image: '城墙之土',
|
|
13685
|
+
look: '骨架偏厚,给人稳当、压得住场的感觉',
|
|
13686
|
+
temper: '沉稳慢热,不轻易表态,表态了就算数',
|
|
13687
|
+
gift: '承载与守成,能把局面稳稳托住',
|
|
13688
|
+
trap: '太钝,机会过了才反应过来',
|
|
13689
|
+
},
|
|
13690
|
+
己: {
|
|
13691
|
+
image: '田园之土',
|
|
13692
|
+
look: '面目温和,身形圆润,没什么棱角',
|
|
13693
|
+
temper: '包容细致,想得多,习惯先照顾别人',
|
|
13694
|
+
gift: '经营与服务,把琐碎的事理顺',
|
|
13695
|
+
trap: '纠结,反复权衡反而错过时机',
|
|
13696
|
+
},
|
|
13697
|
+
庚: {
|
|
13698
|
+
image: '刀剑之金',
|
|
13699
|
+
look: '骨架硬朗,气场直接,说话不绕弯',
|
|
13700
|
+
temper: '果决、讲义气,眼里容不下拖泥带水',
|
|
13701
|
+
gift: '执行与开疆,难啃的骨头敢接',
|
|
13702
|
+
trap: '太刚,锋利的一面容易伤到亲近的人',
|
|
13703
|
+
},
|
|
13704
|
+
辛: {
|
|
13705
|
+
image: '珠玉之金',
|
|
13706
|
+
look: '清秀讲究,衣着细节看得出用心',
|
|
13707
|
+
temper: '精致敏锐,对分寸与体面很在意',
|
|
13708
|
+
gift: '审美与精细活,做得比说的好',
|
|
13709
|
+
trap: '挑剔,也容易被一句评价刺到',
|
|
13710
|
+
},
|
|
13711
|
+
壬: {
|
|
13712
|
+
image: '江河之水',
|
|
13713
|
+
look: '身形偏厚实,眉眼开阔,气度大',
|
|
13714
|
+
temper: '大开大合,爱自由,不喜欢被框住',
|
|
13715
|
+
gift: '统筹与流动,能把资源盘活',
|
|
13716
|
+
trap: '散漫,摊子铺开却收不回来',
|
|
13717
|
+
},
|
|
13718
|
+
癸: {
|
|
13719
|
+
image: '雨露之水',
|
|
13720
|
+
look: '清秀安静,存在感不抢,但耐看',
|
|
13721
|
+
temper: '细腻、直觉强,心事多半自己消化',
|
|
13722
|
+
gift: '感知与研究,能注意到别人漏掉的细节',
|
|
13723
|
+
trap: '多愁,遇事先退,容易错过表态的时机',
|
|
13724
|
+
},
|
|
13725
|
+
};
|
|
13726
|
+
|
|
13727
|
+
// ── 十神画像:这一股力量在生活里像什么 ──────────────────────────
|
|
13728
|
+
const TENGOD_PORTRAIT = {
|
|
13729
|
+
正官: { role: '规则与名分', gift: '守序可靠,答应的事会做到', trap: '太在意评价,放不开手脚', love: '重承诺,但不擅长把在意说出口', work: '适合在成体系的组织里按层级上升' },
|
|
13730
|
+
七杀: { role: '压力与冲劲', gift: '抗压强、敢担事,越难越来劲', trap: '急躁,习惯用硬碰解决问题', love: '容易被有主见的人吸引,也容易互相较劲', work: '适合高挑战、要快速决断的岗位' },
|
|
13731
|
+
正财: { role: '稳定收入与责任', gift: '务实会积累,账目清楚', trap: '算得太细,不敢为机会冒一点险', love: '重实际,用行动多于言语', work: '适合按劳取酬、积累型的路径' },
|
|
13732
|
+
偏财: { role: '机会与流动资源', gift: '善抓机会、人脉活络', trap: '铺得太开,钱和精力都容易留不住', love: '大方、桃花多,边界要自己划', work: '适合业务、投资、资源整合' },
|
|
13733
|
+
食神: { role: '表达与享受', gift: '会生活,也能把喜欢的事做成产出', trap: '太舒服就懒下来,节奏一松就拖', love: '温柔会照顾人,也怕麻烦', work: '适合技术、创作、餐饮、教育' },
|
|
13734
|
+
伤官: { role: '才华与不服', gift: '点子多、敢改,能做出别人做不出的东西', trap: '嘴上不饶人,赢了道理输了关系', love: '要求高,容易挑对方的刺', work: '适合改革、创意、专业型岗位' },
|
|
13735
|
+
正印: { role: '支持与学习', gift: '有耐心、学得进,靠得住', trap: '依赖心重,想得多做得少', love: '需要被理解与照顾', work: '适合研究、文教、需要资质的岗位' },
|
|
13736
|
+
偏印: { role: '偏门与钻研', gift: '冷门的门类也能钻透', trap: '孤,想法多但不爱解释', love: '需要空间,不喜欢被管', work: '适合专精技术、冷门专业' },
|
|
13737
|
+
比肩: { role: '同伴与自我', gift: '独立、扛得住,不轻易麻烦别人', trap: '固执,什么都想亲力亲为', love: '相处像朋友多过像恋人', work: '适合并肩作战或独立负责一块' },
|
|
13738
|
+
劫财: { role: '竞争与行动', gift: '行动快、敢抢,机会面前不犹豫', trap: '冲动,容易在钱和人情上破口', love: '来去都快,需要给彼此空间', work: '适合业务冲刺、竞争型岗位' },
|
|
13739
|
+
|
|
13740
|
+
// 五组:godStats 给的是「比劫 / 食伤 / 财 / 官杀 / 印」这一层,
|
|
13741
|
+
// 组的名目与单颗十神不同,措辞也要跟着放宽——一组里总有两颗星的影子。
|
|
13742
|
+
比劫: { role: '自我与同辈', gift: '独立、扛得住,不太依赖别人', trap: '固执,什么都想自己来', love: '相处像并肩的伙伴', work: '适合独立负责一块,或与同频的人并肩' },
|
|
13743
|
+
食伤: { role: '表达与产出', gift: '有想法,也做得出东西', trap: '话多或要求高,容易得罪人', love: '重视交流,也容易挑刺', work: '适合创作、技术、教学这类要表达的岗位' },
|
|
13744
|
+
财: { role: '资源与现实', gift: '务实、会算账、抓得住机会', trap: '把安全感全押在数字上', love: '重实际,用行动多于言语', work: '适合业务、财务、资源整合' },
|
|
13745
|
+
官杀: { role: '规则与压力', gift: '守序、抗压、担得起责任', trap: '绷得太紧,习惯用硬碰解决', love: '重承诺,也容易管得太宽', work: '适合体系内按层级上升,或高压高挑战的岗位' },
|
|
13746
|
+
印: { role: '支持与学习', gift: '有耐心、学得进、靠得住', trap: '想得多做得少,依赖现成的东西', love: '需要被理解与照顾', work: '适合研究、文教、需要资质的岗位' },
|
|
13747
|
+
};
|
|
13748
|
+
|
|
13749
|
+
// ── 命局基调:先把「这盘是什么形状」说成一句话 ────────────────────
|
|
13750
|
+
// 按旺衰 + 用神方向取一句,不新增算法:全部是已有字段的组合说法。
|
|
13751
|
+
const FRAME_TONE = {
|
|
13752
|
+
强: {
|
|
13753
|
+
泄: '这盘的问题是「力气有余、出口不够」:不缺劲头,缺的是把劲往哪使。先把方向定下来,比再多加一把力更管用。',
|
|
13754
|
+
制: '这盘气足又带压力:能扛事,但也容易一直绷着。学会把压力分出去,比硬顶更能长久。',
|
|
13755
|
+
耗: '这盘底子厚,适合在资源与实务上做文章:把力气换成看得见的成果,别停在想法里。',
|
|
13756
|
+
},
|
|
13757
|
+
弱: {
|
|
13758
|
+
生: '这盘底子偏薄,靠「有人托一把」最有效:找对平台、师友与环境,比自己硬撑省力得多。',
|
|
13759
|
+
比: '这盘单打独斗会累,找到同频的人并肩做,反而能把短板补上。',
|
|
13760
|
+
泄: '这盘不宜再往外耗,先收一收摊子,把根基补稳,再谈扩张。',
|
|
13761
|
+
},
|
|
13762
|
+
中: {
|
|
13763
|
+
default: '这盘五行相对均衡,没有哪一处特别极端:走哪条路都能走,靠的是选择与坚持,不是运气。',
|
|
13764
|
+
},
|
|
13765
|
+
};
|
|
13766
|
+
|
|
13767
|
+
/**
|
|
13768
|
+
* 命局基调:由「强/弱/中」+ 用神角色取一句。
|
|
13769
|
+
* favorRoles 的先后就是优先级:调用方按十神权重排好再传进来,
|
|
13770
|
+
* 这样「喜食伤财官杀」时取到的是分量最重的那一路,而不是固定顺序的第一条。
|
|
13771
|
+
*/
|
|
13772
|
+
function frameToneOf(level, favorRoles) {
|
|
13773
|
+
const strong = /强/.test(String(level || ''));
|
|
13774
|
+
const weak = /弱/.test(String(level || ''));
|
|
13775
|
+
const roles = Array.isArray(favorRoles) ? favorRoles : [String(favorRoles || '')];
|
|
13776
|
+
if (!strong && !weak) return FRAME_TONE.中.default;
|
|
13777
|
+
const table = strong ? FRAME_TONE.强 : FRAME_TONE.弱;
|
|
13778
|
+
for (const r of roles) {
|
|
13779
|
+
const key = /官杀/.test(r) ? '制'
|
|
13780
|
+
: /财/.test(r) ? '耗'
|
|
13781
|
+
: /食伤/.test(r) ? '泄'
|
|
13782
|
+
: /印/.test(r) ? '生'
|
|
13783
|
+
: /比劫/.test(r) ? '比' : '';
|
|
13784
|
+
if (key && table[key]) return table[key];
|
|
13785
|
+
}
|
|
13786
|
+
return strong ? table.泄 : table.生;
|
|
13787
|
+
}
|
|
13788
|
+
|
|
13789
|
+
// ── 地支关系:冲合刑害各自是什么手感 ────────────────────────────
|
|
13790
|
+
// 只解释「这一组关系的性质」,不判具体事件——事件要看它动到的是哪一柱。
|
|
13791
|
+
const RELATION_RULES = [
|
|
13792
|
+
[/自刑/, '自刑:自己跟自己较劲,多半是内耗而不是外来的事'],
|
|
13793
|
+
[/三会|三合/, '三合三会:几股力并成一股,做同类的事更容易成势'],
|
|
13794
|
+
[/六合|合/, '合:人事上容易谈拢,也容易被关系绑住、脱不开身'],
|
|
13795
|
+
[/相冲|冲/, '冲:桩子会晃,变动与拉扯偏多,宜先稳住再动'],
|
|
13796
|
+
[/相刑|刑/, '刑:规矩与情绪上的摩擦,事情不大但磨人'],
|
|
13797
|
+
[/相害|害/, '害:暗处的损耗,多是说不清的不顺'],
|
|
13798
|
+
[/相破|破/, '破:本来成形的事容易散,收尾要多花一分力'],
|
|
13799
|
+
];
|
|
13800
|
+
|
|
13801
|
+
/** 一组地支关系串(如「丑未相冲」)→ 去重后的读法清单 */
|
|
13802
|
+
function relationNotes(list) {
|
|
13803
|
+
const out = [];
|
|
13804
|
+
for (const raw of (Array.isArray(list) ? list : [])) {
|
|
13805
|
+
for (const [re, note] of RELATION_RULES) {
|
|
13806
|
+
if (re.test(raw) && !out.includes(note)) { out.push(note); break; }
|
|
13807
|
+
}
|
|
13808
|
+
}
|
|
13809
|
+
return out;
|
|
13810
|
+
}
|
|
13811
|
+
|
|
13812
|
+
/** 十神名 → 画像;不在表里返回 null,调用方各自决定怎么略过 */
|
|
13813
|
+
function godPortraitOf(name) {
|
|
13814
|
+
return TENGOD_PORTRAIT[String(name || '')] || null;
|
|
13815
|
+
}
|
|
13816
|
+
|
|
13817
|
+
/** 日主天干 → 取象;不在表里返回 null */
|
|
13818
|
+
function stemPortraitOf(stem) {
|
|
13819
|
+
return STEM_PORTRAIT[String(stem || '')] || null;
|
|
13820
|
+
}
|
|
13821
|
+
|
|
13822
|
+
return { STEM_PORTRAIT, TENGOD_PORTRAIT, FRAME_TONE, frameToneOf, relationNotes, godPortraitOf, stemPortraitOf };
|
|
13823
|
+
})();
|
|
13824
|
+
|
|
12058
13825
|
__mods.interpret = (function () {
|
|
12059
13826
|
// 解析与详解模块
|
|
12060
13827
|
// 输入:任一体系的排盘结果(compute 的返回值)
|
|
@@ -12067,6 +13834,10 @@ __mods.interpret = (function () {
|
|
|
12067
13834
|
const { HEX64, HEX_BY_CORE, TRIGRAM, YAO_POSITION, MOVING_NATURE, ZIWEI_STARS, WUXING_INDUSTRY, WUXING_ORGAN, TENGOD_STYLE, LIUREN_JIANG, TAROT_ELEMENT_FOCUS, DISCLAIMER } = __mods['interpret-data'];
|
|
12068
13835
|
// 生年四化要按年干反查四颗星,四化表只在紫微引擎里定义了一份,这里直接复用,避免两处维护打架
|
|
12069
13836
|
const { MUTAGEN } = __mods.ziwei;
|
|
13837
|
+
// 紫微的词库单列一处:宫位取象、主星细节、双星、煞星辅星、四化措辞、庙旺语气、格局读法
|
|
13838
|
+
const { palaceFieldOf, starExtraOf, starPairOf, brightRead, huaInLine, shaLineOf, shaNatureOf, fuLineOf, patternReadOf, MAIN_SHA } = __mods['ziwei-words'];
|
|
13839
|
+
// 八字的画像词库:日主取象、十神画像、命局基调与地支关系说法
|
|
13840
|
+
const { stemPortraitOf, godPortraitOf, frameToneOf, relationNotes } = __mods['bazi-words'];
|
|
12070
13841
|
// 卦体关系的文案与面板 chip 共用同一份标签,避免两处措辞走散
|
|
12071
13842
|
const { bodyLabels, yongshenOf } = __mods.liuyao;
|
|
12072
13843
|
|
|
@@ -12115,7 +13886,8 @@ function askOf(opts) {
|
|
|
12115
13886
|
question,
|
|
12116
13887
|
direction: d.key,
|
|
12117
13888
|
directionLabel: d.label,
|
|
12118
|
-
|
|
13889
|
+
// 没填问题时别在抬头喊一句「(未填写)」——读者只想知道这张盘在说什么
|
|
13890
|
+
echo: question ? `问题:${question} | 询问方向:${d.label}` : `询问方向:${d.label}`,
|
|
12119
13891
|
};
|
|
12120
13892
|
}
|
|
12121
13893
|
|
|
@@ -12364,8 +14136,69 @@ function baziInterpret(r) {
|
|
|
12364
14136
|
},
|
|
12365
14137
|
];
|
|
12366
14138
|
|
|
14139
|
+
// ── 词库取词:日主取象 / 十神画像 / 命局基调 / 地支关系 ────────────
|
|
14140
|
+
const stemP = stemPortraitOf(dm.stem);
|
|
14141
|
+
const topP = godPortraitOf(topName);
|
|
14142
|
+
const secondP = godPortraitOf(secondName);
|
|
14143
|
+
const season = st.parts && st.parts.season ? st.parts.season : null;
|
|
14144
|
+
const dayZhi = pick(r.pillars?.day, 'branch', '');
|
|
14145
|
+
// 组(比劫/食伤…)之外,再点出单颗最突出的十神:同一组里正财与偏财的味道并不一样
|
|
14146
|
+
const byGodSorted = Object.entries(isObj(frame.godStats?.byGod) ? frame.godStats.byGod : {})
|
|
14147
|
+
.filter(([, v]) => Number(v) > 0)
|
|
14148
|
+
.sort((a, b) => b[1] - a[1]);
|
|
14149
|
+
const topGodName = byGodSorted[0] ? byGodSorted[0][0] : '';
|
|
14150
|
+
const topGodP = godPortraitOf(topGodName);
|
|
14151
|
+
// 用神角色按权重排序,命局基调取分量最重的那一路
|
|
14152
|
+
const favorRolesByWeight = (Array.isArray(ys.favorRoles) ? ys.favorRoles : [])
|
|
14153
|
+
.slice()
|
|
14154
|
+
.sort((a, b) => (Number(groups[b]) || 0) - (Number(groups[a]) || 0));
|
|
14155
|
+
|
|
14156
|
+
const frameworkText = [
|
|
14157
|
+
`**日主**:${dm.stem}${dm.element}(${dm.yinYang}${dm.element})${season ? `生于${season.branch}月,日主在月令「${season.word}」` : ''},命局${level}(${pick(st, 'score', '—')} 分)${stemP ? `——${stemP.image}之象` : ''}。`,
|
|
14158
|
+
`**用神**:喜${join(favor) || '—'}(${join(ys.favorRoles || []) || '—'}),忌${join(avoid) || '—'}(${join(ys.avoidRoles || []) || '—'})。${frameToneOf(level, favorRolesByWeight)}`,
|
|
14159
|
+
`**格局**:${primary}(${pick(frame.primary, 'evidence', '')})${(Array.isArray(frame.geju) ? frame.geju : []).filter((g) => g.name && g.name !== primary).length
|
|
14160
|
+
? `,另有${frame.geju.map((g) => g.name).filter((n) => n && n !== primary).join('、')}`
|
|
14161
|
+
: ''}。`,
|
|
14162
|
+
].join('\n');
|
|
14163
|
+
|
|
14164
|
+
const portraitText = [
|
|
14165
|
+
`**外在取象**:${stemP ? `${stemP.image}的日主,传统取象上${stemP.look}` : '这一柱的取象词库未覆盖'}${stemP ? `;气质上${stemP.temper}` : ''}。这一层只是取象,不作定论。`,
|
|
14166
|
+
`**性格底色**:十神里${topName || '—'}最重${top[0] ? `(${top[0][1]})` : ''}${secondName ? `,${secondName}次之` : ''}。${topP ? `${topP.gift};${topP.trap}。` : ''}`
|
|
14167
|
+
+ (topGodP && topGodName && topGodName !== topName ? `具体到单颗,${topGodName}最显,落在「${topGodP.role}」上。` : '')
|
|
14168
|
+
+ (stemP ? `放在${dm.stem}日主身上,长处是「${stemP.gift}」,容易踩的坑是「${stemP.trap}」。` : ''),
|
|
14169
|
+
`**事业与家庭**:${topP ? `做事上${topP.work}` : '做事方式看喜用与时运'}${topP ? `;感情里${topP.love}。` : '。'}日支${dayZhi}${pick(r.pillars?.day, 'zizuo', '') ? `坐${pick(r.pillars?.day, 'zizuo', '')}` : ''},${Number(groups[spouseKey] || 0) >= 2 ? '配偶星不弱,关系里你有条件被好好对待,也要留意别把这些当成理所当然' : '配偶星偏轻,感情更需要主动经营'}。${secondP ? `另一面是${secondName}的${secondP.role}:${secondP.gift}。` : ''}`,
|
|
14170
|
+
].join('\n');
|
|
14171
|
+
|
|
14172
|
+
const yearLines = (r.liunian || []).slice(0, 3).map((l) => {
|
|
14173
|
+
const lk = isObj(l.luck) ? l.luck : {};
|
|
14174
|
+
const notes = relationNotes(l.relations);
|
|
14175
|
+
const why = (lk.reasons || []).slice(0, 2).join(',');
|
|
14176
|
+
return `**${l.year} ${l.ganzhi}**(${l.age}岁·${l.stemTenGod || '—'})${lk.tier || '平'}:${why || '没有特别信号,按大运的基调走'}${notes.length ? `;与命局的关系——${notes.join(';')}` : ''}。`;
|
|
14177
|
+
}).join('\n');
|
|
14178
|
+
const yearsText = yearLines
|
|
14179
|
+
? `先看眼前三年(大字是当年干支与十神,后面是该年的档位与理由):\n${yearLines}\n读法:档位说的是「这一年顺不顺手」,不是「会发生什么」;年份不顺时把重要动作挪到顺的年份,比硬扛更省事。`
|
|
14180
|
+
: '流年数据未取到,暂不展开。';
|
|
14181
|
+
|
|
14182
|
+
const adviceItems = [];
|
|
14183
|
+
if (favor.length) {
|
|
14184
|
+
adviceItems.push(`把生活与工作往${join(favor)}的方向挪一点:${favor.slice(0, 2).map((e) => WUXING_INDUSTRY[e] || '').filter(Boolean).join(';') || '按喜用五行对应的行业挑'}。不必推倒重来,先从环境、圈子和日常习惯改起。`);
|
|
14185
|
+
}
|
|
14186
|
+
if (avoid.length) {
|
|
14187
|
+
adviceItems.push(`对${join(avoid)}保持一点自觉:不是不能碰,而是别在关键决定上给它加码——${avoid.includes('火') ? '少在情绪最热的时候拍板' : avoid.includes('木') ? '少在想法最多的时候开工' : '先把手上的事收尾再谈新的'}。`);
|
|
14188
|
+
}
|
|
14189
|
+
const relNotes = relationNotes(r.relations && r.relations.branches);
|
|
14190
|
+
if (relNotes.length) {
|
|
14191
|
+
adviceItems.push(`命局里的地支关系是「${(r.relations.branches || []).join('、')}」:${relNotes.join(';')}。对应到具体人事,先处理情绪,再处理事情。`);
|
|
14192
|
+
}
|
|
14193
|
+
if (cli && cli.need) {
|
|
14194
|
+
adviceItems.push(`调候要${cli.need.stem}${cli.need.element}:${cli.need.why}。落到日常,就是往这一类的环境、作息与节奏上靠。`);
|
|
14195
|
+
}
|
|
14196
|
+
const adviceText = adviceItems.slice(0, 4).map((t, i) => `${'①②③④'[i]} ${t}`).join('\n');
|
|
14197
|
+
|
|
12367
14198
|
const sections = [
|
|
12368
14199
|
...(cross.length ? [{ key: 'cross', label: '交叉判断', text: cross.join(' ') }] : []),
|
|
14200
|
+
{ key: 'framework', label: '命局框架', text: frameworkText },
|
|
14201
|
+
{ key: 'portrait', label: '画像', text: portraitText },
|
|
12369
14202
|
{
|
|
12370
14203
|
key: 'reasoning', label: '看盘顺序',
|
|
12371
14204
|
// 把「先看什么、后看什么」摊开:用户能照着复核,也避免只给结论不给路径
|
|
@@ -12396,6 +14229,8 @@ function baziInterpret(r) {
|
|
|
12396
14229
|
return `${jiaoLine}当前大运:${pick(cur, 'ganzhi', '—')}(${curSpan})。后续两步:${nextTwo}。\n近五年流年:${years || '—'}。\n读法:大运管"这十年的大环境",流年管"今年的具体天气";两者打架时,以能否动到用神为准。`;
|
|
12397
14230
|
})(),
|
|
12398
14231
|
},
|
|
14232
|
+
{ key: 'years', label: '流年时间轴', text: yearsText },
|
|
14233
|
+
{ key: 'advice', label: '专业建议', text: adviceText },
|
|
12399
14234
|
(() => {
|
|
12400
14235
|
const hits = (r.liunian || []).filter((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
12401
14236
|
return {
|
|
@@ -12596,12 +14431,24 @@ function ziweiInterpret(r) {
|
|
|
12596
14431
|
? `你的命宫无正曜,按紫微的规则借对宫(迁移)来看,主星是${soulStar}`
|
|
12597
14432
|
: `你的命宫与对宫都没有正曜,这里按命主星${soulStar}来看`;
|
|
12598
14433
|
const S = ZIWEI_STARS[soulStar] || ZIWEI_STARS.紫微;
|
|
14434
|
+
// 维度里只点名六煞;其余煞星留在逐宫分析,避免把细枝末节放大成主线
|
|
14435
|
+
const zwMainSha = (p) => zwSha(p).filter((n) => MAIN_SHA.includes(n));
|
|
12599
14436
|
|
|
12600
14437
|
const careerStar = zwMainStar(career);
|
|
12601
14438
|
const wealthStar = zwMainStar(wealth);
|
|
12602
14439
|
const spouseStar = zwMainStar(spouse);
|
|
12603
14440
|
const healthStar = zwMainStar(health);
|
|
12604
14441
|
|
|
14442
|
+
// 词库取词的几个小入口:主星清单、单颗星的亮度、双星组合、主星细节
|
|
14443
|
+
const mainsOf = (p) => (p?.stars || []).filter((x) => x.type === '主星');
|
|
14444
|
+
const brightOf = (p, name) => (p?.stars || []).find((x) => x.name === name)?.brightness || '';
|
|
14445
|
+
const pairOf = (p) => starPairOf(mainsOf(p).map((x) => x.name));
|
|
14446
|
+
const SX = starExtraOf(soulStar) || {};
|
|
14447
|
+
const soulBright = brightRead(brightOf(soul, soulStar));
|
|
14448
|
+
const soulPair = pairOf(soul);
|
|
14449
|
+
// 亮度的语气只调「长处放不放得开」,不改结论:落陷时取 dim 那一句
|
|
14450
|
+
const lightLine = (b, extra) => (extra ? `${b && b.tone === 'bad' ? extra.dim : extra.bright}。` : '');
|
|
14451
|
+
|
|
12605
14452
|
const age = Number(pick(r.liunian?.[0], 'age', NaN));
|
|
12606
14453
|
let daxianPalace = null;
|
|
12607
14454
|
for (const p of r.palaces || []) {
|
|
@@ -12621,14 +14468,21 @@ function ziweiInterpret(r) {
|
|
|
12621
14468
|
const dimensions = [
|
|
12622
14469
|
{
|
|
12623
14470
|
key: 'overall', label: '整体运势',
|
|
12624
|
-
text: `${soulFrom},性格底色上${S.trait}
|
|
14471
|
+
text: `${soulFrom}${soulBright ? `(${soulBright.word}——${soulBright.plain})` : ''},性格底色上${S.trait}。` +
|
|
14472
|
+
(soulPair ? `${soulPair.gist};${soulPair.watch}。` : '') +
|
|
14473
|
+
`本盘${patText}。` +
|
|
12625
14474
|
`当前大限走在${daxianPalace ? `${daxianPalace.palace}(${daxianPalace.daxian.start}–${daxianPalace.daxian.end}岁)` : '当前阶段'},` +
|
|
12626
14475
|
`${lnMutagen ? `流年四化为${lnMutagen},本年的变化感主要落在这几颗星上` : '流年四化信号不明显'}。` +
|
|
12627
14476
|
(r.flow ? `再往下一层,当前流月命宫是${r.flow.month.ganzhi},落在原局${r.flow.month.palace || '未上盘'},本月的变化更容易在这一宫代表的事情上显出来。` : '') +
|
|
12628
14477
|
(natalSihuaText
|
|
12629
14478
|
? `另外你本命的生年四化落在:${natalSihuaText}——这是你这辈子比较稳定的底色,不随某一年改变。`
|
|
12630
14479
|
: ''),
|
|
12631
|
-
advice:
|
|
14480
|
+
advice: (() => {
|
|
14481
|
+
const dxName = daxianPalace ? daxianPalace.palace : '命宫';
|
|
14482
|
+
const dxField = palaceFieldOf(dxName);
|
|
14483
|
+
return `这一阶段的主题更接近「${dxName}」——${dxField ? dxField.field : '这一宫代表的事'}。把它当作这几年的主线,其余安排围着它让路;`
|
|
14484
|
+
+ `${SX.gift ? `你最顺手的做法是${SX.gift}` : `你的优势在${S.trait}`},但要留意${SX.watch || '用它用过了头'}。`;
|
|
14485
|
+
})(),
|
|
12632
14486
|
evidence: [
|
|
12633
14487
|
`命宫 ${soulStar}${soulOwn ? '' : '(借对宫)'}`,
|
|
12634
14488
|
daxianPalace ? `大限 ${daxianPalace.palace} ${daxianPalace.daxian.start}–${daxianPalace.daxian.end}岁` : '',
|
|
@@ -12638,16 +14492,38 @@ function ziweiInterpret(r) {
|
|
|
12638
14492
|
},
|
|
12639
14493
|
{
|
|
12640
14494
|
key: 'work', label: '工作与职业选择',
|
|
12641
|
-
text:
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
14495
|
+
text: (() => {
|
|
14496
|
+
const careerBright = brightRead(brightOf(career, careerStar));
|
|
14497
|
+
const careerPair = pairOf(career);
|
|
14498
|
+
const careerSha = zwMainSha(career);
|
|
14499
|
+
return `命宫${soulStar}给你的是底层偏好:${S.work}。`
|
|
14500
|
+
+ `官禄宫${careerStar
|
|
14501
|
+
? `主星为${careerStar}${careerBright ? `(${careerBright.word})` : ''},${ZIWEI_STARS[careerStar]?.work || '有其自身的做事方式'}`
|
|
14502
|
+
: '无正曜,工作方式更多受环境与他人影响,适合配合型岗位'}。`
|
|
14503
|
+
+ (careerPair ? `${careerPair.gist};要留意${careerPair.watch}。` : '')
|
|
14504
|
+
+ (careerSha.length ? `官禄宫又见${join(careerSha)}:${shaLineOf(careerSha)}` : '')
|
|
14505
|
+
+ `两者合起来看,你更适合${careerStar && careerStar !== soulStar ? `用${soulStar}的方式去做${careerStar}擅长的事` : '在稳定的框架里发挥自己的特点'}。`;
|
|
14506
|
+
})(),
|
|
14507
|
+
advice: `挑工作时可以先看岗位内容是否匹配上面这条;如果暂时不能换,试着在现有岗位里争取靠近这部分的事务——${SX.gift ? `把「${SX.gift}」这类活往自己身上揽,比硬熬更容易做出成绩` : '先做出一件拿得出手的事,比硬熬更容易被看见'}。`,
|
|
14508
|
+
evidence: [
|
|
14509
|
+
`命宫 ${soulStar}${soulBright ? `·${soulBright.word}` : ''}`,
|
|
14510
|
+
`官禄 ${careerStar || '无正曜'}`,
|
|
14511
|
+
`财帛 ${wealthStar || '无正曜'}`,
|
|
14512
|
+
...(zwMainSha(career).length ? [`官禄煞星 ${join(zwMainSha(career))}`] : []),
|
|
14513
|
+
],
|
|
12645
14514
|
},
|
|
12646
14515
|
{
|
|
12647
14516
|
key: 'career', label: '事业发展',
|
|
12648
|
-
text:
|
|
12649
|
-
|
|
12650
|
-
|
|
14517
|
+
text: (() => {
|
|
14518
|
+
const wealthBright = brightRead(brightOf(wealth, wealthStar));
|
|
14519
|
+
const wealthPair = pairOf(wealth);
|
|
14520
|
+
return `财帛宫${wealthStar
|
|
14521
|
+
? `见${wealthStar}${wealthBright ? `(${wealthBright.word})` : ''},${ZIWEI_STARS[wealthStar]?.trait || ''}`
|
|
14522
|
+
: '无正曜'},官禄宫${careerStar || '无正曜'},`
|
|
14523
|
+
+ `${wealthStar && careerStar ? '财与事业两宫都有主星坐守,说明这两块是可以主动经营的部分' : '有一宫无主星,说明该块更容易受外部条件牵动,宜借势而非强求'}。`
|
|
14524
|
+
+ (wealthPair ? `${wealthPair.gist}。` : '')
|
|
14525
|
+
+ `大限推进上,${daxianPalace ? `目前落在${daxianPalace.palace},这一宫管${palaceFieldOf(daxianPalace.palace)?.field || '这一段的事'}` : '当前阶段'},下一步会转入相邻的宫位,重心也会跟着挪。`;
|
|
14526
|
+
})(),
|
|
12651
14527
|
advice: `事业上建议做两件事:一是把可积累的东西(技能、资质、作品)做厚;二是${careerStar ? `发挥${careerStar}的优势——${ZIWEI_STARS[careerStar]?.trait || ''}` : '找一个能带你的前辈或平台'}。遇到四化化忌的年份,先守成再谈扩张。`,
|
|
12652
14528
|
evidence: [
|
|
12653
14529
|
`财帛 ${wealthStar || '无正曜'}`,
|
|
@@ -12657,8 +14533,17 @@ function ziweiInterpret(r) {
|
|
|
12657
14533
|
},
|
|
12658
14534
|
{
|
|
12659
14535
|
key: 'love', label: '爱情与感情',
|
|
12660
|
-
text:
|
|
12661
|
-
|
|
14536
|
+
text: (() => {
|
|
14537
|
+
const spouseBright = brightRead(brightOf(spouse, spouseStar));
|
|
14538
|
+
const spousePair = pairOf(spouse);
|
|
14539
|
+
const spouseSha = zwMainSha(spouse);
|
|
14540
|
+
return `夫妻宫${spouseStar
|
|
14541
|
+
? `主星为${spouseStar}${spouseBright ? `(${spouseBright.word})` : ''},感情上的倾向是${ZIWEI_STARS[spouseStar]?.love || '有自己相处的节奏'}`
|
|
14542
|
+
: '无正曜,关系状态更多由对方与互动方式决定'}。`
|
|
14543
|
+
+ (spousePair ? `${spousePair.gist}。` : '')
|
|
14544
|
+
+ `${spouseSha.length ? `夫妻宫同时见${join(spouseSha)}:${shaLineOf(spouseSha)}煞星不等于定局,更多是提醒你留意沟通方式。` : '夫妻宫未见明显煞星,关系的基调相对平顺。'}`
|
|
14545
|
+
+ (SX.watch ? `另外,你自带的${SX.watch}这一面,在亲密关系里最容易被放大。` : '');
|
|
14546
|
+
})(),
|
|
12662
14547
|
advice: `感情里${spouseStar ? `参考${spouseStar}的特点:${ZIWEI_STARS[spouseStar]?.love || ''}` : '可以更主动地表达自己的需求'}。有分歧时先说清事实与感受,别急着下结论;关系的好坏取决于两个人怎么做,不取决于这张盘。`,
|
|
12663
14548
|
evidence: [
|
|
12664
14549
|
`夫妻宫 ${spouseStar || '无正曜'}`,
|
|
@@ -12668,8 +14553,17 @@ function ziweiInterpret(r) {
|
|
|
12668
14553
|
},
|
|
12669
14554
|
{
|
|
12670
14555
|
key: 'health', label: '健康状况',
|
|
12671
|
-
text:
|
|
12672
|
-
|
|
14556
|
+
text: (() => {
|
|
14557
|
+
const healthBright = brightRead(brightOf(health, healthStar));
|
|
14558
|
+
const healthSha = zwMainSha(health);
|
|
14559
|
+
return `疾厄宫${healthStar
|
|
14560
|
+
? `见${healthStar}${healthBright ? `(${healthBright.word})` : ''},传统取象上${ZIWEI_STARS[healthStar]?.health || '需要留意自身的薄弱环节'}`
|
|
14561
|
+
: '无正曜,身体状态更多受生活作息直接影响'}。`
|
|
14562
|
+
+ (healthSha.length
|
|
14563
|
+
? `同时见${join(healthSha)},按星情只是「${shaNatureOf(healthSha)}」这一层,提示这一块值得比其他部位多一分留意。`
|
|
14564
|
+
: '')
|
|
14565
|
+
+ '这些都是象征性的提示,不构成任何医学判断。';
|
|
14566
|
+
})(),
|
|
12673
14567
|
advice: `把${healthStar ? ZIWEI_STARS[healthStar]?.health?.replace('留意', '').replace('需要留意', '') || '常规' : '常规'}当作体检时重点关注的参考;真正管用的还是规律作息、适度运动与定期检查。身体不舒服请直接就医。`,
|
|
12674
14568
|
evidence: [
|
|
12675
14569
|
`疾厄宫 ${healthStar || '无正曜'}`,
|
|
@@ -12678,9 +14572,106 @@ function ziweiInterpret(r) {
|
|
|
12678
14572
|
},
|
|
12679
14573
|
];
|
|
12680
14574
|
|
|
14575
|
+
// ── 命身底色:先把「这张盘是谁」摆出来,再谈逐宫与格局 ──────────
|
|
14576
|
+
const soulField = palaceFieldOf('命宫');
|
|
14577
|
+
const bodyLands = pick(r.body, 'lands', '');
|
|
14578
|
+
const bodyField = palaceFieldOf(bodyLands);
|
|
14579
|
+
const identityText = [
|
|
14580
|
+
`命宫落在${soul.branch}(${soul && soul.ganzhi ? soul.ganzhi : '—'}),主星${soulStar}${soulBright ? `·${soulBright.word}` : ''}——这一宫管${soulField ? soulField.field : '你自己'},${SX.gift ? `你身上最能用出去的是${SX.gift}` : S.trait}。`
|
|
14581
|
+
+ (SX.gift ? lightLine(soulBright, SX) : ''),
|
|
14582
|
+
soulPair ? `${soulPair.gist};要留意的是${soulPair.watch}。` : '',
|
|
14583
|
+
bodyLands ? `身宫寄在${bodyLands}——${bodyField ? `${bodyField.field}是后天更容易使上劲的地方` : '这是后天着力点'},中年以后会越来越明显。` : '',
|
|
14584
|
+
`五行局为${pick(r.bureau, 'name', '—')},${pick(r.daxian, 'startAge', '—')}岁起运:局定的是节奏(几步起、十年一换),不是好坏。`,
|
|
14585
|
+
`命主${pick(r, 'lifeMaster', '—')}、身主${pick(r, 'bodyMaster', '—')}:传统把这两颗当作整张盘的定调星,命主看底色,身主看后半程的着力点。`,
|
|
14586
|
+
].filter(Boolean).join('\n');
|
|
14587
|
+
|
|
14588
|
+
// ── 逐宫分析:十二宫各一行清单 + 一句读法 ────────────────────
|
|
14589
|
+
const trimDot = (s) => String(s || '').replace(/。$/, '');
|
|
14590
|
+
const palaceLines = (r.palaces || []).map((p) => {
|
|
14591
|
+
const mains = mainsOf(p);
|
|
14592
|
+
const shas = zwSha(p);
|
|
14593
|
+
const fus = (p.stars || []).filter((x) => x.type === '辅星' || x.type === '吉星').map((x) => x.name);
|
|
14594
|
+
const huas = (p.stars || []).filter((x) => x.mutagen).map((x) => `${x.name}化${x.mutagen}`);
|
|
14595
|
+
const selfs = (p.selfHua || []).map((x) => `自化${x.type}`);
|
|
14596
|
+
const head = `【${p.palace}·${p.branch}】`
|
|
14597
|
+
+ `${mains.length ? mains.map((x) => `${x.name}${x.brightness || ''}`).join('·') : '无正曜'}`
|
|
14598
|
+
+ (fus.length ? `|吉 ${fus.slice(0, 3).join('、')}` : '')
|
|
14599
|
+
+ (shas.length ? `|煞 ${shas.join('、')}` : '')
|
|
14600
|
+
+ ((huas.length || selfs.length) ? `|${[...huas, ...selfs].join('、')}` : '');
|
|
14601
|
+
|
|
14602
|
+
const read = [];
|
|
14603
|
+
if (mains.length) {
|
|
14604
|
+
const pair = starPairOf(mains.map((x) => x.name));
|
|
14605
|
+
const ex = starExtraOf(mains[0].name);
|
|
14606
|
+
if (pair) read.push(pair.gist);
|
|
14607
|
+
else if (ex) read.push(ex.gift);
|
|
14608
|
+
} else {
|
|
14609
|
+
// 命无正曜时借对宫:三方数组的第四位就是对宫
|
|
14610
|
+
const opposite = zwMainStar(zwPalace(r, (p.sanfang || [])[3]));
|
|
14611
|
+
read.push(opposite ? `无正曜,借对宫${opposite}来看` : '无正曜,这一宫随环境走');
|
|
14612
|
+
}
|
|
14613
|
+
if (fus.length) read.push(fuLineOf(fus));
|
|
14614
|
+
if (shas.length) read.push(shaLineOf(shas));
|
|
14615
|
+
for (const x of (p.stars || []).filter((y) => y.mutagen).slice(0, 2)) read.push(huaInLine(x.mutagen, p.palace));
|
|
14616
|
+
const tail = read.filter(Boolean).map(trimDot).join(';');
|
|
14617
|
+
return `${head}\n ${tail}。`;
|
|
14618
|
+
}).join('\n');
|
|
14619
|
+
const palacesText = `十二宫从命宫逆排,每宫管一件事。看一宫不能只看本宫,还要并上它的三方四正(本宫+对宫+两个三合宫)——下面先逐宫摊开,再回到整体。\n${palaceLines}`;
|
|
14620
|
+
|
|
14621
|
+
// ── 格局分三层:有利 / 结构提示 / 忌格提醒 ──────────────────
|
|
14622
|
+
const PATTERN_TIERS = [
|
|
14623
|
+
{ tone: 'good', label: '有利格局' },
|
|
14624
|
+
{ tone: 'neutral', label: '结构提示' },
|
|
14625
|
+
{ tone: 'bad', label: '忌格提醒' },
|
|
14626
|
+
];
|
|
14627
|
+
const patternSections = PATTERN_TIERS.map((t) => {
|
|
14628
|
+
const list = patterns.filter((p) => (p.tone || 'neutral') === t.tone);
|
|
14629
|
+
if (!list.length) return null;
|
|
14630
|
+
return {
|
|
14631
|
+
key: `pattern-${t.tone}`,
|
|
14632
|
+
label: t.label,
|
|
14633
|
+
tone: t.tone === 'neutral' ? 'watch' : t.tone,
|
|
14634
|
+
text: list.map((p) => {
|
|
14635
|
+
const rd = patternReadOf(p.name, p.tone);
|
|
14636
|
+
return `**${p.name}** ${rd.gist}\n 依据:${p.evidence}\n 做法:${rd.advice}`;
|
|
14637
|
+
}).join('\n'),
|
|
14638
|
+
};
|
|
14639
|
+
}).filter(Boolean);
|
|
14640
|
+
if (!patternSections.length) {
|
|
14641
|
+
patternSections.push({ key: 'pattern-none', label: '格局', text: '本盘未触发内置的常见格局条目。这不代表盘面平淡——格局只是把若干星位组合起个名字,没命中时按宫位与四化逐条看即可。' });
|
|
14642
|
+
}
|
|
14643
|
+
|
|
14644
|
+
// ── 行动建议:每条都从盘面事实推出来,能指到具体一宫才写 ──────────
|
|
14645
|
+
const adviceItems = [];
|
|
14646
|
+
if (SX.gift) {
|
|
14647
|
+
adviceItems.push(`把「${SX.gift}」做成招牌:${soulBright && soulBright.tone === 'bad'
|
|
14648
|
+
? `${soulStar}在这宫不得地,长处不会自己显出来,越要挑能发挥它的场子`
|
|
14649
|
+
: `${soulStar}${soulBright ? `·${soulBright.word}` : '在命宫'},顺着这条走最省力`}。`);
|
|
14650
|
+
}
|
|
14651
|
+
if (daxianPalace && daxianPalace.daxian) {
|
|
14652
|
+
const dxf = palaceFieldOf(daxianPalace.palace);
|
|
14653
|
+
adviceItems.push(`这几年主线在${daxianPalace.palace}(${daxianPalace.daxian.start}–${daxianPalace.daxian.end}岁):${dxf ? dxf.field : '这一宫的事'}排前面,力气别摊平。`);
|
|
14654
|
+
}
|
|
14655
|
+
const jiHua = natalSihua.find((m) => m.type === '忌');
|
|
14656
|
+
if (jiHua && jiHua.palace) {
|
|
14657
|
+
const jf = palaceFieldOf(jiHua.palace);
|
|
14658
|
+
adviceItems.push(`生年化忌落在${jiHua.palace}:${jf ? jf.huaJi : '这一块容易反复'}——别硬顶,把预期调低一点反而顺。`);
|
|
14659
|
+
}
|
|
14660
|
+
const soulSha = zwMainSha(soul);
|
|
14661
|
+
if (soulSha.length) adviceItems.push(`命宫见${join(soulSha)}:${shaLineOf(soulSha)}`);
|
|
14662
|
+
const spouseSha2 = zwMainSha(spouse);
|
|
14663
|
+
if (spouseSha2.length && !soulSha.length) {
|
|
14664
|
+
adviceItems.push(`夫妻宫见${join(spouseSha2)}:${shaLineOf(spouseSha2)}`);
|
|
14665
|
+
}
|
|
14666
|
+
const adviceText = adviceItems.slice(0, 4)
|
|
14667
|
+
.map((t, i) => `${'①②③④'[i]} ${trimDot(t)}`)
|
|
14668
|
+
.join('\n') || '这张盘的结构比较平,没有单点特别突出——按现有节奏走,把一件事做完整比开新头更划算。';
|
|
14669
|
+
|
|
12681
14670
|
const sections = [
|
|
12682
|
-
{ key: '
|
|
12683
|
-
{ key: '
|
|
14671
|
+
{ key: 'identity', label: '命身底色', text: identityText },
|
|
14672
|
+
{ key: 'palaces', label: '逐宫分析', text: palacesText },
|
|
14673
|
+
...patternSections,
|
|
14674
|
+
{ key: 'advice', label: '行动建议', text: adviceText },
|
|
12684
14675
|
{
|
|
12685
14676
|
key: 'reasoning', label: '看盘顺序',
|
|
12686
14677
|
text: [
|
|
@@ -12992,6 +14983,11 @@ function liuyaoInterpret(r, ask) {
|
|
|
12992
14983
|
} else if (ug.fushen.length) {
|
|
12993
14984
|
useText.push(`用神不上卦:本卦六爻里没有${ug.liuqin},按「用神不上卦则于本宫首卦内寻之」,到${String(pick(ben, 'palace', '')).replace(/宫$/, '')}宫首卦取伏神——${ug.fushen.map((f) => `${f.position}爻${f.ganzhi}${f.element},伏于飞神${f.fei ? `${f.fei.liuqin}${f.fei.ganzhi}${f.fei.element}` : '—'}之下`).join(';')}。`);
|
|
12994
14985
|
if (ug.relationSay.length) useText.push(`飞伏生克:${ug.relationSay.join(';')}。伏神要得出才算有力,藏在忌神之下且被克,则虽有如无。`);
|
|
14986
|
+
const chufu = r.fushenAccess;
|
|
14987
|
+
if (chufu && Array.isArray(chufu.items) && chufu.items.length) {
|
|
14988
|
+
useText.push(`伏神出伏的条件:${chufu.items.map((f) => f.say).join(';')}。`);
|
|
14989
|
+
useText.push('「助」与「压」只把飞伏生克、月建日辰与月破并列摆出,再归成四档(可出 / 有助有压 / 受压难出 / 未得助);不排各家优先级,旬空只标出、不并入档位,也不给应期日期。');
|
|
14990
|
+
}
|
|
12995
14991
|
} else {
|
|
12996
14992
|
useText.push(`用神不上卦,且本宫首卦里也没找到${ug.liuqin},这一问在卦面上没有直接对应物,只能借日月或改日再占。`);
|
|
12997
14993
|
}
|
|
@@ -13062,7 +15058,7 @@ function liuyaoInterpret(r, ask) {
|
|
|
13062
15058
|
|
|
13063
15059
|
sections.push({
|
|
13064
15060
|
key: 'limits', label: '未纳入',
|
|
13065
|
-
text: '
|
|
15061
|
+
text: '本卦没有计算:用神两现时该取哪一爻的权重、伏神出伏的应期(出伏条件已判,应期仍未做)。化进/化退的力重只按月建五态给「得令/失令」这类档位,不折成加权分数,也不叠动变连环;这些都会改变"旺不旺"的判断,所以这里只给取象与方向。',
|
|
13066
15062
|
});
|
|
13067
15063
|
|
|
13068
15064
|
const dimensions = [
|
|
@@ -13496,37 +15492,61 @@ const { CLASSIC_BOOKS } = __mods.classics;
|
|
|
13496
15492
|
*/
|
|
13497
15493
|
function enrichPlain(result, r, ask) {
|
|
13498
15494
|
if (!result) return result;
|
|
15495
|
+
// 注解卡的归属按「维度身份」定,不按显示顺序:所问之事会把某一维提前,
|
|
15496
|
+
// 若按显示顺序先到先得,同一张盘换个问法就换了注解归属。
|
|
15497
|
+
const DIM_RANK = ['overall', 'work', 'career', 'love', 'health'];
|
|
15498
|
+
const rankOf = (key) => { const i = DIM_RANK.indexOf(key); return i < 0 ? DIM_RANK.length : i; };
|
|
15499
|
+
const seen = new Set();
|
|
13499
15500
|
const dims = (result.dimensions || []).map((d) => {
|
|
13500
15501
|
const p = dimensionPlain(d.key, r, {});
|
|
13501
|
-
|
|
13502
|
-
const know = knowledgeFor(r.system, d.key).map((k) => ({
|
|
13503
|
-
id: k.id,
|
|
13504
|
-
gist: k.gist,
|
|
13505
|
-
detail: k.detail,
|
|
13506
|
-
source: k.source,
|
|
13507
|
-
status: k.status,
|
|
13508
|
-
statusLabel: STATUS_LABEL[k.status] || k.status,
|
|
13509
|
-
note: k.note || '',
|
|
13510
|
-
}));
|
|
13511
|
-
return { ...d, ...(p ? { plain: p } : {}), ...(know.length ? { knowledge: know } : {}) };
|
|
15502
|
+
return { ...d, ...(p ? { plain: p } : {}) };
|
|
13512
15503
|
});
|
|
15504
|
+
// 知识条目挂在维度下:讲「为什么这样断」,与结论、依据形成三层。
|
|
15505
|
+
// 两条硬约束,都是为「读得下去」:
|
|
15506
|
+
// ① 一张卡全报告只挂一次——它讲的是「这条规则怎么用」,与挂在哪个维度无关;
|
|
15507
|
+
// 逐维重复会把五段正文冲散(1996 示例盘:29 条里 13 条是同一张卡的复读)。
|
|
15508
|
+
// ② 每维最多 3 条——正文是给人读的,注解是读法不是清单;没挂进正文的分歧条目
|
|
15509
|
+
// 仍会在文末「这套规则有多稳」里逐条列出(带原注),不丢信息。
|
|
15510
|
+
const KNOW_PER_DIM = 3;
|
|
15511
|
+
for (const d of dims.slice().sort((a, b) => rankOf(a.key) - rankOf(b.key))) {
|
|
15512
|
+
const know = knowledgeFor(r.system, d.key)
|
|
15513
|
+
.filter((k) => !seen.has(k.id))
|
|
15514
|
+
.slice(0, KNOW_PER_DIM)
|
|
15515
|
+
.map((k) => ({
|
|
15516
|
+
id: k.id,
|
|
15517
|
+
gist: k.gist,
|
|
15518
|
+
detail: k.detail,
|
|
15519
|
+
source: k.source,
|
|
15520
|
+
status: k.status,
|
|
15521
|
+
statusLabel: STATUS_LABEL[k.status] || k.status,
|
|
15522
|
+
note: k.note || '',
|
|
15523
|
+
}));
|
|
15524
|
+
for (const k of know) seen.add(k.id);
|
|
15525
|
+
if (know.length) d.knowledge = know;
|
|
15526
|
+
}
|
|
13513
15527
|
const texts = [
|
|
13514
15528
|
result.lead,
|
|
13515
15529
|
...dims.map((d) => [d.label, d.text, d.advice, d.plain, ...(d.knowledge || []).map((k) => k.detail)].filter(Boolean).join('')),
|
|
13516
15530
|
...(result.sections || []).map((x) => x.text),
|
|
13517
15531
|
].filter(Boolean);
|
|
13518
15532
|
|
|
13519
|
-
// 文末的诚实声明:把「各家有异说 /
|
|
15533
|
+
// 文末的诚实声明:把「各家有异说 / 还没做」的部分摊开,而不是藏在专业感里。
|
|
15534
|
+
// 「待核实」的在下面单独成段(附原注),这里只列已定论/有异说的,避免同一句话写两遍。
|
|
15535
|
+
// 已在上面展开过的只留条目名当索引;没展开的附原注,保证信息不丢。
|
|
13520
15536
|
const caveats = caveatsFor(r.system);
|
|
13521
|
-
const
|
|
13522
|
-
|
|
15537
|
+
const disputed = caveats.filter((k) => k.status !== 'todo');
|
|
15538
|
+
const caveatLine = disputed.length
|
|
15539
|
+
? disputed.map((k) => {
|
|
15540
|
+
const tag = STATUS_LABEL[k.status] || k.status;
|
|
15541
|
+
return `· ${k.gist}(${tag})${seen.has(k.id) || !k.note ? '' : `——${k.note}`}`;
|
|
15542
|
+
}).join('\n')
|
|
13523
15543
|
: '';
|
|
13524
15544
|
const secs = [...(result.sections || [])];
|
|
13525
15545
|
if (caveatLine) {
|
|
13526
15546
|
secs.push({
|
|
13527
15547
|
key: 'caveats',
|
|
13528
15548
|
label: '这套规则有多稳',
|
|
13529
|
-
text:
|
|
15549
|
+
text: `下列几条各家说法不一,本插件取其中一派并把分歧标出来,供你判断可信度(已在上面展开的只列条目,未展开的附原注):\n${caveatLine}`,
|
|
13530
15550
|
});
|
|
13531
15551
|
}
|
|
13532
15552
|
const todos = caveats.filter((k) => k.status === 'todo');
|
|
@@ -13826,30 +15846,54 @@ const SYSTEM_LABEL = {
|
|
|
13826
15846
|
* 客户端把这段文字写进对话输入框并提交,由对话里的模型基于盘面回答。
|
|
13827
15847
|
*
|
|
13828
15848
|
* @param {object} r compute 的结果(至少要带 system 与 summary)
|
|
13829
|
-
* @param {{question?:string, maxChars?:number}} [opts]
|
|
15849
|
+
* @param {{question?:string, maxChars?:number, interpret?:object}} [opts]
|
|
15850
|
+
* interpret 传面板已算好的解析对象(it)时,把其中的白话结论一并交给模型,
|
|
15851
|
+
* 让对话开场与面板里的「先答所问 / 说人话」是同一个口径;不传则不加这一段。
|
|
13830
15852
|
* @returns {{text:string, question:string, system:string, label:string, chars:number, truncated:boolean}}
|
|
13831
15853
|
*/
|
|
13832
15854
|
function askPrompt(r, opts = {}) {
|
|
13833
15855
|
const label = SYSTEM_LABEL[r && r.system] || (r && r.system) || '未知体系';
|
|
13834
15856
|
const asked = String((opts && opts.question) || '').trim();
|
|
13835
|
-
const question = asked || '
|
|
15857
|
+
const question = asked || '请先用一句白话讲清这张盘的主线,再指出最值得注意的一两处,并说明每处的具体依据。';
|
|
13836
15858
|
const limit = Number.isFinite(opts && opts.maxChars) && opts.maxChars >= 400 ? opts.maxChars : 3000;
|
|
13837
15859
|
const raw = String((r && r.summary) || '').trim();
|
|
13838
15860
|
const truncated = raw.length > limit;
|
|
13839
15861
|
const summary = truncated ? `${raw.slice(0, limit)}…(摘要已截断)` : raw;
|
|
13840
15862
|
|
|
15863
|
+
// 面板里已经算过一遍解析:直接取「直答 / 说人话」,避免模型开场另起一套说法
|
|
15864
|
+
const it = (opts && typeof opts.interpret === 'object' && opts.interpret)
|
|
15865
|
+
|| (r && typeof r.interpret === 'object' && r.interpret) || null;
|
|
15866
|
+
const answer = String((it && it.answer) || '').trim();
|
|
15867
|
+
const plain = String((it && it.plain) || '').trim();
|
|
15868
|
+
const draft = [];
|
|
15869
|
+
if (answer) draft.push(`直答:${answer}`);
|
|
15870
|
+
if (plain) draft.push(`说人话:${plain}`);
|
|
15871
|
+
|
|
13841
15872
|
const lines = [
|
|
13842
15873
|
'【命理追问】下面这张盘是命理插件刚排好的,请就着它回答我的问题;不用重新排盘,盘面字段已经够用。',
|
|
13843
15874
|
`体系:${label}`,
|
|
13844
15875
|
`所问:${question}`,
|
|
13845
15876
|
'',
|
|
15877
|
+
...(draft.length ? [
|
|
15878
|
+
'——开场结论(插件已按同一套规则算好,开场先沿用这句;措辞可改,口径别换)——',
|
|
15879
|
+
...draft,
|
|
15880
|
+
'',
|
|
15881
|
+
] : []),
|
|
13846
15882
|
'——盘面摘要——',
|
|
13847
15883
|
summary || '(这张盘没有摘要字段,请先让我重新排一次。)',
|
|
13848
15884
|
'',
|
|
13849
15885
|
'——回答要求——',
|
|
13850
|
-
'
|
|
13851
|
-
|
|
13852
|
-
|
|
15886
|
+
'读者不懂命理。按下面的骨架答;任何一句他看不懂,就算没写完:',
|
|
15887
|
+
draft.length
|
|
15888
|
+
? '1) 开头一句结论:先沿用上面的「开场结论」,再用一句不用术语的话说清这张盘的主线——只读这一句也该有收获;'
|
|
15889
|
+
: '1) 开头一句结论:不用术语,一句话说清这张盘的主线,只读这一句也该有收获;',
|
|
15890
|
+
'2) 判断最多两条,按重要性排序,每条分四行写:',
|
|
15891
|
+
' 盘面|只引盘面已有的字(具体的柱、宫或爻、字段名),不掺解释;',
|
|
15892
|
+
' 白话|把上一行的术语当场翻成日常话——调候 / 化气 / 通关 / 空亡 / 争合 这类词必须落地,一个词只翻一次,不连续堆三个以上;',
|
|
15893
|
+
' 倾向|说「更可能……」,讲清它在现实里大概意味着什么,用概率语气;',
|
|
15894
|
+
' 边界|这条在什么情况下不成立;盘面没给的,直接写「这盘里看不出来」;',
|
|
15895
|
+
'3) 收尾一句「如果只记一件事」:给一条能核对、能动手的观察点,并说明它出自上面哪条盘面依据;',
|
|
15896
|
+
'4) 别把传统说法当成已证实的事实:不下绝对断言,也不用「肯定」「绝对」这类词,更不写「格局很好」「运程不顺」这种没有信息的空话。',
|
|
13853
15897
|
];
|
|
13854
15898
|
const text = lines.join('\n');
|
|
13855
15899
|
return { text, question, system: (r && r.system) || '', label, chars: text.length, truncated };
|
|
@@ -14202,8 +16246,8 @@ return { matchEvent, rectifyBirth, RECTIFY_KINDS };
|
|
|
14202
16246
|
__mods.index = (function () {
|
|
14203
16247
|
// 统一入口:解析参数、分派到各体系、生成可读摘要
|
|
14204
16248
|
const { buildBazi } = __mods.bazi;
|
|
14205
|
-
const { buildLiuyao, tossLines, bodyLabels, yongshenOf, yongshenStrength, hexagramStrength, jinTuiPower } = __mods.liuyao;
|
|
14206
|
-
const { buildZiwei, BRIGHTNESS, flowOf, asOfParts } = __mods.ziwei;
|
|
16249
|
+
const { buildLiuyao, tossLines, bodyLabels, yongshenOf, yongshenStrength, fushenAccess, hexagramStrength, jinTuiPower } = __mods.liuyao;
|
|
16250
|
+
const { buildZiwei, BRIGHTNESS, flowOf, asOfParts, ZIWEI_SCHOOL_DEFAULTS } = __mods.ziwei;
|
|
14207
16251
|
const { drawTarot } = __mods.tarot;
|
|
14208
16252
|
const { buildMeihua } = __mods.meihua;
|
|
14209
16253
|
const { buildDaliuren } = __mods.daliuren;
|
|
@@ -14257,6 +16301,21 @@ function requireGender(value, who = '') {
|
|
|
14257
16301
|
throw fail('E_INPUT', `${who ? who + '的' : ''}gender 必须是 male 或 female${got};性别决定大运/大限顺逆,不能靠默认值`);
|
|
14258
16302
|
}
|
|
14259
16303
|
|
|
16304
|
+
const ZIWEI_SCHOOL_KEYS = [
|
|
16305
|
+
'brightnessSchool', 'gengYearSihua', 'tianmaSchool', 'tiankongSchool', 'jiekongSchool',
|
|
16306
|
+
'kuiyueSchool', 'tianshiTianshang', 'changshengSchool', 'lateZishi',
|
|
16307
|
+
];
|
|
16308
|
+
|
|
16309
|
+
/** 紫微流派参数原样透传;非法值交给引擎按默认口径回退 */
|
|
16310
|
+
function ziweiSchoolArgs(args) {
|
|
16311
|
+
const out = {};
|
|
16312
|
+
for (const key of ZIWEI_SCHOOL_KEYS) {
|
|
16313
|
+
if (args[key] !== undefined) out[key] = args[key];
|
|
16314
|
+
}
|
|
16315
|
+
if (args.schools && typeof args.schools === 'object') out.schools = args.schools;
|
|
16316
|
+
return out;
|
|
16317
|
+
}
|
|
16318
|
+
|
|
14260
16319
|
/** 解析 'YYYY-MM-DDTHH:mm' / 'YYYY-MM-DD HH:mm' / 'YYYY-MM-DD' */
|
|
14261
16320
|
function parseDateTime(text) {
|
|
14262
16321
|
if (typeof text !== 'string' || !text.trim()) {
|
|
@@ -14350,7 +16409,23 @@ function baziText(r) {
|
|
|
14350
16409
|
}
|
|
14351
16410
|
|
|
14352
16411
|
function ziweiText(r) {
|
|
14353
|
-
|
|
16412
|
+
// 闰月:日期按「闰X月」原样写;换算过起盘月时再附一句,免得把 21 日写成「闰5月21日」
|
|
16413
|
+
const rawMonth = r.lunar.monthRaw || r.lunar.month;
|
|
16414
|
+
const lunarText = `${r.lunar.year}年${r.lunar.isLeap ? `闰${rawMonth}` : r.lunar.month}月${r.lunar.day}日`
|
|
16415
|
+
+ (r.lunar.isLeap && r.lunar.month !== rawMonth ? `(按${r.lunar.month}月起盘)` : '');
|
|
16416
|
+
// 只在显式改动流派时补一行,默认盘不增加噪音
|
|
16417
|
+
const schoolLine = (() => {
|
|
16418
|
+
if (!r.schools) return '';
|
|
16419
|
+
const labels = {
|
|
16420
|
+
brightnessSchool: '亮度', gengYearSihua: '庚干四化', tianmaSchool: '天马', tiankongSchool: '天空',
|
|
16421
|
+
jiekongSchool: '截空', kuiyueSchool: '魁钺', tianshiTianshang: '天伤天使',
|
|
16422
|
+
changshengSchool: '长生', lateZishi: '晚子时',
|
|
16423
|
+
};
|
|
16424
|
+
const diff = Object.entries(labels)
|
|
16425
|
+
.filter(([key]) => r.schools[key] && r.schools[key] !== ZIWEI_SCHOOL_DEFAULTS[key])
|
|
16426
|
+
.map(([key, label]) => `${label} ${r.schools[key]}`);
|
|
16427
|
+
return diff.length ? `【流派】${diff.join(' ')}` : '';
|
|
16428
|
+
})();
|
|
14354
16429
|
const starText = (stars) => (stars.length
|
|
14355
16430
|
? stars.map((s) => `${s.name}${s.mutagen ? `化${s.mutagen}` : ''}`).join(' ')
|
|
14356
16431
|
: '—');
|
|
@@ -14401,6 +16476,7 @@ function ziweiText(r) {
|
|
|
14401
16476
|
`【命宫】${r.soul.branch}(${r.soul.ganzhi}·${r.soul.nayin}) 【身宫】${r.body.branch}(落${r.body.lands}) 【五行局】${r.bureau.name}`,
|
|
14402
16477
|
`【紫微】${r.ziwei} 【天府】${r.tianfu} 【命主】${r.lifeMaster} 【身主】${r.bodyMaster}`,
|
|
14403
16478
|
`【大限】${r.daxian.rule},${r.daxian.startAge}岁起 【小限】${r.xiaoxianRule.direction}`,
|
|
16479
|
+
schoolLine,
|
|
14404
16480
|
`【昌曲】文昌${r.changqu.wenchang.branch}(${r.changqu.wenchang.palace}${r.changqu.wenchang.mutagen ? '·化' + r.changqu.wenchang.mutagen : ''}) 文曲${r.changqu.wenqu.branch}(${r.changqu.wenqu.palace}${r.changqu.wenqu.mutagen ? '·化' + r.changqu.wenqu.mutagen : ''})`,
|
|
14405
16481
|
` ${r.changqu.relation} 入命三方:${r.changqu.inSoulSanfang ? '是' : '否'} 吸收面:${r.changqu.absorb.label}(${r.changqu.absorb.reason})`,
|
|
14406
16482
|
flyLine,
|
|
@@ -14557,6 +16633,11 @@ function liuyaoText(r) {
|
|
|
14557
16633
|
const m = strength.month && strength.month.branch ? `月建 ${strength.month.branch}(${strength.month.element}) ` : '';
|
|
14558
16634
|
out.push(`用神旺衰:${m}${strength.labels.join(' · ')}`);
|
|
14559
16635
|
}
|
|
16636
|
+
// 伏神出伏条件:只在用神不上卦时出现;只归条件档,不给应期
|
|
16637
|
+
const chufu = r.fushenAccess;
|
|
16638
|
+
if (chufu && Array.isArray(chufu.labels) && chufu.labels.length) {
|
|
16639
|
+
out.push(`伏神出伏:${chufu.labels.join(' · ')}`);
|
|
16640
|
+
}
|
|
14560
16641
|
} else {
|
|
14561
16642
|
out.push('用神:未取(未指明所问之事;用「询问方向」指定后即按六亲取用)');
|
|
14562
16643
|
}
|
|
@@ -14623,7 +16704,7 @@ function compute(args = {}) {
|
|
|
14623
16704
|
};
|
|
14624
16705
|
const asOf = checkAsOf(args.asOf);
|
|
14625
16706
|
const other = r.system === 'bazi'
|
|
14626
|
-
? buildZiwei({ ...common, leapAsNext: args.leapAsNext === true, asOf })
|
|
16707
|
+
? buildZiwei({ ...common, leapMonth: args.leapMonth, leapAsNext: args.leapAsNext === true, ...ziweiSchoolArgs(args), asOf })
|
|
14627
16708
|
: buildBazi({ ...common, lateZi: args.lateZi !== false, nowYear: asOf ? asOf.year : undefined });
|
|
14628
16709
|
r.cross = crossCheck(r.system === 'bazi' ? r : other, r.system === 'ziwei' ? r : other);
|
|
14629
16710
|
if (r.interpret) {
|
|
@@ -14676,8 +16757,9 @@ function compute(args = {}) {
|
|
|
14676
16757
|
function interpretText(i) {
|
|
14677
16758
|
if (!i) return '';
|
|
14678
16759
|
const out = [`【${i.title || '解析与详解'}】${i.ask && i.ask.echo ? i.ask.echo : ''}`];
|
|
14679
|
-
//
|
|
14680
|
-
|
|
16760
|
+
// 直答放在最前:先回答「你问的事」,再说依据,避免读者读到最后才知道结论;
|
|
16761
|
+
// 没填问题时就不该喊「答所问」——改为「先看结论」,否则是一句假话
|
|
16762
|
+
if (i.answer) out.push(`▶ ${i.ask && i.ask.question ? '先答所问' : '先看结论'}:${i.answer}`);
|
|
14681
16763
|
if (i.plain) out.push(`▶ 说人话:${i.plain}`);
|
|
14682
16764
|
if (i.lead) out.push(i.lead);
|
|
14683
16765
|
// 一页读懂:报告顶部的五条结论,先给读的人一个「整体形状」
|
|
@@ -14753,7 +16835,9 @@ function computeRaw(args = {}) {
|
|
|
14753
16835
|
const result = buildZiwei({
|
|
14754
16836
|
...dt,
|
|
14755
16837
|
gender: requireGender(args.gender),
|
|
16838
|
+
leapMonth: args.leapMonth,
|
|
14756
16839
|
leapAsNext: args.leapAsNext === true,
|
|
16840
|
+
...ziweiSchoolArgs(args),
|
|
14757
16841
|
longitude: typeof args.longitude === 'number' ? args.longitude : undefined,
|
|
14758
16842
|
address: typeof args.address === 'string' ? args.address : undefined,
|
|
14759
16843
|
geo: args.geo && typeof args.geo === 'object' ? args.geo : undefined,
|
|
@@ -14904,6 +16988,9 @@ function computeRaw(args = {}) {
|
|
|
14904
16988
|
if (ug.liuqin) {
|
|
14905
16989
|
const strength = yongshenStrength(result, ug, { monthBranch, dayBranch: result.dayGanZhi.branch });
|
|
14906
16990
|
if (strength) result.useGodStrength = strength;
|
|
16991
|
+
// 伏神出伏条件:飞伏生克叠月建日辰,只判条件、不出应期
|
|
16992
|
+
const chufu = fushenAccess(result, ug, { monthBranch, dayBranch: result.dayGanZhi.branch });
|
|
16993
|
+
if (chufu) result.fushenAccess = chufu;
|
|
14907
16994
|
}
|
|
14908
16995
|
if (args.seed !== undefined && args.seed !== null && args.seed !== '') result.seed = Number(args.seed);
|
|
14909
16996
|
return { ...result, ...(asOf ? { asOf } : {}), summary: liuyaoText(result) };
|
|
@@ -15004,7 +17091,17 @@ function computeRaw(args = {}) {
|
|
|
15004
17091
|
return { ...result, precision: dt.precision, summary: trendText(result) };
|
|
15005
17092
|
}
|
|
15006
17093
|
if (system === 'fengshui') {
|
|
15007
|
-
const action = args.action === 'advise' ? 'advise' : 'natal';
|
|
17094
|
+
const action = args.action === 'advise' ? 'advise' : args.action === 'xuankong' ? 'xuankong' : 'natal';
|
|
17095
|
+
if (action === 'xuankong') {
|
|
17096
|
+
const result = buildFengshui({
|
|
17097
|
+
action,
|
|
17098
|
+
sitting: args.sitting,
|
|
17099
|
+
facing: args.facing,
|
|
17100
|
+
...(args.period !== undefined ? { period: args.period } : {}),
|
|
17101
|
+
...(Number.isInteger(args.fortuneYear) ? { fortuneYear: args.fortuneYear } : {}),
|
|
17102
|
+
});
|
|
17103
|
+
return { ...result, summary: fengshuiText(result) };
|
|
17104
|
+
}
|
|
15008
17105
|
if (action === 'advise') {
|
|
15009
17106
|
const result = buildFengshui({
|
|
15010
17107
|
action,
|
|
@@ -15043,6 +17140,8 @@ function computeRaw(args = {}) {
|
|
|
15043
17140
|
givenName: args.givenName,
|
|
15044
17141
|
limit: args.limit,
|
|
15045
17142
|
charElements: args.charElements && typeof args.charElements === 'object' ? args.charElements : undefined,
|
|
17143
|
+
strokeOverrides: args.strokeOverrides && typeof args.strokeOverrides === 'object' ? args.strokeOverrides : undefined,
|
|
17144
|
+
surnameStrokes: args.surnameStrokes && typeof args.surnameStrokes === 'object' ? args.surnameStrokes : undefined,
|
|
15046
17145
|
...birth,
|
|
15047
17146
|
...(args.gender === 'male' || args.gender === 'female' ? { gender: args.gender } : {}),
|
|
15048
17147
|
...(args.datetime ? {
|
|
@@ -15221,6 +17320,25 @@ function trendText(r) {
|
|
|
15221
17320
|
|
|
15222
17321
|
/** 风水文本 */
|
|
15223
17322
|
function fengshuiText(r) {
|
|
17323
|
+
if (r.meta.action === 'xuankong') {
|
|
17324
|
+
const p = r.meta.period;
|
|
17325
|
+
const cell = (palace) => {
|
|
17326
|
+
const x = r.palaces.find((y) => y.palace === palace);
|
|
17327
|
+
return `${palace}${x.yun}/${x.shan}/${x.xiang}`;
|
|
17328
|
+
};
|
|
17329
|
+
const row = (names) => names.map(cell).join(' ');
|
|
17330
|
+
const w = r.wangShanWangXiang;
|
|
17331
|
+
return [
|
|
17332
|
+
`【玄空】${r.meta.periodLabel} 坐 ${r.meta.sitting} 向 ${r.meta.facing}`,
|
|
17333
|
+
`【入中】山盘 ${r.meta.shanCenter.star}${r.meta.shanCenter.name}(${r.meta.shanCenter.fly},${r.meta.shanCenter.basis});向盘 ${r.meta.xiangCenter.star}${r.meta.xiangCenter.name}(${r.meta.xiangCenter.fly},${r.meta.xiangCenter.basis})`,
|
|
17334
|
+
`【九宫】${row(['巽', '离', '坤'])}|${row(['震', '中', '兑'])}|${row(['艮', '坎', '乾'])}`,
|
|
17335
|
+
`【当运】山星${p}到${r.dangYun.shan.text};向星${p}到${r.dangYun.xiang.text}`,
|
|
17336
|
+
`【表法】${w.table.length ? w.table.join('、') : '无'};${w.note}`,
|
|
17337
|
+
`【合十】山星合十 ${r.heshi.shan.join('、') || '无'};向星合十 ${r.heshi.xiang.join('、') || '无'}`,
|
|
17338
|
+
...(r.meta.note ? [`※ ${r.meta.note}`] : []),
|
|
17339
|
+
`※ ${r.disclaimer}`,
|
|
17340
|
+
].join('\n');
|
|
17341
|
+
}
|
|
15224
17342
|
if (r.meta.action === 'advise') {
|
|
15225
17343
|
const match = r.mingMatch
|
|
15226
17344
|
? [`【命宅配】${r.mingMatch.text}`]
|
|
@@ -15253,7 +17371,11 @@ function nameText(r) {
|
|
|
15253
17371
|
if (r.action === 'generate') {
|
|
15254
17372
|
return [
|
|
15255
17373
|
`【候选名】姓 ${r.surname}(${r.gender},喜用 ${r.bazi.favorable.join('、')})${r.bazi.basis}`,
|
|
15256
|
-
...r.candidates.map((c) =>
|
|
17374
|
+
...r.candidates.map((c) => {
|
|
17375
|
+
const wu = c.wuge && c.wuge.available ? ` 五格 ${c.wuge.summary}` : '';
|
|
17376
|
+
const ph = c.phonetics && c.phonetics.available ? ` 音韵 ${c.phonetics.level}(${c.phonetics.tonePattern})` : '';
|
|
17377
|
+
return `${c.rank}. ${c.name} ${c.chars.map((x) => `${x.char}(${x.element})${x.meaning}`).join(' ')}${wu}${ph}`;
|
|
17378
|
+
}),
|
|
15257
17379
|
...r.notes.map((n) => `※ ${n}`),
|
|
15258
17380
|
].join('\n');
|
|
15259
17381
|
}
|
|
@@ -15266,10 +17388,20 @@ function nameText(r) {
|
|
|
15266
17388
|
: '';
|
|
15267
17389
|
return `· ${c.char}:${el}|${fit}|${c.meaning}${sug}`;
|
|
15268
17390
|
};
|
|
17391
|
+
const wu = r.wuge;
|
|
17392
|
+
const wugeLine = wu && wu.available
|
|
17393
|
+
? `【五格】${wu.strokes.map((x) => `${x.char}${x.strokes}画`).join('+')}|${wu.summary}|三才 ${wu.sancai.text}`
|
|
17394
|
+
: `【五格】${wu ? wu.reason : '未算'}`;
|
|
17395
|
+
const ph = r.phonetics;
|
|
17396
|
+
const phLine = ph && ph.available
|
|
17397
|
+
? `【音韵】${ph.chars.map((x) => `${x.char}${x.py}${x.tone}`).join(' ')}|声调 ${ph.tonePattern}|${ph.level}${ph.issues.length ? `:${ph.issues.map((i) => i.text).join(';')}` : ''}`
|
|
17398
|
+
: `【音韵】${ph ? ph.reason : '未算'}`;
|
|
15269
17399
|
return [
|
|
15270
17400
|
`【名字评估】${r.fullName}`,
|
|
15271
17401
|
...r.chars.map(charLine),
|
|
15272
17402
|
r.bazi ? `【八字】日主 ${r.bazi.dayMaster && r.bazi.dayMaster.stem ? `${r.bazi.dayMaster.stem}(${r.bazi.dayMaster.element})` : r.bazi.dayMaster},旺衰 ${r.bazi.strength.level}(${r.bazi.strength.score}),${r.bazi.basis}` : '',
|
|
17403
|
+
wugeLine,
|
|
17404
|
+
phLine,
|
|
15273
17405
|
`【结论】${r.verdict}`,
|
|
15274
17406
|
...r.notes.map((n) => `※ ${n}`),
|
|
15275
17407
|
].filter(Boolean).join('\n');
|
|
@@ -15497,7 +17629,8 @@ window.Engine = __mods.index;
|
|
|
15497
17629
|
原先 6px 上下内边距只有 31px 高,手机上是实打实的误触来源 */
|
|
15498
17630
|
.pp-modes label{min-height:44px;display:inline-flex;align-items:center;padding:3px 20px;font-size:12.5px;color:var(--muted);cursor:pointer;border-right:1px solid var(--line);user-select:none}
|
|
15499
17631
|
.pp-modes label:hover{background:var(--hover2)}
|
|
15500
|
-
.
|
|
17632
|
+
/* 提示条是「宫位可点」的唯一说明,--faint 在浅色下只有 2.3:1,换 --muted 才读得清 */
|
|
17633
|
+
.pp-soon{margin-left:auto;padding-right:10px;font-size:12px;color:var(--muted)}
|
|
15501
17634
|
.pp-body{display:none}
|
|
15502
17635
|
#ppm-ben:checked~.pp-body.ben,#ppm-da:checked~.pp-body.da,#ppm-ln:checked~.pp-body.ln{display:block}
|
|
15503
17636
|
#ppm-ben:checked~.pp-modes label[for="ppm-ben"],#ppm-da:checked~.pp-modes label[for="ppm-da"],#ppm-ln:checked~.pp-modes label[for="ppm-ln"]{background:var(--red);color:var(--on-accent)}
|
|
@@ -15821,7 +17954,6 @@ window.Engine = __mods.index;
|
|
|
15821
17954
|
.mp-it-ask .ask-q{font-weight:600;color:var(--ink)}
|
|
15822
17955
|
.mp-it-ask .ask-sep{color:var(--dimline);margin:0 7px}
|
|
15823
17956
|
.mp-it-ask .ask-d{color:var(--lu)}
|
|
15824
|
-
.mp-it-ask .ask-none{color:var(--muted);font-weight:400}
|
|
15825
17957
|
/* 按询问方向提到最前的那一条 */
|
|
15826
17958
|
.mp-it-focus{margin-left:6px;font-size:12px;color:var(--lu);border:1px solid rgba(var(--lu-rgb),.35);border-radius:999px;padding:1px 9px;font-family:system-ui,sans-serif}
|
|
15827
17959
|
.mp-it-dim.focus{background:linear-gradient(90deg,rgba(var(--lu-rgb),.06),transparent 60%);border-left:2px solid var(--lu);padding-left:10px}
|
|
@@ -15869,6 +18001,18 @@ window.Engine = __mods.index;
|
|
|
15869
18001
|
.mp-it-sec{margin-bottom:11px}
|
|
15870
18002
|
.mp-it-sh{font-size:13px;font-weight:700;color:var(--lu);letter-spacing:.06em;margin-bottom:4px}
|
|
15871
18003
|
.mp-it-stext{font-size:13px;line-height:1.9;color:var(--ink2);text-align:justify}
|
|
18004
|
+
/* 分节按「吉 / 留意 / 忌」分层:只改标题色与左侧细线,不换版式 */
|
|
18005
|
+
.mp-it-sec.tone-good,.mp-it-sec.tone-watch,.mp-it-sec.tone-bad{padding-left:8px}
|
|
18006
|
+
.mp-it-sec.tone-good{border-left:2px solid var(--lu)}
|
|
18007
|
+
.mp-it-sec.tone-watch{border-left:2px solid var(--quan)}
|
|
18008
|
+
.mp-it-sec.tone-bad{border-left:2px solid var(--red)}
|
|
18009
|
+
.mp-it-sec.tone-good .mp-it-sh{color:var(--lu)}
|
|
18010
|
+
.mp-it-sec.tone-watch .mp-it-sh{color:var(--quan)}
|
|
18011
|
+
.mp-it-sec.tone-bad .mp-it-sh{color:var(--red)}
|
|
18012
|
+
/* 长节按行分段:一行一段,行内**加粗**只强化术语,不引入其它标记 */
|
|
18013
|
+
.mp-it-p{margin:0 0 5px}
|
|
18014
|
+
.mp-it-p:last-child{margin-bottom:0}
|
|
18015
|
+
.mp-it-p b{color:var(--ink);font-weight:700;letter-spacing:.02em}
|
|
15872
18016
|
/* 一页读懂:报告顶部五条结论 */
|
|
15873
18017
|
.mp-outline{margin:12px 16px 0;border:1px solid var(--line);border-left:3px solid var(--lu);border-radius:8px;background:var(--card);padding:10px 12px}
|
|
15874
18018
|
.mp-outline-h{font-size:12px;font-weight:700;letter-spacing:.12em;color:var(--lu);margin-bottom:6px;font-family:system-ui,sans-serif}
|
|
@@ -16004,8 +18148,61 @@ window.Engine = __mods.index;
|
|
|
16004
18148
|
.mp-nm-c:last-child{border-bottom:0}
|
|
16005
18149
|
.mp-nm-c b{font-family:var(--fx);font-size:16.5px;font-weight:600;white-space:nowrap;letter-spacing:.5px}
|
|
16006
18150
|
.mp-nm-c em{font-style:normal;font-size:11.5px;line-height:1.7;color:var(--muted);font-family:var(--sans)}
|
|
18151
|
+
.mp-nm-wu{margin-top:10px;border-top:1px solid var(--hair);padding-top:9px}
|
|
18152
|
+
.mp-nm-wu-h{display:flex;align-items:baseline;gap:9px;font-size:12.5px;color:var(--ink2)}
|
|
18153
|
+
.mp-nm-wu-h b{font-weight:700;letter-spacing:.18em}
|
|
18154
|
+
.mp-nm-wu-h i{font-style:normal;font-size:11px;color:var(--faint)}
|
|
18155
|
+
.mp-nm-wu-rows{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px;margin:7px 0 6px}
|
|
18156
|
+
.mp-nm-wu-c{border:1px solid var(--line);border-radius:6px;padding:5px 6px;text-align:center;background:var(--band)}
|
|
18157
|
+
.mp-nm-wu-c em{display:block;font-style:normal;font-size:10.5px;color:var(--muted);letter-spacing:.06em}
|
|
18158
|
+
.mp-nm-wu-c b{display:block;font-size:16px;line-height:1.35;color:var(--ink);font-family:var(--sans)}
|
|
18159
|
+
.mp-nm-wu-c i{display:block;font-style:normal;font-size:10px;line-height:1.5;color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
|
18160
|
+
.mp-nm-wu-c.is-ok{border-color:var(--lu)}
|
|
18161
|
+
.mp-nm-wu-c.is-ok b{color:var(--lu)}
|
|
18162
|
+
.mp-nm-wu-c.is-half{border-color:var(--quan)}
|
|
18163
|
+
.mp-nm-wu-c.is-half b{color:var(--quan)}
|
|
18164
|
+
.mp-nm-wu-c.is-bad b{color:var(--ji)}
|
|
18165
|
+
.mp-nm-ph{margin-top:9px;font-size:12.5px;line-height:1.8;color:var(--ink2)}
|
|
18166
|
+
.mp-nm-ph b{font-weight:700;letter-spacing:.18em;margin-right:6px}
|
|
18167
|
+
.mp-nm-ph em{font-style:normal;color:var(--muted);margin-left:6px;font-family:var(--sans);font-size:11.5px}
|
|
18168
|
+
.mp-nm-ph-lv{font-size:11px;border-radius:999px;padding:0 7px;line-height:1.7;border:1px solid var(--line);color:var(--muted)}
|
|
18169
|
+
.mp-nm-ph-lv.ok{color:var(--lu);border-color:var(--lu)}
|
|
18170
|
+
.mp-nm-ph-lv.warn{color:var(--quan);border-color:var(--quan)}
|
|
18171
|
+
.mp-nm-ph-lv.bad{color:var(--ji);border-color:var(--ji)}
|
|
18172
|
+
.mp-nm-ph-i{display:inline-block;margin:2px 6px 0 0;font-size:11.5px;color:var(--muted)}
|
|
18173
|
+
.mp-nm-ph-i:before{content:'·';margin-right:3px;color:var(--faint)}
|
|
16007
18174
|
@media print{.mp-nm{break-inside:avoid}}
|
|
16008
18175
|
.mp-quick-pre{margin:0;white-space:pre-wrap;word-break:break-word;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;line-height:1.9;color:var(--ink2)}
|
|
18176
|
+
/* —— 风水卡片:八宅八向 / 门主灶 / 玄空九宫 ——
|
|
18177
|
+
此前风水结果只是一段等宽文本,「巽8/6/3」要靠读的人自己脑补方位。
|
|
18178
|
+
现在摆成后天八卦 3×3:玄空每宫依次是运/山/向三星,当运高亮;
|
|
18179
|
+
八宅每宫是星名与吉凶。颜色只取共享变量,深色与打印不另写规则。 */
|
|
18180
|
+
.mp-fs .mp-quick-h{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
|
|
18181
|
+
.mp-fs-sub{font-size:11.5px;color:var(--muted);font-family:var(--sans)}
|
|
18182
|
+
.mp-fs-chips{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 10px}
|
|
18183
|
+
.mp-fs-chip{font-size:11.5px;line-height:1.8;border:1px solid var(--line);border-radius:999px;padding:0 9px;color:var(--muted);background:var(--band);font-family:var(--sans)}
|
|
18184
|
+
.mp-fs-chip.ok{color:var(--lu);border-color:color-mix(in srgb,var(--lu) 40%,var(--line))}
|
|
18185
|
+
.mp-fs-key{margin:0 0 6px;font-size:11px;color:var(--faint);font-family:var(--sans)}
|
|
18186
|
+
.mp-fs-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;background:var(--line);border:1px solid var(--line);border-radius:6px;overflow:hidden;margin-bottom:10px}
|
|
18187
|
+
.mp-fs-cell{background:var(--card);padding:7px 9px;display:flex;flex-direction:column;gap:6px;min-height:56px}
|
|
18188
|
+
.mp-fs-cell.center{background:var(--band)}
|
|
18189
|
+
.mp-fs-top{display:flex;align-items:baseline;gap:6px;min-width:0}
|
|
18190
|
+
.mp-fs-gua{font-family:var(--fx);font-size:15px;font-weight:700;line-height:1;color:var(--ink)}
|
|
18191
|
+
.mp-fs-dir{font-size:10.5px;color:var(--muted);font-family:var(--sans);white-space:nowrap}
|
|
18192
|
+
.mp-fs-star{margin-left:auto;font-size:12px;color:var(--ink2);font-family:var(--sans);white-space:nowrap}
|
|
18193
|
+
.mp-fs-star em{font-style:normal;font-size:10px;margin-left:4px;padding:0 5px;border:1px solid currentColor;border-radius:999px;line-height:1.6;vertical-align:1px}
|
|
18194
|
+
.mp-fs-star em.ok{color:var(--lu)}
|
|
18195
|
+
.mp-fs-star em.bad{color:var(--ji)}
|
|
18196
|
+
.mp-fs-nums{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px;font-family:var(--sans);font-variant-numeric:tabular-nums}
|
|
18197
|
+
.mp-fs-nums span{text-align:center;font-size:13px;line-height:1.7;border:1px solid var(--hair);border-radius:4px;color:var(--ink2)}
|
|
18198
|
+
.mp-fs-nums span.on{background:var(--tri);border-color:var(--quan);color:var(--quan);font-weight:700}
|
|
18199
|
+
.mp-fs-facts{margin:0;display:flex;flex-direction:column;gap:4px}
|
|
18200
|
+
.mp-fs-row{display:grid;grid-template-columns:64px minmax(0,1fr);gap:8px;font-size:12px;line-height:1.75}
|
|
18201
|
+
.mp-fs-row dt{margin:0;color:var(--muted);font-family:var(--sans)}
|
|
18202
|
+
.mp-fs-row dd{margin:0;color:var(--ink2);word-break:break-word}
|
|
18203
|
+
.mp-fs-note{margin-top:9px;padding-top:8px;border-top:1px dashed var(--line);font-size:11px;line-height:1.7;color:var(--muted)}
|
|
18204
|
+
@media print{.mp-fs{break-inside:avoid}}
|
|
18205
|
+
@media (max-width:420px){.mp-fs-cell{padding:6px}.mp-fs-gua{font-size:14px}.mp-fs-nums span{font-size:12px}}
|
|
16009
18206
|
/* —— 十六型人格卡片 ——
|
|
16010
18207
|
旧版是「四行细条 + 段落堆叠」:字小、无层级,看着像一份导出的文档。
|
|
16011
18208
|
现在按「类型抬头 → 四维瓦片 → 一句 → 优势/留意 → 功能链 → 场景段」分层,
|
|
@@ -16449,7 +18646,7 @@ window.Engine = __mods.index;
|
|
|
16449
18646
|
return `<div class="pp-center">
|
|
16450
18647
|
${mode}
|
|
16451
18648
|
<div class="ct-t2">公历 ${r.input.year}-${String(r.input.month).padStart(2, '0')}-${String(r.input.day).padStart(2, '0')} ${String(r.input.hour).padStart(2, '0')}:${String(r.input.minute).padStart(2, '0')}</div>
|
|
16452
|
-
<div class="ct-t2">农历 ${r.lunar.year}年${r.lunar.isLeap ?
|
|
18649
|
+
<div class="ct-t2">农历 ${r.lunar.year}年${r.lunar.isLeap ? `闰${r.lunar.monthRaw || r.lunar.month}` : r.lunar.month}月${r.lunar.day}日${r.hourBranch}时${r.lunar.isLeap && r.lunar.monthRaw && r.lunar.month !== r.lunar.monthRaw ? `(按${r.lunar.month}月起盘)` : ''}</div>
|
|
16453
18650
|
${sizhuOf(r) ? `<div class="ct-t3">${sizhuOf(r)}</div>` : ''}
|
|
16454
18651
|
<div class="ct-t4">命主 ${r.lifeMaster} 身主 ${r.bodyMaster}</div>
|
|
16455
18652
|
<div class="ct-t4">命宫 ${r.soul.branch} 身宫 ${r.body.branch} 五行局 ${r.bureau.name}</div>
|
|
@@ -16726,6 +18923,14 @@ window.Engine = __mods.index;
|
|
|
16726
18923
|
return `<span class="pp-chip ${cls}">${esc(l)}</span>`;
|
|
16727
18924
|
}).join('')}</div>`
|
|
16728
18925
|
: '';
|
|
18926
|
+
// 伏神出伏:用神不上卦时才出现;只摆条件档,不写应期
|
|
18927
|
+
const fu = r.fushenAccess && Array.isArray(r.fushenAccess.labels) ? r.fushenAccess : null;
|
|
18928
|
+
const fushenRow = fu && fu.labels.length
|
|
18929
|
+
? `<div class="pp-chips">${fu.labels.map((l) => {
|
|
18930
|
+
const cls = /可出/.test(l) ? 'ok' : /受压难出|有助有压/.test(l) ? 'warn' : '';
|
|
18931
|
+
return `<span class="pp-chip ${cls}">伏神${esc(l)}</span>`;
|
|
18932
|
+
}).join('')}</div>`
|
|
18933
|
+
: '';
|
|
16729
18934
|
// 化进/化退的力重:方向之外再叠月建日辰,单列一排,免与卦体标签混读
|
|
16730
18935
|
const jp = r.jinTuiPower && Array.isArray(r.jinTuiPower.labels) ? r.jinTuiPower : null;
|
|
16731
18936
|
const jinRow = jp && jp.labels.length
|
|
@@ -16749,6 +18954,7 @@ window.Engine = __mods.index;
|
|
|
16749
18954
|
${bodyRow}
|
|
16750
18955
|
${useRow}
|
|
16751
18956
|
${strengthRow}
|
|
18957
|
+
${fushenRow}
|
|
16752
18958
|
${jinRow}
|
|
16753
18959
|
${hexRow}
|
|
16754
18960
|
</div>`;
|
|
@@ -17364,7 +19570,20 @@ window.Engine = __mods.index;
|
|
|
17364
19570
|
const head = (title, sub) => `<div class="mp-nm-h"><b>${esc(title)}</b>${sub ? `<i>${esc(sub)}</i>` : ''}</div>`;
|
|
17365
19571
|
if (r.action === 'generate') {
|
|
17366
19572
|
const fav = r.bazi && r.bazi.favorable ? r.bazi.favorable.join('、') : '';
|
|
17367
|
-
const cands = (r.candidates || []).map((c) =>
|
|
19573
|
+
const cands = (r.candidates || []).map((c) => {
|
|
19574
|
+
const wu = c.wuge && c.wuge.available
|
|
19575
|
+
? (() => {
|
|
19576
|
+
const good = c.wuge.rows.filter((x) => x.level === '吉').length;
|
|
19577
|
+
const bad = c.wuge.rows.filter((x) => x.level === '凶').length;
|
|
19578
|
+
const cls = bad === 0 && good >= 4 ? ' ok' : bad >= 2 ? ' no' : '';
|
|
19579
|
+
return `<span class="mp-nm-fit${cls}" title="${esc(c.wuge.summary)}">五格 ${good}/5 吉</span>`;
|
|
19580
|
+
})()
|
|
19581
|
+
: '';
|
|
19582
|
+
const ph = c.phonetics && c.phonetics.available
|
|
19583
|
+
? `<span class="mp-nm-fit${c.phonetics.level === '拗口' ? ' no' : c.phonetics.level === '顺口' ? ' ok' : ''}" title="${esc((c.phonetics.issues || []).map((x) => x.text).join(';'))}">${esc(c.phonetics.level)}</span>`
|
|
19584
|
+
: '';
|
|
19585
|
+
return `<div class="mp-nm-c"><b>${esc(c.name)}</b><span class="mp-nm-els">${c.chars.map((x) => elChip(x.element)).join('')}${wu}${ph}</span><em>${esc(c.chars.map((x) => x.char + '·' + x.meaning).join(' '))}</em></div>`;
|
|
19586
|
+
}).join('');
|
|
17368
19587
|
return `<section class="mp-nm" aria-label="候选名">
|
|
17369
19588
|
${head('候选名', `姓 ${r.surname}(${r.gender})${fav ? ` 喜用 ${fav}` : ''}`)}
|
|
17370
19589
|
<div class="mp-nm-cand">${cands}</div>
|
|
@@ -17387,10 +19606,24 @@ window.Engine = __mods.index;
|
|
|
17387
19606
|
? `<div class="mp-nm-m">八字:${esc(r.bazi.dayMaster && r.bazi.dayMaster.stem ? `${r.bazi.dayMaster.stem}(${r.bazi.dayMaster.element})` : String(r.bazi.dayMaster || ''))} ${esc(r.bazi.strength ? `${r.bazi.strength.level}(${r.bazi.strength.score})` : '')} 喜用 ${esc((r.bazi.favorable || []).join('、'))}</div>
|
|
17388
19607
|
<div class="mp-nm-m">${esc(r.bazi.basis || '')}</div>`
|
|
17389
19608
|
: '';
|
|
19609
|
+
const LV = (x) => (x === '吉' ? 'is-ok' : x === '半吉' ? 'is-half' : 'is-bad');
|
|
19610
|
+
const wu = r.wuge && r.wuge.available
|
|
19611
|
+
? `<div class="mp-nm-wu">
|
|
19612
|
+
<div class="mp-nm-wu-h"><b>五格</b><i>康熙笔画 · 通行本 81 数理</i></div>
|
|
19613
|
+
<div class="mp-nm-wu-rows">${r.wuge.rows.map((x) => `<div class="mp-nm-wu-c ${LV(x.level)}"><em>${esc(x.key)}</em><b>${x.strokes}</b><i>${esc(`${x.level} · ${x.name}`)}</i></div>`).join('')}</div>
|
|
19614
|
+
<div class="mp-nm-m">笔画:${r.wuge.strokes.map((x) => `${esc(x.char)}${x.strokes}${x.source === 'user' ? '(指定)' : ''}`).join(' + ')}</div>
|
|
19615
|
+
<div class="mp-nm-m">三才:${esc(r.wuge.sancai.text)}</div>
|
|
19616
|
+
</div>`
|
|
19617
|
+
: `<div class="mp-nm-wu"><div class="mp-nm-wu-h"><b>五格</b><i>这一版算不了</i></div><div class="mp-nm-m">${esc(r.wuge ? r.wuge.reason : '未算')}</div></div>`;
|
|
19618
|
+
const ph = r.phonetics && r.phonetics.available
|
|
19619
|
+
? `<div class="mp-nm-ph"><b>音韵</b><span class="mp-nm-ph-lv${r.phonetics.level === '顺口' ? ' ok' : r.phonetics.level === '拗口' ? ' bad' : ' warn'}">${esc(r.phonetics.level)}</span><em>${esc(r.phonetics.chars.map((x) => `${x.py}${x.tone}`).join(' '))} 声调 ${esc(r.phonetics.tonePattern)}</em>${(r.phonetics.issues || []).map((x) => `<span class="mp-nm-ph-i">${esc(x.text)}</span>`).join('')}</div>`
|
|
19620
|
+
: `<div class="mp-nm-ph"><b>音韵</b><em>${esc(r.phonetics ? r.phonetics.reason : '未算')}</em></div>`;
|
|
17390
19621
|
return `<section class="mp-nm" aria-label="名字评估">
|
|
17391
19622
|
${head(r.fullName || '', `字库 ${r.stats && r.stats.libSize ? r.stats.libSize : ''} 字${r.stats && r.stats.unknown ? ` 未收录 ${r.stats.unknown}` : ''}`)}
|
|
17392
19623
|
${rows}
|
|
17393
19624
|
${bz}
|
|
19625
|
+
${wu}
|
|
19626
|
+
${ph}
|
|
17394
19627
|
<div class="mp-nm-verd">${esc(r.verdict || '')}</div>
|
|
17395
19628
|
<div class="mp-nm-note">${(r.notes || []).map((n) => '※ ' + esc(n)).join('<br>')}</div>
|
|
17396
19629
|
</section>`;
|
|
@@ -17575,21 +19808,27 @@ window.Engine = __mods.index;
|
|
|
17575
19808
|
</table></div>
|
|
17576
19809
|
</div>`).join('')}</div>`
|
|
17577
19810
|
: '';
|
|
19811
|
+
// 分节正文先转义再认两种轻标记:换行分段、**术语**加粗——不引入 HTML 注入面
|
|
19812
|
+
const richText = (text) => String(text || '')
|
|
19813
|
+
.split('\n')
|
|
19814
|
+
.map((line) => `<div class="mp-it-p">${esc(line).replace(/\*\*([^*]+)\*\*/g, '<b>$1</b>')}</div>`)
|
|
19815
|
+
.join('');
|
|
17578
19816
|
const secs = (it.sections && it.sections.length)
|
|
17579
|
-
? `<div class="mp-it-secs">${it.sections.map((s) => `<div class="mp-it-sec" id="mp-sec-${esc(s.key)}">
|
|
19817
|
+
? `<div class="mp-it-secs">${it.sections.map((s) => `<div class="mp-it-sec${s.tone ? ` tone-${esc(s.tone)}` : ''}" id="mp-sec-${esc(s.key)}">
|
|
17580
19818
|
<div class="mp-it-sh">${esc(s.label)}</div>
|
|
17581
|
-
<div class="mp-it-stext">${
|
|
19819
|
+
<div class="mp-it-stext">${richText(s.text)}</div>
|
|
17582
19820
|
</div>`).join('')}</div>`
|
|
17583
19821
|
: '';
|
|
17584
19822
|
const tags = [it.systemLabel, MT_LABEL[it.moduleType] || it.moduleType].filter(Boolean);
|
|
17585
19823
|
// 回显所问之事与询问方向:先让用户确认解读是围绕什么展开的
|
|
17586
19824
|
const ask = it.ask;
|
|
17587
|
-
//
|
|
17588
|
-
const
|
|
17589
|
-
|
|
19825
|
+
// 只有真的填了问题、或选了非「综合」方向时才回显;没填就只报方向,不喊「(未填写)」
|
|
19826
|
+
const askQ = ask && ask.question ? esc(ask.question) : '';
|
|
19827
|
+
const askLine = ask && (askQ || (ask.direction && ask.direction !== 'general'))
|
|
19828
|
+
? `<div class="mp-it-ask">${askQ ? `<span class="ask-q">问题:${askQ}</span><span class="ask-sep">|</span>` : ''}<span class="ask-d">询问方向:${esc(ask.directionLabel || '综合')}</span></div>`
|
|
17590
19829
|
: '';
|
|
17591
|
-
//
|
|
17592
|
-
const answer = it.answer ? `<div class="mp-it-ans"><b
|
|
19830
|
+
// 直答与说人话:放在正文最前,先给结论再给推导;没问事时不能写「先答所问」
|
|
19831
|
+
const answer = it.answer ? `<div class="mp-it-ans"><b>${askQ ? '先答所问' : '先看结论'}</b>${esc(it.answer)}</div>` : '';
|
|
17593
19832
|
const plain = it.plain ? `<div class="mp-it-plain"><b>说人话</b>${esc(it.plain)}</div>` : '';
|
|
17594
19833
|
const fu = (it.followups && it.followups.length)
|
|
17595
19834
|
? `<div class="mp-it-fu"><b>还可以这样追问</b><ul>${it.followups.map((q) => `<li>${esc(q)}</li>`).join('')}</ul></div>`
|
|
@@ -17733,6 +19972,97 @@ window.Engine = __mods.index;
|
|
|
17733
19972
|
</section>`;
|
|
17734
19973
|
};
|
|
17735
19974
|
|
|
19975
|
+
// ── 风水:八宅八向 / 门主灶 / 玄空九宫 ──────────────────────────
|
|
19976
|
+
// 与 quickHTML 的「一段文本」不同,这里把八向与九宫摆成方位网格。
|
|
19977
|
+
// 数值全部来自引擎结果(palaces / luckyDirections / houseStars),前端不推导。
|
|
19978
|
+
const FS_GRID = [['巽', '离', '坤'], ['震', '中', '兑'], ['艮', '坎', '乾']];
|
|
19979
|
+
const FS_DIR = { 坎: '正北', 艮: '东北', 震: '正东', 巽: '东南', 离: '正南', 坤: '西南', 兑: '正西', 乾: '西北', 中: '中宫' };
|
|
19980
|
+
const FS_LUCKY = ['生气', '延年', '天医', '伏位'];
|
|
19981
|
+
const fsChip = (text, cls) => `<span class="mp-fs-chip${cls ? ' ' + cls : ''}">${esc(text)}</span>`;
|
|
19982
|
+
const fsCell = (gua, head, body) => `<div class="mp-fs-cell${gua === '中' ? ' center' : ''}">`
|
|
19983
|
+
+ `<div class="mp-fs-top"><span class="mp-fs-gua">${esc(gua)}</span><span class="mp-fs-dir">${esc(FS_DIR[gua] || '')}</span>${head || ''}</div>`
|
|
19984
|
+
+ (body || '') + '</div>';
|
|
19985
|
+
const fsFacts = (rows) => (rows.length
|
|
19986
|
+
? `<dl class="mp-fs-facts">${rows.map(([k, v]) => `<div class="mp-fs-row"><dt>${esc(k)}</dt><dd>${esc(v)}</dd></div>`).join('')}</dl>`
|
|
19987
|
+
: '');
|
|
19988
|
+
const fsSection = (title, sub, chips, grid, facts, notes) => `<section class="mp-quick mp-fs" aria-label="风水结果">`
|
|
19989
|
+
+ `<div class="mp-quick-h"><b>${esc(title)}</b>${sub ? `<span class="mp-fs-sub">${esc(sub)}</span>` : ''}</div>`
|
|
19990
|
+
+ (chips.length ? `<div class="mp-fs-chips">${chips.join('')}</div>` : '')
|
|
19991
|
+
+ grid + facts
|
|
19992
|
+
+ (notes.filter(Boolean).map((x) => `<div class="mp-fs-note">${esc(x)}</div>`).join(''))
|
|
19993
|
+
+ '</section>';
|
|
19994
|
+
/** 八宅八向:按后天八卦方位摆格,吉凶由引擎给的星名判定 */
|
|
19995
|
+
const fsBaguaGrid = (list, aria) => `<div class="mp-fs-grid" role="group" aria-label="${esc(aria)}">`
|
|
19996
|
+
+ FS_GRID.map((row) => row.map((g) => {
|
|
19997
|
+
const x = list.find((y) => y && y.palace === g);
|
|
19998
|
+
if (!x) return fsCell(g, '', '');
|
|
19999
|
+
const good = FS_LUCKY.includes(x.star);
|
|
20000
|
+
const head = `<span class="mp-fs-star"${x.role ? ` title="${esc(x.role)}"` : ''}>${esc(x.star)}`
|
|
20001
|
+
+ `<em class="${good ? 'ok' : 'bad'}">${good ? '吉' : '凶'}</em></span>`;
|
|
20002
|
+
return fsCell(g, head, '');
|
|
20003
|
+
}).join('')).join('') + '</div>';
|
|
20004
|
+
|
|
20005
|
+
function fsXuankong(r, m) {
|
|
20006
|
+
const period = m.period;
|
|
20007
|
+
const by = {};
|
|
20008
|
+
for (const p of r.palaces || []) by[p.palace] = p;
|
|
20009
|
+
const grid = `<div class="mp-fs-key">每宫依次为 <b>运</b>/<b>山</b>/<b>向</b> 三星;底色高亮=当运(${esc(period)}运)</div>`
|
|
20010
|
+
+ '<div class="mp-fs-grid" role="group" aria-label="玄空九宫(运/山/向)">'
|
|
20011
|
+
+ FS_GRID.map((row) => row.map((g) => {
|
|
20012
|
+
const p = by[g];
|
|
20013
|
+
if (!p) return fsCell(g, '', '');
|
|
20014
|
+
const nums = [['运', p.yun], ['山', p.shan], ['向', p.xiang]]
|
|
20015
|
+
.map(([k, v]) => `<span class="${v === period ? 'on' : ''}" title="${esc(k)}星 ${esc(v)}">${esc(v)}</span>`).join('');
|
|
20016
|
+
return fsCell(g, '', `<div class="mp-fs-nums">${nums}</div>`);
|
|
20017
|
+
}).join('')).join('') + '</div>';
|
|
20018
|
+
const w = r.wangShanWangXiang || {};
|
|
20019
|
+
const chips = [
|
|
20020
|
+
fsChip(`山盘 ${m.shanCenter.star}${m.shanCenter.name} · ${m.shanCenter.fly}`),
|
|
20021
|
+
fsChip(`向盘 ${m.xiangCenter.star}${m.xiangCenter.name} · ${m.xiangCenter.fly}`),
|
|
20022
|
+
fsChip(w.byChart ? '盘面:到山到向' : '盘面:未到山到向', w.byChart ? 'ok' : ''),
|
|
20023
|
+
fsChip(w.byTable ? '表法:在列' : '表法:未列', w.byTable ? 'ok' : ''),
|
|
20024
|
+
];
|
|
20025
|
+
const facts = fsFacts([
|
|
20026
|
+
['入中', `山盘 ${m.shanCenter.star}${m.shanCenter.name}(${m.shanCenter.fly},${m.shanCenter.basis});`
|
|
20027
|
+
+ `向盘 ${m.xiangCenter.star}${m.xiangCenter.name}(${m.xiangCenter.fly},${m.xiangCenter.basis})`],
|
|
20028
|
+
['当运', `山星${period}落 ${r.dangYun.shan.text};向星${period}落 ${r.dangYun.xiang.text}`],
|
|
20029
|
+
['合十', `山星:${(r.heshi.shan || []).join('、') || '无'};向星:${(r.heshi.xiang || []).join('、') || '无'}`],
|
|
20030
|
+
['表法', `${w.note || ''}${(w.table || []).length ? ` 本运所列:${w.table.join('、')}。` : ' 本运表法无局。'}`],
|
|
20031
|
+
]);
|
|
20032
|
+
return fsSection('玄空下卦', `${m.periodLabel} · 坐${m.sitting} · 向${m.facing}`, chips, grid, facts, [m.note, r.disclaimer]);
|
|
20033
|
+
}
|
|
20034
|
+
|
|
20035
|
+
function fsNatal(r, m) {
|
|
20036
|
+
const mg = r.mingGua || {};
|
|
20037
|
+
const grid = fsBaguaGrid([...(r.luckyDirections || []), ...(r.unluckyDirections || [])], '八宅八向(吉凶)');
|
|
20038
|
+
const chips = [fsChip(mg.compatible || '—'), fsChip(`${m.gender}命 · ${m.guaYear} 年立春界`)];
|
|
20039
|
+
const rows = [];
|
|
20040
|
+
if (r.yearlyFlying) {
|
|
20041
|
+
const fy = r.yearlyFlying;
|
|
20042
|
+
rows.push(['年紫白', `${fy.centerName}入中;${fy.palaces.filter((p) => p.palace !== '中')
|
|
20043
|
+
.map((p) => `${p.palace}${p.name}`).join('、')}`]);
|
|
20044
|
+
}
|
|
20045
|
+
return fsSection('八宅命卦', `${mg.num}${mg.gua}(${mg.group})· ${mg.direction}`, chips, grid, fsFacts(rows), [m.note, r.disclaimer]);
|
|
20046
|
+
}
|
|
20047
|
+
|
|
20048
|
+
function fsAdvise(r, m) {
|
|
20049
|
+
const lay = r.layout || {};
|
|
20050
|
+
const grid = fsBaguaGrid(r.houseStars || [], '宅卦八向(吉凶)');
|
|
20051
|
+
const chips = [fsChip(`${m.houseGua}宅 · ${m.houseGroup}`), fsChip(`坐${m.sitting}`), fsChip(`向${m.facing}`)];
|
|
20052
|
+
const rows = [['门', lay.door], ['灶', lay.stove], ['床', lay.bed], ['厕', lay.toilet]];
|
|
20053
|
+
if (r.mingMatch) rows.push(['命宅配', r.mingMatch.text]);
|
|
20054
|
+
return fsSection('门主灶', `${m.houseGua}宅 · 坐${m.sitting} · 向${m.facing}`, chips, grid, fsFacts(rows),
|
|
20055
|
+
[m.birthNote, r.disclaimer]);
|
|
20056
|
+
}
|
|
20057
|
+
|
|
20058
|
+
pp.fengshuiHTML = function (r) {
|
|
20059
|
+
if (!r || r.system !== 'fengshui') return pp.quickHTML(r);
|
|
20060
|
+
const m = r.meta || {};
|
|
20061
|
+
if (m.action === 'xuankong') return fsXuankong(r, m);
|
|
20062
|
+
if (m.action === 'advise') return fsAdvise(r, m);
|
|
20063
|
+
return fsNatal(r, m);
|
|
20064
|
+
};
|
|
20065
|
+
|
|
17736
20066
|
pp.quickHTML = function (r) {
|
|
17737
20067
|
if (!r) return '';
|
|
17738
20068
|
const LABEL = {
|
|
@@ -17882,12 +20212,100 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
17882
20212
|
let mhMode = 'time';
|
|
17883
20213
|
let xlrMode = 'time';
|
|
17884
20214
|
let fsMode = 'natal';
|
|
20215
|
+
let fsPeriod = '9';
|
|
17885
20216
|
let nnMode = 'assess';
|
|
17886
20217
|
let convMode = 'solar2lunar';
|
|
17887
20218
|
|
|
17888
20219
|
const el = (id) => document.getElementById(id);
|
|
17889
20220
|
const pad = (n) => String(n).padStart(2, '0');
|
|
17890
20221
|
|
|
20222
|
+
// ── 首屏:最近用过 / 分组 ↔ 平铺 ────────────────────────────────
|
|
20223
|
+
// 只记「点过哪个入口」,不存任何输入内容;读写失败(隐私模式、禁用存储)就降级成不记。
|
|
20224
|
+
const RECENT_KEY = 'mp.recent.tabs';
|
|
20225
|
+
const VIEW_KEY = 'mp.first.view';
|
|
20226
|
+
const RECENT_MAX = 3;
|
|
20227
|
+
|
|
20228
|
+
function storeGet(key) {
|
|
20229
|
+
try { return JSON.parse(window.localStorage.getItem(key) || 'null'); } catch (e) { return null; }
|
|
20230
|
+
}
|
|
20231
|
+
function storeSet(key, val) {
|
|
20232
|
+
try { window.localStorage.setItem(key, JSON.stringify(val)); } catch (e) { /* 存不了不影响使用 */ }
|
|
20233
|
+
}
|
|
20234
|
+
|
|
20235
|
+
/** 今天 / 昨天 / 月-日:让「最近用过」能看出是哪次 */
|
|
20236
|
+
function dayLabel(ts) {
|
|
20237
|
+
const d = new Date(ts);
|
|
20238
|
+
if (Number.isNaN(d.getTime())) return '';
|
|
20239
|
+
const day = (x) => new Date(x.getFullYear(), x.getMonth(), x.getDate()).getTime();
|
|
20240
|
+
const diff = Math.round((day(new Date()) - day(d)) / 86400000);
|
|
20241
|
+
if (diff <= 0) return '今天';
|
|
20242
|
+
if (diff === 1) return '昨天';
|
|
20243
|
+
return `${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
|
20244
|
+
}
|
|
20245
|
+
|
|
20246
|
+
/** 当前页面上真实存在的入口 → 名称。存储里的 tab 值先过这张表,避免脏数据被当选择器用 */
|
|
20247
|
+
function entryLabels() {
|
|
20248
|
+
const map = {};
|
|
20249
|
+
document.querySelectorAll('.tab[data-tab]').forEach((b) => { map[b.dataset.tab] = b.textContent.trim(); });
|
|
20250
|
+
return map;
|
|
20251
|
+
}
|
|
20252
|
+
|
|
20253
|
+
function renderRecent() {
|
|
20254
|
+
const row = el('recent');
|
|
20255
|
+
const box = el('recent-list');
|
|
20256
|
+
if (!row || !box) return;
|
|
20257
|
+
const labels = entryLabels();
|
|
20258
|
+
const list = (storeGet(RECENT_KEY) || []).filter((x) => x && labels[x.tab]).slice(0, RECENT_MAX);
|
|
20259
|
+
box.replaceChildren();
|
|
20260
|
+
list.forEach((x) => {
|
|
20261
|
+
const b = document.createElement('button');
|
|
20262
|
+
b.type = 'button';
|
|
20263
|
+
b.className = 'rc';
|
|
20264
|
+
b.dataset.tab = x.tab;
|
|
20265
|
+
b.appendChild(document.createTextNode(labels[x.tab]));
|
|
20266
|
+
const when = dayLabel(x.at);
|
|
20267
|
+
if (when) {
|
|
20268
|
+
const i = document.createElement('i');
|
|
20269
|
+
i.textContent = when;
|
|
20270
|
+
b.appendChild(i);
|
|
20271
|
+
}
|
|
20272
|
+
b.addEventListener('click', () => activate(x.tab));
|
|
20273
|
+
box.appendChild(b);
|
|
20274
|
+
});
|
|
20275
|
+
row.hidden = list.length === 0;
|
|
20276
|
+
}
|
|
20277
|
+
|
|
20278
|
+
function recordRecent(t) {
|
|
20279
|
+
if (!entryLabels()[t]) return;
|
|
20280
|
+
const list = (storeGet(RECENT_KEY) || []).filter((x) => x && x.tab && x.tab !== t);
|
|
20281
|
+
list.unshift({ tab: t, at: Date.now() });
|
|
20282
|
+
storeSet(RECENT_KEY, list.slice(0, RECENT_MAX));
|
|
20283
|
+
renderRecent();
|
|
20284
|
+
}
|
|
20285
|
+
|
|
20286
|
+
/** 点入口:切 tab + 立刻算;人格问卷例外,答够 12 题才出结果 */
|
|
20287
|
+
function activate(next) {
|
|
20288
|
+
setTab(next);
|
|
20289
|
+
recordRecent(next);
|
|
20290
|
+
if (next === 'mbti') mbEnter(); else run();
|
|
20291
|
+
}
|
|
20292
|
+
|
|
20293
|
+
/** 分组 / 平铺:只切显示,19 个 tab 与分组卡片两套入口始终可用 */
|
|
20294
|
+
function applyView(v) {
|
|
20295
|
+
const flat = v === 'flat';
|
|
20296
|
+
document.body.classList.toggle('view-flat', flat);
|
|
20297
|
+
document.body.classList.toggle('view-group', !flat);
|
|
20298
|
+
document.querySelectorAll('.view-switch [data-view]').forEach((b) => {
|
|
20299
|
+
const on = b.dataset.view === (flat ? 'flat' : 'group');
|
|
20300
|
+
b.classList.toggle('on', on);
|
|
20301
|
+
b.setAttribute('aria-pressed', on ? 'true' : 'false');
|
|
20302
|
+
});
|
|
20303
|
+
if (flat) {
|
|
20304
|
+
const cur = document.querySelector('.tab.on');
|
|
20305
|
+
if (cur) setTimeout(() => scrollTabIntoView(cur), 0);
|
|
20306
|
+
}
|
|
20307
|
+
}
|
|
20308
|
+
|
|
17891
20309
|
// ── 时间语义分类 ────────────────────────────────────────────────
|
|
17892
20310
|
// birth:八字 / 紫微 —— 要的是「出生时间」,必然是过去,用示例默认,不取当前时刻
|
|
17893
20311
|
// cast :六爻 / 梅花 / 大六壬 —— 要的是「起卦时刻」,占的就是当下,自动取本机当前时刻
|
|
@@ -17932,7 +20350,7 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
17932
20350
|
star: '星座按公历日期给出太阳星座与当日基调;同日同星座结果固定。',
|
|
17933
20351
|
numerology: '生命数字按公历生日归约出生命路径数、生日数与态度数。',
|
|
17934
20352
|
trend: '人生 K 线按大运与流年十神给逐年运势分,画成走势图。',
|
|
17935
|
-
fengshui: '
|
|
20353
|
+
fengshui: '风水看八宅命卦、大游年四吉四凶与流年九宫飞星;也可按坐向看门主灶倾向,或按运与坐向排玄空下卦盘。',
|
|
17936
20354
|
name: '起名按八字喜用匹配字库五行,可评估现有名字或生成候选名。',
|
|
17937
20355
|
mbti: '十六型人格是一份 MBTI 风格问卷:24 题分 6 页,每题按 1(完全不像)到 5(很像我)打分;答满 12 题就能出结果。',
|
|
17938
20356
|
};
|
|
@@ -18069,7 +20487,7 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
18069
20487
|
`<button type="button" class="mp-chip${pastMarks[r.year] === m ? ' on' : ''}" data-pmark="${r.year}" data-mark="${m}">${l}</button>`).join('')}</span></div>`;
|
|
18070
20488
|
return `<div class="mp-verify"><div class="mp-verify-h">验前事 · 过去几年的信号(只读,不改盘)</div>
|
|
18071
20489
|
${rows.map(row).join('')}
|
|
18072
|
-
<div class="mp-verify-foot"><button type="button" class="mp-btn ghost" data-calfit="1"
|
|
20490
|
+
<div class="mp-verify-foot"><button type="button" class="mp-btn ghost" data-calfit="1">算贴合度</button>
|
|
18073
20491
|
<span id="fitout" class="mp-verify-fit">${pastFit ? `命中 ${pastFit.yes}/${pastFit.answered}(${pastFit.level}):${pastFit.advice}` : ''}</span></div></div>`;
|
|
18074
20492
|
}
|
|
18075
20493
|
|
|
@@ -18081,7 +20499,7 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
18081
20499
|
.map(([v, l]) => `<option value="${v}"${ev.kind === v ? ' selected' : ''}>${l}</option>`).join('')}
|
|
18082
20500
|
</select></div>`).join('');
|
|
18083
20501
|
return `<div class="mp-rect"><div class="mp-verify-h">生时校正 · 用过去的事反推时辰</div>${rows}
|
|
18084
|
-
<button type="button" class="mp-btn ghost" data-rectify="1"
|
|
20502
|
+
<button type="button" class="mp-btn ghost" data-rectify="1">计算候选时辰</button>
|
|
18085
20503
|
<div id="rectout">${rectOutHTML()}</div></div>`;
|
|
18086
20504
|
}
|
|
18087
20505
|
|
|
@@ -18269,8 +20687,13 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
18269
20687
|
if (tab === 'trend') { args.gender = el('gender').value; args.toAge = Number(el('toage').value) || 60; args.trueSolar = el('ts').checked; args.lateZi = el('latezi') ? el('latezi').checked : true; }
|
|
18270
20688
|
if (tab === 'fengshui') {
|
|
18271
20689
|
args.action = fsMode;
|
|
18272
|
-
if (fsMode === '
|
|
18273
|
-
else {
|
|
20690
|
+
if (fsMode === 'natal') { args.gender = el('gender').value; }
|
|
20691
|
+
else {
|
|
20692
|
+
args.sitting = el('sitting').value.trim();
|
|
20693
|
+
args.facing = el('facing').value.trim();
|
|
20694
|
+
delete args.datetime;
|
|
20695
|
+
if (fsMode === 'xuankong') args.period = Number(el('fsperiod').value) || 9;
|
|
20696
|
+
}
|
|
18274
20697
|
}
|
|
18275
20698
|
if (tab === 'name') {
|
|
18276
20699
|
args.action = nnMode;
|
|
@@ -18280,7 +20703,8 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
18280
20703
|
args.trueSolar = el('ts').checked; args.lateZi = el('latezi') ? el('latezi').checked : true;
|
|
18281
20704
|
} else {
|
|
18282
20705
|
args.givenName = el('givenname').value.trim();
|
|
18283
|
-
|
|
20706
|
+
// 生辰留着:填了就按喜用判、空着 engine 自己只评字面五行
|
|
20707
|
+
if (!date || !time) delete args.datetime;
|
|
18284
20708
|
}
|
|
18285
20709
|
}
|
|
18286
20710
|
// 问题与卦象一起交给解读:解读按它展开,并在开头回显供你确认
|
|
@@ -18313,6 +20737,7 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
18313
20737
|
: tab === 'trend' ? window.__PP.trendHTML(r)
|
|
18314
20738
|
: tab === 'name' ? window.__PP.nameHTML(r)
|
|
18315
20739
|
: tab === 'mbti' ? window.__PP.mbtiHTML(r)
|
|
20740
|
+
: tab === 'fengshui' ? window.__PP.fengshuiHTML(r)
|
|
18316
20741
|
: window.__PP.quickHTML(r));
|
|
18317
20742
|
last = { r, html, tab, date, time, timed, trend };
|
|
18318
20743
|
paint();
|
|
@@ -18332,6 +20757,7 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
18332
20757
|
* 「此刻」按钮据此取消。
|
|
18333
20758
|
*/
|
|
18334
20759
|
function goCast() {
|
|
20760
|
+
recordRecent(tab);
|
|
18335
20761
|
// 人格问卷没有时间可补:先看答够没有,再走同一套计算
|
|
18336
20762
|
if (tab === 'mbti') { mbSubmit(); return; }
|
|
18337
20763
|
const k = kindOf(tab);
|
|
@@ -18377,6 +20803,7 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
18377
20803
|
const k = kindOf(tab);
|
|
18378
20804
|
const birth = isBirthTab(tab);
|
|
18379
20805
|
document.querySelectorAll('.tab').forEach((b) => b.classList.toggle('on', b.dataset.tab === tab));
|
|
20806
|
+
document.querySelectorAll('.tool').forEach((b) => b.classList.toggle('on', b.dataset.tab === tab));
|
|
18380
20807
|
scrollTabIntoView(document.querySelector('.tab.on'));
|
|
18381
20808
|
el('for-bazi').style.display = birth ? '' : 'none';
|
|
18382
20809
|
el('for-gender').style.display = birth ? '' : 'none';
|
|
@@ -18437,8 +20864,9 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
18437
20864
|
document.querySelectorAll('#xlrmode button').forEach((b) => b.classList.toggle('on', b.dataset.mode === xlrMode));
|
|
18438
20865
|
el('xlr-num').style.display = xlrMode === 'number' ? '' : 'none';
|
|
18439
20866
|
document.querySelectorAll('#fsmode button').forEach((b) => b.classList.toggle('on', b.dataset.mode === fsMode));
|
|
18440
|
-
el('fs-advise').style.display = fsMode
|
|
18441
|
-
el('fs-advise2').style.display = fsMode
|
|
20867
|
+
el('fs-advise').style.display = fsMode !== 'natal' ? '' : 'none';
|
|
20868
|
+
el('fs-advise2').style.display = fsMode !== 'natal' ? '' : 'none';
|
|
20869
|
+
if (el('fs-period')) el('fs-period').style.display = fsMode === 'xuankong' ? '' : 'none';
|
|
18442
20870
|
document.querySelectorAll('#nnmode button').forEach((b) => b.classList.toggle('on', b.dataset.mode === nnMode));
|
|
18443
20871
|
el('nn-assess').style.display = nnMode === 'assess' ? '' : 'none';
|
|
18444
20872
|
el('nn-generate').style.display = nnMode === 'generate' ? '' : 'none';
|
|
@@ -18601,6 +21029,7 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
18601
21029
|
|
|
18602
21030
|
function mbSubmit() {
|
|
18603
21031
|
if (mbAnswered() < MBTI_MIN) { mbNudge(); return; }
|
|
21032
|
+
recordRecent('mbti');
|
|
18604
21033
|
run();
|
|
18605
21034
|
}
|
|
18606
21035
|
|
|
@@ -18613,11 +21042,27 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
18613
21042
|
}
|
|
18614
21043
|
|
|
18615
21044
|
window.addEventListener('DOMContentLoaded', () => {
|
|
18616
|
-
|
|
18617
|
-
|
|
18618
|
-
|
|
18619
|
-
|
|
21045
|
+
// 两套入口(平铺 tab 与分组卡片)走同一条激活路径,避免行为分叉
|
|
21046
|
+
document.querySelectorAll('.tab, .tool').forEach((b) => b.addEventListener('click', () => activate(b.dataset.tab)));
|
|
21047
|
+
document.querySelectorAll('.view-switch [data-view]').forEach((b) => b.addEventListener('click', () => {
|
|
21048
|
+
applyView(b.dataset.view);
|
|
21049
|
+
storeSet(VIEW_KEY, b.dataset.view);
|
|
18620
21050
|
}));
|
|
21051
|
+
// 分组卡片:窄屏每组只露 4 个,余下的折在「还有 N 个」后面(展开态由 CSS 控制)
|
|
21052
|
+
document.querySelectorAll('.tgroup').forEach((g) => {
|
|
21053
|
+
const more = g.querySelector('.tmore');
|
|
21054
|
+
if (!more) return;
|
|
21055
|
+
const extra = g.querySelectorAll('.ttools>.tool').length - 4;
|
|
21056
|
+
if (extra <= 0) { more.style.display = 'none'; return; }
|
|
21057
|
+
more.textContent = `还有 ${extra} 个`;
|
|
21058
|
+
more.addEventListener('click', () => {
|
|
21059
|
+
const open = g.classList.toggle('open');
|
|
21060
|
+
more.textContent = open ? '收起' : `还有 ${extra} 个`;
|
|
21061
|
+
more.setAttribute('aria-expanded', open ? 'true' : 'false');
|
|
21062
|
+
});
|
|
21063
|
+
});
|
|
21064
|
+
applyView(storeGet(VIEW_KEY) === 'flat' ? 'flat' : 'group');
|
|
21065
|
+
renderRecent();
|
|
18621
21066
|
const mbHost = el('mbti-qs');
|
|
18622
21067
|
if (mbHost) {
|
|
18623
21068
|
renderMbti();
|
|
@@ -18652,6 +21097,7 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
18652
21097
|
el('gender').value = 'male';
|
|
18653
21098
|
el('addr').value = '河北石家庄';
|
|
18654
21099
|
setTab('bazi');
|
|
21100
|
+
recordRecent('bazi');
|
|
18655
21101
|
run();
|
|
18656
21102
|
});
|
|
18657
21103
|
el('gender').addEventListener('change', run);
|
|
@@ -18679,7 +21125,7 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
18679
21125
|
seg('#fsmode button', (v) => { fsMode = v; });
|
|
18680
21126
|
seg('#nnmode button', (v) => { nnMode = v; });
|
|
18681
21127
|
seg('#convertmode button', (v) => { convMode = v; syncQuick(); run(); });
|
|
18682
|
-
['ztask', 'zdays', 'zsheng', 'num1', 'num2', 'num3', 'toage', 'sitting', 'facing', 'surname', 'givenname', 'nlimit', 'lunardate', 'leapm']
|
|
21128
|
+
['ztask', 'zdays', 'zsheng', 'num1', 'num2', 'num3', 'toage', 'sitting', 'facing', 'fsperiod', 'surname', 'givenname', 'nlimit', 'lunardate', 'leapm']
|
|
18683
21129
|
.forEach((id) => { const n = el(id); if (n) n.addEventListener('change', run); });
|
|
18684
21130
|
// 方法页:按钮开合(静态内容,无网络)
|
|
18685
21131
|
const mOpen = el('method-open');
|
|
@@ -18724,7 +21170,7 @@ document.head.appendChild(Object.assign(document.createElement('style'), { textC
|
|
|
18724
21170
|
if (e.target && e.target.id === 'askq' && e.key === 'Enter') { e.preventDefault(); doAsk(); }
|
|
18725
21171
|
});
|
|
18726
21172
|
// 切到问事的体系时把光标放进「所问之事」
|
|
18727
|
-
document.querySelectorAll('.tab').forEach((b) => b.addEventListener('click', () => {
|
|
21173
|
+
document.querySelectorAll('.tab, .tool').forEach((b) => b.addEventListener('click', () => {
|
|
18728
21174
|
if (needAsk(tab) && !el('question').value.trim() && el('question').focus) el('question').focus();
|
|
18729
21175
|
}));
|
|
18730
21176
|
setTab('ziwei');
|