Initial commit with CC BY-NC-ND 4.0 license

This commit is contained in:
2026-02-13 09:59:19 +08:00
commit 2c31e1cbc8
140 changed files with 44625 additions and 0 deletions

View File

@@ -0,0 +1,428 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Amily2 表格编辑器</title>
<link rel="stylesheet" href="table.css">
<style>
.worldbook-selection-container {
display: flex;
gap: 15px;
margin-top: 10px;
}
.worldbook-column {
flex: 1;
display: flex;
flex-direction: column;
min-width: 0; /* Prevents flex items from overflowing */
}
.scrollable-container {
border: 1px solid var(--input-border-color, #444);
border-radius: 5px;
padding: 10px;
height: 150px;
overflow-y: auto;
background-color: var(--input-bg-color, #222);
margin-top: 5px;
margin-bottom: 5px;
}
.scrollable-container .checkbox-item {
display: flex;
align-items: center;
margin-bottom: 5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.scrollable-container .checkbox-item input[type="checkbox"] {
margin-right: 8px;
flex-shrink: 0;
}
.scrollable-container .checkbox-item label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
select.text_pole {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
background-image: url("data:image/svg+xml;utf8,<svg fill='white' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path d='M7 10l5 5 5-5z'/><path d='M0 0h24v24H0z' fill='none'/></svg>");
background-repeat: no-repeat;
background-position: right 8px center;
background-size: 1.2em;
padding-right: 2em !important;
border-radius: 5px;
}
</style>
</head>
<body>
<div class="amily2-header">
<div class="additional-features-title">
<i class="fas fa-table"></i> 内存储司 · 表格核心
</div>
<button id="amily2_back_to_main_from_forms" class="menu_button secondary small_button interactable">
返回主殿 <i class="fas fa-arrow-right"></i>
</button>
</div>
<hr class="header-divider" style="margin-top: 5px; margin-bottom: 10px;">
<div id="upper-controls-wrapper">
<fieldset class="settings-group" style="padding: 10px; margin-bottom: 10px;">
<legend><i class="fas fa-brain"></i> 中枢决策室</legend>
<div class="sinan-navigation-deck" style="gap: 5px; margin-bottom: 10px;">
<button class="sinan-nav-item active" data-tab="injection-settings"><i class="fas fa-cogs"></i> 注入设置</button>
<button class="sinan-nav-item" data-tab="action-center"><i class="fas fa-toolbox"></i> 操作中心</button>
<button class="sinan-nav-item" data-tab="ai-template"><i class="fas fa-robot"></i> 指令模板</button>
<button class="sinan-nav-item" data-tab="world-settings"><i class="fas fa-globe"></i> 世界读取</button>
</div>
<div class="sinan-content-wrapper">
<div id="sinan-injection-settings-tab" class="sinan-tab-pane active">
<div class="inline-settings-grid">
<label for="table-injection-position">注入位置</label>
<select id="table-injection-position" class="text_pole">
<option value="2">主提示前</option>
<option value="0">主提示后</option>
<option value="1">聊天内</option>
</select>
<label for="table-injection-depth">注入深度</label>
<input type="number" id="table-injection-depth" class="text_pole" value="3">
<label>注入角色</label>
<div class="radio-group">
<input type="radio" id="table-role-system" name="table-injection-role" value="0" data-setting-key="injection.role" data-type="integer">
<label for="table-role-system">系统</label>
<input type="radio" id="table-role-user" name="table-injection-role" value="1" data-setting-key="injection.role" data-type="integer">
<label for="table-role-user">用户</label>
<input type="radio" id="table-role-ai" name="table-injection-role" value="2" data-setting-key="injection.role" data-type="integer">
<label for="table-role-ai">AI</label>
</div>
<label for="batch-filling-threshold">批处理阈值</label>
<input type="number" id="batch-filling-threshold" class="text_pole" value="30">
</div>
<div class="control-block-with-switch" style="margin-top: 10px;">
<label for="show-table-in-chat-toggle">聊天内显示表格</label>
<label class="toggle-switch">
<input type="checkbox" id="show-table-in-chat-toggle" data-setting-key="show_table_in_chat" data-type="boolean">
<span class="slider"></span>
</label>
</div>
<div class="control-block-with-switch" style="margin-top: 10px;">
<label for="render-on-every-message-toggle">持续渲染最新消息</label>
<label class="toggle-switch">
<input type="checkbox" id="render-on-every-message-toggle" data-setting-key="render_on_every_message" data-type="boolean">
<span class="slider"></span>
</label>
</div>
</div>
<div id="sinan-world-settings-tab" class="sinan-tab-pane">
<div class="amily2_opt_settings_block">
<label for="table_worldbook_enabled">启用世界书</label>
<label class="toggle-switch">
<input id="table_worldbook_enabled" type="checkbox" />
<span class="slider"></span>
</label>
</div>
<div class="amily2_opt_settings_block">
<label for="table_worldbook_char_limit">世界书最大字符数: <span id="table_worldbook_char_limit_value">60000</span></label>
<input type="range" id="table_worldbook_char_limit" min="1000" max="200000" step="1000" value="60000">
</div>
<hr>
<div class="amily2_opt_settings_block_radio">
<label>世界书来源</label>
<div class="amily2_opt_radio_group">
<input type="radio" id="table_worldbook_source_character" name="table_worldbook_source" value="character" checked>
<label for="table_worldbook_source_character">角色卡主世界书</label>
<input type="radio" id="table_worldbook_source_manual" name="table_worldbook_source" value="manual">
<label for="table_worldbook_source_manual">手动选择世界书</label>
</div>
</div>
<div id="table_worldbook_select_wrapper" style="display: none;">
<div class="worldbook-selection-container">
<!-- World Book List Column -->
<div class="worldbook-column">
<div class="amily2_opt_label_with_button_wrapper">
<label>选择世界书 (可多选)</label>
<button id="table_refresh_worldbooks" class="menu_button" title="刷新世界书列表"><i class="fa-solid fa-sync"></i></button>
</div>
<div class="table-search-wrapper">
<input type="text" id="table_worldbook_search" class="table-search-input" placeholder="搜索世界书名称...">
<i class="fas fa-search table-search-icon"></i>
</div>
<div id="table_worldbook_checkbox_list" class="scrollable-container">
<!-- 世界书勾选框将在这里动态生成 -->
</div>
<small class="notes">勾选需要启用的世界书。</small>
</div>
</div>
</div>
<!-- World Book Entry List Column -->
<div class="worldbook-column" style="margin-top: 10px;">
<label>选择条目 (可多选)</label>
<div class="table-search-wrapper">
<input type="text" id="table_entry_search" class="table-search-input" placeholder="搜索条目名称、关键词...">
<i class="fas fa-search table-search-icon"></i>
</div>
<div id="table_worldbook_entry_list" class="scrollable-container">
<!-- 世界书条目勾选框将在这里动态生成 -->
</div>
<small class="notes">勾选需要注入的条目。</small>
</div>
</div>
<div id="sinan-action-center-tab" class="sinan-tab-pane">
<div class="control-block-with-switch" style="margin-bottom: 15px; padding: 8px; border: 2px solid #4a9eff; border-radius: 5px; background: rgba(74, 158, 255, 0.1);">
<label for="table-system-master-switch" style="font-weight: bold; color: #4a9eff;">
<i class="fas fa-power-off"></i> 表格系统总开关
</label>
<label class="toggle-switch">
<input type="checkbox" id="table-system-master-switch" data-setting-key="table_system_enabled" data-type="boolean">
<span class="slider"></span>
</label>
</div>
<div class="control-block-with-switch" style="margin-bottom: 10px;">
<label for="table-injection-enabled-toggle">启用表格注入</label>
<label class="toggle-switch">
<input type="checkbox" id="table-injection-enabled" data-setting-key="table_injection_enabled" data-type="boolean">
<span class="slider"></span>
</label>
</div>
<div class="control-block-with-switch" style="margin-bottom: 10px;">
<label for="context-optimization-enabled-toggle">启用上下文优化 (合并世界书)</label>
<label class="toggle-switch">
<input type="checkbox" id="context-optimization-enabled" data-setting-key="context_optimization_enabled" data-type="boolean">
<span class="slider"></span>
</label>
</div>
<div class="control-block-with-switch" style="margin-bottom: 10px;">
<label>填表模式</label>
<div class="radio-group">
<input type="radio" id="main-api-mode" name="filling-mode" value="main-api" checked>
<label for="main-api-mode">原始</label>
<input type="radio" id="secondary-api-mode" name="filling-mode" value="secondary-api">
<label for="secondary-api-mode">分步</label>
<input type="radio" id="optimized-mode" name="filling-mode" value="optimized">
<label for="optimized-mode">兼容优化</label>
</div>
</div>
<!-- 分步填表高级控制 - 仅在分步模式下显示 -->
<div id="secondary-filler-controls" style="display: none; border-left: 2px solid #4a9eff; padding-left: 10px; margin-bottom: 10px;">
<!-- 上下文深度 -->
<div class="control-block-with-switch" style="margin-bottom: 10px; flex-direction: column; align-items: flex-start;">
<label for="secondary-filler-context">上下文深度</label>
<input type="number" id="secondary-filler-context" min="0" max="20" step="1" value="2" class="text_pole" style="width: 80px; margin-top: 5px;">
<small class="notes" style="margin-top: 5px; display: block;">填表时参考的历史上下文消息数量。</small>
</div>
<!-- 填表批次 -->
<div class="control-block-with-switch" style="margin-bottom: 10px; flex-direction: column; align-items: flex-start;">
<label for="secondary-filler-batch">填表批次 (Batch)</label>
<input type="number" id="secondary-filler-batch" min="0" max="20" step="1" value="0" class="text_pole" style="width: 80px; margin-top: 5px;">
<small class="notes" style="margin-top: 5px; display: block;">单次填表处理的消息数量 (0 = 实时单条模式)。</small>
</div>
<!-- 保留楼层 -->
<div class="control-block-with-switch" style="margin-bottom: 10px; flex-direction: column; align-items: flex-start;">
<label for="secondary-filler-buffer">保留楼层 (Buffer)</label>
<input type="number" id="secondary-filler-buffer" min="0" max="10" step="1" value="0" class="text_pole" style="width: 80px; margin-top: 5px;">
<small class="notes" style="margin-top: 5px; display: block;">始终保留不填表的最新消息数量 (缓冲防抖)。</small>
</div>
</div>
<div id="table-independent-rules-container" class="control-block-with-switch" style="margin-bottom: 10px; display: none; flex-direction: column; align-items: flex-start; gap: 8px;">
<div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
<label for="table-independent-rules-enabled">启用独立提取规则</label>
<label class="toggle-switch">
<input type="checkbox" id="table-independent-rules-enabled">
<span class="slider"></span>
</label>
</div>
<button id="table-configure-rules-btn" class="menu_button small_button" style="display: none;"><i class="fas fa-cog"></i> 配置规则</button>
<small class="notes">启用后,分步填表和批量填表将使用下方配置的专属规则,而非微言录的规则。</small>
</div>
<div class="action-center-buttons" style="gap: 8px;">
<button id="amily2-open-relationship-graph-btn" class="menu_button accent small_button interactable"><i class="fas fa-project-diagram"></i> 关系图谱</button>
<button id="amily2-export-preset-btn" class="menu_button primary small_button interactable"><i class="fas fa-file-export"></i> 导出预设</button>
<button id="amily2-export-preset-full-btn" class="menu_button primary small_button interactable"><i class="fas fa-file-archive"></i> 导出备份</button>
<button id="amily2-import-preset-btn" class="menu_button secondary small_button interactable"><i class="fas fa-file-upload"></i> 导入预设</button>
<button id="amily2-import-global-preset-btn" class="menu_button secondary small_button interactable"><i class="fas fa-globe"></i> 导入全局</button>
<button id="amily2-clear-global-preset-btn" class="menu_button danger small_button interactable"><i class="fas fa-undo"></i> 清除全局</button>
<button id="amily2-clear-all-tables-btn" class="menu_button danger small_button interactable"><i class="fas fa-trash-alt"></i> 清空内容</button>
</div>
<p class="notes" style="margin-top: 8px; margin-bottom: 10px;">说明:可以导出不含剧情的"纯净预设"用于分享,或导出包含剧情的"完整备份"用于存档。</p>
<hr class="section-divider" style="margin: 10px 0;">
<!-- 历史记录清理区域 -->
<fieldset class="settings-group" style="border-style: dashed; padding: 8px; margin-bottom: 10px;">
<legend><i class="fas fa-trash-alt"></i> 历史记录清理</legend>
<div class="control-block-with-switch" style="margin-bottom: 10px; flex-direction: column; align-items: flex-start;">
<label for="clear-records-before-floor">清除此楼层前的表格记录</label>
<div style="display: flex; gap: 10px; align-items: center; width: 100%; margin-top: 5px;">
<input type="number" id="clear-records-before-floor" class="text_pole" style="flex: 1;" placeholder="输入楼层号 (例如: 100)">
<button id="clear-records-btn" class="menu_button danger small_button interactable">
<i class="fas fa-eraser"></i> 一键清除
</button>
</div>
<small class="notes" style="margin-top: 5px; display: block;">
警告:此操作将永久删除指定楼层之前所有消息中存储的表格快照。这可以显著减小聊天记录文件的大小,但会导致无法回退到这些楼层的表格状态。当前最新的表格状态不会受影响。
</small>
</div>
</fieldset>
<hr class="section-divider" style="margin: 10px 0;">
<!-- Nccs API 控制区域 -->
<fieldset class="settings-group" style="border-style: dashed; padding: 8px; margin-bottom: 10px;">
<legend><i class="fas fa-brain"></i> Nccs API 系统</legend>
<div class="control-block-with-switch" style="margin-bottom: 10px;">
<label for="nccs-api-enabled">启用 Nccs API</label>
<label class="toggle-switch">
<input type="checkbox" id="nccs-api-enabled" data-setting-key="nccsEnabled" data-type="boolean">
<span class="slider"></span>
</label>
</div>
<div id="nccs-api-config" style="display: none;">
<div class="amily2_opt_settings_block" style="margin-bottom: 10px;">
<label for="nccs-api-mode">API 模式</label>
<select id="nccs-api-mode" class="text_pole">
<option value="openai_test">全兼容模式</option>
<option value="sillytavern_preset">SillyTavern预设模式</option>
</select>
</div>
<div class="amily2_opt_settings_block" style="margin-bottom: 10px;">
<label for="nccs-api-url">API URL</label>
<input type="text" id="nccs-api-url" class="text_pole" placeholder="https://api.openai.com/v1">
</div>
<div class="amily2_opt_settings_block" style="margin-bottom: 10px;">
<label for="nccs-api-key">API Key</label>
<input type="password" id="nccs-api-key" class="text_pole" placeholder="输入您的API密钥">
</div>
<div class="amily2_opt_settings_block" style="margin-bottom: 10px;">
<label for="nccs-api-model">模型</label>
<div style="display: flex; gap: 5px; align-items: center;">
<input type="text" id="nccs-api-model" class="text_pole" placeholder="选择或输入模型">
</div>
</div>
<div class="amily2_opt_settings_block" style="margin-bottom: 10px;">
<label for="nccs-max-tokens">最大Token数: <span id="nccs-max-tokens-value">2000</span></label>
<input type="range" id="nccs-max-tokens" min="100" max="100000" step="100" value="2000">
</div>
<div class="amily2_opt_settings_block" style="margin-bottom: 10px;">
<label for="nccs-temperature">Temperature: <span id="nccs-temperature-value">0.7</span></label>
<input type="range" id="nccs-temperature" min="0" max="2" step="0.1" value="0.7">
</div>
<div class="amily2_opt_settings_block" style="margin-bottom: 10px;">
<label for="nccs-sillytavern-preset">SillyTavern 预设</label>
<select id="nccs-sillytavern-preset" class="text_pole">
<option value="">选择预设</option>
</select>
</div>
<div class="nccs-button-row" style="display: flex; gap: 10px; justify-content: center; margin-top: 15px;">
<button id="nccs-test-connection" class="menu_button primary small_button interactable">
<i class="fas fa-plug"></i> 测试连接
</button>
<button id="nccs-fetch-models" class="menu_button secondary small_button interactable">
<i class="fas fa-download"></i> 获取模型
</button>
</div>
</div>
</fieldset>
<hr class="section-divider" style="margin: 10px 0;">
<div class="action-center-buttons" id="theme-action-buttons" style="gap: 8px;">
<button id="amily2-import-theme-btn" class="menu_button small_button interactable"><i class="fas fa-palette"></i> 导入主题</button>
<button id="amily2-export-theme-btn" class="menu_button small_button interactable"><i class="fas fa-paint-brush"></i> 导出主题</button>
<button id="amily2-reset-theme-btn" class="menu_button small_button interactable"><i class="fas fa-undo"></i> 恢复默认</button>
</div>
<p class="notes" style="margin-top: 8px;">说明导入下载的主题JSON文件或将当前的外观导出分享。</p>
</div>
<div id="sinan-ai-template-tab" class="sinan-tab-pane">
<fieldset class="settings-group" style="border-style: dashed; padding: 8px; margin-bottom: 10px;">
<legend><i class="fas fa-scroll"></i> 规则提示词</legend>
<div class="amily2_settings_block prompt-editor-area">
<textarea id="ai-rule-template-editor" class="text_pole" rows="2"></textarea>
<div class="editor-buttons-panel">
<button id="ai-rule-template-save-btn" class="menu_button accent small_button interactable"><i class="fas fa-save"></i> 保存</button>
<button id="ai-rule-template-restore-btn" class="menu_button secondary small_button interactable"><i class="fas fa-undo"></i> 默认</button>
</div>
</div>
</fieldset>
<fieldset class="settings-group" style="border-style: dashed; padding: 8px;">
<legend><i class="fas fa-tasks"></i> 流程提示词</legend>
<div class="amily2_settings_block prompt-editor-area">
<textarea id="ai-flow-template-editor" class="text_pole" rows="2"></textarea>
<div class="editor-buttons-panel">
<button id="ai-flow-template-save-btn" class="menu_button accent small_button interactable"><i class="fas fa-save"></i> 保存</button>
<button id="ai-flow-template-restore-btn" class="menu_button secondary small_button interactable"><i class="fas fa-undo"></i> 默认</button>
</div>
</div>
</fieldset>
<hr class="section-divider" style="margin: 10px 0;">
<div id="table-filling-controls" style="display: flex; flex-direction: column; gap: 10px; align-items: center;">
<!-- 楼层选择区域 -->
<div style="display: flex; gap: 10px; align-items: center; justify-content: center;">
<label for="floor-start-input" style="font-size: 12px; white-space: nowrap;">起始楼层:</label>
<input type="number" id="floor-start-input" class="text_pole" style="width: 80px;" placeholder="1" min="1">
<label for="floor-end-input" style="font-size: 12px; white-space: nowrap;">结束楼层:</label>
<input type="number" id="floor-end-input" class="text_pole" style="width: 80px;" placeholder="10" min="1">
</div>
<!-- 填表按钮区域 -->
<div style="display: flex; gap: 10px; align-items: center; justify-content: center; flex-wrap: wrap;">
<button id="fill-table-now-btn" class="menu_button small_button">立即填表</button>
<button id="fill-selected-floors-btn" class="menu_button accent small_button">选定楼层填表</button>
<button id="fill-current-floor-btn" class="menu_button secondary small_button">填当前楼层</button>
<button id="rollback-and-refill-btn" class="menu_button secondary small_button">回退重填</button>
<button id="reorganize-table-btn" class="menu_button warning small_button">重新整理</button>
</div>
</div>
</div>
</div>
</fieldset>
<div id="table-log-display" class="hly-log-display" style="margin-top: 10px; margin-bottom: 10px;">
</div>
</div>
<div id="all-tables-container" class="hly-scroll">
<div id="add-table-placeholder" title="敕令新表">
<i class="fas fa-plus"></i>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,900 @@
:root {
--amily2-bg-color: #2C2C2C;
--amily2-button-color: #4A4A4A;
--amily2-text-color: #E0E0E0;
/* Global Table Variables */
--am2-gap-main: 10px;
--am2-padding-main: 8px 5px;
--am2-container-bg: rgba(0, 0, 0, 0.2);
--am2-container-border: 1px solid rgba(255, 255, 255, 0.2);
--am2-container-border-radius: 12px;
--am2-container-padding: 10px 5px;
--am2-container-shadow: inset 0 0 15px rgba(0,0,0,0.2);
--am2-title-font-size: 1.1em;
--am2-title-font-weight: bold;
--am2-title-text-shadow: 0 0 5px rgba(200, 200, 255, 0.3);
--am2-title-gradient-start: #c0bde4;
--am2-title-gradient-end: #dfdff0;
--am2-title-icon-color: #9e8aff;
--am2-title-icon-margin: 10px;
--am2-table-bg: rgba(40, 40, 45, 0.8);
--am2-table-border: 1px solid rgba(255, 255, 255, 0.15);
--am2-table-cell-padding: 4px 6px;
--am2-header-bg: rgba(255, 255, 255, 0.1);
--am2-header-color: #ececec;
--am2-row-even-bg: rgba(0, 0, 0, 0.15);
--am2-row-hover-bg: rgba(255, 255, 255, 0.1);
--am2-header-editable-bg: rgba(172, 216, 255, 0.1);
--am2-header-editable-focus-bg: rgba(172, 216, 255, 0.25);
--am2-header-editable-focus-outline: 1px solid #79b8ff;
--am2-cell-editable-bg: rgba(255, 255, 172, 0.1);
--am2-cell-editable-focus-bg: rgba(255, 255, 172, 0.25);
--am2-cell-editable-focus-outline: 1px solid #ffc107;
--am2-index-col-bg: rgba(0, 0, 0, 0.2);
--am2-index-col-color: #9e8aff;
--am2-index-col-width: 40px;
--am2-index-col-padding: 4px 5px;
--am2-controls-gap: 5px;
--am2-controls-margin-bottom: 10px;
--am2-cell-highlight-bg: rgba(144, 238, 144, 0.3);
}
#amily2_memorisation_forms_panel {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
gap: var(--am2-gap-main);
padding: var(--am2-padding-main);
box-sizing: border-box;
min-width: 0;
}
#upper-controls-wrapper {
}
#amily2_memorisation_forms_panel #all-tables-container {
overflow-y: auto;
padding: var(--am2-container-padding);
border: var(--am2-container-border);
border-radius: var(--am2-container-border-radius);
background: transparent;
box-shadow: var(--am2-container-shadow);
}
.amily2-table-header-container {
background-color: rgba(50, 50, 55, 0.9);
border: 1px solid rgba(255, 255, 255, 0.15);
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 8px 8px 0 0;
padding: 8px 12px;
margin-bottom: 0;
display: flex;
justify-content: space-between;
align-items: center;
}
#amily2_memorisation_forms_panel #all-tables-container h3 {
font-size: 1em;
font-weight: bold;
padding: 0;
margin: 0;
color: #e0e0e0;
text-shadow: none;
display: flex;
align-items: center;
white-space: nowrap;
flex-shrink: 0;
}
#amily2_memorisation_forms_panel #all-tables-container h3 > i {
margin-right: 8px;
color: #9e8aff;
}
#amily2_memorisation_forms_panel .table-controls {
display: flex;
flex-direction: row;
gap: 5px;
justify-content: flex-end;
margin-bottom: 0;
transition: box-shadow 0.5s ease-in-out;
table-layout: fixed;
width: 100%;
box-shadow: 0 4px 15px rgba(0,0,0,0.3);
border-radius: 8px;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.1);
}
#amily2_memorisation_forms_panel table[id^="amily2-table-"] tr:nth-child(even) {
background-color: var(--am2-row-even-bg);
}
#amily2_memorisation_forms_panel table[id^="amily2-table-"] tr:hover {
background-color: var(--am2-row-hover-bg);
}
#amily2_memorisation_forms_panel table[id^="amily2-table-"] th,
#amily2_memorisation_forms_panel table[id^="amily2-table-"] td {
border-right: var(--am2-table-border);
border-bottom: var(--am2-table-border);
padding: 0;
text-align: left;
vertical-align: middle;
}
#amily2_memorisation_forms_panel table[id^="amily2-table-"] th:last-child,
#amily2_memorisation_forms_panel table[id^="amily2-table-"] td:last-child {
border-right: none;
}
#amily2_memorisation_forms_panel table[id^="amily2-table-"] tr:last-child td {
border-bottom: none;
}
.amily2-cell-content {
padding: var(--am2-table-cell-padding);
white-space: normal;
word-break: break-word;
height: auto;
max-height: 120px; /* Limit cell height */
overflow-y: auto; /* Allow scrolling for long content */
line-height: 1.3;
}
/* Custom scrollbar for cell content */
.amily2-cell-content::-webkit-scrollbar {
width: 4px;
}
.amily2-cell-content::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.1);
}
.amily2-cell-content::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.2);
border-radius: 2px;
}
.amily2-cell-content::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.4);
}
#amily2_memorisation_forms_panel table[id^="amily2-table-"] th {
background-color: var(--am2-header-bg);
color: var(--am2-header-color);
font-weight: 600;
position: relative;
font-size: 0.95em;
letter-spacing: 0.5px;
border-bottom: 2px solid rgba(158, 138, 255, 0.4) !important; /* Accent color border */
padding: 6px 8px; /* Direct padding for th */
}
#amily2_memorisation_forms_panel .amily2-resizer {
position: absolute;
top: 0;
right: -5px; /* Center the larger handle on the border */
width: 10px; /* Increase hit area for easier grabbing */
height: 100%;
cursor: col-resize;
user-select: none;
background-color: transparent; /* Make the larger hit area invisible until hovered */
transition: background-color 0.2s ease;
}
#amily2_memorisation_forms_panel .amily2-resizer:hover,
#amily2_memorisation_forms_panel .amily2-resizer:active {
background-color: rgba(158, 138, 255, 0.5);
}
#amily2_memorisation_forms_panel .index-col {
background-color: var(--am2-index-col-bg);
text-align: center !important;
font-weight: bold;
color: var(--am2-index-col-color);
padding: var(--am2-table-cell-padding);
word-break: normal;
position: relative;
cursor: pointer;
border-right: 1px solid rgba(255, 255, 255, 0.1);
font-family: monospace;
font-size: 1.1em;
}
#amily2_memorisation_forms_panel th[contenteditable="true"] {
background-color: var(--am2-header-editable-bg);
transition: background-color 0.3s;
}
#amily2_memorisation_forms_panel th[contenteditable="true"]:focus {
background-color: var(--am2-header-editable-focus-bg);
outline: var(--am2-header-editable-focus-outline);
}
#amily2_memorisation_forms_panel td[contenteditable="true"] {
background-color: var(--am2-cell-editable-bg);
transition: background-color 0.3s;
}
#amily2_memorisation_forms_panel td[contenteditable="true"]:focus {
background-color: var(--am2-cell-editable-focus-bg);
outline: var(--am2-cell-editable-focus-outline);
}
#amily2_memorisation_forms_panel .menu_button {
background: var(--am2-button-bg, var(--amily2-button-color));
background-image: var(--am2-button-gradient, none);
background-size: 200% 100%;
background-position: 0% 50%;
border: 1px solid var(--am2-button-border-color, rgba(255, 255, 255, 0.2)) !important;
color: var(--am2-button-text-color, var(--amily2-text-color)) !important;
padding: 8px 15px;
border-radius: 8px;
cursor: pointer;
font-weight: bold;
transition: all 0.4s ease-out !important;
}
#amily2_memorisation_forms_panel .menu_button:hover {
background-color: var(--am2-button-hover-bg, rgba(255, 255, 255, 0.2));
background-position: 100% 50%;
border-color: var(--am2-button-hover-border-color, #fff) !important;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0,0,0,0.4);
}
#amily2_memorisation_forms_panel .menu_button.danger {
background: var(--am2-button-danger-bg, rgba(255, 82, 82, 0.2)) !important;
border-color: var(--am2-button-danger-border-color, rgba(255, 82, 82, 0.5)) !important;
}
#amily2_memorisation_forms_panel .menu_button.danger:hover {
background: var(--am2-button-danger-hover-bg, rgba(255, 82, 82, 0.4)) !important;
border-color: var(--am2-button-danger-hover-border-color, #ff5252) !important;
}
/* 【延迟删除】恢复按钮的成功样式 */
#amily2_memorisation_forms_panel .menu_button.success {
background: var(--am2-button-success-bg, rgba(40, 167, 69, 0.2)) !important;
border-color: var(--am2-button-success-border-color, rgba(40, 167, 69, 0.5)) !important;
}
#amily2_memorisation_forms_panel .menu_button.success:hover {
background: var(--am2-button-success-hover-bg, rgba(40, 167, 69, 0.4)) !important;
border-color: var(--am2-button-success-hover-border-color, #28a745) !important;
}
#amily2_memorisation_forms_panel .menu_button.small_button {
padding: 5px 12px;
font-size: 0.9em;
border-radius: 6px;
writing-mode: horizontal-tb !important;
white-space: nowrap;
}
#amily2_memorisation_forms_panel .hly-log-display {
background: transparent;
border-radius: 8px;
padding: 12px;
border: 1px solid #444;
max-height: 100px;
overflow-y: auto;
font-size: 0.9em;
color: var(--amily2-text-color);
display: flex;
flex-direction: column;
gap: 5px;
margin-bottom: 10px;
}
#amily2_memorisation_forms_panel .hly-log-entry {
margin: 0;
padding: 4px 8px;
border-radius: 4px;
line-height: 1.5;
text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
}
#amily2_memorisation_forms_panel .hly-log-entry .fa-solid {
margin-right: 8px;
width: 16px;
text-align: center;
}
#amily2_memorisation_forms_panel .log-info {
color: #a0c4ff;
border-left: 3px solid #6b9eff;
}
#amily2_memorisation_forms_panel .log-success {
color: #a8d8b4;
border-left: 3px solid #5cb85c;
}
#amily2_memorisation_forms_panel .log-error {
color: #ffadad;
border-left: 3px solid #d9534f;
}
#amily2_memorisation_forms_panel .log-warn {
color: #ffd6a5;
border-left: 3px solid #f0ad4e;
}
.settings-group {
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 12px;
padding: 12px;
margin: 0;
}
.settings-group > legend {
color: var(--amily2-text-color);
font-weight: bold;
padding: 0 10px;
margin-left: 10px;
font-size: 1.1em;
}
.settings-group > legend > i {
margin-right: 8px;
color: #9e8aff;
}
.central-control-wrapper {
display: flex;
flex-direction: row;
gap: 15px;
}
.central-control-wrapper .control-section {
flex: 1;
display: flex;
flex-direction: column;
}
.central-control-wrapper #ai-template-section .hly-textarea {
flex-grow: 1;
height: 100%;
min-height: 150px;
}
.central-control-wrapper .vertical-divider {
width: 1px;
background-color: rgba(255, 255, 255, 0.2);
align-self: stretch;
}
.inline-settings-grid {
display: grid;
grid-template-columns: auto 1fr;
gap: 8px 12px;
align-items: center;
}
.inline-settings-grid label {
font-weight: bold;
text-align: right;
white-space: nowrap;
}
.inline-settings-grid .text_pole {
width: 100%;
}
#amily2_memorisation_forms_panel.prompt-editor-area {
display: flex;
flex-direction: column;
gap: 8px;
}
#amily2_memorisation_forms_panel.editor-buttons-panel {
display: flex;
justify-content: flex-end;
gap: 8px;
}
#add-table-placeholder {
width: 100%;
padding: 20px 0;
border: 2px dashed rgba(255, 255, 255, 0.3);
border-radius: 12px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
transition: all 0.3s ease;
margin-top: 20px;
}
#add-table-placeholder i {
font-size: 2em;
color: rgba(255, 255, 255, 0.4);
transition: all 0.3s ease;
}
#add-table-placeholder:hover {
background-color: rgba(255, 255, 255, 0.05);
border-color: rgba(255, 255, 255, 0.6);
}
#add-table-placeholder:hover i {
color: rgba(255, 255, 255, 0.8);
transform: scale(1.1);
}
#amily2-action-center {
display: flex !important;
flex-direction: row !important;
gap: 10px !important;
}
.sinan-navigation-deck {
display: flex;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
margin-bottom: 15px;
}
.sinan-nav-item {
padding: 10px 20px;
cursor: pointer;
border: none;
background-color: transparent;
color: var(--amily2-text-color);
font-size: 1em;
border-bottom: 3px solid transparent;
transition: all 0.3s ease;
}
.sinan-nav-item:hover {
background-color: rgba(255, 255, 255, 0.05);
color: var(--amily2-text-color);
}
.sinan-nav-item.active {
color: #9e8aff;
border-bottom-color: #9e8aff;
font-weight: bold;
}
.sinan-nav-item i {
margin-right: 8px;
}
.sinan-content-wrapper {
padding: 10px;
}
.sinan-tab-pane {
display: none;
animation: fadeIn 0.5s;
}
.sinan-tab-pane.active {
display: block;
}
.action-center-buttons {
display: flex;
flex-wrap: wrap;
gap: 15px;
justify-content: center;
}
.action-center-buttons .menu_button {
flex-grow: 1;
min-width: 180px;
}
.notes {
font-size: 0.9em;
color: var(--amily2-text-color);
margin-top: 15px;
text-align: center;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.control-block-with-switch {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
background-color: rgba(255, 255, 255, 0.05);
border-radius: 8px;
}
.control-block-with-switch label {
font-weight: bold;
color: var(--amily2-text-color);
}
.toggle-switch {
position: relative;
display: inline-block;
width: 50px;
height: 28px;
}
.toggle-switch input {
opacity: 0;
width: 0;
height: 0;
}
#amily2_memorisation_forms_panel .slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #555;
transition: .4s;
border-radius: 28px;
}
#amily2_memorisation_forms_panel .slider:before {
position: absolute;
content: "";
height: 20px;
width: 20px;
left: 4px;
top: 50%;
background-color: var(--amily2-text-color);
border-radius: 50%;
transition: .4s;
transform: translateY(-50%);
}
#amily2_memorisation_forms_panel input:checked + .slider {
background-color: #8a72ff;
}
#amily2_memorisation_forms_panel input:focus + .slider {
box-shadow: 0 0 1px #8a72ff;
}
#amily2_memorisation_forms_panel input:checked + .slider:before {
transform: translateX(22px) translateY(-50%);
}
.amily2-context-menu {
display: none;
z-index: 9999;
flex-direction: column;
gap: 0;
padding: 4px;
background-color: rgba(30, 30, 40, 0.98);
border: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 6px;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
width: max-content;
}
.amily2-row-context-menu {
position: absolute;
top: 0;
left: 100%;
z-index: 10000;
display: none; /* Initially hidden */
flex-direction: column;
gap: 4px;
padding: 8px;
width: max-content;
background-color: rgba(30, 30, 40, 0.98);
border: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 6px;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
}
/* Now controlled by a class on the parent TD for consistency */
td.amily2-menu-open .amily2-row-context-menu {
display: flex;
}
.amily2-context-menu.amily2-menu-active {
display: flex;
}
th .amily2-context-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 10000;
display: none;
grid-template-columns: repeat(2, 1fr);
gap: 4px;
padding: 8px;
width: max-content;
background-color: rgba(30, 30, 40, 0.98);
border: 1px solid rgba(255, 255, 255, 0.5);
border-radius: 6px;
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.4);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
}
th.amily2-menu-open .amily2-context-menu {
display: grid;
}
#amily2_memorisation_forms_panel .amily2-context-menu .menu_button {
white-space: nowrap;
border: none !important;
border-radius: 0 !important;
padding: 4px 8px !important;
font-size: 0.85em !important;
background: transparent !important;
transition: background-color 0.2s ease !important;
text-align: left !important;
font-weight: normal !important;
transform: none !important;
box-shadow: none !important;
margin: 0 !important;
}
#amily2_memorisation_forms_panel .amily2-context-menu .menu_button:hover {
background: rgba(255, 255, 255, 0.15) !important;
transform: none !important;
box-shadow: none !important;
}
/* This rule is now part of the main .amily2-row-context-menu block above */
@media (max-width: 768px) {
#amily2_memorisation_forms_panel {
padding: 0;
}
#upper-controls-wrapper {
padding: var(--am2-padding-main);
}
#amily2_memorisation_forms_panel #all-tables-container {
padding: 10px 2px;
}
/* Make resizer easier to touch on mobile */
#amily2_memorisation_forms_panel .amily2-resizer {
width: 15px;
right: -7px; /* Adjust position to keep it centered on the border */
}
}
#amily2_memorisation_forms_panel .cell-highlight {
background-color: var(--am2-cell-highlight-bg, rgba(144, 238, 144, 0.3)) !important;
transition: background-color 0.3s ease-in-out;
}
/* 自定义列名编辑对话框样式 */
.custom-input-dialog {
border: none;
border-radius: 12px;
background: rgba(30, 30, 40, 0.95);
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6);
width: 90vw;
max-width: 450px;
padding: 0;
}
.custom-input-dialog .popup-body {
background: rgba(40, 45, 60, 0.9);
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.15);
}
.custom-input-dialog #column-name-input {
transition: all 0.3s ease;
}
.custom-input-dialog #column-name-input:focus {
border-color: rgba(158, 138, 255, 0.8) !important;
box-shadow: 0 0 8px rgba(158, 138, 255, 0.3);
outline: none;
}
.custom-input-dialog .popup-button-ok:hover {
background: rgba(158, 138, 255, 0.5) !important;
border-color: rgba(158, 138, 255, 0.8) !important;
transform: translateY(-1px);
}
.custom-input-dialog .popup-button-cancel:hover {
background: rgba(120, 120, 120, 0.4) !important;
border-color: rgba(120, 120, 120, 0.6) !important;
transform: translateY(-1px);
}
/* Nccs API 按钮行样式 */
.nccs-button-row {
display: flex;
gap: 10px;
justify-content: center;
align-items: center;
margin-top: 15px;
}
.nccs-button-row .menu_button {
min-width: 120px;
height: 35px;
border-radius: 20px;
background: linear-gradient(45deg, rgba(74, 158, 255, 0.6), rgba(138, 114, 255, 0.6));
border: 1px solid rgba(74, 158, 255, 0.8) !important;
color: #fff !important;
font-weight: bold;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
gap: 5px;
}
.nccs-button-row .menu_button:hover {
background: linear-gradient(45deg, rgba(74, 158, 255, 0.8), rgba(138, 114, 255, 0.8));
transform: translateY(-2px);
box-shadow: 0 4px 15px rgba(74, 158, 255, 0.4);
}
.nccs-button-row .menu_button.secondary {
background: linear-gradient(45deg, rgba(120, 120, 120, 0.6), rgba(160, 160, 160, 0.6));
border: 1px solid rgba(120, 120, 120, 0.8) !important;
}
.nccs-button-row .menu_button.secondary:hover {
background: linear-gradient(45deg, rgba(120, 120, 120, 0.8), rgba(160, 160, 160, 0.8));
box-shadow: 0 4px 15px rgba(120, 120, 120, 0.4);
}
/* Styles for tables injected into chat messages */
#amily2-chat-table-container {
margin-top: 10px;
padding: 10px;
border: 1px solid var(--am2-container-border, rgba(255, 255, 255, 0.2));
border-radius: 8px;
background-color: rgba(0, 0, 0, 0.2);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
overflow-x: auto; /* Ensure horizontal scrolling on small screens */
}
.amily2-chat-table {
margin-bottom: 15px;
}
.amily2-chat-table:last-child {
margin-bottom: 0;
}
.amily2-chat-table h4 {
font-size: 1em;
font-weight: bold;
color: var(--am2-header-color, #e0e0e0);
margin-bottom: 8px;
padding-bottom: 5px;
border-bottom: 1px solid var(--am2-table-border, rgba(255, 255, 255, 0.25));
}
.amily2-chat-table table {
width: 100%;
border-collapse: collapse;
font-size: 0.9em;
}
.amily2-chat-table th,
.amily2-chat-table td {
border: 1px solid rgba(255, 255, 255, 0.2);
padding: 5px 8px;
text-align: left;
vertical-align: top;
}
.amily2-chat-table th {
background-color: rgba(255, 255, 255, 0.1);
font-weight: bold;
border-bottom: 1px solid rgba(255, 255, 255, 0.3);
}
/* Styles for collapsible in-chat tables */
.amily2-chat-table-summary {
cursor: pointer;
font-weight: bold;
padding: 5px;
border-radius: 4px;
transition: background-color 0.2s ease;
list-style: none; /* Hide the default triangle */
display: block;
}
.amily2-chat-table-summary::-webkit-details-marker {
display: none; /* Hide the default triangle in Chrome/Safari */
}
.amily2-chat-table-summary:before {
content: '▶';
margin-right: 8px;
font-size: 0.8em;
display: inline-block;
transition: transform 0.2s ease;
}
.amily2-chat-table-details[open] > .amily2-chat-table-summary:before {
transform: rotate(90deg);
}
.amily2-chat-table-summary:hover {
background-color: rgba(255, 255, 255, 0.1);
}
@media (max-width: 768px) {
.amily2-chat-table th,
.amily2-chat-table td {
padding: 4px 6px; /* Reduce padding on mobile */
font-size: 0.85em; /* Slightly smaller font on mobile */
}
#amily2-chat-table-container {
padding: 5px; /* Reduce container padding on mobile */
}
/* On mobile, allow text wrapping to prevent overflow */
.amily2-chat-table th,
.amily2-chat-table td {
white-space: normal;
word-break: break-all;
}
}
.amily2-chat-table td.amily2-cell-highlight {
background-color: var(--am2-cell-highlight-bg, rgba(144, 238, 144, 0.3));
transition: background-color 0.5s ease-in-out;
}
#amily2-chat-table-container.mobile-table-view .amily2-chat-table th,
#amily2-chat-table-container.mobile-table-view .amily2-chat-table td {
white-space: nowrap;
}
.pending-deletion-row {
background-color: rgba(255, 82, 82, 0.15) !important;
transition: background-color 0.3s ease;
}
.pending-deletion-row:hover {
background-color: rgba(255, 82, 82, 0.25) !important;
}
.pending-deletion-row td {
opacity: 0.7;
}
h3.table-updated {
color: #87CEFA !important;
text-shadow: 0 0 8px #00BFFF, 0 0 12px rgba(0, 191, 255, 0.5);
transition: color 0.4s ease-in-out, text-shadow 0.4s ease-in-out;
}