dsh-metaphysics 0.38.2 → 0.50.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +315 -8
- package/README.md +353 -342
- package/client.js +2699 -177
- package/engine/almanac.js +7 -6
- package/engine/bazi-words.js +174 -0
- package/engine/bazi.js +62 -0
- package/engine/classics.js +175 -9
- package/engine/crosscheck.js +29 -3
- package/engine/fengshui.js +197 -11
- package/engine/followup.js +29 -5
- package/engine/geju.js +90 -5
- package/engine/index.js +119 -13
- package/engine/interpret-knowledge.js +48 -12
- package/engine/interpret-plain.js +380 -322
- package/engine/interpret.js +328 -35
- package/engine/liuyao.js +185 -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 +3419 -527
package/engine/interpret.js
CHANGED
|
@@ -13,6 +13,13 @@ import {
|
|
|
13
13
|
} from './interpret-data.js';
|
|
14
14
|
// 生年四化要按年干反查四颗星,四化表只在紫微引擎里定义了一份,这里直接复用,避免两处维护打架
|
|
15
15
|
import { MUTAGEN } from './ziwei.js';
|
|
16
|
+
// 紫微的词库单列一处:宫位取象、主星细节、双星、煞星辅星、四化措辞、庙旺语气、格局读法
|
|
17
|
+
import {
|
|
18
|
+
palaceFieldOf, starExtraOf, starPairOf, brightRead, huaInLine,
|
|
19
|
+
shaLineOf, shaNatureOf, fuLineOf, patternReadOf, MAIN_SHA,
|
|
20
|
+
} from './ziwei-words.js';
|
|
21
|
+
// 八字的画像词库:日主取象、十神画像、命局基调与地支关系说法
|
|
22
|
+
import { stemPortraitOf, godPortraitOf, frameToneOf, relationNotes } from './bazi-words.js';
|
|
16
23
|
// 卦体关系的文案与面板 chip 共用同一份标签,避免两处措辞走散
|
|
17
24
|
import { bodyLabels, yongshenOf } from './liuyao.js';
|
|
18
25
|
|
|
@@ -61,7 +68,8 @@ function askOf(opts) {
|
|
|
61
68
|
question,
|
|
62
69
|
direction: d.key,
|
|
63
70
|
directionLabel: d.label,
|
|
64
|
-
|
|
71
|
+
// 没填问题时别在抬头喊一句「(未填写)」——读者只想知道这张盘在说什么
|
|
72
|
+
echo: question ? `问题:${question} | 询问方向:${d.label}` : `询问方向:${d.label}`,
|
|
65
73
|
};
|
|
66
74
|
}
|
|
67
75
|
|
|
@@ -310,8 +318,69 @@ function baziInterpret(r) {
|
|
|
310
318
|
},
|
|
311
319
|
];
|
|
312
320
|
|
|
321
|
+
// ── 词库取词:日主取象 / 十神画像 / 命局基调 / 地支关系 ────────────
|
|
322
|
+
const stemP = stemPortraitOf(dm.stem);
|
|
323
|
+
const topP = godPortraitOf(topName);
|
|
324
|
+
const secondP = godPortraitOf(secondName);
|
|
325
|
+
const season = st.parts && st.parts.season ? st.parts.season : null;
|
|
326
|
+
const dayZhi = pick(r.pillars?.day, 'branch', '');
|
|
327
|
+
// 组(比劫/食伤…)之外,再点出单颗最突出的十神:同一组里正财与偏财的味道并不一样
|
|
328
|
+
const byGodSorted = Object.entries(isObj(frame.godStats?.byGod) ? frame.godStats.byGod : {})
|
|
329
|
+
.filter(([, v]) => Number(v) > 0)
|
|
330
|
+
.sort((a, b) => b[1] - a[1]);
|
|
331
|
+
const topGodName = byGodSorted[0] ? byGodSorted[0][0] : '';
|
|
332
|
+
const topGodP = godPortraitOf(topGodName);
|
|
333
|
+
// 用神角色按权重排序,命局基调取分量最重的那一路
|
|
334
|
+
const favorRolesByWeight = (Array.isArray(ys.favorRoles) ? ys.favorRoles : [])
|
|
335
|
+
.slice()
|
|
336
|
+
.sort((a, b) => (Number(groups[b]) || 0) - (Number(groups[a]) || 0));
|
|
337
|
+
|
|
338
|
+
const frameworkText = [
|
|
339
|
+
`**日主**:${dm.stem}${dm.element}(${dm.yinYang}${dm.element})${season ? `生于${season.branch}月,日主在月令「${season.word}」` : ''},命局${level}(${pick(st, 'score', '—')} 分)${stemP ? `——${stemP.image}之象` : ''}。`,
|
|
340
|
+
`**用神**:喜${join(favor) || '—'}(${join(ys.favorRoles || []) || '—'}),忌${join(avoid) || '—'}(${join(ys.avoidRoles || []) || '—'})。${frameToneOf(level, favorRolesByWeight)}`,
|
|
341
|
+
`**格局**:${primary}(${pick(frame.primary, 'evidence', '')})${(Array.isArray(frame.geju) ? frame.geju : []).filter((g) => g.name && g.name !== primary).length
|
|
342
|
+
? `,另有${frame.geju.map((g) => g.name).filter((n) => n && n !== primary).join('、')}`
|
|
343
|
+
: ''}。`,
|
|
344
|
+
].join('\n');
|
|
345
|
+
|
|
346
|
+
const portraitText = [
|
|
347
|
+
`**外在取象**:${stemP ? `${stemP.image}的日主,传统取象上${stemP.look}` : '这一柱的取象词库未覆盖'}${stemP ? `;气质上${stemP.temper}` : ''}。这一层只是取象,不作定论。`,
|
|
348
|
+
`**性格底色**:十神里${topName || '—'}最重${top[0] ? `(${top[0][1]})` : ''}${secondName ? `,${secondName}次之` : ''}。${topP ? `${topP.gift};${topP.trap}。` : ''}`
|
|
349
|
+
+ (topGodP && topGodName && topGodName !== topName ? `具体到单颗,${topGodName}最显,落在「${topGodP.role}」上。` : '')
|
|
350
|
+
+ (stemP ? `放在${dm.stem}日主身上,长处是「${stemP.gift}」,容易踩的坑是「${stemP.trap}」。` : ''),
|
|
351
|
+
`**事业与家庭**:${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}。` : ''}`,
|
|
352
|
+
].join('\n');
|
|
353
|
+
|
|
354
|
+
const yearLines = (r.liunian || []).slice(0, 3).map((l) => {
|
|
355
|
+
const lk = isObj(l.luck) ? l.luck : {};
|
|
356
|
+
const notes = relationNotes(l.relations);
|
|
357
|
+
const why = (lk.reasons || []).slice(0, 2).join(',');
|
|
358
|
+
return `**${l.year} ${l.ganzhi}**(${l.age}岁·${l.stemTenGod || '—'})${lk.tier || '平'}:${why || '没有特别信号,按大运的基调走'}${notes.length ? `;与命局的关系——${notes.join(';')}` : ''}。`;
|
|
359
|
+
}).join('\n');
|
|
360
|
+
const yearsText = yearLines
|
|
361
|
+
? `先看眼前三年(大字是当年干支与十神,后面是该年的档位与理由):\n${yearLines}\n读法:档位说的是「这一年顺不顺手」,不是「会发生什么」;年份不顺时把重要动作挪到顺的年份,比硬扛更省事。`
|
|
362
|
+
: '流年数据未取到,暂不展开。';
|
|
363
|
+
|
|
364
|
+
const adviceItems = [];
|
|
365
|
+
if (favor.length) {
|
|
366
|
+
adviceItems.push(`把生活与工作往${join(favor)}的方向挪一点:${favor.slice(0, 2).map((e) => WUXING_INDUSTRY[e] || '').filter(Boolean).join(';') || '按喜用五行对应的行业挑'}。不必推倒重来,先从环境、圈子和日常习惯改起。`);
|
|
367
|
+
}
|
|
368
|
+
if (avoid.length) {
|
|
369
|
+
adviceItems.push(`对${join(avoid)}保持一点自觉:不是不能碰,而是别在关键决定上给它加码——${avoid.includes('火') ? '少在情绪最热的时候拍板' : avoid.includes('木') ? '少在想法最多的时候开工' : '先把手上的事收尾再谈新的'}。`);
|
|
370
|
+
}
|
|
371
|
+
const relNotes = relationNotes(r.relations && r.relations.branches);
|
|
372
|
+
if (relNotes.length) {
|
|
373
|
+
adviceItems.push(`命局里的地支关系是「${(r.relations.branches || []).join('、')}」:${relNotes.join(';')}。对应到具体人事,先处理情绪,再处理事情。`);
|
|
374
|
+
}
|
|
375
|
+
if (cli && cli.need) {
|
|
376
|
+
adviceItems.push(`调候要${cli.need.stem}${cli.need.element}:${cli.need.why}。落到日常,就是往这一类的环境、作息与节奏上靠。`);
|
|
377
|
+
}
|
|
378
|
+
const adviceText = adviceItems.slice(0, 4).map((t, i) => `${'①②③④'[i]} ${t}`).join('\n');
|
|
379
|
+
|
|
313
380
|
const sections = [
|
|
314
381
|
...(cross.length ? [{ key: 'cross', label: '交叉判断', text: cross.join(' ') }] : []),
|
|
382
|
+
{ key: 'framework', label: '命局框架', text: frameworkText },
|
|
383
|
+
{ key: 'portrait', label: '画像', text: portraitText },
|
|
315
384
|
{
|
|
316
385
|
key: 'reasoning', label: '看盘顺序',
|
|
317
386
|
// 把「先看什么、后看什么」摊开:用户能照着复核,也避免只给结论不给路径
|
|
@@ -326,6 +395,19 @@ function baziInterpret(r) {
|
|
|
326
395
|
`⑤ 落到维度:工作看喜用五行与十神权重;感情看配偶星与日支;健康看最旺与最弱的五行。五维度都只是这套推导的应用,不是另一套算法。`,
|
|
327
396
|
].join('\n'),
|
|
328
397
|
},
|
|
398
|
+
...(r.renyuan ? [(() => {
|
|
399
|
+
const ry = r.renyuan;
|
|
400
|
+
const table = ry.segments.map((s) => `${s.stem}${s.from}–${s.to}`).join(' / ');
|
|
401
|
+
const nextSeg = ry.next ? `,第 ${ry.next.from} 日起交 ${ry.next.stem}${ry.next.element}` : '';
|
|
402
|
+
const outside = ry.inHidden ? '' : ` 表里的 ${ry.active} 不在本柱藏干表中(属余气口径),两表各照原样,不互相改写。`;
|
|
403
|
+
const beyond = ry.beyond ? ' 你生在第 31 日以后,已超出 30 日表,按本气算,不硬分摊。' : '';
|
|
404
|
+
return {
|
|
405
|
+
key: 'renyuan', label: '人元司权',
|
|
406
|
+
text: `生于${ry.month}月第 ${ry.day} 日(从${ry.term ? ry.term.name : '节'}起算,节当日为第 1 日,日差按本盘所用时刻所在日计):这一日由 **${ry.active}${ry.activeElement}** 司权,第 ${ry.segment.from}–${ry.segment.to} 日属它${nextSeg}。\n`
|
|
407
|
+
+ '月令这一个月里,余气、中气、本气轮值,不是整月同一个五行当值——所以「月令是什么」,还要看生在第几日。\n'
|
|
408
|
+
+ `**口径**:本插件固定 30 日表(${table});另有 7/7/16、9/3/18 等分法,各家不一。分日只作解释层的一层细节,**不改取格**:取格仍按本气、透干与会支判定。${outside}${beyond}`,
|
|
409
|
+
};
|
|
410
|
+
})()] : []),
|
|
329
411
|
{
|
|
330
412
|
key: 'timeline', label: '时间窗',
|
|
331
413
|
text: (() => {
|
|
@@ -342,8 +424,12 @@ function baziInterpret(r) {
|
|
|
342
424
|
return `${jiaoLine}当前大运:${pick(cur, 'ganzhi', '—')}(${curSpan})。后续两步:${nextTwo}。\n近五年流年:${years || '—'}。\n读法:大运管"这十年的大环境",流年管"今年的具体天气";两者打架时,以能否动到用神为准。`;
|
|
343
425
|
})(),
|
|
344
426
|
},
|
|
427
|
+
{ key: 'years', label: '流年时间轴', text: yearsText },
|
|
428
|
+
{ key: 'advice', label: '专业建议', text: adviceText },
|
|
345
429
|
(() => {
|
|
346
430
|
const hits = (r.liunian || []).filter((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
431
|
+
const e = suiyunClassicOf(r);
|
|
432
|
+
const src = e ? `\n原文:《${CLASSIC_BOOKS[e.book].name}·${e.chapter}》「${e.quote}」\n白话:${e.plain}` : '';
|
|
347
433
|
return {
|
|
348
434
|
key: 'suiyun', label: '岁运提示',
|
|
349
435
|
text: hits.length
|
|
@@ -351,7 +437,7 @@ function baziInterpret(r) {
|
|
|
351
437
|
const stem = (l.suiyun.dayun || []).map((d) => `第${d.step}步${d.ganzhi}`).join('、');
|
|
352
438
|
return `${l.year} ${l.ganzhi}(${stem || '未到起运'}):${l.suiyun.signals.map((s) => s.detail).join(';')}`;
|
|
353
439
|
}).join('\n') +
|
|
354
|
-
'\n读法:岁运并临、运年反吟与流年伏吟/反吟只说明干支层面重复或对冲,传统上当作「变动感较强」的信号;本插件不据此判吉凶,要落到具体年份,仍看该年是否动到用神。'
|
|
440
|
+
'\n读法:岁运并临、运年反吟与流年伏吟/反吟只说明干支层面重复或对冲,传统上当作「变动感较强」的信号;本插件不据此判吉凶,要落到具体年份,仍看该年是否动到用神。' + src
|
|
355
441
|
: '近十年没有岁运并临、运年反吟或流年伏吟/反吟。「岁运并临主大凶」这类说法流传很广,本插件只把它当变动提示,没有命中就不作额外解读。',
|
|
356
442
|
};
|
|
357
443
|
})(),
|
|
@@ -542,12 +628,24 @@ function ziweiInterpret(r) {
|
|
|
542
628
|
? `你的命宫无正曜,按紫微的规则借对宫(迁移)来看,主星是${soulStar}`
|
|
543
629
|
: `你的命宫与对宫都没有正曜,这里按命主星${soulStar}来看`;
|
|
544
630
|
const S = ZIWEI_STARS[soulStar] || ZIWEI_STARS.紫微;
|
|
631
|
+
// 维度里只点名六煞;其余煞星留在逐宫分析,避免把细枝末节放大成主线
|
|
632
|
+
const zwMainSha = (p) => zwSha(p).filter((n) => MAIN_SHA.includes(n));
|
|
545
633
|
|
|
546
634
|
const careerStar = zwMainStar(career);
|
|
547
635
|
const wealthStar = zwMainStar(wealth);
|
|
548
636
|
const spouseStar = zwMainStar(spouse);
|
|
549
637
|
const healthStar = zwMainStar(health);
|
|
550
638
|
|
|
639
|
+
// 词库取词的几个小入口:主星清单、单颗星的亮度、双星组合、主星细节
|
|
640
|
+
const mainsOf = (p) => (p?.stars || []).filter((x) => x.type === '主星');
|
|
641
|
+
const brightOf = (p, name) => (p?.stars || []).find((x) => x.name === name)?.brightness || '';
|
|
642
|
+
const pairOf = (p) => starPairOf(mainsOf(p).map((x) => x.name));
|
|
643
|
+
const SX = starExtraOf(soulStar) || {};
|
|
644
|
+
const soulBright = brightRead(brightOf(soul, soulStar));
|
|
645
|
+
const soulPair = pairOf(soul);
|
|
646
|
+
// 亮度的语气只调「长处放不放得开」,不改结论:落陷时取 dim 那一句
|
|
647
|
+
const lightLine = (b, extra) => (extra ? `${b && b.tone === 'bad' ? extra.dim : extra.bright}。` : '');
|
|
648
|
+
|
|
551
649
|
const age = Number(pick(r.liunian?.[0], 'age', NaN));
|
|
552
650
|
let daxianPalace = null;
|
|
553
651
|
for (const p of r.palaces || []) {
|
|
@@ -567,14 +665,21 @@ function ziweiInterpret(r) {
|
|
|
567
665
|
const dimensions = [
|
|
568
666
|
{
|
|
569
667
|
key: 'overall', label: '整体运势',
|
|
570
|
-
text: `${soulFrom},性格底色上${S.trait}
|
|
668
|
+
text: `${soulFrom}${soulBright ? `(${soulBright.word}——${soulBright.plain})` : ''},性格底色上${S.trait}。` +
|
|
669
|
+
(soulPair ? `${soulPair.gist};${soulPair.watch}。` : '') +
|
|
670
|
+
`本盘${patText}。` +
|
|
571
671
|
`当前大限走在${daxianPalace ? `${daxianPalace.palace}(${daxianPalace.daxian.start}–${daxianPalace.daxian.end}岁)` : '当前阶段'},` +
|
|
572
672
|
`${lnMutagen ? `流年四化为${lnMutagen},本年的变化感主要落在这几颗星上` : '流年四化信号不明显'}。` +
|
|
573
673
|
(r.flow ? `再往下一层,当前流月命宫是${r.flow.month.ganzhi},落在原局${r.flow.month.palace || '未上盘'},本月的变化更容易在这一宫代表的事情上显出来。` : '') +
|
|
574
674
|
(natalSihuaText
|
|
575
675
|
? `另外你本命的生年四化落在:${natalSihuaText}——这是你这辈子比较稳定的底色,不随某一年改变。`
|
|
576
676
|
: ''),
|
|
577
|
-
advice:
|
|
677
|
+
advice: (() => {
|
|
678
|
+
const dxName = daxianPalace ? daxianPalace.palace : '命宫';
|
|
679
|
+
const dxField = palaceFieldOf(dxName);
|
|
680
|
+
return `这一阶段的主题更接近「${dxName}」——${dxField ? dxField.field : '这一宫代表的事'}。把它当作这几年的主线,其余安排围着它让路;`
|
|
681
|
+
+ `${SX.gift ? `你最顺手的做法是${SX.gift}` : `你的优势在${S.trait}`},但要留意${SX.watch || '用它用过了头'}。`;
|
|
682
|
+
})(),
|
|
578
683
|
evidence: [
|
|
579
684
|
`命宫 ${soulStar}${soulOwn ? '' : '(借对宫)'}`,
|
|
580
685
|
daxianPalace ? `大限 ${daxianPalace.palace} ${daxianPalace.daxian.start}–${daxianPalace.daxian.end}岁` : '',
|
|
@@ -584,16 +689,38 @@ function ziweiInterpret(r) {
|
|
|
584
689
|
},
|
|
585
690
|
{
|
|
586
691
|
key: 'work', label: '工作与职业选择',
|
|
587
|
-
text:
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
692
|
+
text: (() => {
|
|
693
|
+
const careerBright = brightRead(brightOf(career, careerStar));
|
|
694
|
+
const careerPair = pairOf(career);
|
|
695
|
+
const careerSha = zwMainSha(career);
|
|
696
|
+
return `命宫${soulStar}给你的是底层偏好:${S.work}。`
|
|
697
|
+
+ `官禄宫${careerStar
|
|
698
|
+
? `主星为${careerStar}${careerBright ? `(${careerBright.word})` : ''},${ZIWEI_STARS[careerStar]?.work || '有其自身的做事方式'}`
|
|
699
|
+
: '无正曜,工作方式更多受环境与他人影响,适合配合型岗位'}。`
|
|
700
|
+
+ (careerPair ? `${careerPair.gist};要留意${careerPair.watch}。` : '')
|
|
701
|
+
+ (careerSha.length ? `官禄宫又见${join(careerSha)}:${shaLineOf(careerSha)}` : '')
|
|
702
|
+
+ `两者合起来看,你更适合${careerStar && careerStar !== soulStar ? `用${soulStar}的方式去做${careerStar}擅长的事` : '在稳定的框架里发挥自己的特点'}。`;
|
|
703
|
+
})(),
|
|
704
|
+
advice: `挑工作时可以先看岗位内容是否匹配上面这条;如果暂时不能换,试着在现有岗位里争取靠近这部分的事务——${SX.gift ? `把「${SX.gift}」这类活往自己身上揽,比硬熬更容易做出成绩` : '先做出一件拿得出手的事,比硬熬更容易被看见'}。`,
|
|
705
|
+
evidence: [
|
|
706
|
+
`命宫 ${soulStar}${soulBright ? `·${soulBright.word}` : ''}`,
|
|
707
|
+
`官禄 ${careerStar || '无正曜'}`,
|
|
708
|
+
`财帛 ${wealthStar || '无正曜'}`,
|
|
709
|
+
...(zwMainSha(career).length ? [`官禄煞星 ${join(zwMainSha(career))}`] : []),
|
|
710
|
+
],
|
|
591
711
|
},
|
|
592
712
|
{
|
|
593
713
|
key: 'career', label: '事业发展',
|
|
594
|
-
text:
|
|
595
|
-
|
|
596
|
-
|
|
714
|
+
text: (() => {
|
|
715
|
+
const wealthBright = brightRead(brightOf(wealth, wealthStar));
|
|
716
|
+
const wealthPair = pairOf(wealth);
|
|
717
|
+
return `财帛宫${wealthStar
|
|
718
|
+
? `见${wealthStar}${wealthBright ? `(${wealthBright.word})` : ''},${ZIWEI_STARS[wealthStar]?.trait || ''}`
|
|
719
|
+
: '无正曜'},官禄宫${careerStar || '无正曜'},`
|
|
720
|
+
+ `${wealthStar && careerStar ? '财与事业两宫都有主星坐守,说明这两块是可以主动经营的部分' : '有一宫无主星,说明该块更容易受外部条件牵动,宜借势而非强求'}。`
|
|
721
|
+
+ (wealthPair ? `${wealthPair.gist}。` : '')
|
|
722
|
+
+ `大限推进上,${daxianPalace ? `目前落在${daxianPalace.palace},这一宫管${palaceFieldOf(daxianPalace.palace)?.field || '这一段的事'}` : '当前阶段'},下一步会转入相邻的宫位,重心也会跟着挪。`;
|
|
723
|
+
})(),
|
|
597
724
|
advice: `事业上建议做两件事:一是把可积累的东西(技能、资质、作品)做厚;二是${careerStar ? `发挥${careerStar}的优势——${ZIWEI_STARS[careerStar]?.trait || ''}` : '找一个能带你的前辈或平台'}。遇到四化化忌的年份,先守成再谈扩张。`,
|
|
598
725
|
evidence: [
|
|
599
726
|
`财帛 ${wealthStar || '无正曜'}`,
|
|
@@ -603,8 +730,17 @@ function ziweiInterpret(r) {
|
|
|
603
730
|
},
|
|
604
731
|
{
|
|
605
732
|
key: 'love', label: '爱情与感情',
|
|
606
|
-
text:
|
|
607
|
-
|
|
733
|
+
text: (() => {
|
|
734
|
+
const spouseBright = brightRead(brightOf(spouse, spouseStar));
|
|
735
|
+
const spousePair = pairOf(spouse);
|
|
736
|
+
const spouseSha = zwMainSha(spouse);
|
|
737
|
+
return `夫妻宫${spouseStar
|
|
738
|
+
? `主星为${spouseStar}${spouseBright ? `(${spouseBright.word})` : ''},感情上的倾向是${ZIWEI_STARS[spouseStar]?.love || '有自己相处的节奏'}`
|
|
739
|
+
: '无正曜,关系状态更多由对方与互动方式决定'}。`
|
|
740
|
+
+ (spousePair ? `${spousePair.gist}。` : '')
|
|
741
|
+
+ `${spouseSha.length ? `夫妻宫同时见${join(spouseSha)}:${shaLineOf(spouseSha)}煞星不等于定局,更多是提醒你留意沟通方式。` : '夫妻宫未见明显煞星,关系的基调相对平顺。'}`
|
|
742
|
+
+ (SX.watch ? `另外,你自带的${SX.watch}这一面,在亲密关系里最容易被放大。` : '');
|
|
743
|
+
})(),
|
|
608
744
|
advice: `感情里${spouseStar ? `参考${spouseStar}的特点:${ZIWEI_STARS[spouseStar]?.love || ''}` : '可以更主动地表达自己的需求'}。有分歧时先说清事实与感受,别急着下结论;关系的好坏取决于两个人怎么做,不取决于这张盘。`,
|
|
609
745
|
evidence: [
|
|
610
746
|
`夫妻宫 ${spouseStar || '无正曜'}`,
|
|
@@ -614,8 +750,17 @@ function ziweiInterpret(r) {
|
|
|
614
750
|
},
|
|
615
751
|
{
|
|
616
752
|
key: 'health', label: '健康状况',
|
|
617
|
-
text:
|
|
618
|
-
|
|
753
|
+
text: (() => {
|
|
754
|
+
const healthBright = brightRead(brightOf(health, healthStar));
|
|
755
|
+
const healthSha = zwMainSha(health);
|
|
756
|
+
return `疾厄宫${healthStar
|
|
757
|
+
? `见${healthStar}${healthBright ? `(${healthBright.word})` : ''},传统取象上${ZIWEI_STARS[healthStar]?.health || '需要留意自身的薄弱环节'}`
|
|
758
|
+
: '无正曜,身体状态更多受生活作息直接影响'}。`
|
|
759
|
+
+ (healthSha.length
|
|
760
|
+
? `同时见${join(healthSha)},按星情只是「${shaNatureOf(healthSha)}」这一层,提示这一块值得比其他部位多一分留意。`
|
|
761
|
+
: '')
|
|
762
|
+
+ '这些都是象征性的提示,不构成任何医学判断。';
|
|
763
|
+
})(),
|
|
619
764
|
advice: `把${healthStar ? ZIWEI_STARS[healthStar]?.health?.replace('留意', '').replace('需要留意', '') || '常规' : '常规'}当作体检时重点关注的参考;真正管用的还是规律作息、适度运动与定期检查。身体不舒服请直接就医。`,
|
|
620
765
|
evidence: [
|
|
621
766
|
`疾厄宫 ${healthStar || '无正曜'}`,
|
|
@@ -624,9 +769,106 @@ function ziweiInterpret(r) {
|
|
|
624
769
|
},
|
|
625
770
|
];
|
|
626
771
|
|
|
772
|
+
// ── 命身底色:先把「这张盘是谁」摆出来,再谈逐宫与格局 ──────────
|
|
773
|
+
const soulField = palaceFieldOf('命宫');
|
|
774
|
+
const bodyLands = pick(r.body, 'lands', '');
|
|
775
|
+
const bodyField = palaceFieldOf(bodyLands);
|
|
776
|
+
const identityText = [
|
|
777
|
+
`命宫落在${soul.branch}(${soul && soul.ganzhi ? soul.ganzhi : '—'}),主星${soulStar}${soulBright ? `·${soulBright.word}` : ''}——这一宫管${soulField ? soulField.field : '你自己'},${SX.gift ? `你身上最能用出去的是${SX.gift}` : S.trait}。`
|
|
778
|
+
+ (SX.gift ? lightLine(soulBright, SX) : ''),
|
|
779
|
+
soulPair ? `${soulPair.gist};要留意的是${soulPair.watch}。` : '',
|
|
780
|
+
bodyLands ? `身宫寄在${bodyLands}——${bodyField ? `${bodyField.field}是后天更容易使上劲的地方` : '这是后天着力点'},中年以后会越来越明显。` : '',
|
|
781
|
+
`五行局为${pick(r.bureau, 'name', '—')},${pick(r.daxian, 'startAge', '—')}岁起运:局定的是节奏(几步起、十年一换),不是好坏。`,
|
|
782
|
+
`命主${pick(r, 'lifeMaster', '—')}、身主${pick(r, 'bodyMaster', '—')}:传统把这两颗当作整张盘的定调星,命主看底色,身主看后半程的着力点。`,
|
|
783
|
+
].filter(Boolean).join('\n');
|
|
784
|
+
|
|
785
|
+
// ── 逐宫分析:十二宫各一行清单 + 一句读法 ────────────────────
|
|
786
|
+
const trimDot = (s) => String(s || '').replace(/。$/, '');
|
|
787
|
+
const palaceLines = (r.palaces || []).map((p) => {
|
|
788
|
+
const mains = mainsOf(p);
|
|
789
|
+
const shas = zwSha(p);
|
|
790
|
+
const fus = (p.stars || []).filter((x) => x.type === '辅星' || x.type === '吉星').map((x) => x.name);
|
|
791
|
+
const huas = (p.stars || []).filter((x) => x.mutagen).map((x) => `${x.name}化${x.mutagen}`);
|
|
792
|
+
const selfs = (p.selfHua || []).map((x) => `自化${x.type}`);
|
|
793
|
+
const head = `【${p.palace}·${p.branch}】`
|
|
794
|
+
+ `${mains.length ? mains.map((x) => `${x.name}${x.brightness || ''}`).join('·') : '无正曜'}`
|
|
795
|
+
+ (fus.length ? `|吉 ${fus.slice(0, 3).join('、')}` : '')
|
|
796
|
+
+ (shas.length ? `|煞 ${shas.join('、')}` : '')
|
|
797
|
+
+ ((huas.length || selfs.length) ? `|${[...huas, ...selfs].join('、')}` : '');
|
|
798
|
+
|
|
799
|
+
const read = [];
|
|
800
|
+
if (mains.length) {
|
|
801
|
+
const pair = starPairOf(mains.map((x) => x.name));
|
|
802
|
+
const ex = starExtraOf(mains[0].name);
|
|
803
|
+
if (pair) read.push(pair.gist);
|
|
804
|
+
else if (ex) read.push(ex.gift);
|
|
805
|
+
} else {
|
|
806
|
+
// 命无正曜时借对宫:三方数组的第四位就是对宫
|
|
807
|
+
const opposite = zwMainStar(zwPalace(r, (p.sanfang || [])[3]));
|
|
808
|
+
read.push(opposite ? `无正曜,借对宫${opposite}来看` : '无正曜,这一宫随环境走');
|
|
809
|
+
}
|
|
810
|
+
if (fus.length) read.push(fuLineOf(fus));
|
|
811
|
+
if (shas.length) read.push(shaLineOf(shas));
|
|
812
|
+
for (const x of (p.stars || []).filter((y) => y.mutagen).slice(0, 2)) read.push(huaInLine(x.mutagen, p.palace));
|
|
813
|
+
const tail = read.filter(Boolean).map(trimDot).join(';');
|
|
814
|
+
return `${head}\n ${tail}。`;
|
|
815
|
+
}).join('\n');
|
|
816
|
+
const palacesText = `十二宫从命宫逆排,每宫管一件事。看一宫不能只看本宫,还要并上它的三方四正(本宫+对宫+两个三合宫)——下面先逐宫摊开,再回到整体。\n${palaceLines}`;
|
|
817
|
+
|
|
818
|
+
// ── 格局分三层:有利 / 结构提示 / 忌格提醒 ──────────────────
|
|
819
|
+
const PATTERN_TIERS = [
|
|
820
|
+
{ tone: 'good', label: '有利格局' },
|
|
821
|
+
{ tone: 'neutral', label: '结构提示' },
|
|
822
|
+
{ tone: 'bad', label: '忌格提醒' },
|
|
823
|
+
];
|
|
824
|
+
const patternSections = PATTERN_TIERS.map((t) => {
|
|
825
|
+
const list = patterns.filter((p) => (p.tone || 'neutral') === t.tone);
|
|
826
|
+
if (!list.length) return null;
|
|
827
|
+
return {
|
|
828
|
+
key: `pattern-${t.tone}`,
|
|
829
|
+
label: t.label,
|
|
830
|
+
tone: t.tone === 'neutral' ? 'watch' : t.tone,
|
|
831
|
+
text: list.map((p) => {
|
|
832
|
+
const rd = patternReadOf(p.name, p.tone);
|
|
833
|
+
return `**${p.name}** ${rd.gist}\n 依据:${p.evidence}\n 做法:${rd.advice}`;
|
|
834
|
+
}).join('\n'),
|
|
835
|
+
};
|
|
836
|
+
}).filter(Boolean);
|
|
837
|
+
if (!patternSections.length) {
|
|
838
|
+
patternSections.push({ key: 'pattern-none', label: '格局', text: '本盘未触发内置的常见格局条目。这不代表盘面平淡——格局只是把若干星位组合起个名字,没命中时按宫位与四化逐条看即可。' });
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// ── 行动建议:每条都从盘面事实推出来,能指到具体一宫才写 ──────────
|
|
842
|
+
const adviceItems = [];
|
|
843
|
+
if (SX.gift) {
|
|
844
|
+
adviceItems.push(`把「${SX.gift}」做成招牌:${soulBright && soulBright.tone === 'bad'
|
|
845
|
+
? `${soulStar}在这宫不得地,长处不会自己显出来,越要挑能发挥它的场子`
|
|
846
|
+
: `${soulStar}${soulBright ? `·${soulBright.word}` : '在命宫'},顺着这条走最省力`}。`);
|
|
847
|
+
}
|
|
848
|
+
if (daxianPalace && daxianPalace.daxian) {
|
|
849
|
+
const dxf = palaceFieldOf(daxianPalace.palace);
|
|
850
|
+
adviceItems.push(`这几年主线在${daxianPalace.palace}(${daxianPalace.daxian.start}–${daxianPalace.daxian.end}岁):${dxf ? dxf.field : '这一宫的事'}排前面,力气别摊平。`);
|
|
851
|
+
}
|
|
852
|
+
const jiHua = natalSihua.find((m) => m.type === '忌');
|
|
853
|
+
if (jiHua && jiHua.palace) {
|
|
854
|
+
const jf = palaceFieldOf(jiHua.palace);
|
|
855
|
+
adviceItems.push(`生年化忌落在${jiHua.palace}:${jf ? jf.huaJi : '这一块容易反复'}——别硬顶,把预期调低一点反而顺。`);
|
|
856
|
+
}
|
|
857
|
+
const soulSha = zwMainSha(soul);
|
|
858
|
+
if (soulSha.length) adviceItems.push(`命宫见${join(soulSha)}:${shaLineOf(soulSha)}`);
|
|
859
|
+
const spouseSha2 = zwMainSha(spouse);
|
|
860
|
+
if (spouseSha2.length && !soulSha.length) {
|
|
861
|
+
adviceItems.push(`夫妻宫见${join(spouseSha2)}:${shaLineOf(spouseSha2)}`);
|
|
862
|
+
}
|
|
863
|
+
const adviceText = adviceItems.slice(0, 4)
|
|
864
|
+
.map((t, i) => `${'①②③④'[i]} ${trimDot(t)}`)
|
|
865
|
+
.join('\n') || '这张盘的结构比较平,没有单点特别突出——按现有节奏走,把一件事做完整比开新头更划算。';
|
|
866
|
+
|
|
627
867
|
const sections = [
|
|
628
|
-
{ key: '
|
|
629
|
-
{ key: '
|
|
868
|
+
{ key: 'identity', label: '命身底色', text: identityText },
|
|
869
|
+
{ key: 'palaces', label: '逐宫分析', text: palacesText },
|
|
870
|
+
...patternSections,
|
|
871
|
+
{ key: 'advice', label: '行动建议', text: adviceText },
|
|
630
872
|
{
|
|
631
873
|
key: 'reasoning', label: '看盘顺序',
|
|
632
874
|
text: [
|
|
@@ -938,6 +1180,11 @@ function liuyaoInterpret(r, ask) {
|
|
|
938
1180
|
} else if (ug.fushen.length) {
|
|
939
1181
|
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(';')}。`);
|
|
940
1182
|
if (ug.relationSay.length) useText.push(`飞伏生克:${ug.relationSay.join(';')}。伏神要得出才算有力,藏在忌神之下且被克,则虽有如无。`);
|
|
1183
|
+
const chufu = r.fushenAccess;
|
|
1184
|
+
if (chufu && Array.isArray(chufu.items) && chufu.items.length) {
|
|
1185
|
+
useText.push(`伏神出伏的条件:${chufu.items.map((f) => f.say).join(';')}。`);
|
|
1186
|
+
useText.push('「助」与「压」只把飞伏生克、月建日辰与月破并列摆出,再归成四档(可出 / 有助有压 / 受压难出 / 未得助);不排各家优先级,旬空只标出、不并入档位,也不给应期日期。');
|
|
1187
|
+
}
|
|
941
1188
|
} else {
|
|
942
1189
|
useText.push(`用神不上卦,且本宫首卦里也没找到${ug.liuqin},这一问在卦面上没有直接对应物,只能借日月或改日再占。`);
|
|
943
1190
|
}
|
|
@@ -975,10 +1222,32 @@ function liuyaoInterpret(r, ask) {
|
|
|
975
1222
|
useText.push(`时令对用神:${head},日辰 ${strength.day ? `${strength.day.branch}(${strength.day.element})` : '—'}。${body.join(';')}。`);
|
|
976
1223
|
useText.push('月建看这一段时令站在哪一边,日辰看当天那股力量是扶还是克;两处同时看,只报状态,不折成分数。');
|
|
977
1224
|
}
|
|
978
|
-
useText.push('
|
|
1225
|
+
useText.push('这一层只把用神、卦体与时令对起来,不折成分数、不断成败;应期另在「应期线索」一节只给触发支与快慢。');
|
|
979
1226
|
sections.push({ key: 'yongshen', label: '用神落位与卦体', text: useText.join('\n') });
|
|
980
1227
|
}
|
|
981
1228
|
|
|
1229
|
+
// 应期线索:只给触发支与快慢方向,不给日期
|
|
1230
|
+
{
|
|
1231
|
+
const yq = r.yingqi;
|
|
1232
|
+
if (yq && Array.isArray(yq.items) && yq.items.length) {
|
|
1233
|
+
const rows = yq.items.map((it) => {
|
|
1234
|
+
const flags = [
|
|
1235
|
+
it.monthState && it.monthState !== 'unknown' ? `月建${it.monthState}` : '',
|
|
1236
|
+
it.monthChong ? '月破' : '',
|
|
1237
|
+
it.kong ? '旬空' : '',
|
|
1238
|
+
].filter(Boolean).join('、');
|
|
1239
|
+
return `${it.position}爻${it.branch}${it.element}${flags ? `(${flags})` : ''}:${it.tempoSay}`;
|
|
1240
|
+
});
|
|
1241
|
+
sections.push({
|
|
1242
|
+
key: 'yingqi',
|
|
1243
|
+
label: '应期线索',
|
|
1244
|
+
text: `应期快慢:${yq.tempoSay}。${rows.join(';')}。可留意的地支:${yq.triggers.map((t) => `${t.branch}(${t.labels.join('、')})`).join(';')}。` +
|
|
1245
|
+
`${yq.viaFushen ? '用神不上卦,这里的支取自伏神;伏神要先得出才算数。' : ''}` +
|
|
1246
|
+
'这一节只把传统的「逢值、逢冲、逢合」与旬空的出空、冲空摆出来,不换算成具体日期、不排先后、也不判忌神受制;近事以日计、远事以月计,用哪把尺取决于事情本身。',
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
|
|
982
1251
|
// 全卦逐爻旺衰:不挑用神,六爻都过一遍,看整张卦的气压在哪一头
|
|
983
1252
|
{
|
|
984
1253
|
const hs = r.hexStrength;
|
|
@@ -1008,7 +1277,7 @@ function liuyaoInterpret(r, ask) {
|
|
|
1008
1277
|
|
|
1009
1278
|
sections.push({
|
|
1010
1279
|
key: 'limits', label: '未纳入',
|
|
1011
|
-
text: '
|
|
1280
|
+
text: '本卦没有计算:用神两现时该取哪一爻的权重、应期的具体日期(只给逢值/逢冲/逢合的触发支与快慢方向)、忌神受制的时点、动变连环。化进/化退的力重只按月建五态给「得令/失令」这类档位,不折成加权分数;这些都会改变"旺不旺"的判断,所以这里只给取象与方向。',
|
|
1012
1281
|
});
|
|
1013
1282
|
|
|
1014
1283
|
const dimensions = [
|
|
@@ -1434,7 +1703,7 @@ const BUILDERS = {
|
|
|
1434
1703
|
import { interpretQimen } from './qimen-interpret.js';
|
|
1435
1704
|
import { buildAnswer, buildPlain, buildGlossary, buildFollowups, dimensionPlain } from './interpret-plain.js';
|
|
1436
1705
|
import { knowledgeFor, caveatsFor, STATUS_LABEL } from './interpret-knowledge.js';
|
|
1437
|
-
import { CLASSIC_BOOKS } from './classics.js';
|
|
1706
|
+
import { CLASSIC_BOOKS, suiyunClassicOf } from './classics.js';
|
|
1438
1707
|
|
|
1439
1708
|
/**
|
|
1440
1709
|
* 给任意体系的解析结果补上「白话四层」:直答 / 说人话 / 每维一句话 / 追问建议。
|
|
@@ -1442,37 +1711,61 @@ import { CLASSIC_BOOKS } from './classics.js';
|
|
|
1442
1711
|
*/
|
|
1443
1712
|
function enrichPlain(result, r, ask) {
|
|
1444
1713
|
if (!result) return result;
|
|
1714
|
+
// 注解卡的归属按「维度身份」定,不按显示顺序:所问之事会把某一维提前,
|
|
1715
|
+
// 若按显示顺序先到先得,同一张盘换个问法就换了注解归属。
|
|
1716
|
+
const DIM_RANK = ['overall', 'work', 'career', 'love', 'health'];
|
|
1717
|
+
const rankOf = (key) => { const i = DIM_RANK.indexOf(key); return i < 0 ? DIM_RANK.length : i; };
|
|
1718
|
+
const seen = new Set();
|
|
1445
1719
|
const dims = (result.dimensions || []).map((d) => {
|
|
1446
1720
|
const p = dimensionPlain(d.key, r, {});
|
|
1447
|
-
|
|
1448
|
-
const know = knowledgeFor(r.system, d.key).map((k) => ({
|
|
1449
|
-
id: k.id,
|
|
1450
|
-
gist: k.gist,
|
|
1451
|
-
detail: k.detail,
|
|
1452
|
-
source: k.source,
|
|
1453
|
-
status: k.status,
|
|
1454
|
-
statusLabel: STATUS_LABEL[k.status] || k.status,
|
|
1455
|
-
note: k.note || '',
|
|
1456
|
-
}));
|
|
1457
|
-
return { ...d, ...(p ? { plain: p } : {}), ...(know.length ? { knowledge: know } : {}) };
|
|
1721
|
+
return { ...d, ...(p ? { plain: p } : {}) };
|
|
1458
1722
|
});
|
|
1723
|
+
// 知识条目挂在维度下:讲「为什么这样断」,与结论、依据形成三层。
|
|
1724
|
+
// 两条硬约束,都是为「读得下去」:
|
|
1725
|
+
// ① 一张卡全报告只挂一次——它讲的是「这条规则怎么用」,与挂在哪个维度无关;
|
|
1726
|
+
// 逐维重复会把五段正文冲散(1996 示例盘:29 条里 13 条是同一张卡的复读)。
|
|
1727
|
+
// ② 每维最多 3 条——正文是给人读的,注解是读法不是清单;没挂进正文的分歧条目
|
|
1728
|
+
// 仍会在文末「这套规则有多稳」里逐条列出(带原注),不丢信息。
|
|
1729
|
+
const KNOW_PER_DIM = 3;
|
|
1730
|
+
for (const d of dims.slice().sort((a, b) => rankOf(a.key) - rankOf(b.key))) {
|
|
1731
|
+
const know = knowledgeFor(r.system, d.key)
|
|
1732
|
+
.filter((k) => !seen.has(k.id))
|
|
1733
|
+
.slice(0, KNOW_PER_DIM)
|
|
1734
|
+
.map((k) => ({
|
|
1735
|
+
id: k.id,
|
|
1736
|
+
gist: k.gist,
|
|
1737
|
+
detail: k.detail,
|
|
1738
|
+
source: k.source,
|
|
1739
|
+
status: k.status,
|
|
1740
|
+
statusLabel: STATUS_LABEL[k.status] || k.status,
|
|
1741
|
+
note: k.note || '',
|
|
1742
|
+
}));
|
|
1743
|
+
for (const k of know) seen.add(k.id);
|
|
1744
|
+
if (know.length) d.knowledge = know;
|
|
1745
|
+
}
|
|
1459
1746
|
const texts = [
|
|
1460
1747
|
result.lead,
|
|
1461
1748
|
...dims.map((d) => [d.label, d.text, d.advice, d.plain, ...(d.knowledge || []).map((k) => k.detail)].filter(Boolean).join('')),
|
|
1462
1749
|
...(result.sections || []).map((x) => x.text),
|
|
1463
1750
|
].filter(Boolean);
|
|
1464
1751
|
|
|
1465
|
-
// 文末的诚实声明:把「各家有异说 /
|
|
1752
|
+
// 文末的诚实声明:把「各家有异说 / 还没做」的部分摊开,而不是藏在专业感里。
|
|
1753
|
+
// 「待核实」的在下面单独成段(附原注),这里只列已定论/有异说的,避免同一句话写两遍。
|
|
1754
|
+
// 已在上面展开过的只留条目名当索引;没展开的附原注,保证信息不丢。
|
|
1466
1755
|
const caveats = caveatsFor(r.system);
|
|
1467
|
-
const
|
|
1468
|
-
|
|
1756
|
+
const disputed = caveats.filter((k) => k.status !== 'todo');
|
|
1757
|
+
const caveatLine = disputed.length
|
|
1758
|
+
? disputed.map((k) => {
|
|
1759
|
+
const tag = STATUS_LABEL[k.status] || k.status;
|
|
1760
|
+
return `· ${k.gist}(${tag})${seen.has(k.id) || !k.note ? '' : `——${k.note}`}`;
|
|
1761
|
+
}).join('\n')
|
|
1469
1762
|
: '';
|
|
1470
1763
|
const secs = [...(result.sections || [])];
|
|
1471
1764
|
if (caveatLine) {
|
|
1472
1765
|
secs.push({
|
|
1473
1766
|
key: 'caveats',
|
|
1474
1767
|
label: '这套规则有多稳',
|
|
1475
|
-
text:
|
|
1768
|
+
text: `下列几条各家说法不一,本插件取其中一派并把分歧标出来,供你判断可信度(已在上面展开的只列条目,未展开的附原注):\n${caveatLine}`,
|
|
1476
1769
|
});
|
|
1477
1770
|
}
|
|
1478
1771
|
const todos = caveats.filter((k) => k.status === 'todo');
|