Add two-stage charged-crystal demo and original art set.

This commit is contained in:
2026-08-13 13:18:41 +08:00
commit e9f5f81f46
686 changed files with 25601 additions and 0 deletions
+207
View File
@@ -0,0 +1,207 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="dark">
<title>魔力工坊 · 配方树工作台</title>
<link rel="stylesheet" href="./styles.css?v=20260812-2">
</head>
<body>
<div class="app" id="app" aria-busy="true">
<header class="topbar">
<div class="brand">
<span class="brand-mark" aria-hidden="true"></span>
<div>
<strong>配方树工作台</strong>
<span>魔力工坊 / 策划数据</span>
</div>
</div>
<div class="top-stats" aria-label="数据统计">
<span><b id="statRecipes"></b> 配方</span>
<span><b id="statItems"></b> 物品</span>
<span><b id="statMachines"></b> 设施</span>
</div>
<div class="toolbar" role="toolbar" aria-label="文件和编辑操作">
<span class="save-state loading" id="saveState"><i></i><span>读取中</span></span>
<button class="button ghost" id="undoButton" type="button" title="撤销(Ctrl+Z" disabled>撤销</button>
<button class="button ghost" id="redoButton" type="button" title="重做(Ctrl+Y" disabled>重做</button>
<button class="button ghost" id="importButton" type="button">导入</button>
<button class="button ghost" id="exportButton" type="button">导出</button>
<button class="button issue-button" id="issuesButton" type="button"><span id="issueCount">校验</span></button>
<button class="button primary" id="saveButton" type="button" title="保存到 data/recipe-book.jsonCtrl+S">保存数据</button>
</div>
</header>
<main class="workspace">
<aside class="catalog panel" aria-label="数据目录">
<div class="panel-heading">
<div>
<span class="eyebrow">数据目录</span>
<h1>配方与物料</h1>
</div>
<button class="icon-button" id="addEntityButton" type="button" aria-label="新增当前类型" title="新增当前类型"></button>
</div>
<div class="type-tabs" id="typeTabs" role="tablist" aria-label="数据类型">
<button type="button" role="tab" data-type="recipes" class="active">配方 <span id="tabRecipes">0</span></button>
<button type="button" role="tab" data-type="items">物品 <span id="tabItems">0</span></button>
<button type="button" role="tab" data-type="machines">设施 <span id="tabMachines">0</span></button>
</div>
<label class="search-box">
<span aria-hidden="true"></span>
<input id="catalogSearch" type="search" placeholder="搜索名称、ID 或标签" autocomplete="off">
<kbd>/</kbd>
</label>
<div class="catalog-filters">
<label>
<span>阶段</span>
<select id="stageFilter"><option value="all">全部阶段</option></select>
</label>
<label>
<span>生态区</span>
<select id="biomeFilter"><option value="all">全部生态区</option></select>
</label>
</div>
<div class="catalog-summary" id="catalogSummary">正在整理数据…</div>
<nav class="entity-list" id="entityList" aria-label="实体列表"></nav>
</aside>
<section class="graph-panel panel" aria-label="配方依赖图">
<div class="graph-header">
<div class="graph-title">
<span class="eyebrow">依赖视图</span>
<h2 id="graphTitle">配方树</h2>
<p id="graphSubtitle">选择左侧条目以查看上下游。</p>
</div>
<div class="graph-controls">
<div class="segmented" id="graphMode" aria-label="图谱范围">
<button type="button" data-mode="focus" class="active">聚焦</button>
<button type="button" data-mode="full">全局</button>
</div>
<label class="depth-control" id="depthControl">层级
<select id="graphDepth">
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
</select>
</label>
<button class="button ghost compact" id="fitGraphButton" type="button">适应画布</button>
</div>
</div>
<div class="graph-stage" id="graphStage">
<svg id="recipeGraph" role="img" aria-label="物品与配方依赖关系图">
<defs>
<marker id="arrowOutput" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L8,4 L0,8 Z" fill="#67d8b2"></path>
</marker>
<marker id="arrowInput" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L8,4 L0,8 Z" fill="#8795b5"></path>
</marker>
</defs>
<g id="graphViewport">
<g id="graphBackdrop"></g>
<g id="graphEdges"></g>
<g id="graphNodes"></g>
</g>
</svg>
<div class="graph-empty" id="graphEmpty" hidden>
<span></span>
<strong>没有可显示的节点</strong>
<p>调整筛选条件,或选择其他条目。</p>
</div>
<div class="zoom-tools" aria-label="画布缩放">
<button type="button" id="zoomOutButton" aria-label="缩小"></button>
<output id="zoomOutput">100%</output>
<button type="button" id="zoomInButton" aria-label="放大"></button>
</div>
<div class="graph-legend">
<span><i class="legend-item"></i>物品</span>
<span><i class="legend-recipe"></i>配方</span>
<span><i class="legend-catalyst"></i>催化/状态</span>
</div>
</div>
<footer class="graph-footer">
<div id="routeSummary"></div>
<div class="graph-hint">滚轮缩放 · 拖拽平移 · 单击节点编辑</div>
</footer>
</section>
<aside class="inspector panel" aria-label="属性编辑器">
<div class="panel-heading inspector-heading">
<div>
<span class="eyebrow">属性编辑器</span>
<h2 id="inspectorTitle">选择一个条目</h2>
</div>
<span class="entity-kind" id="inspectorKind"></span>
</div>
<div id="inspectorContent" class="inspector-content">
<div class="empty-inspector">
<span></span>
<p>从左侧目录或中央配方树选择一个条目。</p>
</div>
</div>
</aside>
</main>
</div>
<dialog id="issuesDialog" class="issues-dialog">
<form method="dialog" class="dialog-shell">
<header>
<div>
<span class="eyebrow">实时校验</span>
<h2>数据健康检查</h2>
<p id="issuesSummary"></p>
</div>
<button class="icon-button" value="cancel" aria-label="关闭">×</button>
</header>
<div class="issue-filter" id="issueFilter">
<button type="button" data-severity="all" class="active">全部</button>
<button type="button" data-severity="error">错误</button>
<button type="button" data-severity="warning">警告</button>
<button type="button" data-severity="info">提示</button>
</div>
<div class="issue-list" id="issueList"></div>
<footer>
<span>点击问题可定位到对应条目。</span>
<button class="button primary" value="cancel">完成</button>
</footer>
</form>
</dialog>
<dialog id="helpDialog" class="help-dialog">
<form method="dialog" class="dialog-shell">
<header>
<div><span class="eyebrow">字段速查</span><h2>魔法配方怎么填</h2></div>
<button class="icon-button" value="cancel" aria-label="关闭">×</button>
</header>
<div class="help-content">
<dl>
<dt>消耗</dt><dd>每次制作永久扣除,例如木材、供物。</dd>
<dt>催化</dt><dd>参与法则但不扣除,例如生命锚核、边界石。</dd>
<dt>流体</dt><dd>按配方批次统计的管网输入。</dd>
<dt>状态</dt><dd>物品必须带入某种状态,完成后可由产出表达状态变化。</dd>
<dt>权重</dt><dd>用于传送门结果袋;同一配方所有权重应合计 100。</dd>
<dt>概率</dt><dd>用于独立概率结果;全部产出都是概率项时应合计 1。</dd>
<dt></dt><dd>一次制作给传送门或仪式网络增加的复杂度压力。</dd>
</dl>
</div>
<footer><span>修改会先进入浏览器草稿;“保存数据”才写回项目。</span><button class="button primary" value="cancel">知道了</button></footer>
</form>
</dialog>
<input id="importFile" type="file" accept="application/json,.json" hidden>
<div class="toast-stack" id="toastStack" aria-live="polite"></div>
<script type="module" src="./app.mjs?v=20260812-5"></script>
</body>
</html>