全站通知:

Widget:命盘模拟器

来自代号鸢WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

<style> /* ===== 洗命盘模拟器 v0.1-draft · 精致星空玄学风(视觉demo 改订:lockic·对话卡·道具icon;三宫恒生效,无开宫状态) ===== */

  1. dlymp-app{
 --dlymp-ink:#f2e7d0; --dlymp-ink-dim:#b3a68c; --dlymp-acc:#c9a86a; --dlymp-acc2:#e8d3a0;
 --dlymp-bd:rgba(201,168,106,.38); --dlymp-bd-soft:rgba(201,168,106,.22);
 --dlymp-bg:rgba(13,22,44,.6); --dlymp-bg-solid:#101a33;
 --dlymp-qb:#86bcff; --dlymp-qp:#d0a4ff; --dlymp-qo:#d9a97c;
 --dlymp-gold-btn:linear-gradient(180deg,#eed9a8 0%,#d9b878 55%,#c39f5c 100%);
 --dlymp-btn-gold:url("https://patchwiki.biligame.com/images/yuan/a/af/2shst5sd0ngsfhcom8w92k6l4glfcwf.png");
 --dlymp-btn-dark:url("https://patchwiki.biligame.com/images/yuan/2/29/64q6ahv9xg3j74zbcj6i9qf3hyjz6z5.png");
 --dlymp-gold-line:#c9a86a; --dlymp-gold-text:#3a2a10;
 --dlymp-card-shadow:0 10px 34px rgba(0,0,0,.42);
 --dlymp-radius:6px; --dlymp-radius-s:2px;
 --font-ui:-apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei","微软雅黑",sans-serif;
 --font-st:"USMCCyuanjiantecu", "Plangothic", system-ui, sans-serif,"STSong","STZhongsong","SimSun",serif;
 position:relative; max-width:1120px; margin:0 auto; padding:6px 10px 30px;
 font-family:var(--font-ui); color:var(--dlymp-ink); font-size:14px; line-height:1.55;
 background:
   radial-gradient(1.5px 1.5px at 12% 18%,rgba(255,244,214,.85) 50%,transparent 51%),
   radial-gradient(1px 1px at 78% 8%,rgba(255,244,214,.7) 50%,transparent 51%),
   radial-gradient(1.5px 1.5px at 88% 42%,rgba(214,228,255,.6) 50%,transparent 51%),
   radial-gradient(1px 1px at 32% 64%,rgba(255,244,214,.55) 50%,transparent 51%),
   radial-gradient(1px 1px at 58% 88%,rgba(214,228,255,.5) 50%,transparent 51%),
   radial-gradient(1.5px 1.5px at 6% 82%,rgba(255,244,214,.6) 50%,transparent 51%),
   radial-gradient(640px 300px at 50% -8%,rgba(201,168,106,.14),transparent 70%),
   radial-gradient(520px 260px at 50% 108%,rgba(84,110,180,.16),transparent 70%),
   linear-gradient(180deg,#0c1730 0%,#0a1327 55%,#0b1122 100%);
 border:1px solid var(--dlymp-bd); border-radius:10px;
 box-shadow:0 18px 60px rgba(0,0,0,.5), inset 0 1px 0 rgba(232,211,160,.12);
 box-sizing:border-box; -webkit-tap-highlight-color:transparent;

}

  1. dlymp-app *{box-sizing:border-box}
  2. dlymp-app button{font-family:var(--font-ui);cursor:pointer}
  3. dlymp-app .pxcard{background:var(--dlymp-bg);border:1px solid var(--dlymp-bd-soft);
 border-radius:var(--dlymp-radius);box-shadow:var(--dlymp-card-shadow),inset 0 1px 0 rgba(232,211,160,.08)}

/* ---- 页脚口径行 ---- */

  1. dlymp-foot{text-align:center;font-size:12px;color:var(--dlymp-ink-dim);margin:16px 0 0;letter-spacing:.06em;opacity:.75}

/* ---- 折叠区 ---- */

  1. dlymp-app .fold{margin:8px 4px}
  2. dlymp-app .fold-head{display:flex;align-items:center;gap:8px;padding:10px 14px;cursor:pointer;user-select:none;
 font-family:var(--font-st);font-weight:500;font-size:16px;letter-spacing:.14em;color:var(--dlymp-acc2)}
  1. dlymp-app .fold-head .arr{margin-left:auto;font-size:12px;color:var(--dlymp-acc2);transition:transform .18s}
  2. dlymp-app .fold.open .fold-head .arr{transform:rotate(180deg)}
  3. dlymp-app .fold-body{display:none;padding:4px 14px 14px}
  4. dlymp-app .fold.open .fold-body{display:block}
  5. dlymp-app .fold-head .cnt{margin-left:auto;font-size:12px;color:var(--dlymp-ink-dim);letter-spacing:.03em;font-family:var(--font-ui);font-weight:400}
  6. dlymp-app .fold.open .fold-head .cnt{display:none}

/* ---- 密探选择 ---- */

  1. dlymp-search{width:100%;padding:9px 14px;font-size:14px;color:var(--dlymp-ink);background:rgba(9,16,34,.6);
 border:1px solid var(--dlymp-bd-soft);border-radius:999px;outline:none;margin:2px 0 8px;transition:border-color .15s}
  1. dlymp-search:focus{border-color:var(--dlymp-acc)}
  2. dlymp-search::placeholder{color:#8d8064}
  3. dlymp-rchips{display:flex;flex-direction:column;gap:5px;margin-bottom:4px}
  4. dlymp-rchips .frow{display:flex;gap:6px;flex-wrap:wrap;align-items:center}
  5. dlymp-rchips .flab{flex:none;font-size:12px;color:var(--dlymp-ink-dim);letter-spacing:.06em}
  6. dlymp-app .pfilter{flex:none;padding:8px 14px 2px}
  7. dlymp-app .rscroll{flex:0 1 auto;min-height:0;overflow-y:auto;display:grid;grid-template-columns:repeat(4,1fr);gap:8px 6px;
 padding:6px 14px 10px;align-content:start;scrollbar-width:thin;scrollbar-color:var(--dlymp-bd) transparent}
  1. dlymp-app .rscroll::-webkit-scrollbar{width:5px}
  2. dlymp-app .rscroll::-webkit-scrollbar-thumb{background:var(--dlymp-bd);border-radius:3px}
  3. dlymp-app .xscroll{grid-template-columns:repeat(3,1fr);gap:6px}
  4. dlymp-app .fchip{font-size:12px;color:var(--dlymp-ink-dim);background:rgba(9,16,34,.5);border:1px solid var(--dlymp-bd-soft);
 border-radius:999px;padding:3px 11px;cursor:pointer;user-select:none;letter-spacing:.04em;transition:all .15s}
  1. dlymp-app .fchip.on{background:var(--dlymp-gold-btn);border-color:var(--dlymp-gold-line);color:var(--dlymp-gold-text);font-weight:700}
  2. dlymp-app .ritem{display:flex;flex-direction:column;align-items:center;gap:3px;cursor:pointer;user-select:none;
 background:rgba(9,16,34,.45);border:1px solid var(--dlymp-bd-soft);border-radius:6px;padding:8px 2px 6px;position:relative;transition:all .15s}
  1. dlymp-app .ritem:hover{border-color:var(--dlymp-acc);transform:translateY(-1px)}
  2. dlymp-app .ritem.cur{border-color:var(--dlymp-acc2);background:rgba(201,168,106,.14);box-shadow:0 0 0 1px rgba(232,211,160,.5),0 4px 14px rgba(0,0,0,.3)}
  3. dlymp-app .ritem .avwrap{position:relative;width:55px;height:55px}
  4. dlymp-app .ritem .avwrap .ava{width:55px;height:55px;border-radius:50%;object-fit:cover;
 background:#16203c;pointer-events:none;border:1.5px solid rgba(232,211,160,.4)}
  1. dlymp-app .ritem .nm{font-size:12px;font-weight:600;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:0 3px}
  2. dlymp-app .ritem .nm small{font-size:10px;letter-spacing:0}
  3. dlymp-rempty{grid-column:1/-1;text-align:center;color:var(--dlymp-ink-dim);font-size:13px;padding:22px 0;letter-spacing:.08em}

/* ---- 头部区块:密探在左、心仪命盘在右,同一行 ---- */

  1. dlymp-topbar{display:flex;flex-direction:column;align-items:stretch;gap:8px;margin:4px 4px 0;padding:8px 14px}
  2. dlymp-rolebar{flex:none;display:flex;align-items:center;gap:9px;min-width:0}
  3. dlymp-rolebar .rb-av{position:relative;flex:none;width:60px;height:60px}
  4. dlymp-rolebar .rb-ava{width:60px;height:60px;border-radius:6px;object-fit:cover;border:1.5px solid rgba(232,211,160,.55);background:#16203c;
 box-shadow:0 4px 14px rgba(0,0,0,.35)}
  1. dlymp-rolebar .rb-info{flex:1;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:4px}
  2. dlymp-rolebar .rb-nm{font-family:var(--font-st);font-weight:500;font-size:18px;letter-spacing:.06em;max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:var(--dlymp-acc2)}
  3. dlymp-rolebar .rb-change{font-size:12px;color:var(--dlymp-acc2);background:none;border:1px solid var(--dlymp-bd);border-radius:999px;padding:3px 14px;transition:all .15s}
  4. dlymp-rolebar .rb-change:hover{background:rgba(201,168,106,.12)}
  5. dlymp-rolebar .rb-change:active{transform:scale(.96)}
  6. dlymp-rolebar .rb-none{color:var(--dlymp-ink-dim);font-size:13px;letter-spacing:.06em}
  7. dlymp-expbar{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px;border-top:1px dashed var(--dlymp-bd);padding-top:8px}
  8. dlymp-expbar .xb-head{display:flex;align-items:center;gap:6px}
  9. dlymp-expbar .xb-lab{flex:none;font-family:var(--font-st);font-weight:500;font-size:14px;letter-spacing:.1em;color:var(--dlymp-acc2);white-space:nowrap}
  10. dlymp-expset{margin-left:auto;flex:none;font-size:12px;color:var(--dlymp-gold-text);font-weight:700;letter-spacing:.1em;
 background:var(--dlymp-btn-gold) center/100% 100% no-repeat;border:none;border-radius:999px;padding:5px 16px;box-shadow:0 3px 10px rgba(0,0,0,.3)}
  1. dlymp-expset:active{transform:scale(.96)}
  2. dlymp-expchips{display:flex;flex-direction:column;gap:3px;min-width:0}
  3. dlymp-expchips .xb-none{font-size:12px;color:var(--dlymp-ink-dim);letter-spacing:.06em}
  4. dlymp-expchips .xgrp{display:flex;align-items:center;gap:3px;flex-wrap:wrap;min-width:0}
  5. dlymp-expchips .xgrp i{font-style:normal;flex:none;font-size:12px;color:var(--dlymp-ink-dim);letter-spacing:.04em}
  6. dlymp-expchips .xmini{font-size:12px;border:1px solid currentColor;border-radius:999px;padding:1px 8px;line-height:1.5;
 max-width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  1. dlymp-expchips .xmini.qb{color:var(--dlymp-qb)} #dlymp-expchips .xmini.qp{color:var(--dlymp-qp)} #dlymp-expchips .xmini.qo{color:var(--dlymp-qo)}

/* ---- 选择器芯片详情徽章 / 心仪分段开关 ---- */

  1. dlymp-app .xchip .inf,#dlymp-app .pop .pitem .inf{position:absolute;top:1px;left:3px;z-index:2;
 width:16px;height:16px;border-radius:50%;font-size:12px;line-height:14px;text-align:center;
 color:var(--dlymp-ink-dim);border:1px solid var(--dlymp-bd-soft);background:rgba(9,16,34,.6)}
  1. dlymp-app .xchip .inf:active,#dlymp-app .pop .pitem .inf:active{transform:scale(.9)}
  2. dlymp-expseg{display:flex;gap:6px;justify-content:center;margin-top:8px}
  3. dlymp-expseg button{font-size:12px;letter-spacing:.1em;padding:3px 16px;border-radius:999px;cursor:pointer;
 color:var(--dlymp-ink-dim);background:rgba(9,16,34,.5);border:1px solid var(--dlymp-bd-soft);transition:all .15s}
  1. dlymp-expseg button.on{color:var(--dlymp-gold-text);font-weight:700;background:var(--dlymp-gold-btn);border-color:transparent}
  2. dlymp-expseg button:active{transform:scale(.95)}

/* ---- 命格详情弹窗 ---- */ /* 选择器内嵌命格详情(网格下方,分隔线隔开,不再弹窗套弹窗) */

  1. dlymp-app .xinfo{margin:10px 14px 0;padding-top:10px;border-top:1px solid var(--dlymp-bd-soft)}
  2. dlymp-app .xinfo .in-head{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-bottom:6px}
  3. dlymp-app .xinfo .in-pal{font-family:var(--font-st);font-weight:bold;font-size:14px;color:var(--dlymp-acc2);letter-spacing:.1em}
  4. dlymp-app .xinfo .in-ttl{font-size:14px;font-weight:700}
  5. dlymp-app .xinfo .in-ttl.qb{color:var(--dlymp-qb)} #dlymp-app .xinfo .in-ttl.qp{color:var(--dlymp-qp)} #dlymp-app .xinfo .in-ttl.qo{color:var(--dlymp-qo)}
  6. dlymp-app .xinfo .in-q{font-size:12px;border:1px solid currentColor;border-radius:999px;padding:0 7px;line-height:1.5}
  7. dlymp-app .xinfo .in-q.qb{color:var(--dlymp-qb)} #dlymp-app .xinfo .in-q.qp{color:var(--dlymp-qp)} #dlymp-app .xinfo .in-q.qo{color:var(--dlymp-qo)}
  8. dlymp-app .xinfo .in-desc{font-size:13px;line-height:1.7;color:var(--dlymp-ink)}

/* ---- A/B tab(手机端) ---- */

  1. dlymp-tabs{display:flex;gap:8px;margin:6px 4px 0;padding:4px;background:rgba(9,16,34,.5);
 border:1px solid var(--dlymp-bd-soft);border-radius:999px}
  1. dlymp-tabs button{flex:1;padding:6px 0;font-size:15px;letter-spacing:.2em;font-family:var(--font-st);font-weight:500;
 color:var(--dlymp-ink-dim);background:transparent;border:none;border-radius:999px;transition:all .18s}
  1. dlymp-tabs button.on{color:var(--dlymp-gold-text);font-weight:500;background:var(--dlymp-btn-gold) center/100% 100% no-repeat;box-shadow:0 3px 10px rgba(0,0,0,.3)}
  2. dlymp-tabs button:active{transform:scale(.97)}

/* ---- 盘面区 ---- */

  1. dlymp-boards{margin:4px 4px}
  2. dlymp-app .bpane{display:none}
  3. dlymp-app .bpane.on{display:block}
  4. dlymp-app .bcard{padding:8px 10px 10px}
  5. dlymp-app .bhead{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:4px}
  6. dlymp-app .btag{font-family:var(--font-st);font-weight:500;font-size:16px;letter-spacing:.16em;color:var(--dlymp-acc2)}
  1. dlymp-app .bgrid{position:relative;display:grid;grid-template-columns:repeat(4,1fr);gap:5px;
 max-width:420px;margin:0 auto;padding:8px;background:rgba(6,12,26,.55);
 border:1px solid var(--dlymp-bd-soft);border-radius:var(--dlymp-radius);
 box-shadow:inset 0 2px 18px rgba(0,0,0,.35)}
  1. dlymp-app .bgrid svg.links{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:1}
  2. dlymp-app .bgrid svg.links line{stroke:var(--dlymp-acc2);stroke-width:.7;opacity:.4}
  3. dlymp-app .cell{position:relative;z-index:2;aspect-ratio:4/3;overflow:hidden;display:flex;flex-direction:column;align-items:center;justify-content:center;
 gap:2px;padding:4px 2px;cursor:pointer;user-select:none;text-align:center;
 background:linear-gradient(180deg,rgba(24,36,68,.55),rgba(14,22,46,.55));
 border:1px solid var(--dlymp-bd-soft);border-radius:var(--dlymp-radius-s);transition:border-color .15s,box-shadow .15s}
  1. dlymp-app .cell:hover{border-color:var(--dlymp-acc)}
  2. dlymp-app .cell.hole{background:transparent;border-color:transparent;cursor:default;pointer-events:none;box-shadow:none}
  3. dlymp-app .cell .eng{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
 font-family:var(--font-st);font-weight:500;font-size:24px;color:var(--dlymp-ink);opacity:.1;pointer-events:none;letter-spacing:.1em}
  1. dlymp-app .cell .ttl{position:relative;font-size:10px;line-height:1.3;font-weight:600;max-width:100%;
 display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;word-break:break-all}
  1. dlymp-app .cell.qb .ttl{color:var(--dlymp-qb)}
  2. dlymp-app .cell.qp .ttl{color:var(--dlymp-qp)}
  3. dlymp-app .cell.qo .ttl{color:var(--dlymp-qo)}
  4. dlymp-app .cell.pal-on{background:linear-gradient(180deg,rgba(60,48,20,.5),rgba(30,26,14,.45));
 border-color:rgba(232,211,160,.6);box-shadow:0 0 12px rgba(232,211,160,.14),inset 0 0 10px rgba(232,211,160,.08)}
  1. dlymp-app .cell.sel{border-color:var(--dlymp-acc2);box-shadow:0 0 0 1.5px rgba(232,211,160,.65)}
  2. dlymp-app .cell:active{transform:scale(.97)}
  3. dlymp-app .bgrid.small{gap:3px;padding:4px}
  4. dlymp-app .bgrid.small .cell{aspect-ratio:2/1.5;cursor:default}
  5. dlymp-app .bgrid.small .cell .eng{font-size:17px}
  6. dlymp-app .bempty{max-width:420px;margin:0 auto;padding:34px 10px;text-align:center;color:var(--dlymp-ink-dim);
 font-size:13px;letter-spacing:.1em;border:1px dashed var(--dlymp-bd);border-radius:var(--dlymp-radius)}

/* ---- 锁 PNG(文件:UI-命盘模拟器-锁.png,64x37 横版金锁,2026-09-22 替换占位 SVG):off=半透明金锁可锁,on=变绿+绿光已锁(hue-rotate 55°,暗部正好落到 #6fa052 附近) ---- */

  1. dlymp-app .cell .lockic{position:absolute;top:2px;right:0px;z-index:2;width:24px;line-height:0;cursor:pointer}
  2. dlymp-app .cell .lockic img{width:18px;height:auto;display:block;opacity:.5;
 filter:drop-shadow(0 1px 1px rgba(0,0,0,.45));transition:opacity .15s,filter .15s}
  1. dlymp-app .cell .lockic.on img{opacity:1;
 filter:hue-rotate(50deg) drop-shadow(0 1px 1px rgba(0,0,0,.4)) drop-shadow(0 0 4px rgba(111,160,82,.9))}

/* ---- 对比态 ---- */

  1. dlymp-app .cmp-cap{text-align:center;font-family:var(--font-st);font-weight:500;font-size:14px;letter-spacing:.3em;color:var(--dlymp-acc2);margin:1px 0 2px}
  2. dlymp-app .vsep{display:flex;justify-content:center;align-items:center;padding:0}
  3. dlymp-app .vsep i{width:13px;height:13px;border-right:2px solid var(--dlymp-acc2);border-bottom:2px solid var(--dlymp-acc2);
 transform:rotate(45deg) translate(-2px,-2px);border-radius:2px;opacity:.8}

/* ---- 详情区 ---- */

  1. dlymp-app .bdetail{max-width:420px;margin:8px auto 0;height:118px;overflow-y:auto;padding:9px 13px;
 background:rgba(8,14,30,.6);border:1px solid var(--dlymp-bd-soft);border-radius:var(--dlymp-radius-s);
 scrollbar-width:thin;scrollbar-color:var(--dlymp-bd) transparent}
  1. dlymp-app .bdetail::-webkit-scrollbar{width:5px}
  2. dlymp-app .bdetail::-webkit-scrollbar-thumb{background:var(--dlymp-bd);border-radius:3px}
  3. dlymp-app .bdetail .d-ph{color:var(--dlymp-ink-dim);font-size:12px;text-align:center;padding-top:34px;letter-spacing:.12em}
  4. dlymp-app .bdetail .d-line1{display:flex;align-items:center;gap:7px;flex-wrap:wrap}
  5. dlymp-app .bdetail .d-pal{font-family:var(--font-st);font-weight:bold;font-size:14px;color:var(--dlymp-acc2);letter-spacing:.1em}
  6. dlymp-app .bdetail .d-ttl{font-size:14px;font-weight:700}
  7. dlymp-app .bdetail .d-ttl.qb{color:var(--dlymp-qb)} #dlymp-app .bdetail .d-ttl.qp{color:var(--dlymp-qp)} #dlymp-app .bdetail .d-ttl.qo{color:var(--dlymp-qo)}
  8. dlymp-app .bdetail .d-q{font-size:12px;border:1px solid currentColor;border-radius:999px;padding:0 7px;line-height:1.5}
  9. dlymp-app .bdetail .d-q.qb{color:var(--dlymp-qb)} #dlymp-app .bdetail .d-q.qp{color:var(--dlymp-qp)} #dlymp-app .bdetail .d-q.qo{color:var(--dlymp-qo)}
  10. dlymp-app .bdetail .d-desc{margin-top:5px;font-size:13px;line-height:1.65;color:var(--dlymp-ink)}
  11. dlymp-app .bdetail .kw{color:var(--dlymp-acc2);border-bottom:1px dotted var(--dlymp-acc2)}

/* ---- 按钮区 ---- */

  1. dlymp-app .bbtns{max-width:420px;margin:6px auto 0;text-align:center}
  2. dlymp-app .costline{display:flex;align-items:center;justify-content:center;gap:6px;font-size:13px;color:var(--dlymp-ink-dim);margin-bottom:4px;flex-wrap:wrap}

/* 消耗道具:单胶囊合并两 icon,18px 无文字(2026-09-22 乔泽拍板,收回 ≥35px;仿游戏内"消耗:icon icon"一行) */

  1. dlymp-app .costitem{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--dlymp-bd-soft);border-radius:999px;padding:3px 10px;background:rgba(9,16,34,.5)}
  2. dlymp-app .costitem img{width:18px;height:18px;object-fit:contain}
  3. dlymp-app .fbtn{font-size:14px;letter-spacing:.14em;border-radius:999px;padding:7px 18px;border:none;
 color:var(--dlymp-acc2);background:var(--dlymp-btn-dark) center/100% 100% no-repeat;transition:filter .15s}
  1. dlymp-app .fbtn:hover{filter:brightness(.93)}
  2. dlymp-app .fbtn.main{color:var(--dlymp-gold-text);font-weight:700;background:var(--dlymp-btn-gold) center/100% 100% no-repeat;
 box-shadow:0 4px 14px rgba(0,0,0,.35)}
  1. dlymp-app .fbtn.ghost{color:var(--dlymp-ink-dim)}
  2. dlymp-app .fbtn:active{transform:scale(.97)}
  3. dlymp-app .fbtn:disabled{opacity:.45;cursor:default;transform:none}
  4. dlymp-app .fbtn.big{display:inline-block;min-width:200px;padding:9px 34px;font-size:16px;letter-spacing:.24em;font-family:var(--font-st)}
  5. dlymp-app .cbtns{max-width:420px;margin:6px auto 0;display:flex;gap:8px}
  6. dlymp-app .cbtns .fbtn{flex:1;padding:6px 0;font-size:13px;letter-spacing:.06em;white-space:nowrap}

/* ---- 期望/录入通用 ---- */

  1. dlymp-app .set-note{font-size:12px;color:var(--dlymp-ink-dim);margin:2px 0 6px;line-height:1.6}
  2. dlymp-app .xchip{position:relative;font-size:12px;line-height:1.3;padding:7px 14px 7px 20px;text-align:center;cursor:pointer;user-select:none;
 background:rgba(9,16,34,.5);border:1px solid var(--dlymp-bd-soft);border-radius:4px;word-break:break-all;
 display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:38px;transition:all .15s}
  1. dlymp-app .xchip.qb{color:var(--dlymp-qb)} #dlymp-app .xchip.qp{color:var(--dlymp-qp)} #dlymp-app .xchip.qo{color:var(--dlymp-qo)}
  2. dlymp-app .xchip.on{border-color:var(--dlymp-acc2);background:rgba(201,168,106,.16);box-shadow:0 0 0 1px rgba(232,211,160,.45)}
  3. dlymp-app .xchip .ord{position:absolute;top:1px;right:3px;font-size:12px;color:var(--dlymp-acc2);font-weight:700}
  4. dlymp-app .xchip:active{transform:scale(.96)}
  5. dlymp-app .entrybtn{margin-left:auto;flex:none;font-size:12px;color:var(--dlymp-acc2);background:none;
 border:1px solid var(--dlymp-bd);border-radius:999px;padding:3px 13px;letter-spacing:.08em;transition:all .15s}
  1. dlymp-app .entrybtn:hover{background:rgba(201,168,106,.12)}
  2. dlymp-app .entrybtn:active{transform:scale(.96)}

/* ---- 结算面板 ---- */

  1. dlymp-stats{margin:10px 4px;padding:4px 14px 12px}
  2. dlymp-stats .st-h{font-family:var(--font-st);font-weight:bold;font-size:16px;letter-spacing:.16em;padding:9px 2px 2px;color:var(--dlymp-acc2)}
  3. dlymp-app .bp-row{display:flex;align-items:center;gap:9px;padding:8px 2px;border-bottom:1px dashed var(--dlymp-bd-soft);font-size:13px}
  4. dlymp-app .bp-row .bp-lab{flex:none;width:96px;display:flex;align-items:center;gap:5px;color:var(--dlymp-ink-dim);letter-spacing:.06em}
  5. dlymp-app .bp-row .bp-lab img{width:35px;height:35px;object-fit:contain}
  6. dlymp-app .bp-row .bp-val{flex:1;min-width:0}
  7. dlymp-app .bp-row .bp-val b{color:var(--dlymp-acc2);font-size:15px}
  8. dlymp-app .bp-row .bp-val .sub{color:var(--dlymp-ink-dim);font-size:12px}
  9. dlymp-stats .st-foot{display:flex;justify-content:center;padding:11px 0 2px}
  10. dlymp-reset{font-size:13px;letter-spacing:.14em;border-radius:999px;padding:8px 30px;color:var(--dlymp-ink-dim);
 background:rgba(9,16,34,.55);border:1px solid var(--dlymp-bd);transition:all .15s}
  1. dlymp-reset:hover{border-color:var(--dlymp-acc)}
  2. dlymp-reset:active{transform:scale(.97)}

/* 本页隐藏站方右下角回顶按钮(.global-container 小广,fixed 100x100 碍事;乔泽拍板 2026-09-22)——widget style 只在宿主页注入 */ .global-container{display:none!important}

/* ---- 概率速查 ---- */

  1. dlymp-probwrap{overflow-x:auto}
  2. dlymp-probtab{width:100%;border-collapse:collapse;font-size:12px;min-width:340px}
  3. dlymp-probtab th,#dlymp-probtab td{border:1px solid var(--dlymp-bd-soft);padding:6px 6px;text-align:center;line-height:1.5}
  4. dlymp-probtab th{font-family:var(--font-st);font-weight:500;letter-spacing:.1em;color:var(--dlymp-acc2);background:rgba(201,168,106,.08)}
  5. dlymp-probtab td:first-child{text-align:left;color:var(--dlymp-ink)}
  6. dlymp-probtab td{color:var(--dlymp-ink-dim)}
  7. dlymp-probnote{font-size:12px;color:var(--dlymp-ink-dim);margin-top:6px;line-height:1.6}

/* ---- 手机端全屏去嵌套 padding(2026-09-22 乔泽:撑满整屏;实测 375px 下 game-bg 15px + app 10px + 各卡 margin 4px + bcard 10px 叠掉 ~47px/侧) ----

  .game-bg.container 是站方页面壳,widget style 只在宿主页注入(同 .global-container 隐藏先例),不影响其他页面 */

@media (max-width:768px){

 .game-bg.container{padding-left:0;padding-right:0}
 #dlymp-app{padding:4px 4px 16px;border-left:none;border-right:none;border-radius:0}
 #dlymp-topbar{margin:4px 0 0;padding:8px 10px}
 #dlymp-tabs{margin:6px 0 0}
 #dlymp-boards{margin:4px 0}
 #dlymp-app .bcard{padding:6px 8px 8px}
 #dlymp-stats{margin:10px 0;padding:4px 10px 10px}
 #dlymp-app .fold{margin:8px 0}
 #dlymp-app .fold-head{padding:10px 10px}
 #dlymp-app .fold-body{padding:4px 10px 10px}

}

/* ---- 弹窗 ---- */

  1. dlymp-app .pop{position:fixed;inset:0;z-index:10000;display:none;align-items:flex-start;justify-content:center; padding-top:12vh;background:rgba(4,8,20,.74)}
  2. dlymp-app .pop.is-open{display:flex}

/* 弹窗开着时压站头 logo:.wiki-header 是 z-index:3!important,正文 #content 仅 z:1,弹窗 z 再高也被封顶(2026-09-21 实测) */ body.dlymp-modal-on .wiki-header{z-index:0 !important}

  1. dlymp-app .pop .vdlg{width:min(400px,calc(100% - 20px));max-height:76vh;display:flex;flex-direction:column;overflow:hidden;
 background:var(--dlymp-bg-solid);
 border:1px solid var(--dlymp-bd);border-radius:8px;
 box-shadow:0 24px 70px rgba(0,0,0,.7),inset 0 1px 0 rgba(232,211,160,.12)}
  1. dlymp-app .pop .vhead{flex:none;text-align:center;padding:16px 16px 2px}
  2. dlymp-app .pop .vhead h3{font-family:var(--font-st);font-weight:500;font-size:20px;letter-spacing:.24em;margin:0;
 background:linear-gradient(180deg,#f6e8c4,#d3b578);-webkit-background-clip:text;background-clip:text;color:transparent}
  1. dlymp-app .pop .hairline{margin:10px 24px 0;border-top:1px solid var(--dlymp-bd-soft)}
  2. dlymp-app .pop .vbody{flex:1;min-height:0;overflow-y:auto;padding:12px 22px;font-size:14px;line-height:1.8;
 scrollbar-width:thin;scrollbar-color:var(--dlymp-bd) transparent}
  1. dlymp-app .pop .vbody .pop-stats{margin-top:9px;font-size:13px;color:var(--dlymp-ink-dim);border-top:1px dashed var(--dlymp-bd-soft);padding-top:8px}
  2. dlymp-app .pop .vbody .pop-stats b{color:var(--dlymp-acc2)}
  3. dlymp-app .pop .vbody .pop-stats img{width:35px;height:35px;object-fit:contain;vertical-align:-9px;margin:0 1px}
  4. dlymp-app .pop .vfoot{flex:none;display:flex;justify-content:center;gap:12px;padding:12px 16px 16px;border-top:1px solid var(--dlymp-bd-soft)}

/* ---- 对话卡(站内 dialogue1 轮子 scoped 复刻:彩蛋=学宫灵灵七交易对话,2026-09-21 用户给语法) ---- */

  1. dlymp-app .dialogue1-card{box-sizing:border-box;position:relative;display:flow-root;width:100%;margin:10px 0 0;overflow:hidden;
 box-shadow:inset 0 0 0 2px #ede3cd,inset 0 2px 10px rgba(188,165,113,.3)}
  1. dlymp-app .dialogue1-avatar{min-height:85px;padding:5px;border-radius:28px;display:flex}
  2. dlymp-app .dialogue1-avatar-left{position:absolute;left:-2px;bottom:-8px;width:65px;height:auto}
  3. dlymp-app .dialogue1-avatar-left img{width:100%;height:auto;display:block}
  4. dlymp-app .dialogue1-avatar-right{margin-top:5px;margin-left:61px}
  5. dlymp-app .dialogue1-name{position:relative;display:inline-block;font-family:serif;font-size:16px;font-weight:800;
 text-shadow:1px 0 1px #dfc7c7}
  1. dlymp-app .dialogue1-name::before{content:"▾"}
  2. dlymp-app .dialogue1-content{margin:5px 0}
  3. dlymp-app .dialogue1-default{color:#5d3920;border-color:#5d3920;background:linear-gradient(145deg,#ffffff,#f2ede8)}

@media (max-width:768px){

 #dlymp-app .dialogue1-avatar{min-height:75px;padding:5px 5px 5px 0;border-radius:22px}
 #dlymp-app .dialogue1-avatar-left{bottom:-8px;width:55px}
 #dlymp-app .dialogue1-avatar-right{margin-left:54px}
 #dlymp-app .dialogue1-name{font-size:14px}
 #dlymp-app .dialogue1-content{margin:2px 0;font-size:12px}

}

/* 命格选择/录入大弹窗 */

  1. dlymp-app .pop .pdlg{width:min(820px,calc(100% - 16px));height:min(500px,84vh);display:flex;flex-direction:column;overflow:hidden;
 background:var(--dlymp-bg-solid);border:1px solid var(--dlymp-bd);border-radius:8px;
 box-shadow:0 24px 70px rgba(0,0,0,.7),inset 0 1px 0 rgba(232,211,160,.12)}
  1. dlymp-app .pop .phead{flex:none;text-align:center;padding:14px 14px 0}
  2. dlymp-app .pop .phead h3{font-family:var(--font-st);font-weight:500;font-size:19px;letter-spacing:.18em;margin:0;
 background:linear-gradient(180deg,#f6e8c4,#d3b578);-webkit-background-clip:text;background-clip:text;color:transparent}
  1. dlymp-app .pop .phead .sub{margin-top:2px;font-size:12px;color:var(--dlymp-ink-dim);letter-spacing:.06em}
  2. dlymp-app .pop .pgrid{flex:1;min-height:0;overflow-y:auto;display:grid;grid-template-columns:repeat(2,1fr);
 gap:7px;padding:10px 14px;align-content:start;scrollbar-width:thin;scrollbar-color:var(--dlymp-bd) transparent}
  1. dlymp-app .pop .pitem{position:relative;font-size:13px;padding:9px 6px;text-align:center;cursor:pointer;user-select:none;
 background:rgba(9,16,34,.5);border:1px solid var(--dlymp-bd-soft);border-radius:4px;line-height:1.35;transition:all .15s}
  1. dlymp-app .pop .pitem.qb{color:var(--dlymp-qb)} #dlymp-app .pop .pitem.qp{color:var(--dlymp-qp)} #dlymp-app .pop .pitem.qo{color:var(--dlymp-qo)}
  2. dlymp-app .pop .pitem:hover{border-color:var(--dlymp-acc)}
  3. dlymp-app .pop .pitem.cur{border-color:var(--dlymp-acc2);background:rgba(201,168,106,.18);box-shadow:0 0 0 1px rgba(232,211,160,.5)}
  4. dlymp-app .pop .pitem.dis{opacity:.38;cursor:default}
  5. dlymp-app .pop .pitem:active{transform:scale(.96)}
  6. dlymp-app .pop .pfoot{flex:none;display:flex;justify-content:center;gap:12px;padding:11px 16px 14px;border-top:1px solid var(--dlymp-bd-soft)}

/* ---- toast ---- */

  1. dlymp-toast{position:fixed;left:50%;bottom:14vh;transform:translateX(-50%) translateY(8px);z-index:10050;
 max-width:calc(100% - 40px);padding:9px 18px;font-size:13px;letter-spacing:.06em;color:var(--dlymp-ink);
 background:var(--dlymp-bg-solid);border:1px solid var(--dlymp-bd);border-radius:999px;box-shadow:0 10px 30px rgba(0,0,0,.55);
 opacity:0;pointer-events:none;transition:opacity .18s,transform .18s;text-align:center}
  1. dlymp-toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

/* ---- PC 平铺 ---- */ @media (min-width:900px){

 #dlymp-tabs{display:none}
 #dlymp-boards{display:grid;grid-template-columns:1fr 1fr;gap:12px;align-items:start}
 #dlymp-app .bpane{display:block}
 #dlymp-topbar{flex-direction:row;align-items:center}
 #dlymp-rolebar{width:53%}
 #dlymp-expbar{border-top:none;border-left:1px dashed var(--dlymp-bd);padding-top:0;padding-left:10px}
 #dlymp-app .rscroll{grid-template-columns:repeat(6,1fr)}
 #dlymp-app .xscroll{grid-template-columns:repeat(4,1fr)}
 #dlymp-app .pop .pgrid{grid-template-columns:repeat(4,1fr)}
 #dlymp-app .cell .ttl{font-size:12px}
 #dlymp-app .ritem .avwrap{width:60px;height:60px}
 #dlymp-app .ritem .avwrap .ava{width:60px;height:60px}

} @media (max-width:390px){

 #dlymp-app .cell .eng{font-size:20px}
 #dlymp-app .fbtn.big{font-size:15px;letter-spacing:.2em}

}

/* ============================================================

* 命盘模拟器 · 背景视觉优化 v0.2(2026-09-21 workbuddy demo 产物,2026-09-22 kimi 核对后增量上线)
* 摸鱼鱼@workbuddy代笔  |  纯增量追加,不改动原有规则
* 方案:光斑层 + 暗角 + 盘面暗底收力 + 中心光核 + 格子提亮 + 生效位强光晕;光斑强度 28%
* kimi 核对记录:线上 .cell.hole(1,2,0)优先级高于本段 .cell(1,1,0),空洞格保持透明不受影响;
*               .bgrid.small 的 gap:3px(1,2,0)同样不被本段 gap:8px 覆盖;连线为 viewBox 百分比锚点,不受 gap 影响;
*               删去原补丁 .cell.pal-on b 提亮规则——线上宫格无 ,标题是 .ttl 且用品质色(蓝/紫/橙)传递信息,不能盖成暖白
* ============================================================ */

/* ---- 0. 层叠上下文:必须加,否则 ::before/::after 的 z-index:-1 会掉到父背景后面看不见 ---- */

  1. dlymp-app{isolation:isolate}

/* ---- 1. 光斑层(静态,永不参与命盘重绘)---- */

  1. dlymp-app::before{
 content:"";position:absolute;inset:-8%;z-index:-1;pointer-events:none;
 opacity:.28;                                    /* 光斑强度 28%,想调只改这一行 */
 background:
   radial-gradient(30% 34% at 14% 16%, rgba(140,110,220,.34), transparent 70%),
   radial-gradient(34% 38% at 86% 78%, rgba(201,168,106,.30), transparent 72%),
   radial-gradient(26% 30% at 58% 40%, rgba(84,130,200,.24), transparent 70%);
 filter:blur(56px);

}

/* ---- 2. 暗角:中心亮、四角沉,把视线压到盘面 ---- */

  1. dlymp-app::after{
 content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
 background:radial-gradient(120% 85% at 50% 42%, transparent 40%, rgba(4,8,18,.5) 100%);

}

/* ---- 3. 盘面暗底收力(原 .55 + inset .35 是"发闷"的真凶)---- */

  1. dlymp-app .bgrid{
 background:rgba(6,12,26,.26);
 box-shadow:inset 0 2px 14px rgba(0,0,0,.22);
 gap:8px;                                        /* 原 5px */

}

/* ---- 4. 中心光核:补在 2x2 空区 ---- */

  1. dlymp-app .bgrid::before{
 content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
 width:44%;aspect-ratio:1;border-radius:50%;z-index:0;pointer-events:none;
 background:radial-gradient(circle,rgba(232,211,160,.18) 0%,rgba(201,168,106,.08) 45%,transparent 70%);

}

/* ---- 5. 格子:提亮 + 圆角 6px(不动 --dlymp-radius-s,那个变量按钮共用)---- */

  1. dlymp-app .cell{
 border-radius:6px;
 background:linear-gradient(180deg,rgba(28,40,72,.66),rgba(16,26,50,.60));

}

/* ---- 6. 生效位:同色双层光晕 ---- */

  1. dlymp-app .cell.pal-on{
 background:linear-gradient(180deg,rgba(78,62,26,.62),rgba(38,32,18,.5));
 border-color:rgba(232,211,160,.75);
 box-shadow:0 0 0 1px rgba(232,211,160,.35),
            0 0 18px 2px rgba(232,211,160,.28),
            inset 0 0 14px rgba(232,211,160,.12);

} </style> <body>

心仪命盘<button id="dlymp-expset" type="button">设置</button>
     
   <button id="dlymp-tab-A" class="on" type="button">命盘 1</button>
   <button id="dlymp-tab-B" type="button">命盘 2</button>



天、命、弃、子
这是九幽大君对你的眷顾,或许你也有成为天命弃子的潜质。
<button class="fbtn main" id="dlymp-hit-ok" type="button">继续改命</button>

纹丝未动

天、命、弃、子
平等的命运……嗯,我应该没算错吧?
<button class="fbtn main" id="dlymp-white-ok" type="button">知道了</button>

初始命盘录入

       <button class="fbtn ghost" id="dlymp-entry-cancel" type="button">取消</button>
       <button class="fbtn ghost" id="dlymp-entry-random" type="button">随机生成</button>
       <button class="fbtn main" id="dlymp-entry-apply" type="button">确定</button>

更换密探

       <input id="dlymp-search" type="text" placeholder="搜索:名字 / 拼音 / 首字母简写" autocomplete="off">
       <button class="fbtn ghost" id="dlymp-role-close" type="button">关闭</button>

心仪命盘

<button type="button" data-i="0" class="on">心仪一</button><button type="button" data-i="1">心仪二</button>
       <button class="fbtn ghost" id="dlymp-expclr" type="button">清空</button>
       <button class="fbtn ghost" id="dlymp-exp-skip" type="button" style="display:none">返回</button>
       <button class="fbtn main" id="dlymp-exp-ok" type="button">确定</button>


善恶簿自助,功过格畅饮,洗刷刷大舞台,有梦你就来。代码仅为娱乐,不清楚游戏实际内容,没有实际参考意义。

<script> (function(){ 'use strict'; /* 工具常量(防搬运指纹) */ var DHYMP_TOOL={name:'dhy-mingpan',ver:'0.1-draft'};

/* 数据双形态(2026-09-21 定):

  本地 file:// 调试 —— window.DHY_MINGPAN_DATA / DHY_MINGPAN_FILTER(20公共数据库/命盘模拟器_本地数据.js)
  wiki 线上 —— 宿主页数据块 #dlymp-src(SMW #ask + 模板:命盘模拟器/数据行 节点)

+

(稀有度/头像/实装倒序)

+

(拼音/简写搜索字典) */ function decodeEnt(s){var t=document.createElement('textarea');t.innerHTML=s;return t.value;} /* SMW printout HTML -> 工具统一 desc 格式(<color=#x> 与 <中文关键词> 标记) */ function normDomDesc(el){

 var h=el.innerHTML||;
 h=h.replace(/<font[^>]*color="?(#[0-9a-fA-F]{6})"?[^>]*>/gi,'<color=$1>').replace(/<\/font>/gi,'</color>');
 h=h.replace(/<br\s*\/?>/gi,'\n');
 h=h.replace(/<(?!\/?color[=>])[a-zA-Z\/!][^>]*>/g,);
 return decodeEnt(h).trim();

} /* SMW 值残留 strip marker('"`UNIQ--ref-XXX-QINU`"')清洗:戏学北极效果名带 ref 所致(2026-09-21) */ function stripUniq(s){return s.replace(/'"?`?UNIQ--[a-zA-Z]+-[0-9A-Fa-f]+-QINU`?"?'?/g,).trim();} function loadData(){

 if(window.DHY_MINGPAN_DATA&&window.DHY_MINGPAN_DATA.roles){
   return {D:window.DHY_MINGPAN_DATA,
           F:window.DHY_MINGPAN_FILTER||{pinyin_full:{},pinyin_first:{},alias:{}}};
 }
 var src=document.getElementById('dlymp-src');
 var poolEl=document.getElementById('MIRROR_POOL');
 if(!src||!poolEl)return null;
 var poolArr=null,F={pinyin_full:{},pinyin_first:{},alias:{}};
 try{poolArr=JSON.parse(poolEl.textContent);}catch(e){return null;}
 try{var f=JSON.parse(document.getElementById('MP_FILTER').textContent);if(f)F=f;}catch(e){}
 if(!poolArr||!poolArr.length)return null;
 var meta={},ord=[];
 poolArr.forEach(function(it){meta[it.name]=it;ord.push(it.name);});
 var roles={},cnt={};
 Array.prototype.forEach.call(src.querySelectorAll('.dlymp-r'),function(el){
   var n=el.getAttribute('data-n'),m=meta[n];
   if(!m)return; /* 白名单:密探池名单外(测试页/活动页等)一律丢弃 */
   var pid=parseInt(el.getAttribute('data-p'),10);
   if(!(pid>=1&&pid<=12))return;
   var r=roles[n]||(roles[n]={rarity:m.rarity||,job:m.job||,attribute:m.attribute||,avatar:m.avatar||,native:,pool:new Array(12)});
   if(r.pool[pid-1])return; /* 酆公玖/酆公珠合体双命盘:每宫取首条(策划书 3.3) */
   var q=el.querySelector('.q'),g=el.querySelector('.g'),t=el.querySelector('.t'),d=el.querySelector('.d');
   r.pool[pid-1]={slot:g?stripUniq(g.textContent):,q:q?q.textContent.trim():,
                  title:t?stripUniq(t.textContent):,desc:d?normDomDesc(d):};
   cnt[n]=(cnt[n]||0)+1;
 });
 var out={},poolOrder=[];
 ord.forEach(function(n){
   if(roles[n]&&cnt[n]===12){out[n]=roles[n];poolOrder.push(n);}
 });
 return {D:{ver:'smw-live',count:poolOrder.length,poolOrder:poolOrder,roles:out},F:F};

} var _ld=loadData(); if(!_ld){document.getElementById('dlymp-foot').textContent='数据加载失败:本地需 命盘模拟器_本地数据.js;线上需宿主页 #dlymp-src 数据块';return;} var D=_ld.D, F=_ld.F;

/* ---- 几何与常量 ---- */ /* 12 宫格索引 -> (行,列),行/列 1 起;中央 2x2 为空 */ var CELL_RC=[[1,1],[1,2],[1,3],[1,4],[2,1],[2,4],[3,1],[3,4],[4,1],[4,2],[4,3],[4,4]]; var RC_CELL={}; CELL_RC.forEach(function(rc,i){RC_CELL[rc[0]+','+rc[1]]=i;}); /* 宫名固定表(仅展示标签,策划书 1.1) */ var PALACE_NAME={'1,1':'阳明','1,2':'暗星','1,3':'丹曲','1,4':'延寿','2,1':'命宫','2,4':'中天','3,1':'益算','3,4':'帝君','4,1':'北极','4,2':'太岁','4,3':'天关','4,4':'上生'}; /* 宫位(生效位)候选格索引:(1,1)=0 (2,4)=5 (4,2)=9 */ var CAND=[0,5,9]; var QCLS={'蓝':'qb','紫':'qp','橙':'qo'}; var QRANK={'橙':0,'紫':1,'蓝':2}; /* 品质权重(2026-09-22 用户反馈「爆率太高」后新增的模型假设,待实机样本校正):

  玩家实测随机命盘生效位蓝多紫少、橙极少;而配置中品质与命格绑定固定(全数据集 420 个效果名仅 2 个跨品质),
  故不能重 roll 品质,建模为「按品质加权、无放回抽 3 个生效位」——每条命格权重 = QW[品质]。
  调口径只改这一行;概率速查表按当前权重对当前密探池实时精确枚举,不会出现模型与表格打架。 */

var QW={'蓝':5,'紫':4,'橙':3}; function qw(pi,pool){return QW[pool[pi].q]||1;} /* 加权无放回抽 k 条,返回抽中的 pool 索引(顺序=抽取顺序);exclude={pi:true} 跳过锁定项 */ function wdraw(pool,k,exclude){

 var avail=[],i;
 for(i=0;i<pool.length;i++)if(!exclude||!exclude[i])avail.push(i);
 var out=[];
 while(out.length<k&&avail.length){
   var W=0;for(i=0;i<avail.length;i++)W+=qw(avail[i],pool);
   var r=Math.random()*W,acc=0,pick=avail.length-1;
   for(i=0;i<avail.length;i++){acc+=qw(avail[i],pool);if(r<acc){pick=i;break;}}
   out.push(avail[pick]);avail.splice(pick,1);
 }
 return out;

} /* 生成一整盘(12 格 pool 索引):3 个生效位按品质加权无放回抽取、位置随机;

  其余 9 格用剩余命格均匀填充(仅展示)。keep={cell,pi} 时该格保留(锁)。 */

function genBoard(pool,keep){

 var board=new Array(12).fill(null),excl={},i;
 if(keep){board[keep.cell]=keep.pi;excl[keep.pi]=true;}
 var cc=shuffleBoard(CAND.filter(function(c){return !keep||c!==keep.cell;}),null);
 var hits=wdraw(pool,cc.length,excl);
 for(i=0;i<cc.length;i++){board[cc[i]]=hits[i];excl[hits[i]]=true;}
 var rest=[];
 for(i=0;i<pool.length;i++)if(!excl[i])rest.push(i);
 rest=shuffleBoard(rest,null);
 var ri=0;
 for(i=0;i<12;i++)if(board[i]===null)board[i]=rest[ri++];
 return board;

} /* 精确枚举:加权无放回抽 k 条(k≤3),对事件 ev(有序抽取数组) 累加命中概率。

  12 条池 k=3 仅 1320 个有序叶节点,选中密探/心仪变化时实时重算开销可忽略。 */

function enumProb(pool,k,ev,exclude){

 var avail=[],i;
 for(i=0;i<pool.length;i++)if(!exclude||!exclude[i])avail.push(i);
 var p=0;
 (function rec(left,picks,prob){
   if(picks.length===k){if(ev(picks))p+=prob;return;}
   var W=0,j;for(j=0;j<left.length;j++)W+=qw(left[j],pool);
   for(j=0;j<left.length;j++){
     var nl=left.slice();nl.splice(j,1);
     rec(nl,picks.concat(left[j]),prob*qw(left[j],pool)/W);
   }
 })(avail,[],1);
 return p;

} /* 锁洗策略期望(精确枚举,规则=最多锁 1 宫;2026-09-22 群聊反馈"一发入魂 560 次太苛刻"——真实玩法是出 1 条就锁):

  m=1 无需锁;m≥2:洗到 ≥1 条心仪出现即锁(m=3 时锁让追洗期望最小的那条,等价于把高权重条留池),
  锁定洗每次 1 善恶簿+1 功过格;剩余条须在后续同一洗全部落进空余生效位(m=2 剩 1 条抽 2 位;m=3 剩 2 条抽 2 位)。
  返回 {shan,gong} 期望消耗(小数),无解返回 null。与 doWash/genBoard 模型一致:锁定条从池排除,空位加权无放回抽。 */

function lockExp(pool,T){

 function hasAll(pk,arr){return arr.every(function(x){return pk.indexOf(x)>=0;});}
 function hasAny(pk,arr){return arr.some(function(x){return pk.indexOf(x)>=0;});}
 var m=T.length;
 if(m===1){var p1=enumProb(pool,3,function(pk){return pk.indexOf(T[0])>=0;});return p1>0?{shan:1/p1,gong:0}:null;}
 var pa=enumProb(pool,3,function(pk){return hasAny(pk,T);});
 if(pa<=0)return null;
 var shan=1/pa,rem=0,i;
 if(m===2){
   for(i=0;i<2;i++)(function(locked,other){
     var pOnly=enumProb(pool,3,function(pk){return pk.indexOf(locked)>=0&&pk.indexOf(other)<0;});
     var excl={};excl[locked]=true;
     var pc=enumProb(pool,2,function(pk){return pk.indexOf(other)>=0;},excl);
     if(pc>0)rem+=(pOnly/pa)/pc;
   })(T[i],T[1-i]);
   return {shan:shan+rem,gong:rem};
 }
 /* m=3:枚举「恰好出现子集 S」(非空真子集)→ 锁 S 中最优一条;全集同洗出现则直接收工(pa 里含该支) */
 for(var mask=1;mask<7;mask++)(function(){
   var S=T.filter(function(_,i2){return mask&(1<<i2);});
   var pS=enumProb(pool,3,function(pk){
     var c=0;T.forEach(function(t){if(pk.indexOf(t)>=0)c++;});
     return c===S.length&&S.every(function(t){return pk.indexOf(t)>=0;});
   });
   if(pS<=0)return;
   var best=Infinity;
   S.forEach(function(locked){
     var rest=T.filter(function(t){return t!==locked;});
     var excl={};excl[locked]=true;
     var pb=enumProb(pool,2,function(pk){return hasAll(pk,rest);},excl);
     if(pb>0)best=Math.min(best,1/pb);
   });
   if(best<Infinity)rem+=(pS/pa)*best;
 })();
 return {shan:shan+rem,gong:rem};

} /* 命格选择网格固定排序:橙→紫→蓝,同品质保持 pool 原相对顺序(稳定排序) */ function sortedPoolIdx(pool){

 return pool.map(function(_,i){return i;}).sort(function(a,b){return (QRANK[pool[a].q]-QRANK[pool[b].q])||(a-b);});

} var RARITY_ORDER=['绝密','机密','隐密','电影']; var JOB_ORDER=['破军','龙盾','岐黄','神纪','诡道']; var ATTR_ORDER=['地','水','风','火','阴','阳','混沌']; /* 列表排序档:电影=绝密同档,其余依次(2026-09-22 用户拍板口径) */ var RARITY_RANK={'绝密':0,'电影':0,'机密':1,'隐密':2}; var ITEM_PRICE={shan:50,gong:100}; var ITEM_ICON={

 shan:'https://patchwiki.biligame.com/images/yuan/7/7f/7vdz9c8pm9gi1fymqqk1zwae8dzdv55.png',
 gong:'https://patchwiki.biligame.com/images/yuan/f/f0/039ezllhzelib33epqepevrc535uc5i.png'

}; function itemIcon(t,s){return '<img src="'+ITEM_ICON[t]+'" width="'+s+'" height="'+s+'" alt="" onerror="this.style.display=\'none\'">';}

/* ================= 纯函数(回归测试直接调用,无 DOM 依赖) ================= */ /* 均匀洗牌(Fisher-Yates):仅用于生效位内部位置打乱与非生效格填充;

  盘面生成的概率模型在 genBoard(品质加权无放回抽生效位,见 QW) */

function shuffleBoard(arr,lockedIdx){

 var a=arr.slice();
 var idxs=[];
 for(var i=0;i<a.length;i++){if(i!==lockedIdx)idxs.push(i);}
 for(var k=idxs.length-1;k>0;k--){
   var j=Math.floor(Math.random()*(k+1));
   var t=a[idxs[k]];a[idxs[k]]=a[idxs[j]];a[idxs[j]]=t;
 }
 return a;

} function titleOf(x){return (x&&typeof x==='object')?x.title:String(x);} /* 命中判定:三个生效位上的命格集合 包含 期望集合 */ function checkHit(boardArr,activeIdxArr,expectTitlesArr){

 if(!expectTitlesArr||!expectTitlesArr.length)return false;
 if(!activeIdxArr||!activeIdxArr.length)return false;
 var got={};
 activeIdxArr.forEach(function(i){got[titleOf(boardArr[i])]=true;});
 return expectTitlesArr.every(function(t){return !!got[t];});

} /* 白洗判定:新旧两盘在三个生效位上的命格集合与位置完全一致 */ function checkWhiteWash(newArr,oldArr,activeIdxArr){

 if(!activeIdxArr||!activeIdxArr.length)return false;
 return activeIdxArr.every(function(i){return titleOf(newArr[i])===titleOf(oldArr[i]);});

}

/* ================= 状态(全内存,刷新清零) ================= */ function newBoardState(){return {board:null,locked:[],sel:null,selSrc:'cur',phase:'main',newBoard:null};} var state={

 role:null,active:'A',rchip:'全部',job:'全部',attr:'全部',search:,
 boards:{A:newBoardState(),B:newBoardState()},
 expect:[[],[]],     /* 两套心仪命格(title 数组,各 1~3 条;任一套全中即命中),全工具共享 */
 expIdx:0,           /* 心仪弹窗正在编辑哪一套:0=心仪一 1=心仪二 */
 entry:{A:[],B:[]},    /* 初始录入:各盘按点击顺序排列的池索引数组 */
 stats:{A:{n:0,shan:0,gong:0},B:{n:0,shan:0,gong:0}},
 since:{n:0,shan:0,gong:0}  /* 自期望设定/上次命中以来 */

}; var popQueue=[];

/* ================= 工具 ================= */ function $(id){return document.getElementById(id);} function esc(s){return String(s).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');} /* 效果文案渲染:先转义,再把 <color=#xxxxxx> 与 <关键词> 两种游戏标签转 HTML */ function renderDesc(s){

 var t=esc(s);
 t=t.replace(/<color=(#[0-9a-fA-F]{6})>/g,'').replace(/<\/color>/g,'');
 t=t.replace(/<([^&<>\/]{1,12})>/g,'$1');
 return t;

} function curRole(){return state.role?D.roles[state.role]:null;} function curPool(){var r=curRole();return r?r.pool:null;} var toastTimer=null; function toast(msg){

 var el=$('dlymp-toast');el.textContent=msg;el.classList.add('show');
 clearTimeout(toastTimer);toastTimer=setTimeout(function(){el.classList.remove('show');},1800);

} function openPop(id){$(id).classList.add('is-open');document.body.classList.add('dlymp-modal-on');} function closePop(id){$(id).classList.remove('is-open');drainPopQueue();syncModalClass();} /* 站头 logo(.wiki-header z-index:3!important)压住一切弹窗:弹窗开着时把站头降到 z0,全关后恢复(2026-09-21 实测踩坑) */ function syncModalClass(){

 if(!document.querySelector('#dlymp-app .pop.is-open')&&!popQueue.length)document.body.classList.remove('dlymp-modal-on');

} function queuePop(fn){popQueue.push(fn);drainPopQueue();} function drainPopQueue(){

 if(!popQueue.length)return;
 var anyOpen=document.querySelector('#dlymp-app .pop.is-open');
 if(anyOpen)return;
 var fn=popQueue.shift();fn();

}

/* ================= 密探选择器 ================= */ function roleMatch(name,q){

 if(!q)return true;
 if(/^[a-z0-9]+$/i.test(q)){
   var pf=String(F.pinyin_full[name]||).toLowerCase();
   var pi=String(F.pinyin_first[name]||).toLowerCase();
   return pf.indexOf(q.toLowerCase())>=0||pi.indexOf(q.toLowerCase())===0;
 }
 var al=F.alias[name];
 var arr=Array.isArray(al)?al:(al?[al]:[]);
 if(name.indexOf(q)>=0)return true;
 return arr.some(function(a){return String(a).indexOf(q)>=0;});

} function renderRchips(){

 /* 三行筛选:品质(稀有度)/ 职业 / 属性,值从数据动态收集(不显示数量);三行均按固定表排序,表外值兜底排尾 */
 var rows=[['品质','rchip','rarity',RARITY_ORDER],['职业','job','job',JOB_ORDER],['属性','attr','attribute',ATTR_ORDER]];
 var html=;
 rows.forEach(function(row){
   var label=row[0],key=row[1],field=row[2],order=row[3];
   var vals=[],seen={};
   Object.keys(D.roles).forEach(function(n){
     var v=D.roles[n][field]||;
     if(!v)return;
     /* 双属性(赵云=风,火)不单独出芯片:拆开分别计入两个单属性 */
     var parts=field==='attribute'?v.split(','):[v];
     parts.forEach(function(p){
       if(!p||seen[p])return;
       seen[p]=1;vals.push(p);
     });
   });
   if(order)vals.sort(function(a,b){var ia=order.indexOf(a),ib=order.indexOf(b);return (ia<0?99:ia)-(ib<0?99:ib);});
   else vals.sort();

var h='

'+label+'';
   ['全部'].concat(vals).forEach(function(v){
     h+=''+v+'';
   });
html+=h+'

';

 });
 $('dlymp-rchips').innerHTML=html;
 Array.prototype.forEach.call($('dlymp-rchips').querySelectorAll('.fchip'),function(ch){
   ch.addEventListener('click',function(){
     state[ch.getAttribute('data-k')]=ch.getAttribute('data-v');
     renderRchips();renderRgrid();
   });
 });

} function renderRgrid(){

 var names=Object.keys(D.roles).filter(function(n){
   var r=D.roles[n];
   if(state.rchip!=='全部'&&r.rarity!==state.rchip)return false;
   if(state.job!=='全部'&&r.job!==state.job)return false;
   if(state.attr!=='全部'&&(r.attribute||).split(',').indexOf(state.attr)<0)return false;
   return roleMatch(n,state.search.trim());
 });
 /* 排序:品质档(电影=绝密同档)→ 档内按实装倒序(新密探在前,poolOrder 即实装倒序);筛选 chips 只过滤不分组 */
 var ord={};
 (D.poolOrder||[]).forEach(function(n,i){ord[n]=i;});
 names.sort(function(a,b){
   var ra=RARITY_RANK[D.roles[a].rarity],rb=RARITY_RANK[D.roles[b].rarity];
   if(ra==null)ra=9;if(rb==null)rb=9;
   return ra-rb||((ord[a]==null?9999:ord[a])-(ord[b]==null?9999:ord[b]));
 });
 var html=;
 names.forEach(function(n){
   var r=D.roles[n];
   /* 超长名(>5 字,如 史子眇·赴烛)套 small 缩字号,不动全局字号 */
   var nm=n.length>5?''+esc(n)+'':esc(n);

html+='

'
     +'<img class="ava" src="'+esc(r.avatar)+'" alt="" loading="lazy">'
+''+nm+'

';

 });

if(!names.length)html='

没有匹配的密探

';

 $('dlymp-rgrid').innerHTML=html;
 Array.prototype.forEach.call($('dlymp-rgrid').querySelectorAll('.ritem'),function(it){
   it.addEventListener('click',function(){selectRole(it.getAttribute('data-name'));});
 });

} function selectRole(name){

 if(!D.roles[name])return;
 var changed=state.role!==name;
 state.role=name;
 state.boards.A=newBoardState();state.boards.B=newBoardState();
 state.boards.A.board=genBoard(curPool(),null);
 state.boards.B.board=genBoard(curPool(),null);
 state.entry={A:[],B:[]};
 if(changed){state.expect=[[],[]];state.expIdx=0;resetSince();}
 $('dlymp-xinfo').hidden=true;$('dlymp-einfo').hidden=true;
 closePop('dlymp-pop-role');
 renderAll();
 /* 选定后连弹:心仪 → 命盘 1 录入 → 命盘 2 录入(各步可跳过) */
 chain=true;
 renderExpPop();openPop('dlymp-pop-exp');

} function renderRolebar(){

 var el=$('dlymp-rolebar');
 if(!state.role){el.innerHTML='尚未选择密探 —— 点右侧「更换」选一位';return;}
 var r=curRole();
 el.innerHTML='<img class="rb-ava" src="'+esc(r.avatar)+'" alt="">'
   +''+esc(state.role)+''
   +'<button class="rb-change" id="dlymp-rb-change" type="button">更换</button>';
 $('dlymp-rb-change').addEventListener('click',function(){
   renderRchips();renderRgrid();
   openPop('dlymp-pop-role');
 });

}

/* ================= 盘面渲染 ================= */ function linksSvg(){

 /* 三角连线锚点(游戏截图同款):(1,1)右下角 ↔ (2,4)左边中点 ↔ (4,2)顶边中点;三宫恒生效,三边常画 */
 var pt=[[25,25],[75,37.5],[37.5,75]]; /* 顺序同 CAND:(1,1)、(2,4)、(4,2);viewBox 100x100,格域 25x25 */
 var edges=[[0,1],[1,2],[2,0]],s=;
 edges.forEach(function(e){
   s+='<line x1="'+pt[e[0]][0]+'" y1="'+pt[e[0]][1]+'" x2="'+pt[e[1]][0]+'" y2="'+pt[e[1]][1]+'"/>';
 });
 return '<svg class="links" viewBox="0 0 100 100" preserveAspectRatio="none">'+s+'</svg>';

} function lockImg(){

 /* 金锁 PNG(文件:UI-命盘模拟器-锁.png,64x37):状态由 CSS 控制(off=半透明可锁,on=实色+绿光已锁) */
 return '<img src="https://patchwiki.biligame.com/images/yuan/f/f9/5sfnit4svrvxr55ojk90g0wbrb4qlvt.png" width="24" height="14" alt="" draggable="false">';

} function cellHtml(b,cellIdx,pool,boardArr,small,src){

 var rc=CELL_RC[cellIdx];
 var palName=PALACE_NAME[rc[0]+','+rc[1]];
 var isCand=CAND.indexOf(cellIdx)>=0;
 var pi=boardArr[cellIdx];
 var item=pool[pi];
 var cls='cell '+QCLS[item.q];
 if(isCand)cls+=' pal-on';
 if(b.sel===cellIdx&&b.selSrc===src)cls+=' sel';

var h='

';
 h+=''+esc(item.slot)+'';
 h+=''+esc(item.title)+'';
 var lk=b.locked.indexOf(cellIdx)>=0;
 /* 锁挂在原命盘/主界面(当前盘 b.board)上:锁的是「现有这格命格+位置别动」,洗时保留;
    新命盘(pending)无锁图标(2026-09-22 用户拍板,推翻 ⑪ 的方向) */
 if(isCand&&src!=='new'){
   h+=''+lockImg()+'';
 }
h+='

';

 return h;

} function gridHtml(b,pool,boardArr,small,src){

 var h=linksSvg();
 for(var r=1;r<=4;r++)for(var c=1;c<=4;c++){

if(r>=2&&r<=3&&c>=2&&c<=3){h+='

';continue;}

   h+=cellHtml(b,RC_CELL[r+','+c],pool,boardArr,small,src);
 }
 return h;

} function bindGrid(el,b,src){

 Array.prototype.forEach.call(el.querySelectorAll('.lockic'),function(lc){
   lc.addEventListener('click',function(e){
     e.stopPropagation(); /* 点锁图标不触发宫格选中/详情 */
     toggleLockCell(b,parseInt(lc.getAttribute('data-lock'),10));
   });
 });
 if(b.phase==='compare')return; /* 对比态不绑定点格看详情 */
 Array.prototype.forEach.call(el.querySelectorAll('.cell[data-cell]'),function(cel){
   cel.addEventListener('click',function(){
     var idx=parseInt(cel.getAttribute('data-cell'),10);
     if(b.sel===idx&&b.selSrc===src){b.sel=null;}
     else{b.sel=idx;b.selSrc=src;}
     state.active=paneKey(b);
     renderAll();
   });
 });

} function paneKey(b){return state.boards.A===b?'A':'B';}

function renderPane(k){

 var b=state.boards[k],pane=$('dlymp-pane-'+k),pool=curPool();

var h='

'; h+='
命盘 '+boardLabel(k)+''
   +'<button class="entrybtn" id="dlymp-entrybtn-'+k+'" type="button">录入</button>'
+'
';
 if(!pool){
h+='
选择密探后生成命盘
';
 }else if(b.phase==='compare'){
   /* 2026-09-22 用户拍板:对比态上原下新(原命盘在上、新命盘在下),其余不变 */
h+='
原命盘
'; h+='
'+gridHtml(b,pool,b.board,true,'old')+'
'; h+='
'; h+='
新命盘
'; h+='
'+gridHtml(b,pool,b.newBoard,true,'new')+'
';
 }else{
h+='
'+gridHtml(b,pool,b.board,false,'cur')+'
';
 }
if(b.phase!=='compare')h+='
';
 if(pool&&b.phase==='compare'){
   var locked=b.locked.length>0;
h+='
消耗:'
     +''+itemIcon('shan',18)
     +(locked?itemIcon('gong',18):)
+'
'; h+='
'
     +'<button class="fbtn ghost" id="dlymp-cancel-'+k+'" type="button">取消</button>'
     +'<button class="fbtn ghost" id="dlymp-again-'+k+'" type="button">再次改命</button>'
     +'<button class="fbtn main" id="dlymp-accept-'+k+'" type="button">接受结果</button>'
+'
';
 }else if(pool){
   var locked2=b.locked.length>0;
h+='
消耗:'
     +''+itemIcon('shan',18)
     +(locked2?itemIcon('gong',18):)
+'
' +'<button class="fbtn main big" id="dlymp-go-'+k+'" type="button">开始改命</button>
';
 }
h+='

';

 pane.innerHTML=h;
 if(!pool)return;
 /* 绑定 */
 $('dlymp-entrybtn-'+k).addEventListener('click',function(){openEntry(k);});
 if(b.phase==='compare'){
   bindGrid($('dlymp-grid-new-'+k),b,'new');
   bindGrid($('dlymp-grid-old-'+k),b,'old');
   $('dlymp-cancel-'+k).addEventListener('click',function(){cancelWash(k);});
   $('dlymp-again-'+k).addEventListener('click',function(){doWash(k);});
   $('dlymp-accept-'+k).addEventListener('click',function(){acceptWash(k);});
 }else{
   bindGrid($('dlymp-grid-'+k),b,'cur');
   $('dlymp-go-'+k).addEventListener('click',function(){doWash(k);});
 }
 renderDetail(k);

}

function renderDetail(k){

 var b=state.boards[k],el=$('dlymp-detail-'+k),pool=curPool();
 if(!el)return; /* 对比态无详情区 */

if(!pool){el.innerHTML='

点按宫格查看命格详情

';return;} if(b.sel==null){el.innerHTML='

点按宫格查看命格详情

';return;}

 var arr=(b.phase==='compare'&&b.selSrc==='old')?b.board:(b.phase==='compare'?b.newBoard:b.board);
 /* 对比态点哪盘显示哪盘:selSrc=old 看原命盘,否则看新命盘 */
 var item=pool[arr[b.sel]];
 var rc=CELL_RC[b.sel];
 var palName=PALACE_NAME[rc[0]+','+rc[1]];

var h='

'
   +''+palName+'宫'
   +''+esc(item.title)+''
   +''+item.q+''
+'

' +'

'+renderDesc(item.desc)+'

';

 el.innerHTML=h;

}

/* ================= 锁定 ================= */ function toggleLockCell(b,idx){

 /* 锁只能落在三个生效位上;每盘最多 1 个,点第二个自动顶替 */
 if(CAND.indexOf(idx)<0)return;
 state.active=paneKey(b);
 if(b.locked.indexOf(idx)>=0){b.locked=[];}
 else{
   if(b.locked.length&&b.locked[0]!==idx)toast('每盘最多锁 1 格,已顶替原锁定');
   b.locked=[idx];
 }
 renderAll();

}

/* ================= 改命流程 ================= */ function addCost(k,locked){

 var s=state.stats[k];
 s.n++;s.shan++;if(locked)s.gong++;
 state.since.n++;state.since.shan++;if(locked)state.since.gong++;

} function resetSince(){state.since={n:0,shan:0,gong:0};} function doWash(k){

 var b=state.boards[k],pool=curPool();
 if(!pool||!b.board)return;
 state.active=k;
 /* 锁挂在当前盘(原命盘/主界面)上:锁的是现有「命格+位置」,改命时新盘保留该格,其余加权重抽 */
 var lockedIdx=b.locked.length?b.locked[0]:null;
 addCost(k,lockedIdx!=null);
 var oldItems=b.board.map(function(i){return pool[i];});
 /* 新盘按品质加权模型重新生成(锁定格保留当前盘同条命格+位置,其余照常抽) */
 var newIdx=genBoard(pool,lockedIdx!=null?{cell:lockedIdx,pi:b.board[lockedIdx]}:null);
 var newItems=newIdx.map(function(i){return pool[i];});
 b.newBoard=newIdx;b.phase='compare';b.sel=null;
 renderAll();
 var white=checkWhiteWash(newItems,oldItems,CAND);
 var hit=state.expect.some(function(s){return s.length>0&&checkHit(newItems,CAND,s);});
 if(white){
   queuePop(function(){openPop('dlymp-pop-white');});
 }
 if(hit){
   var sn=state.since;
   $('dlymp-hit-stats').innerHTML='为洗出期望命盘,共改命 '+sn.n+' 次,消耗 '+itemIcon('shan',16)+'善恶簿 ×'+sn.shan+'、'+itemIcon('gong',16)+'功过格 ×'+sn.gong+'';
   queuePop(function(){openPop('dlymp-pop-hit');});
   resetSince();
 }

} function cancelWash(k){

 var b=state.boards[k];
 b.newBoard=null;b.phase='main';b.sel=null; /* 锁属于当前盘:取消保留锁 */
 renderAll();

} function acceptWash(k){

 var b=state.boards[k];
 b.board=b.newBoard;b.newBoard=null;b.phase='main';b.sel=null; /* 锁定格内容不变,接受后锁继续有效 */
 renderAll();
 toast('已接受新命盘(命盘 '+boardLabel(k)+')');

}

/* ================= 心仪命盘(期望,两套,任一全中即命中) ================= */ function boardLabel(k){return k==='A'?'1':'2';} /* 入口行:两套心仪分组小芯片 / 未设置 */ function renderExpbar(){

 var wrap=$('dlymp-expchips'),pool=curPool();
 var has=state.expect[0].length||state.expect[1].length;
 renderProb(); /* 心仪变动 → 速查表心仪行联动 */
 if(!pool||!has){wrap.innerHTML='未设置';return;}
 var h=;
 state.expect.forEach(function(set,gi){
   if(!set.length)return;
   h+='心仪'+'一二'[gi]+'';
   set.forEach(function(t){
     var item=null;
     for(var i=0;i<pool.length;i++)if(pool[i].title===t){item=pool[i];break;}
     h+=''+esc(t)+'';
   });
   h+='';
 });
 wrap.innerHTML=h;

} /* 弹窗内:12 条平铺芯片(带「详」徽章)+ 双套计数 + 分段开关 */ function renderExpPop(){

 var grid=$('dlymp-xgrid'),pool=curPool();

if(!pool){grid.innerHTML='

先选择密探

';return;}

 var ai=state.expIdx;
 $('dlymp-exp-sub').textContent=state.role+' 的 12 条命格 · 心仪一 '+state.expect[0].length+'/3 · 心仪二 '+state.expect[1].length+'/3,任一套全中即命中';
 $('dlymp-exp-skip').style.display=chain?:'none';
 Array.prototype.forEach.call(document.querySelectorAll('#dlymp-expseg button'),function(btn){
   btn.classList.toggle('on',parseInt(btn.getAttribute('data-i'),10)===ai);
 });
 var h=;
 sortedPoolIdx(pool).forEach(function(pi){
   var item=pool[pi];
   var o1=state.expect[0].indexOf(item.title),o2=state.expect[1].indexOf(item.title);
   var marks=[];
   if(o1>=0)marks.push('一');
   if(o2>=0)marks.push('二');

h+='

=0)?' on':)+'" data-pi="'+pi+'">'
     +'详'
     +(marks.length?''+marks.join()+'':)
+esc(item.title)+'

';

 });
 grid.innerHTML=h;
 Array.prototype.forEach.call(grid.querySelectorAll('.xchip'),function(ch){
   ch.addEventListener('click',function(){
     var pi=parseInt(ch.getAttribute('data-pi'),10);
     toggleExpect(pool[pi].title);
     openInfo(pi,'dlymp-xinfo',true);
   });
 });
 Array.prototype.forEach.call(grid.querySelectorAll('.inf'),function(badge){
   badge.addEventListener('click',function(e){
     e.stopPropagation();
     openInfo(parseInt(badge.getAttribute('data-pi'),10),'dlymp-xinfo');
   });
 });

} function toggleExpect(title){

 var set=state.expect[state.expIdx];
 var i=set.indexOf(title);
 if(i>=0){set.splice(i,1);}
 else{
   if(set.length>=3){toast('每套心仪最多选 3 条');return;}
   set.push(title);
 }
 resetSince(); /* 期望变更即清零重计 */
 renderExpbar();renderExpPop();

} /* 命格详情内嵌区(选择器「详」徽章唤起,渲染在网格下方;再点同一徽章收起;点格子本体=强制展开不收起) */ function openInfo(pi,boxId,forceShow){

 var pool=curPool();if(!pool)return;
 var box=$(boxId),item=pool[pi];
 if(!box)return;
 if(!forceShow&&!box.hidden&&box.getAttribute('data-pi')===String(pi)){box.hidden=true;return;}
 box.setAttribute('data-pi',pi);

box.innerHTML='

'
   +''+esc(item.slot)+'宫'
   +''+esc(item.title)+''
+''+item.q+'

' +'

'+renderDesc(item.desc)+'

';

 box.hidden=false;

}

/* ================= 初始命盘录入(弹窗:12 条互斥多选) ================= */ var entryCtx=null; /* 当前录入目标盘 'A'|'B' */ var chain=false; /* 连弹链:选定密探 → 心仪 → 盘 1 录入 → 盘 2 录入 */ function openEntry(k){

 if(!curPool())return;
 entryCtx=k;
 state.entry[k]=state.entry[k].slice(0,CAND.length);
 $('dlymp-entry-title').textContent='初始命盘录入 · 命盘 '+boardLabel(k);
 $('dlymp-entry-cancel').textContent=chain?'跳过':'取消';
 $('dlymp-einfo').hidden=true;
 renderEntryPop();
 openPop('dlymp-pop-entry');

} function renderEntryPop(){

 var grid=$('dlymp-entry-grid'),pool=curPool();

if(!pool){grid.innerHTML='

先选择密探

';return;}

 var k=entryCtx,kn=CAND.length,picks=state.entry[k];
 var full=picks.length>=kn,h=;
 sortedPoolIdx(pool).forEach(function(pi){
   var item=pool[pi];
   var oi=picks.indexOf(pi);

h+='

=0?' cur':(full?' dis':))+'" data-pi="'+pi+'">'
     +'详'
+esc(item.title)+'

';

 });
 grid.innerHTML=h;
 Array.prototype.forEach.call(grid.querySelectorAll('.pitem'),function(it){
   if(it.classList.contains('dis'))return;
   it.addEventListener('click',function(){
     var pi=parseInt(it.getAttribute('data-pi'),10),oi=picks.indexOf(pi);
     if(oi>=0)picks.splice(oi,1);else picks.push(pi);
     renderEntryPop();
     openInfo(pi,'dlymp-einfo',true);
   });
 });
 Array.prototype.forEach.call(grid.querySelectorAll('.inf'),function(badge){
   badge.addEventListener('click',function(e){
     e.stopPropagation();
     openInfo(parseInt(badge.getAttribute('data-pi'),10),'dlymp-einfo');
   });
 });
 $('dlymp-entry-sub').textContent='已选 '+picks.length+'/'+kn+' · 点击顺序即三个连线宫位的填入顺序,其余格随机填充';
 $('dlymp-entry-apply').disabled=picks.length<kn;

} function applyEntry(k,randomOnly){

 var b=state.boards[k],pool=curPool();
 if(!pool){toast('先选择密探');return;}
 if(randomOnly){
   /* 随机生成 = 模拟系统发放的初始命盘:与改命同一加权模型(玩家实测初始盘蓝多紫少橙极少) */
   b.board=genBoard(pool,null);b.sel=null;b.phase='main';b.newBoard=null;b.locked=[];
   state.active=k;renderAll();toast('命盘 '+boardLabel(k)+' 已随机生成');return;
 }
 var picks=state.entry[k].slice(0,CAND.length);
 var used={},cell;
 picks.forEach(function(pi){used[pi]=true;});
 var rest=[];
 for(var i=0;i<12;i++)if(!used[i])rest.push(i);
 rest=shuffleBoard(rest,null);
 var board=new Array(12).fill(null);
 var ui=0;
 CAND.forEach(function(c){if(ui<picks.length){board[c]=picks[ui++];}});
 var ri=0;
 for(cell=0;cell<12;cell++)if(board[cell]===null)board[cell]=rest[ri++];
 b.board=board;b.sel=null;b.phase='main';b.newBoard=null;b.locked=[];
 /* 锁属于当前盘:录入/随机生成换了整个盘,锁清空(取消/接受则保留锁) */
 state.active=k;
 renderAll();
 toast('命盘 '+boardLabel(k)+' 已'+(randomOnly?'随机生成':'按录入生成'));

} /* 连弹链推进:盘 1 → 盘 2 → 结束 */ function chainNext(){

 if(!chain)return;
 if(entryCtx==='A'){openEntry('B');}
 else{chain=false;$('dlymp-role-close').style.display=;}

}

/* ================= 结算面板 ================= */ function renderStats(){

 var A=state.stats.A,B=state.stats.B;
 $('dlymp-st-n').textContent=A.n+B.n;
 $('dlymp-st-na').textContent=A.n;
 $('dlymp-st-nb').textContent=B.n;
 $('dlymp-st-shan').textContent=A.shan+B.shan;
 $('dlymp-st-gong').textContent=A.gong+B.gong;
 $('dlymp-st-gold').textContent=(A.shan+B.shan)*ITEM_PRICE.shan+(A.gong+B.gong)*ITEM_PRICE.gong;

}

/* ================= 状态缓存(刷新/重进恢复上次状态,2026-09-22 用户拍板) ================= */ /* 存储降级链(B站App禁localStorage红线):localStorage → cookie(30天) → 内存 */ var SAVE_KEY='dhyly_mingpan_v1'; var _memSave=null; function storageSet(s){

 try{localStorage.setItem(SAVE_KEY,s);return;}catch(e){}
 try{document.cookie=SAVE_KEY+'='+encodeURIComponent(s)+';path=/;max-age=2592000';}catch(e){}
 _memSave=s;

} function storageGet(){

 try{var s=localStorage.getItem(SAVE_KEY);if(s)return s;}catch(e){}
 try{
   var m=document.cookie.match(new RegExp('(?:^|; )'+SAVE_KEY+'=([^;]*)'));
   if(m)return decodeURIComponent(m[1]);
 }catch(e){}
 return _memSave;

} function packBoard(b){return {board:b.board,locked:b.locked,phase:b.phase,newBoard:b.newBoard};} var _saveTimer=null; /* 挂在 renderAll 上 debounce 1s:任何操作重渲染后自动落盘 */ function saveSoon(){

 clearTimeout(_saveTimer);
 _saveTimer=setTimeout(function(){
   try{
     storageSet(JSON.stringify({v:1,role:state.role,active:state.active,
       boards:{A:packBoard(state.boards.A),B:packBoard(state.boards.B)},
       expect:state.expect,entry:state.entry,stats:state.stats,since:state.since}));
   }catch(e){}
 },1000);

} function validBoardArr(a){return Array.isArray(a)&&a.length===12&&a.every(function(i){return Number.isInteger(i)&&i>=0&&i<12;});} /* 恢复上次状态;坏档(角色不在池/版本不符/数据残缺)自动丢弃返回 false */ function loadSave(){

 var raw=storageGet();
 if(!raw)return false;
 var s;
 try{s=JSON.parse(raw);}catch(e){return false;}
 if(!s||s.v!==1||!s.role||!D.roles[s.role])return false;
 state.role=s.role;
 state.active=(s.active==='B')?'B':'A';
 ['A','B'].forEach(function(k){
   var sb=(s.boards&&s.boards[k])||{},b=state.boards[k];
   if(validBoardArr(sb.board)){
     b.board=sb.board;
     b.locked=Array.isArray(sb.locked)?sb.locked.filter(function(i){return Number.isInteger(i)&&i>=0&&i<12;}):[];
     if(sb.phase==='compare'&&validBoardArr(sb.newBoard)){b.phase='compare';b.newBoard=sb.newBoard;}
   }
 });
 if(Array.isArray(s.expect))state.expect=[Array.isArray(s.expect[0])?s.expect[0]:[],Array.isArray(s.expect[1])?s.expect[1]:[]];
 if(s.entry)['A','B'].forEach(function(k){if(Array.isArray(s.entry[k]))state.entry[k]=s.entry[k].filter(function(i){return Number.isInteger(i)&&i>=0&&i<12;});});
 if(s.stats)['A','B'].forEach(function(k){var st=s.stats[k];if(st)state.stats[k]={n:st.n|0,shan:st.shan|0,gong:st.gong|0};});
 if(s.since)state.since={n:s.since.n|0,shan:s.since.shan|0,gong:s.since.gong|0};
 return true;

}

/* ================= 总渲染 & 事件 ================= */ /* ================= 概率速查(按当前密探池 × QW 权重实时精确枚举) ================= */ function renderProb(){

 var body=$('dlymp-probbody'),note=$('dlymp-probnote'),pool=curPool();
 if(!body)return;
 if(!pool){

body.innerHTML='选择密探后,按其 12 条命格池实时精确枚举';

   note.textContent=;return;
 }
 function fmt(p){
   if(p<=0)return '—';
   var e=1/p;
   return (p*100).toFixed(2)+'%(约 '+(e>=100?Math.round(e):e.toFixed(1))+' 次)';
 }
 var rows=[],rep={},i;
 for(i=0;i<12;i++)if(rep[pool[i].q]==null)rep[pool[i].q]=i; /* 同品质条目权重相同,取首条为代表 */
 ['蓝','紫','橙'].forEach(function(q){
   if(rep[q]==null)return;
   var pi=rep[q];
   rows.push(['指定 1 条命中('+q+'目标)',
     fmt(enumProb(pool,3,function(pk){return pk.indexOf(pi)>=0;}))]);
 });
 ['蓝','紫','橙'].forEach(function(q){
   if(rep[q]==null)return;
   var pi=rep[q],li=(rep['蓝']!==pi)?rep['蓝']:(rep['紫']!==undefined&&rep['紫']!==pi?rep['紫']:rep['橙']);
   if(li==null||li===pi)return;
   var excl={};excl[li]=true; /* 锁的不是目标,锁定格按蓝计(最常见情形) */
   rows.push(['锁 1 条后再中指定 1 条('+q+'目标)',
     fmt(enumProb(pool,2,function(pk){return pk.indexOf(pi)>=0;},excl))]);
 });
 /* 心仪套装命中(已设置才显示;含期望消耗折算) */
 var setIdxs=[];
 state.expect.forEach(function(set,gi){
   if(!set.length)return;
   var idxs=[],ok=true;
   set.forEach(function(t){
     var f=-1;for(var i=0;i<12;i++)if(pool[i].title===t){f=i;break;}
     if(f<0)ok=false;else idxs.push(f);
   });
   if(!ok||!idxs.length||idxs.length>3)return;
   setIdxs.push(idxs);
   var p=enumProb(pool,3,function(pk){return idxs.every(function(x){return pk.indexOf(x)>=0;});});
   var s='一发 '+fmt(p);
   var le=lockExp(pool,idxs);
   if(le){
     var gold=Math.round((le.shan*ITEM_PRICE.shan+le.gong*ITEM_PRICE.gong)/100)*100;
     s+='
'+(idxs.length>1?'锁洗期望(出 1 条即锁)':'期望(无需锁)')+' ≈ '+Math.ceil(le.shan)+' 善恶簿' +(le.gong>0.05?' + '+Math.ceil(le.gong)+' 功过格':) +' ≈ '+gold+' 白金币'; } rows.push(['洗中心仪'+'一二'[gi]+'('+idxs.length+' 条全中)',s]); }); if(setIdxs.length===2){ var pany=enumProb(pool,3,function(pk){ return setIdxs.some(function(idxs){return idxs.every(function(x){return pk.indexOf(x)>=0;});}); }); rows.push(['任一套心仪全中',fmt(pany)]); }

body.innerHTML=rows.map(function(r){return ''+r[0]+''+r[1]+'';}).join();

 note.textContent='模型假设(2026-09-22 修订,待实机样本校正):品质与命格绑定固定(蓝/紫/橙为配置定值,不会重 roll);每次生成盘面时 3 个生效位按品质加权无放回抽取,权重 蓝:紫:橙 = '+QW['蓝']+':'+QW['紫']+':'+QW['橙']+',其余 9 格仅展示。上表为当前密探池在该权重下的精确枚举值;锁行按「锁的不是目标」计;心仪行附锁洗策略期望(最多锁 1 宫:出 1 条心仪即锁,剩余条须同洗全中,3 条时优先锁权重最低条,精确枚举)。游戏真实权重未知,本表随假设变动,仅供规划参考。';

}

function renderAll(){

 renderRolebar();
 renderPane('A');renderPane('B');
 renderExpbar();renderStats();renderProb();
 $('dlymp-tab-A').classList.toggle('on',state.active==='A');
 $('dlymp-tab-B').classList.toggle('on',state.active==='B');
 $('dlymp-pane-A').classList.toggle('on',state.active==='A');
 $('dlymp-pane-B').classList.toggle('on',state.active==='B');
 saveSoon();

}

function bindStatic(){

 $('dlymp-probsec-head').addEventListener('click',function(){$('dlymp-probsec').classList.toggle('open');});
 $('dlymp-search').addEventListener('input',function(e){state.search=e.target.value;renderRgrid();});
 $('dlymp-tab-A').addEventListener('click',function(){state.active='A';renderAll();});
 $('dlymp-tab-B').addEventListener('click',function(){state.active='B';renderAll();});
 $('dlymp-role-close').addEventListener('click',function(){closePop('dlymp-pop-role');});
 $('dlymp-expset').addEventListener('click',function(){$('dlymp-xinfo').hidden=true;renderExpPop();openPop('dlymp-pop-exp');});
 $('dlymp-exp-ok').addEventListener('click',function(){
   closePop('dlymp-pop-exp');
   renderExpbar(); /* 提交心仪后联动速查表(renderAll 之外的直达路径) */
   if(chain)openEntry('A');
 });
 $('dlymp-expclr').addEventListener('click',function(){
   state.expect[state.expIdx]=[];resetSince();renderExpbar();renderExpPop();
 });
 $('dlymp-reset').addEventListener('click',function(){
   state.stats={A:{n:0,shan:0,gong:0},B:{n:0,shan:0,gong:0}};
   resetSince();renderStats();toast('统计已重置');
 });
 $('dlymp-hit-ok').addEventListener('click',function(){closePop('dlymp-pop-hit');});
 $('dlymp-white-ok').addEventListener('click',function(){closePop('dlymp-pop-white');});
 /* 连弹中心仪步的「返回」:回上一步重新选密探(重选会重新随机两盘并重置连弹链) */
 $('dlymp-exp-skip').addEventListener('click',function(){
   closePop('dlymp-pop-exp');
   if(chain)openPop('dlymp-pop-role');
 });
 Array.prototype.forEach.call(document.querySelectorAll('#dlymp-expseg button'),function(btn){
   btn.addEventListener('click',function(){
     state.expIdx=parseInt(btn.getAttribute('data-i'),10);
     renderExpPop();
   });
 });
 $('dlymp-entry-random').addEventListener('click',function(){
   if(entryCtx)applyEntry(entryCtx,true);
   closePop('dlymp-pop-entry');chainNext();
 });
 $('dlymp-entry-apply').addEventListener('click',function(){
   if(entryCtx)applyEntry(entryCtx,false);
   closePop('dlymp-pop-entry');chainNext();
 });
 $('dlymp-entry-cancel').addEventListener('click',function(){
   closePop('dlymp-pop-entry');chainNext();
 });

}

/* 测试 API(回归脚本直接调用;核心函数均为无 DOM 依赖的纯函数,renderAll 仅供测试强制重绘) */ window.__dlymp={shuffleBoard:shuffleBoard,genBoard:genBoard,wdraw:wdraw,enumProb:enumProb,lockExp:lockExp,QW:QW,checkHit:checkHit,checkWhiteWash:checkWhiteWash,state:state,tool:DHYMP_TOOL,renderAll:renderAll};

/* 开场:有缓存档直接恢复上次状态(不弹强制选人);无档才走引导连弹(选人 → 心仪 → 盘 1 录入 → 盘 2 录入) */ (function init(){

 bindStatic();
 var restored=loadSave();
 renderAll();
 renderRchips();renderRgrid();
 if(restored){toast('已恢复上次状态');}
 else{
   $('dlymp-role-close').style.display='none';
   openPop('dlymp-pop-role');
 }

})(); })(); </script>