dsh-metaphysics 0.62.4 → 0.62.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 CHANGED
@@ -1,4 +1,28 @@
1
- ## 0.62.4(2026-11-07,待发布)
1
+ ## 0.62.5(2026-11-09,待发布)
2
+
3
+ > 本段主题(2026-11-08,B14):把书目覆盖表里最后 3 项「只有书名、没有原文」升级成有原文——易传(十翼)、奇门遁甲元灵经、奇门遁甲秘笈大全。覆盖表 **74 / 3 / 69 → 77 / 0 / 69**,「只有书名」这一类清零。不改排盘口径、不新建知识卡(`KNOWLEDGE` 仍 59 张)。
4
+
5
+ - **三本新书 33 条入库:16 条接五张已有奇门卡、17 条只进索引页**(`engine/citations.js`、`engine/citations-fuwen.js`、`test/fixtures/citation-sources.json`):`CITATION_BOOKS` 66 → **69 本**(新登记 `yichuan` / `yuanling` / `miji`);引擎侧 `CITATIONS` 166 → **182**、附文库 `FUWEN_CITATIONS` 257 → **274**、`LIBRARY_CITATIONS` 423 → **456**,加八字三书 41 条后索引条目 **464 → 497**,再加穷通宝鉴 120 格摘句,可核验原文 **584 → 617 条**。8 页新底本走仓库自己的 `tools/citation-fetch.mjs` 抓取、由 `merge-citation-sources.mjs` **只补缺**写入 fixture(341 → **349 页**,已有 341 页一字节未动),所以探测文本与 fixture 文本逐字一致。接线口径照旧:能对上引擎已有判定层的才接卡,对不上的只入索引页,不硬挂、不新造断语。
6
+ - **易传 10 条全部只入库,一条不接卡**(`engine/citations-fuwen.js`):后天八卦方位表虽与 `engine/fengshui.js` 的 `PALACE_DIRECTION` 八方相符,但地相一栏本站没有知识卡;性情/类象/先天对待/六画成卦/大衍蓍法/太极/重卦/爻效各篇本站都没有判定层。10 条白话逐条写明为什么不接卡,并有断言钉死「引擎侧零条 `/yijing/` 链接、10 条不被任何卡片/破格规则/成格索引引用」。两处容易混引的地方也钉住了:「变化者进退之象」讲阴阳消长,**不是**六爻的化进神退神,不接 `liuyao-jintui-yong`;「爻效天下之动」讲全体爻,不接 `liuyao-dongbian`。底本只存系辞上下、说卦、序卦、杂卦五篇,**彖、象、文言三传未收**,故「十翼」不全;本批 10 条出自 3 页(说卦 5、系辞上 3、系辞下 2),序卦、杂卦有页未选句。
7
+ - **接卡的 16 条逐格与引擎表对拍,不是「看着像」**(`engine/qimen.js` 新增只读视图 `QIMEN_JU_TABLE` / `QIMEN_BASE_TABLES`、`test/citations.test.mjs` B14 专段):照已有 `QIMEN_CONDITION_TABLES` / `QIMEN_STATE_TABLES` 的「供测试与文档引用」写法导出 24 节气三元局数表与九星八门定宫表,测试**从引文原文里解析出表格**再与引擎逐格比——元灵经卷一局数 **24/24**(底本「惊蜇」归一到惊蛰)、六仪配旬首对 `xunShouLiuYi()` **6/6**、秘笈卷十五六仪刑击格对 `jiXing` **6/6**、门迫歌对 `gatePalaceRelation()` **8 门 13 宫全是「门迫」**、迫制和义格四类 **4/4** 一一对应、三奇入墓歌对 `ruMu` **3/3**、秘笈总序八方对 `PALACE_DIRECTION` **8/8**、说卦传先天对待四对对 `TRI_NAME` 互补相加 **4/4 皆九**;符头三元与阴阳遁分界另与 `buildQimen` 的规则串同口径。九星定宫、八门定宫两条只入库不接卡,但白话里写了「与引擎逐宫相符」,所以也钉成断言(对 `BASIC_STARS` **9/9**、对 `BASIC_GATES` **8/8**),不留只有结构完整性、没有逐宫比对的半截核验。
8
+ - **对不上的照实记异,其中一处改掉了卡片里的过度声称**(`engine/interpret-knowledge.js`、`engine/citations.js`):秘笈卷十五「时墓格」戊六、壬四、丙六与引擎相符,**辛(书艮八/引擎巽四辰)、乙(书坤二/引擎乾六戌)两句相异**;`qimen-rumu` 卡原先的 source 泛称「六仪入墓见《奇门遁甲秘笈大全》卷十五」,等于把全书当成引擎表的出处,现改成写明「只戊、壬、丙三句相符,辛、乙两句相异」。同卷「奇墓格」又作「乙到临坤」(与引擎乙墓戌不同),因此**只入索引页不接卡**;引擎表不动,它另有《统宗·玄机赋》阴干逆行取墓的出处。测试里专门写了一条**反向证伪**断言:辛乙两句必须与引擎不同——哪天引擎表被改成与书一致,这条会先红,逼人来复核而不是悄悄「对齐古籍」。十干克应的三处同格异文(青龙返首/总序作反首、乙加辛青龙逃走的三种断语、甲加甲伏吟/青龙出土)一律并列不合并。
9
+ - **十干克应卡由「通行说」升「已定位」,但 note 写明只证三组不证全表**(`engine/citations.js` 的 `CARD_CITATIONS['qimen-ganying']`、`engine/interpret-knowledge.js`):升级依据是元灵经卷二甲加甲「吉凶不定,惟看门如何。门吉则吉,门凶则凶」,正是该卡「先取成象、再与门星神合看,不单独回答事情成不成」那一层的原文。但卷二「天盘加地盘吉凶」**只存天盘甲、乙、丙三组,各 9 条、三组都缺「加戊」,页面到「丙加地盘癸」为止,丁以下七组未收**,所以 refs 只证这三组与这一层口径,note 与卡片都写明**不证通行 100 组表全文**,其余七十馀组仍取通行表汇编、无单条原文。「通行说」卡片 8 → **7 张**(待补仍 1 张),计数锁同步改。
10
+ - **底本缺陷照录不代改**(`docs/知识扩展与待核实清单.md` 附十三):说卦传第三章被底本误题作「《老子。说卦传》」;震/巽/坎类象有 □①-⑥ 缺字,只引干净的乾、坤两段;大衍章下一句「归奇於□①以象闰」有缺字,引到「揲之以四以象四时」为止(断言钉死 quote 结尾与不含「归奇」);三奇入墓歌「丁奇乙未临艮土」中「乙未」未详,照录并写明疑有讹脱;秘笈页内「干」即乾、「直符」即值符、「尅」即克,引文照原字、解析时归一;秘笈分类页**跳过卷三**(003 是卷二、004 是卷四),实收 29 卷;说卦传只明写六方,**坤西南、兑正西两方本页没有明写**,由秘笈总序补证,两条白话互相点名,不拿说卦传冒充八方俱全。
11
+
12
+ - **验证**:按附五记的收尾顺序重建——改引擎与文案 → `build-client` → 改文档与 CHANGELOG → 再 `build-client` + `build-html` → 生成 `docs/citations.html` → `test-all` → `check-assertions --update` → **再 `build-html`** → 全量 `test:ci` 九步全绿(**155/155** 测试文件,用时 40.4s;check-bundle `client.js` 289 KB / gzip 89 KB、18 块 gzip 合计 **2.51 MB**、单块上限 **288 KB**、逐模块编译 70 个、宿主形态可执行且与源码逐字节一致;check-verification 2 个产物与源码渲染逐字节一致;凭据扫描 **337** 文件干净;check-patterns 80 文件;HTML 注入面 5 文件;check-perf 29 项,1000 混合盘 **336 ms / RSS 94 MB**;`verify-tests-can-fail` 15 PASS / 1 FAIL → exit 1)。断言基线 **8376 → 8415**(只增不减,B14 净增 39 全在 citations 一档),`test/citations.test.mjs` **210 → 249 PASS / 0 FAIL**。分块 gzip:**bazi 233.6 / hepan 232.3 / ziwei 228.8 / liuyao 195.2 / qimen 187.6 KB**,最大块离 288 KB 上限还有约 54 KB——进分块的只有 16 条定位字段、5 张卡的 refs 与 source/note、两个只读视图(`QIMEN_JU_TABLE` / `QIMEN_BASE_TABLES`)与本段条目标题,17 条原文白话与 8 页底本全在不打包的 fuwen/fixture 侧。`docs/citations.html` 重建到 **451 KB**、统计 464 → 497 条,与 `buildCitationsHTML()` 逐字节一致。桌面 exe 副本仍刻意停在 0.62.2,不重建。
13
+
14
+ > 续(2026-11-09):结掉「交运只有数学自证、没有第三方对拍」这笔欠账,把炳祥课堂的力量量化层接成只读标注,再把已吸收的命理知识收束成一份可执行的口径总纲。全程不改 L0/L1 结论——旺衰分、喜忌、取格、交运字段一律原样,新增字段都是并列只读。
15
+
16
+ - **交运第三方对拍入仓:23 例,四柱 22/22、顺逆 23/23、时间基准 20/20、首运 3/3**(`test/fixtures/baziqa-jiaoyun.json`、`test/fixtures/vendor-jiaoyun-pages.json`、`tools/capture-baziqa-jiaoyun.mjs`、`tools/capture-vendor-jiaoyun.mjs`、`tools/data-jiaoyun.mjs`、`tools/gen-jiaoyun-data.mjs`、`tools/backtest-jiaoyun.mjs`、`test/bazi-jiaoyun-backtest.test.mjs`):BaziQA 固定 commit `3bad3de` 的 117 盘里取 20 例(`qiyun.start_date` 由 lunar-python 1.4.8 算),另取元梓知易 / Multifate / 靈台 三张公开页面作 L0 历法层 3 例;抓取脚本与抓到的正文、sha256 都留在仓库,`gen-jiaoyun-data.mjs --check` 与 `data-jiaoyun.mjs` 逐字节一致。绝对偏差日均 **3.48 天**、最大 10 天、无一例超档,偏差已逐项归因到「BaziQA 的 `after_days` 只有 0/10/20 三档(117/117,一时辰折十日的量化)+ 日历月加算」,不是取节或顺逆算错。
17
+ - **起运岁新增只读并列口径 `dayun.startAgeExact`**(`engine/bazi.js`、`engine/diff.js`):`startAge` 仍按四舍五入到月(口语「几岁几个月」),新字段截断到年/月/日/时,两者同源、互不覆盖。用同一份 `spanDays` 复算:截断到月 **23/23** 全中厂家值,四舍五入只有 **15/23**;8 例差全部是「月内余数 ≥0.5 被进位」,逐例可复算。元梓页把四段都印了(9 年 10 个月 21 天 12 小时),本机四段全中。
18
+ - **炳祥课堂的力量量化层接入为只读标注,不动既有旺衰、喜忌与取格**(新增 `engine/structure.js`,改 `engine/bazi.js` / `engine/geju.js` / `engine/interpret.js`):`strength.branchStructure` 给八大地支结构 code(AAAA…ABBA)、从格静态概率与平衡度;`strength.weightPct` 按柱给年 13% / 月 41% / 日 27% / 时 19%;`frame.bingyao` 病药(正格 >35%、从格 >15%,从格按类型反转喜忌)、`frame.xianshen` 闲神(食伤与官杀较弱者,4% 最佳、≥10% 显忌,显性 ×3 只进文案排序)、`frame.patternScore` 成格评分(只评正八格月令格,建禄/羊刃/月劫等外格不评)、`relations.anhe` 暗合另列、不混入合冲刑害;解析层新增「病药」「闲神」两节与「量化口径」说明。三柱(时辰未知)一律打 `placeholderHour`、不套从格概率、时柱权重不计入合计(81%)且不归一化。七个新测试文件共 238 条断言。
19
+ - **撤掉三处过度声称,命中率从虚高改回可核**(`tools/backtest-jiaoyun.mjs`、`docs/命理口径总纲.md` §6):① 旧样本把上游已扣过夏令时的 `chart.datetime` 再喂 `dst:true`,等于扣两次(民用时间错 1 小时、交运错 5 天),现改喂原文钟表时间 `time.clock` 并加 `frameOk` 闸门(20/20),另用「双重扣必给出不同结果」反向证伪该闸门不是恒真;② Multifate 页面没印四柱与「几天」,旧样本把本机值当厂家值填进去、凭空多出一例「命中」,现一律记 `published:false` 并剔除出分母,四柱命中由 23/23 修正为 **22/22**;③ 枇杷八字那份输出自相矛盾,旧稿替它编了「取节错误」根因,现改判 `UNUSABLE_CASES` 不入分母。偏差均值随之由 3.70 天修正为 **3.48 天**。
20
+ - **《命理口径总纲》入仓:23 条裁决,冲突处直接选定主口径并写清理由与置信边界**(新增 `docs/命理口径总纲.md`、`docs/炳祥八字-课程知识内化.md`,改 `docs/参考资料与对拍来源.md` §7、`docs/知识扩展与待核实清单.md` §三.2、`docs/对话记录与决策日志.md`):明确不做兼透次序/三会改格、体用能量比、紫微破格/奇门入墓/六爻用神多现,应期只到年运不推流日;旺衰保留现有相对分,炳祥百分比只作宫位百分比与结构概率的只读视图;51%、旺衰 90% / 调候 10%、大运:流年 3:2~2:1 等课堂口径只进解读注记,不改判定。
21
+ - **验证**:`build-client` → 改文档与 CHANGELOG → 再 `build-client` + `build-html` → 全量 `test:ci` 九步全绿(**163/163** 测试文件;check-bundle 逐块均在上限内、宿主形态与源码逐字节一致;check-verification 两产物与源码渲染一致;凭据扫描干净;check-patterns / check-html-sinks / check-perf 均过)。断言基线 **8376 → 8729**(只增不减:citations 段 +39,八字新测试 +314),已按 `check-assertions --update` 重算。另顺手钉死 `bool-flags.test.mjs` 里紫微 `flow` 读本机当前时刻带来的偶发噪声(加 `asOf`),不改引擎行为。桌面 exe 副本仍停在 0.62.2,未重建。
22
+
23
+ ## 0.62.4(2026-11-07,已发布)
24
+
25
+ > 已发布:npm `dsh-metaphysics@0.62.4`,shasum `e081b9a3fa7d16aacd912dcc27ca793216b4a5ef`,103 个文件;tag `v0.62.4` → `a16994e`,[GitHub release](https://github.com/xuanfu-web/dsh-metaphysics/releases/tag/v0.62.4) 已建,`main` 已推送。
2
26
 
3
27
  > 本段主题:把手机「书库」13 个分类、146 项书名与仓库引文库逐类对名,补上《紫微斗数全书》卷一的赋文,并把「原文照录 + 本站白话」从浏览器分块里彻底拆出去——引文库从此不再受 232 KB 分块线约束。
4
28
 
package/client.almanac.js CHANGED
@@ -1,4 +1,4 @@
1
- window.__ModuleLoader__.load({id:"dsh-metaphysics",chunk:"client.almanac.js",factory(pt){const R={};return R.fail=(function(){return{fail:(U,H)=>{const B=new Error(H);return B.code=U,B}}})(),R.bool=(function(){function L(r,h=!1){return r==null||r===""?h:r===!0||r===1||r==="true"||r==="1"?!0:r===!1||r===0||r==="false"||r==="0"?!1:h}const U={lateZi:!0,trueSolar:!0,dst:!0,isLeapMonth:!1,leapAsNext:!1,cross:!1,hourUnknown:!1,diff:!1,shadow:!1,trace:!1,rectify:!1,withInterpret:!1},H={lateZi:!0,trueSolar:!0,dst:!0,hourUnknown:!1};function B(r,h){let l=r;const E=($,b)=>{Object.is(r[$],b)||(l===r&&(l={...r}),l[$]=b)},w=$=>{l===r&&(l={...r}),delete l[$]};for(const[$,b]of Object.entries(h))if(r[$]!==void 0){if(typeof r[$]=="string"&&r[$].trim()===""){w($);continue}E($,L(r[$],b))}return l}function Z(r){if(!r||typeof r!="object"||Array.isArray(r))return r;let h=r;for(const[l,E]of Object.entries(H)){if(r[l]===void 0)continue;if(typeof r[l]=="string"&&r[l].trim()===""){h===r&&(h={...r}),delete h[l];continue}const w=L(r[l],E);Object.is(r[l],w)||(h===r&&(h={...r}),h[l]=w)}return h}function k(r){if(!r||typeof r!="object")return r;let h=B(r,U);for(const l of["partner","partner2"]){const E=h[l],w=Z(E);w!==E&&(h===r&&(h={...r}),h[l]=w)}return h}const N=["hour","minute","longitude","verifyPast","seed","days","lunarYear","lunarMonth","lunarDay","num1","num2","num3","upper","lower","changing","count","toAge","fortuneYear","period","limit","sittingOffset","sittingDegree","facingOffset","facingDegree","year","month","day"],q=["lines","rectifyHours","answers"],j=["strokeOverrides","surnameStrokes"],m=/^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;function f(r){if(typeof r!="string")return r;const h=r.trim();if(!m.test(h))return r;const l=Number(h);return Number.isFinite(l)?l:r}function v(r){let h=!1;const l={};for(const[E,w]of Object.entries(r)){const $=w===null?null:f(w);Object.is($,w)||(h=!0),l[E]=$}return h?l:r}function p(r){if(!r||typeof r!="object")return r;let h=r;const l=(E,w)=>{Object.is(r[E],w)||(h===r&&(h={...r}),h[E]=w)};for(const E of N)if(r[E]!==void 0){if(typeof r[E]=="string"&&r[E].trim()===""){h===r&&(h={...r}),delete h[E];continue}l(E,f(r[E]))}for(const E of q){const w=r[E];if(!Array.isArray(w))continue;let $=!1;const b=w.map(a=>{if(a===null)return null;if(typeof a=="string"&&a.trim()===""){$=!0;return}const d=f(a);return Object.is(d,a)||($=!0),d});$&&l(E,b)}for(const E of j){const w=r[E];!w||typeof w!="object"||Array.isArray(w)||l(E,v(w))}return h}return{bool:L,FLAG_DEFAULTS:U,canonicalFlags:k,NUMERIC_KEYS:N,NUMERIC_ARRAY_KEYS:q,NUMERIC_MAP_KEYS:j,canonicalNumbers:p}})(),R.diff=(function(){const{bool:L}=R.bool||{},U=new Set(["summary","interpret","castAt","asOf","precision","disclaimer","note","trueSolarText","civilText","offsetMinutes","input","jd","juMethod","juMethodNote","lateZiHourMode","leapPolicy","schools","bodyMasterSchool","bodyMasterNote","handle","handleError","revision","brief","briefError"]),H=a=>a!==null&&typeof a=="object";function B(a,d,c="",g=[]){if(a===d)return g;if(!H(a)||!H(d))return g.push({path:c||"(root)",from:a,to:d}),g;const x=new Set([...Object.keys(a),...Object.keys(d)]);for(const T of x){if(U.has(T))continue;const A=c?`${c}.${T}`:T,D=a[T],I=d[T];H(D)&&H(I)?B(D,I,A,g):JSON.stringify(D)!==JSON.stringify(I)&&g.push({path:A,from:D,to:I})}return g}const Z=[[/^pillars\.year\.ganzhi$/,"年柱"],[/^pillars\.month\.ganzhi$/,"月柱"],[/^pillars\.day\.ganzhi$/,"日柱"],[/^pillars\.hour\.ganzhi$/,"时柱"],[/^pillars\.\w+\.hidden/,"藏干"],[/^pillars\.\w+\.stemTenGod$/,"十神"],[/^pillars\.\w+\.kongwang/,"空亡"],[/^pillars\.\w+\.dishi$|^pillars\.\w+\.zizuo$/,"十二长生"],[/^pillars\.\w+\.nayin$/,"纳音"],[/^dayMaster\./,"日主"],[/^palaces\.(taiyuan|minggong|shengong)\./,"命身宫"],[/^palaces\.\d+\.(palace|branch|stem|ganzhi)$/,"宫位"],[/^palaces\.\d+\.stars\.\d+\.(name|brightness|type)$/,"星曜"],[/^palaces\.\d+\.shensha\./,"神煞"],[/^palaces\.\d+\.(daxian|xiaoxian)\./,"大限"],[/^palaces\.\d+\.sanfang\./,"三方四正"],[/^palaces\.\d+\./,"宫位"],[/^palaces\./,"命身宫"],[/^soul\./,"命宫"],[/^body\./,"身宫"],[/^doujun\./,"流年斗君"],[/^siZhu\.year$/,"年柱"],[/^siZhu\.month$/,"月柱"],[/^siZhu\.day$/,"日柱"],[/^siZhu\.time$/,"时柱"],[/^ju$|^juNumber$/,"局数"],[/^yuan$/,"三元"],[/^dun$/,"阴阳遁"],[/^daxian(List)?\./,"大限"],[/^fly(Chains|Composite)?\./,"飞星"],[/^pattern/,"格局"],[/^schools\./,"流派回显"],[/^dayun\.jiao\./,"起运"],[/^dayun\.toNextJieDays$/,"起运时间"],[/^dayun\.list\.(\d+)\.ganzhi$/,"大运干支"],[/^dayun\.startAge\./,"起运时间"],[/^dayun\./,"大运评分"],[/^liunian\./,"流年"],[/^jieqi\./,"节气边界"],[/^solarTime\./,"真太阳时"],[/^dayGanZhi$/,"日辰"],[/^hourZhi$/,"时支"],[/^yueJiang\./,"月将"],[/^xunKong$/,"旬空"],[/^lines\.(\d+)\./,"爻"],[/^shensha\./,"神煞"],[/^frame\./,"格局用神"],[/^strength\./,"旺衰"],[/^wuxing\./,"五行计数"],[/^relations\./,"干支关系"],[/^input\./,"输入回显"]],k=[[/^pillars\./,"四柱"],[/^shensha\./,"神煞"],[/^dayun\./,"大运"],[/^liunian\./,"流年"],[/^frame\./,"格局用神"],[/^strength\./,"旺衰"],[/^wuxing\./,"五行计数"],[/^dayMaster\./,"日主"],[/^relations\./,"干支关系"],[/^palaces\.(taiyuan|minggong|shengong)\./,"命身宫"],[/^palaces\.\d+\./,"宫位"],[/^palaces\./,"命身宫"],[/^soul\.|^body\.|^doujun\./,"命身宫"],[/^siZhu\./,"四柱"],[/^ju$|^juNumber$|^yuan$|^dun$/,"局数"],[/^daxian/,"大限"],[/^fly/,"飞星"],[/^pattern/,"格局"],[/^jieqi\./,"节气"],[/^solarTime\./,"真太阳时"],[/^input\./,"输入回显"],[/^lines\./,"爻"]],N=[[/^pillars\.(year|month|day|hour)\.ganzhi$/,"柱"],[/^palaces\.(minggong|shengong)\.ganzhi$/,"命身宫"],[/^soul\.ganzhi$/,"命宫"],[/^body\.branch$/,"身宫"],[/^siZhu\.(year|month|day|time)$/,"柱"],[/^dayun\.jiao\.at$/,"起运"],[/^dayGanZhi$/,"日辰"],[/^hourZhi$/,"时支"],[/^ju$|^juNumber$|^juName$/,"局数"],[/^dun$/,"阴阳遁"],[/^lines\.\d+\.(ganzhi|yinYang|name)$/,"爻"],[/^yueJiang\.(name|zhi)$/,"月将"]];function q(a){for(const[d,c]of Z)if(d.test(a))return c;return j(a)||a}function j(a){for(const[d,c]of k)if(d.test(a))return c;return""}function m(a){for(const[d,c]of N)if(d.test(a))return c;return""}function f(a){return[...a].sort((d,c)=>d.path.localeCompare(c.path,"zh-Hans-CN",{numeric:!0}))}function v(a){if(!a.length)return"本盘不受此口径影响:所有字段一致。";const d=a.filter(T=>m(T.path)),c=[...new Set(a.map(T=>j(T.path)).filter(Boolean))],g=d.length?`根因 ${d.length} 处:`+d.slice(0,4).map(T=>`${q(T.path)} ${p(T.from)}→${p(T.to)}`).join("、")+(d.length>4?" 等":""):"无单一根因",x=c.length?`;连带影响 ${c.slice(0,6).join("、")}${c.length>6?" 等":""} ${c.length} 类,共 ${a.length} 处`:`;共 ${a.length} 处`;return g+x+"。"}const p=a=>a===void 0?"—":a===null?"null":typeof a=="string"?a:Array.isArray(a)?a.join("")||"[]":typeof a=="object"?JSON.stringify(a):String(a);function r(a,{title:d="",limit:c=12}={}){const g=[];if(d&&g.push(`【${d}】`),g.push(v(a)),!a.length)return g.join(`
1
+ window.__ModuleLoader__.load({id:"dsh-metaphysics",chunk:"client.almanac.js",factory(pt){const R={};return R.fail=(function(){return{fail:(U,H)=>{const B=new Error(H);return B.code=U,B}}})(),R.bool=(function(){function L(r,h=!1){return r==null||r===""?h:r===!0||r===1||r==="true"||r==="1"?!0:r===!1||r===0||r==="false"||r==="0"?!1:h}const U={lateZi:!0,trueSolar:!0,dst:!0,isLeapMonth:!1,leapAsNext:!1,cross:!1,hourUnknown:!1,diff:!1,shadow:!1,trace:!1,rectify:!1,withInterpret:!1},H={lateZi:!0,trueSolar:!0,dst:!0,hourUnknown:!1};function B(r,h){let l=r;const E=($,b)=>{Object.is(r[$],b)||(l===r&&(l={...r}),l[$]=b)},w=$=>{l===r&&(l={...r}),delete l[$]};for(const[$,b]of Object.entries(h))if(r[$]!==void 0){if(typeof r[$]=="string"&&r[$].trim()===""){w($);continue}E($,L(r[$],b))}return l}function Z(r){if(!r||typeof r!="object"||Array.isArray(r))return r;let h=r;for(const[l,E]of Object.entries(H)){if(r[l]===void 0)continue;if(typeof r[l]=="string"&&r[l].trim()===""){h===r&&(h={...r}),delete h[l];continue}const w=L(r[l],E);Object.is(r[l],w)||(h===r&&(h={...r}),h[l]=w)}return h}function k(r){if(!r||typeof r!="object")return r;let h=B(r,U);for(const l of["partner","partner2"]){const E=h[l],w=Z(E);w!==E&&(h===r&&(h={...r}),h[l]=w)}return h}const N=["hour","minute","longitude","verifyPast","seed","days","lunarYear","lunarMonth","lunarDay","num1","num2","num3","upper","lower","changing","count","toAge","fortuneYear","period","limit","sittingOffset","sittingDegree","facingOffset","facingDegree","year","month","day"],q=["lines","rectifyHours","answers"],j=["strokeOverrides","surnameStrokes"],m=/^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/;function f(r){if(typeof r!="string")return r;const h=r.trim();if(!m.test(h))return r;const l=Number(h);return Number.isFinite(l)?l:r}function v(r){let h=!1;const l={};for(const[E,w]of Object.entries(r)){const $=w===null?null:f(w);Object.is($,w)||(h=!0),l[E]=$}return h?l:r}function p(r){if(!r||typeof r!="object")return r;let h=r;const l=(E,w)=>{Object.is(r[E],w)||(h===r&&(h={...r}),h[E]=w)};for(const E of N)if(r[E]!==void 0){if(typeof r[E]=="string"&&r[E].trim()===""){h===r&&(h={...r}),delete h[E];continue}l(E,f(r[E]))}for(const E of q){const w=r[E];if(!Array.isArray(w))continue;let $=!1;const b=w.map(a=>{if(a===null)return null;if(typeof a=="string"&&a.trim()===""){$=!0;return}const d=f(a);return Object.is(d,a)||($=!0),d});$&&l(E,b)}for(const E of j){const w=r[E];!w||typeof w!="object"||Array.isArray(w)||l(E,v(w))}return h}return{bool:L,FLAG_DEFAULTS:U,canonicalFlags:k,NUMERIC_KEYS:N,NUMERIC_ARRAY_KEYS:q,NUMERIC_MAP_KEYS:j,canonicalNumbers:p}})(),R.diff=(function(){const{bool:L}=R.bool||{},U=new Set(["summary","interpret","castAt","asOf","precision","disclaimer","note","trueSolarText","civilText","offsetMinutes","input","jd","juMethod","juMethodNote","lateZiHourMode","leapPolicy","schools","bodyMasterSchool","bodyMasterNote","handle","handleError","revision","brief","briefError"]),H=a=>a!==null&&typeof a=="object";function B(a,d,c="",g=[]){if(a===d)return g;if(!H(a)||!H(d))return g.push({path:c||"(root)",from:a,to:d}),g;const x=new Set([...Object.keys(a),...Object.keys(d)]);for(const T of x){if(U.has(T))continue;const A=c?`${c}.${T}`:T,D=a[T],I=d[T];H(D)&&H(I)?B(D,I,A,g):JSON.stringify(D)!==JSON.stringify(I)&&g.push({path:A,from:D,to:I})}return g}const Z=[[/^pillars\.year\.ganzhi$/,"年柱"],[/^pillars\.month\.ganzhi$/,"月柱"],[/^pillars\.day\.ganzhi$/,"日柱"],[/^pillars\.hour\.ganzhi$/,"时柱"],[/^pillars\.\w+\.hidden/,"藏干"],[/^pillars\.\w+\.stemTenGod$/,"十神"],[/^pillars\.\w+\.kongwang/,"空亡"],[/^pillars\.\w+\.dishi$|^pillars\.\w+\.zizuo$/,"十二长生"],[/^pillars\.\w+\.nayin$/,"纳音"],[/^dayMaster\./,"日主"],[/^palaces\.(taiyuan|minggong|shengong)\./,"命身宫"],[/^palaces\.\d+\.(palace|branch|stem|ganzhi)$/,"宫位"],[/^palaces\.\d+\.stars\.\d+\.(name|brightness|type)$/,"星曜"],[/^palaces\.\d+\.shensha\./,"神煞"],[/^palaces\.\d+\.(daxian|xiaoxian)\./,"大限"],[/^palaces\.\d+\.sanfang\./,"三方四正"],[/^palaces\.\d+\./,"宫位"],[/^palaces\./,"命身宫"],[/^soul\./,"命宫"],[/^body\./,"身宫"],[/^doujun\./,"流年斗君"],[/^siZhu\.year$/,"年柱"],[/^siZhu\.month$/,"月柱"],[/^siZhu\.day$/,"日柱"],[/^siZhu\.time$/,"时柱"],[/^ju$|^juNumber$/,"局数"],[/^yuan$/,"三元"],[/^dun$/,"阴阳遁"],[/^daxian(List)?\./,"大限"],[/^fly(Chains|Composite)?\./,"飞星"],[/^pattern/,"格局"],[/^schools\./,"流派回显"],[/^dayun\.jiao\./,"起运"],[/^dayun\.toNextJieDays$/,"起运时间"],[/^dayun\.list\.(\d+)\.ganzhi$/,"大运干支"],[/^dayun\.startAge(Exact)?\./,"起运时间"],[/^dayun\./,"大运评分"],[/^liunian\./,"流年"],[/^jieqi\./,"节气边界"],[/^solarTime\./,"真太阳时"],[/^dayGanZhi$/,"日辰"],[/^hourZhi$/,"时支"],[/^yueJiang\./,"月将"],[/^xunKong$/,"旬空"],[/^lines\.(\d+)\./,"爻"],[/^shensha\./,"神煞"],[/^frame\./,"格局用神"],[/^strength\./,"旺衰"],[/^wuxing\./,"五行计数"],[/^relations\./,"干支关系"],[/^input\./,"输入回显"]],k=[[/^pillars\./,"四柱"],[/^shensha\./,"神煞"],[/^dayun\./,"大运"],[/^liunian\./,"流年"],[/^frame\./,"格局用神"],[/^strength\./,"旺衰"],[/^wuxing\./,"五行计数"],[/^dayMaster\./,"日主"],[/^relations\./,"干支关系"],[/^palaces\.(taiyuan|minggong|shengong)\./,"命身宫"],[/^palaces\.\d+\./,"宫位"],[/^palaces\./,"命身宫"],[/^soul\.|^body\.|^doujun\./,"命身宫"],[/^siZhu\./,"四柱"],[/^ju$|^juNumber$|^yuan$|^dun$/,"局数"],[/^daxian/,"大限"],[/^fly/,"飞星"],[/^pattern/,"格局"],[/^jieqi\./,"节气"],[/^solarTime\./,"真太阳时"],[/^input\./,"输入回显"],[/^lines\./,"爻"]],N=[[/^pillars\.(year|month|day|hour)\.ganzhi$/,"柱"],[/^palaces\.(minggong|shengong)\.ganzhi$/,"命身宫"],[/^soul\.ganzhi$/,"命宫"],[/^body\.branch$/,"身宫"],[/^siZhu\.(year|month|day|time)$/,"柱"],[/^dayun\.jiao\.at$/,"起运"],[/^dayGanZhi$/,"日辰"],[/^hourZhi$/,"时支"],[/^ju$|^juNumber$|^juName$/,"局数"],[/^dun$/,"阴阳遁"],[/^lines\.\d+\.(ganzhi|yinYang|name)$/,"爻"],[/^yueJiang\.(name|zhi)$/,"月将"]];function q(a){for(const[d,c]of Z)if(d.test(a))return c;return j(a)||a}function j(a){for(const[d,c]of k)if(d.test(a))return c;return""}function m(a){for(const[d,c]of N)if(d.test(a))return c;return""}function f(a){return[...a].sort((d,c)=>d.path.localeCompare(c.path,"zh-Hans-CN",{numeric:!0}))}function v(a){if(!a.length)return"本盘不受此口径影响:所有字段一致。";const d=a.filter(T=>m(T.path)),c=[...new Set(a.map(T=>j(T.path)).filter(Boolean))],g=d.length?`根因 ${d.length} 处:`+d.slice(0,4).map(T=>`${q(T.path)} ${p(T.from)}→${p(T.to)}`).join("、")+(d.length>4?" 等":""):"无单一根因",x=c.length?`;连带影响 ${c.slice(0,6).join("、")}${c.length>6?" 等":""} ${c.length} 类,共 ${a.length} 处`:`;共 ${a.length} 处`;return g+x+"。"}const p=a=>a===void 0?"—":a===null?"null":typeof a=="string"?a:Array.isArray(a)?a.join("")||"[]":typeof a=="object"?JSON.stringify(a):String(a);function r(a,{title:d="",limit:c=12}={}){const g=[];if(d&&g.push(`【${d}】`),g.push(v(a)),!a.length)return g.join(`
2
2
  `);const x=f(a.filter(A=>m(A.path))),T=f(a.filter(A=>!m(A.path)));if(x.length){g.push(""),g.push(" 根因(口径直接改动):");for(const A of x)g.push(` ${q(A.path).padEnd(6)} ${p(A.from)} → ${p(A.to)}`)}if(T.length){g.push(""),g.push(` 连带变化(${T.length} 处,展示前 ${Math.min(c,T.length)} 处):`);for(const A of T.slice(0,c))g.push(` ${q(A.path).padEnd(6)} ${p(A.from)} → ${p(A.to)}`);if(T.length>c){const A={};for(const D of T.slice(c)){const I=j(D.path)||"其他";A[I]=(A[I]||0)+1}g.push(" 其余:"+Object.entries(A).map(([D,I])=>`${D} ${I} 处`).join("、"))}}return g.join(`
3
3
  `)}const h=(a,d,c,g,x,T)=>({key:a,title:d,short:c,read:A=>{const D=A[a]!==void 0?A[a]:A.schools&&A.schools[a];return T[D]?D:g},alt:A=>A===x?g:x,label:A=>T[A]||A}),l={bazi:[{key:"lateZi",title:"晚子时:23:00 后是否换日",short:"晚子时",read:a=>L(a.lateZi,!0),alt:a=>!a,label:a=>a?"换日":"不换日"},{key:"trueSolar",title:"真太阳时:是否按出生地经度修正",short:"真太阳时",read:a=>L(a.trueSolar,!0),alt:a=>!a,label:a=>a?"修正":"不修正"}],ziwei:[{key:"leapMonth",title:"闰月归月:按日切分 / 整月归次月",short:"闰月归月",read:a=>a.leapMonth==="next"||a.leapMonth==="prev"?a.leapMonth:"split",alt:a=>a==="split"?"next":"split",label:a=>({split:"按日切分",next:"整月归次月",prev:"整月归本月"})[a]||a},{key:"trueSolar",title:"真太阳时:是否按出生地经度修正",short:"真太阳时",read:a=>L(a.trueSolar,!0),alt:a=>!a,label:a=>a?"修正":"不修正"},h("brightnessSchool","亮度表:默认 / QS 七档","亮度表","default","QS",{default:"默认",QS:"QS(七档)",XD1:"XD1(七档)",ZZ:"ZZ(五档)",XD2:"XD2(五档)"}),h("gengYearSihua","庚干四化:阳武阴同 / 同科阴忌","庚干四化","GYWYT","GYWTY",{GYWYT:"阳武阴同",GYWTY:"同科阴忌",GYWFT:"府科同忌",GYWFX:"府科相忌",GYWTX:"同科相忌"}),h("tianmaSchool","天马:按年支 / 按生月","天马","year-branch","month-branch",{"year-branch":"年支","month-branch":"生月"}),h("tiankongSchool","天空:不排 / 年支顺行","天空","off","normal",{off:"不排",normal:"年支顺行","shun-jia-shi":"加生时"}),h("jiekongSchool","截空旬空:不排 / 正副双星","截空旬空","off","double",{off:"不排",single:"单星",double:"正副双星",zhanyan:"占验派"}),h("kuiyueSchool","魁钺:qs1 / qs2","魁钺","qs1","qs2",{qs1:"qs1",qs2:"qs2","zhong-yiming":"中一鸣"}),h("tianshiTianshang","天伤天使:常规 / 中州互换","天伤天使","normal","zhongzhou",{normal:"常规",zhongzhou:"中州(阴男阳女互换)"}),h("changshengSchool","长生:阴阳顺逆 / 火土起寅","长生","yin-yang-shun-ni","huo-tu",{"yin-yang-shun-ni":"阴阳顺逆","shui-tu":"水二","huo-tu":"火土(土五局起寅)"}),h("lateZishi","晚子时:归当日 / 归次日","晚子时","current-day","next-day",{"current-day":"归当日","next-day":"归次日","all-current":"全归当日","day-cur-time-next":"日归当日·时归次日"}),h("shenzhuSchool","身主:子午皆火星 / 子铃午火","身主","common","verse",{common:"子午皆火星",verse:"子铃午火(安身主诀逐字)"}),h("zuoyaoSchool","杂曜:49 颗简盘 / 61 颗全表","杂曜全表","minimal","full",{minimal:"49 颗(简盘)",full:"61 颗(加十二颗杂曜)"})],qimen:[{key:"juMethod",title:"取局流派:拆补 / 超神接气 / 置闰",short:"取局流派",read:a=>["chaibu","chaoshen","zhirun"].includes(a.juMethod)?a.juMethod:"chaibu",alt:a=>a==="chaibu"?"zhirun":"chaibu",label:a=>({chaibu:"拆补法",chaoshen:"超神接气",zhirun:"置闰法"})[a]||a},{key:"lateZiHourMode",title:"晚子时:23:00 后归当日 / 次日",short:"晚子时归日",read:a=>a.lateZiHourMode==="next-day"?"next-day":"same-day",alt:a=>a==="next-day"?"same-day":"next-day",label:a=>a==="next-day"?"归次日":"归当日"}]},E={bazi:[{path:"pillars.day.ganzhi",label:"日柱"},{path:"pillars.hour.ganzhi",label:"时柱"},{path:"strength.level",label:"旺衰"},{path:"frame.primaryName",label:"格局"},{path:"frame.yongshen.favor",label:"喜用"},{path:"dayun.jiao.at",label:"起运"}],ziwei:[{path:"soul.ganzhi",label:"命宫"},{path:"body.branch",label:"身宫支"},{path:"bureau.name",label:"五行局"},{path:"bodyMaster",label:"身主"},{path:"daxianList.0.ages",label:"起大限"}],qimen:[{path:"siZhu.day",label:"日柱"},{path:"ju",label:"局数"},{path:"zhiFu.star",label:"值符"},{path:"zhiShi.gate",label:"值使"}]};function w(a,d){let c=a;for(const g of String(d).split(".")){if(c==null)return;c=c[g]}return c}function $(a){return a==null?"—":Array.isArray(a)?a.join("、"):typeof a=="object"?"—":String(a)}function b(a,d,c){return(E[a]||[]).map(x=>{const T=$(w(d,x.path)),A=$(w(c,x.path));return{key:x.path,label:x.label,current:T,alt:A,changed:T!==A}})}return{diffObjects:B,labelOf:q,categoryOf:j,rootOf:m,sortDiffs:f,summarize:v,formatValue:p,renderDiff:r,CALIBER_SWITCHES:l,CALIBER_VIEWS:E,viewCell:$,viewRows:b}})(),R.fingerprint=(function(){const L="0123456789ABCDEFGHJKMNPQRSTVWXYZ";function U(k){return JSON.stringify(H(k))}function H(k){if(k===null)return null;const N=typeof k;if(N==="string")return typeof k.normalize=="function"?k.normalize("NFC"):k;if(N==="number")return Number.isFinite(k)?Object.is(k,-0)?0:k:null;if(N==="boolean")return k;if(Array.isArray(k))return k.map(H);if(N==="object"){const q=Object.create(null);for(const j of Object.keys(k).sort()){const m=k[j];m===void 0||typeof m=="function"||typeof m=="symbol"||(q[j]=H(m))}return q}return null}function B(k){const N=String(k);let q=2166136261,j=2654435769;for(let v=0;v<N.length;v+=1){const p=N.charCodeAt(v);for(const r of[p&255,p>>>8])q=Math.imul(q^r,16777619),j=Math.imul(j^r,2246822507)}let m=(q>>>0)*8+(j>>>29),f="";for(let v=0;v<7;v+=1)f=L[m%32]+f,m=Math.floor(m/32);return f}function Z(k={}){const N=String(k.system||""),q=String(k.version||"dev"),j=k.seed===void 0||k.seed===null||k.seed===""?null:Number(k.seed),m=k.asOf?String(k.asOf):null,f=k.params&&typeof k.params=="object"?k.params:{},v=U({system:N,params:f,seed:j,asOf:m}),p=U({base:v,version:q});return{id:`LY-${B(p)}`,baseId:`LY-${B(v)}`,version:q,system:N,payload:v}}return{canonicalJson:U,shortHash:B,fingerprintOf:Z}})(),R.validate=(function(){const{fail:L}=R.fail||{},U=1600,H=2400;function B(f){return f%4===0&&f%100!==0||f%400===0}function Z(f,v){return v===2?B(f)?29:28:[31,28,31,30,31,30,31,31,30,31,30,31][v-1]||0}const k=f=>typeof f=="string"?`「${f}」`:String(f),N="引擎只接受解析好的公历字段 { year, month, day, hour?, minute? };字符串请先交给宿主层的 parseDateTime 解析";function q(f,v=""){const p=v?`${v} 的`:"";if(!f||typeof f!="object"||Array.isArray(f)){const E=f===null?"null":Array.isArray(f)?"数组":typeof f;throw L("E_INPUT",`${p}入参必须是对象(收到 ${E});${N}`)}const r=f.hour===void 0?0:f.hour,h=f.minute===void 0?0:f.minute;for(const[E,w]of[["year",f.year],["month",f.month],["day",f.day],["hour",r],["minute",h]])if(!Number.isInteger(w))throw L("E_INPUT",`${p}${E} 必须是整数(收到 ${k(w)});${N}`);if(f.year<U||f.year>H)throw L("E_INPUT",`${p}year 超出支持范围 ${U}–${H}(收到 ${f.year});更早的年份时区与历法口径不可靠`);if(f.month<1||f.month>12)throw L("E_INPUT",`${p}month 超出范围 1–12(收到 ${f.month})`);const l=Z(f.year,f.month);if(f.day<1||f.day>l)throw L("E_INPUT",`${p}日期不存在:${f.year}-${f.month}-${f.day}(${f.year} 年 ${f.month} 月只有 ${l} 天)`);if(r<0||r>23)throw L("E_INPUT",`${p}hour 超出范围 0–23(收到 ${r})`);if(h<0||h>59)throw L("E_INPUT",`${p}minute 超出范围 0–59(收到 ${h})`);return f}function j(f,v,p){if(!f||typeof f!="object"||Array.isArray(f)){const r=f===null?"null":f===void 0?"undefined":Array.isArray(f)?"数组":typeof f;throw L("E_INPUT",`${v} 必须是对象(收到 ${r});${p}`)}return f}function m(f,v=""){const p=v?`${v}:`:"";if(f.year<U||f.year>H)throw L("E_RANGE",`${p}晚子时按次日归后落到 ${f.year}-${String(f.month).padStart(2,"0")}-${String(f.day).padStart(2,"0")},超出可计算范围 ${U}–${H};请把时刻挪到 23 点前,或换一天起课`);return f}return{MIN_YEAR:U,MAX_YEAR:H,isLeapYear:B,daysInMonth:Z,assertCivil:q,assertObject:j,assertShifted:m}})(),R.datetime=(function(){const{fail:L}=R.fail||{},{MIN_YEAR:U,MAX_YEAR:H}=R.validate||{};function B(N,q){return q===2?N%4===0&&N%100!==0||N%400===0?29:28:[31,28,31,30,31,30,31,31,30,31,30,31][q-1]}function Z(N,q=""){const j=String(N??"").trim(),m=/^(\d{4})-(\d{1,2})-(\d{1,2})$/.exec(j);if(!m)return null;const f=Number(m[1]),v=Number(m[2]),p=Number(m[3]);if(v<1||v>12||p<1||p>B(f,v))return null;if(f<U||f>H){const r=q?`${q} `:"";throw L("E_RANGE",`${r}「${m[0]}」的年份超出可计算范围(${U}–${H},收到 ${f} 年);农历与节气表不覆盖之外的年份`)}return{year:f,month:v,day:p}}function k(N){if(typeof N!="string"||!N.trim())throw L("E_INPUT","缺少 datetime(公历日期时间),例如 1990-05-12T14:30");const q=N.trim().match(/^(\d{4})-(\d{1,2})-(\d{1,2})(?:[T\s](\d{1,2}):(\d{1,2})(?::(\d{1,2}))?)?$/);if(!q)throw L("E_INPUT",`无法解析 datetime:「${N}」,请用 1990-05-12T14:30 这种格式`);if(q[6]!==void 0&&Number(q[6])>59)throw L("E_INPUT",`秒超出范围:${q[6]}`);const j={year:Number(q[1]),month:Number(q[2]),day:Number(q[3]),hour:Number(q[4]??0),minute:Number(q[5]??0)};if(j.month<1||j.month>12)throw L("E_INPUT",`月份超出范围:${j.month}`);const m=B(j.year,j.month);if(j.day<1||j.day>m)throw L("E_INPUT",`日期不存在:${j.year}-${j.month}-${j.day}(${j.year} 年 ${j.month} 月只有 ${m} 天)`);if(j.hour>23||j.minute>59)throw L("E_INPUT",`时间超出范围:${j.hour}:${j.minute}`);if(j.year<U||j.year>H)throw L("E_RANGE",`年份 ${j.year} 超出可计算范围(${U}–${H})`);return(j.year<1900||j.year>2100)&&(j.precision={level:"approx",note:`ΔT 模型仅覆盖 1900–2100,${j.year} 年按端点值外推,节气与朔望时刻可能有分钟级偏差,月柱在交节前后需复核`}),j}return{daysInMonth:B,parseYmd:Z,parseDateTime:k}})(),R.lru=(function(){function L({max:U=64,ttlMs:H=0,name:B="lru",now:Z=()=>Date.now()}={}){const k=new Map,N={name:B,hits:0,misses:0,evictions:0,expirations:0},q=j=>H>0&&Z()-j.at>H;return{name:B,max:U,ttlMs:H,get(j){const m=k.get(j);if(!m||q(m)){m&&(k.delete(j),N.expirations+=1),N.misses+=1;return}return k.delete(j),k.set(j,m),N.hits+=1,m.value},set(j,m){for(k.has(j)&&k.delete(j),k.set(j,{value:m,at:Z()});k.size>U;)k.delete(k.keys().next().value),N.evictions+=1;return m},has(j){const m=k.get(j);return m?q(m)?(k.delete(j),N.expirations+=1,!1):!0:!1},delete(j){return k.delete(j)},clear(){k.clear()},get size(){return k.size},stats(){const j=N.hits+N.misses;return{name:B,size:k.size,max:U,hits:N.hits,misses:N.misses,evictions:N.evictions,expirations:N.expirations,hitRate:j?N.hits/j:0}}}}return{createLru:L}})(),R.nayin=(function(){const L=["海中金","炉中火","大林木","路旁土","剑锋金","山头火","涧下水","城头土","白蜡金","杨柳木","泉中水","屋上土","霹雳火","松柏木","长流水","沙中金","山下火","平地木","壁上土","金箔金","覆灯火","天河水","大驿土","钗钏金","桑柘木","大溪水","沙中土","天上火","石榴木","大海水"];function U(H){const B=(Number(H)%60+60)%60,Z=L[Math.floor(B/2)];return{name:Z,element:Z[2]}}return{NAYIN_NAMES:L,nayinOf:U}})(),R.sanhe=(function(){const L=[{branches:["申","子","辰"],element:"水"},{branches:["亥","卯","未"],element:"木"},{branches:["寅","午","戌"],element:"火"},{branches:["巳","酉","丑"],element:"金"}],U=Object.fromEntries(L.map(Z=>[Z.branches.join(""),Z.element])),H=Object.fromEntries(L.flatMap(Z=>Z.branches.map(k=>[k,Z.element])));function B(Z){return L.find(k=>k.branches.includes(Z))||null}return{SANHE_GROUPS:L,SANHE:U,SANHE_ELEMENT:H,sanheGroupOf:B}})(),R["vsop-earth"]=(function(){const L=[[1.75347045673,0,0],[.03341656453,4.66925680415,6283.0758499914],[.00034894275,4.62610242189,12566.1516999828],[3417572e-11,2.82886579754,3.523118349],[3497056e-11,2.74411783405,5753.3848848968],[3135899e-11,3.62767041756,77713.7714681205],[2676218e-11,4.41808345438,7860.4193924392],[2342691e-11,6.13516214446,3930.2096962196],[1273165e-11,2.03709657878,529.6909650946],[1324294e-11,.74246341673,11506.7697697936],[901854e-11,2.04505446477,26.2983197998],[1199167e-11,1.10962946234,1577.3435424478],[857223e-11,3.50849152283,398.1490034082],[779786e-11,1.17882681962,5223.6939198022],[99025e-10,5.23268072088,5884.9268465832],[753141e-11,2.53339052847,5507.5532386674],[505267e-11,4.58292599973,18849.2275499742],[492392e-11,4.20505711826,775.522611324],[356672e-11,2.91954114478,.0673103028],[284125e-11,1.89869240932,796.2980068164],[242879e-11,.34481445893,5486.777843175],[317087e-11,5.84901948512,11790.6290886588],[271112e-11,.31486255375,10977.078804699],[206217e-11,4.80646631478,2544.3144198834],[205478e-11,1.86953770281,5573.1428014331],[202318e-11,2.45767790232,6069.7767545534],[126225e-11,1.08295459501,20.7753954924],[155516e-11,.83306084617,213.299095438],[115132e-11,.64544911683,.9803210682],[102851e-11,.63599845579,4694.0029547076],[101724e-11,4.2667980198,7.1135470008],[99206e-11,6.20992926918,2146.1654164752],[132212e-11,3.41118292683,2942.4634232916],[97607e-11,.68101342359,155.4203994342],[85128e-11,1.29870764804,6275.9623029906],[74651e-11,1.755089133,5088.6288397668],[101895e-11,.97569280312,15720.8387848784],[84711e-11,3.67080093031,71430.69561812909],[73547e-11,4.67926633877,801.8209311238],[73874e-11,3.50319414955,3154.6870848956],[78757e-11,3.03697458703,12036.4607348882],[79637e-11,1.80791287082,17260.1546546904],[85803e-11,5.9832263126,161000.6857376741],[56963e-11,2.78430458592,6286.5989683404],[61148e-11,1.81839892984,7084.8967811152],[69627e-11,.83297621398,9437.762934887],[56116e-11,4.38694865354,14143.4952424306],[62449e-11,3.97763912806,8827.3902698748],[51145e-11,.28306832879,5856.4776591154],[55577e-11,3.47006059924,6279.5527316424],[41036e-11,5.36817592855,8429.2412664666],[51605e-11,1.33282739866,1748.016413067],[51992e-11,.18914947184,12139.5535091068],[49e-8,.48735014197,1194.4470102246],[392e-9,6.16833020996,10447.3878396044],[3557e-10,1.775968892,6812.766815086],[3677e-10,6.04133863162,10213.285546211],[36596e-11,2.56957481827,1059.3819301892],[33296e-11,.59310278598,17789.845619785],[35954e-11,1.70875808777,2352.8661537718],[40938e-11,2.39850938714,19651.048481098],[30047e-11,2.73975124088,1349.8674096588],[30412e-11,.44294464169,83996.84731811189],[23663e-11,.48473622521,8031.0922630584],[23574e-11,2.06528133162,3340.6124266998],[21089e-11,4.14825468851,951.7184062506],[24738e-11,.21484762138,3.5904286518],[25352e-11,3.16470891653,4690.4798363586],[22823e-11,5.22195230819,4705.7323075436],[21419e-11,1.42563910473,16730.4636895958],[21891e-11,5.55594302779,553.5694028424],[203e-9,.37133792946,283.8593188652]],U=[[6283.0758499914,0,0],[.00206058863,2.67823455808,6283.0758499914],[4303419e-11,2.63512233481,12566.1516999828],[425264e-11,1.59046982018,3.523118349],[109017e-11,2.96631010675,1577.3435424478],[93479e-11,2.59211109542,18849.2275499742],[119305e-11,5.79555765566,26.2983197998],[72121e-11,1.13840581212,529.6909650946],[67784e-11,1.87453300345,398.1490034082],[6735e-10,4.40932832004,5507.5532386674],[59045e-11,2.88815790631,5223.6939198022],[55976e-11,2.17471740035,155.4203994342],[45411e-11,.39799502896,796.2980068164],[36298e-11,.46875437227,775.522611324],[28962e-11,2.64732254645,7.1135470008],[20844e-11,5.34138275149,.9803210682]],H=[[8721859e-11,1.07253635559,6283.0758499914],[99099e-10,3.14159265359,0],[294833e-11,.43717350256,12566.1516999828],[27338e-11,.05295636147,3.523118349],[16333e-11,5.18820215724,26.2983197998],[15745e-11,3.68504712183,155.4203994342],[9425e-11,.29667114694,18849.2275499742],[8938e-11,2.05706319592,77713.7714681205],[694e-10,.82691541038,775.522611324],[5061e-11,4.6624323168,1577.3435424478]],B=[[289058e-11,5.84173149732,6283.0758499914],[20712e-11,6.0498393902,12566.1516999828],[2962e-11,5.1956057957,155.4203994342],[2527e-11,3.14159265359,0],[1288e-11,4.7219761197,3.523118349]],Z=[[7714e-11,4.14117321449,6283.0758499914],[1016e-11,3.27573644241,12566.1516999828]];function k(N){let q=0;for(const[m,f,v]of L)q+=m*Math.cos(f+v*N);let j=1;for(const m of[U,H,B,Z]){j*=N;for(const[f,v,p]of m)q+=f*j*Math.cos(v+p*N)}return q}return{earthL:k}})(),R.calendar=(function(){const{earthL:L}=R["vsop-earth"]||{},{createLru:U}=R.lru||{},{bool:H}=R.bool||{},B=["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"],Z=["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"],k=["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"];function N(_){return(285+15*_)%360}function q(_,C,G){const ie=Math.floor((14-C)/12),Q=_+4800-ie,Y=C+12*ie-3;return G+Math.floor((153*Y+2)/5)+365*Q+Math.floor(Q/4)-Math.floor(Q/100)+Math.floor(Q/400)-32045}function j(_){const C=_+32044,G=Math.floor((4*C+3)/146097),ie=C-Math.floor(146097*G/4),Q=Math.floor((4*ie+3)/1461),Y=ie-Math.floor(1461*Q/4),X=Math.floor((5*Y+2)/153);return{year:100*G+Q-4800+Math.floor(X/10),month:X+3-12*Math.floor(X/10),day:Y-Math.floor((153*X+2)/5)+1}}function m(_,C){for(let G=0;G<60;G++)if(G%10===_&&G%12===C)return G;return-1}function f(_){const C=(_%60+60)%60;return{index:C,stem:B[C%10],branch:Z[C%12],name:B[C%10]+Z[C%12]}}function v(_){return((_+49)%60+60)%60}function p(_){const C=_-2451545,G=C/36525,ie=C/365250;let Q=L(ie)*180/Math.PI+180;Q=(Q%360+360)%360;const Y=(5029.0966*G+1.11113*G*G-6e-6*G*G*G)/3600;Q+=Y,Q-=.09033/3600;const X=(125.04452-1934.136261*G)*Math.PI/180,le=(280.4665+36000.7698*G)*Math.PI/180,oe=(218.3165+481267.8813*G)*Math.PI/180,je=(-17.2*Math.sin(X)-1.32*Math.sin(2*le)-.23*Math.sin(2*oe)+.21*Math.sin(2*X))/3600;Q+=je;const ne=(357.52911+35999.05029*G-1537e-7*G*G)*Math.PI/180,pe=.016708634-42037e-9*G-1267e-10*G*G,Pe=1.000001018*(1-pe*pe)/(1+pe*Math.cos(ne+(1.914602-.004817*G)*(Math.PI/180)*Math.sin(ne)));return Q-=20.4898/3600/(Pe||1),(Q%360+360)%360}function r(_){if(_<1900){const X=_;if(X<1600)return 120;if(X<1700){const oe=X-1600;return 120-.9808*oe-.01532*oe*oe+oe*oe*oe/7129}if(X<1800){const oe=X-1700;return 8.83+.1603*oe-.0059285*oe*oe+13336e-8*oe*oe*oe-oe**4/1174e3}if(X<1860){const oe=X-1800;return 13.72-.332447*oe+.0068612*oe*oe+.0041116*oe**3-37436e-8*oe**4+121272e-10*oe**5-1699e-10*oe**6+875e-12*oe**7}const le=X-1860;return 7.62+.5737*le-.251754*le*le+.01680668*le**3-.0004473624*le**4+le**5/233174}const C=[[1900,-2.8],[1920,21.2],[1940,24.3],[1950,29.1],[1960,33.2],[1970,40.2],[1980,50.5],[1990,56.9],[2e3,63.8],[2010,66.1],[2020,69.4],[2030,72],[2050,80],[2100,110]];if(_<=C[0][0])return C[0][1];for(let X=1;X<C.length;X++)if(_<=C[X][0]){const[le,oe]=C[X-1],[je,ne]=C[X];return oe+(ne-oe)*(_-le)/(je-le)}const[G,ie]=C[C.length-1],Q=(G-1820)/100,Y=(_-1820)/100;return ie+32*(Y*Y-Q*Q)}const h=8/24,l=7.7611/24,E=2425612+4/24;function w(_){return _<E?l:h}const $=U({max:4096,name:"termInstant"}),b=1e-5,a=new Map,d=365.2422;function c(_,C){const G=N(C),ie=q(_,1,5)-.5+C*15.2184,Q=a.get(C);let Y=Q!==void 0?Q+d:ie;Math.abs(Y-ie)>20&&(Y=ie);for(let le=0;le<12;le++){let oe=G-p(Y);if(oe=((oe+180)%360+360)%360-180,Y+=oe/.98564736,Math.abs(oe)<b)break}a.set(C,Y);const X=Y-r(_)/86400;return X+w(X)}function g(_,C){const G=_*24+C,ie=$.get(G);if(ie!==void 0)return ie;const Q=c(_,C);return $.set(G,Q),Q}function x(_){const C=Math.floor(_+.5),G=_+.5-C,ie=Math.min(1439,Math.floor(Math.round(G*86400)/60)),{year:Q,month:Y,day:X}=j(C);return{year:Q,month:Y,day:X,hour:Math.floor(ie/60),minute:ie%60}}function T({year:_,month:C,day:G,hour:ie=0,minute:Q=0}){return q(_,C,G)-.5+(ie*60+Q)/1440}function A(_,C,G){const ie=q(_,C,G)-q(_,1,1)+1,Q=2*Math.PI*(ie-81)/364;return 9.87*Math.sin(2*Q)-7.53*Math.cos(Q)-1.5*Math.sin(Q)}const D=U({max:8,name:"termWindow"}),I=U({max:32,name:"termYear"}),ge=Array.from({length:24},(_,C)=>C),ze=ge.filter(_=>_%2===0);function o(_,C){const G=C?`${_}|jie`:`${_}|all`,ie=I.get(G);if(ie)return ie;if(C){const Y=I.get(`${_}|all`);if(Y){const X=Y.filter(le=>le.index%2===0);return I.set(G,X),X}}const Q=[];for(const Y of C?ze:ge)Q.push({year:_,index:Y,name:k[Y],jd:g(_,Y)});return Q.sort((Y,X)=>Y.jd-X.jd),I.set(G,Q),Q}function M(_,C={}){const G=H(C.jieOnly),ie=G?`${_}|jie`:_,Q=D.get(ie);if(Q)return Q;const Y=[...o(_-1,G),...o(_,G),...o(_+1,G)];return Y.sort((X,le)=>X.jd-le.jd),D.set(ie,Y),Y}function J(_){if(typeof _!="string"||_.length<2)return[];const C=B.indexOf(_[0]),G=Z.indexOf(_[1]);if(C<0||G<0)return[];const ie=m(C,G);if(ie<0)return[];const Q=Math.floor(ie/10)*10;return[Z[(Q+10)%12],Z[(Q+11)%12]]}function te(_,C){let G=null;for(const ie of _)if(ie.index%2===0)if(ie.jd<=C)G=ie;else break;return G}function W(_,C){for(const G of _)if(G.index%2===0&&G.jd>C)return G;return null}function ee(_){const C=x(_),G=ie=>String(ie).padStart(2,"0");return`${C.year}-${G(C.month)}-${G(C.day)} ${G(C.hour)}:${G(C.minute)}`}function re(){return[$.stats(),I.stats(),D.stats()]}return{STEMS:B,BRANCHES:Z,TERM_NAMES:k,termLongitude:N,toJDN:q,fromJDN:j,sexagenaryIndex:m,ganzhiName:f,dayGanzhiIndex:v,sunLongitude:p,deltaTSeconds:r,OFFSET_MODERN:h,OFFSET_BEIJING_LOCAL:l,CUTOVER_JD:E,localOffsetFor:w,termInstantJd:g,jdToParts:x,partsToJd:T,equationOfTime:A,termWindow:M,xunKongOf:J,previousJie:te,nextJie:W,formatJd:ee,cacheMetrics:re}})(),R.lunar=(function(){const{toJDN:L,jdToParts:U,termInstantJd:H,deltaTSeconds:B,localOffsetFor:Z}=R.calendar||{},k=29.530588861,N=245155009766e-5,q=Math.PI/180;function j(r){const h=r/1236.85,l=N+k*r+15437e-8*h*h-15e-8*h*h*h+73e-11*h*h*h*h,E=1-.002516*h-74e-7*h*h,w=(2.5534+29.1053567*r-14e-7*h*h-11e-8*h*h*h)*q,$=(201.5643+385.81693528*r+.0107582*h*h+1238e-8*h*h*h-58e-9*h*h*h*h)*q,b=(160.7108+390.67050284*r-.0016118*h*h-227e-8*h*h*h+11e-9*h*h*h*h)*q,a=(124.7746-1.56375588*r+.0020672*h*h+215e-8*h*h*h)*q,d=-.4072*Math.sin($)+.17241*E*Math.sin(w)+.01608*Math.sin(2*$)+.01039*Math.sin(2*b)+.00739*E*Math.sin($-w)-.00514*E*Math.sin($+w)+.00208*E*E*Math.sin(2*w)-.00111*Math.sin($-2*b)-57e-5*Math.sin($+2*b)+56e-5*E*Math.sin(2*$+w)-42e-5*Math.sin(3*$)+42e-5*E*Math.sin(w+2*b)+38e-5*E*Math.sin(w-2*b)-24e-5*E*Math.sin(2*$-w)-17e-5*Math.sin(a)-7e-5*Math.sin($+2*w)+4e-5*Math.sin(2*$-2*b)+4e-5*Math.sin(3*w)+3e-5*Math.sin($+w-2*b)+3e-5*Math.sin(2*$+2*b)-3e-5*Math.sin($+w+2*b)+3e-5*Math.sin($-w+2*b)-2e-5*Math.sin($-w-2*b)-2e-5*Math.sin(3*$+w)+2e-5*Math.sin(4*$),c=l+d-B(2e3+h*100)/86400;return c+Z(c)}function m(r){return Math.floor(r+.5)}function f(r){return Math.round((r+.5-N)/k)}function v(r,h,l){for(let E=r-1;E<=r+1;E++)for(let w=1;w<24;w+=2){const $=H(E,w),b=m($);if(b>=h&&b<l)return{index:w,jd:$}}return null}function p(r,h,l){const E=L(r,h,l),w=m(H(r,23)),$=E<w?r-1:r,b=m(H($,23));let a=f(b);for(;m(j(a))>b;)a--;for(;m(j(a+1))<=b;)a++;const d=m(H($+1,23));let c=a;for(;m(j(c+1))<=d;)c++;const g=c-a;let x=-1;if(g===13)for(let D=1;D<=g;D++){const I=m(j(a+D-1)),ge=m(j(a+D));if(!v($,I,ge)){x=D;break}}let T=11,A=!1;for(let D=1;D<=15;D++){const I=m(j(a+D-1)),ge=m(j(a+D)),ze=v($,I,ge),o=D===x;if(E>=I&&E<ge){const M=U(j(a+D-1)),J=o?(T+10)%12+1:T;return{year:$,lunarYear:A?$+1:$,month:J,day:E-I+1,isLeap:o,monthStart:`${M.year}-${String(M.month).padStart(2,"0")}-${String(M.day).padStart(2,"0")}`,hasZhongQi:!!ze}}o||(T=T%12+1,T===1&&(A=!0))}throw new Error(`农历换算失败:${r}-${h}-${l}`)}return{SYNODIC:k,newMoonJd:j,dayNumberOf:m,solarToLunar:p}})(),R.geo=(function(){const{bool:L}=R.bool||{},U=`
4
4
  北京 116.41 39.90;上海 121.47 31.23;天津 117.20 39.13;重庆 106.55 29.56