'+DATA.metrics.locatedLocations+'/'+DATA.metrics.locations+' 个地点有坐标;'+DATA.metrics.timedEvents+'/'+DATA.metrics.events+' 件事件进入数值时间轴。
From 9f2cb6ef038d7ab5812bf2d90c7c7b295a919f69 Mon Sep 17 00:00:00 2001 From: CochraneK <48022373+CochraneK@users.noreply.github.com> Date: Mon, 14 Sep 2026 12:11:41 +0800 Subject: [PATCH 01/14] ui: restore classic visual theme --- web/css/theme.css | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/web/css/theme.css b/web/css/theme.css index d6abec9..4983f52 100644 --- a/web/css/theme.css +++ b/web/css/theme.css @@ -1,25 +1,7 @@ -/* ===== Visual polish 2026-09 · Ming digital-humanities skin ===== */ -:root{--paper-deep:#fbf6ea;--ink-soft:#544b43;--radius-lg:14px;--radius-md:10px;--shadow:0 10px 28px rgba(54,42,30,.075);--shadow-hover:0 16px 38px rgba(54,42,30,.12);--focus-ring:0 0 0 3px rgba(184,139,53,.28)} -html{background:#ece5da}body{background:radial-gradient(circle at 12% -8%,rgba(184,139,53,.13),transparent 34rem),radial-gradient(circle at 92% 8%,rgba(141,48,37,.07),transparent 28rem),linear-gradient(180deg,#f5f0e7 0,#eee8de 100%);background-attachment:fixed}::selection{background:#d9bf83;color:#2b251f} -.skip-link{position:fixed;left:16px;top:10px;z-index:100;transform:translateY(-180%);padding:8px 12px;border-radius:8px;background:#fffdf8;color:var(--accent);border:1px solid #cdbd9e;box-shadow:var(--shadow);font-weight:700;text-decoration:none}.skip-link:focus{transform:translateY(0)} -button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,[tabindex]:focus-visible{outline:2px solid #b88b35;outline-offset:2px;box-shadow:var(--focus-ring)} -.app-header{background:linear-gradient(135deg,rgba(37,31,26,.985),rgba(55,45,37,.985));border-bottom-color:#59493b;box-shadow:0 5px 20px rgba(31,24,18,.16)}@supports (backdrop-filter:blur(12px)){.app-header{background:linear-gradient(135deg,rgba(37,31,26,.93),rgba(55,45,37,.93));backdrop-filter:blur(12px) saturate(115%)}} -.header-inner{min-height:64px}.brand{font-family:'Songti SC','STSong','SimSun','Noto Serif CJK SC',serif;letter-spacing:.075em;text-shadow:0 1px 0 rgba(0,0,0,.2)}.header-stat{color:#cfc1ae}.tabs{scrollbar-width:thin;scrollbar-color:#655548 transparent}.tabs button,.subnav button{transition:background .16s ease,border-color .16s ease,color .16s ease,transform .16s ease,box-shadow .16s ease}.tabs button{border-radius:999px;background:rgba(255,255,255,.055);color:#eadfd2}.tabs button:hover{background:rgba(255,255,255,.1);transform:translateY(-1px)}.tabs button.active{background:linear-gradient(180deg,#9b3a2d,#81281f);border-color:#b05244;box-shadow:inset 0 1px 0 rgba(255,255,255,.16),0 5px 14px rgba(80,26,20,.2)} -.shell{max-width:1380px;padding-top:28px}.section-head{margin-bottom:18px}.section-head h2{position:relative;font-family:'Songti SC','STSong','SimSun','Noto Serif CJK SC',serif;font-weight:700;letter-spacing:.055em;color:#302820}.section-head h2::after{content:'';display:block;width:34px;height:2px;margin-top:7px;background:linear-gradient(90deg,var(--accent),var(--gold));border-radius:999px}.section-head p{max-width:78ch;color:#746a61} -.panel{border-color:#ddd3c4;border-radius:var(--radius-lg);box-shadow:var(--shadow)}.hero-copy{position:relative;overflow:hidden;background:radial-gradient(circle at 88% 15%,rgba(184,139,53,.22),transparent 22rem),linear-gradient(135deg,#302821,#45382d);border:1px solid #5a493b;border-radius:var(--radius-lg);box-shadow:0 14px 36px rgba(49,36,25,.14)}.hero-copy::after{content:'';position:absolute;right:-54px;bottom:-76px;width:220px;height:220px;border:1px solid rgba(222,190,121,.14);border-radius:50%;box-shadow:0 0 0 22px rgba(222,190,121,.025),0 0 0 48px rgba(222,190,121,.018);pointer-events:none}.hero-copy h2{font-family:'Songti SC','STSong','SimSun','Noto Serif CJK SC',serif;letter-spacing:.065em} -.metric,.distribution-stat,.location-card,.dynasty-card,.clean-card,.insight-toc-card{transition:transform .16s ease,box-shadow .16s ease,border-color .16s ease}.metric{border-color:#e2d8c8;border-radius:var(--radius-md);box-shadow:0 3px 12px rgba(54,42,30,.035)}.metric:hover,.distribution-stat:hover{transform:translateY(-2px);border-color:#cfbea3;box-shadow:0 10px 22px rgba(54,42,30,.08)}.metric .value,.distribution-stat strong{font-variant-numeric:tabular-nums}.quality-grid .quality{border-radius:0 9px 9px 0;background:linear-gradient(90deg,#fbf6ea,#fffdf8)} -.toolbar input,.toolbar select,.visual-toolbar select,.network-controls select{border-color:#d1c4b2;box-shadow:inset 0 1px 2px rgba(55,43,32,.025);transition:border-color .15s ease,box-shadow .15s ease,background .15s ease}.toolbar input:focus,.toolbar select:focus,.visual-toolbar select:focus,.network-controls select:focus{border-color:#b88b35;background:#fffdf9} -.location-card{border-color:#dfd5c6;border-radius:12px;box-shadow:0 4px 14px rgba(50,40,30,.045)}.location-card:hover{transform:translateY(-2px);border-color:#cdbb9f;box-shadow:var(--shadow-hover)}.card-title{font-family:'Songti SC','STSong','SimSun','Noto Serif CJK SC',serif;letter-spacing:.025em}.tag,.source-chip,.ep-tag{border-radius:999px} -.table-wrap{border-color:#d9cdbc;border-radius:12px;box-shadow:0 6px 18px rgba(54,42,30,.04)}.data-table th{background:linear-gradient(180deg,#faf6ed,#f3ede3);color:#5f5348}.data-table tr:nth-child(even) td{background:rgba(248,244,236,.42)}.data-table tr:hover td{background:#fff8ec} -.map-box,.network-svg,.full-graph-canvas{border-color:#d3c7b7;border-radius:12px;box-shadow:inset 0 0 0 1px rgba(255,255,255,.35)}.loc-dock{border-radius:12px;border-color:#d9cdbc}.character-card{border-radius:12px;box-shadow:0 5px 16px rgba(50,40,30,.07)}.character-card:hover{box-shadow:0 14px 30px rgba(50,40,30,.14)}.dynasty-card{border-radius:12px}.insight-toc,.insight-sec,.insight-refs{box-shadow:0 6px 18px rgba(60,45,25,.04)} -dialog{border:1px solid #cfc2b1;border-radius:14px;box-shadow:0 24px 78px rgba(20,15,10,.34)}dialog::backdrop{background:rgba(27,22,18,.56);backdrop-filter:blur(2px)}.dialog-head{position:sticky;top:-22px;z-index:2;background:var(--paper);padding-top:22px}.dialog-close,.loc-dock .dock-close{transition:background .15s ease,color .15s ease,transform .15s ease}.dialog-close:hover,.loc-dock .dock-close:hover{background:#e7ddcf;color:var(--accent)}.app-footer{text-align:center;padding:4px 24px 30px;font-size:12px;letter-spacing:.02em;color:#81776d} - -/* ===== V2 信息架构:分组导航 + 探索路径 + 可视化统一 ===== */ -.header-inner{display:grid;grid-template-columns:max-content minmax(0,1fr);grid-template-areas:'brand stat' 'tabs tabs';column-gap:18px;row-gap:9px;align-items:center}.brand{grid-area:brand}.header-stat{grid-area:stat;justify-self:end}.tabs{grid-area:tabs;width:100%;margin-left:0;padding:9px 0 1px;border-top:1px solid rgba(238,225,208,.12);gap:10px;align-items:center} -.nav-cluster{display:flex;align-items:center;gap:4px;padding-left:10px;border-left:1px solid rgba(238,225,208,.15);flex:none}.nav-cluster:first-child{padding-left:0;border-left:0}.nav-cluster-label{margin-right:2px;color:#bda990;font-size:9px;line-height:1;letter-spacing:.16em;white-space:nowrap}.nav-cluster button{padding:6px 10px;font-size:12px} -.v2-journeys{margin:0 0 18px}.v2-journey-head{display:flex;justify-content:space-between;align-items:end;gap:14px;margin-bottom:10px}.v2-journey-head h3{margin:0;font-family:'Songti SC','STSong','SimSun','Noto Serif CJK SC',serif;font-size:18px;letter-spacing:.05em;color:#372f28}.v2-journey-head p{margin:0;color:var(--muted);font-size:12px}.v2-journey-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}.v2-journey-card{position:relative;overflow:hidden;background:linear-gradient(145deg,rgba(255,253,248,.96),rgba(247,241,230,.92));border:1px solid #ddd1bf;border-radius:12px;padding:15px 16px;box-shadow:0 6px 18px rgba(54,42,30,.045)}.v2-journey-card::before{content:'';position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--journey,var(--gold))}.v2-journey-card:nth-child(1){--journey:var(--accent)}.v2-journey-card:nth-child(2){--journey:var(--blue)}.v2-journey-card:nth-child(3){--journey:var(--green)}.v2-journey-kicker{display:block;color:var(--journey);font-size:10px;font-weight:700;letter-spacing:.14em}.v2-journey-card h4{margin:4px 0 5px;font-size:16px;color:#3a3129}.v2-journey-card p{margin:0;color:#70665d;font-size:12px;line-height:1.65}.v2-journey-links{display:flex;flex-wrap:wrap;gap:6px;margin-top:11px}.v2-journey-links button{border:1px solid #d5c7b3;background:#fffdf8;color:#645649;border-radius:999px;padding:4px 10px;font-size:11px}.v2-journey-links button:hover{border-color:var(--journey);color:var(--journey);background:#fffaf0} -.visuals-panel,.map-wrap{position:relative;overflow:hidden}.visuals-panel::before,.map-wrap::before{content:'';position:absolute;top:0;left:0;width:92px;height:3px;background:linear-gradient(90deg,var(--accent),var(--gold),transparent);z-index:2}.map-wrap::before{background:linear-gradient(90deg,var(--green),var(--blue),transparent)}.heatmap-wrap,.network-svg,.full-graph-canvas,.map-box{background:linear-gradient(180deg,#fffdf9,#faf6ee)}.timeline{background:linear-gradient(90deg,rgba(255,253,248,.94),rgba(249,244,234,.92));border:1px solid #ded2c1;border-left:3px solid var(--gold);border-radius:0 12px 12px 0;padding:16px 18px 16px 24px;box-shadow:0 6px 18px rgba(54,42,30,.04)}.chronicle-wrap{background:linear-gradient(180deg,rgba(255,253,248,.94),rgba(248,243,233,.9));border:1px solid #ded2c1;border-radius:12px;padding:14px;box-shadow:0 6px 18px rgba(54,42,30,.04)}.dynasty-band{border-radius:9px;overflow:hidden;box-shadow:inset 0 0 0 1px rgba(255,255,255,.3)}.insight-sec{scroll-margin-top:122px} -@media(max-width:900px){.v2-journey-grid{grid-template-columns:1fr}.header-inner{grid-template-columns:1fr;grid-template-areas:'brand' 'stat' 'tabs';row-gap:6px}.header-stat{justify-self:start}.tabs{padding-top:8px}} -@media(max-width:640px){body{background-attachment:scroll}.header-inner{align-items:flex-start}.tabs{scroll-snap-type:x proximity;padding-bottom:4px;gap:8px}.nav-cluster{scroll-snap-align:start}.nav-cluster-label{font-size:8px}.tabs button{flex:0 0 auto;scroll-snap-align:start}.shell{padding-top:20px}.section-head h2::after{margin-top:5px}.panel{border-radius:11px}.metric:hover,.distribution-stat:hover,.location-card:hover{transform:none}.v2-journey-head{align-items:flex-start;flex-direction:column;gap:2px}.v2-journey-card{padding:13px 14px}.timeline{padding:13px 12px 13px 18px}.chronicle-wrap{padding:10px}.insight-sec{scroll-margin-top:142px}} +/* ===== Classic UI compatibility layer ===== + Keep the original pre-V1 visual language. This file now carries only + non-invasive accessibility behavior; app.css remains the visible skin. */ +.skip-link{position:fixed;left:16px;top:10px;z-index:100;transform:translateY(-180%);padding:8px 12px;border-radius:6px;background:#fffdf8;color:var(--accent);border:1px solid #cdbd9e;font-weight:700;text-decoration:none}.skip-link:focus{transform:translateY(0)} +button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible,[tabindex]:focus-visible{outline:2px solid #b88b35;outline-offset:2px} @media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}*,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}} @media print{.skip-link{display:none!important}} From 23e3ff0a266dd1fee9d12feb762e5d847e0ff3af Mon Sep 17 00:00:00 2001 From: CochraneK <48022373+CochraneK@users.noreply.github.com> Date: Mon, 14 Sep 2026 12:11:51 +0800 Subject: [PATCH 02/14] ui: disable visible experience overlays --- web/css/experience.css | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/web/css/experience.css b/web/css/experience.css index a2fd3d1..6d57526 100644 --- a/web/css/experience.css +++ b/web/css/experience.css @@ -1,8 +1,2 @@ -/* ===== V3 product experience components ===== */ -.header-stat{display:flex;align-items:center;justify-content:flex-end;gap:10px;flex-wrap:wrap}.command-trigger,.command-inline{display:inline-flex;align-items:center;gap:7px;border:1px solid rgba(232,216,190,.28);border-radius:999px;background:rgba(255,255,255,.07);color:#f1e6d8;padding:5px 9px;font-size:11px;line-height:1;white-space:nowrap}.command-trigger:hover{background:rgba(255,255,255,.12);border-color:#c5a05f}.command-trigger kbd,.command-inline kbd,.command-foot kbd,.command-input-wrap kbd{font:inherit;font-size:9px;border:1px solid currentColor;border-radius:4px;padding:2px 5px;opacity:.72}.command-inline{background:#3a3129;color:#f7efe2;border-color:#5b4b3d;padding:7px 10px}.command-inline:hover{border-color:var(--gold);color:#fff} -.command-shell[hidden]{display:none}.command-shell{position:fixed;inset:0;z-index:120;display:flex;align-items:flex-start;justify-content:center;padding:10vh 18px 24px;background:rgba(25,20,16,.56);backdrop-filter:blur(6px)}body.command-open{overflow:hidden}.command-panel{width:min(760px,100%);max-height:min(74vh,720px);display:flex;flex-direction:column;overflow:hidden;background:#fffdf8;border:1px solid #cdbfae;border-radius:16px;box-shadow:0 28px 90px rgba(20,15,10,.38)}.command-head{display:flex;justify-content:space-between;gap:16px;align-items:start;padding:16px 18px 10px}.command-head>div{display:flex;flex-direction:column;gap:2px}.command-head strong{font-family:'Songti SC','STSong','SimSun','Noto Serif CJK SC',serif;font-size:19px;color:#302820}.command-head span{font-size:11px;color:var(--muted)}.command-close{border:0;background:#f1ebe2;color:#64594e;border-radius:7px;width:30px;height:30px;font-size:18px;line-height:1}.command-close:hover{background:#e7ddcf;color:var(--accent)}.command-input-wrap{display:flex;align-items:center;gap:9px;margin:0 14px 10px;padding:10px 12px;background:#f8f3ea;border:1px solid #d9cdbc;border-radius:11px}.command-search-icon{font-size:19px;color:var(--accent)}.command-input-wrap input{flex:1;min-width:0;border:0;outline:0;background:transparent;color:var(--ink);font-size:15px}.command-input-wrap kbd{color:#81776d}.command-results{overflow:auto;padding:0 8px 8px}.command-item{width:100%;display:grid;grid-template-columns:54px minmax(0,1fr) 24px;gap:9px;align-items:center;border:0;border-radius:9px;background:transparent;padding:9px 10px;text-align:left;color:var(--ink)}.command-item:hover,.command-item.active{background:#f2ead9}.command-kind{justify-self:start;border-radius:999px;background:#ece5d7;color:#7b6542;padding:2px 7px;font-size:10px}.command-copy{display:flex;flex-direction:column;min-width:0}.command-copy strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}.command-copy small{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--muted);font-size:10px}.command-enter{color:#9a8d80}.command-empty{padding:28px;text-align:center;color:var(--muted);font-size:12px}.command-foot{display:flex;justify-content:space-between;gap:12px;border-top:1px solid #e6ddd0;padding:8px 16px;color:#8a8076;font-size:10px} -.v3-story{margin:0 0 18px}.v3-story-head{display:flex;justify-content:space-between;gap:18px;align-items:start;margin-bottom:14px}.v3-eyebrow{display:block;color:var(--gold);font-size:9px;font-weight:800;letter-spacing:.18em}.v3-story-head h3{margin:3px 0 3px;font-family:'Songti SC','STSong','SimSun','Noto Serif CJK SC',serif;font-size:20px;color:#342c25}.v3-story-head p{margin:0;color:var(--muted);font-size:11px}.v3-story-grid{display:grid;grid-template-columns:1fr 1.15fr;gap:12px}.v3-story-card{background:linear-gradient(145deg,#fffdf9,#f8f2e7);border:1px solid #ded2c0;border-radius:11px;padding:14px 15px}.v3-story-card>strong{display:block;color:#44382e;margin-bottom:9px}.v3-story-card p{margin:8px 0 0;color:var(--muted);font-size:10.5px}.v3-progress-row{display:flex;justify-content:space-between;gap:10px;margin-top:7px;color:#655a50;font-size:11px}.v3-progress-row b{color:var(--accent);font-variant-numeric:tabular-nums}.v3-progress{height:6px;background:#eae1d4;border-radius:999px;overflow:hidden}.v3-progress i{display:block;height:100%;background:linear-gradient(90deg,var(--accent),var(--gold));border-radius:inherit}.v3-signal-list{margin:0;display:grid;grid-template-columns:1fr 1fr;gap:7px 12px}.v3-signal-list div{min-width:0;border-bottom:1px dashed #e5dac9;padding-bottom:6px}.v3-signal-list dt{color:var(--muted);font-size:9px}.v3-signal-list dd{margin:1px 0 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#44382e;font-size:11.5px;font-weight:700}.v3-story-actions{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:12px;color:var(--muted);font-size:10px}.v3-story-actions button{border:1px solid #d7c9b5;border-radius:999px;background:#fffdf8;color:#67584a;padding:4px 9px;font-size:10px}.v3-story-actions button:hover{border-color:var(--gold);color:var(--accent)} -.v3-graph-reader{margin:12px 0;padding:13px 14px;border:1px solid #ded2c1;border-radius:11px;background:linear-gradient(145deg,#fbf7ef,#fffdf9)}.v3-graph-reader-head{display:flex;align-items:start;justify-content:space-between;gap:14px}.v3-graph-reader-head strong{display:block;margin:2px 0;color:#3d332b;font-size:14px}.v3-graph-reader-head p{margin:0;max-width:78ch;color:var(--muted);font-size:10.5px;line-height:1.6}.v3-graph-tools{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:10px}.v3-graph-tools label{display:flex;align-items:center;gap:7px;color:var(--muted);font-size:10px;flex:1;min-width:240px}.v3-graph-tools input{flex:1;min-width:150px;border:1px solid #d2c5b3;border-radius:7px;background:#fff;padding:6px 8px;color:var(--ink)}.v3-graph-status{color:#806f5d;font-size:10px}.v3-hubs{display:flex;align-items:center;gap:6px;flex-wrap:wrap;margin-top:10px}.v3-hubs>span{color:var(--muted);font-size:10px;margin-right:2px}.v3-hubs button{display:inline-flex;align-items:baseline;gap:5px;border:1px solid #d9cdbc;border-radius:999px;background:#fffdf8;color:#584a3d;padding:4px 9px}.v3-hubs button:hover{border-color:var(--accent);color:var(--accent)}.v3-hubs small{color:#9a8c7d;font-size:8px}.v3-graph-explain{display:flex;gap:12px;flex-wrap:wrap;margin-top:10px;padding-top:9px;border-top:1px dashed #ded3c4;color:#766a5f;font-size:9.5px}.v3-graph-explain span{display:inline-flex;align-items:center;gap:4px}.v3-dot{width:8px;height:8px;border-radius:50%;background:var(--accent);display:inline-block}.v3-dot.focus{box-shadow:0 0 0 3px rgba(141,48,37,.16)}.v3-line{width:16px;height:2px;background:var(--blue);display:inline-block} -@media(max-width:900px){.v3-story-grid{grid-template-columns:1fr}.v3-signal-list{grid-template-columns:1fr 1fr}.header-stat{justify-content:flex-start}} -@media(max-width:640px){.command-shell{padding:5vh 8px 10px}.command-panel{max-height:88vh;border-radius:12px}.command-foot{display:none}.command-item{grid-template-columns:48px minmax(0,1fr) 18px}.command-trigger span{display:none}.v3-story-head{flex-direction:column;gap:8px}.v3-signal-list{grid-template-columns:1fr}.v3-graph-reader-head{flex-direction:column}.v3-graph-tools label{min-width:100%;align-items:flex-start;flex-direction:column}.v3-graph-tools input{width:100%}} -@media print{.command-trigger,.command-shell,.command-inline,.v3-graph-reader{display:none!important}} +/* Classic UI mode: no visible V2/V3 product-experience overlays. + The online delivery/search infrastructure remains available underneath. */ From b2be9f3d17b2e539d1e903ea643d0cc2830ec2d5 Mon Sep 17 00:00:00 2001 From: CochraneK <48022373+CochraneK@users.noreply.github.com> Date: Mon, 14 Sep 2026 12:12:04 +0800 Subject: [PATCH 03/14] ui: disable progressive visible UI enhancements --- web/js/experience.js | 200 +------------------------------------------ 1 file changed, 4 insertions(+), 196 deletions(-) diff --git a/web/js/experience.js b/web/js/experience.js index 4ed9fc8..e1ee821 100644 --- a/web/js/experience.js +++ b/web/js/experience.js @@ -1,197 +1,5 @@ -/* ===== V3 产品体验层:全局搜索 / 首页叙事 / 图谱阅读器 ===== - 这是 app.js 之后加载的渐进增强层:只调用现有 DATA / setView / show* / graph helpers, - 不复制业务渲染器。删除本文件后,12 个原视图仍应保持完整可用。 */ -(function(){ -'use strict'; -if(typeof DATA==='undefined'||typeof setView!=='function')return; - -const VIEWS=[ - ['overview','总览','知识库 首页 全局'],['distribution','分布','章节 密度 抽取 诊断'], - ['timeline','时间轴','年份 事件 时间'],['dynasty','帝王','皇帝 年号 在位'],['chronicle','年谱','人物 生平 年代'], - ['characters','人物','角色 人物卡'],['locations','地点','地名 地图 空间'],['events','事件','事件 索引'],['relations','关系','人物关系 网络'], - ['visuals','图谱','网络 热力图 可视化'],['map','地图','圣地巡礼 郑和 航线'],['insight','洞察','跨学科 报告'] -]; -const TYPE_LABEL={view:'视图',person:'人物',place:'地点',event:'事件'}; -const safe=v=>String(v==null?'':v).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); -const norm=v=>String(v==null?'':v).trim().toLowerCase(); -const pct=(a,b)=>b?Math.round(a*100/b):0; - -/* ------------------------------ 全局快捷搜索 ------------------------------ */ -/* V9_SHARDED_CHARACTER_DETAIL_COMMAND_DATA */ -let commandRows=null,commandRowsMode='',commandResults=[],commandActive=0,commandLastFocus=null; -function commandHasFullData(){return typeof window.__MING_ENSURE_FULL_DATA!=='function'||window.__MING_FULL_DATA_READY===true;} -function commandHasSearchIndex(){return window.__MING_SEARCH_INDEX_READY===true&&window.__MING_SEARCH_INDEX__&&Array.isArray(window.__MING_SEARCH_INDEX__.rows);} -function commandMode(){return commandHasFullData()?'full':(commandHasSearchIndex()?'search':'boot');} -function buildCommandRows(){ - const mode=commandMode(); - if(commandRows&&commandRowsMode===mode)return commandRows; - const rows=[]; - VIEWS.forEach(([id,title,keys])=>rows.push({kind:'view',id,title,meta:'切换到 '+title,search:norm(title+' '+keys)})); - if(mode==='full'){ - (DATA.characters||[]).forEach(x=>{ - const aliases=(x.aliases||[]).join(' '),p=x.profile||{}; - rows.push({kind:'person',id:x.name,title:x.name,meta:[x.role,(p.factions||[]).join('、'),x.life].filter(Boolean).join(' · '),search:norm([x.name,aliases,x.role,x.faction,p.raw,(p.factions||[]).join(' ')].join(' ')),raw:x}); - }); - (DATA.locations||[]).forEach(x=>rows.push({kind:'place',id:x.ancient,title:x.ancient,meta:[x.modern,x.region].filter(Boolean).join(' · '),search:norm([x.ancient,x.modern,x.region,(x.altNames||[]).join(' '),(x.mentionedAs||[]).join(' ')].join(' ')),raw:x})); - (DATA.events||[]).forEach(x=>rows.push({kind:'event',id:x.id,title:x.name,meta:[x.year||'年份待考',x.category,x.location].filter(Boolean).join(' · '),search:norm([x.name,x.year,x.category,x.type,x.location,(x.participants||[]).join(' ')].join(' ')),raw:x})); - }else if(mode==='search'){ - (window.__MING_SEARCH_INDEX__.rows||[]).forEach(x=>rows.push({kind:x.kind,id:x.id,title:x.title,meta:x.meta||'',search:norm(x.search||x.title)})); - } - commandRows=rows;commandRowsMode=mode; - return rows; -} -function commandScore(row,q){ - const t=norm(row.title);if(!q)return row.kind==='view'?90:(row.kind==='person'?30:10); - if(t===q)return 140; - if(t.startsWith(q))return 120-Math.min(t.length-q.length,20); - const i=row.search.indexOf(q);return i<0?-1:90-Math.min(i,45); -} -function commandShell(){ - let shell=document.getElementById('commandPalette'); - if(shell)return shell; - shell=document.createElement('div');shell.id='commandPalette';shell.className='command-shell';shell.hidden=true; - shell.innerHTML='
下面是数据覆盖与结构信号,不是人物重要性或历史价值排名。
'+DATA.metrics.locatedLocations+'/'+DATA.metrics.locations+' 个地点有坐标;'+DATA.metrics.timedEvents+'/'+DATA.metrics.events+' 件事件进入数值时间轴。
节点越大,关系度数越高;线条颜色表示关系类别。点击节点后,无关节点自动降到 12% 不透明度,用邻域聚焦降低视觉噪声。