2026-01-17 16:34:39 +08:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
|
<html lang="zh-CN">
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<head>
|
|
|
|
|
|
<meta charset="UTF-8" />
|
|
|
|
|
|
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no" />
|
|
|
|
|
|
<title>小白板</title>
|
|
|
|
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
|
|
|
|
|
|
<style>
|
|
|
|
|
|
*{margin:0;padding:0;box-sizing:border-box}:root{--bg:#FDFDF9;--bg2:#FFFFFF;--bg3:#F0F0EE;--c:#1C1917;--c2:#57534E;--c3:#78716C;--bd:#E5E5E4;--r4:8px;--r6:12px;--r8:16px;--shadow-sm:0 1px 3px rgba(0,0,0,0.1);--shadow:0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06);--shadow-lg:0 20px 25px -5px rgba(0,0,0,0.1),0 10px 10px -5px rgba(0,0,0,0.04)}html,body{width:100%;height:100%;overflow:hidden;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;background:var(--bg);color:var(--c)}.fc,.fcc{display:flex;align-items:center}.fcc{justify-content:center}.g4{gap:4px}.g6{gap:6px}.g10{gap:10px}.g20{gap:20px}.p12{padding:12px}.r6{border-radius:var(--r6)}.bd{border:1px solid var(--bd)}.bg3{background:var(--bg3)}.fs12{font-size:12px}.fw6{font-weight:600}.c2{color:var(--c2)}.usn{user-select:none}.f1{flex:1}.jsb{justify-content:space-between}.mt6{margin-top:6px}.mt8{margin-top:8px}.mt10{margin-top:10px}.mt12{margin-top:12px}.mt16{margin-top:16px}.mb4{margin-bottom:4px}.mb8{margin-bottom:8px}.mb10{margin-bottom:10px}.mb12{margin-bottom:12px}.lh15{line-height:1.5}.lh165{line-height:1.65}.w100{width:100px}.w140{width:140px}.btn{padding:8px 16px;background:var(--bg2);font-size:13px;font-weight:500;cursor:pointer;border:1px solid var(--bd);border-radius:var(--r4);color:var(--c);transition:all .2s;box-shadow:var(--shadow-sm);display:inline-flex;align-items:center;justify-content:center;gap:6px}.btn:hover{background:#fafafa;border-color:#dcdcdc;box-shadow:var(--shadow);transform:translateY(-1px)}.btn:active{transform:translateY(0)}.btn:disabled{opacity:.5;cursor:not-allowed;box-shadow:none;transform:none}.btn-p{background:var(--c);color:#fff;border-color:var(--c)}.btn-p:hover{background:#2a2a28;color:#fff;border-color:#2a2a28}.btn-due{background:#ffe1e1 !important;border-color:#ff9b9b !important;color:#7a1f1f !important}.btn-s{padding:6px 12px;font-size:12px}.btn-c,.btn-add{padding:0;border-radius:50%;flex-shrink:0}.btn-c{width:32px;height:32px;background:var(--bg3);border-color:var(--bd);color:var(--c2)}.btn-c:hover{background:#e7e5e4;color:var(--c)}.btn-add{width:36px;height:36px;background:var(--bg2);color:var(--c);box-shadow:var(--shadow-sm)}.fold{background:var(--bg2);border:1px solid var(--bd);border-radius:var(--r6);margin-bottom:8px;overflow:hidden;box-shadow:var(--shadow-sm);transition:box-shadow .2s}.fold:hover{box-shadow:var(--shadow)}.fold-h{padding:12px 16px;cursor:pointer;display:flex;justify-content:space-between;align-items:center}.fold-a{color:var(--c3);font-size:10px;transition:transform .15s}.fold.exp .fold-a{transform:rotate(180deg)}.fold-b{max-height:0;overflow:hidden;transition:max-height .2s cubic-bezier(0,1,0,1)}.fold.exp .fold-b{max-height:500px;transition:max-height .3s ease-in-out}.side-nav-wrap{position:fixed;left:12px;top:50%;transform:translateY(-50%);z-index:500;display:flex;flex-direction:column;gap:8px}.side-glass{background:rgba(255,255,255,.8);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,0.5);box-shadow:var(--shadow)}.side-nav,.side-menu{display:flex;flex-direction:column;border-radius:24px}.side-nav{gap:6px;padding:8px 6px}.side-menu{position:relative;padding:6px 6px;align-items:center}.side-menu-btn,.nav-i{display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--c3);transition:all .2s}.side-menu-btn{width:32px;height:32px;font-size:12px;border-radius:10px}.nav-i{width:36px;height:36px;border-radius:50%}.nav-i i{font-size:14px}.side-menu-btn:hover,.nav-i:hover{background:var(--bg3);color:var(--c)}.side-menu-btn.act,.nav-i.act{background:var(--c);color:#fff;box-shadow:var(--shadow-sm)}.side-menu-panel{position:absolute;left:100%;top:50%;transform:translateY(-50%);margin-left:12px;display:none;flex-direction:column;gap:6px;padding:8px;background:var(--bg2);border-radius:var(--r6);border:1px solid var(--bd);white-space:nowrap;z-index:600;box-shadow:var(--shadow)}.side-menu-panel.show{display:flex}.side-menu-panel .btn{font-size:11px;padding:6px 12px;width:100%;justify-content:flex-start}.toolbar{height:52px;backg
|
|
|
|
|
|
</style></style>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</head>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<body>
|
|
|
|
|
|
<!-- Side Nav -->
|
|
|
|
|
|
<div class="side-nav-wrap">
|
|
|
|
|
|
<div class="side-menu side-glass">
|
|
|
|
|
|
<div class="side-menu-btn" id="btn-side-menu-toggle" title="快捷操作"><i class="fa-solid fa-ellipsis"></i></div>
|
|
|
|
|
|
<div class="side-menu-panel" id="side-menu-panel">
|
|
|
|
|
|
<button class="btn btn-s fc g4" id="btn-gen-local-map"><i class="fa-solid fa-plus"></i>局部地图</button>
|
|
|
|
|
|
<button class="btn btn-s fc g4" id="btn-simulate"><i class="fa-solid fa-rotate"></i>世界推演</button>
|
|
|
|
|
|
<button class="btn btn-s fc g4" id="btn-gen-local-scene"><i
|
|
|
|
|
|
class="fa-solid fa-feather-pointed"></i>局部剧情</button>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<nav class="side-nav side-glass">
|
|
|
|
|
|
<div class="nav-i" data-p="world"><i class="fa-solid fa-earth-americas"></i></div>
|
|
|
|
|
|
<div class="nav-i act" data-p="map"><i class="fa-solid fa-map"></i></div>
|
|
|
|
|
|
<div class="nav-i" data-p="comm"><i class="fa-solid fa-phone"></i></div>
|
|
|
|
|
|
</nav>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Toolbar -->
|
|
|
|
|
|
<div class="toolbar fc g10 usn">
|
|
|
|
|
|
<div class="toolbar-t">小白板<span>预测试</span></div>
|
|
|
|
|
|
<button class="btn btn-s fc g6" id="btn-deduce"><i class="fa-solid fa-wand-magic-sparkles"></i>生成</button>
|
|
|
|
|
|
<button class="btn btn-s fc g6" id="btn-settings"><i class="fa-solid fa-gear"></i>设置</button>
|
|
|
|
|
|
<button class="btn btn-c fcc" id="btn-close">✕</button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Main -->
|
|
|
|
|
|
<div class="main-wrap">
|
|
|
|
|
|
<!-- World -->
|
|
|
|
|
|
<div class="page page-pad" id="page-world">
|
|
|
|
|
|
<div class="banner">
|
|
|
|
|
|
<img src="https://picsum.photos/800/300" alt="" />
|
|
|
|
|
|
<div class="banner-ov">
|
|
|
|
|
|
<div>探索未知的世界...</div>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
2026-01-31 23:06:03 +08:00
|
|
|
|
|
|
|
|
|
|
<div class="news-sec">
|
|
|
|
|
|
<div class="sec-hd">
|
|
|
|
|
|
<h3 class="sec-t">最新消息</h3>
|
|
|
|
|
|
<button class="btn btn-add fcc" id="btn-refresh-world-news" title="只刷新世界新闻"><i
|
|
|
|
|
|
class="fa-solid fa-rotate"></i></button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div id="news-list"></div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<div class="user-guide" id="user-guide">
|
|
|
|
|
|
<h3 class="sec-t">当前状态</h3>
|
|
|
|
|
|
<div class="user-guide-state" id="ug-state">尚未生成世界数据...</div>
|
|
|
|
|
|
<h3 class="sec-t mt12">行动指南</h3>
|
|
|
|
|
|
<div class="user-guide-actions" id="ug-actions">
|
|
|
|
|
|
<div class="user-guide-action">等待世界生成...</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Map -->
|
|
|
|
|
|
<div class="page act" id="page-map">
|
|
|
|
|
|
<div id="mapWrap">
|
|
|
|
|
|
<div class="map-lbl" id="map-lbl">
|
|
|
|
|
|
<i class="fa-solid fa-map-location-dot"></i>
|
|
|
|
|
|
<span id="map-lbl-t">大地图</span>
|
|
|
|
|
|
<i class="fa-solid fa-chevron-down"></i>
|
|
|
|
|
|
<select id="map-lbl-select" class="map-lbl-sel"></select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="map-act">
|
|
|
|
|
|
<button class="btn btn-s btn-p fc g6" id="btn-goto"><i class="fa-solid fa-location-arrow"></i><span
|
|
|
|
|
|
id="goto-t">前往</span></button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div id="inner"><svg id="lines"></svg></div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<div class="panel" id="zoom-ind">100%</div>
|
|
|
|
|
|
<div class="panel" id="tip">
|
|
|
|
|
|
<div class="desc" id="desc"></div>
|
|
|
|
|
|
<div class="info-w">
|
|
|
|
|
|
<div class="info-h">
|
|
|
|
|
|
<div class="info-t" id="info-t"></div>
|
|
|
|
|
|
<div class="info-bk" id="info-bk">← 返回</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="info-c" id="info-c"></div>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
2026-01-31 23:06:03 +08:00
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Contacts -->
|
|
|
|
|
|
<div class="page page-pad" id="page-comm">
|
|
|
|
|
|
<div class="comm-hd">
|
|
|
|
|
|
<div class="comm-tabs">
|
|
|
|
|
|
<div class="comm-tab act" data-t="stranger">陌路人</div>
|
|
|
|
|
|
<div class="comm-tab" data-t="contact">联络人</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button class="btn btn-add fcc" id="btn-refresh-strangers" title="微信摇一摇,寻找遇过的陌生人"><i
|
|
|
|
|
|
class="fa-solid fa-street-view"></i></button>
|
|
|
|
|
|
<button class="btn btn-add fcc" id="btn-add-ct"><i class="fa-solid fa-plus"></i></button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<div id="sec-stranger" class="comm-sec act"></div>
|
|
|
|
|
|
<div id="sec-contact" class="comm-sec"></div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
2026-01-31 23:06:03 +08:00
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Chat -->
|
|
|
|
|
|
<div class="chat" id="chat">
|
|
|
|
|
|
<div class="chat-hd">
|
|
|
|
|
|
<div class="chat-av" id="chat-av"></div>
|
|
|
|
|
|
<div class="chat-t">
|
|
|
|
|
|
<div class="chat-nm" id="chat-nm"></div>
|
|
|
|
|
|
<div class="chat-st" id="chat-st"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="chat-hd-acts">
|
|
|
|
|
|
<button class="chat-compress" id="chat-compress" title="压缩总结"><i
|
|
|
|
|
|
class="fa-solid fa-compress"></i></button>
|
|
|
|
|
|
<button class="chat-clr" id="chat-clr" title="清空记录"><i class="fa-solid fa-trash"></i></button>
|
|
|
|
|
|
<button class="chat-x" id="chat-x"><i class="fa-solid fa-xmark"></i></button>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<div class="chat-msgs" id="chat-msgs"></div>
|
|
|
|
|
|
<div class="chat-in-w">
|
|
|
|
|
|
<button class="chat-send" id="chat-back" title="回退"><i class="fa-solid fa-rotate-left"></i></button>
|
|
|
|
|
|
<input type="text" class="chat-in" id="chat-in" placeholder="输入消息..." />
|
|
|
|
|
|
<button class="chat-send" id="chat-send"><i class="fa-solid fa-paper-plane"></i></button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Right Panel -->
|
|
|
|
|
|
<div class="side-pop" id="side-pop">
|
|
|
|
|
|
<div class="side-pop-handle" id="side-pop-handle">
|
|
|
|
|
|
<div class="side-pop-bar"></div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<div class="side-pop-ct">
|
|
|
|
|
|
<div class="side-pop-hd fc jsb">
|
|
|
|
|
|
<span>场景描述</span>
|
|
|
|
|
|
<button class="btn btn-s fc g4" id="btn-refresh-local-map"><i
|
|
|
|
|
|
class="fa-solid fa-rotate-right"></i>刷新</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="side-pop-desc" id="side-desc"></div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
2026-01-31 23:06:03 +08:00
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Mobile Bottom Sheet -->
|
|
|
|
|
|
<div class="mob-pop" id="mob-pop">
|
|
|
|
|
|
<div class="pop-h-ind"><span data-l="2"></span><span data-l="1"></span><span data-l="0"></span></div>
|
|
|
|
|
|
<div class="pop-hd" id="pop-hd">
|
|
|
|
|
|
<div class="pop-handle"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="pop-ct">
|
|
|
|
|
|
<div class="pop-desc" id="mob-desc"></div>
|
|
|
|
|
|
<div class="pop-info">
|
|
|
|
|
|
<div class="pop-info-h">
|
|
|
|
|
|
<div class="pop-info-t" id="mob-info-t"></div>
|
|
|
|
|
|
<div class="pop-info-bk" id="mob-info-bk">← 返回</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div id="mob-info-c"></div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
2026-01-31 23:06:03 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Settings Modal (Redesigned) -->
|
|
|
|
|
|
<div class="modal" id="m-settings">
|
|
|
|
|
|
<div class="modal-bd"></div>
|
|
|
|
|
|
<div class="modal-p lg settings-modal">
|
|
|
|
|
|
<div class="modal-hd fc">
|
|
|
|
|
|
<nav class="settings-nav">
|
|
|
|
|
|
<button class="set-nav-item act" onclick="clickTab(this, 'tab-general')"><i
|
|
|
|
|
|
class="fa-solid fa-sliders"></i> <span class="nav-txt">常规</span></button>
|
|
|
|
|
|
<button class="set-nav-item" onclick="clickTab(this, 'tab-conn')"><i class="fa-solid fa-link"></i>
|
|
|
|
|
|
<span class="nav-txt">连接</span></button>
|
|
|
|
|
|
<button class="set-nav-item" onclick="clickTab(this, 'tab-data')"><i
|
|
|
|
|
|
class="fa-solid fa-database"></i> <span class="nav-txt">数据</span></button>
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
<button class="modal-x fcc">✕</button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<div class="settings-body">
|
|
|
|
|
|
<!-- Content -->
|
|
|
|
|
|
<div class="settings-content">
|
|
|
|
|
|
<!-- Tab: General -->
|
|
|
|
|
|
<div class="set-tab-page act" id="tab-general">
|
|
|
|
|
|
<div class="set-group">
|
|
|
|
|
|
<div class="set-group-t">运行模式</div>
|
|
|
|
|
|
<div class="form-g mb4">
|
|
|
|
|
|
<select class="form-in" id="set-mode">
|
|
|
|
|
|
<option value="story">故事模式 (Story Mode)</option>
|
|
|
|
|
|
<option value="assist">辅助模式 (Assist Mode)</option>
|
|
|
|
|
|
</select>
|
|
|
|
|
|
<div class="tips-box"><i class="fa-solid fa-circle-info"></i>
|
|
|
|
|
|
故事模式包含完整的世界模拟;辅助模式仅用于生成辅助地图/剧情。</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="set-group">
|
|
|
|
|
|
<div class="set-group-t">剧情控制</div>
|
|
|
|
|
|
<div class="set-row g20">
|
|
|
|
|
|
<div class="form-g f1">
|
|
|
|
|
|
<label class="form-l">当前阶段 (Stage)</label>
|
|
|
|
|
|
<input type="number" class="form-in" id="set-stage" min="0" max="10" value="0" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="form-g f1">
|
|
|
|
|
|
<label class="form-l">偏离分数 (Deviation)</label>
|
|
|
|
|
|
<input type="number" class="form-in" id="set-deviation" min="0" max="100"
|
|
|
|
|
|
value="0" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="form-g">
|
|
|
|
|
|
<label class="form-l">推演倒计时 (Sim Countdown)</label>
|
|
|
|
|
|
<div class="fc g10">
|
|
|
|
|
|
<input type="number" class="form-in f1" id="set-sim-target" value="5" />
|
|
|
|
|
|
<span class="fs12 c2">行动数</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="set-hint">当数值≤0时提醒进行世界推演。</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="set-group">
|
|
|
|
|
|
<div class="set-group-t">历史记录</div>
|
|
|
|
|
|
<div class="set-test">
|
|
|
|
|
|
<label class="form-l">上下文楼层数</label>
|
|
|
|
|
|
<input type="number" class="form-in w100" id="set-history-count" min="0" max="200"
|
|
|
|
|
|
value="50" />
|
|
|
|
|
|
<label class="fc g4 fs12 c2 usn" style="margin-left:auto">
|
|
|
|
|
|
<input type="checkbox" id="set-use-stream" /> <span style="font-weight:600">启用流式
|
|
|
|
|
|
(Streaming)</span>
|
|
|
|
|
|
</label>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="set-test-res" id="test-res"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Tab: Connection -->
|
|
|
|
|
|
<div class="set-tab-page" id="tab-conn">
|
|
|
|
|
|
<div class="set-group">
|
|
|
|
|
|
<div class="set-group-t">API 设置</div>
|
|
|
|
|
|
<div class="form-g">
|
|
|
|
|
|
<label class="form-l">API 端点 (URL)</label>
|
|
|
|
|
|
<input type="text" class="form-in" id="set-api-url" placeholder="默认使用 SillyTavern 设置" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="form-g">
|
|
|
|
|
|
<label class="form-l">API 密钥 (Key)</label>
|
|
|
|
|
|
<input type="password" class="form-in" id="set-api-key" placeholder="如需覆盖请填写" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="set-group">
|
|
|
|
|
|
<div class="set-group-t">模型选择 (Model)</div>
|
|
|
|
|
|
<div class="set-row g10">
|
|
|
|
|
|
<input type="text" class="form-in f1" id="set-model" placeholder="Model ID" />
|
|
|
|
|
|
<button class="btn btn-s" id="btn-fetch-models">获取列表</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<select class="form-in mt6" id="set-model-list"></select>
|
|
|
|
|
|
<div class="mt10">
|
|
|
|
|
|
<button class="btn btn-s btn-p w100" id="btn-test-conn">测试连接</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Tab: Data -->
|
|
|
|
|
|
<div class="set-tab-page" id="tab-data">
|
|
|
|
|
|
<div class="set-group">
|
|
|
|
|
|
<div class="set-group-t">NPC 生成设置</div>
|
|
|
|
|
|
<div class="set-row g20">
|
|
|
|
|
|
<div class="form-g f1">
|
|
|
|
|
|
<label class="form-l">插入位置</label>
|
|
|
|
|
|
<select class="form-in" id="set-npc-position">
|
|
|
|
|
|
<option value="0">Char 前</option>
|
|
|
|
|
|
<option value="1">Char 后</option>
|
|
|
|
|
|
<option value="2">AN 前</option>
|
|
|
|
|
|
<option value="3">AN 后</option>
|
|
|
|
|
|
<option value="5">EM 前</option>
|
|
|
|
|
|
<option value="6">EM 后</option>
|
|
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="form-g f1">
|
|
|
|
|
|
<label class="form-l">条目顺序</label>
|
|
|
|
|
|
<input type="number" class="form-in" id="set-npc-order" min="0" max="1000"
|
|
|
|
|
|
value="100" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="set-group">
|
|
|
|
|
|
<div class="set-group-t">预设数据 (Presets)</div>
|
|
|
|
|
|
<div class="set-hint mb12">勾选要写入预设的数据块:</div>
|
|
|
|
|
|
<div id="data-list" class="data-grid"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="set-group">
|
|
|
|
|
|
<div class="set-group-t">高级模板</div>
|
|
|
|
|
|
<div class="set-hint mb10">自定义提示词与JSON格式。</div>
|
|
|
|
|
|
<button class="btn btn-s w100" id="btn-adv-prompts"><i class="fa-solid fa-pen"></i>
|
|
|
|
|
|
编辑高级模板</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<div class="modal-ft fc">
|
|
|
|
|
|
<button class="btn btn-s m-cancel">取消</button>
|
|
|
|
|
|
<button class="btn btn-s btn-p" id="set-save">保存设置</button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
2026-01-31 23:06:03 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Advanced Prompts Modal -->
|
|
|
|
|
|
<div class="modal adv-modal" id="m-adv-prompts">
|
|
|
|
|
|
<div class="modal-bd"></div>
|
|
|
|
|
|
<div class="modal-p">
|
|
|
|
|
|
<div class="modal-hd fc">
|
|
|
|
|
|
<h2>高级设置 · 模板编辑</h2><button class="modal-x fcc">✕</button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<div class="adv-layout">
|
|
|
|
|
|
<!-- Sidebar -->
|
|
|
|
|
|
<div class="adv-sidebar">
|
|
|
|
|
|
<div class="form-g">
|
|
|
|
|
|
<label class="form-l">选择模板</label>
|
|
|
|
|
|
<select class="form-in" id="adv-key"></select>
|
|
|
|
|
|
<div class="set-hint mt8">优先级:角色卡 > 原保存 > 默认。</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Main Content -->
|
|
|
|
|
|
<div class="adv-main">
|
|
|
|
|
|
<div class="adv-section">
|
|
|
|
|
|
<div class="adv-h-title">UAUA 提示词 (JS Function String)</div>
|
|
|
|
|
|
<div class="uaua-grid">
|
|
|
|
|
|
<div class="form-g"><label class="form-l">User 1 (u1)</label><textarea class="ed-ta-adv"
|
|
|
|
|
|
id="adv-u1"></textarea></div>
|
|
|
|
|
|
<div class="form-g"><label class="form-l">Assistant 1 (a1)</label><textarea
|
|
|
|
|
|
class="ed-ta-adv" id="adv-a1"></textarea></div>
|
|
|
|
|
|
<div class="form-g"><label class="form-l">User 2 (u2)</label><textarea class="ed-ta-adv"
|
|
|
|
|
|
id="adv-u2"></textarea></div>
|
|
|
|
|
|
<div class="form-g"><label class="form-l">Assistant 2 (a2)</label><textarea
|
|
|
|
|
|
class="ed-ta-adv" id="adv-a2"></textarea></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div class="adv-section" id="adv-json-wrap">
|
|
|
|
|
|
<div class="adv-h-title">JSON Template</div>
|
|
|
|
|
|
<textarea class="ed-ta-adv" id="adv-json" style="min-height:300px;font-size:13px"></textarea>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<div class="modal-ft fc">
|
|
|
|
|
|
<div class="fc g10 f1">
|
|
|
|
|
|
<button class="btn btn-s" id="adv-reset"><i class="fa-solid fa-rotate-left"></i> 重置</button>
|
|
|
|
|
|
<select class="form-in w140" id="adv-scope" title="选择来源">
|
|
|
|
|
|
<option value="character">角色</option>
|
|
|
|
|
|
<option value="global">通用</option>
|
|
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<button class="btn btn-s" id="adv-save-global">通用保存</button>
|
|
|
|
|
|
<button class="btn btn-s btn-p" id="adv-save-char">角色卡保存</button>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Data Edit Modal -->
|
|
|
|
|
|
<div class="modal" id="m-data-edit">
|
|
|
|
|
|
<div class="modal-bd"></div>
|
|
|
|
|
|
<div class="modal-p">
|
|
|
|
|
|
<div class="modal-hd fc">
|
|
|
|
|
|
<h2 id="data-edit-title">编辑数据</h2><button class="modal-x fcc">✕</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-by">
|
|
|
|
|
|
<textarea class="ed-ta" id="data-edit-ta"></textarea>
|
|
|
|
|
|
<pre class="ed-preview" id="data-edit-preview"></pre>
|
|
|
|
|
|
<div class="ed-err" id="data-edit-err"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-ft fc"><button class="btn btn-s m-cancel">取消</button><button class="btn btn-s btn-p"
|
|
|
|
|
|
id="data-edit-save">保存</button></div>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Goto Modal -->
|
|
|
|
|
|
<div class="modal" id="m-goto">
|
|
|
|
|
|
<div class="modal-bd"></div>
|
|
|
|
|
|
<div class="modal-p sm">
|
|
|
|
|
|
<div class="modal-hd fc">
|
|
|
|
|
|
<h2>确认前往</h2><button class="modal-x fcc">✕</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-by">
|
|
|
|
|
|
<div class="goto-d" id="goto-d"></div>
|
|
|
|
|
|
<div class="form-g"><label class="form-l">任务目标(可选)</label><textarea class="form-in form-ta"
|
|
|
|
|
|
id="goto-task" placeholder="描述你要做什么..."></textarea></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-ft fc"><button class="btn btn-s m-cancel">取消</button><button class="btn btn-s btn-p"
|
|
|
|
|
|
id="goto-ok">确认前往</button></div>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Invite Modal -->
|
|
|
|
|
|
<div class="modal" id="m-invite">
|
|
|
|
|
|
<div class="modal-bd"></div>
|
|
|
|
|
|
<div class="modal-p sm">
|
|
|
|
|
|
<div class="modal-hd fc">
|
|
|
|
|
|
<h2>邀请前往</h2><button class="modal-x fcc">✕</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-by">
|
|
|
|
|
|
<div class="goto-d" id="inv-t"></div>
|
|
|
|
|
|
<div class="form-g"><label class="form-l">选择地点</label>
|
|
|
|
|
|
<div class="loc-list" id="loc-list"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-ft fc"><button class="btn btn-s m-cancel">取消</button><button class="btn btn-s btn-p"
|
|
|
|
|
|
id="inv-ok">发送邀请</button></div>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- World Gen Modal -->
|
|
|
|
|
|
<div class="modal" id="m-world-gen">
|
|
|
|
|
|
<div class="modal-bd"></div>
|
|
|
|
|
|
<div class="modal-p">
|
|
|
|
|
|
<div class="modal-hd fc">
|
|
|
|
|
|
<h2>世界生成</h2><button class="modal-x fcc">✕</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-by">
|
|
|
|
|
|
<div class="form-g">
|
|
|
|
|
|
<label class="form-l">玩家特殊需求(可选)</label>
|
|
|
|
|
|
<textarea class="form-in form-ta" id="world-gen-req" rows="4"
|
|
|
|
|
|
placeholder="例如:希望有更多悬疑元素、增加一个神秘组织..."></textarea>
|
|
|
|
|
|
<div class="set-hint">AI 会根据当前世界观和你的需求生成完整的世界数据</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div id="world-gen-status" class="set-hint"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-ft fc"><button class="btn btn-s m-cancel">取消</button><button class="btn btn-s btn-p"
|
|
|
|
|
|
id="world-gen-ok"><i class="fa-solid fa-wand-magic-sparkles"></i> 开始生成</button></div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- World Sim Modal -->
|
|
|
|
|
|
<div class="modal" id="m-world-sim">
|
|
|
|
|
|
<div class="modal-bd"></div>
|
|
|
|
|
|
<div class="modal-p">
|
|
|
|
|
|
<div class="modal-hd fc">
|
|
|
|
|
|
<h2>世界推演</h2><button class="modal-x fcc">✕</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-by">
|
|
|
|
|
|
<div class="form-g">
|
|
|
|
|
|
<div class="set-hint mb12">
|
|
|
|
|
|
<strong>推演模式</strong>:根据玩家行为和时间流逝,演化世界状态。
|
|
|
|
|
|
<ul class="lh15" style="margin:8px 0;padding-left:20px;font-size:12px">
|
|
|
|
|
|
<li>L1/L2 将大幅更新</li>
|
|
|
|
|
|
<li>L3/L4 适度调整</li>
|
|
|
|
|
|
<li>L5 保持不变</li>
|
|
|
|
|
|
<li>Stage 将推进到下一阶段</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="set-hint warn">⚠️ 此操作会覆盖当前世界数据,建议先备份</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div id="world-sim-status" class="set-hint"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-ft fc"><button class="btn btn-s m-cancel">取消</button><button class="btn btn-s btn-p"
|
|
|
|
|
|
id="world-sim-ok"><i class="fa-solid fa-rotate"></i> 开始推演</button></div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Add Contact Modal -->
|
|
|
|
|
|
<div class="modal" id="m-add-ct">
|
|
|
|
|
|
<div class="modal-bd"></div>
|
|
|
|
|
|
<div class="modal-p sm">
|
|
|
|
|
|
<div class="modal-hd fc">
|
|
|
|
|
|
<h2>添加联络人</h2><button class="modal-x fcc">✕</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-by">
|
|
|
|
|
|
<div class="form-g">
|
|
|
|
|
|
<label class="form-l">UID(世界书条目UID)</label>
|
|
|
|
|
|
<div class="set-row">
|
|
|
|
|
|
<input type="text" class="form-in" id="add-uid" placeholder="请输入世界书条目UID" />
|
|
|
|
|
|
<button class="btn btn-s" id="btn-check-uid"><i class="fa-solid fa-search"></i> 检查</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="set-hint">输入角色卡绑定世界书的条目UID</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="form-g" id="name-select-group" style="display:none">
|
|
|
|
|
|
<label class="form-l">选择名字</label>
|
|
|
|
|
|
<select class="form-in" id="add-name">
|
|
|
|
|
|
<option value="">-- 请选择 --</option>
|
|
|
|
|
|
</select>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div id="uid-check-err" class="ed-err"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-ft fc"><button class="btn btn-s m-cancel">取消</button><button class="btn btn-s btn-p"
|
|
|
|
|
|
id="add-ct-ok" disabled>确定</button></div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<!-- Result Modal -->
|
|
|
|
|
|
<div class="modal" id="m-result">
|
|
|
|
|
|
<div class="modal-bd"></div>
|
|
|
|
|
|
<div class="modal-p sm">
|
|
|
|
|
|
<div class="modal-hd fc">
|
|
|
|
|
|
<h2 id="res-title">操作结果</h2><button class="modal-x fcc">✕</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-by">
|
|
|
|
|
|
<div id="res-msg"></div>
|
|
|
|
|
|
<div id="res-record-box">
|
|
|
|
|
|
<div class="set-hint mb4">详细记录:</div>
|
|
|
|
|
|
<pre id="res-record"></pre>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="modal-ft fc">
|
|
|
|
|
|
<button class="btn btn-s" id="res-action"></button>
|
|
|
|
|
|
<button class="btn btn-s btn-p m-cancel">确定</button>
|
|
|
|
|
|
</div>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
2026-01-31 23:06:03 +08:00
|
|
|
|
<script>
|
|
|
|
|
|
const D={stage:0,deviationScore:0,simulationTarget:5,meta:{truth:null,onion_layers:null,timeline:null,user_guide:null},world:{},maps:{outdoor:{nodes:[]},indoor:null},sceneSetup:null,contacts:{strangers:[],contacts:[{name:"{{characterName}}",avatar:"",color:"#555",location:"在线",info:"角色卡联络人",online:!0,worldbookUid:"__CHARACTER_CARD__",messages:[],summarizedCount:0}]}};let charSmsHistory={messages:[],summarizedCount:0,summaries:{}};const $=t=>document.getElementById(t),$$=t=>document.querySelectorAll(t),isMob=()=>innerWidth<=550,escHtml=t=>t.replace(/[&<>"']/g,(t=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[t]))),h=t=>escHtml(String(t??"")),stripXml=t=>t?t.replace(/<(\w+)[^>]*>[\s\S]*?<\/\1>/g,"").replace(/<[^>]+\/?>/g,"").trim():"",parseLinks=t=>h(t).replace(/\*\*([^*]+)\*\*/g,'<span class="loc-lk" data-loc="$1">$1</span>'),PARENT_ORIGIN=(()=>{try{return new URL(document.referrer).origin}catch{return window.location.origin}})(),post=(t,e={})=>parent.postMessage({source:"LittleWhiteBox-OutlineFrame",type:t,...e},PARENT_ORIGIN),syncSimDueUI=()=>{const t=(Number(D.simulationTarget)||0)<=0;$("btn-simulate")?.classList.toggle("btn-due",t),$("world-sim-ok")?.classList.toggle("btn-due",t)},BtnState={load:(t,e)=>{t.disabled=!0,t._o=t.innerHTML,t.innerHTML=`<i class="fa-solid fa-spinner fa-spin"></i> ${e}`},reset:(t,e)=>{t.disabled=!1,t.innerHTML=e||t._o}},Req={_p:{},_id:0,create(t){const e=t+"_"+ ++this._id;return this._p[t]={id:e},e},get(t){return this._p[t]},match(t){const e=t?.split("_")[0];return this._p[e]?.id===t?this._p[e]:null},set(t,e){Object.assign(this._p[t]||{},e)},clear(t){delete this._p[t]}},openM=t=>$(t).classList.add("act"),closeM=t=>$(t).classList.remove("act"),dirMap={north:[0,-1],south:[0,1],east:[1,0],west:[-1,0],northeast:[1,-1],northwest:[-1,-1],southeast:[1,1],southwest:[-1,1]};let playerLocation="未知",curNode=null,drag=!1,scale=1,offX=0,offY=0,seed=123456789,nodes=[],lines=[],anim=!1,chatTgt=null,invTgt=null,selLoc=null,smsGen=!1,selectedMapValue="current";const inner=$("inner"),svg=$("lines"),mapWrap=$("mapWrap"),popup=$("mob-pop"),chat=$("chat"),sidePop=$("side-pop"),rand=()=>(seed=(9301*seed+49297)%233280)/233280,getCurInside=()=>D.maps?.indoor?.[playerLocation]||null,snaps=()=>[$("pop-hd")?.offsetHeight||0,.3*innerHeight,.65*innerHeight];let popH=0,popDrag=!1,popSY=0,popSH=0,popLv=1;const inds=popup.querySelectorAll(".pop-h-ind span"),setPopH=t=>{const e=snaps();popH=Math.max(e[0],Math.min(.85*innerHeight,t)),popup.style.height=popH+"px",popLv=e.map(((t,e)=>[e,Math.abs(popH-t)])).sort(((t,e)=>t[1]-e[1]))[0][0],inds.forEach(((t,e)=>t.classList.toggle("act",e===popLv)))},snapTo=t=>{popLv=Math.max(0,Math.min(2,t)),setPopH(snaps()[popLv])},openPop=(t=1)=>{popup.classList.add("act"),snapTo(t)};$("side-pop-handle").onclick=()=>sidePop.classList.toggle("act"),$("pop-hd").onmousedown=t=>{popDrag=!0,popSY=t.clientY,popSH=popH||snaps()[1],popup.classList.add("drag"),t.preventDefault()},$("pop-hd").ontouchstart=t=>{t.preventDefault(),popDrag=!0,popSY=t.touches[0].clientY,popSH=popH||snaps()[1],popup.classList.add("drag")},document.onmousemove=t=>{popDrag&&setPopH(popSH+popSY-t.clientY)},document.ontouchmove=t=>{popDrag&&t.touches.length&&(t.preventDefault(),setPopH(popSH+popSY-t.touches[0].clientY))};const endDrag=()=>{popDrag&&(popDrag=!1,popup.classList.remove("drag"),snapTo(popLv))};document.onmouseup=endDrag,document.ontouchend=endDrag,document.ontouchcancel=endDrag;const bindLinks=t=>t.querySelectorAll(".loc-lk").forEach((t=>t.onclick=e=>{e.stopPropagation();const s=t.dataset.loc,o=nodes.find((t=>t.name===s));if(o)return panTo(o),void showInfo(o);const a=getCurInside(),n=a?.nodes?.find((t=>t.name===s));n&&($("info-t").textContent=n.name,$("info-c").textContent=n.info||"暂无信息...",$("tip").classList.add("show"),$("btn-goto").classList.remove("show"),isMob()&&($("mob-info-t").textContent=n.name,$("mob-info-c").textContent=n.info||"暂无信息...",popup.classList.contains("act")||openPop(1)))})),bindFold=t=>t.querySelector(".fold-h").onclick=()=>t.classList.toggle("e
|
|
|
|
|
|
</script></script>
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</body>
|
2026-01-31 23:06:03 +08:00
|
|
|
|
|
2026-01-17 16:34:39 +08:00
|
|
|
|
</html>
|