dsh-metaphysics 0.69.0 → 0.70.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.
@@ -361,7 +361,7 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
361
361
  <div class="wrap">
362
362
  <header>
363
363
  <div class="brand-row">
364
- <div class="brand"><span class="seal" aria-hidden="true">命</span><span class="brand-txt">命理排盘<span class="ver">v0.69.0</span><small>八字 · 紫微 · 六爻 · 梅花 · 六壬 · 奇门 · 合盘 · 塔罗 全部在本机计算</small></span></div>
364
+ <div class="brand"><span class="seal" aria-hidden="true">命</span><span class="brand-txt">命理排盘<span class="ver">v0.70.0</span><small>八字 · 紫微 · 六爻 · 梅花 · 六壬 · 奇门 · 合盘 · 塔罗 全部在本机计算</small></span></div>
365
365
  <div class="view-switch">
366
366
  <span class="hint">熟练了可以换回平铺</span>
367
367
  <span class="seg" role="group" aria-label="首屏样式">
@@ -679,7 +679,7 @@ h3::after{content:"";flex:1;height:1px;background:linear-gradient(90deg,var(--li
679
679
  <h3>对拍:把典籍当期望值</h3>
680
680
  <ul><li>六爻:京房八宫卦序与世应,64 卦全表;旬空六旬表</li><li>六壬:日干寄宫、中气换将;紫微:纳音定五行局、紫微天府相照</li><li>卦例:《增删卜易》9 条 +《卜筮正宗》128 条(93 成对 + 35 静卦),核本变卦 / 动爻数 / 卦宫 / 缺爻 / 旬空</li><li>奇门:20 个时辰 × 9 宫,核四柱 / 局数 / 值符 / 值使 / 星门神 / 天盘干</li></ul>
681
681
  <h3>工程验证</h3>
682
- <ul><li>测试:177 个测试文件 / 9881 条断言;七道闸(回归 · 断言基线 · 测试可失败自检 · HTML 注入面 · 工程约定 · 产物宿主形态 · 随机扫射)</li><li>可复现:seed / asOf 显式;同一输入同一输出</li><li>口径:晚子时、真太阳时、奇门三流派、闰月归月都可切换,并有字段级差异对照</li></ul>
682
+ <ul><li>测试:177 个测试文件 / 10072 条断言;七道闸(回归 · 断言基线 · 测试可失败自检 · HTML 注入面 · 工程约定 · 产物宿主形态 · 随机扫射)</li><li>可复现:seed / asOf 显式;同一输入同一输出</li><li>口径:晚子时、真太阳时、奇门三流派、闰月归月都可切换,并有字段级差异对照</li></ul>
683
683
 
684
684
  <h3>已知边界(不猜)</h3>
685
685
  <ul><li>六爻应期(具体哪天应验)不做;卦例只录动爻个数,不录爻位</li><li>财富/健康只给结构判断与档位,不给金额区间、不作诊断</li><li>紫微飞星已做「单一支化逐宫追到成环」与「三方四正 16 条按落宫归堆」,但都未叠大限流年四化、不折吉凶;八字交运日已能算到日/时,但未与第三方排盘案例批量对拍</li></ul>
@@ -19268,11 +19268,22 @@ __mods.taiyi = (function () {
19268
19268
  // 6. 文昌:积年 mod 18,阳局自武德(申)起、阴局自吕申(寅)起,顺行十六神,
19269
19269
  // 遇阴德(乾)、大武(坤)各数两次
19270
19270
  //
19271
- // 没有做的(scope 里写明,别在文案里假装有):计神、始击、定目、主算 / 客算、
19272
- // 主客大小将、三基(君基 / 臣基 / 民基)、五福、十精,以及掩迫关囚击格等格局判定。
19273
- // 这些各有独立起例,互相对不上时整套盘会自相矛盾,必须单独一轮对着《太乙金镜式经》
19274
- // 与《太乙统宗宝鉴》逐条对拍,不在这层混进来。
19271
+ // 7. 计神:积年 mod 60 得六十甲子序,从寅起逆数十二支
19272
+ // 8. 始击:计神加和德(艮)之宫,天目(文昌)随盘移一位,即始击
19273
+ // 9. 主算 / 客算:沿九宫环顺行累加宫数,天目在正宫按本数、在间神先计一,
19274
+ // 数到太乙宫前一位为止
19275
+ // 10. 大将 = 算数个位(得十置一),参将 = 大将 × 3 的个位
19276
+ // 11. 掩、迫、囚、格、关五种位置关系
19277
+ //
19278
+ // 12. 定目、三基、五福、大游、十精、八种格局、阴阳数和
19279
+ // 13. 月计 / 日计 / 时计:按《太乙金镜式经》卷一的积月、积日、时实三套推法
19280
+ // 14. 古法吉凶:按卷一《推太公考时法》——八种相犯全无、主客数和,算和顺;
19281
+ // 命中任何一犯,古法算相犯。这是古籍的占断口径,不是预测,文案里必须写明。
19282
+ //
19283
+ // 没有做的(scope 里写明,别在文案里假装有):四神拆成本身与绛宫、明堂、玉堂
19284
+ // 十二位全序;胜负断辞与三旗五将。
19275
19285
 
19286
+ const { termInstantJd, toJDN, jdToParts, dayGanzhiIndex, STEMS } = (__mods.calendar || {});
19276
19287
  const { assertCivil } = (__mods.validate || {});
19277
19288
  const { assertObject } = (__mods.validate || {});
19278
19289
 
@@ -19330,6 +19341,210 @@ const FIVE_YUAN = ['甲子元', '丙子元', '戊子元', '庚子元', '壬子
19330
19341
  /** 三理:太乙在每一宫理天、理地、理人各一年 */
19331
19342
  const THREE_LI = ['理天', '理地', '理人'];
19332
19343
 
19344
+ /** 《太乙金镜式经》卷一的天文常数:章岁、章月、日法、月法 */
19345
+ const ZHANG_SUI = 657;
19346
+ const ZHANG_YUE = 8726;
19347
+ const RI_FA = 49;
19348
+ const YUE_FA = 2447;
19349
+
19350
+ /** 二十四局一周 → 宫序(起一宫顺行八宫、不游中五)与入宫第几期 */
19351
+ function palaceFromR24(r24) {
19352
+ const k = Math.ceil(r24 / 3);
19353
+ const inPalace = r24 - (k - 1) * 3 || 3;
19354
+ return { k, palace: YANG_WALK[k - 1], inPalace };
19355
+ }
19356
+
19357
+ /** 从某支起、逆行第 n 步(n 取 1..12,1 就是起点) */
19358
+ function branchWalk(startIdx, step) {
19359
+ const idx = (((startIdx - (step - 1)) % 12) + 12) % 12;
19360
+ return { idx, branch: BRANCH_NAMES[idx] };
19361
+ }
19362
+
19363
+ /** 十六神顺行第 n 步:遇阴德(乾)、大武(坤)各数两次,故十八步一周 */
19364
+ function sixteenStep(startGod, rest18) {
19365
+ const start = SIXTEEN.findIndex((x) => x.god === startGod);
19366
+ const steps = [];
19367
+ for (let i = 0; i < SIXTEEN.length; i += 1) {
19368
+ const cur = SIXTEEN[(start + i) % SIXTEEN.length];
19369
+ steps.push(cur);
19370
+ if (cur.pos === '乾' || cur.pos === '坤') steps.push(cur);
19371
+ }
19372
+ return steps[rim(rest18, 18) - 1];
19373
+ }
19374
+
19375
+ /** 月计:积月 = ⌊积年 × 章月 ÷ 章岁⌋,其余数称闰余 */
19376
+ function monthJiOf(jinian) {
19377
+ const jiyue = Number((BigInt(jinian) * BigInt(ZHANG_YUE)) / BigInt(ZHANG_SUI));
19378
+ const r24 = rim(jiyue, 24);
19379
+ const t = palaceFromR24(r24);
19380
+ const mu = sixteenStep('武德', rim(jiyue, 18));
19381
+ const js = branchWalk(2, rim(rim(jiyue, 60), 12));
19382
+ return {
19383
+ jiyue,
19384
+ taiyi: { rest24: r24, palace: t.palace, palaceName: PALACES[t.palace].name, unitInPalace: t.inPalace },
19385
+ mu: { pos: mu.pos, god: mu.god, palace: mu.num },
19386
+ jishen: js,
19387
+ };
19388
+ }
19389
+
19390
+ /** 日计:积日 = ⌊积月 × 月法 ÷ 日法⌋ */
19391
+ function dayJiOf(jinian) {
19392
+ const jiyue = Number((BigInt(jinian) * BigInt(ZHANG_YUE)) / BigInt(ZHANG_SUI));
19393
+ const jiri = Number((BigInt(jiyue) * BigInt(YUE_FA)) / BigInt(RI_FA));
19394
+ const r24 = rim(jiri, 24);
19395
+ const t = palaceFromR24(r24);
19396
+ const mu = sixteenStep('武德', rim(jiri, 18));
19397
+ const js = branchWalk(2, rim(rim(jiri, 60), 12));
19398
+ return {
19399
+ jiri,
19400
+ taiyi: { rest24: r24, palace: t.palace, palaceName: PALACES[t.palace].name, unitInPalace: t.inPalace },
19401
+ mu: { pos: mu.pos, god: mu.god, palace: mu.num },
19402
+ jishen: js,
19403
+ };
19404
+ }
19405
+
19406
+ /** 时计:以上年冬至为天正、十二时一辰,时实 = (冬至积日 − 1) × 12 + 时辰序 */
19407
+ function hourJiOf(datetime) {
19408
+ const { year, month, day, hour } = datetime;
19409
+ const wp = jdToParts(termInstantJd(year - 1, 23));
19410
+ const winterJdn = toJDN(wp.year, wp.month, wp.day);
19411
+ const summerJd = termInstantJd(year, 11);
19412
+ const nowJd = toJDN(year, month, day) - 0.5 + (hour * 60) / 1440;
19413
+ const dun = nowJd >= summerJd ? 'yin' : 'yang';
19414
+ const hIdx = Math.floor(((hour + 1) % 24) / 2);
19415
+ const shiShi = (winterJdn - 1) * 12 + hIdx;
19416
+ const r24 = rim(shiShi, 24);
19417
+ const t = palaceFromR24(r24);
19418
+ const start = dun === 'yang' ? 2 : 8;
19419
+ const js = branchWalk(start, rim(rim(shiShi, 60), 12));
19420
+ return {
19421
+ shiShi,
19422
+ dun,
19423
+ taiyi: { rest24: r24, palace: t.palace, palaceName: PALACES[t.palace].name, unitInPalace: t.inPalace },
19424
+ jishen: js,
19425
+ note: '时计用现代节气定冬至与夏至,不用唐代气法常数;与卷一的古历口径会有几日差。',
19426
+ };
19427
+ }
19428
+
19429
+ /** 古法吉凶:按卷一《推太公考时法》的位置判据,只判「相犯与否」与「数和不和」 */
19430
+ function jiXiongOf(o) {
19431
+ const items = (o.geju && o.geju.list) || [];
19432
+ const xiangFan = items.length > 0;
19433
+ const zhuHe = !!(o.heshu && o.heshu.zhu && o.heshu.zhu.he);
19434
+ const keHe = !!(o.heshu && o.heshu.ke && o.heshu.ke.he);
19435
+ const he = zhuHe && keHe;
19436
+ const gate = (o.gate && o.gate.gate) || '';
19437
+ // 卷一「吉道谓开休生三门」,年家只值一门,能判的就到这里
19438
+ const jiDao = gate === '开' || gate === '休' || gate === '生';
19439
+ // 用词照《太乙金镜式经》:凶、不和、吉、大吉;不自造档位
19440
+ let grade = 'ji';
19441
+ if (xiangFan) grade = 'xiong';
19442
+ else if (!he) grade = 'buhe';
19443
+ else if (jiDao) grade = 'daji';
19444
+ const label = grade === 'xiong' ? '凶' : grade === 'buhe' ? '不和' : grade === 'daji' ? '大吉' : '吉';
19445
+ const basis = xiangFan
19446
+ ? '命中' + items.join('、') + ',不满足卷一「上下无掩击迫囚关格对、并不相犯」'
19447
+ : !he
19448
+ ? '不相犯,但' + (zhuHe ? '客算' : '主算') + '落在不和'
19449
+ : jiDao
19450
+ ? '阴阳和顺、不相犯,八门又值' + gate + '(卷一所称吉道)'
19451
+ : '阴阳和顺、不相犯,八门值' + gate + ',不在开休生之内';
19452
+ const text = basis + '。';
19453
+ const note = '卷一另有「大利」「利以行兵」「先吉后凶」,要五将与神将同参,这一层没有做。';
19454
+ return { xiangFan, items, he, gate, grade, label, text, note };
19455
+ }
19456
+
19457
+ /* ── 神将层(第五层)─────────────────────────────────────────────
19458
+ 卷一《推太乙当时法》:「以日度加时因步六壬式,知天乙成败之分」——
19459
+ 借六壬十二神看四将与文昌、始击落在吉神还是凶神下。口径由本盘自定,写在这里备查:
19460
+ 1) 十二神用六壬序(贵人、螣蛇、朱雀、六合、勾陈、青龙、天后、太阴、玄武、太常、白虎、天空);
19461
+ 2) 贵人按日干起(甲戊庚丑未 / 乙己子申 / 丙丁亥酉 / 壬癸巳卯 / 辛午寅),卯至申用昼贵、酉至寅用夜贵;
19462
+ 3) 贵人临亥子丑寅卯辰顺行、临巳午未申酉戌逆行;
19463
+ 4) 四将与文昌、始击的卦位按后天八卦取一支(乾亥、坎子、艮丑、震卯、巽巳、离午、坤未、兑酉),
19464
+ 再取该支上的神;太乙九宫一宫两支,取生支这一支,是本盘唯一能自洽的一档。
19465
+ 这一层只给「古法怎么判」,不给成不成。 */
19466
+
19467
+ const TWELVE_GODS = ['贵人', '螣蛇', '朱雀', '六合', '勾陈', '青龙', '天后', '太阴', '玄武', '太常', '白虎', '天空'];
19468
+ const GOD_GOOD = ['贵人', '六合', '青龙', '太阴', '太常'];
19469
+ const GOD_BAD = ['螣蛇', '朱雀', '勾陈', '玄武', '白虎', '天空'];
19470
+ /** 后天八卦取支:一宫两支时取生支(与十六神位里同向那一支一致) */
19471
+ const TRIGRAM_TO_BRANCH = { 乾: '亥', 坎: '子', 艮: '丑', 震: '卯', 巽: '巳', 离: '午', 坤: '未', 兑: '酉' };
19472
+ /** 十六神位名 → 地支:卦位取生支,支位原样 */
19473
+ const POS_TO_BRANCH = { ...TRIGRAM_TO_BRANCH, 子: '子', 丑: '丑', 寅: '寅', 卯: '卯', 辰: '辰', 巳: '巳', 午: '午', 未: '未', 申: '申', 酉: '酉', 戌: '戌', 亥: '亥' };
19474
+ const GUI_REN = { 甲: '丑', 戊: '丑', 庚: '丑', 乙: '子', 己: '子', 丙: '亥', 丁: '亥', 壬: '巳', 癸: '巳', 辛: '午' };
19475
+ const GUI_REN_NIGHT = { 甲: '未', 戊: '未', 庚: '未', 乙: '申', 己: '申', 丙: '酉', 丁: '酉', 壬: '卯', 癸: '卯', 辛: '寅' };
19476
+
19477
+ /** 当天的日干 */
19478
+ function dayStemOf(year, month, day) {
19479
+ const idx = dayGanzhiIndex(toJDN(year, month, day));
19480
+ return STEMS[((idx % 10) + 10) % 10];
19481
+ }
19482
+
19483
+ /** 起十二神:昼贵 / 夜贵按卯~申、酉~寅分;反回 { stem, day, startBranch, dir, table } */
19484
+ function twelveGodsOf(stem, hour) {
19485
+ const h = typeof hour === 'number' ? hour : 0;
19486
+ const bi = Math.floor(((h + 1) % 24) / 2);
19487
+ const day = bi >= 2 && bi <= 7;
19488
+ const start = (day ? GUI_REN : GUI_REN_NIGHT)[stem] || '丑';
19489
+ const si = BRANCH_NAMES.indexOf(start);
19490
+ const dir = ['亥', '子', '丑', '寅', '卯', '辰'].includes(start) ? 1 : -1;
19491
+ const table = {};
19492
+ TWELVE_GODS.forEach((g, k) => {
19493
+ const bi2 = ((si + dir * k) % 12 + 12) % 12;
19494
+ table[BRANCH_NAMES[bi2]] = g;
19495
+ });
19496
+ return { stem, day, startBranch: start, dir, table };
19497
+ }
19498
+
19499
+ /** 四将与文昌、始击各落哪一神下 */
19500
+ function shenJiangOf(o) {
19501
+ const t = twelveGodsOf(o.dayStem, o.hour);
19502
+ const b2b = POS_TO_BRANCH;
19503
+ const rows = [
19504
+ ['主大将', o.jiang.zhuDaName],
19505
+ ['主参将', o.jiang.zhuCanName],
19506
+ ['客大将', o.jiang.keDaName],
19507
+ ['客参将', o.jiang.keCanName],
19508
+ ['文昌', o.wenchang && o.wenchang.pos],
19509
+ ['始击', o.shiji && o.shiji.pos],
19510
+ ].map(([who, gua]) => {
19511
+ const br = b2b[gua] || '';
19512
+ const god = br ? t.table[br] || '' : '';
19513
+ const kind = GOD_GOOD.includes(god) ? 'good' : GOD_BAD.includes(god) ? 'bad' : 'mid';
19514
+ return { who, gua, branch: br, god, kind };
19515
+ });
19516
+ const goods = rows.filter((x) => x.kind === 'good').map((x) => x.who + '在' + x.god);
19517
+ const bads = rows.filter((x) => x.kind === 'bad').map((x) => x.who + '在' + x.god);
19518
+ const mids = rows.filter((x) => x.kind === 'mid').map((x) => x.who + '在' + (x.god || '无名'));
19519
+ return { ...t, rows, goods, bads, mids };
19520
+ }
19521
+
19522
+ /**
19523
+ * 位置层 + 神将层合成卷一的判辞:凶 / 不和 / 吉 / 大吉 / 大利 / 先吉后凶。
19524
+ * 卷一判语:门具将发遇吉神则大吉;门杜闭塞遇吉神守固大利;门杜闭塞遇凶神则先吉后凶。
19525
+ * 位置层已相犯时古法认定「不相犯」不成立,不再往上抬。
19526
+ */
19527
+ function verdictOf(o) {
19528
+ const pos = o.jixiong || {};
19529
+ const sj = o.shenjiang || {};
19530
+ const gate = (o.gate && o.gate.gate) || '';
19531
+ const jiDao = gate === '开' || gate === '休' || gate === '生';
19532
+ const rows = sj.rows || [];
19533
+ const allGood = rows.length > 0 && (sj.bads || []).length === 0 && (sj.mids || []).length === 0;
19534
+ const anyBad = (sj.bads || []).length > 0;
19535
+ let grade = pos.grade || 'ji';
19536
+ let label = pos.label || '吉';
19537
+ if (grade !== 'xiong' && allGood) {
19538
+ grade = jiDao ? 'daji' : 'dali';
19539
+ label = jiDao ? '大吉' : '大利';
19540
+ } else if (grade !== 'xiong' && anyBad) {
19541
+ grade = jiDao ? 'xianji' : 'xiong';
19542
+ label = jiDao ? '先吉后凶' : '凶';
19543
+ }
19544
+ return { grade, label, jiDao, allGood, anyBad, posGrade: pos.grade, text: pos.text };
19545
+ }
19546
+
19547
+ /** 《太乙金镜式经》这一层覆盖的算法清单(面板与文案都从这里取) */
19333
19548
  const TAIYI_SCOPE = {
19334
19549
  covered: [
19335
19550
  '太乙积年与五元六纪',
@@ -19338,14 +19553,23 @@ const TAIYI_SCOPE = {
19338
19553
  '太乙落宫(三年一宫、不入中五)',
19339
19554
  '八门(三十年一转)',
19340
19555
  '文昌(十八年一周,遇乾、坤各数两次)',
19556
+ '计神(积年 mod 60,从寅起逆数)',
19557
+ '始击(计神加和德,天目随移)',
19558
+ '主算、客算与主客大小将、参将',
19559
+ '掩、击、格、对、提、迫、囚、关八种位置关系',
19560
+ '定目(年支合神移至太岁宫)',
19561
+ '三基(君基、臣基、民基)',
19562
+ '五福、大游',
19563
+ '十精其余(天乙、地乙、直符、四神、小游)',
19564
+ '阴阳数和(重阳、重阴、上和、次和、下和)',
19565
+ '月计、日计、时计(积月、积日、时实三套推法)',
19566
+ '古法吉凶倾向(相犯与否 + 数和不和)',
19341
19567
  ],
19342
19568
  notCovered: [
19343
- '计神、始击、定目',
19344
- '主算、客算与主客大小将参将',
19345
- '三基(君基、臣基、民基)、五福、十精',
19346
- '掩、迫、关、囚、击、格等格局判定',
19569
+ '四神拆成本身与绛宫、明堂、玉堂的十二位全序',
19570
+ '胜负断辞、三旗五将',
19347
19571
  ],
19348
- note: '这一层只到「太乙、八门、文昌」三个落点;主客算与格局需要另一套起例,未收录。',
19572
+ note: '这一层做到太乙、八门、文昌、计神、始击、主客算与四将、八种格局、定目、三基、五福、大游、十精、阴阳数和、月日时三计、古法吉凶与神将判辞;阴阳遁按冬至夏至交节判;四神十二位全序、胜负断辞不做。',
19349
19573
  };
19350
19574
 
19351
19575
  /** 取模成 1..n(余数 0 当 n) */
@@ -19387,7 +19611,11 @@ function yuanJiOf(rest360) {
19387
19611
  */
19388
19612
  function dunOf(jd) {
19389
19613
  if (typeof jd !== 'number' || !Number.isFinite(jd)) return { dun: 'yang', by: 'default' };
19390
- return { dun: 'yang', by: 'jd' };
19614
+ const p = jdToParts(jd);
19615
+ const summer = termInstantJd(p.year, 11); // 当年夏至
19616
+ const winter = termInstantJd(p.year, 23); // 当年冬至
19617
+ const yin = jd >= summer && jd < winter;
19618
+ return { dun: yin ? 'yin' : 'yang', by: 'jd', summer, winter };
19391
19619
  }
19392
19620
 
19393
19621
  /** 太乙落宫:局数 mod 24,三年一宫 */
@@ -19435,6 +19663,226 @@ function wenChang(jinian, dun) {
19435
19663
  return { rest18: r, pos: hit.pos, god: hit.god, num: hit.num, palaceName: PALACES[hit.num].name };
19436
19664
  }
19437
19665
 
19666
+ /** 八卦正宫名(十六神里 pos 落在这八个上就是正宫,其余是间神) */
19667
+ const GUA_NAMES = ['乾', '兑', '离', '震', '巽', '坎', '艮', '坤'];
19668
+
19669
+ /** 九宫环顺行:坎八 → 艮三 → 震四 → 巽九 → 离二 → 坤七 → 兑六 → 乾一 */
19670
+ const PALACE_RING = [8, 3, 4, 9, 2, 7, 6, 1];
19671
+
19672
+ /** 十二支名 */
19673
+ const BRANCH_NAMES = ['子', '丑', '寅', '卯', '辰', '巳', '午', '未', '申', '酉', '戌', '亥'];
19674
+
19675
+ /** 地支序 → 十六神索引(子→地主、丑→阳德、寅→吕申……) */
19676
+ const BRANCH_TO_SIXTEEN = [2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 1];
19677
+
19678
+ /** 对宫:一乾对九巽、二离对八坎、三艮对七坤、四震对六兑,中五无对 */
19679
+ const OPPOSITE_PALACE = { 1: 9, 9: 1, 2: 8, 8: 2, 3: 7, 7: 3, 4: 6, 6: 4, 5: 5 };
19680
+
19681
+ /** 九宫环上的下一宫 */
19682
+ function nextPalace(palace) {
19683
+ const i = PALACE_RING.indexOf(palace);
19684
+ return PALACE_RING[(i + 1) % PALACE_RING.length];
19685
+ }
19686
+
19687
+ /** 九宫环上的上一宫(顺行的「前一宫」,即太乙左右) */
19688
+ function prevPalace(palace) {
19689
+ const i = PALACE_RING.indexOf(palace);
19690
+ return PALACE_RING[(i - 1 + PALACE_RING.length) % PALACE_RING.length];
19691
+ }
19692
+
19693
+ /** 六合:与某支相合的那一支(子丑、寅亥、卯戌、辰酉、巳申、午未) */
19694
+ const LIU_HE = [1, 0, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2];
19695
+
19696
+ /**
19697
+ * 定目:淘金歌「为客最难详定计,便以合神加太岁」——把合神搬到太岁所在处,
19698
+ * 盘整体旋转,原先天目(文昌)落到的位置就是定目。
19699
+ */
19700
+ function dingMuOf(wenChangIdx, yearBranchIdx) {
19701
+ const heIdx = LIU_HE[yearBranchIdx];
19702
+ const taiSui16 = BRANCH_TO_SIXTEEN[yearBranchIdx];
19703
+ const he16 = BRANCH_TO_SIXTEEN[heIdx];
19704
+ const idx16 = ((wenChangIdx + (taiSui16 - he16)) % 16 + 16) % 16;
19705
+ const item = SIXTEEN[idx16];
19706
+ return { shift: taiSui16 - he16, idx16, pos: item.pos, god: item.god, palace: item.num, palaceName: PALACES[item.num].name };
19707
+ }
19708
+
19709
+ /** 三基:君基三十年一移起午、臣基三年一移起午、民基一年一移起戌,顺行十二支 */
19710
+ function sanJiOf(jinian) {
19711
+ const step = (base, period, start) => BRANCH_NAMES[(start + Math.floor((jinian - 1) / period)) % 12];
19712
+ return {
19713
+ jun: step('jun', 30, 6),
19714
+ chen: step('chen', 3, 6),
19715
+ min: step('min', 1, 10),
19716
+ note: '君基三十年一移、臣基三年一移,都从午起;民基一年一移,从戌起,顺行十二支。',
19717
+ };
19718
+ }
19719
+
19720
+ /** 五福:四十五年移一位,上元甲子起一宫,乾一 → 艮三 → 巽九 → 坤七 → 中五 */
19721
+ const WUFU_ORDER = [1, 3, 9, 7, 5];
19722
+ function wuFuOf(jinian) {
19723
+ const i = Math.floor((jinian - 1) / 45) % WUFU_ORDER.length;
19724
+ const palace = WUFU_ORDER[i];
19725
+ return { index: i, palace, palaceName: PALACES[palace].name };
19726
+ }
19727
+
19728
+ /** 大游:三十六年移一位,上元甲子起七宫,逆数 七→六→四→三→二→一→九→八 */
19729
+ const DAYOU_ORDER = [7, 6, 4, 3, 2, 1, 9, 8];
19730
+ function daYouOf(jinian) {
19731
+ const i = Math.floor((jinian - 1) / 36) % DAYOU_ORDER.length;
19732
+ const palace = DAYOU_ORDER[i];
19733
+ return { index: i, palace, palaceName: PALACES[palace].name };
19734
+ }
19735
+
19736
+ /** 十二支上的位移取位(起点按地支索引,三年/三十年一移) */
19737
+ function branchStep(startIdx, period, jinian) {
19738
+ return { index: (startIdx + Math.floor((jinian - 1) / period)) % 12, name: BRANCH_NAMES[(startIdx + Math.floor((jinian - 1) / period)) % 12] };
19739
+ }
19740
+
19741
+ /**
19742
+ * 十精里的四个「十二宫」神:
19743
+ * 天乙「甲子上元从六起,三年一徙顺行踪」(第六位 = 巳)
19744
+ * 地乙「上元甲子九宫九,顺行十二宫中序,三年亦易」
19745
+ * 直符「上元甲子元从五,十二宫中顺数详」(第五位 = 辰 → 按九宫数五 = 中宫,这里按十二支第五位辰起)
19746
+ * 小游:三年一移,起一宫。
19747
+ */
19748
+ function shiJingOf(jinian) {
19749
+ const tianYi = branchStep(5, 3, jinian);
19750
+ const diYi = branchStep(8, 3, jinian);
19751
+ const zhiFu = branchStep(4, 3, jinian);
19752
+ const SI_SHEN_RING = ['一宫', '二宫', '三宫', '四宫', '五宫', '六宫', '七宫', '八宫', '九宫', '绛宫', '明堂', '玉堂'];
19753
+ const siShen = SI_SHEN_RING[Math.floor((jinian - 1) / 3) % 12];
19754
+ const xiaoYou = PALACES[YANG_WALK[Math.floor((jinian - 1) / 3) % 8]].name;
19755
+ return {
19756
+ tianyi: tianYi.name,
19757
+ diyi: diYi.name,
19758
+ zhifu: zhiFu.name,
19759
+ sishen: siShen,
19760
+ xiaoyou: xiaoYou,
19761
+ note: '天乙、地乙、直符、四神、小游都按上元甲子起例、三年一移;十精的另一半是五福、君基、臣基、民基、大游。',
19762
+ };
19763
+ }
19764
+
19765
+ /**
19766
+ * 阴阳和不和(张良经 / 卷二):太乙在阳宫(八三四九)得奇数为重阳,得偶数为和;
19767
+ * 太乙在阴宫(二七六一)得偶数为重阴,得奇数为和。这里只判这一段,不做胜负推断。
19768
+ */
19769
+ function heShuOf(taiyiPalace, suan) {
19770
+ const YANG = [8, 3, 4, 9];
19771
+ const yin = !YANG.includes(taiyiPalace);
19772
+ const odd = suan % 2 === 1;
19773
+ const chongYang = !yin && odd;
19774
+ const chongYin = yin && !odd;
19775
+ const he = !chongYang && !chongYin;
19776
+ const SHANG = [14, 18];
19777
+ const CI = [23, 29, 32];
19778
+ const XIA = [12, 16, 27, 34, 38];
19779
+ const grade = SHANG.includes(suan) ? '上和' : CI.includes(suan) ? '次和' : XIA.includes(suan) ? '下和' : '';
19780
+ return {
19781
+ grade,
19782
+ yang: !yin,
19783
+ odd,
19784
+ he,
19785
+ chongYang,
19786
+ chongYin,
19787
+ text: he
19788
+ ? `太乙在${yin ? '阴' : '阳'}宫、算得${odd ? '奇' : '偶'}数,为阴阳和${grade ? '(' + grade + ')' : ''}。`
19789
+ : chongYang
19790
+ ? '太乙在阳宫、算得奇数,为重阳,按经文属不和。'
19791
+ : '太乙在阴宫、算得偶数,为重阴,按经文属不和。',
19792
+ };
19793
+ }
19794
+
19795
+
19796
+ /**
19797
+ * 计神:积年 mod 60 得六十甲子第几年(1..60),从寅起逆数十二支。
19798
+ * 甲子年(序 1)计神在寅;寅年(序 3)计神在子,即「太岁在寅,计神在子」。
19799
+ */
19800
+ function jiShenOf(jinian) {
19801
+ const r = rim(jinian, 60);
19802
+ const bi = (((2 - (r - 1)) % 12) + 12) % 12;
19803
+ const idx16 = BRANCH_TO_SIXTEEN[bi];
19804
+ const item = SIXTEEN[idx16];
19805
+ return { r, branch: BRANCH_NAMES[bi], idx16, god: item.god, palace: item.num, palaceName: PALACES[item.num].name };
19806
+ }
19807
+
19808
+ /**
19809
+ * 始击:计神加和德(艮,十六神索引 4)之宫,天目随盘整体移动。
19810
+ * 位移 = 和德索引 − 计神索引;文昌落位顺移同一位移。
19811
+ */
19812
+ function shiJiOf(wenChangIdx, jiIdx16) {
19813
+ const HE_DE = 4;
19814
+ const shift = HE_DE - jiIdx16;
19815
+ const idx16 = ((wenChangIdx + shift) % 16 + 16) % 16;
19816
+ const item = SIXTEEN[idx16];
19817
+ return { shift, idx16, pos: item.pos, god: item.god, palace: item.num, palaceName: PALACES[item.num].name };
19818
+ }
19819
+
19820
+ /**
19821
+ * 主算 / 客算:从某位天目所在处起,沿九宫环顺行累加宫数。
19822
+ * 天目在正宫按本宫数起;在间神先计一,再从该间神所属的正宫继续。
19823
+ * 数到太乙宫前一位为止(不含太乙宫本身)。
19824
+ */
19825
+ function suanOf(idx16, taiyiPalace) {
19826
+ const item = SIXTEEN[idx16];
19827
+ const isJian = !GUA_NAMES.includes(item.pos);
19828
+ let total = isJian ? 1 : 0;
19829
+ let cur = item.num;
19830
+ for (let i = 0; i < PALACE_RING.length; i += 1) {
19831
+ if (cur === taiyiPalace) break;
19832
+ total += cur;
19833
+ cur = nextPalace(cur);
19834
+ }
19835
+ return total === 0 ? 1 : total;
19836
+ }
19837
+
19838
+ /** 大将宫数:算数个位,整十按「得十置一」归一宫 */
19839
+ function generalOf(n) {
19840
+ const g = n % 10;
19841
+ return g === 0 ? 1 : g;
19842
+ }
19843
+
19844
+ /** 参将宫数:大将 × 3 的个位,整十同样归一宫 */
19845
+ function canJiangOf(g) {
19846
+ const c = (g * 3) % 10;
19847
+ return c === 0 ? 1 : c;
19848
+ }
19849
+
19850
+ /** 掩迫囚格关:只判位置关系,不掺吉凶 */
19851
+ function gejuOf(o) {
19852
+ const { taiyiPalace, shiJiPalace, wenChangPalace, zhuDa, keDa, zhuCan, keCan } = o;
19853
+ const near = [nextPalace(taiyiPalace), prevPalace(taiyiPalace)];
19854
+ const yan = shiJiPalace === taiyiPalace;
19855
+ const ji = near.includes(shiJiPalace);
19856
+ const ge = shiJiPalace === OPPOSITE_PALACE[taiyiPalace];
19857
+ const dui = wenChangPalace === OPPOSITE_PALACE[taiyiPalace];
19858
+ const ti = keDa === wenChangPalace;
19859
+ const poAt = [];
19860
+ if (near.includes(wenChangPalace)) poAt.push('文昌');
19861
+ if (near.includes(zhuDa)) poAt.push('主大将');
19862
+ if (near.includes(keDa)) poAt.push('客大将');
19863
+ if (near.includes(zhuCan)) poAt.push('主参将');
19864
+ if (near.includes(keCan)) poAt.push('客参将');
19865
+ const qiuAt = [['主大将', zhuDa], ['客大将', keDa], ['主参将', zhuCan], ['客参将', keCan]]
19866
+ .filter((x) => x[1] === taiyiPalace).map((x) => x[0]);
19867
+ const cross = [
19868
+ ['主大将', zhuDa, '客大将', keDa],
19869
+ ['主大将', zhuDa, '客参将', keCan],
19870
+ ['客大将', keDa, '主参将', zhuCan],
19871
+ ['主参将', zhuCan, '客参将', keCan],
19872
+ ];
19873
+ const guan = cross.filter((x) => x[1] === x[3]).map((x) => x[0] + '与' + x[2] + '同宫');
19874
+ const list = [];
19875
+ if (yan) list.push('掩:始击与太乙同宫');
19876
+ if (ji) list.push('击:始击在太乙左右');
19877
+ if (ge) list.push('格:太乙与始击相望(对宫)');
19878
+ if (dui) list.push('对:文昌冲太乙宫');
19879
+ if (ti) list.push('提:客大将与文昌同宫');
19880
+ if (poAt.length) list.push('迫:' + poAt.join('、') + '在太乙前后');
19881
+ if (qiuAt.length) list.push('囚:' + qiuAt.join('、') + '与太乙同宫');
19882
+ if (guan.length) list.push('关:' + guan.join(','));
19883
+ return { yan, ji, ge, dui, ti, po: poAt, qiu: qiuAt, guan, list };
19884
+ }
19885
+
19438
19886
  /** 主入口 */
19439
19887
  function buildTaiyi(input) {
19440
19888
  assertObject(input, '太乙神数');
@@ -19446,12 +19894,52 @@ function buildTaiyi(input) {
19446
19894
  const yuanji = yuanJiOf(rest360);
19447
19895
  const gate = eightGate(year);
19448
19896
 
19449
- // 年家默认阳遁;给了具体日期时,口径仍写在 meta 里,方便以后接交节判定
19450
- const dun = 'yang';
19897
+ // 阳遁 / 阴遁按交节判:冬至到次年夏至为阳,夏至到冬至为阴。
19898
+ // 这一盘总要落到某一天,所以直接按日期判,不再默认阳遁。
19899
+ const hourNum = typeof input.hour === 'number' ? input.hour : 0;
19900
+ const nowJd = toJDN(year, month, day) - 0.5 + hourNum / 24;
19901
+ const dunInfo = dunOf(nowJd);
19902
+ const dun = dunInfo.dun;
19451
19903
 
19452
19904
  const t = taiyiPalace(ju, dun);
19453
19905
  const wc = wenChang(jinian, dun);
19454
19906
 
19907
+ const wcIdx16 = SIXTEEN.findIndex((x) => x.pos === wc.pos && x.god === wc.god);
19908
+ const js = jiShenOf(jinian);
19909
+ const sj = shiJiOf(wcIdx16, js.idx16);
19910
+ const zhuSuan = suanOf(wcIdx16, t.palace);
19911
+ const keSuan = suanOf(sj.idx16, t.palace);
19912
+ const zhuDa = generalOf(zhuSuan);
19913
+ const keDa = generalOf(keSuan);
19914
+ const zhuCan = canJiangOf(zhuDa);
19915
+ const keCan = canJiangOf(keDa);
19916
+ const geju = gejuOf({
19917
+ taiyiPalace: t.palace,
19918
+ shiJiPalace: sj.palace,
19919
+ wenChangPalace: wc.num,
19920
+ zhuDa,
19921
+ keDa,
19922
+ zhuCan,
19923
+ keCan,
19924
+ });
19925
+ const yearBranchIdx = (((year - 4) % 12) + 12) % 12;
19926
+ const dm = dingMuOf(wcIdx16, yearBranchIdx);
19927
+ const heZhu = heShuOf(t.palace, zhuSuan);
19928
+ const heKe = heShuOf(t.palace, keSuan);
19929
+ const heshu = { zhu: heZhu, ke: heKe };
19930
+ const jixiong = jiXiongOf({ geju, heshu, gate });
19931
+ const dayStem = dayStemOf(year, month, day);
19932
+ const jiangObj = {
19933
+ zhuDa, keDa, zhuCan, keCan,
19934
+ zhuDaName: PALACES[zhuDa].name, keDaName: PALACES[keDa].name,
19935
+ zhuCanName: PALACES[zhuCan].name, keCanName: PALACES[keCan].name,
19936
+ };
19937
+ const shenjiang = shenJiangOf({ dayStem, hour: typeof input.hour === 'number' ? input.hour : 0, jiang: jiangObj, wenchang: wc, shiji: sj });
19938
+ const verdict = verdictOf({ jixiong, shenjiang, gate });
19939
+ const monthJi = monthJiOf(jinian);
19940
+ const dayJi = dayJiOf(jinian);
19941
+ const hourJi = hourJiOf({ year, month, day, hour: typeof input.hour === 'number' ? input.hour : 0 });
19942
+
19455
19943
  return {
19456
19944
  system: 'taiyi',
19457
19945
  meta: {
@@ -19462,18 +19950,45 @@ function buildTaiyi(input) {
19462
19950
  ju,
19463
19951
  dun,
19464
19952
  dunText: dun === 'yin' ? '阴遁' : '阳遁',
19953
+ dunBy: dunInfo.by,
19465
19954
  epoch: TAIYI_EPOCH,
19466
19955
  },
19467
19956
  year: { ...yuanji, rest360 },
19468
19957
  taiyi: t,
19469
19958
  gate,
19470
19959
  wenchang: wc,
19960
+ jishen: js,
19961
+ shiji: sj,
19962
+ suan: { zhu: zhuSuan, ke: keSuan },
19963
+ jiang: {
19964
+ zhuDa,
19965
+ keDa,
19966
+ zhuCan,
19967
+ keCan,
19968
+ zhuDaName: PALACES[zhuDa].name,
19969
+ keDaName: PALACES[keDa].name,
19970
+ zhuCanName: PALACES[zhuCan].name,
19971
+ keCanName: PALACES[keCan].name,
19972
+ },
19973
+ geju,
19974
+ dingmu: dm,
19975
+ sanji: sanJiOf(jinian),
19976
+ wufu: wuFuOf(jinian),
19977
+ dayou: daYouOf(jinian),
19978
+ shijing: shiJingOf(jinian),
19979
+ heshu,
19980
+ jixiong,
19981
+ verdict,
19982
+ shenjiang,
19983
+ month: monthJi,
19984
+ day: dayJi,
19985
+ hour: hourJi,
19471
19986
  scope: TAIYI_SCOPE,
19472
19987
  };
19473
19988
  }
19474
19989
 
19475
19990
 
19476
- return { TAIYI_EPOCH, PALACES, SIXTEEN, YANG_WALK, YIN_WALK, EIGHT_GATES, GATE_BASE_YEAR, GATE_PERIOD, FIVE_YUAN, THREE_LI, TAIYI_SCOPE, taiyiJinian, taiyiRound, yuanJiOf, dunOf, taiyiPalace, eightGate, wenChang, buildTaiyi };
19991
+ return { TAIYI_EPOCH, PALACES, SIXTEEN, YANG_WALK, YIN_WALK, EIGHT_GATES, GATE_BASE_YEAR, GATE_PERIOD, FIVE_YUAN, THREE_LI, ZHANG_SUI, ZHANG_YUE, RI_FA, YUE_FA, palaceFromR24, branchWalk, sixteenStep, monthJiOf, dayJiOf, hourJiOf, jiXiongOf, TWELVE_GODS, GOD_GOOD, GOD_BAD, TRIGRAM_TO_BRANCH, POS_TO_BRANCH, dayStemOf, twelveGodsOf, shenJiangOf, verdictOf, TAIYI_SCOPE, taiyiJinian, taiyiRound, yuanJiOf, dunOf, taiyiPalace, eightGate, wenChang, GUA_NAMES, PALACE_RING, BRANCH_NAMES, BRANCH_TO_SIXTEEN, OPPOSITE_PALACE, nextPalace, prevPalace, LIU_HE, dingMuOf, sanJiOf, WUFU_ORDER, wuFuOf, DAYOU_ORDER, daYouOf, shiJingOf, heShuOf, jiShenOf, shiJiOf, suanOf, generalOf, canJiangOf, gejuOf, buildTaiyi };
19477
19992
  })();
19478
19993
 
19479
19994
  __mods.xiaoliuren = (function () {
@@ -29113,9 +29628,36 @@ function taiyiSummary(r) {
29113
29628
  h: '文昌在哪',
29114
29629
  t: `文昌在${r.wenchang.pos}(${r.wenchang.god},${r.wenchang.palaceName}宫)。文昌十八年一周,阳局从申起、阴局从寅起,路上遇乾、坤各数两次,所以要数满十八步才回到原点。`,
29115
29630
  },
29631
+ {
29632
+ h: '计神、始击与主客算',
29633
+ t: `计神在${r.jishen.branch},始击在${r.shiji.pos}(${r.shiji.god})。主算 ${r.suan.zhu}、客算 ${r.suan.ke}:大将按算数的个位落宫(整十归一),参将是大将乘三的个位。四个将分别落在${r.jiang.zhuDaName}、${r.jiang.keDaName}、${r.jiang.zhuCanName}、${r.jiang.keCanName}宫。`,
29634
+ },
29635
+ {
29636
+ h: '定目、三基与五福',
29637
+ t: `定目在${r.dingmu.pos}(${r.dingmu.god}):淘金歌讲「以合神加太岁」,把合神搬到太岁处,天目跟着转过去,落点就是定目。三基——君基${r.sanji.jun}(三十年一移)、臣基${r.sanji.chen}(三年一移)、民基${r.sanji.min}(一年一移);五福在${r.wufu.palaceName}宫(四十五年一移),大游在${r.dayou.palaceName}宫(三十六年一移、逆数)。十精另五位:天乙${r.shijing.tianyi}、地乙${r.shijing.diyi}、直符${r.shijing.zhifu}、四神${r.shijing.sishen}、小游${r.shijing.xiaoyou}。`,
29638
+ },
29639
+ {
29640
+ h: '阴阳数和',
29641
+ t: `主算:${r.heshu.zhu.text}客算:${r.heshu.ke.text}这一段只说「和不和」,上和、次和、下和是算数落在特定数上的分级,不据此断胜负。`,
29642
+ },
29643
+ {
29644
+ h: '卦象吉凶',
29645
+ t: `${r.jixiong.label}。${r.jixiong.text}${r.jixiong.note}判据出自卷一《推太公考时法》,只标吉凶,不推成与不成。`,
29646
+ },
29647
+ {
29648
+ h: '神将与判辞',
29649
+ t: (() => {
29650
+ const sj = r.shenjiang;
29651
+ if (!sj || !sj.rows) return '这一盘没有排神将。';
29652
+ const goods = sj.goods && sj.goods.length ? '在吉神下的:' + sj.goods.join('、') : '没有将落在吉神下';
29653
+ const bads = sj.bads && sj.bads.length ? '在凶神下的:' + sj.bads.join('、') : '没有将落在凶神下';
29654
+ const v = r.verdict ? '合起来判「' + r.verdict.label + '」。' : '';
29655
+ return '按日干起十二神(' + sj.stem + '日、' + (sj.day ? '昼贵' : '夜贵') + '、贵人临' + sj.startBranch + (sj.dir > 0 ? '顺' : '逆') + '行),' + goods + ';' + bads + '。' + v + '这一层是古人拿十二神看四将落位的办法,只说明古法怎么判,不是对事情的预测。';
29656
+ })(),
29657
+ },
29116
29658
  {
29117
29659
  h: '这一盘算到哪一层',
29118
- t: `积年 ${r.meta.jinian},残年 ${r.meta.rest360},${r.meta.dunText}${r.meta.ju}局。太乙、八门、文昌三个落点是齐的;${r.scope.notCovered.slice(0, 2).join('、')}这几项没有收录,盘面上也不显示。`,
29660
+ t: `积年 ${r.meta.jinian},残年 ${r.meta.rest360},${r.meta.dunText}${r.meta.ju}局。太乙、八门、文昌、计神、始击、主客算与四将、掩迫囚格关、定目、三基、五福、大游、十精、阴阳数和、月日时三计、古法吉凶都在;${r.scope.notCovered.join('、')}这几项没有收录,盘面上也不显示。`,
29119
29661
  },
29120
29662
  ];
29121
29663
  return {
@@ -29129,7 +29671,7 @@ function taiyiSummary(r) {
29129
29671
  `八门十年一变的说法常被混用,这里按三十年一转的口径——${r.gate.gate}值这三十年,不是今年才轮到。`,
29130
29672
  '太乙是象数盘,给的是位置的对应关系,不是「今年会发生什么」的判决。',
29131
29673
  ],
29132
- caveat: `这一层只到太乙、八门、文昌三个落点;${r.scope.notCovered.join(';')}都未收录,别按它们解读。`,
29674
+ caveat: `这一层到太乙、八门、文昌、计神、始击、主客算与四将、八种格局、定目、三基、五福、大游、十精与阴阳数和;${r.scope.notCovered.join(';')}都未收录,别按它们解读。`,
29133
29675
  footer: '太乙年家用积年推局,与八字按立春换年、运气按大寒分年都不同口径,三套不要互相印证。',
29134
29676
  };
29135
29677
  }
@@ -30850,7 +31392,7 @@ function computeRaw(args = {}) {
30850
31392
  }
30851
31393
  if (system === 'taiyi') {
30852
31394
  const dt = parseDateTime(args.datetime);
30853
- const result = buildTaiyi({ year: dt.year, month: dt.month, day: dt.day });
31395
+ const result = buildTaiyi({ year: dt.year, month: dt.month, day: dt.day, hour: dt.hour });
30854
31396
  return { ...result, summary: taiyiText(result) };
30855
31397
  }
30856
31398
  if (system === 'constitution') {
@@ -31114,7 +31656,25 @@ function taiyiText(r) {
31114
31656
  L.push(`太乙在${r.taiyi.palaceName}宫(第${r.taiyi.palace}宫,${r.taiyi.dir}),第${r.taiyi.yearInPalace}年,${r.taiyi.li}。`);
31115
31657
  L.push(`八门:${r.gate.gate}。`);
31116
31658
  L.push(`文昌在${r.wenchang.pos}(${r.wenchang.god},${r.wenchang.palaceName}宫)。`);
31117
- L.push(`这一层只算到太乙、八门、文昌三个落点;${r.scope.notCovered.join('、')}。`);
31659
+ L.push(`计神在${r.jishen.branch}(${r.jishen.god}),始击在${r.shiji.pos}(${r.shiji.god},${r.shiji.palaceName}宫)。`);
31660
+ L.push(`主算 ${r.suan.zhu}:主大将${r.jiang.zhuDaName}宫、主参将${r.jiang.zhuCanName}宫;客算 ${r.suan.ke}:客大将${r.jiang.keDaName}宫、客参将${r.jiang.keCanName}宫。`);
31661
+ L.push(r.geju.list.length ? `格局:${r.geju.list.join(';')}。` : '四将之间不相犯,没有掩、迫、囚、格、关。');
31662
+ L.push(`定目在${r.dingmu.pos}(${r.dingmu.god},${r.dingmu.palaceName}宫)。`);
31663
+ L.push(`三基:君基${r.sanji.jun}、臣基${r.sanji.chen}、民基${r.sanji.min};五福在${r.wufu.palaceName}宫,大游在${r.dayou.palaceName}宫。`);
31664
+ L.push(`十精:天乙${r.shijing.tianyi}、地乙${r.shijing.diyi}、直符${r.shijing.zhifu}、四神${r.shijing.sishen}、小游${r.shijing.xiaoyou}。`);
31665
+ L.push(`数和-主算:${r.heshu.zhu.text} 客算:${r.heshu.ke.text}`);
31666
+ const sj = r.shenjiang || {};
31667
+ if (sj.rows) {
31668
+ const goods = sj.goods && sj.goods.length ? sj.goods.join('、') : '无';
31669
+ const bads = sj.bads && sj.bads.length ? sj.bads.join('、') : '无';
31670
+ L.push(`神将:${sj.stem}日(${sj.day ? '昼贵' : '夜贵'})起${sj.startBranch}、${sj.dir > 0 ? '顺' : '逆'}行;在吉神下的有 ${goods};在凶神下的有 ${bads}。`);
31671
+ }
31672
+ if (r.verdict) L.push(`判辞:${r.verdict.label}。`);
31673
+ L.push(`月计:太乙在${r.month.taiyi.palaceName}宫(第${r.month.taiyi.unitInPalace}月),天目${r.month.mu.pos}(${r.month.mu.god}),计神在${r.month.jishen.branch}。`);
31674
+ L.push(`日计:太乙在${r.day.taiyi.palaceName}宫(第${r.day.taiyi.unitInPalace}日),天目${r.day.mu.pos}(${r.day.mu.god}),计神在${r.day.jishen.branch}。`);
31675
+ L.push(`时计:太乙在${r.hour.taiyi.palaceName}宫(第${r.hour.taiyi.unitInPalace}时),计神在${r.hour.jishen.branch}。${r.hour.note}`);
31676
+ L.push(`卦象:${r.jixiong.label}——${r.jixiong.text}`);
31677
+ L.push(`这一层到太乙、八门、文昌、计神、始击、主客算与四将、八种格局、定目、三基、五福、大游、十精、阴阳数和、月日时三计与古法吉凶;${r.scope.notCovered.join('、')}未收录。`);
31118
31678
  return L.join('\n');
31119
31679
  }
31120
31680
 
@@ -31428,7 +31988,7 @@ return { interpret, DIRECTIONS, DIRECTION_DEFAULT, BRIGHTNESS, flowOf, parseDate
31428
31988
  })();
31429
31989
 
31430
31990
  window.Engine = __mods.index;
31431
- window.__MP_VER = "0.69.0";
31991
+ window.__MP_VER = "0.70.0";
31432
31992
  </script>
31433
31993
  <script>
31434
31994
  // 两个 UI 共用的表单规则:宿主面板(src/app.js)与独立页(src/web-ui.js)。
@@ -31549,7 +32109,7 @@ window.__MP_VER = "0.69.0";
31549
32109
  --tri:#eef0ea;--soul:#f7ece9;--sel:#f5efe9;--link:#f0efe9;
31550
32110
  --red:#a02c26;--red-rgb:160,44,38;--lu:#3d5a52;--lu-rgb:61,90,82;
31551
32111
  --quan:#6e5a2e;--quan-rgb:110,90,46;--ke:#3a5568;--ke-rgb:58,85,104;--ji:#a02c26;
31552
- --br-good:#4c7a5c;--br-bad:#9c5b56;--on-accent:#fff;--wx-metal:#8a6b1f;
32112
+ --br-good:#4c7a5c;--br-bad:#9c5b56;--on-accent:var(--on-accent);--wx-metal:#8a6b1f;
31553
32113
  --tg-bi:#4e5d6b;--tg-shi:#55685c;--tg-cai:#6e5a2e;--tg-guan:#8a4a42;--tg-yin:#5d5570;
31554
32114
  /* 之前 mp-cli / mp-qt / mp-cl / 起名卡里引用了 --ink3、--fx、--sans,却从未定义:
31555
32115
  var() 取不到值 → 整条声明作废,字色与字形全靠继承,楷体、弱化灰都成了摆设。 */
@@ -32158,6 +32718,77 @@ window.__MP_VER = "0.69.0";
32158
32718
  /* 三柱盘提示:表下一行,别让人以为漏画了一列 */
32159
32719
  .pp-warn{margin:8px 0 0;padding:7px 10px;border:1px solid color-mix(in srgb,var(--quan) 34%,var(--line));border-radius:8px;background:color-mix(in srgb,var(--quan) 10%,transparent);color:var(--ink2);font-size:11.5px;line-height:1.55}
32160
32720
  /* 顶部人话总结:第一屏唯一的「先说结论」块,边框与留白都比盘面重一档 */
32721
+ .mp-wl-h{display:flex;flex-wrap:wrap;gap:8px;padding-bottom:7px}
32722
+ .mp-wl-y{font-size:15px;font-weight:700}
32723
+ .mp-wl-z{font-weight:600;color:var(--lu)}
32724
+ .mp-wl-m,.mp-wl-tm,.mp-wl-tg,.mp-wl-no{font-size:11px;color:var(--label)}
32725
+ .mp-wl-tag{display:inline-block;margin:0 6px 4px 0;padding:1px 8px;border-radius:999px;background:var(--band)}
32726
+ .mp-wl-tag.on{background:var(--lu);color:var(--on-accent)}
32727
+ .mp-wl-sec,.mp-wl-note{font-size:13px;line-height:1.6;padding-bottom:5px}
32728
+ .mp-wl-sec em{font-style:normal;margin-right:6px}
32729
+ .mp-wl-steps{display:flex;flex-direction:column;gap:3px}
32730
+ .mp-wl-step{display:grid;grid-template-columns:16px 1fr 34px auto;gap:7px;font-size:12px;padding:3px 7px;border-radius:7px}
32731
+ .mp-wl-step.on{background:var(--band);font-weight:600}
32732
+ .mp-ty-h{display:flex;flex-wrap:wrap;gap:8px;align-items:baseline;padding-bottom:7px}
32733
+ .mp-ty-y{font-size:15px;font-weight:700}
32734
+ .mp-ty-j{font-weight:600;color:var(--lu)}
32735
+ .mp-ty-m{font-size:11px;color:var(--label)}
32736
+ .mp-ty-plain{padding:9px 2px 10px;border-top:1px solid var(--hair);margin-top:8px}
32737
+ .mp-ty-plain p{margin:0 0 6px;font-size:13px;line-height:1.65;color:var(--ink2)}
32738
+ .mp-ty-plain .mp-ty-lead{font-size:14px;font-weight:600;color:var(--ink)}
32739
+ .mp-ty-plain .mp-ty-close{font-size:12px;color:var(--label);margin-bottom:0}
32740
+ .mp-ty-det{margin-top:4px}
32741
+ .mp-ty-det summary{cursor:pointer;font-size:12px;color:var(--label);padding:4px 0}
32742
+ .mp-ty-g{display:grid;grid-template-columns:repeat(3,1fr);gap:4px;margin:2px 0 8px}
32743
+ .mp-ty-cell{position:relative;border-radius:8px;background:var(--band);padding:7px 6px;text-align:center;font-size:12px;min-height:50px}
32744
+ .mp-ty-cell b{display:block;font-size:13px}
32745
+ .mp-ty-cell em{font-style:normal;font-size:11px;color:var(--label)}
32746
+ .mp-ty-cell.on{background:var(--lu);color:var(--on-accent)}
32747
+ .mp-ty-cell.on em{color:rgba(255,255,255,.82)}
32748
+ .mp-ty-cell.mid{opacity:.5}
32749
+ .mp-ty-mark{position:absolute;top:3px;right:4px;font-style:normal;font-size:10px;padding:0 4px;border-radius:999px;background:var(--on-accent);color:var(--lu)}
32750
+ .mp-ty-jx{font-weight:600}
32751
+ .mp-ty-jx.xiong{color:var(--red)}
32752
+ .mp-ty-jx.buhe{color:var(--quan)}
32753
+ .mp-ty-jx.daji{color:var(--lu);font-weight:700}
32754
+ .mp-ty-jx.ji{color:var(--lu)}
32755
+ .mp-ty-mark.s{top:19px;background:var(--band);color:var(--ink2)}
32756
+ .mp-ty-mark.w{right:auto;left:4px;color:var(--ink2)}
32757
+ .mp-ty-sec{font-size:13px;line-height:1.6;padding-bottom:4px}
32758
+ .mp-ty-sec em{font-style:normal;margin-right:6px;color:var(--label)}
32759
+ .mp-ty-note{font-size:11px;line-height:1.6;color:var(--label)}
32760
+ .mp-cs{border-radius:12px;overflow:hidden;background:var(--label);border:1px solid var(--hair)}
32761
+ .mp-cs-h{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:10px 12px;border-bottom:1px solid var(--hair)}
32762
+ .mp-cs-main{font-size:20px;font-weight:800;letter-spacing:.04em}
32763
+ .mp-cs-meta{display:flex;flex-direction:column;gap:1px;flex:1 1 160px;min-width:0}
32764
+ .mp-cs-meta b{font-size:13px;font-weight:600;line-height:1.5}
32765
+ .mp-cs-meta i{font-size:12px;font-style:normal;color:var(--ink2)}
32766
+ .mp-cs-count{font-size:12px;color:var(--ink2);white-space:nowrap}
32767
+ .mp-cs-bars{display:flex;flex-direction:column;gap:5px;padding:10px 12px 8px}
32768
+ .mp-cs-row{display:grid;grid-template-columns:52px 1fr 30px 52px;align-items:center;gap:8px;font-size:12px;line-height:1.4}
32769
+ .mp-cs-row.main{font-weight:700}
32770
+ .mp-cs-n{white-space:nowrap}
32771
+ .mp-cs-track{position:relative;height:8px;border-radius:999px;background:var(--band)}
32772
+ .mp-cs-track i{display:block;height:100%;border-radius:999px;background:var(--dimline)}
32773
+ .mp-cs-track i.on{background:var(--lu)}
32774
+ .mp-cs-tick{position:absolute;top:0;bottom:0;width:1px;background:var(--label)}
32775
+ .mp-cs-v{text-align:right;color:var(--ink)}
32776
+ .mp-cs-l{color:var(--ink2);font-size:11px}
32777
+ .mp-cs-sec{padding:2px 12px 6px;font-size:13px;line-height:1.7}
32778
+ .mp-cs-sec em{display:inline-block;margin-right:6px;padding:0 6px;border-radius:4px;font-style:normal;font-size:11px;background:var(--band);color:var(--ink2)}
32779
+ .mp-cs-care{padding:4px 12px 8px;font-size:13px;line-height:1.7}
32780
+ .mp-cs-care b{display:block;margin-bottom:2px}
32781
+ .mp-cs-care ul{margin:0;padding-left:18px}
32782
+ .mp-cs-note{padding:6px 12px 10px;font-size:12px;line-height:1.6;color:var(--ink2)}
32783
+ .mp-cs-paper{padding:8px 12px;font-size:13px;line-height:1.7}
32784
+ .mp-cs-paper ol{margin:6px 0;padding-left:20px}
32785
+ .mp-cs-paper li{margin:2px 0}
32786
+ .mp-cs-no{display:inline-block;min-width:22px;color:var(--ink2);font-variant-numeric:tabular-nums}
32787
+ .mp-cs-paper li em{margin-left:6px;font-style:normal;font-size:11px;color:var(--ink2)}
32788
+ .mp-cs-paper .mp-cs-h{display:flex;align-items:center;gap:10px;padding:0 0 6px}
32789
+ .mp-cs-paper .mp-cs-h i{font-size:12px;font-style:normal;color:var(--ink2)}
32790
+ .mp-cs-paper .mp-cs-count{font-size:12px;color:var(--ink2)}
32791
+ .mp-cs-paper .mp-cs-note{font-size:12px;color:var(--ink2)}
32161
32792
  .mp-br{margin:0 0 12px;padding:14px 16px 12px;border:1px solid color-mix(in srgb,var(--red) 26%,var(--line));border-radius:12px;
32162
32793
  background:linear-gradient(180deg,color-mix(in srgb,var(--red) 6%,var(--card)),var(--card));color:var(--ink)}
32163
32794
  .mp-br-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:6px}
@@ -35607,34 +36238,109 @@ window.__MP_VER = "0.69.0";
35607
36238
  // 分数是数值,直接插;文字一律走 esc(check-html-sinks 按「调用了 esc」核对)。
35608
36239
  // 太乙神数:九宫地盘 + 太乙/文昌落点 + 八门 + 五元六纪。
35609
36240
  // 地盘按「南上北下」排:巽离坤 / 震中兑 / 艮坎乾。中五宫太乙不入,只作方位补全。
35610
- // 只有太乙、八门、文昌三个落点是算实的,其余项目(主客算、格局)不在盘上出现。
36241
+ // 太乙、八门、文昌、计神、始击、主客算与四将都是算实的;定目、三基五福十精、击格不在盘上出现。
35611
36242
  pp.taiyiHTML = function (r) {
35612
36243
  if (!r || !r.taiyi || !r.meta) return '';
35613
36244
  const t = r.taiyi;
35614
36245
  const wc = r.wenchang || {};
36246
+ const sj = r.shiji || {};
36247
+ const js = r.jishen || {};
36248
+ const su = r.suan || {};
36249
+ const jj = r.jiang || {};
36250
+ const gj = r.geju || {};
35615
36251
  const grid = [[9, '巽'], [2, '离'], [7, '坤'], [4, '震'], [5, '中'], [6, '兑'], [3, '艮'], [8, '坎'], [1, '乾']];
35616
36252
  const cells = grid.map((c) => {
35617
36253
  const num = c[0];
35618
36254
  const nm = c[1];
35619
36255
  const on = t.palace === num;
35620
36256
  const w = wc.num === num;
35621
- const marks = (on ? '<i class="mp-ty-mark">太乙</i>' : '') + (w ? '<i class="mp-ty-mark w">文昌</i>' : '');
36257
+ const sjOn = sj.palace === num;
36258
+ const marks = (on ? '<i class="mp-ty-mark">太乙</i>' : '') + (sjOn ? '<i class="mp-ty-mark s">始击</i>' : '') + (w ? '<i class="mp-ty-mark w">文昌</i>' : '');
35622
36259
  return `<div class="mp-ty-cell${on ? ' on' : ''}${nm === '中' ? ' mid' : ''}"><b>${esc(nm)}</b><em>${num}</em>${marks}</div>`;
35623
36260
  }).join('');
35624
36261
  const nc = (r.scope && r.scope.notCovered) || [];
36262
+ const mo = r.month || {};
36263
+ const da = r.day || {};
36264
+ const ho = r.hour || {};
36265
+ const monthN = (mo.taiyi && mo.taiyi.palaceName) || '';
36266
+ const monthU = String((mo.taiyi && mo.taiyi.unitInPalace) || '');
36267
+ const monthMu = mo.mu ? mo.mu.pos + '(' + mo.mu.god + ')' : '';
36268
+ const monthJs = (mo.jishen && mo.jishen.branch) || '';
36269
+ const dayN = (da.taiyi && da.taiyi.palaceName) || '';
36270
+ const dayU = String((da.taiyi && da.taiyi.unitInPalace) || '');
36271
+ const dayMu = da.mu ? da.mu.pos + '(' + da.mu.god + ')' : '';
36272
+ const dayJs = (da.jishen && da.jishen.branch) || '';
36273
+ const hourN = (ho.taiyi && ho.taiyi.palaceName) || '';
36274
+ const hourU = String((ho.taiyi && ho.taiyi.unitInPalace) || '');
36275
+ const hourJs = (ho.jishen && ho.jishen.branch) || '';
36276
+ const jx = r.jixiong || {};
36277
+ const vd = r.verdict || {};
36278
+ const vdGrade = vd.grade || jx.grade || 'xiong';
36279
+ const vdLabel = vd.label || jx.label || '凶';
36280
+ const sjj = r.shenjiang || {};
36281
+ const sjLine = sjj.rows
36282
+ ? `${sjj.stem}日、${sjj.day ? '昼贵' : '夜贵'}起${sjj.startBranch}${sjj.dir > 0 ? '顺' : '逆'}行;吉神下:${(sjj.goods || []).join('、') || '无'};凶神下:${(sjj.bads || []).join('、') || '无'}`
36283
+ : '未排';
36284
+ const jxGrade = jx.grade || 'xiong';
36285
+ const jxLabel = jx.label || '凶';
36286
+ const gateName = (r.gate && r.gate.gate) || '';
36287
+ // 八种格局翻成日常话,一个词只翻一次
36288
+ const SAY = {
36289
+ 掩: '客方的目和太乙挤在同一格',
36290
+ 击: '始击挨在太乙左右',
36291
+ 格: '太乙和始击隔一格正面对上',
36292
+ 对: '文昌从对面顶过来',
36293
+ 提: '客大将和文昌挤在一格',
36294
+ 迫: '有将贴得太近,就在太乙前后一格',
36295
+ 囚: '有将被关在太乙那一格里',
36296
+ 关: '主客两边的人撞在一处',
36297
+ };
36298
+ const hits = (gj.list || []).map((x) => {
36299
+ const k = String(x).charAt(0);
36300
+ return SAY[k] ? k + '——' + SAY[k] : String(x);
36301
+ });
36302
+ const lead = jxGrade === 'xiong'
36303
+ ? `太乙站在${t.palaceName}宫(${t.dir}),值${gateName}门,判凶:主客两边有几样撞到了一起。`
36304
+ : jxGrade === 'daji'
36305
+ ? `太乙站在${t.palaceName}宫(${t.dir}),值${gateName}门,判大吉:位置和数都顺,门也在吉道上。`
36306
+ : jxGrade === 'buhe'
36307
+ ? `太乙站在${t.palaceName}宫(${t.dir}),值${gateName}门,判不和:位置不冲突,但数上不合。`
36308
+ : `太乙站在${t.palaceName}宫(${t.dir}),值${gateName}门,判吉:位置不冲突。`;
35625
36309
  return `<section class="mp-ty" aria-label="太乙神数">
35626
36310
  <div class="mp-ty-h">
35627
36311
  <span class="mp-ty-y">${esc(String(r.meta.year))} 年</span>
35628
36312
  <span class="mp-ty-j">${esc(r.meta.dunText || '')}${esc(String(r.meta.ju))}局</span>
35629
36313
  <span class="mp-ty-m">太乙临 ${esc(t.palaceName || '')} 宫</span>
35630
- <span class="mp-ty-m">${esc(r.gate ? r.gate.gate : '')}</span>
36314
+ <span class="mp-ty-m">${esc(gateName)}</span>
35631
36315
  </div>
35632
36316
  <div class="mp-ty-g">${cells}</div>
35633
- <div class="mp-ty-sec"><em>太乙</em>第 ${esc(String(t.palace || ''))} 宫(${esc(t.dir || '')}),三年里的第 ${esc(String(t.yearInPalace || ''))} 年,${esc(t.li || '')}</div>
35634
- <div class="mp-ty-sec"><em>八门</em>${esc(r.gate ? r.gate.gate : '')} 八门三十年一转,1954 年从休门起</div>
35635
- <div class="mp-ty-sec"><em>文昌</em>${esc(wc.pos || '')}(${esc(wc.god || '')},${esc(wc.palaceName || '')}宫) 十八年一周</div>
35636
- <div class="mp-ty-sec"><em>积年</em>${esc(String(r.meta.jinian || ''))} 残年 ${esc(String(r.meta.rest360 || ''))} ${esc(r.year ? r.year.jiName : '')}${esc(r.year ? String(r.year.jiYear) : '')}年 ${esc(r.year ? r.year.yuanName : '')}第 ${esc(r.year ? String(r.year.yuanYear) : '')} 年</div>
35637
- <div class="mp-ty-note">只算到太乙、八门、文昌三个落点;${esc(nc.join('、'))}未收录,盘上不显示。</div>
36317
+ <div class="mp-ty-plain">
36318
+ <p class="mp-ty-lead">${esc(lead)}</p>
36319
+ <p>先看太乙落在哪一格——那是「主」这一年的位置,整张盘围着它转。</p>
36320
+ <p>${esc(gateName)}门一值三十年,管的是这三十年的大环境,不是今年单一年的事。</p>
36321
+ <p>判${esc(jxLabel)},是因为${esc(hits.length ? hits.join(';') : '八种位置关系一个都没犯')}。</p>
36322
+ <p class="mp-ty-close">这一层只摆位置和数,不回答事情成不成;想看每一步怎么来的,展开下面的细目。</p>
36323
+ </div>
36324
+ <details class="mp-ty-det">
36325
+ <summary>细目(想核对推导再展开)</summary>
36326
+ <div class="mp-ty-sec"><em>太乙</em>第 ${esc(String(t.palace || ''))} 宫(${esc(t.dir || '')}),三年里的第 ${esc(String(t.yearInPalace || ''))} 年,${esc(t.li || '')}</div>
36327
+ <div class="mp-ty-sec"><em>八门</em>${esc(gateName)} 八门三十年一转,1954 年从休门起</div>
36328
+ <div class="mp-ty-sec"><em>文昌</em>${esc(wc.pos || '')}(${esc(wc.god || '')},${esc(wc.palaceName || '')}宫) 十八年一周</div>
36329
+ <div class="mp-ty-sec"><em>定目</em>${esc((r.dingmu && r.dingmu.pos) || '')}(${esc((r.dingmu && r.dingmu.god) || '')}) <em>三基</em>君${esc((r.sanji && r.sanji.jun) || '')} 臣${esc((r.sanji && r.sanji.chen) || '')} 民${esc((r.sanji && r.sanji.min) || '')}</div>
36330
+ <div class="mp-ty-sec"><em>五福</em>${esc((r.wufu && r.wufu.palaceName) || '')}宫 <em>大游</em>${esc((r.dayou && r.dayou.palaceName) || '')}宫 <em>十精</em>天乙${esc((r.shijing && r.shijing.tianyi) || '')} 地乙${esc((r.shijing && r.shijing.diyi) || '')} 直符${esc((r.shijing && r.shijing.zhifu) || '')}</div>
36331
+ <div class="mp-ty-sec"><em>数和</em>主算 ${esc((r.heshu && r.heshu.zhu && r.heshu.zhu.text) || '')} 客算 ${esc((r.heshu && r.heshu.ke && r.heshu.ke.text) || '')}</div>
36332
+ <div class="mp-ty-sec"><em>月计</em>太乙在 ${esc(monthN)} 宫(第 ${esc(monthU)} 月) 天目 ${esc(monthMu)} 计神 ${esc(monthJs)}</div>
36333
+ <div class="mp-ty-sec"><em>日计</em>太乙在 ${esc(dayN)} 宫(第 ${esc(dayU)} 日) 天目 ${esc(dayMu)} 计神 ${esc(dayJs)}</div>
36334
+ <div class="mp-ty-sec"><em>时计</em>太乙在 ${esc(hourN)} 宫(第 ${esc(hourU)} 时) 计神 ${esc(hourJs)}</div>
36335
+ <div class="mp-ty-sec"><em>吉凶</em><b class="mp-ty-jx ${esc(vdGrade)}">${esc(vdLabel)}</b> ${esc((r.jixiong && r.jixiong.text) || '')}</div>
36336
+ <div class="mp-ty-sec"><em>神将</em>${esc(sjLine)}</div>
36337
+ <div class="mp-ty-sec"><em>计神</em>${esc(js.branch || '')}(${esc(js.god || '')}) <em>始击</em>${esc(sj.pos || '')}(${esc(sj.god || '')},${esc(sj.palaceName || '')}宫)</div>
36338
+ <div class="mp-ty-sec"><em>主算</em>${esc(String(su.zhu || ''))} 主大将${esc(jj.zhuDaName || '')}宫 主参将${esc(jj.zhuCanName || '')}宫</div>
36339
+ <div class="mp-ty-sec"><em>客算</em>${esc(String(su.ke || ''))} 客大将${esc(jj.keDaName || '')}宫 客参将${esc(jj.keCanName || '')}宫</div>
36340
+ <div class="mp-ty-sec"><em>格局</em>${gj.list && gj.list.length ? esc(gj.list.join(';')) : '四将不相犯,没有掩、迫、囚、格、关'}</div>
36341
+ <div class="mp-ty-sec"><em>积年</em>${esc(String(r.meta.jinian || ''))} 残年 ${esc(String(r.meta.rest360 || ''))} ${esc(r.year ? r.year.jiName : '')}${esc(r.year ? String(r.year.jiYear) : '')}年 ${esc(r.year ? r.year.yuanName : '')}第 ${esc(r.year ? String(r.year.yuanYear) : '')} 年</div>
36342
+ <div class="mp-ty-note">算到太乙、八门、文昌、计神、始击、主客算与四将、五种格局;${esc(nc.join('、'))}未收录,盘上不显示。将落中五时只标数不加宫名。</div>
36343
+ </details>
35638
36344
  </section>`;
35639
36345
  };
35640
36346