dsh-metaphysics 0.46.5 → 0.50.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 +148 -0
- package/README.md +18 -11
- package/client.js +1075 -78
- package/docs/assets/dsh-metaphysics-group.jpg +0 -0
- package/engine/almanac.js +7 -6
- package/engine/bazi.js +73 -1
- package/engine/classics.js +53 -3
- package/engine/crosscheck.js +29 -3
- package/engine/diff.js +301 -197
- package/engine/geju.js +78 -14
- package/engine/index.js +112 -10
- package/engine/interpret-knowledge.js +19 -10
- package/engine/interpret-plain.js +19 -3
- package/engine/interpret.js +46 -6
- package/engine/liuyao.js +100 -0
- package/index.js +12 -2
- package/package.json +2 -2
- package//345/221/275/347/220/206/346/216/222/347/233/230.html +1082 -99
- package/docs/assets/dsh-metaphysics-group.png +0 -0
package/engine/geju.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import { judgeClimate, arbitrate } from './tiaohou.js';
|
|
11
11
|
import { qtOf } from './qiongtong.js';
|
|
12
|
+
import { sanheGroupOf } from './sanhe.js';
|
|
12
13
|
|
|
13
14
|
const STEMS = ['甲', '乙', '丙', '丁', '戊', '己', '庚', '辛', '壬', '癸'];
|
|
14
15
|
const BRANCHES = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];
|
|
@@ -87,6 +88,25 @@ export function elementRoles(dayStem) {
|
|
|
87
88
|
|
|
88
89
|
// ── 月令格 ───────────────────────────────────────────────────
|
|
89
90
|
|
|
91
|
+
// 四墓(杂气)月:辰戌丑未所藏多、用神不一,取用先看透干,再看会支。
|
|
92
|
+
// 会支只认三合局——子平真诠十六「逢申与子会局」的例子即三合,三会方与兼透兼用仍不纳入。
|
|
93
|
+
const ZA_MONTHS = ['辰', '未', '戌', '丑'];
|
|
94
|
+
|
|
95
|
+
function huiCandidate(pillars, monthBranch, cands) {
|
|
96
|
+
if (!ZA_MONTHS.includes(monthBranch)) return null;
|
|
97
|
+
const group = sanheGroupOf(monthBranch);
|
|
98
|
+
if (!group) return null;
|
|
99
|
+
const others = ['year', 'day', 'hour'];
|
|
100
|
+
const need = group.branches.filter((b) => b !== monthBranch);
|
|
101
|
+
if (!need.every((b) => others.some((k) => pillars[k].branch === b))) return null;
|
|
102
|
+
const cand = cands.find((c) => STEM_ELEMENT[c.stem] === group.element);
|
|
103
|
+
if (!cand) return null;
|
|
104
|
+
const where = others
|
|
105
|
+
.filter((k) => need.includes(pillars[k].branch))
|
|
106
|
+
.map((k) => `${({ year: '年', day: '日', hour: '时' })[k]}支${pillars[k].branch}`);
|
|
107
|
+
return { ...cand, group, where };
|
|
108
|
+
}
|
|
109
|
+
|
|
90
110
|
function monthPattern(pillars, dayStem, monthBranch) {
|
|
91
111
|
const hidden = HIDDEN[monthBranch] || [];
|
|
92
112
|
const cands = hidden.map((stem, i) => ({
|
|
@@ -98,10 +118,13 @@ function monthPattern(pillars, dayStem, monthBranch) {
|
|
|
98
118
|
const others = ['year', 'month', 'hour'];
|
|
99
119
|
const exposedKey = others.find((k) => cands.some((c) => c.stem === pillars[k].stem));
|
|
100
120
|
const base = cands[0];
|
|
101
|
-
const
|
|
121
|
+
const hui = exposedKey ? null : huiCandidate(pillars, monthBranch, cands);
|
|
122
|
+
const use = exposedKey ? cands.find((c) => c.stem === pillars[exposedKey].stem) : (hui || base);
|
|
123
|
+
const usedBy = exposedKey ? '透干' : (hui ? '会支' : '本气');
|
|
102
124
|
const exposedPos = exposedKey ? { year: '年', month: '月', hour: '时' }[exposedKey] : null;
|
|
103
125
|
|
|
104
|
-
|
|
126
|
+
// 建禄只认日干的禄位;戊土辰月、己土未月这类「本气比肩但不在禄位」的杂气月不再冒称建禄
|
|
127
|
+
if (base.god === '比肩' && LUSHEN_BRANCH[dayStem] === monthBranch) {
|
|
105
128
|
return {
|
|
106
129
|
name: '建禄格',
|
|
107
130
|
kind: '月令格',
|
|
@@ -118,10 +141,31 @@ function monthPattern(pillars, dayStem, monthBranch) {
|
|
|
118
141
|
}
|
|
119
142
|
return { name: '月劫格', kind: '月令格', evidence: `月令${monthBranch}本气${base.stem}为劫财` };
|
|
120
143
|
}
|
|
144
|
+
if (usedBy === '本气' && base.god === '比肩') {
|
|
145
|
+
return {
|
|
146
|
+
name: '比肩格',
|
|
147
|
+
kind: '月令格',
|
|
148
|
+
evidence: `月令${monthBranch}藏${hidden.join('')},本气${base.stem}为比肩,但${dayStem}禄在${LUSHEN_BRANCH[dayStem]}、不在${monthBranch},属杂气月比肩当权`,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
// 子平十六:「透乙则用月劫」——杂气月由透干或会支取到劫财时,仍作月劫论
|
|
152
|
+
if (usedBy !== '本气' && use.god === '劫财') {
|
|
153
|
+
const via = exposedKey ? `透于${exposedPos}干` : `${hui.where.join('、')}会成${hui.group.element}局`;
|
|
154
|
+
return {
|
|
155
|
+
name: '月劫格',
|
|
156
|
+
kind: '月令格',
|
|
157
|
+
evidence: `月令${monthBranch}藏${hidden.join('')},${use.pos}${use.stem}(劫财)${via},劫财为用,作月劫论`,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
121
160
|
const name = `${use.god}格`;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
161
|
+
let ex;
|
|
162
|
+
if (exposedKey) {
|
|
163
|
+
ex = `月令${monthBranch}藏${hidden.join('')},${use.pos}${use.stem}(${use.god})透于${exposedPos}干`;
|
|
164
|
+
} else if (hui) {
|
|
165
|
+
ex = `月令${monthBranch}藏${hidden.join('')},本气${base.stem}(${base.god})未透干,而${hui.where.join('、')}会成${hui.group.element}局,取${use.pos}${use.stem}(${use.god})为用`;
|
|
166
|
+
} else {
|
|
167
|
+
ex = `月令${monthBranch}藏${hidden.join('')},本气${base.stem}(${base.god})未透干,以月令本气取格`;
|
|
168
|
+
}
|
|
125
169
|
return { name, kind: '月令格', evidence: ex };
|
|
126
170
|
}
|
|
127
171
|
|
|
@@ -236,11 +280,17 @@ function yongshenOf(dayStem, monthBranch, strength, wuxing, branches = []) {
|
|
|
236
280
|
const me = roles.me;
|
|
237
281
|
const weak = strength.level === '身弱' || strength.level === '偏弱';
|
|
238
282
|
const strong = strength.level === '身强' || strength.level === '偏强';
|
|
283
|
+
const roleName = (el) => (el === me ? '比劫' : el === roles.inMe ? '印'
|
|
284
|
+
: el === roles.shi ? '食伤' : el === roles.cai ? '财' : '官杀');
|
|
285
|
+
const ROLE_VERB = { 比劫: '帮身', 印: '生身', 食伤: '泄秀', 财: '耗', 官杀: '制' };
|
|
239
286
|
|
|
240
287
|
const baseFavor = weak ? [roles.inMe, me] : strong ? [roles.shi, roles.cai, roles.guan] : [roles.inMe, me, roles.shi];
|
|
241
288
|
const baseAvoid = weak ? [roles.shi, roles.cai, roles.guan] : strong ? [me, roles.inMe] : [roles.guan, roles.cai];
|
|
242
289
|
let favor = baseFavor.slice();
|
|
243
290
|
let avoid = baseAvoid.slice();
|
|
291
|
+
// 调候所忌若正好是扶抑所喜(弱土遇燥的火、寒湿盘的强土遇水),两边不能同时列。
|
|
292
|
+
// 本表保留在喜用、不列入忌,并单列「有争议」;否则摘要会出现同一行既喜又忌。
|
|
293
|
+
const disputed = [];
|
|
244
294
|
|
|
245
295
|
// 先判气候,再决定要不要让调候压过扶抑
|
|
246
296
|
const climate = judgeClimate({ monthBranch, dayStem, wuxing, branches });
|
|
@@ -251,27 +301,39 @@ function yongshenOf(dayStem, monthBranch, strength, wuxing, branches = []) {
|
|
|
251
301
|
const needEl = climate.need.element;
|
|
252
302
|
if (!favor.includes(needEl)) favor.unshift(needEl);
|
|
253
303
|
avoid = avoid.filter((e) => e !== needEl);
|
|
254
|
-
|
|
304
|
+
const badEl = climate.avoidElement;
|
|
305
|
+
if (badEl && favor.includes(badEl)) {
|
|
306
|
+
disputed.push({
|
|
307
|
+
element: badEl,
|
|
308
|
+
favorRole: roleName(badEl),
|
|
309
|
+
favorVerb: ROLE_VERB[roleName(badEl)],
|
|
310
|
+
climate: climate.label,
|
|
311
|
+
note: `调候忌${badEl}(${climate.label}),但它在扶抑里为${roleName(badEl)};本表保留在喜用,不列入忌。`,
|
|
312
|
+
});
|
|
313
|
+
} else if (badEl && !avoid.includes(badEl)) {
|
|
314
|
+
avoid.unshift(badEl);
|
|
315
|
+
}
|
|
255
316
|
}
|
|
256
317
|
|
|
257
|
-
const roleName = (el) => (el === me ? '比劫' : el === roles.inMe ? '印'
|
|
258
|
-
: el === roles.shi ? '食伤' : el === roles.cai ? '财' : '官杀');
|
|
259
318
|
const expand = {
|
|
260
319
|
比劫: ['比肩', '劫财'], 印: ['正印', '偏印'], 食伤: ['食神', '伤官'],
|
|
261
320
|
财: ['正财', '偏财'], 官杀: ['正官', '七杀'],
|
|
262
321
|
};
|
|
263
322
|
const favorTenGods = Array.from(new Set(favor.flatMap((el) => expand[roleName(el)] || [])));
|
|
264
323
|
const avoidTenGods = Array.from(new Set(avoid.flatMap((el) => expand[roleName(el)] || [])));
|
|
324
|
+
const disputedTenGods = Array.from(new Set(disputed.flatMap((d) => expand[roleName(d.element)] || [])));
|
|
265
325
|
const tongguan = tongguanOf(favor, avoid, wuxing);
|
|
266
326
|
|
|
327
|
+
const describe = (el) => `${el}(${roleName(el)}·${ROLE_VERB[roleName(el)]})`;
|
|
328
|
+
const disputedText = disputed
|
|
329
|
+
.map((d) => `${d.element}(扶抑为${d.favorRole}·${d.favorVerb};${d.climate}盘调候忌${d.element},本表保留在喜用)`)
|
|
330
|
+
.join('、');
|
|
267
331
|
const detail = [
|
|
268
332
|
`日主${dayStem}${me},${strength.level}(${strength.score} 分):`,
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
: '身中和,先取调候与通关,喜忌随大运流年动态变化。',
|
|
274
|
-
`调候:${climate.label}(${(climate.evidence || []).join('、')})${climate.need ? `,取${climate.need.stem}${climate.need.element},忌${climate.avoidElement}` : ',气候平和'}。`,
|
|
333
|
+
`喜${favor.map(describe).join('、') || '—'};忌${avoid.map(describe).join('、') || '—'}。`,
|
|
334
|
+
disputed.length ? `有争议:${disputedText}。` : '',
|
|
335
|
+
!weak && !strong ? '身中和,先取调候与通关,喜忌随大运流年动态变化。' : '',
|
|
336
|
+
`调候:${climate.label}(${(climate.evidence || []).join('、')})${climate.need ? `,取${climate.need.stem}${climate.need.element},忌${climate.avoidElement}${disputed.some((d) => d.element === climate.avoidElement) ? '(有争议)' : ''}` : ',气候平和'}。`,
|
|
275
337
|
qt ? `穷通宝鉴:${qt.month}${dayStem}${me},用神${qt.yong.join('、')}(首取${qt.primary})。` : '',
|
|
276
338
|
tongguan
|
|
277
339
|
? `通关:忌${tongguan.foe}克用${tongguan.use},五行以${tongguan.bridge}为关;局中${tongguan.level === '可通'
|
|
@@ -291,10 +353,12 @@ function yongshenOf(dayStem, monthBranch, strength, wuxing, branches = []) {
|
|
|
291
353
|
level: strength.level,
|
|
292
354
|
favor,
|
|
293
355
|
avoid,
|
|
356
|
+
disputed,
|
|
294
357
|
favorRoles: favor.map(roleName),
|
|
295
358
|
avoidRoles: avoid.map(roleName),
|
|
296
359
|
favorTenGods,
|
|
297
360
|
avoidTenGods,
|
|
361
|
+
disputedTenGods,
|
|
298
362
|
tiaohou: { ...climate, ...arb, element: climate.need ? climate.need.element : null },
|
|
299
363
|
climate,
|
|
300
364
|
qt,
|
package/engine/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// 统一入口:解析参数、分派到各体系、生成可读摘要
|
|
2
2
|
import { buildBazi } from './bazi.js';
|
|
3
|
-
import { buildLiuyao, tossLines, bodyLabels, yongshenOf, yongshenStrength, fushenAccess, hexagramStrength, jinTuiPower } from './liuyao.js';
|
|
3
|
+
import { buildLiuyao, tossLines, bodyLabels, yongshenOf, yongshenStrength, fushenAccess, hexagramStrength, jinTuiPower, yingqiWindow } from './liuyao.js';
|
|
4
4
|
import { buildZiwei, BRIGHTNESS, flowOf, asOfParts, ZIWEI_SCHOOL_DEFAULTS } from './ziwei.js';
|
|
5
5
|
import { drawTarot } from './tarot.js';
|
|
6
6
|
import { buildMeihua } from './meihua.js';
|
|
@@ -13,7 +13,7 @@ import { toJDN, ganzhiName, dayGanzhiIndex } from './calendar.js';
|
|
|
13
13
|
import { randomOf, isSeed } from './random.js';
|
|
14
14
|
import { interpret, DIRECTIONS, DIRECTION_DEFAULT } from './interpret.js';
|
|
15
15
|
import { followup, askPrompt } from './followup.js';
|
|
16
|
-
import { crossCheck, crossText } from './crosscheck.js';
|
|
16
|
+
import { crossCheck, crossText, crossSection } from './crosscheck.js';
|
|
17
17
|
import { pastSignals, verifyFit } from './verify.js';
|
|
18
18
|
import { rectifyBirth } from './rectify.js';
|
|
19
19
|
import { buildAlmanac } from './almanac.js';
|
|
@@ -24,7 +24,8 @@ import { buildStar } from './star.js';
|
|
|
24
24
|
import { buildNumerology } from './numerology.js';
|
|
25
25
|
import { buildMbti, mbtiPaper } from './mbti.js';
|
|
26
26
|
import { buildConvert } from './convert.js';
|
|
27
|
-
import { classicsFor, classicsText } from './classics.js';
|
|
27
|
+
import { classicsFor, classicsText, suiyunClassicOf, classicOf, CLASSIC_BOOKS } from './classics.js';
|
|
28
|
+
import { diffObjects, summarize, sortDiffs, labelOf, rootOf, categoryOf, formatValue, CALIBER_SWITCHES } from './diff.js';
|
|
28
29
|
import { buildTrend } from './trend.js';
|
|
29
30
|
import { buildFengshui } from './fengshui.js';
|
|
30
31
|
import { buildName } from './name.js';
|
|
@@ -126,12 +127,22 @@ function baziText(r) {
|
|
|
126
127
|
? `神煞(${r.shensha.count} 见):` + r.shensha.groups.map((g) =>
|
|
127
128
|
`${g.cat}|` + g.items.map((i) => `${i.name}(${i.pillars.map((k) => SHORT[k]).join('')})`).join('、')).join(';')
|
|
128
129
|
: '神煞:—';
|
|
130
|
+
const ry = r.renyuan;
|
|
131
|
+
const rySrc = classicOf('smt-renyuan');
|
|
132
|
+
const renyuanLine = ry
|
|
133
|
+
? `人元:${ry.month}月第${ry.day}日,${ry.active}${ry.activeElement}司权(${ry.segments.map((s) => `${s.stem}${s.from}–${s.to}`).join(' ')})${ry.beyond ? ';已过 30 日表,按本气算' : ''}${rySrc ? `|原文见《${CLASSIC_BOOKS[rySrc.book].name}·${rySrc.chapter}》` : ''}`
|
|
134
|
+
: '';
|
|
135
|
+
const ysd = (r.frame && r.frame.yongshen && r.frame.yongshen.disputed) || [];
|
|
136
|
+
const disText = ysd.length
|
|
137
|
+
? ` 有争议:${ysd.map((d) => `${d.element}(${d.favorRole};${d.climate}盘调候忌${d.element})`).join('、')}`
|
|
138
|
+
: '';
|
|
139
|
+
const disEls = new Set(ysd.map((d) => d.element));
|
|
129
140
|
const gejuLine = r.frame ? [
|
|
130
141
|
`格局:${r.frame.primary ? `${r.frame.primary.name}(${r.frame.primary.evidence})` : '—'}`,
|
|
131
142
|
` ${r.frame.geju.map((g) => `${g.name}[${g.kind}]`).join(' ')}`,
|
|
132
|
-
`用神:喜${r.frame.yongshen.favor.join('')}(${r.frame.yongshen.favorTenGods.join('、')}) 忌${r.frame.yongshen.avoid.join('')}(${r.frame.yongshen.avoidTenGods.join('、')}
|
|
143
|
+
`用神:喜${r.frame.yongshen.favor.join('')}(${r.frame.yongshen.favorTenGods.join('、')}) 忌${r.frame.yongshen.avoid.join('')}(${r.frame.yongshen.avoidTenGods.join('、')})${disText} ${r.frame.yongshen.method}`,
|
|
133
144
|
` ${r.frame.yongshen.detail}`,
|
|
134
|
-
`寒暖:${r.climate ? `${r.climate.label}(${(r.climate.evidence || []).join('、')})${r.climate.need ? ` 调候取${r.climate.need.stem}${r.climate.need.element} 忌${r.climate.avoidElement}` : ''}` : '—'}` +
|
|
145
|
+
`寒暖:${r.climate ? `${r.climate.label}(${(r.climate.evidence || []).join('、')})${r.climate.need ? ` 调候取${r.climate.need.stem}${r.climate.need.element} 忌${r.climate.avoidElement}${disEls.has(r.climate.avoidElement) ? '(有争议)' : ''}` : ''}` : '—'}` +
|
|
135
146
|
(r.frame.yongshen.qt ? ` 穷通:${r.frame.yongshen.qt.month}${r.frame.yongshen.qt.stem}取${r.frame.yongshen.qt.yong.join('、')}(首取${r.frame.yongshen.qt.primary})` : ''),
|
|
136
147
|
`十神权重:${Object.entries(r.frame.godStats.groups).map(([k, v]) => `${k}${v}`).join(' ')}`,
|
|
137
148
|
] : [];
|
|
@@ -148,15 +159,18 @@ function baziText(r) {
|
|
|
148
159
|
shenshaLine,
|
|
149
160
|
`真太阳时:${r.solarTime.trueSolarText}(${r.input.geo ? r.input.geo.note + ';' : ''}${r.solarTime.note}) 晚子时:${r.input.lateZi ? '23:00 后算次日' : '23:00 后仍算当日'}`,
|
|
150
161
|
`节气:上一节 ${r.jieqi.previous.name} ${r.jieqi.previous.time} 下一节 ${r.jieqi.next.name} ${r.jieqi.next.time}`,
|
|
162
|
+
...(renyuanLine ? [renyuanLine] : []),
|
|
151
163
|
`大运:${r.dayun.rule}(${r.dayun.direction}),${r.dayun.startAge.years}岁${r.dayun.startAge.months}个月起运${jiao}`,
|
|
152
164
|
` ${dayun}`,
|
|
153
165
|
`流年:${r.liunian.slice(0, 10).map((l) => `${l.year}${l.ganzhi}(${l.stemTenGod})${l.luck ? `·${l.luck.tier}` : ''}`).join(' ')}`,
|
|
154
166
|
(() => {
|
|
155
167
|
const hits = r.liunian.filter((l) => l.suiyun && l.suiyun.signals && l.suiyun.signals.length);
|
|
156
|
-
if (!hits.length) return '
|
|
157
|
-
const label = (s) => `${s.type}${s.type.startsWith('流年') && s.target ? `(${s.target})` : ''}`;
|
|
168
|
+
if (!hits.length) return '岁运提示:近十年无岁运并临、运年反吟或大运/流年伏吟、反吟(只标干支,不判吉凶)';
|
|
169
|
+
const label = (s) => `${s.type}${(s.type.startsWith('流年') || s.type.startsWith('大运')) && s.target ? `(${s.target})` : ''}`;
|
|
170
|
+
const e = suiyunClassicOf(r);
|
|
171
|
+
const src = e ? `|古籍见《${CLASSIC_BOOKS[e.book].name}·${e.chapter}》` : '';
|
|
158
172
|
return '岁运提示(只标干支变动,不判吉凶):' + hits
|
|
159
|
-
.map((l) => `${l.year}${l.ganzhi} ${l.suiyun.signals.map(label).join('/')}`).join(';');
|
|
173
|
+
.map((l) => `${l.year}${l.ganzhi} ${l.suiyun.signals.map(label).join('/')}`).join(';') + src;
|
|
160
174
|
})(),
|
|
161
175
|
'(格局、用神、行运吉凶为扶抑+简化调候的量化提示,非断语。)',
|
|
162
176
|
].join('\n') + near;
|
|
@@ -408,6 +422,11 @@ function liuyaoText(r) {
|
|
|
408
422
|
if (jt && Array.isArray(jt.lines) && jt.lines.length) {
|
|
409
423
|
out.push(`进退力重:${jt.lines.map((l) => `${l.position}爻${l.from}→${l.to}${l.type}·${l.verdict}`).join(' · ')}`);
|
|
410
424
|
}
|
|
425
|
+
// 应期线索:只列地支与快慢,不给日期
|
|
426
|
+
const yq = r.yingqi;
|
|
427
|
+
if (yq && Array.isArray(yq.triggers) && yq.triggers.length) {
|
|
428
|
+
out.push(`应期线索:${yq.tempo} · ${yq.triggers.map((t) => `${t.labels.join('/')}${t.branch}`).join(' · ')}(只列地支,不出日期)`);
|
|
429
|
+
}
|
|
411
430
|
return out.filter(Boolean).join('\n');
|
|
412
431
|
}
|
|
413
432
|
|
|
@@ -428,6 +447,14 @@ export function compute(args = {}) {
|
|
|
428
447
|
r.classics = classicsFor(r);
|
|
429
448
|
const ct = classicsText(r.classics);
|
|
430
449
|
if (ct) r.summary = `${r.summary}\n【古籍】\n${ct}`;
|
|
450
|
+
// 岁运提示的原文不占五条上限:只在盘面真有岁运信号时挂到结果上,摘要、解析层与面板各自取用
|
|
451
|
+
const syc = suiyunClassicOf(r);
|
|
452
|
+
if (syc) r.suiyunClassic = { ...syc, bookName: CLASSIC_BOOKS[syc.book].name };
|
|
453
|
+
// 人元司事的原文同样不进五条取条表:每张八字盘都有人元,随「人元司权」一节给出
|
|
454
|
+
if (r.renyuan) {
|
|
455
|
+
const ryc = classicOf('smt-renyuan');
|
|
456
|
+
if (ryc) r.renyuanClassic = { ...ryc, bookName: CLASSIC_BOOKS[ryc.book].name };
|
|
457
|
+
}
|
|
431
458
|
}
|
|
432
459
|
// 超出 ΔT 覆盖范围时把精度提示顶到摘要最前,别让远期盘悄悄出错
|
|
433
460
|
if (r && r.precision && r.precision.level === 'approx' && r.summary) {
|
|
@@ -462,7 +489,7 @@ export function compute(args = {}) {
|
|
|
462
489
|
: buildBazi({ ...common, lateZi: args.lateZi !== false, nowYear: asOf ? asOf.year : undefined });
|
|
463
490
|
r.cross = crossCheck(r.system === 'bazi' ? r : other, r.system === 'ziwei' ? r : other);
|
|
464
491
|
if (r.interpret) {
|
|
465
|
-
r.interpret.sections.push(
|
|
492
|
+
r.interpret.sections.push(crossSection(r.cross));
|
|
466
493
|
}
|
|
467
494
|
}
|
|
468
495
|
// 验前事:把过去若干年的流年信号摊开(只读,不改盘)
|
|
@@ -548,6 +575,69 @@ export function interpretText(i) {
|
|
|
548
575
|
return out.join('\n');
|
|
549
576
|
}
|
|
550
577
|
|
|
578
|
+
/** 对照时不参与计算的参数:它们只影响解析/附加模块,不影响盘面 */
|
|
579
|
+
const CALIBER_IGNORE_ARGS = ['cross', 'verifyPast', 'withInterpret', 'question', 'direction', 'ask', 'geocode', 'rectify', 'events'];
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* 口径对照:同一组输入,只把某一个口径开关换成它的另一档,逐字段列出变化。
|
|
583
|
+
* 这一步不新增断法,也不改盘;返回根因字段、分类计数与一句话总结,供面板/独立页/工具共用。
|
|
584
|
+
*/
|
|
585
|
+
export function caliberCompare(args = {}, opts = {}) {
|
|
586
|
+
const system = opts.system || args.system;
|
|
587
|
+
const switches = opts.switches || CALIBER_SWITCHES[system] || [];
|
|
588
|
+
if (!switches.length) return { system, switches: [], affected: 0, total: 0 };
|
|
589
|
+
const base = { ...args };
|
|
590
|
+
for (const k of CALIBER_IGNORE_ARGS) delete base[k];
|
|
591
|
+
const rows = switches.map((sw) => {
|
|
592
|
+
const current = sw.read(base);
|
|
593
|
+
const alt = sw.alt(current);
|
|
594
|
+
let diffs = [];
|
|
595
|
+
let error = '';
|
|
596
|
+
try {
|
|
597
|
+
diffs = diffObjects(
|
|
598
|
+
compute({ ...base, [sw.key]: current }),
|
|
599
|
+
compute({ ...base, [sw.key]: alt }),
|
|
600
|
+
);
|
|
601
|
+
} catch (e) {
|
|
602
|
+
error = (e && e.message) || String(e);
|
|
603
|
+
}
|
|
604
|
+
const roots = sortDiffs(diffs.filter((d) => rootOf(d.path))).map((d) => ({
|
|
605
|
+
path: d.path,
|
|
606
|
+
label: labelOf(d.path),
|
|
607
|
+
from: formatValue(d.from),
|
|
608
|
+
to: formatValue(d.to),
|
|
609
|
+
}));
|
|
610
|
+
const counts = new Map();
|
|
611
|
+
for (const d of diffs) {
|
|
612
|
+
const c = categoryOf(d.path) || '其他';
|
|
613
|
+
counts.set(c, (counts.get(c) || 0) + 1);
|
|
614
|
+
}
|
|
615
|
+
const categories = [...counts.entries()]
|
|
616
|
+
.map(([name, count]) => ({ name, count }))
|
|
617
|
+
.sort((a, b) => b.count - a.count || a.name.localeCompare(b.name, 'zh-Hans-CN'));
|
|
618
|
+
return {
|
|
619
|
+
key: sw.key,
|
|
620
|
+
title: sw.title,
|
|
621
|
+
short: sw.short,
|
|
622
|
+
current,
|
|
623
|
+
alt,
|
|
624
|
+
currentLabel: sw.label(current),
|
|
625
|
+
altLabel: sw.label(alt),
|
|
626
|
+
total: diffs.length,
|
|
627
|
+
summary: error ? '' : summarize(diffs),
|
|
628
|
+
roots,
|
|
629
|
+
categories,
|
|
630
|
+
error,
|
|
631
|
+
};
|
|
632
|
+
});
|
|
633
|
+
return {
|
|
634
|
+
system,
|
|
635
|
+
switches: rows,
|
|
636
|
+
affected: rows.filter((r) => !r.error && r.total > 0).length,
|
|
637
|
+
total: rows.reduce((n, r) => n + r.total, 0),
|
|
638
|
+
};
|
|
639
|
+
}
|
|
640
|
+
|
|
551
641
|
const JU_METHODS = ['chaibu', 'chaoshen', 'zhirun'];
|
|
552
642
|
const TAROT_COUNTS = [1, 3, 5];
|
|
553
643
|
const LATE_ZI_MODES = ['same-day', 'next-day'];
|
|
@@ -745,6 +835,9 @@ function computeRaw(args = {}) {
|
|
|
745
835
|
// 伏神出伏条件:飞伏生克叠月建日辰,只判条件、不出应期
|
|
746
836
|
const chufu = fushenAccess(result, ug, { monthBranch, dayBranch: result.dayGanZhi.branch });
|
|
747
837
|
if (chufu) result.fushenAccess = chufu;
|
|
838
|
+
// 应期线索:只列逢值/逢冲/逢合与旬空的出空/冲空,再给快慢方向,不换算日期
|
|
839
|
+
const yq = yingqiWindow(result, ug, { monthBranch });
|
|
840
|
+
if (yq) result.yingqi = yq;
|
|
748
841
|
}
|
|
749
842
|
if (args.seed !== undefined && args.seed !== null && args.seed !== '') result.seed = Number(args.seed);
|
|
750
843
|
return { ...result, ...(asOf ? { asOf } : {}), summary: liuyaoText(result) };
|
|
@@ -1170,6 +1263,15 @@ export function renderText(result) {
|
|
|
1170
1263
|
if (extra) parts.push(extra);
|
|
1171
1264
|
}
|
|
1172
1265
|
if (result.cross) parts.push(`【八字 × 紫微 交叉验证】\n${crossText(result.cross)}`);
|
|
1266
|
+
if (result.caliber && Array.isArray(result.caliber.switches) && result.caliber.switches.length) {
|
|
1267
|
+
const c = result.caliber;
|
|
1268
|
+
parts.push('【口径对照】同一组输入,只换一个口径(不判哪套更准,也不改盘面)\n'
|
|
1269
|
+
+ c.switches.map((s) => {
|
|
1270
|
+
if (s.error) return `· ${s.title}:未能对照(${s.error})`;
|
|
1271
|
+
if (!s.total) return `· ${s.title}:${s.currentLabel} → ${s.altLabel},本盘无变化`;
|
|
1272
|
+
return `· ${s.title}:${s.currentLabel} → ${s.altLabel}\n ${s.summary}`;
|
|
1273
|
+
}).join('\n'));
|
|
1274
|
+
}
|
|
1173
1275
|
if (result.followup) {
|
|
1174
1276
|
const f = result.followup;
|
|
1175
1277
|
parts.push(`【追问】${f.question}\n${f.answer}${f.evidence && f.evidence.length ? `\n 依据:${f.evidence.join(';')} 置信度:${f.confidence}` : ''}`);
|
|
@@ -1196,7 +1298,7 @@ export { geocodeAddress, resolveAddress };
|
|
|
1196
1298
|
export { buildBazi, buildLiuyao, tossLines };
|
|
1197
1299
|
export { followup, askPrompt };
|
|
1198
1300
|
export { pastSignals, verifyFit, rectifyBirth };
|
|
1199
|
-
export { crossCheck, crossText };
|
|
1301
|
+
export { crossCheck, crossText, crossSection };
|
|
1200
1302
|
export { buildAlmanac, buildZeri, buildChenggu, buildXiaoliuren, buildStar, buildNumerology, buildConvert };
|
|
1201
1303
|
export { buildTrend, buildFengshui, buildName };
|
|
1202
1304
|
|
|
@@ -15,10 +15,10 @@ export const KNOWLEDGE = [
|
|
|
15
15
|
id: 'bazi-yueling-siquan',
|
|
16
16
|
system: 'bazi', dims: ['overall', 'career'],
|
|
17
17
|
gist: '月令不是「一个月」,是当月最有权的那一个字。',
|
|
18
|
-
detail: '
|
|
19
|
-
source: '
|
|
18
|
+
detail: '月令藏干按本气、中气、余气分日用事,本气当权的时间最长。所以判旺衰先看日主在月令是得令还是失令——得令者未看全局,已有三分底气。本插件按 30 日表算出「生在本月第几日、哪一干当权」,给的是月内轮值这一层细节;旺衰与取格仍以月令本气、透干与会支为主,不随轮值改判。三命通会卷二·论人元司事另列一套日数(寅月五日/五日/二十日),与本插件取的通行表不同;原文并列,不改判。',
|
|
19
|
+
source: '《子平真诠》论用神;人元司权分日之说见《渊海子平》;三命通会卷二·论人元司事(典藏网 7529)另列一套日数',
|
|
20
20
|
status: 'variant',
|
|
21
|
-
note: '各家对中气、余气各主几日分法不同(有 7/7/16、9/3/18
|
|
21
|
+
note: '各家对中气、余气各主几日分法不同(有 7/7/16、9/3/18 等多说);本插件固定通行 30 日表(如寅月戊7丙7甲16),节当日为第 1 日,第 31 日以后按本气算、不硬分摊。三命通会此本寅月作 5/5/20、卯月作 7/23,与通行表不同,两表各照原样。司权表与本柱藏干表口径不同(子月壬、卯月甲、午月丙、酉月庚、亥月戊只出现在司权表里),两表各照原样;取格不随轮值改判。',
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
id: 'bazi-tonggen-tougan',
|
|
@@ -66,10 +66,10 @@ export const KNOWLEDGE = [
|
|
|
66
66
|
id: 'bazi-suiyun',
|
|
67
67
|
system: 'bazi', dims: ['overall', 'career'],
|
|
68
68
|
gist: '大运管十年基调,流年管当年触发。',
|
|
69
|
-
detail: '
|
|
70
|
-
source: '
|
|
69
|
+
detail: '大运像换了条路,流年像这条路上某一段的天气。岁运并临(当值大运与流年干支相同)、运年反吟(大运与流年天克地冲)、大运伏吟(大运与原局某柱干支相同)、大运反吟(大运与原局某柱天克地冲)、流年伏吟(流年与原局某柱干支相同)、流年反吟(流年与原局某柱天克地冲),是传统上标记「变动较大」的年份,属于提示而非断语。本插件逐年标出六类信号:当值大运按该年立春到次年立春的区间取,交运落在年内时前后两步并列;大运与本命四柱的伏吟/反吟整步大运都在,会连续多年重复列出;只标干支重复与对冲,不折分数。原文里「返吟」指岁运与日柱相对、「伏吟」指岁运压日,与本插件「干支相同为伏吟、天克地冲为反吟」不是同一套定义,两者并列、不合并。',
|
|
70
|
+
source: '《三命通会》卷二·总论岁运(https://www.diancang.xyz/xuanxuewushu/sanmingtonghui/7539.html);岁运并临之说出自《渊海子平》',
|
|
71
71
|
status: 'variant',
|
|
72
|
-
note: '
|
|
72
|
+
note: '「岁运并临主大凶」是流传最广也最被滥用的说法,本插件只作变动提示,不断吉凶;大运与本命四柱的伏吟/反吟会连续多年出现,不逐年加重;四柱十神层面的引化也未叠入。',
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
id: 'bazi-liuqin',
|
|
@@ -125,6 +125,15 @@ export const KNOWLEDGE = [
|
|
|
125
125
|
status: 'variant',
|
|
126
126
|
note: '化气格成立条件各家宽严不一(是否要求月令为化神、日主是否允许有根),本插件只列条件、附原文,不据此断定化气已成。',
|
|
127
127
|
},
|
|
128
|
+
{
|
|
129
|
+
id: 'bazi-zaji-quyong',
|
|
130
|
+
system: 'bazi', dims: ['overall', 'career'],
|
|
131
|
+
gist: '辰戌丑未是杂气月:先看透干,再看会支。',
|
|
132
|
+
detail: '四墓(辰戌丑未)每个字都藏着不止一气,用神不一,所以叫杂气。子平真诠的取法是:藏干透到天干的先用(甲生辰月,透戊用偏财、透癸用正印、透乙用月劫);没有透干,再看地支有没有与月支会成三合局(辰月逢申子会水,就取水印)。本插件按「透干 → 三合会支 → 本气」的次序取格,依据里写明走的是哪一条,并把《论杂气如何取用》附在结果里。',
|
|
133
|
+
source: '《子平真诠》十六、论杂气如何取用',
|
|
134
|
+
status: 'variant',
|
|
135
|
+
note: '原文说「兼透则兼用」,但只给一个格名时总要落到一个藏干;本插件只取最先透出的那一干,会支也只认三合、不认三会方,且不判原文所说的「有情 / 无情」,取舍次序各家另有说法。',
|
|
136
|
+
},
|
|
128
137
|
{
|
|
129
138
|
id: 'bazi-zhuanwang-yuanwen',
|
|
130
139
|
system: 'bazi', dims: ['overall', 'career'],
|
|
@@ -290,10 +299,10 @@ export const KNOWLEDGE = [
|
|
|
290
299
|
id: 'liuyao-yingqi',
|
|
291
300
|
system: 'liuyao', dims: ['overall', 'career'],
|
|
292
301
|
gist: '应期是「什么时候见分晓」,不是「哪天」。',
|
|
293
|
-
detail: '
|
|
302
|
+
detail: '近事以日计、远事以月计;常见取法是等用神逢值、逢冲、逢合之期,或等忌神受制之期。本插件只做前一半:把用神(不上卦则取伏神)的逢值、逢冲、逢合三支列出,旬空另标出空与冲空,再按月建五态给「偏速 / 偏缓 / 待解 / 未定」一个快慢方向;忌神受制与具体日期仍未做。应期法各家互有出入,同一卦不同取法可以差出很远,所以只作时间窗口的提示。',
|
|
294
303
|
source: '《卜筮正宗》应期章;《增删卜易》',
|
|
295
304
|
status: 'variant',
|
|
296
|
-
note: '
|
|
305
|
+
note: '应期取法(值日、冲、合、填实、旬空出空)各家优先级不同,本插件只并列触发支、不排先后,也不换算日期;近事以日计、远事以月计,用哪把尺由事情远近决定,不代选。',
|
|
297
306
|
},
|
|
298
307
|
{
|
|
299
308
|
id: 'liuyao-liushen',
|
|
@@ -450,10 +459,10 @@ export const KNOWLEDGE = [
|
|
|
450
459
|
id: 'liuyao-yingqi-exact',
|
|
451
460
|
system: 'liuyao', dims: [],
|
|
452
461
|
gist: '具体应期(哪一天应验)本插件尚未推算。',
|
|
453
|
-
detail: '
|
|
462
|
+
detail: '应期需要综合用神旺衰、动变、旬空出空、日月冲合多层条件,且各家取法不同。当前只给时间窗口的方向性提示(逢值 / 逢冲 / 逢合的触发支,加一个快慢方向),不给具体日期——与其给一个看起来精确、实则拍脑袋的日子,不如留白。',
|
|
454
463
|
source: '待补:《卜筮正宗》应期章逐条实现 + 已录 128 条卦例对拍(源 138 条)',
|
|
455
464
|
status: 'todo',
|
|
456
|
-
note: '扩展方向:用《卜筮正宗》卦例里有明确应验日期的条目做回归,先验证再输出。',
|
|
465
|
+
note: '扩展方向:用《卜筮正宗》卦例里有明确应验日期的条目做回归,先验证再输出。0.50.0 已给出触发支与快慢方向,仍不输出日期。',
|
|
457
466
|
},
|
|
458
467
|
];
|
|
459
468
|
|
|
@@ -90,6 +90,19 @@ function jinTuiPlain(r) {
|
|
|
90
90
|
return `动爻的进退还要看时令:${jp.lines.map((l) => `${l.position}爻${l.from}→${l.to}${l.type},${sayOf(l)}`).join(';')}。`;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
+
// 应期线索 → 一句白话:只给快慢与可留意的支,不换算日期
|
|
94
|
+
function yingqiPlain(r) {
|
|
95
|
+
const yq = r && r.yingqi;
|
|
96
|
+
if (!yq || !Array.isArray(yq.triggers) || !yq.triggers.length) return '';
|
|
97
|
+
const when = yq.tempo === '偏速' ? '大体偏近,近事更容易先见分晓'
|
|
98
|
+
: yq.tempo === '偏缓' ? '大体偏远,别指望立刻见分晓'
|
|
99
|
+
: yq.tempo === '待解' ? '眼下还有月破或旬空,得先等条件解除'
|
|
100
|
+
: '缺月建,快慢暂不定';
|
|
101
|
+
const branches = yq.triggers.map((t) => t.branch).join('、');
|
|
102
|
+
const fu = yq.viaFushen ? '(用神是伏神,先要出得来)' : '';
|
|
103
|
+
return `应期上${when};传统会留意${branches}这几个地支${fu}——这只是提示,不换算成具体哪天。`;
|
|
104
|
+
}
|
|
105
|
+
|
|
93
106
|
// 全卦逐爻旺衰 → 一句白话:整张卦的气偏在哪一头(与用神那一句分开说)
|
|
94
107
|
function hexStrengthPlain(hs) {
|
|
95
108
|
if (!hs || !hs.counts) return '';
|
|
@@ -200,7 +213,7 @@ export function buildAnswer(r, ask, ctx = {}) {
|
|
|
200
213
|
head + `先说结论:本卦是${s(ben.name, '—')}` +
|
|
201
214
|
`${ben.palace ? `(${ben.palace})` : ''}` +
|
|
202
215
|
`${moving.length ? `,第 ${moving.join('、')} 爻动,变为${s(bian.name, '—')}` : ',六爻安静没有动爻'}。` +
|
|
203
|
-
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${hexStrengthPlain(r.hexStrength)}`,
|
|
216
|
+
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${yingqiPlain(r)}${hexStrengthPlain(r.hexStrength)}`,
|
|
204
217
|
'断卦的落点在「世爻」(代表你)和「动爻」(事情的推动点),下面「看盘顺序」就按这个次序展开。',
|
|
205
218
|
].join('');
|
|
206
219
|
}
|
|
@@ -226,6 +239,9 @@ export function buildPlain(r, ask, ctx = {}) {
|
|
|
226
239
|
const ys = (r.frame && r.frame.yongshen) || {};
|
|
227
240
|
const favor = join(ys.favor);
|
|
228
241
|
const avoid = join(ys.avoid);
|
|
242
|
+
const dis = Array.isArray(ys.disputed) && ys.disputed.length
|
|
243
|
+
? `有一点要说明:${ys.disputed.map((d) => d.element).join('、')}在扶抑里算${ys.disputed.map((d) => d.favorRole).join('、')}(能${ys.disputed.map((d) => d.favorVerb).join('、')}),按调候看又偏忌(${ys.disputed.map((d) => `${d.climate}盘忌${d.element}`).join('、')}),两派说法不一;实际用在什么时候,看季节和环境取舍,不必当成绝对的好或坏。`
|
|
244
|
+
: '';
|
|
229
245
|
const strength = STRENGTH_PLAIN[st.level] || '力量偏中性';
|
|
230
246
|
const tiaohou = ys.tiaohou && ys.tiaohou.note ? `另外,${ys.tiaohou.note},所以「暖一点、亮一点」的环境通常更舒服。` : '';
|
|
231
247
|
const sy = (r.liunian || []).find((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
@@ -234,7 +250,7 @@ export function buildPlain(r, ask, ctx = {}) {
|
|
|
234
250
|
: '';
|
|
235
251
|
return `你的命局属于「${s(st.level, '中性')}」:${strength}。` +
|
|
236
252
|
`${favor ? `能补${favor}的环境(行业、方位、作息、相处的人)会让你省力;${avoid ? `而${avoid}偏重的场合容易空耗,能绕就绕。` : ''}` : ''}` +
|
|
237
|
-
tiaohou + syPlain;
|
|
253
|
+
dis + tiaohou + syPlain;
|
|
238
254
|
}
|
|
239
255
|
if (r.system === 'ziwei') {
|
|
240
256
|
const body = r.body || {};
|
|
@@ -268,7 +284,7 @@ export function buildPlain(r, ask, ctx = {}) {
|
|
|
268
284
|
const plainBody = bodyPlainOf(labels);
|
|
269
285
|
return `${s(ben.name, '这一卦')}讲的是一个「${moving.length ? '正在动、还会变' : '暂时不动、先看清'}」的局面——` +
|
|
270
286
|
`${moving.length ? '有动爻,说明事情还有转圜空间,不是死局。' : '六爻安静,说明当下更该观察而不是硬推。'}` +
|
|
271
|
-
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${hexStrengthPlain(r.hexStrength)}`;
|
|
287
|
+
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${yingqiPlain(r)}${hexStrengthPlain(r.hexStrength)}`;
|
|
272
288
|
}
|
|
273
289
|
return '';
|
|
274
290
|
}
|
package/engine/interpret.js
CHANGED
|
@@ -170,6 +170,7 @@ function baziInterpret(r) {
|
|
|
170
170
|
const level = pick(st, 'level', '中和');
|
|
171
171
|
const favor = Array.isArray(ys.favor) ? ys.favor : [];
|
|
172
172
|
const avoid = Array.isArray(ys.avoid) ? ys.avoid : [];
|
|
173
|
+
const disputed = Array.isArray(ys.disputed) ? ys.disputed : [];
|
|
173
174
|
const primary = pick(frame, 'primaryName', '未取定');
|
|
174
175
|
const gender = pick(r.input, 'gender', '');
|
|
175
176
|
const isMale = gender === 'male';
|
|
@@ -395,6 +396,21 @@ function baziInterpret(r) {
|
|
|
395
396
|
`⑤ 落到维度:工作看喜用五行与十神权重;感情看配偶星与日支;健康看最旺与最弱的五行。五维度都只是这套推导的应用,不是另一套算法。`,
|
|
396
397
|
].join('\n'),
|
|
397
398
|
},
|
|
399
|
+
...(r.renyuan ? [(() => {
|
|
400
|
+
const ry = r.renyuan;
|
|
401
|
+
const table = ry.segments.map((s) => `${s.stem}${s.from}–${s.to}`).join(' / ');
|
|
402
|
+
const nextSeg = ry.next ? `,第 ${ry.next.from} 日起交 ${ry.next.stem}${ry.next.element}` : '';
|
|
403
|
+
const outside = ry.inHidden ? '' : ` 表里的 ${ry.active} 不在本柱藏干表中(属余气口径),两表各照原样,不互相改写。`;
|
|
404
|
+
const beyond = ry.beyond ? ' 你生在第 31 日以后,已超出 30 日表,按本气算,不硬分摊。' : '';
|
|
405
|
+
const ryc = r.renyuanClassic || classicOf('smt-renyuan');
|
|
406
|
+
const src = ryc ? `\n原文:《${CLASSIC_BOOKS[ryc.book].name}·${ryc.chapter}》「${ryc.quote}」\n白话:${ryc.plain}` : '';
|
|
407
|
+
return {
|
|
408
|
+
key: 'renyuan', label: '人元司权',
|
|
409
|
+
text: `生于${ry.month}月第 ${ry.day} 日(从${ry.term ? ry.term.name : '节'}起算,节当日为第 1 日,日差按本盘所用时刻所在日计):这一日由 **${ry.active}${ry.activeElement}** 司权,第 ${ry.segment.from}–${ry.segment.to} 日属它${nextSeg}。\n`
|
|
410
|
+
+ '月令这一个月里,余气、中气、本气轮值,不是整月同一个五行当值——所以「月令是什么」,还要看生在第几日。\n'
|
|
411
|
+
+ `**口径**:本插件固定通行 30 日表(${table});另有 7/7/16、9/3/18 等分法,三命通会此本又作 5/5/20(见下原文),各家不一。分日只作解释层的一层细节,**不改取格**:取格仍按本气、透干与会支判定。${outside}${beyond}` + src,
|
|
412
|
+
};
|
|
413
|
+
})()] : []),
|
|
398
414
|
{
|
|
399
415
|
key: 'timeline', label: '时间窗',
|
|
400
416
|
text: (() => {
|
|
@@ -415,6 +431,8 @@ function baziInterpret(r) {
|
|
|
415
431
|
{ key: 'advice', label: '专业建议', text: adviceText },
|
|
416
432
|
(() => {
|
|
417
433
|
const hits = (r.liunian || []).filter((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
434
|
+
const e = suiyunClassicOf(r);
|
|
435
|
+
const src = e ? `\n原文:《${CLASSIC_BOOKS[e.book].name}·${e.chapter}》「${e.quote}」\n白话:${e.plain}` : '';
|
|
418
436
|
return {
|
|
419
437
|
key: 'suiyun', label: '岁运提示',
|
|
420
438
|
text: hits.length
|
|
@@ -422,8 +440,8 @@ function baziInterpret(r) {
|
|
|
422
440
|
const stem = (l.suiyun.dayun || []).map((d) => `第${d.step}步${d.ganzhi}`).join('、');
|
|
423
441
|
return `${l.year} ${l.ganzhi}(${stem || '未到起运'}):${l.suiyun.signals.map((s) => s.detail).join(';')}`;
|
|
424
442
|
}).join('\n') +
|
|
425
|
-
'\n
|
|
426
|
-
: '
|
|
443
|
+
'\n读法:岁运并临、运年反吟、大运与流年的伏吟/反吟只说明干支层面重复或对冲,传统上当作「变动感较强」的信号;本插件不据此判吉凶,要落到具体年份,仍看该年是否动到用神。大运与本命四柱的伏吟/反吟整步大运都在,会连续多年出现,不当成逐年加重。' + src
|
|
444
|
+
: '近十年没有岁运并临、运年反吟或大运/流年伏吟、反吟。「岁运并临主大凶」这类说法流传很广,本插件只把它当变动提示,没有命中就不作额外解读。',
|
|
427
445
|
};
|
|
428
446
|
})(),
|
|
429
447
|
{
|
|
@@ -460,7 +478,7 @@ function baziInterpret(r) {
|
|
|
460
478
|
...(cli ? [{
|
|
461
479
|
key: 'climate', label: '寒暖燥湿',
|
|
462
480
|
text: `${cli.narration}${cli.need
|
|
463
|
-
? `调候取${cli.need.stem}${cli.need.element},忌${cli.avoidElement};${cli.clash ? '与扶抑冲突,本盘以调候为先' : '与扶抑同向'}`
|
|
481
|
+
? `调候取${cli.need.stem}${cli.need.element},忌${cli.avoidElement}${disputed.some((d) => d.element === cli.avoidElement) ? '(有争议:该行在扶抑中为喜,见用神节)' : ''};${cli.clash ? '与扶抑冲突,本盘以调候为先' : disputed.some((d) => d.element === cli.avoidElement) ? '调候所忌在扶抑里为喜,两说并存' : '与扶抑同向'}`
|
|
464
482
|
: '气候平和,调候不作主取'}。`,
|
|
465
483
|
}] : []),
|
|
466
484
|
...(ys.qt ? [{
|
|
@@ -1207,10 +1225,32 @@ function liuyaoInterpret(r, ask) {
|
|
|
1207
1225
|
useText.push(`时令对用神:${head},日辰 ${strength.day ? `${strength.day.branch}(${strength.day.element})` : '—'}。${body.join(';')}。`);
|
|
1208
1226
|
useText.push('月建看这一段时令站在哪一边,日辰看当天那股力量是扶还是克;两处同时看,只报状态,不折成分数。');
|
|
1209
1227
|
}
|
|
1210
|
-
useText.push('
|
|
1228
|
+
useText.push('这一层只把用神、卦体与时令对起来,不折成分数、不断成败;应期另在「应期线索」一节只给触发支与快慢。');
|
|
1211
1229
|
sections.push({ key: 'yongshen', label: '用神落位与卦体', text: useText.join('\n') });
|
|
1212
1230
|
}
|
|
1213
1231
|
|
|
1232
|
+
// 应期线索:只给触发支与快慢方向,不给日期
|
|
1233
|
+
{
|
|
1234
|
+
const yq = r.yingqi;
|
|
1235
|
+
if (yq && Array.isArray(yq.items) && yq.items.length) {
|
|
1236
|
+
const rows = yq.items.map((it) => {
|
|
1237
|
+
const flags = [
|
|
1238
|
+
it.monthState && it.monthState !== 'unknown' ? `月建${it.monthState}` : '',
|
|
1239
|
+
it.monthChong ? '月破' : '',
|
|
1240
|
+
it.kong ? '旬空' : '',
|
|
1241
|
+
].filter(Boolean).join('、');
|
|
1242
|
+
return `${it.position}爻${it.branch}${it.element}${flags ? `(${flags})` : ''}:${it.tempoSay}`;
|
|
1243
|
+
});
|
|
1244
|
+
sections.push({
|
|
1245
|
+
key: 'yingqi',
|
|
1246
|
+
label: '应期线索',
|
|
1247
|
+
text: `应期快慢:${yq.tempoSay}。${rows.join(';')}。可留意的地支:${yq.triggers.map((t) => `${t.branch}(${t.labels.join('、')})`).join(';')}。` +
|
|
1248
|
+
`${yq.viaFushen ? '用神不上卦,这里的支取自伏神;伏神要先得出才算数。' : ''}` +
|
|
1249
|
+
'这一节只把传统的「逢值、逢冲、逢合」与旬空的出空、冲空摆出来,不换算成具体日期、不排先后、也不判忌神受制;近事以日计、远事以月计,用哪把尺取决于事情本身。',
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
|
|
1214
1254
|
// 全卦逐爻旺衰:不挑用神,六爻都过一遍,看整张卦的气压在哪一头
|
|
1215
1255
|
{
|
|
1216
1256
|
const hs = r.hexStrength;
|
|
@@ -1240,7 +1280,7 @@ function liuyaoInterpret(r, ask) {
|
|
|
1240
1280
|
|
|
1241
1281
|
sections.push({
|
|
1242
1282
|
key: 'limits', label: '未纳入',
|
|
1243
|
-
text: '
|
|
1283
|
+
text: '本卦没有计算:用神两现时该取哪一爻的权重、应期的具体日期(只给逢值/逢冲/逢合的触发支与快慢方向)、忌神受制的时点、动变连环。化进/化退的力重只按月建五态给「得令/失令」这类档位,不折成加权分数;这些都会改变"旺不旺"的判断,所以这里只给取象与方向。',
|
|
1244
1284
|
});
|
|
1245
1285
|
|
|
1246
1286
|
const dimensions = [
|
|
@@ -1666,7 +1706,7 @@ const BUILDERS = {
|
|
|
1666
1706
|
import { interpretQimen } from './qimen-interpret.js';
|
|
1667
1707
|
import { buildAnswer, buildPlain, buildGlossary, buildFollowups, dimensionPlain } from './interpret-plain.js';
|
|
1668
1708
|
import { knowledgeFor, caveatsFor, STATUS_LABEL } from './interpret-knowledge.js';
|
|
1669
|
-
import { CLASSIC_BOOKS } from './classics.js';
|
|
1709
|
+
import { CLASSIC_BOOKS, suiyunClassicOf, classicOf } from './classics.js';
|
|
1670
1710
|
|
|
1671
1711
|
/**
|
|
1672
1712
|
* 给任意体系的解析结果补上「白话四层」:直答 / 说人话 / 每维一句话 / 追问建议。
|