dsh-metaphysics 0.59.1 → 0.61.0
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 +1550 -1378
- package/README.md +17 -14
- package/client.almanac.js +60 -59
- package/client.bazi.js +118 -109
- package/client.chenggu.js +61 -60
- package/client.convert.js +60 -59
- package/client.daliuren.js +117 -116
- package/client.fengshui.js +62 -61
- package/client.hepan.js +117 -108
- package/client.js +422 -341
- package/client.liuyao.js +122 -120
- package/client.mbti.js +63 -62
- package/client.name.js +71 -70
- package/client.numerology.js +63 -62
- package/client.qimen.js +114 -113
- package/client.star.js +66 -65
- package/client.tarot.js +118 -117
- package/client.trend.js +112 -111
- package/client.xiaoliuren.js +77 -76
- package/client.zeri.js +66 -65
- package/client.ziwei.js +121 -112
- package/engine/calendar.js +8 -2
- package/engine/citations.js +4 -0
- package/engine/diff.js +3 -0
- package/engine/dst.js +28 -1
- package/engine/event-prompt.js +7 -1
- package/engine/followup.js +16 -1
- package/engine/handle.js +6 -2
- package/engine/index.js +101 -16
- package/engine/interpret-knowledge.js +21 -0
- package/engine/interpret.js +7 -3
- package/engine/liuyao.js +4 -0
- package/engine/lunar.js +10 -11
- package/engine/meihua.js +3 -0
- package/engine/name-data.js +24 -78
- package/engine/name-extra.js +415 -0
- package/engine/name.js +36 -9
- package/engine/plain-summary.js +5 -1
- package/engine/random.js +9 -1
- package/engine/rectify.js +24 -3
- package/engine/surname-data.js +249 -0
- package/engine/tarot-cards.js +143 -0
- package/engine/tarot.js +74 -27
- package/engine/trend.js +29 -20
- package/engine/yijing-text.js +792 -0
- package/engine/zeri-shensha.js +958 -0
- package/engine/zeri.js +151 -37
- package/engine/ziwei-zuoyao.js +313 -0
- package/engine/ziwei.js +42 -3
- package/index.js +35 -13
- package/package.json +5 -4
- package//345/221/275/347/220/206/346/216/222/347/233/230.html +4090 -285
package/engine/zeri.js
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
1
|
+
// 择日:逐日按《协纪辨方书》卷十一「用事」命中宜忌,再用卷十「宜忌」六等与德神制化定吉凶方向,
|
|
2
|
+
// 叠冲属相排除后排序。口径透明:这是排序引导,不是吉凶断语。
|
|
3
3
|
import { fromJDN, toJDN } from './calendar.js';
|
|
4
4
|
import { buildAlmanac, SHENGXIAO } from './almanac.js';
|
|
5
|
+
import {
|
|
6
|
+
computeDayShensha, taskShenshaHits, xingHitText, gradeDay,
|
|
7
|
+
ZERI_SHENSHA_BASIS, ZERI_JUAN10_BASIS,
|
|
8
|
+
} from './zeri-shensha.js';
|
|
9
|
+
import { fail } from './fail.js';
|
|
10
|
+
|
|
11
|
+
// 择日的入参错误一律带 E_INPUT:裸 new Error 到工具层只剩 [E_INTERNAL],
|
|
12
|
+
// 模型拿到的是一句没有指向性的文案,改不了参数。
|
|
13
|
+
const bad = (message) => fail('E_INPUT', message);
|
|
5
14
|
|
|
6
15
|
/** 支持的事项:直接宜词 + 关联宜词(黄历措辞)。 */
|
|
7
16
|
export const TASKS = {
|
|
@@ -60,20 +69,40 @@ const ZHIXING_FAVOR = {
|
|
|
60
69
|
medical: ['除', '开'],
|
|
61
70
|
};
|
|
62
71
|
|
|
63
|
-
const
|
|
72
|
+
const VERDICT_RANK = { 推荐: 3, 可用: 2, 平平: 1, 回避: 0 };
|
|
73
|
+
|
|
74
|
+
/** 由卷十「六等」与德神制化判定的决断,映射到界面用语。 */
|
|
75
|
+
const verdictOf = (grade, ctx) => {
|
|
64
76
|
if (ctx.chongSelf) {
|
|
65
77
|
return { verdict: '回避', text: `当日冲${ctx.chongSelf}(当事人属相):传统择日径直排除,不进推荐与可用名单。`, excluded: true };
|
|
66
78
|
}
|
|
67
|
-
|
|
68
|
-
|
|
79
|
+
const basis = `${grade.label}(${grade.doctrine})→ ${grade.decision}`;
|
|
80
|
+
const tally = `吉 ${grade.ji}、凶 ${grade.xiong}`;
|
|
81
|
+
if (grade.forced.length) {
|
|
69
82
|
return {
|
|
70
|
-
verdict: '
|
|
71
|
-
text:
|
|
83
|
+
verdict: '回避',
|
|
84
|
+
text: `卷十 ${grade.label},但所问事项正在德神亦不解的余忌之列(${grade.forced.map((g) => g.name).join('、')}):${grade.doctrine},故仍忌。`,
|
|
72
85
|
excluded: false,
|
|
73
86
|
};
|
|
74
87
|
}
|
|
75
|
-
if (
|
|
76
|
-
|
|
88
|
+
if (grade.decision === '从宜不从忌') {
|
|
89
|
+
if (grade.score >= 2) {
|
|
90
|
+
return { verdict: '推荐', text: `卷十作 ${basis};${tally},宜项足以胜忌。`, excluded: false };
|
|
91
|
+
}
|
|
92
|
+
return { verdict: '可用', text: `卷十作 ${basis};${tally},可用但助力不厚。`, excluded: false };
|
|
93
|
+
}
|
|
94
|
+
if (grade.decision === '从宜亦从忌') {
|
|
95
|
+
return { verdict: '可用', text: `卷十作 ${basis};${tally},宜忌并见,择时仍须避开忌项。`, excluded: false };
|
|
96
|
+
}
|
|
97
|
+
if (grade.decision === '不宜不忌') {
|
|
98
|
+
return { verdict: '平平', text: `卷十作 ${basis};${tally},无所助也无所忌。`, excluded: false };
|
|
99
|
+
}
|
|
100
|
+
if (grade.decision === '从忌不从宜') {
|
|
101
|
+
const why = ctx.avoidText.length ? `忌项:${ctx.avoidText.join('、')}。` : '';
|
|
102
|
+
return { verdict: '回避', text: `卷十作 ${basis};${tally},${why}此日对所问事项不宜。`, excluded: false };
|
|
103
|
+
}
|
|
104
|
+
const why = ctx.avoidText.length ? `忌项:${ctx.avoidText.join('、')};` : '';
|
|
105
|
+
return { verdict: '回避', text: `卷十作 ${basis};${tally},${why}传统作诸事皆忌。`, excluded: false };
|
|
77
106
|
};
|
|
78
107
|
|
|
79
108
|
/**
|
|
@@ -104,39 +133,50 @@ const ymd = (p) => `${p.year}-${String(p.month).padStart(2, '0')}-${String(p.day
|
|
|
104
133
|
*/
|
|
105
134
|
export function buildZeri(input) {
|
|
106
135
|
const task = input.task;
|
|
107
|
-
if (!TASKS[task]) throw
|
|
136
|
+
if (!TASKS[task]) throw bad(`不支持的事项「${task}」。支持:${Object.keys(TASKS).join('、')}`);
|
|
108
137
|
const shengXiaoRaw = typeof input.shengXiao === 'string' ? input.shengXiao.trim() : '';
|
|
109
138
|
const shengXiao = shengXiaoRaw || null;
|
|
110
|
-
if (shengXiao && !SHENGXIAO.includes(shengXiao)) throw
|
|
139
|
+
if (shengXiao && !SHENGXIAO.includes(shengXiao)) throw bad(`shengXiao 须为生肖名:${SHENGXIAO.join('、')}`);
|
|
111
140
|
|
|
112
141
|
// 候选日模式:只比用户给的这几天,不再按区间扫
|
|
113
142
|
let candidates = null;
|
|
114
143
|
if (input.candidates !== undefined && input.candidates !== null) {
|
|
115
144
|
if (!Array.isArray(input.candidates)) {
|
|
116
|
-
throw
|
|
145
|
+
throw bad('candidates 须为日期数组,例如 ["2026-12-01","2026-12-08","2026-12-15"]');
|
|
117
146
|
}
|
|
118
|
-
if (input.candidates.length < 2) throw
|
|
119
|
-
if (input.candidates.length > 12) throw
|
|
147
|
+
if (input.candidates.length < 2) throw bad('candidates 至少给 2 个候选日;只想看一天请用 startDate + days: 1');
|
|
148
|
+
if (input.candidates.length > 12) throw bad('candidates 最多 12 个候选日;更多请用 startDate + days 扫区间');
|
|
120
149
|
const seen = new Set();
|
|
121
150
|
candidates = [];
|
|
122
151
|
for (const raw of input.candidates) {
|
|
123
152
|
const p = parseYmd(raw);
|
|
124
|
-
if (!p) throw
|
|
153
|
+
if (!p) throw bad(`候选日不是真实存在的公历日期:「${raw}」,请用 2026-12-01 这种格式`);
|
|
125
154
|
const key = ymd(p);
|
|
126
155
|
if (seen.has(key)) continue;
|
|
127
156
|
seen.add(key);
|
|
128
157
|
candidates.push(p);
|
|
129
158
|
}
|
|
130
|
-
if (candidates.length < 2) throw
|
|
159
|
+
if (candidates.length < 2) throw bad('候选日去重后不足 2 天;至少要两个不同的日子才谈得上比较');
|
|
131
160
|
}
|
|
132
161
|
|
|
133
162
|
let start = null;
|
|
134
163
|
let days = 0;
|
|
135
164
|
if (!candidates) {
|
|
136
165
|
const m = /^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(String(input.startDate || '').trim());
|
|
137
|
-
if (!m) throw
|
|
166
|
+
if (!m) throw bad('择日需要 startDate(公历 YYYY-MM-DD)——请向用户询问起算日,不要代填');
|
|
138
167
|
start = { year: Number(m[1]), month: Number(m[2]), day: Number(m[3]) };
|
|
139
|
-
days
|
|
168
|
+
// days 以前只认 Number.isInteger,于是 "45"(模型很爱给字符串)与 45.5 都静默变成 30 天:
|
|
169
|
+
// 用户要的区间被悄悄改短,而结果里只看得到实际扫了几天,看不出被改过。
|
|
170
|
+
// 现在:能规范成整数的(含数字串)就规范,范围外或非数字一律报错,不猜。
|
|
171
|
+
const rawDays = input.days;
|
|
172
|
+
if (rawDays === undefined || rawDays === null || rawDays === '') {
|
|
173
|
+
days = 30;
|
|
174
|
+
} else {
|
|
175
|
+
const n = Number(rawDays);
|
|
176
|
+
if (!Number.isInteger(n)) throw bad(`择日的 days 要是 1–60 的整数,收到「${rawDays}」`);
|
|
177
|
+
if (n < 1 || n > 60) throw bad(`择日的 days 要在 1–60 之间(${n} 超出范围);更长请用分段多次查询`);
|
|
178
|
+
days = n;
|
|
179
|
+
}
|
|
140
180
|
}
|
|
141
181
|
|
|
142
182
|
const spec = TASKS[task];
|
|
@@ -144,21 +184,33 @@ export function buildZeri(input) {
|
|
|
144
184
|
|
|
145
185
|
const makeRow = (p) => {
|
|
146
186
|
const a = buildAlmanac(p);
|
|
147
|
-
|
|
187
|
+
const monthBranch = a.ganzhi.month.slice(-1);
|
|
188
|
+
const dayInfo = computeDayShensha({
|
|
189
|
+
monthBranch,
|
|
190
|
+
dayGz: a.ganzhi.day,
|
|
191
|
+
xing: a.zhiXing,
|
|
192
|
+
lunarDay: a.lunar.day,
|
|
193
|
+
});
|
|
194
|
+
const hits = taskShenshaHits(task, dayInfo);
|
|
195
|
+
|
|
196
|
+
const grade = gradeDay(hits, dayInfo);
|
|
197
|
+
const favor = zhixingSet.includes(a.zhiXing);
|
|
198
|
+
const score = grade.score;
|
|
199
|
+
|
|
148
200
|
const reasons = [];
|
|
149
|
-
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
if (
|
|
153
|
-
|
|
154
|
-
if (
|
|
201
|
+
// 建除适配是现代简表,只作同分参考,不进卷十吉凶轻重。
|
|
202
|
+
if (favor) reasons.push(`建除${a.zhiXing}神利${task}(现代简表,参考不计分)`);
|
|
203
|
+
if (grade.good.length) reasons.push(`宜项:${grade.good.map((g) => `${g.name}(${g.w})`).join('、')},合吉 ${grade.ji}`);
|
|
204
|
+
if (grade.remains.length) reasons.push(`忌项:${grade.remains.map((g) => `${g.name}(${g.w})`).join('、')},合凶 ${grade.xiong}`);
|
|
205
|
+
if (grade.resolved.length) reasons.push(`德神可解:${grade.resolved.map((g) => g.name).join('、')}`);
|
|
206
|
+
if (grade.forced.length) reasons.push(`德神犹忌(所问正在余忌):${grade.forced.map((g) => g.name).join('、')}`);
|
|
207
|
+
reasons.push(`卷十 ${grade.label}:${grade.doctrine},${grade.decision}`);
|
|
208
|
+
|
|
155
209
|
const chongSelf = shengXiao && a.chong.shengXiao === shengXiao ? shengXiao : null;
|
|
156
|
-
if (chongSelf)
|
|
157
|
-
if (zhixingSet.includes(a.zhiXing)) { score += 1; reasons.push(`建除${a.zhiXing}神利${task}(+1)`); }
|
|
158
|
-
if (a.zhiXing === '破' && spec.category !== 'burial') { score -= 1; reasons.push('破日(-1)'); }
|
|
159
|
-
if (a.zhiXing === '危' && spec.category !== 'travel' && spec.category !== 'worship') { score -= 1; reasons.push('危日(-1)'); }
|
|
210
|
+
if (chongSelf) reasons.push(`冲${shengXiao}(当事人属相,径直排除)`);
|
|
160
211
|
|
|
161
|
-
const
|
|
212
|
+
const avoidText = grade.remains.map((g) => g.name);
|
|
213
|
+
const v = verdictOf(grade, { chongSelf, avoidText });
|
|
162
214
|
return {
|
|
163
215
|
date: a.meta.date,
|
|
164
216
|
weekday: a.meta.weekday,
|
|
@@ -169,9 +221,44 @@ export function buildZeri(input) {
|
|
|
169
221
|
ji: a.ji,
|
|
170
222
|
chong: a.chong.shengXiao,
|
|
171
223
|
score,
|
|
224
|
+
favor,
|
|
172
225
|
reasons,
|
|
173
226
|
verdict: v.verdict,
|
|
174
227
|
verdictText: v.text,
|
|
228
|
+
grade: {
|
|
229
|
+
key: grade.key,
|
|
230
|
+
label: grade.label,
|
|
231
|
+
doctrine: grade.doctrine,
|
|
232
|
+
decision: grade.decision,
|
|
233
|
+
withDe: grade.withDe,
|
|
234
|
+
de: grade.de,
|
|
235
|
+
ji: grade.ji,
|
|
236
|
+
xiong: grade.xiong,
|
|
237
|
+
ratio: grade.ratio,
|
|
238
|
+
resolved: grade.resolved.map((g) => g.name),
|
|
239
|
+
remains: grade.remains.map((g) => g.name),
|
|
240
|
+
forced: grade.forced.map((g) => g.name),
|
|
241
|
+
...(grade.allJiCombo ? { combo: '月厌叠月破/灾煞:虽遇德仍诸事皆忌' } : {}),
|
|
242
|
+
note: grade.note,
|
|
243
|
+
},
|
|
244
|
+
shensha: {
|
|
245
|
+
monthBranch,
|
|
246
|
+
xing: dayInfo.xing,
|
|
247
|
+
names: dayInfo.names,
|
|
248
|
+
use: {
|
|
249
|
+
xing: hits.use.xing.map((h) => xingHitText(h)),
|
|
250
|
+
shensha: hits.use.shensha,
|
|
251
|
+
day: hits.use.day,
|
|
252
|
+
lunar: hits.use.lunar,
|
|
253
|
+
},
|
|
254
|
+
avoid: {
|
|
255
|
+
xing: hits.avoid.xing.map((h) => xingHitText(h)),
|
|
256
|
+
shensha: hits.avoid.shensha,
|
|
257
|
+
day: hits.avoid.day,
|
|
258
|
+
lunar: hits.avoid.lunar,
|
|
259
|
+
},
|
|
260
|
+
...(hits.unsupported.length ? { unsupported: hits.unsupported } : {}),
|
|
261
|
+
},
|
|
175
262
|
...(v.excluded ? { excluded: true } : {}),
|
|
176
263
|
};
|
|
177
264
|
};
|
|
@@ -180,7 +267,10 @@ export function buildZeri(input) {
|
|
|
180
267
|
? candidates.map(makeRow)
|
|
181
268
|
: Array.from({ length: days }, (_, i) => makeRow(fromJDN(toJDN(start.year, start.month, start.day) + i)));
|
|
182
269
|
|
|
183
|
-
|
|
270
|
+
// 先按卷十决断排(推荐 > 可用 > 平平 > 回避),同档再按吉凶差分,最后用建除适配作同分参考。
|
|
271
|
+
const rankOf = (d) => (d.excluded ? -1 : (VERDICT_RANK[d.verdict] ?? 0));
|
|
272
|
+
const ranked = list.slice().sort((x, y) => rankOf(y) - rankOf(x) || y.score - x.score
|
|
273
|
+
|| Number(y.favor) - Number(x.favor) || (x.date < y.date ? -1 : 1));
|
|
184
274
|
const startDate = candidates
|
|
185
275
|
? candidates.slice().sort((x, y) => (ymd(x) < ymd(y) ? -1 : 1)).map(ymd)[0]
|
|
186
276
|
: ymd(start);
|
|
@@ -201,7 +291,7 @@ export function buildZeri(input) {
|
|
|
201
291
|
ties: pool.filter((d) => d.score === top.score).map((d) => d.date),
|
|
202
292
|
} : null,
|
|
203
293
|
spread: Math.max(...scores) - Math.min(...scores),
|
|
204
|
-
note: '
|
|
294
|
+
note: '候选日只在这几天里比:先按卷十「六等」与德神制化定宜忌方向,再以吉凶权重差分;胜出只表示更合所问事项,不代表「好多少」。',
|
|
205
295
|
};
|
|
206
296
|
}
|
|
207
297
|
|
|
@@ -214,9 +304,7 @@ export function buildZeri(input) {
|
|
|
214
304
|
days: list.length,
|
|
215
305
|
shengXiao,
|
|
216
306
|
...(candidates ? { candidates: candidates.map(ymd) } : {}),
|
|
217
|
-
scope: shengXiao
|
|
218
|
-
? `宜忌按建除简表;已给当事人属相(${shengXiao}),凡当日冲该属相径直排除。评分仅用于排序引导。`
|
|
219
|
-
: '宜忌按建除简表;未给当事人属相,未做冲属相排除。评分仅用于排序引导。',
|
|
307
|
+
scope: `宜忌按《协纪辨方书》卷十一「用事」逐条神煞,吉凶轻重按卷十「宜忌」六等与德神制化;${shengXiao ? `已给当事人属相(${shengXiao}),凡当日冲该属相径直排除。` : '未给当事人属相,未做冲属相排除。'}六等阈值为本仓校准(吉凶权重比 3/2、1、2/3、1/2),非古籍常数;卷十等第表的逐月逐日单元格未全量编码。评分仅用于排序引导。`,
|
|
220
308
|
},
|
|
221
309
|
best: ranked.filter((d) => d.verdict === '推荐' && !d.excluded).slice(0, 5).map((d) => d.date),
|
|
222
310
|
usable: ranked.filter((d) => d.verdict === '可用' && !d.excluded).slice(0, 5).map((d) => d.date),
|
|
@@ -224,7 +312,33 @@ export function buildZeri(input) {
|
|
|
224
312
|
days: list,
|
|
225
313
|
...(compare ? { compare } : {}),
|
|
226
314
|
excludedCount: list.filter((d) => d.excluded).length,
|
|
227
|
-
|
|
228
|
-
|
|
315
|
+
shenshaRef: {
|
|
316
|
+
text: ZERI_SHENSHA_BASIS.text,
|
|
317
|
+
edition: ZERI_SHENSHA_BASIS.edition,
|
|
318
|
+
volumes: ZERI_SHENSHA_BASIS.volumes,
|
|
319
|
+
unsupported: ZERI_SHENSHA_BASIS.unsupported,
|
|
320
|
+
note: ZERI_SHENSHA_BASIS.note,
|
|
321
|
+
juan10: {
|
|
322
|
+
text: ZERI_JUAN10_BASIS.text,
|
|
323
|
+
corpusLines: ZERI_JUAN10_BASIS.corpusLines,
|
|
324
|
+
note: ZERI_JUAN10_BASIS.note,
|
|
325
|
+
thresholdsNote: ZERI_JUAN10_BASIS.thresholdsNote,
|
|
326
|
+
grades: ZERI_JUAN10_BASIS.grades.map((g) => ({
|
|
327
|
+
key: g.key, label: g.label, doctrine: g.doctrine, withDe: g.withDe, withoutDe: g.withoutDe,
|
|
328
|
+
})),
|
|
329
|
+
ping: ZERI_JUAN10_BASIS.ping,
|
|
330
|
+
deRules: ZERI_JUAN10_BASIS.deRules.map((r) => ({
|
|
331
|
+
name: r.name, cls: r.cls, anyOf: r.anyOf, residualEntries: r.residualEntries,
|
|
332
|
+
})),
|
|
333
|
+
},
|
|
334
|
+
},
|
|
335
|
+
sources: [
|
|
336
|
+
'宜忌:建除十二神通行简表(黄历层,逐日 yi/ji 原样保留)',
|
|
337
|
+
'神煞宜忌:《钦定协纪辨方书》卷十一「用事」逐条',
|
|
338
|
+
'吉凶轻重:卷十「宜忌」六等与德神制化(遇德/不遇德)',
|
|
339
|
+
'神煞起法:卷四建除、卷五/卷六义例、卷九立成',
|
|
340
|
+
'排序:卷十决断 + 吉凶权重差分 + 属相排除(确定性)',
|
|
341
|
+
],
|
|
342
|
+
disclaimer: '择日为传统黄历口径的本地计算,属民俗参考;神煞依卷十一逐条宜忌,吉凶轻重依卷十「六等」与德神制化,六等阈值为本仓校准,逐月逐日等第表未逐格数字化。评分只用于排序,不构成择日结论。',
|
|
229
343
|
};
|
|
230
344
|
}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
// 紫微杂曜安星库(H4):全表里通行、但本插件默认盘不排的十二颗杂曜。
|
|
2
|
+
// 每条给:定宫依据、安星诀原文、逐宫查表或公式、五行与基本义、出处与互核情况。
|
|
3
|
+
//
|
|
4
|
+
// 口径(三条硬规矩):
|
|
5
|
+
// ① 只收「至少两处独立来源给出同一张表」的星;查不到的宁可不收,不凭记忆补一格。
|
|
6
|
+
// ② 诀文逐字照抄来源,转抄例子与诀文冲突时以诀文为准,冲突本身写进 note(例:天才的
|
|
7
|
+
// 网络例子自相矛盾,见该条)。
|
|
8
|
+
// ③ 异名不合并:年支系的「蜚廉」与博士十二神的「飞廉」是两颗星,同名不同宫;
|
|
9
|
+
// 「解神」按月安(月解),另有按年安的「年解」,两者都收、都标依据,不互相替换。
|
|
10
|
+
// 龙德/月德同样按年支可安,但与岁前十二神的龙德同名而异宫,本库不另立(见 SKIPPED)。
|
|
11
|
+
|
|
12
|
+
import { BRANCHES } from './calendar.js';
|
|
13
|
+
|
|
14
|
+
const fix = (i) => ((i % 12) + 12) % 12;
|
|
15
|
+
|
|
16
|
+
// ── 逐宫查表(键 = 依据值,值 = 地支序 0=子) ──────────────────
|
|
17
|
+
|
|
18
|
+
// 解神(月解):正二在申、三四在戌、五六在子、七八在寅、九十在辰、十一十二在午。
|
|
19
|
+
// 另一写法「单月冲宫觅解神,双月还依单月辰」——按月建(正月起寅)取对冲,
|
|
20
|
+
// 正月建寅冲申、三月建辰冲戌……与上表逐格相同,故两式互核通过。
|
|
21
|
+
export const TABLE_JIESHEN = { 1: 8, 2: 8, 3: 10, 4: 10, 5: 0, 6: 0, 7: 2, 8: 2, 9: 4, 10: 4, 11: 6, 12: 6 };
|
|
22
|
+
|
|
23
|
+
// 天巫:正五九月在巳、二六十月在申、三七十一月在寅、四八十二月在亥(巳申寅亥四生位轮十二月)。
|
|
24
|
+
export const TABLE_TIANWU = { 1: 5, 5: 5, 9: 5, 2: 8, 6: 8, 10: 8, 3: 2, 7: 2, 11: 2, 4: 11, 8: 11, 12: 11 };
|
|
25
|
+
|
|
26
|
+
// 天月:一犬二蛇三在龙,四虎五羊六兔宫,七猪八羊九在虎,十马冬犬腊寅中。
|
|
27
|
+
export const TABLE_TIANUE = { 1: 10, 2: 5, 3: 4, 4: 2, 5: 7, 6: 3, 7: 11, 8: 7, 9: 2, 10: 6, 11: 10, 12: 2 };
|
|
28
|
+
|
|
29
|
+
// 阴煞:正七月在寅、二八月在子、三九月在戌、四十月在申、五十一月在午、六十二月在辰。
|
|
30
|
+
export const TABLE_YINSHA = { 1: 2, 7: 2, 2: 0, 8: 0, 3: 10, 9: 10, 4: 8, 10: 8, 5: 6, 11: 6, 6: 4, 12: 4 };
|
|
31
|
+
|
|
32
|
+
// 天官贵人(生年干):甲羊乙龙壬犬宜,丙蛇丁虎己辛鸡,戊兔庚猪癸宜马。
|
|
33
|
+
// 天福贵人(生年干):甲爱金鸡乙爱猴,丁猪丙鼠己虎头,戊寻玉兔庚壬马,辛癸逢蛇爵禄荣。
|
|
34
|
+
// 另有合并诀「甲喜羊鸡乙龙猴……」把两星排在同一行,逐干拆开与本表全同;
|
|
35
|
+
// 戊年两星同在卯宫(合并诀只举「戊玉兔」一格,两诀合看才知道是同居)。
|
|
36
|
+
export const TABLE_TIANGUAN = { 甲: 7, 乙: 4, 丙: 5, 丁: 2, 戊: 3, 己: 9, 庚: 11, 辛: 9, 壬: 10, 癸: 6 };
|
|
37
|
+
export const TABLE_TIANFU = { 甲: 9, 乙: 8, 丙: 0, 丁: 11, 戊: 3, 己: 2, 庚: 6, 辛: 5, 壬: 6, 癸: 5 };
|
|
38
|
+
|
|
39
|
+
// 天厨(生年干):甲丁食蛇口,乙戊辛马方,丙从鼠口得,己食于猴房,庚食虎头上,壬鸡癸猪堂。
|
|
40
|
+
// 另一传本「甲丁蛇位号天厨,丙鼠壬鸡癸伴猪,乙戊辛干皆向马,己猴庚虎福神殊」——字面不同、
|
|
41
|
+
// 逐干落宫相同;另有排盘文直接列出十干表,三处一致。
|
|
42
|
+
export const TABLE_TIANCHU = { 甲: 5, 乙: 6, 丙: 0, 丁: 5, 戊: 6, 己: 8, 庚: 2, 辛: 6, 壬: 9, 癸: 11 };
|
|
43
|
+
|
|
44
|
+
// 蜚廉(生年支):「蜚廉分方顺年移,西南东北各轮之」——子年起申宫,按西方(申酉戌)、
|
|
45
|
+
// 南方(巳午未)、东方(寅卯辰)、北方(亥子丑)四组顺轮十二年支。
|
|
46
|
+
export const TABLE_FEILIAN = { 子: 8, 丑: 9, 寅: 10, 卯: 5, 辰: 6, 巳: 7, 午: 2, 未: 3, 申: 4, 酉: 11, 戌: 0, 亥: 1 };
|
|
47
|
+
|
|
48
|
+
// 天德/年解(生年支):「天德星君起酉宫,顺至生年定其踪;年解戌宫逆行去,数至生年可解凶。」
|
|
49
|
+
export const TIANDE_START = 9; // 酉起子,顺行
|
|
50
|
+
export const NIANJIE_START = 10; // 戌起子,逆行
|
|
51
|
+
|
|
52
|
+
// ── 库(顺序即面板与全文的展示顺序) ──────────────────────────
|
|
53
|
+
|
|
54
|
+
export const ZUOYAO_LIB = [
|
|
55
|
+
{
|
|
56
|
+
name: '解神',
|
|
57
|
+
basis: '生月',
|
|
58
|
+
type: '吉星',
|
|
59
|
+
wuxing: '阴水(一说属土,通行表不取五行断)',
|
|
60
|
+
verse: '正二在申三四在戍,五六在子七八在寅,九十月坐于辰宫,十一十二在午宫。\n(另一式:单月冲宫觅解神,双月还依单月辰。)',
|
|
61
|
+
table: TABLE_JIESHEN,
|
|
62
|
+
meaning: '消灾解厄:灾厄临身前先有感应,逢凶化吉之力。与按生年安的「年解」不是同一颗星。',
|
|
63
|
+
temple: null,
|
|
64
|
+
refs: ['https://m.yi958.com/ziwei/posts/15175', 'http://www.360doc.cn/article/6029610_1149007117.html', 'https://wk.baidu.com/view/2d750d65783e0912a2162a58'],
|
|
65
|
+
check: '三源同表;两式(查表法/月建对冲法)逐月互核一致',
|
|
66
|
+
note: '解神即「月解」,网络转抄常与年解混为一条,本库分列两星。',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: '天巫',
|
|
70
|
+
basis: '生月',
|
|
71
|
+
type: '吉星',
|
|
72
|
+
wuxing: '阳土',
|
|
73
|
+
verse: '正五九月在巳,二六十月在申,三七十一在寅,四八十二在亥。\n(另一式:巳申寅亥天巫位,分轮十二月星君。)',
|
|
74
|
+
table: TABLE_TIANWU,
|
|
75
|
+
meaning: '升迁与香火:主地位提升、近宗教玄学;会吉星则名声显。',
|
|
76
|
+
temple: null,
|
|
77
|
+
refs: ['https://m.yi958.com/ziwei/posts/15175', 'http://www.360doc.cn/article/6029610_1149007117.html', 'https://wk.baidu.com/view/2d750d65783e0912a2162a58'],
|
|
78
|
+
check: '三源同表(四生位轮十二月,两式同一)',
|
|
79
|
+
note: '',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: '天月',
|
|
83
|
+
basis: '生月',
|
|
84
|
+
type: '煞星',
|
|
85
|
+
wuxing: '阴土',
|
|
86
|
+
verse: '一犬二蛇三在龙,四虎五羊六兔宫,七猪八羊九在虎,十马冬犬腊寅中。',
|
|
87
|
+
table: TABLE_TIANUE,
|
|
88
|
+
meaning: '病符之星:主小病缠身、体弱,也主与世无争、缺主见。',
|
|
89
|
+
temple: null,
|
|
90
|
+
refs: ['https://m.yi958.com/ziwei/posts/15175', 'http://www.360doc.cn/article/6029610_1149007117.html', 'https://zhidao.baidu.com/question/252564654384154444.html'],
|
|
91
|
+
check: '三源逐字同诀(八月在未、十二月在寅两处最易抄错,三源皆同)',
|
|
92
|
+
note: '',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: '阴煞',
|
|
96
|
+
basis: '生月',
|
|
97
|
+
type: '煞星',
|
|
98
|
+
wuxing: '阴土',
|
|
99
|
+
verse: '正七月在寅,二八月在子,三九月在戍,四十月在申,五十一在午,六十二在辰。\n(另一式:寅子戌,申午辰,分六月,阴煞临。)',
|
|
100
|
+
table: TABLE_YINSHA,
|
|
101
|
+
meaning: '疑心与暗耗:主多疑、易受小人拖累,也主自我约束反省。',
|
|
102
|
+
temple: null,
|
|
103
|
+
refs: ['https://m.yi958.com/ziwei/posts/15175', 'http://www.360doc.cn/article/6029610_1149007117.html', 'https://m.meipian.cn/58g6z14p'],
|
|
104
|
+
check: '三源同表(隔六月同宫,正七寅、二八子……)',
|
|
105
|
+
note: '',
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: '天官',
|
|
109
|
+
basis: '生年干',
|
|
110
|
+
type: '吉星',
|
|
111
|
+
wuxing: '阳土',
|
|
112
|
+
verse: '甲羊乙龙壬犬宜,丙蛇丁虎己辛鸡,戊兔庚猪癸宜马,其人贵显可先知。',
|
|
113
|
+
table: TABLE_TIANGUAN,
|
|
114
|
+
meaning: '主贵显、清闲:喜入命宫或官禄宫;与天同、天梁庙地同宫主尊荣高寿,余者平常。',
|
|
115
|
+
temple: ['寅', '申', '巳', '卯'],
|
|
116
|
+
refs: ['https://ziweiscience.com/index.php/2024-06-25/anxingfa/', 'https://m.yi958.com/ziwei/posts/15175', 'https://www.daowen.com/book/content/226294168/14993368.html'],
|
|
117
|
+
check: '两诀(分立式/合并式)逐干互核一致;入庙四宫另见专论',
|
|
118
|
+
note: '己、辛同年干落酉,属原表如此,不是抄重。',
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: '天福',
|
|
122
|
+
basis: '生年干',
|
|
123
|
+
type: '吉星',
|
|
124
|
+
wuxing: '阳土',
|
|
125
|
+
verse: '甲爱金鸡乙爱猴,丁猪丙鼠己虎头,戊寻玉兔庚壬马,辛癸逢蛇爵禄荣。',
|
|
126
|
+
table: TABLE_TIANFU,
|
|
127
|
+
meaning: '主爵禄、吉祥:乐于助人、爱享受,运限逢之受人注目。',
|
|
128
|
+
temple: ['寅', '申', '巳', '卯'],
|
|
129
|
+
refs: ['https://ziweiscience.com/index.php/2024-06-25/anxingfa/', 'https://m.yi958.com/ziwei/posts/15175', 'https://www.daowen.com/book/content/226294168/14993368.html'],
|
|
130
|
+
check: '两诀逐干互核一致;庚、壬同年干落午,戊年与天官同居卯宫',
|
|
131
|
+
note: '合并诀「壬犬马癸马蛇游」把壬午、癸巳排在一起,与分立式同。',
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: '天厨',
|
|
135
|
+
basis: '生年干',
|
|
136
|
+
type: '吉星',
|
|
137
|
+
wuxing: '阴土',
|
|
138
|
+
verse: '甲丁食蛇口,乙戊辛马方,丙从鼠口得,己食于猴房,庚食虎头上,壬鸡癸猪堂。\n(另传:甲丁蛇位号天厨,丙鼠壬鸡癸伴猪,乙戊辛干皆向马,己猴庚虎福神殊。)',
|
|
139
|
+
table: TABLE_TIANCHU,
|
|
140
|
+
meaning: '俸禄与口福:主食禄、公职,也主厨艺与鉴赏;会天才更显烹饪之资。',
|
|
141
|
+
temple: null,
|
|
142
|
+
refs: ['https://m.yi958.com/ziwei/posts/15175', 'http://www.360doc.cn/article/6029610_1149007117.html', 'https://m.bilibili.com/opus/1015667810277261321', 'https://baijiahao.baidu.com/s?id=1841437745877521371'],
|
|
143
|
+
check: '两字面不同的诀 + 一处十干明表,四处逐干全同',
|
|
144
|
+
note: '甲丁同居巳,乙戊辛同居午,是原表同宫而非抄重。',
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: '蜚廉',
|
|
148
|
+
basis: '生年支',
|
|
149
|
+
type: '煞星',
|
|
150
|
+
wuxing: '阴火',
|
|
151
|
+
verse: '蜚廉分方顺年移,西南东北各轮之。\n(释:子年起申宫,十二年支先西方申酉戌、次南方巳午未、续东方寅卯辰、最后北方亥子丑。)',
|
|
152
|
+
table: TABLE_FEILIAN,
|
|
153
|
+
meaning: '口舌是非:主小人、诽谤、虚惊,宜静不宜争。',
|
|
154
|
+
temple: null,
|
|
155
|
+
refs: ['http://www.360doc.cn/article/6029610_1149007117.html', 'https://m.bilibili.com/opus/1015667810277261321'],
|
|
156
|
+
check: '两源同诀同释(王亭之中州派讲义与安星口诀本),四方位轮年支的落宫逐支一致',
|
|
157
|
+
note: '与博士十二神的「飞廉」同名异星:飞廉按禄存起、随大限顺逆,蜚廉只按生年支,两不相代。',
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
name: '天德',
|
|
161
|
+
basis: '生年支',
|
|
162
|
+
type: '吉星',
|
|
163
|
+
wuxing: '阳火',
|
|
164
|
+
verse: '天德星君起酉宫,顺至生年定其踪。',
|
|
165
|
+
formula: (c) => fix(TIANDE_START + c.yearBranch),
|
|
166
|
+
meaning: '福佑之星:主逢凶化吉、有扶助,与岁前十二神的「天德」同名异宫。',
|
|
167
|
+
temple: null,
|
|
168
|
+
refs: ['http://www.360doc.cn/article/6029610_1149007117.html', 'https://m.bilibili.com/opus/1015667810277261321'],
|
|
169
|
+
check: '两源同诀(酉宫起子顺行)',
|
|
170
|
+
note: '岁前十二神里也有「天德」(太岁起顺数第十位),本盘两处都会出现,同名不同星,不可互换。',
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: '年解',
|
|
174
|
+
basis: '生年支',
|
|
175
|
+
type: '吉星',
|
|
176
|
+
wuxing: '阳水',
|
|
177
|
+
verse: '年解戌宫逆行去,数至生年可解凶。',
|
|
178
|
+
formula: (c) => fix(NIANJIE_START - c.yearBranch),
|
|
179
|
+
meaning: '一生灾厄的总闸:与按生月安的「解神(月解)」分属两颗,年解管大事、月解管当期。',
|
|
180
|
+
temple: null,
|
|
181
|
+
refs: ['http://www.360doc.cn/article/6029610_1149007117.html', 'https://m.bilibili.com/opus/1015667810277261321'],
|
|
182
|
+
check: '两源同诀(戌宫起子逆行)',
|
|
183
|
+
note: '',
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: '天才',
|
|
187
|
+
basis: '命宫+生年支',
|
|
188
|
+
type: '杂曜',
|
|
189
|
+
wuxing: '阳木',
|
|
190
|
+
verse: '命宫起子天才顺。\n(释:自命宫起子年,顺数至本生年支安之。)',
|
|
191
|
+
formula: (c) => fix(c.soulIndex + c.yearBranch),
|
|
192
|
+
meaning: '才智与技艺:主聪明、有专长,会天厨增烹饪之资,会主星庙旺方显。',
|
|
193
|
+
temple: null,
|
|
194
|
+
refs: ['https://ziweiscience.com/index.php/2024-06-25/anxingfa/', 'http://www.360doc.cn/article/6029610_1149007117.html', 'https://m.meipian.cn/58g6z14p'],
|
|
195
|
+
check: '三源同诀(命宫起子顺数生年支)',
|
|
196
|
+
note: '360doc 转抄的例子自相矛盾:说命宫在午、戌年生人,按诀数到辰(该盘夫妻宫正在辰),却写成「巳宫安天才」。以诀文为准,例子判为笔误。',
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
name: '天寿',
|
|
200
|
+
basis: '身宫+生年支',
|
|
201
|
+
type: '杂曜',
|
|
202
|
+
wuxing: '阳土',
|
|
203
|
+
verse: '身宫起子天寿堂。\n(释:自身宫起子年,顺数至本生年支安之。)',
|
|
204
|
+
formula: (c) => fix(c.bodyIndex + c.yearBranch),
|
|
205
|
+
meaning: '寿年与长者缘:主稳重、近长辈,与天才对看(一按命宫、一按身宫)。',
|
|
206
|
+
temple: null,
|
|
207
|
+
refs: ['https://ziweiscience.com/index.php/2024-06-25/anxingfa/', 'http://www.360doc.cn/article/6029610_1149007117.html', 'https://m.meipian.cn/58g6z14p'],
|
|
208
|
+
check: '三源同诀;转抄例子「亥年生人身宫在卯→寅宫」与公式复算一致',
|
|
209
|
+
note: '',
|
|
210
|
+
},
|
|
211
|
+
];
|
|
212
|
+
|
|
213
|
+
// 按年支可安、但本库刻意不另立的星:写清楚为什么不留,免得日后「顺手补上」造成同名双宫。
|
|
214
|
+
export const ZUOYAO_SKIPPED = [
|
|
215
|
+
{
|
|
216
|
+
name: '龙德',
|
|
217
|
+
reason: '「龙德起羊(未)」按年支可安,但岁前十二神已有同名「龙德」(太岁起顺数第八位),两处同名异宫会让面板与断语打架。岁前那一套已在宫位神煞里呈现,故不另立。',
|
|
218
|
+
refs: ['https://m.bilibili.com/opus/1015667810277261321'],
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
name: '月德',
|
|
222
|
+
reason: '「月起巳」按年支安月德;只见于「年支六曜诀」一条脉络,且与神煞体系无对应,收进来会给出无法验证的庙旺断,故不收。',
|
|
223
|
+
refs: ['https://m.bilibili.com/opus/1015667810277261321', 'http://www.360doc.cn/article/6029610_1149007117.html'],
|
|
224
|
+
},
|
|
225
|
+
];
|
|
226
|
+
|
|
227
|
+
export const ZUOYAO_NAMES = ZUOYAO_LIB.map((s) => s.name);
|
|
228
|
+
|
|
229
|
+
/** 全表统计:供面板与测试核对「收了几颗、几颗有庙、几颗有明表」 */
|
|
230
|
+
export const ZUOYAO_STATS = Object.freeze({
|
|
231
|
+
total: ZUOYAO_LIB.length,
|
|
232
|
+
byBasis: Object.freeze(ZUOYAO_LIB.reduce((acc, s) => {
|
|
233
|
+
acc[s.basis] = (acc[s.basis] || 0) + 1;
|
|
234
|
+
return acc;
|
|
235
|
+
}, {})),
|
|
236
|
+
withTable: ZUOYAO_LIB.filter((s) => s.table).length,
|
|
237
|
+
withFormula: ZUOYAO_LIB.filter((s) => s.formula).length,
|
|
238
|
+
withTemple: ZUOYAO_LIB.filter((s) => s.temple && s.temple.length).length,
|
|
239
|
+
byType: Object.freeze(ZUOYAO_LIB.reduce((acc, s) => {
|
|
240
|
+
acc[s.type] = (acc[s.type] || 0) + 1;
|
|
241
|
+
return acc;
|
|
242
|
+
}, {})),
|
|
243
|
+
skipped: ZUOYAO_SKIPPED.map((s) => s.name),
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
/** 单颗星的落宫(表格优先,公式其次);依据缺字段时返回 null,不猜宫。 */
|
|
247
|
+
export function zuoyaoBranch(star, ctx) {
|
|
248
|
+
if (star.table) {
|
|
249
|
+
const key = star.basis === '生月' ? ctx.lunarMonth
|
|
250
|
+
: star.basis === '生年干' ? ctx.yearStem
|
|
251
|
+
: star.basis === '生年支' ? BRANCHES[fix(ctx.yearBranch)]
|
|
252
|
+
: null;
|
|
253
|
+
if (key === null || key === undefined) return null;
|
|
254
|
+
const v = star.table[key];
|
|
255
|
+
return typeof v === 'number' ? fix(v) : null;
|
|
256
|
+
}
|
|
257
|
+
if (star.formula) {
|
|
258
|
+
// 四颗公式曜全都要生年支;天才另要命宫、天寿另要身宫。少一个就整颗不排。
|
|
259
|
+
if (typeof ctx.yearBranch !== 'number') return null;
|
|
260
|
+
if (star.basis === '命宫+生年支' && typeof ctx.soulIndex !== 'number') return null;
|
|
261
|
+
if (star.basis === '身宫+生年支' && typeof ctx.bodyIndex !== 'number') return null;
|
|
262
|
+
const v = star.formula(ctx);
|
|
263
|
+
return typeof v === 'number' && Number.isFinite(v) ? fix(v) : null;
|
|
264
|
+
}
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* 安十二颗杂曜。ctx = { lunarMonth, yearStem, yearBranch, soulIndex, bodyIndex }
|
|
270
|
+
* 返回 [{ name, type, branch, basis, verse }],branch 为地支序。
|
|
271
|
+
* 任何一颗算不出宫位(例如没传命宫)就整颗跳过,绝不安到默认宫。
|
|
272
|
+
*/
|
|
273
|
+
export function placeZuoyao(ctx = {}) {
|
|
274
|
+
const out = [];
|
|
275
|
+
for (const star of ZUOYAO_LIB) {
|
|
276
|
+
const branch = zuoyaoBranch(star, ctx);
|
|
277
|
+
if (branch === null) continue;
|
|
278
|
+
out.push({
|
|
279
|
+
name: star.name,
|
|
280
|
+
type: star.type,
|
|
281
|
+
branch,
|
|
282
|
+
basis: star.basis,
|
|
283
|
+
verse: star.verse,
|
|
284
|
+
meaning: star.meaning,
|
|
285
|
+
...(star.temple && star.temple.length ? { temple: star.temple } : {}),
|
|
286
|
+
...(star.temple && star.temple.includes(BRANCHES[branch]) ? { inTemple: true } : {}),
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
return out;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** 一行摘要:全表收了哪些星、按什么定宫 */
|
|
293
|
+
export function zuoyaoBriefText() {
|
|
294
|
+
const groups = [];
|
|
295
|
+
for (const [basis, n] of Object.entries(ZUOYAO_STATS.byBasis)) {
|
|
296
|
+
groups.push(`${basis} ${ZUOYAO_LIB.filter((s) => s.basis === basis).map((s) => s.name).join('、')}(${n})`);
|
|
297
|
+
}
|
|
298
|
+
return groups.join(' ');
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* 安星诀全文(逐颗一行:星名+定宫依据+诀文+互核情况)。
|
|
303
|
+
* 面板、独立页与「复制提问」共用这一段:外部模型只拿到盘面星名是不够的,
|
|
304
|
+
* 得知道这一颗是怎么定宫的,才不会把杂曜当成随意摆放的装饰。
|
|
305
|
+
*/
|
|
306
|
+
export function zuoyaoVerseBlock(list) {
|
|
307
|
+
const rows = (list && list.length ? list : ZUOYAO_LIB);
|
|
308
|
+
return rows.map((s) => {
|
|
309
|
+
const star = ZUOYAO_LIB.find((x) => x.name === s.name) || s;
|
|
310
|
+
const at = typeof s.branch === 'number' ? `(本盘落${BRANCHES[fix(s.branch)]}宫)` : '';
|
|
311
|
+
return `${star.name}|${star.basis}${at}|${String(star.verse || '').replace(/\n/g, '')}|互核:${star.check || '—'}`;
|
|
312
|
+
}).join('\n');
|
|
313
|
+
}
|