@waterwx/dsh-novel-forge 1.7.3 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +3627 -447
- package/lib/client.js.map +1 -1
- package/lib/index.js +1127 -141
- package/lib/index.js.map +1 -1
- package/lib/types/author-assets.d.ts +25 -0
- package/lib/types/client/api.d.ts +31 -1
- package/lib/types/client/locales.d.ts +16 -0
- package/lib/types/client/panel/AdaptModeView.d.ts +4 -0
- package/lib/types/client/panel/AuthorAssetsView.d.ts +4 -0
- package/lib/types/client/panel/AuthorHome.d.ts +30 -0
- package/lib/types/client/panel/ModelManager.d.ts +14 -0
- package/lib/types/client/panel/ModelPicker.d.ts +11 -0
- package/lib/types/client/panel/ProgressConsole.d.ts +17 -0
- package/lib/types/client/panel/ProgressHomeView.d.ts +5 -0
- package/lib/types/client/panel/ReasoningSection.d.ts +10 -0
- package/lib/types/client/panel/SettingsView.d.ts +14 -0
- package/lib/types/client/text.d.ts +9 -0
- package/lib/types/engine.d.ts +39 -1
- package/lib/types/index.d.ts +8 -0
- package/lib/types/protocol.d.ts +339 -0
- package/package.json +1 -1
- package/src/author-assets.ts +166 -0
- package/src/client/api.ts +82 -0
- package/src/client/locales.ts +32 -0
- package/src/client/mount.tsx._new +97 -0
- package/src/client/mount.tsx._nf +97 -0
- package/src/client/mount.tsx._tmp +97 -0
- package/src/client/panel/AdaptModeView.tsx +202 -0
- package/src/client/panel/AuthorAssetsView.tsx +206 -0
- package/src/client/panel/AuthorHome.tsx +107 -0
- package/src/client/panel/ImportModal.tsx +2 -1
- package/src/client/panel/ModelManager.tsx +205 -0
- package/src/client/panel/NovelPanel.tsx +73 -79
- package/src/client/panel/ProgressConsole.tsx +64 -0
- package/src/client/panel/ProgressHomeView.tsx +87 -0
- package/src/client/panel/ReasoningSection.tsx +31 -0
- package/src/client/panel/SettingsView.tsx +292 -0
- package/src/client/panel/panel.module.css +325 -0
- package/src/client/sidebar-entry.ts +1 -1
- package/src/client/text.ts +28 -0
- package/src/engine.ts +442 -0
- package/src/index.ts +20 -0
- package/src/protocol.ts +356 -0
- package/src/routes.ts +323 -0
package/lib/client.js
CHANGED
|
@@ -61,6 +61,18 @@ window.__ModuleLoader__.load({
|
|
|
61
61
|
storyboardPrompts: "/api/dsh-novel-forge/storyboard/prompts",
|
|
62
62
|
/** 生图接口连通性测试(设置页每个模型条目用)。 */
|
|
63
63
|
imageTest: "/api/dsh-novel-forge/image-test",
|
|
64
|
+
/** LLM 模型连通性测试:真实最小调用,验证 Key / 端点 / 模型可用。 */
|
|
65
|
+
llmTest: "/api/dsh-novel-forge/llm-test",
|
|
66
|
+
/** 添加模型:厂商直填 key 或自定义路由,写进 DSH 凭据与 llm-pi-ai 路由。 */
|
|
67
|
+
addModel: "/api/dsh-novel-forge/llm-add",
|
|
68
|
+
/** 运行时厂商目录(DSH pi-ai 可配置提供方 + 内置适配器)。 */
|
|
69
|
+
llmVendors: "/api/dsh-novel-forge/llm-vendors",
|
|
70
|
+
/** 查询某个 provider 当前可用的模型(添加成功后可即时刷新)。 */
|
|
71
|
+
llmModels: "/api/dsh-novel-forge/llm-models",
|
|
72
|
+
/** 已注册的提供方路由列表(提供方管理)。 */
|
|
73
|
+
llmProviders: "/api/dsh-novel-forge/llm-providers",
|
|
74
|
+
/** 移除一个提供方。 */
|
|
75
|
+
llmRemove: "/api/dsh-novel-forge/llm-remove",
|
|
64
76
|
/** 重置项目(可选携带新大纲):清空设定/卷/章节/伏笔/资产/事实库。 */
|
|
65
77
|
reset: "/api/dsh-novel-forge/reset",
|
|
66
78
|
/** 全书一致性质检:LLM 扫描已生成章节,输出矛盾问题清单。 */
|
|
@@ -109,8 +121,94 @@ window.__ModuleLoader__.load({
|
|
|
109
121
|
/** 生产单状态(含进度统计与日志)。 */
|
|
110
122
|
runStatus: "/api/dsh-novel-forge/run/status",
|
|
111
123
|
config: "/api/dsh-novel-forge/config",
|
|
112
|
-
openFolder: "/api/dsh-novel-forge/open-folder"
|
|
124
|
+
openFolder: "/api/dsh-novel-forge/open-folder",
|
|
125
|
+
/** 作者资产库/总数据:读取个人跨书资产(笔法/红线/套路/角色模板/世界观模板)。 */
|
|
126
|
+
authorAssets: "/api/dsh-novel-forge/author-assets",
|
|
127
|
+
/** 作者资产库:新增/更新一条资产(upsert by id)。 */
|
|
128
|
+
authorAssetsUpsert: "/api/dsh-novel-forge/author-assets/upsert",
|
|
129
|
+
/** 作者资产库:删除一条资产。 */
|
|
130
|
+
authorAssetsRemove: "/api/dsh-novel-forge/author-assets/remove",
|
|
131
|
+
/** 作者资产库:导入默认(书架书的写作资产/角色 + 内置全局库)批量沉淀。 */
|
|
132
|
+
authorAssetsImportDefault: "/api/dsh-novel-forge/author-assets/import-default",
|
|
133
|
+
/** 改编模式:上传全文 → 分析 → 原文设定卡片/可改范围矩阵。 */
|
|
134
|
+
adaptAnalyze: "/api/dsh-novel-forge/adapt/analyze",
|
|
135
|
+
/** 改编模式:确认要改的维度 → 生成映射表/改编规则/联动影响清单。 */
|
|
136
|
+
adaptPropose: "/api/dsh-novel-forge/adapt/propose",
|
|
137
|
+
/** 改编模式:执行术语替换(全局替换 + 命中统计 + 改编文本预览)。 */
|
|
138
|
+
adaptExecute: "/api/dsh-novel-forge/adapt/execute",
|
|
139
|
+
/** 主题自定义背景:上传图片(POST,存盘并返回服务端 URL)。 */
|
|
140
|
+
themeBackgroundUpload: "/api/dsh-novel-forge/theme/background",
|
|
141
|
+
/** 主题自定义背景:读取已上传文件(GET prefix,/theme/background/<name>)。 */
|
|
142
|
+
themeBackgroundGet: "/api/dsh-novel-forge/theme/background"
|
|
113
143
|
};
|
|
144
|
+
/** 预置的常见厂商(id=provider 路由;添加模型下拉兜底用,其余厂商由运行时目录动态补充)。 */
|
|
145
|
+
const LLM_VENDORS = [
|
|
146
|
+
{
|
|
147
|
+
id: "deepseek-official",
|
|
148
|
+
name: "DeepSeek",
|
|
149
|
+
route: "deepseek-official",
|
|
150
|
+
apiKeyEnv: "DEEPSEEK_API_KEY",
|
|
151
|
+
defaultModel: "deepseek-v4-flash",
|
|
152
|
+
models: [
|
|
153
|
+
"deepseek-v4-flash",
|
|
154
|
+
"deepseek-v4-pro",
|
|
155
|
+
"deepseek-chat",
|
|
156
|
+
"deepseek-reasoner"
|
|
157
|
+
],
|
|
158
|
+
builtin: true
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
id: "zai-coding-cn",
|
|
162
|
+
name: "智谱 GLM",
|
|
163
|
+
route: "zai-coding-cn",
|
|
164
|
+
apiKeyEnv: "ZAI_CODING_CN_API_KEY",
|
|
165
|
+
defaultModel: "glm-5.3-flash",
|
|
166
|
+
models: [
|
|
167
|
+
"glm-4.5-air",
|
|
168
|
+
"glm-4.7",
|
|
169
|
+
"glm-5-turbo",
|
|
170
|
+
"glm-5.1",
|
|
171
|
+
"glm-5.2",
|
|
172
|
+
"glm-5.3",
|
|
173
|
+
"glm-5.3-flash",
|
|
174
|
+
"glm-5v-turbo"
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
id: "qwen-token-plan-cn",
|
|
179
|
+
name: "千问百炼",
|
|
180
|
+
route: "qwen-token-plan-cn",
|
|
181
|
+
apiKeyEnv: "QWEN_TOKEN_PLAN_CN_API_KEY",
|
|
182
|
+
defaultModel: "qwen3.7-max",
|
|
183
|
+
models: [
|
|
184
|
+
"qwen3.6-flash",
|
|
185
|
+
"qwen3.6-plus",
|
|
186
|
+
"qwen3.7-max",
|
|
187
|
+
"qwen3.7-plus",
|
|
188
|
+
"qwen3.8-max",
|
|
189
|
+
"qwen3.8-max-preview"
|
|
190
|
+
]
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
id: "openrouter",
|
|
194
|
+
name: "OpenRouter",
|
|
195
|
+
route: "openrouter",
|
|
196
|
+
apiKeyEnv: "OPENROUTER_API_KEY",
|
|
197
|
+
defaultModel: "z-ai/glm-5.3-flash",
|
|
198
|
+
models: [
|
|
199
|
+
"z-ai/glm-4.6",
|
|
200
|
+
"z-ai/glm-4.7",
|
|
201
|
+
"z-ai/glm-5",
|
|
202
|
+
"z-ai/glm-5-turbo",
|
|
203
|
+
"z-ai/glm-5.1",
|
|
204
|
+
"z-ai/glm-5.2",
|
|
205
|
+
"z-ai/glm-5.3-flash",
|
|
206
|
+
"auto",
|
|
207
|
+
"deepseek/deepseek-v4-flash",
|
|
208
|
+
"anthropic/claude-sonnet-4.6"
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
];
|
|
114
212
|
//#endregion
|
|
115
213
|
//#region src/client/api.ts
|
|
116
214
|
/**
|
|
@@ -318,6 +416,33 @@ window.__ModuleLoader__.load({
|
|
|
318
416
|
async imageTest(req) {
|
|
319
417
|
return postJson(NOVEL_API.imageTest, req);
|
|
320
418
|
}
|
|
419
|
+
/** 对选中的提供商/模型发一次最小真实调用,验证连通性。 */
|
|
420
|
+
async llmTest(provider, model) {
|
|
421
|
+
return postJson(NOVEL_API.llmTest, {
|
|
422
|
+
provider,
|
|
423
|
+
model
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
/** 添加模型:厂商直填 key,或自定义 OpenAI 兼容路由(写 DSH 凭据 + 注册路由)。 */
|
|
427
|
+
async addModel(req) {
|
|
428
|
+
return postJson(NOVEL_API.addModel, req);
|
|
429
|
+
}
|
|
430
|
+
/** 运行时厂商目录(DSH pi-ai 可配置提供方 + 内置适配器)。 */
|
|
431
|
+
async llmVendors() {
|
|
432
|
+
return readJson(await fetch(NOVEL_API.llmVendors));
|
|
433
|
+
}
|
|
434
|
+
/** 查询某个 provider 当前可用的模型(添加成功后可即时刷新)。 */
|
|
435
|
+
async llmModels(provider) {
|
|
436
|
+
return readJson(await fetch(NOVEL_API.llmModels + "?provider=" + encodeURIComponent(provider)));
|
|
437
|
+
}
|
|
438
|
+
/** 已注册的提供方路由列表(提供方管理卡片)。 */
|
|
439
|
+
async llmProviders() {
|
|
440
|
+
return readJson(await fetch(NOVEL_API.llmProviders));
|
|
441
|
+
}
|
|
442
|
+
/** 移除一个提供方(unset key + 移除 llm-pi-ai 路由)。 */
|
|
443
|
+
async removeProvider(req) {
|
|
444
|
+
return postJson(NOVEL_API.llmRemove, req);
|
|
445
|
+
}
|
|
321
446
|
async roles(req) {
|
|
322
447
|
return postJson(NOVEL_API.roles, req);
|
|
323
448
|
}
|
|
@@ -542,6 +667,41 @@ window.__ModuleLoader__.load({
|
|
|
542
667
|
async assistantClear() {
|
|
543
668
|
return postJson(NOVEL_API.assistantClear, {});
|
|
544
669
|
}
|
|
670
|
+
/** 作者资产库/总数据:读取跨书可复用资产。 */
|
|
671
|
+
async authorAssets() {
|
|
672
|
+
return readJson(await fetch(NOVEL_API.authorAssets));
|
|
673
|
+
}
|
|
674
|
+
/** 作者资产库:新增/更新一条资产(upsert by id)。 */
|
|
675
|
+
async authorAssetsUpsert(asset) {
|
|
676
|
+
return postJson(NOVEL_API.authorAssetsUpsert, { asset });
|
|
677
|
+
}
|
|
678
|
+
/** 作者资产库:删除一条资产。 */
|
|
679
|
+
async authorAssetsRemove(id) {
|
|
680
|
+
return postJson(NOVEL_API.authorAssetsRemove, { id });
|
|
681
|
+
}
|
|
682
|
+
/** 作者资产库:导入默认(书架书的写作资产/角色 + 内置全局库)批量沉淀。 */
|
|
683
|
+
async authorAssetsImportDefault() {
|
|
684
|
+
return postJson(NOVEL_API.authorAssetsImportDefault, {});
|
|
685
|
+
}
|
|
686
|
+
/** 改编模式 P0:上传全文 → 原文设定卡片 / 可改范围矩阵。 */
|
|
687
|
+
async adaptAnalyze(text, filePath) {
|
|
688
|
+
return postJson(NOVEL_API.adaptAnalyze, {
|
|
689
|
+
text,
|
|
690
|
+
filePath
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
/** 改编模式 P1:确认要改的维度 → 生成映射表/改编规则/联动影响清单。 */
|
|
694
|
+
async adaptPropose(req) {
|
|
695
|
+
return postJson(NOVEL_API.adaptPropose, req);
|
|
696
|
+
}
|
|
697
|
+
/** 改编模式 P2:执行术语替换(全局替换 + 命中统计 + 改编文本预览)。 */
|
|
698
|
+
async adaptExecute(req) {
|
|
699
|
+
return postJson(NOVEL_API.adaptExecute, req);
|
|
700
|
+
}
|
|
701
|
+
/** 主题自定义背景:上传图片,服务端存盘并返回可访问 URL。 */
|
|
702
|
+
async themeBackgroundUpload(dataUrl) {
|
|
703
|
+
return postJson(NOVEL_API.themeBackgroundUpload, { dataUrl });
|
|
704
|
+
}
|
|
545
705
|
};
|
|
546
706
|
//#endregion
|
|
547
707
|
//#region src/client/locales.ts
|
|
@@ -689,7 +849,23 @@ window.__ModuleLoader__.load({
|
|
|
689
849
|
"settings.provider": "模型提供商",
|
|
690
850
|
"settings.model": "模型",
|
|
691
851
|
"settings.modelCustom": "自定义…",
|
|
852
|
+
"settings.customProvider": "自定义提供商…",
|
|
853
|
+
"settings.edit": "编辑",
|
|
854
|
+
"settings.delete": "删除",
|
|
692
855
|
"settings.modelCustomPlaceholder": "输入任意模型 id",
|
|
856
|
+
"settings.savedModels": "我的模型",
|
|
857
|
+
"settings.modelCards": "模型卡片(内置 + 已添加)",
|
|
858
|
+
"settings.savedModelName": "名称",
|
|
859
|
+
"settings.addModel": "添加模型",
|
|
860
|
+
"settings.catalogRefresh": "刷新厂商",
|
|
861
|
+
"settings.refreshModels": "刷新模型",
|
|
862
|
+
"settings.savedModelsHint": "手动添加常用模型(provider + 模型 id),点击即可切换当前模型;厂商模式会写入 DSH 凭据并注册路由。",
|
|
863
|
+
"settings.testConnection": "测试连通",
|
|
864
|
+
"settings.testRunning": "测试中",
|
|
865
|
+
"settings.testOk": "连通",
|
|
866
|
+
"settings.testFail": "失败",
|
|
867
|
+
"settings.testHint": "真实发送一次最小调用(约几十 token),验证 Key / 端点 / 模型可用。",
|
|
868
|
+
"settings.reasoningSection": "推理强度",
|
|
693
869
|
"settings.reasoningEffort": "写作类任务思考强度 (reasoningEffort)",
|
|
694
870
|
"settings.reasoningHint": "章节生成/润色/重写/审稿等写作任务使用;关掉更省更快。",
|
|
695
871
|
"settings.analysisReasoning": "分析类任务思考强度(提炼/拆书/反推大纲)",
|
|
@@ -840,7 +1016,23 @@ window.__ModuleLoader__.load({
|
|
|
840
1016
|
"settings.provider": "Provider",
|
|
841
1017
|
"settings.model": "Model",
|
|
842
1018
|
"settings.modelCustom": "Custom…",
|
|
1019
|
+
"settings.customProvider": "Custom provider…",
|
|
1020
|
+
"settings.edit": "Edit",
|
|
1021
|
+
"settings.delete": "Delete",
|
|
843
1022
|
"settings.modelCustomPlaceholder": "Type any model id",
|
|
1023
|
+
"settings.savedModels": "My Models",
|
|
1024
|
+
"settings.modelCards": "Model cards (built-in + added)",
|
|
1025
|
+
"settings.savedModelName": "Name",
|
|
1026
|
+
"settings.addModel": "Add model",
|
|
1027
|
+
"settings.catalogRefresh": "Refresh vendors",
|
|
1028
|
+
"settings.refreshModels": "Refresh models",
|
|
1029
|
+
"settings.savedModelsHint": "Manually add a model (provider + model id); click to switch. Vendor mode writes the key into DSH credentials and registers the route.",
|
|
1030
|
+
"settings.testConnection": "Test",
|
|
1031
|
+
"settings.testRunning": "Testing",
|
|
1032
|
+
"settings.testOk": "OK",
|
|
1033
|
+
"settings.testFail": "Failed",
|
|
1034
|
+
"settings.testHint": "Sends one minimal real call (~dozens of tokens) to verify key / endpoint / model.",
|
|
1035
|
+
"settings.reasoningSection": "Reasoning",
|
|
844
1036
|
"settings.reasoningEffort": "Writing-task reasoning effort",
|
|
845
1037
|
"settings.analysisReasoning": "Analysis-task reasoning (extract / breakdown / reverse outline)",
|
|
846
1038
|
"settings.analysisReasoningHint": "One-off analysis tasks (roles/scenes/bible extract, breakdown, reverse outline) default to low; not affected by the writing-level switch.",
|
|
@@ -5202,7 +5394,7 @@ window.__ModuleLoader__.load({
|
|
|
5202
5394
|
key: "d0xqtd"
|
|
5203
5395
|
}]
|
|
5204
5396
|
]);
|
|
5205
|
-
createLucideIcon("boxes", [
|
|
5397
|
+
const Boxes = createLucideIcon("boxes", [
|
|
5206
5398
|
["path", {
|
|
5207
5399
|
d: "M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z",
|
|
5208
5400
|
key: "lc1i9w"
|
|
@@ -5739,7 +5931,7 @@ window.__ModuleLoader__.load({
|
|
|
5739
5931
|
key: "s3unb"
|
|
5740
5932
|
}]
|
|
5741
5933
|
]);
|
|
5742
|
-
createLucideIcon("brush", [
|
|
5934
|
+
const Brush = createLucideIcon("brush", [
|
|
5743
5935
|
["path", {
|
|
5744
5936
|
d: "m11 10 3 3",
|
|
5745
5937
|
key: "fzmg1i"
|
|
@@ -17618,7 +17810,7 @@ window.__ModuleLoader__.load({
|
|
|
17618
17810
|
key: "af1f0g"
|
|
17619
17811
|
}]
|
|
17620
17812
|
]);
|
|
17621
|
-
createLucideIcon("image", [
|
|
17813
|
+
const Image = createLucideIcon("image", [
|
|
17622
17814
|
["rect", {
|
|
17623
17815
|
width: "18",
|
|
17624
17816
|
height: "18",
|
|
@@ -17749,7 +17941,7 @@ window.__ModuleLoader__.load({
|
|
|
17749
17941
|
d: "M6 16c5 0 7-8 12-8a4 4 0 0 1 0 8c-5 0-7-8-12-8a4 4 0 1 0 0 8",
|
|
17750
17942
|
key: "18ogeb"
|
|
17751
17943
|
}]]);
|
|
17752
|
-
createLucideIcon("info", [
|
|
17944
|
+
const Info = createLucideIcon("info", [
|
|
17753
17945
|
["circle", {
|
|
17754
17946
|
cx: "12",
|
|
17755
17947
|
cy: "12",
|
|
@@ -18908,7 +19100,7 @@ window.__ModuleLoader__.load({
|
|
|
18908
19100
|
key: "1szwhi"
|
|
18909
19101
|
}]
|
|
18910
19102
|
]);
|
|
18911
|
-
createLucideIcon("list-checks", [
|
|
19103
|
+
const ListChecks = createLucideIcon("list-checks", [
|
|
18912
19104
|
["path", {
|
|
18913
19105
|
d: "M13 5h8",
|
|
18914
19106
|
key: "a7qcls"
|
|
@@ -23663,7 +23855,7 @@ window.__ModuleLoader__.load({
|
|
|
23663
23855
|
key: "165o2o"
|
|
23664
23856
|
}]
|
|
23665
23857
|
]);
|
|
23666
|
-
createLucideIcon("pencil", [["path", {
|
|
23858
|
+
const Pencil = createLucideIcon("pencil", [["path", {
|
|
23667
23859
|
d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",
|
|
23668
23860
|
key: "1a8usu"
|
|
23669
23861
|
}], ["path", {
|
|
@@ -24114,7 +24306,7 @@ window.__ModuleLoader__.load({
|
|
|
24114
24306
|
key: "1ooewy"
|
|
24115
24307
|
}]
|
|
24116
24308
|
]);
|
|
24117
|
-
createLucideIcon("play", [["path", {
|
|
24309
|
+
const Play = createLucideIcon("play", [["path", {
|
|
24118
24310
|
d: "M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z",
|
|
24119
24311
|
key: "10ikf1"
|
|
24120
24312
|
}]]);
|
|
@@ -25137,7 +25329,7 @@ window.__ModuleLoader__.load({
|
|
|
25137
25329
|
key: "1r8tn9"
|
|
25138
25330
|
}]
|
|
25139
25331
|
]);
|
|
25140
|
-
createLucideIcon("refresh-cw", [
|
|
25332
|
+
const RefreshCw = createLucideIcon("refresh-cw", [
|
|
25141
25333
|
["path", {
|
|
25142
25334
|
d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",
|
|
25143
25335
|
key: "v9h5vc"
|
|
@@ -32359,7 +32551,7 @@ window.__ModuleLoader__.load({
|
|
|
32359
32551
|
d: "M12 19v3",
|
|
32360
32552
|
key: "npa21l"
|
|
32361
32553
|
}]]);
|
|
32362
|
-
createLucideIcon("trash-2", [
|
|
32554
|
+
const Trash2 = createLucideIcon("trash-2", [
|
|
32363
32555
|
["path", {
|
|
32364
32556
|
d: "M10 11v6",
|
|
32365
32557
|
key: "nco0om"
|
|
@@ -32975,7 +33167,7 @@ window.__ModuleLoader__.load({
|
|
|
32975
33167
|
key: "1snsnr"
|
|
32976
33168
|
}]
|
|
32977
33169
|
]);
|
|
32978
|
-
createLucideIcon("upload", [
|
|
33170
|
+
const Upload = createLucideIcon("upload", [
|
|
32979
33171
|
["path", {
|
|
32980
33172
|
d: "M12 3v12",
|
|
32981
33173
|
key: "1x0j5s"
|
|
@@ -34149,7 +34341,7 @@ window.__ModuleLoader__.load({
|
|
|
34149
34341
|
key: "x3v2xh"
|
|
34150
34342
|
}]
|
|
34151
34343
|
]);
|
|
34152
|
-
createLucideIcon("wand-sparkles", [
|
|
34344
|
+
const WandSparkles = createLucideIcon("wand-sparkles", [
|
|
34153
34345
|
["path", {
|
|
34154
34346
|
d: "m21.64 3.64-1.28-1.28a1.21 1.21 0 0 0-1.72 0L2.36 18.64a1.21 1.21 0 0 0 0 1.72l1.28 1.28a1.2 1.2 0 0 0 1.72 0L21.64 5.36a1.2 1.2 0 0 0 0-1.72",
|
|
34155
34347
|
key: "ul74o6"
|
|
@@ -34953,7 +35145,7 @@ window.__ModuleLoader__.load({
|
|
|
34953
35145
|
key: "qb1veh"
|
|
34954
35146
|
}]
|
|
34955
35147
|
]);
|
|
34956
|
-
createLucideIcon("x", [["path", {
|
|
35148
|
+
const X = createLucideIcon("x", [["path", {
|
|
34957
35149
|
d: "M18 6 6 18",
|
|
34958
35150
|
key: "1bl5f8"
|
|
34959
35151
|
}], ["path", {
|
|
@@ -35202,26 +35394,38 @@ window.__ModuleLoader__.load({
|
|
|
35202
35394
|
exports.BarChart3 = ChartColumn;
|
|
35203
35395
|
exports.BookMarked = BookMarked;
|
|
35204
35396
|
exports.BookOpen = BookOpen;
|
|
35397
|
+
exports.Boxes = Boxes;
|
|
35205
35398
|
exports.Brain = Brain;
|
|
35399
|
+
exports.Brush = Brush;
|
|
35206
35400
|
exports.Clapperboard = Clapperboard;
|
|
35207
35401
|
exports.Download = Download;
|
|
35208
35402
|
exports.Factory = Factory;
|
|
35209
35403
|
exports.FileText = FileText;
|
|
35210
35404
|
exports.Folder = Folder;
|
|
35405
|
+
exports.Image = Image;
|
|
35406
|
+
exports.Info = Info;
|
|
35211
35407
|
exports.Library = Library;
|
|
35408
|
+
exports.ListChecks = ListChecks;
|
|
35212
35409
|
exports.MessageSquare = MessageSquare;
|
|
35213
35410
|
exports.Palette = Palette;
|
|
35214
35411
|
exports.PenLine = PenLine;
|
|
35412
|
+
exports.Pencil = Pencil;
|
|
35413
|
+
exports.Play = Play;
|
|
35215
35414
|
exports.PlugZap = PlugZap;
|
|
35216
35415
|
exports.Plus = Plus;
|
|
35416
|
+
exports.RefreshCw = RefreshCw;
|
|
35217
35417
|
exports.RotateCcw = RotateCcw;
|
|
35218
35418
|
exports.ScrollText = ScrollText;
|
|
35219
35419
|
exports.Search = Search;
|
|
35220
35420
|
exports.Settings = Settings;
|
|
35221
35421
|
exports.Sparkles = Sparkles;
|
|
35422
|
+
exports.Trash2 = Trash2;
|
|
35423
|
+
exports.Upload = Upload;
|
|
35424
|
+
exports.Wand2 = WandSparkles;
|
|
35222
35425
|
exports.Wrench = Wrench;
|
|
35426
|
+
exports.X = X;
|
|
35223
35427
|
})))();
|
|
35224
|
-
const css = ".zE6uZW_entry{align-items:center;gap:var(--nf-space-8,8px);width:100%;padding:var(--nf-space-8,8px) var(--nf-space-12,12px);color:var(--dsw-alias-label-primary,#1f1f23);cursor:pointer;text-align:left;border-radius:var(--nf-radius-6,6px);background:0 0;border:none;font-size:14px;transition:background .15s;display:flex}body[data-ds-dark-theme] .zE6uZW_entry{color:var(--dsw-alias-label-primary,#ececf1)}.zE6uZW_entry:hover{background:var(--dsw-alias-interactive-bg-hover,#7f7f7f1f)}.zE6uZW_entry[data-active]{background:var(--dsw-alias-interactive-bg-active,#7f7f7f33)}.zE6uZW_entryIcon{flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.zE6uZW_entryLabel{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}[data-pane=conversation]{position:relative}.zE6uZW_view{z-index:60;color-scheme:light;--nf-font:-apple-system, BlinkMacSystemFont, \"SF Pro Display\", \"SF Pro Text\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;--nf-font-mono:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;--nf-bg:#f2f2f7db;--nf-bg-raise:#ffffffb8;--nf-bg-inset:#7676801f;--nf-border:#3c3c4329;--nf-border-strong:#3c3c4352;--nf-text:#1c1c1e;--nf-text-2:#3c3c43;--nf-text-2-alpha:#3c3c43ad;--nf-text-3:#8e8e93;--nf-accent:#00b85c;--nf-accent-hover:#00a04e;--nf-accent-soft:#00b85c1f;--nf-accent-fg:#fff;--nf-hover:#0000000d;--nf-success:#34c759;--nf-error:#ff3b30;--nf-warn:#ff9500;--nf-info:#00b85c;--nf-shadow:0 1px 3px #0000000f, 0 12px 32px #00000014;--nf-shadow-lg:0 4px 12px #00000012, 0 20px 48px #0000001f;--nf-card-shadow:0 2px 6px #0000000f, 0 14px 38px #00000024;--nf-card-shadow-hover:0 4px 10px #00000014, 0 22px 52px #0003;--nf-glass-face:linear-gradient(180deg, #fff6 0%, #ffffff4d 26%, #ffffff3d 52%, #fff3 78%, #ffffff2e 100%);--nf-glass-core:radial-gradient(60% 40% at 30% 0%, #fff9 0%, #fff3 42%, #fff0 78%);--nf-glass-sheen:#ffffff8c;--nf-glass-border:#ffffff80;--nf-glass-inset:#fff6;--nf-glass-orb-a:#00b85c3d;--nf-glass-orb-b:#78a0ff33;--nf-glass-noise:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E\");--nf-card-radius:20px;--nf-card-blur:26px;--nf-card-saturate:170%;--nf-card-brightness:1.04;--nf-card-sheen:#ffffff80;--nf-card-border:1px solid #ffffff59;--nf-ctrl-radius:14px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid #ffffffb3;--nf-ctrl-sheen:#ffffff80;--nf-ctrl-caret:var(--nf-accent);--nf-glass-bg-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='1000'%3E%3Cdefs%3E%3Cfilter id='b' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='110'/%3E%3C/filter%3E%3C/defs%3E%3Cg filter='url(%23b)'%3E%3Ccircle cx='300' cy='180' r='420' fill='%2335d07a' fill-opacity='0.62'/%3E%3Ccircle cx='1240' cy='260' r='470' fill='%233aa7ff' fill-opacity='0.58'/%3E%3Ccircle cx='900' cy='860' r='470' fill='%2340cfc0' fill-opacity='0.5'/%3E%3Ccircle cx='1500' cy='820' r='330' fill='%23ff9fb0' fill-opacity='0.4'/%3E%3Ccircle cx='600' cy='620' r='260' fill='%23b06ef0' fill-opacity='0.42'/%3E%3Ccircle cx='180' cy='600' r='220' fill='%23ffd166' fill-opacity='0.36'/%3E%3C/g%3E%3C/svg%3E\");background:var(--nf-bg);backdrop-filter:blur(30px)saturate(170%)brightness(1.04);color:var(--nf-text);--nf-fs-10:10px;--nf-fs-12:12px;--nf-fs-14:14px;--nf-fs-16:16px;--nf-fs-18:18px;--nf-fs-20:20px;--nf-fs-22:22px;--nf-fs-24:24px;--nf-fs-34:34px;--nf-fs-42:42px;--nf-icon-s:14px;--nf-icon-m:16px;--nf-icon-l:18px;--nf-icon-xl:22px;--nf-space-2:2px;--nf-space-4:4px;--nf-space-6:6px;--nf-space-8:8px;--nf-space-10:10px;--nf-space-12:12px;--nf-space-14:14px;--nf-space-16:16px;--nf-space-18:18px;--nf-space-20:20px;--nf-space-24:24px;--nf-space-28:28px;--nf-space-32:32px;--nf-radius-2:2px;--nf-radius-4:4px;--nf-radius-6:6px;--nf-radius-8:8px;--nf-radius-10:10px;--nf-radius-12:12px;--nf-radius-14:14px;--nf-radius-16:16px;--nf-radius-20:20px;--nf-radius-22:22px;--nf-radius-999:999px;--nf-ctrl-s:28px;--nf-ctrl-m:32px;--nf-ctrl-l:38px;--nf-container-pad:20px 22px;--nf-container-gap:var(--nf-space-14,14px);--nf-card-pad:20px 22px;--nf-nav-pad:16px 12px 14px;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Segoe UI,Roboto,Helvetica Neue,sans-serif;display:none;position:absolute;inset:0;overflow:auto}.zE6uZW_panel[data-nf-mode=dark],body[data-ds-dark-theme] .zE6uZW_panel:not([data-nf-mode]),.zE6uZW_view:has(>.zE6uZW_panel[data-nf-mode=dark]),body[data-ds-dark-theme] .zE6uZW_view:not(:has(>.zE6uZW_panel[data-nf-mode=light])){color-scheme:dark;--nf-bg:#0a0b0ddb;--nf-bg-raise:#1c1c1ec7;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff47;--nf-text:#f2f2f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b8;--nf-text-3:#8e8e93;--nf-accent:#35d07a;--nf-accent-hover:#5ce695;--nf-accent-soft:#35d07a33;--nf-accent-fg:#062b18;--nf-hover:#ffffff17;--nf-success:#30d158;--nf-error:#ff453a;--nf-warn:#ff9f0a;--nf-info:#35d07a;--nf-shadow:0 1px 2px #00000059, 0 10px 30px #0006;--nf-shadow-lg:0 4px 12px #0006, 0 20px 48px #0000008c;--nf-card-shadow:0 2px 6px #00000059, 0 14px 38px #00000073;--nf-card-shadow-hover:0 4px 10px #0006, 0 22px 52px #0000008c;--nf-glass-face:linear-gradient(180deg, #3e424a85 0%, #363a4275 26%, #30343c66 52%, #2a2e365c 78%, #262a3257 100%);--nf-glass-core:radial-gradient(60% 40% at 30% 0%, #ffffff38 0%, #ffffff14 42%, #fff0 78%);--nf-glass-sheen:#ffffff3d;--nf-glass-border:#ffffff24;--nf-glass-inset:#ffffff14;--nf-glass-orb-a:#00ca525c;--nf-glass-orb-b:#78a0ff47;--nf-glass-noise:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E\");--nf-card-radius:20px;--nf-card-blur:28px;--nf-card-saturate:165%;--nf-card-brightness:1;--nf-card-border:1px solid #ffffff24;--nf-card-sheen:#ffffff38;--nf-glass-bg-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='1000'%3E%3Cdefs%3E%3Cfilter id='b' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='110'/%3E%3C/filter%3E%3C/defs%3E%3Cg filter='url(%23b)'%3E%3Ccircle cx='300' cy='180' r='420' fill='%231a9f4d' fill-opacity='0.44'/%3E%3Ccircle cx='1240' cy='260' r='470' fill='%23268bd6' fill-opacity='0.40'/%3E%3Ccircle cx='900' cy='860' r='470' fill='%232a9e94' fill-opacity='0.36'/%3E%3Ccircle cx='1500' cy='820' r='330' fill='%23e07a94' fill-opacity='0.30'/%3E%3Ccircle cx='600' cy='620' r='260' fill='%238c5bd6' fill-opacity='0.32'/%3E%3C/g%3E%3C/svg%3E\");--nf-ctrl-radius:14px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid #ffffff2e;--nf-ctrl-sheen:#fff3;--nf-ctrl-caret:var(--nf-accent)}html[data-dsh-novelforge-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) .zE6uZW_view{display:block}.zE6uZW_panel[data-nf-theme=macos],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-mode=light][data-nf-theme=macos]{--nf-bg:#f5f6f8eb;--nf-bg-raise:#ffffffc7;--nf-bg-inset:#7676801a;--nf-border:#3c3c4324;--nf-border-strong:#3c3c434d;--nf-text:#1d1d1f;--nf-text-2:#3a3a3c;--nf-text-2-alpha:#3a3a3cb3;--nf-text-3:#86868b;--nf-accent:#007aff;--nf-accent-hover:#0071e3;--nf-accent-soft:#007aff1f;--nf-accent-fg:#fff;--nf-hover:#0000000a;--nf-info:#5856d6;--nf-shadow:0 1px 3px #0000000d, 0 10px 28px #00000012;--nf-shadow-lg:0 4px 12px #0000000f, 0 18px 44px #0000001c;--nf-card-shadow:0 2px 6px #0000000d, 0 12px 34px #00000017;--nf-card-shadow-hover:0 4px 10px #00000012, 0 20px 48px #00000024;--nf-glass-face:#ffffffb3;--nf-glass-core:transparent;--nf-glass-sheen:#fffc;--nf-glass-border:#ffffffe6;--nf-glass-inset:#fff9;--nf-glass-orb-a:#007aff14;--nf-glass-orb-b:#5856d612;--nf-glass-noise:none;--nf-card-radius:12px;--nf-card-blur:42px;--nf-card-saturate:150%;--nf-card-border:1px solid var(--nf-border);--nf-card-sheen:#ffffff59;--nf-ctrl-radius:8px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid var(--nf-border-strong);--nf-ctrl-sheen:#ffffff59;--nf-ctrl-caret:var(--nf-accent)}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=macos],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=macos]:not([data-nf-mode]){--nf-bg:#1c1c1ee6;--nf-bg-raise:#2c2c2ed1;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff42;--nf-text:#f5f5f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b3;--nf-text-3:#98989d;--nf-accent:#0a84ff;--nf-accent-hover:#3a9bff;--nf-accent-soft:#0a84ff33;--nf-accent-fg:#fff;--nf-hover:#ffffff0f;--nf-info:#bf5af2;--nf-shadow:0 1px 2px #0006, 0 10px 30px #00000073;--nf-shadow-lg:0 4px 12px #00000073, 0 18px 44px #0009;--nf-card-shadow:0 2px 6px #0006, 0 14px 38px #00000080;--nf-card-shadow-hover:0 4px 10px #00000073, 0 22px 52px #0009;--nf-glass-face:#2c2c2ed9;--nf-glass-core:transparent;--nf-glass-sheen:#fff3;--nf-glass-border:#ffffff2e;--nf-glass-inset:#ffffff0f;--nf-glass-orb-a:#0a84ff29;--nf-glass-orb-b:#bf5af214;--nf-glass-noise:none}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_button{border:1px solid var(--nf-border-strong);background:color-mix(in srgb, var(--nf-bg-raise) 82%, #fff);box-shadow:0 1px 1px #0000000a,inset 0 1px #fff9}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_buttonPrimary{background:linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 90%, #fff), var(--nf-accent));color:var(--nf-accent-fg);box-shadow:0 1px 3px color-mix(in srgb, var(--nf-accent) 45%, transparent), inset 0 1px 0 #ffffff59;border-color:#0000}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_input,.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_textarea{border:1px solid var(--nf-border-strong);background:var(--nf-bg-raise)}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_input:focus,.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft)}.zE6uZW_panel[data-nf-theme=neumorph]{--nf-card-radius:20px;--nf-card-blur:0px;--nf-card-saturate:100%;--nf-card-border:none;--nf-card-sheen:#fff0;--nf-ctrl-radius:10px;--nf-ctrl-bg:var(--nf-bg-inset);--nf-ctrl-border:none;--nf-ctrl-sheen:#fff0;--nf-ctrl-caret:var(--nf-text-3);--nf-glass-bg-image:none}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph]{--nf-bg:#e4e9f2;--nf-bg-raise:#e4e9f2;--nf-bg-inset:#d9dfe8;--nf-border:#8c9baf59;--nf-border-strong:#78879e80;--nf-text:#3a4250;--nf-text-2:#5b6472;--nf-text-2-alpha:#465060b3;--nf-text-3:#8b94a3;--nf-hover:#5a697d14;--nf-shadow:4px 4px 10px #a3b1c68c, -4px -4px 10px #ffffffd9;--nf-shadow-lg:6px 6px 14px #a3b1c699, -6px -6px 14px #ffffffe6;--nf-card-shadow:9px 9px 18px #a3b1c68c, -9px -9px 18px #ffffffd9;--nf-card-shadow-hover:12px 12px 24px #a3b1c6a6, -12px -12px 24px #fffffff2;--nf-glass-face:#e4e9f2;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#a3b1c666;--nf-glass-inset:#d9dfe8;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=neumorph],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph]:not([data-nf-mode]){--nf-bg:#2b2f36;--nf-bg-raise:#2b2f36;--nf-bg-inset:#25292f;--nf-border:#0a0c1080;--nf-border-strong:#080a0e99;--nf-text:#d6dae1;--nf-text-2:#a8aeb8;--nf-text-2-alpha:#a8aeb8b3;--nf-text-3:#757c88;--nf-hover:#ffffff0d;--nf-shadow:4px 4px 10px #00000080, -4px -4px 10px #6068763d;--nf-shadow-lg:6px 6px 14px #0000008c, -6px -6px 14px #60687642;--nf-card-shadow:9px 9px 18px #00000080, -9px -9px 18px #6068763d;--nf-card-shadow-hover:12px 12px 24px #0009, -12px -12px 24px #60687647;--nf-glass-face:#2b2f36;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#0c0e1273;--nf-glass-inset:#25292f;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-theme=clay]{--nf-card-radius:28px;--nf-card-blur:0px;--nf-card-saturate:100%;--nf-card-brightness:1;--nf-card-border:1px solid #fff9;--nf-card-sheen:#ffffffd9;--nf-ctrl-radius:16px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid #ffffff8c;--nf-ctrl-sheen:#ffffffb3;--nf-ctrl-caret:var(--nf-accent);--nf-glass-bg-image:none}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay],.zE6uZW_panel[data-nf-mode=light][data-nf-theme=clay]{--nf-bg:#f2eae0;--nf-bg-raise:#efe4d6;--nf-bg-inset:#e6d8c6;--nf-border:#78604829;--nf-border-strong:#78604847;--nf-text:#3a3330;--nf-text-2:#5a4f48;--nf-text-2-alpha:#5a4f48b3;--nf-text-3:#9a8c80;--nf-accent:#e08a5c;--nf-accent-hover:#d67a4a;--nf-accent-soft:#e08a5c29;--nf-accent-fg:#fff;--nf-hover:#78604814;--nf-success:#7fae6a;--nf-error:#c96b63;--nf-warn:#d9a660;--nf-info:#e08a5c;--nf-shadow:0 8px 16px -6px #5a463247, inset 0 6px 10px #ffffff8c, inset 0 -6px 10px #7860481f;--nf-shadow-lg:0 16px 28px -10px #5a463257, inset 0 6px 10px #ffffff8c, inset 0 -6px 10px #78604824;--nf-card-shadow:0 16px 28px -10px #5a463257, inset 0 -8px 12px #78604824, inset 0 8px 12px #fff9;--nf-card-shadow-hover:0 22px 36px -12px #5a463261, inset 0 -8px 12px #78604829, inset 0 8px 12px #ffffffb3;--nf-glass-face:#efe4d6;--nf-glass-core:transparent;--nf-glass-sheen:#ffffffd9;--nf-glass-border:#fff9;--nf-glass-inset:#e6d8c6;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]){--nf-bg:#2a2522;--nf-bg-raise:#37302b;--nf-bg-inset:#2f2925;--nf-border:#ffffff14;--nf-border-strong:#ffffff2e;--nf-text:#efe9e3;--nf-text-2:#c7beb5;--nf-text-2-alpha:#c7beb5b3;--nf-text-3:#8a8078;--nf-accent:#e69a6c;--nf-accent-hover:#f0ac82;--nf-accent-soft:#e69a6c33;--nf-accent-fg:#241b16;--nf-hover:#ffffff0f;--nf-success:#9cba82;--nf-error:#d98f86;--nf-warn:#d9a660;--nf-info:#e69a6c;--nf-shadow:0 8px 16px -6px #0000008c, inset 0 6px 10px #ffffff1f, inset 0 -6px 10px #00000059;--nf-shadow-lg:0 16px 28px -10px #0000009e, inset 0 6px 10px #ffffff1f, inset 0 -6px 10px #0006;--nf-card-shadow:0 16px 28px -10px #0000009e, inset 0 -8px 12px #0006, inset 0 8px 12px #ffffff24;--nf-card-shadow-hover:0 22px 36px -12px #000000ad, inset 0 -8px 12px #00000070, inset 0 8px 12px #ffffff2e;--nf-glass-face:#37302b;--nf-glass-core:transparent;--nf-glass-sheen:#ffffff29;--nf-glass-border:#ffffff29;--nf-glass-inset:#2f2925;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-theme=clay] .zE6uZW_input,.zE6uZW_panel[data-nf-theme=clay] .zE6uZW_textarea{background:var(--nf-bg-inset);border-color:var(--nf-border-strong);box-shadow:inset 3px 3px 7px #78604824,inset -3px -3px 7px #ffffff80}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay] .zE6uZW_button{background:linear-gradient(#f6ecdf,#eee0cf);border-color:#fff9;box-shadow:0 8px 16px -6px #5a463259,inset 0 3px 4px #fffc,inset 0 -3px 5px #78604833}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay] .zE6uZW_button:hover:not([disabled]){box-shadow:0 12px 22px -8px #5a46326b,inset 0 3px 4px #ffffffd9,inset 0 -3px 5px #78604838}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay] .zE6uZW_buttonPrimary{color:var(--nf-accent-fg);background:linear-gradient(#eda178,#e08a5c);border-color:#0000;box-shadow:0 8px 16px -6px #e08a5c8c,inset 0 3px 4px #ffffff80,inset 0 -3px 5px #9646284d}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_button,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_button{background:linear-gradient(#403731,#332c27);border-color:#ffffff29;box-shadow:0 8px 16px -6px #0000008c,inset 0 3px 4px #ffffff24,inset 0 -3px 5px #0006}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_button:hover:not([disabled]),body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_button:hover:not([disabled]){box-shadow:0 12px 22px -8px #0009,inset 0 3px 4px #ffffff29,inset 0 -3px 5px #00000070}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_buttonPrimary,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_buttonPrimary{color:var(--nf-accent-fg);background:linear-gradient(#f0ac82,#d67a4a);border-color:#0000;box-shadow:0 8px 16px -6px #e69a6c80,inset 0 3px 4px #fff6,inset 0 -3px 5px #7832144d}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_input,.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_textarea,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_input,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_textarea{box-shadow:inset 3px 3px 7px #00000073,inset -3px -3px 7px #ffffff14}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input,body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea{background:var(--nf-bg-inset);border-color:#0000;box-shadow:inset 3px 3px 7px #a3b1c68c,inset -3px -3px 7px #ffffffe6}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input:focus,body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:inset 2px 2px 6px #a3b1c680, inset -2px -2px 6px #ffffffd9, 0 0 0 3px var(--nf-accent-soft)}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea{background:var(--nf-bg-inset);border-color:#0000;box-shadow:inset 3px 3px 7px #0000008c,inset -3px -3px 7px #6068763d}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input:focus,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:inset 2px 2px 6px #00000080, inset -2px -2px 6px #60687638, 0 0 0 3px var(--nf-accent-soft)}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button{background:var(--nf-bg-raise);border-color:#0000;box-shadow:5px 5px 10px #a3b1c68c,-5px -5px 10px #ffffffe6}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:hover:not([disabled]){background:var(--nf-bg-raise);border-color:#0000;box-shadow:7px 7px 14px #a3b1c699,-7px -7px 14px #fffffff2}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #a3b1c68c,inset -3px -3px 7px #ffffffe6}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_buttonPrimary{background:linear-gradient(#00c563,#00a952);box-shadow:5px 5px 10px #a3b1c699,-5px -5px 10px #ffffffd9}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button{background:var(--nf-bg-raise);border-color:#0000;box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:hover:not([disabled]){background:var(--nf-bg-raise);border-color:#0000;box-shadow:7px 7px 14px #0000008c,-7px -7px 14px #60687642}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #0000008c,inset -3px -3px 7px #6068763d}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_buttonPrimary{background:linear-gradient(#3ddc86,#27b96a);box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}.zE6uZW_panel{min-width:0;height:100%;font-size:var(--nf-fs-14,14px);flex-direction:column;line-height:1.6;display:flex;position:relative;overflow:hidden}.zE6uZW_panel:before{content:\"\";z-index:0;pointer-events:none;background:var(--nf-glass-bg-image,none) center / cover no-repeat, radial-gradient(46% 36% at 18% 12%, var(--nf-glass-orb-a), transparent 70%), radial-gradient(52% 42% at 88% 22%, var(--nf-glass-orb-b), transparent 72%), radial-gradient(120% 95% at 50% 42%, transparent 55%, #0202031a 100%);position:absolute;inset:0}.zE6uZW_panel[data-nf-theme=macos]{--nf-glass-bg-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='1000'%3E%3Cdefs%3E%3Cfilter id='b' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='140'/%3E%3C/filter%3E%3C/defs%3E%3Cg filter='url(%23b)'%3E%3Ccircle cx='320' cy='220' r='320' fill='%230a84ff' fill-opacity='0.34'/%3E%3Ccircle cx='1180' cy='320' r='360' fill='%237f5af0' fill-opacity='0.30'/%3E%3Ccircle cx='920' cy='820' r='380' fill='%2340cfc0' fill-opacity='0.26'/%3E%3Ccircle cx='1460' cy='820' r='260' fill='%23ff9fb0' fill-opacity='0.18'/%3E%3C/g%3E%3C/svg%3E\")}.zE6uZW_panelTitle{font-size:var(--nf-fs-16,16px);letter-spacing:.2px;align-items:center;gap:var(--nf-space-8,8px);margin:0;font-weight:700;display:flex}.zE6uZW_panelTitle:before{content:\"\";border-radius:var(--nf-radius-2,2px);background:linear-gradient(180deg, var(--nf-accent), var(--nf-info));width:4px;height:16px}.zE6uZW_iconButton{cursor:pointer;font-size:var(--nf-fs-16,16px);color:var(--nf-text-2);padding:var(--nf-space-4,4px) var(--nf-space-10,9px);border-radius:var(--nf-radius-10,9px);background:0 0;border:none;transition:background .15s,color .15s,transform .1s}.zE6uZW_iconButton:hover{background:var(--nf-hover);color:var(--nf-text);transform:translateY(-1px)}.zE6uZW_tabBar{gap:var(--nf-space-2,2px);padding:var(--nf-space-8,8px) var(--nf-space-14,14px) 0;border-bottom:1px solid var(--nf-border);background:var(--nf-bg-raise);z-index:4;flex-shrink:0;display:flex;position:sticky;top:45px}.zE6uZW_tab{padding:var(--nf-space-8,7px) var(--nf-space-14,13px);cursor:pointer;border-radius:var(--nf-radius-8,8px) var(--nf-radius-8,8px) 0 0;font-size:var(--nf-fs-14,13.5px);color:var(--nf-text-2);background:0 0;border:none;font-weight:500;transition:color .15s,background .15s;position:relative}.zE6uZW_tab:hover{color:var(--nf-text);background:var(--nf-hover)}.zE6uZW_tab[data-active]{color:var(--nf-accent);font-weight:600}.zE6uZW_tab[data-active]:after{content:\"\";border-radius:var(--nf-radius-2,2px) var(--nf-radius-2,2px) 0 0;background:var(--nf-accent);height:2.5px;position:absolute;bottom:-1px;left:10px;right:10px}.zE6uZW_panelContent{padding:var(--nf-container-pad,20px 22px);gap:var(--nf-container-gap,14px);z-index:1;flex-direction:column;flex:1;display:flex;position:relative;overflow:auto}.zE6uZW_panelBody{z-index:1;flex:1;min-height:0;display:flex;position:relative}.zE6uZW_panelNav{align-self:stretch;gap:var(--nf-space-6,6px);width:216px;padding:var(--nf-nav-pad,16px 12px 14px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-16,18px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(28px)saturate(175%);flex-direction:column;flex:none;margin:10px 0 10px 12px;transition:width .18s;display:flex;overflow-y:auto}.zE6uZW_panelNavCollapsed{width:52px;padding:var(--nf-space-10,10px) var(--nf-space-6,6px)}.zE6uZW_navGroup{gap:var(--nf-space-6,6px);flex-direction:column;display:flex}.zE6uZW_navGroupLabel{font-size:var(--nf-fs-12,12px);letter-spacing:.8px;text-transform:uppercase;color:var(--nf-text-3);padding:var(--nf-space-12,12px) var(--nf-space-10,10px) var(--nf-space-6,6px);user-select:none;font-weight:600}.zE6uZW_navGroupSep{background:var(--nf-border);height:1px;margin:6px 8px 4px}.zE6uZW_navSpacer{flex:1;min-height:8px}.zE6uZW_navAbout{gap:var(--nf-space-4,4px);padding:var(--nf-space-8,8px) var(--nf-space-6,6px) var(--nf-space-4,4px);border-top:1px solid var(--nf-border);flex-direction:column;flex:none;margin-top:4px;display:flex}.zE6uZW_navAboutRow{justify-content:space-between;align-items:center;gap:var(--nf-space-4,4px);cursor:pointer;font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);padding:var(--nf-space-4,4px) var(--nf-space-6,6px);border-radius:var(--nf-radius-8,8px);text-align:left;white-space:nowrap;background:0 0;border:none;transition:color .15s,background .15s;display:flex}.zE6uZW_navAboutRow:hover{color:var(--nf-text);background:var(--nf-hover)}.zE6uZW_navAboutUpdate{background:var(--nf-accent-soft);color:var(--nf-accent);cursor:pointer;font-size:var(--nf-fs-12,10.5px);padding:var(--nf-space-4,4px) var(--nf-space-6,6px);border-radius:var(--nf-radius-8,8px);text-align:left;white-space:nowrap;border:none;font-weight:600}.zE6uZW_navAboutUpdate:hover{color:var(--nf-accent-hover)}.zE6uZW_panelNavCollapsed .zE6uZW_navAbout{padding:var(--nf-space-6,6px) var(--nf-space-2,2px) var(--nf-space-2,2px);align-items:center}.zE6uZW_panelNavCollapsed .zE6uZW_navAboutRow{padding:var(--nf-space-4,4px) 0;justify-content:center;width:100%}.zE6uZW_navTabBadge{min-width:18px;height:18px;padding:0 var(--nf-space-6,5px);border-radius:var(--nf-radius-999,999px);background:var(--nf-accent);color:#fff;font-size:var(--nf-fs-12,10.5px);text-align:center;flex:none;margin-left:auto;font-weight:700;line-height:18px;display:inline-block}.zE6uZW_panelNavCollapsed .zE6uZW_navTabBadge{min-width:18px;height:18px;line-height:18px;font-size:var(--nf-fs-12,9px);padding:0 var(--nf-space-6,5px);position:absolute;top:2px;right:2px}.zE6uZW_navTabBadgeDanger{background:var(--nf-error)}.zE6uZW_navTabBadgeWarn{background:var(--nf-warn)}.zE6uZW_navTabBadgeDone{background:var(--nf-success)}.zE6uZW_navTabBadgeLive{background:var(--nf-success);animation:1.2s ease-in-out infinite zE6uZW_navBadgePulse}@keyframes zE6uZW_navBadgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.8)}}.zE6uZW_navTab{align-items:center;gap:var(--nf-space-10,10px);cursor:pointer;border-radius:var(--nf-radius-10,10px);width:100%;padding:var(--nf-space-12,11px) var(--nf-space-12,12px);font-size:var(--nf-fs-14,14px);color:var(--nf-text-2-alpha,var(--nf-text-2));text-align:left;white-space:nowrap;background:0 0;border:1px solid #0000;font-weight:500;transition:color .15s,background .15s,border-color .15s,box-shadow .15s;display:flex;position:relative}.zE6uZW_panelNavCollapsed .zE6uZW_navTab{padding:var(--nf-space-8,8px) 0;justify-content:center}.zE6uZW_navTab:hover{color:var(--nf-text);background:var(--nf-hover)}.zE6uZW_navTab[data-active]{color:var(--nf-accent);background:color-mix(in srgb, var(--nf-text) 8%, transparent);border-color:color-mix(in srgb, var(--nf-text) 16%, transparent);box-shadow:inset 0 1px 0 color-mix(in srgb, var(--nf-text) 6%, transparent);font-weight:600}.zE6uZW_navTab[data-active] .zE6uZW_navTabIcon{color:var(--nf-accent)}.zE6uZW_navTabIcon{text-align:center;width:22px;font-size:var(--nf-fs-16,17px);flex:none;line-height:1}.zE6uZW_navTabLabel{text-overflow:ellipsis;overflow:hidden}.zE6uZW_navTitle{align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-2,2px) var(--nf-space-6,6px) var(--nf-space-12,12px);border-bottom:1px solid var(--nf-border);flex:none;min-width:0;margin-bottom:6px;display:flex}.zE6uZW_navTitleLogo{border-radius:var(--nf-radius-10,10px);background:linear-gradient(145deg, var(--nf-accent), var(--nf-accent-hover));width:34px;height:34px;color:var(--nf-accent-fg);font-weight:800;font-size:var(--nf-fs-14,15px);box-shadow:0 6px 16px var(--nf-accent-soft);flex:none;justify-content:center;align-items:center;display:flex}.zE6uZW_navTitleName{font-weight:700;font-size:var(--nf-fs-14,15px);letter-spacing:.2px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_navTitleBook{font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_panelNavCollapsed .zE6uZW_navTitle{padding:var(--nf-space-2,2px) 0 var(--nf-space-10,10px);justify-content:center}.zE6uZW_panelNavCollapsed .zE6uZW_navTitleLogo{width:32px;height:var(--nf-ctrl-m,32px)}.zE6uZW_navActions{gap:var(--nf-space-6,6px);padding-top:var(--nf-space-8,8px);border-top:1px solid var(--nf-border);flex:none;margin-top:8px;display:flex}.zE6uZW_navActionBtn{border:1px solid var(--nf-border);color:var(--nf-text-2);cursor:pointer;border-radius:var(--nf-radius-10,10px);height:var(--nf-ctrl-m,32px);font-size:var(--nf-fs-14,14px);background:0 0;flex:1;justify-content:center;align-items:center;line-height:1;transition:background .15s,color .15s,border-color .15s;display:inline-flex}.zE6uZW_navActionBtn:hover{background:var(--nf-hover);color:var(--nf-text);border-color:var(--nf-border-strong)}.zE6uZW_panelNavCollapsed .zE6uZW_navActions{flex-direction:column;align-items:stretch}.zE6uZW_bookSwitch{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-10,9px);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);cursor:pointer;text-align:left;font:inherit;color:var(--nf-text);flex:none;min-width:0;margin-top:4px;transition:background .15s,border-color .15s;display:flex}.zE6uZW_bookSwitch:hover{background:var(--nf-hover);border-color:var(--nf-border-strong)}.zE6uZW_bookSwitchCover{border-radius:var(--nf-radius-6,5px);background:linear-gradient(160deg, var(--nf-accent), color-mix(in srgb, var(--nf-accent) 45%, #000));width:26px;height:34px;color:var(--nf-accent-fg);font-size:var(--nf-fs-12,11px);flex:none;justify-content:center;align-items:center;font-weight:700;display:flex}.zE6uZW_bookSwitchName{font-size:var(--nf-fs-12,12.5px);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.zE6uZW_bookSwitchMeta{font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_bookSwitchArrow{color:var(--nf-text-3);font-size:var(--nf-fs-12,12px);flex:none;margin-left:auto}.zE6uZW_statRowD{gap:var(--nf-space-12,12px);grid-template-columns:repeat(auto-fit,minmax(150px,1fr));display:grid}.zE6uZW_statCardD{justify-content:space-between;align-items:flex-start;gap:var(--nf-space-10,10px);padding:var(--nf-space-14,14px) var(--nf-space-16,16px);border-radius:var(--nf-radius-16,16px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);min-width:0;display:flex}.zE6uZW_statCardDLabel{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3)}.zE6uZW_statCardDValue{font-size:var(--nf-fs-22,22px);color:var(--nf-text);margin-top:2px;font-weight:700}.zE6uZW_statCardDUnit{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3);font-weight:400}.zE6uZW_statCardDDetail{font-size:var(--nf-fs-12,11.5px);color:var(--nf-text-3);text-overflow:ellipsis;white-space:nowrap;margin-top:2px;overflow:hidden}.zE6uZW_statCardDDown{color:var(--nf-error)}.zE6uZW_statCardDIcon{width:38px;height:var(--nf-ctrl-l,38px);border-radius:var(--nf-radius-12,12px);font-size:var(--nf-fs-18,18px);background:var(--nf-accent-soft);flex:none;justify-content:center;align-items:center;display:flex}.zE6uZW_statCardDIconRed{background:color-mix(in srgb, var(--nf-error) 13%, transparent)}.zE6uZW_tlBar{gap:var(--nf-space-6,6px);margin-top:8px;display:flex}.zE6uZW_tlSeg{gap:var(--nf-space-4,4px);cursor:pointer;min-width:0;font:inherit;background:0 0;border:none;flex-direction:column;flex:1;padding:0;display:flex}.zE6uZW_tlSegTrack{border-radius:var(--nf-radius-999,999px);background:var(--nf-hover);border:1px solid var(--nf-border);height:8px;overflow:hidden}.zE6uZW_tlSegFill{border-radius:var(--nf-radius-999,999px);background:var(--nf-accent);width:100%;height:100%;display:block}.zE6uZW_tlSegTodo .zE6uZW_tlSegFill{opacity:0}.zE6uZW_tlSegTodo .zE6uZW_tlSegTrack{background:0 0}.zE6uZW_tlSegCurrent .zE6uZW_tlSegTrack{border-color:var(--nf-accent);box-shadow:0 0 0 2px var(--nf-accent-soft)}.zE6uZW_tlSegCurrent .zE6uZW_tlSegFill{opacity:.45}.zE6uZW_tlSegLabel{font-size:var(--nf-fs-12,10.5px);color:var(--nf-text-3);text-align:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_tlSegDone .zE6uZW_tlSegLabel{color:var(--nf-accent);font-weight:600}.zE6uZW_tlSeg:hover .zE6uZW_tlSegTrack{border-color:var(--nf-border-strong)}.zE6uZW_card{border:var(--nf-card-border,1px solid var(--nf-glass-border));border-radius:var(--nf-card-radius,22px);padding:var(--nf-card-pad,20px 22px);gap:var(--nf-space-10,10px);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1.5px 0 var(--nf-card-sheen,var(--nf-glass-sheen)), inset 0 -1px 0 #ffffff1a;backdrop-filter:blur(var(--nf-card-blur,30px)) saturate(var(--nf-card-saturate,180%)) brightness(var(--nf-card-brightness,1.06));flex-direction:column;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.zE6uZW_card:before{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-core), linear-gradient(90deg, transparent, var(--nf-card-sheen,var(--nf-glass-sheen)), transparent) no-repeat 10% 0 / 80% 1px, linear-gradient(156deg, #ffffff42 0%, #fff0 55%);z-index:0;position:absolute;inset:0}.zE6uZW_card:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.zE6uZW_card:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1.5px 0 var(--nf-card-sheen,var(--nf-glass-sheen)), inset 0 -1px 0 #ffffff40;transform:translateY(-3px)}.zE6uZW_card>*{z-index:1;position:relative}.zE6uZW_cardTitle{font-size:var(--nf-fs-14,14px);color:var(--nf-text);align-items:center;gap:var(--nf-space-8,8px);margin:0;font-weight:650;display:flex}.zE6uZW_button{border:1px solid var(--nf-ctrl-border,var(--nf-border-strong));background:var(--nf-ctrl-bg,var(--nf-bg-inset));color:var(--nf-text);padding:var(--nf-space-8,7px) var(--nf-space-16,15px);border-radius:var(--nf-ctrl-radius,10px);cursor:pointer;font-size:var(--nf-fs-14,13px);box-shadow:inset 0 1px 0 var(--nf-ctrl-sheen,#ffffff17);white-space:nowrap;font-weight:500;transition:background .15s,border-color .15s,transform .1s,box-shadow .15s}.zE6uZW_button:hover:not([disabled]){background:var(--nf-hover);border-color:var(--nf-border-strong);transform:translateY(-1px)}.zE6uZW_button:active:not([disabled]){transform:translateY(0)scale(.97)}.zE6uZW_button[disabled]{opacity:.45;cursor:not-allowed}.zE6uZW_buttonPrimary{background:linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 88%, #fff), var(--nf-accent));color:var(--nf-accent-fg);border-radius:var(--nf-radius-10,10px);box-shadow:0 2px 10px color-mix(in srgb, var(--nf-accent) 45%, transparent), 0 0 0 .5px color-mix(in srgb, var(--nf-accent) 30%, transparent), inset 0 1px 0 #ffffff73;border-color:#0000}.zE6uZW_buttonPrimary:hover:not([disabled]){background:linear-gradient(180deg, var(--nf-accent-hover), color-mix(in srgb, var(--nf-accent-hover) 85%, #000));box-shadow:0 12px 30px color-mix(in srgb, var(--nf-accent) 50%, transparent), 0 0 0 .5px color-mix(in srgb, var(--nf-accent) 30%, transparent), inset 0 1px 0 #ffffff73;border-color:#0000;transform:translateY(-1px)}.zE6uZW_buttonDanger{border-color:var(--nf-error);color:var(--nf-error)}.zE6uZW_buttonDanger:hover:not([disabled]){background:#ff3b301a}.zE6uZW_buttonSmall{padding:var(--nf-space-4,4px) var(--nf-space-10,10px);font-size:var(--nf-fs-12,12px);border-radius:var(--nf-ctrl-radius,8px)}.zE6uZW_field{gap:var(--nf-space-6,5px);flex-direction:column;display:flex}.zE6uZW_fieldLabel{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);font-weight:500}.zE6uZW_input{border:var(--nf-ctrl-border,1px solid var(--nf-border-strong));background:var(--nf-ctrl-bg,var(--nf-bg-inset));color:var(--nf-text);color-scheme:light;border-radius:var(--nf-ctrl-radius,12px);padding:var(--nf-space-8,7px) var(--nf-space-12,11px);font-size:var(--nf-fs-14,13px);box-sizing:border-box;width:100%;box-shadow:inset 0 1px 0 var(--nf-ctrl-sheen,#ffffff17);transition:border-color .15s,box-shadow .15s}body[data-ds-dark-theme] .zE6uZW_input,.zE6uZW_panel[data-nf-mode=dark] .zE6uZW_input{color-scheme:dark}.zE6uZW_panel[data-nf-mode=light] .zE6uZW_input,body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input{color-scheme:light}select.zE6uZW_input{cursor:pointer;-webkit-appearance:none;appearance:none;background-image:linear-gradient(45deg, transparent 50%, var(--nf-ctrl-caret,var(--nf-text-3)) 50%), linear-gradient(135deg, var(--nf-ctrl-caret,var(--nf-text-3)) 50%, transparent 50%);background-position:calc(100% - 18px),calc(100% - 12px);background-repeat:no-repeat;background-size:6px 6px,6px 6px;padding-right:30px}.zE6uZW_input option{color:var(--nf-text);background:var(--nf-bg-raise);font-size:var(--nf-fs-14,15px)}.zE6uZW_input:focus,.zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft);outline:none}.zE6uZW_input::placeholder,.zE6uZW_textarea::placeholder{color:var(--nf-text-3)}.zE6uZW_textarea{border:var(--nf-ctrl-border,1px solid var(--nf-border-strong));background:var(--nf-ctrl-bg,var(--nf-bg-inset));color:var(--nf-text);border-radius:var(--nf-ctrl-radius,12px);padding:var(--nf-space-10,9px) var(--nf-space-12,11px);font-size:var(--nf-fs-14,13px);box-sizing:border-box;resize:vertical;width:100%;min-height:200px;font-family:inherit;line-height:1.7;transition:border-color .15s,box-shadow .15s}.zE6uZW_row{align-items:center;gap:var(--nf-space-8,8px);flex-wrap:wrap;display:flex}.zE6uZW_spaceBetween{justify-content:space-between}.zE6uZW_chapterList{gap:var(--nf-space-8,8px);flex-direction:column;display:flex}.zE6uZW_volumeGroup{gap:var(--nf-space-6,6px);flex-direction:column;display:flex}.zE6uZW_volumeGroupHeader{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);border-radius:var(--nf-radius-10,10px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);cursor:pointer;user-select:none;font-size:var(--nf-fs-14,13px);transition:border-color .15s;display:flex}.zE6uZW_volumeGroupHeader:hover{border-color:var(--nf-accent)}.zE6uZW_volumeGroupToggle{font-size:var(--nf-fs-12,11px);color:var(--nf-text-2);flex:none}.zE6uZW_chapter{align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-10,9px) var(--nf-space-12,12px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);background:var(--nf-bg);transition:border-color .15s,box-shadow .15s,transform .1s;display:flex}.zE6uZW_chapter:hover{border-color:var(--nf-border-strong);box-shadow:var(--nf-shadow)}.zE6uZW_chapterFocus{animation:.9s ease-in-out 3 zE6uZW_chapterFocusPulse;border-color:var(--nf-accent)!important;box-shadow:0 0 0 3px color-mix(in srgb, var(--nf-accent) 35%, transparent)!important}@keyframes zE6uZW_chapterFocusPulse{0%,to{background:var(--nf-bg)}50%{background:color-mix(in srgb, var(--nf-accent) 18%, var(--nf-bg))}}.zE6uZW_chapterNum{min-width:28px;height:var(--nf-ctrl-s,28px);padding:0 var(--nf-space-8,8px);border-radius:var(--nf-radius-8,8px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);flex-shrink:0;justify-content:center;align-items:center;font-weight:700;display:inline-flex}.zE6uZW_chapterMain{flex:1;min-width:0}.zE6uZW_chapterTitle{font-weight:600;font-size:var(--nf-fs-14,13px);align-items:center;gap:var(--nf-space-8,8px);color:var(--nf-text);display:flex}.zE6uZW_chapterBeats{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_chapterActions{gap:var(--nf-space-4,4px);opacity:.85;flex-shrink:0;transition:opacity .15s;display:flex}.zE6uZW_chapter:hover .zE6uZW_chapterActions{opacity:1}.zE6uZW_badge{font-size:var(--nf-fs-12,11px);padding:var(--nf-space-2,2px) var(--nf-space-10,9px);border-radius:var(--nf-radius-999,999px);white-space:nowrap;letter-spacing:.2px;border:1px solid;font-weight:600}.zE6uZW_badgePending{color:var(--nf-info);border-color:var(--nf-info);background:color-mix(in srgb, var(--nf-info) 10%, transparent)}.zE6uZW_badgeGenerating{color:var(--nf-accent);border-color:var(--nf-accent);background:color-mix(in srgb, var(--nf-accent) 12%, transparent);animation:1.2s ease-in-out infinite zE6uZW_pulse}.zE6uZW_badgeWritten{color:var(--nf-warn);border-color:var(--nf-warn);background:color-mix(in srgb, var(--nf-warn) 10%, transparent)}.zE6uZW_badgeRejected{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.zE6uZW_badgeDone{color:var(--nf-success);border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 10%, transparent)}.zE6uZW_badgeError{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.zE6uZW_reviewBox{border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);background:var(--nf-bg-inset);gap:var(--nf-space-6,6px);font-size:var(--nf-fs-12,12.5px);flex-direction:column;display:flex}.zE6uZW_chapterPreview{white-space:pre-wrap;word-break:break-all;max-height:320px;font-size:var(--nf-fs-12,12.5px);color:var(--nf-text);background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);margin:0;font-family:inherit;line-height:1.8;overflow:auto}.zE6uZW_chatScroll{gap:var(--nf-space-10,10px);min-height:240px;max-height:480px;padding:var(--nf-space-14,14px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);flex-direction:column;flex:1;display:flex;overflow-y:auto}.zE6uZW_chatBubbleUser{background:linear-gradient(180deg, var(--nf-accent), var(--nf-accent-hover));max-width:90%;color:var(--nf-accent-fg);border-radius:var(--nf-radius-14,14px) var(--nf-radius-14,14px) var(--nf-radius-4,4px) var(--nf-radius-14,14px);padding:var(--nf-space-10,9px) var(--nf-space-14,14px);font-size:var(--nf-fs-14,13px);align-self:flex-end;box-shadow:0 2px 6px #4d6bfe33}.zE6uZW_chatBubbleAssistant{background:var(--nf-bg-raise);max-width:92%;color:var(--nf-text);border:1px solid var(--nf-border);border-radius:var(--nf-radius-14,14px) var(--nf-radius-14,14px) var(--nf-radius-14,14px) var(--nf-radius-4,4px);padding:var(--nf-space-10,9px) var(--nf-space-14,14px);font-size:var(--nf-fs-14,13px);box-shadow:var(--nf-shadow);align-self:flex-start}.zE6uZW_chatRole{font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);margin-bottom:3px;font-weight:600}.zE6uZW_toolLive{padding:var(--nf-space-8,8px) var(--nf-space-10,10px);border-radius:var(--nf-radius-8,8px);background:var(--nf-bg-inset);border:1px dashed var(--nf-border-strong);font-size:var(--nf-fs-12,12px);white-space:pre-wrap;word-break:break-all;color:var(--nf-text-2);max-height:180px;margin-top:6px;line-height:1.7;overflow-y:auto}.zE6uZW_assistantStatus{padding:var(--nf-space-6,6px) var(--nf-space-12,12px);border-radius:var(--nf-radius-999,999px);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);background:var(--nf-bg-inset);border:1px solid var(--nf-border);align-items:center;gap:var(--nf-space-6,6px);flex:none;margin-top:6px;display:flex}.zE6uZW_assistantStatusBusy{color:var(--nf-accent);border-color:var(--nf-accent);background:var(--nf-accent-soft);font-weight:600}.zE6uZW_toolSteps{gap:var(--nf-space-4,4px);flex-direction:column;margin-top:6px;display:flex}.zE6uZW_toolStep{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-6,5px) var(--nf-space-10,10px);border-radius:var(--nf-radius-8,8px);font-size:var(--nf-fs-12,12px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);display:flex}.zE6uZW_toolStepActive{border-color:var(--nf-accent);background:var(--nf-accent-soft)}.zE6uZW_toolStepError{border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.zE6uZW_toolStepIcon{font-size:var(--nf-fs-14,13px);flex:none}.zE6uZW_toolStepName{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-weight:600;overflow:hidden}.zE6uZW_toolStepStatus{color:var(--nf-text-2);font-size:var(--nf-fs-12,11px);flex:none}.zE6uZW_toolStepActive .zE6uZW_toolStepStatus{color:var(--nf-accent)}.zE6uZW_toolStepError .zE6uZW_toolStepStatus{color:var(--nf-error)}.zE6uZW_toolStepDetail{width:100%;color:var(--nf-error);font-size:var(--nf-fs-12,11px);word-break:break-all}.zE6uZW_progress{border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-14,14px);font-size:var(--nf-fs-12,12px);white-space:pre-wrap;word-break:break-all;min-height:60px;max-height:220px;color:var(--nf-text-2);font-family:var(--nf-font-mono);background:var(--nf-bg-inset);line-height:1.8;overflow:auto}.zE6uZW_progressLine{color:var(--nf-text-2);opacity:.9}.zE6uZW_progressLineLive{color:var(--nf-accent);align-items:center;gap:var(--nf-space-8,8px);font-weight:600;display:flex}.zE6uZW_progressBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);flex:none;width:110px;height:6px;display:inline-block;overflow:hidden}.zE6uZW_progressBarFill{border-radius:var(--nf-radius-4,3px);background:var(--nf-accent);height:100%;transition:width .3s;display:block}.zE6uZW_busyRow{justify-content:space-between;align-items:center;gap:var(--nf-space-12,12px);flex-wrap:wrap;display:flex}.zE6uZW_liveText{font-size:var(--nf-fs-12,12px);font-variant-numeric:tabular-nums;color:var(--nf-text-2)}.zE6uZW_bigProgressBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);height:8px;margin-top:10px;overflow:hidden}.zE6uZW_bigProgressBarFill{border-radius:var(--nf-radius-999,999px);background:linear-gradient(90deg, var(--nf-accent), var(--nf-accent-2,var(--nf-accent)));height:100%;transition:width .3s;display:block}.zE6uZW_diffLegend{align-items:center;gap:var(--nf-space-14,14px);font-size:var(--nf-fs-12,12px);flex-wrap:wrap;margin:6px 0 8px;display:flex}.zE6uZW_legendOld{color:var(--nf-error);font-weight:700}.zE6uZW_legendNew{color:var(--nf-success);font-weight:700}.zE6uZW_onlyChanges{align-items:center;gap:var(--nf-space-4,4px);color:var(--nf-text-2);cursor:pointer;margin-left:auto;display:inline-flex}.zE6uZW_diffList{border:1px solid var(--nf-border);border-radius:var(--nf-radius-8,8px);background:var(--nf-bg-inset);min-height:0;padding:var(--nf-space-10,10px) var(--nf-space-12,12px);gap:var(--nf-space-8,8px);font-size:var(--nf-fs-14,13px);flex-direction:column;flex:1;line-height:1.7;display:flex;overflow-y:auto}.zE6uZW_diffSame{border:1px dashed var(--nf-border);border-radius:var(--nf-radius-6,6px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);color:var(--nf-text-2);opacity:.85}.zE6uZW_diffSame summary{cursor:pointer;font-size:var(--nf-fs-12,12px);user-select:none}.zE6uZW_diffSameBody{white-space:pre-wrap;margin-top:6px}.zE6uZW_diffChange{border:1px solid var(--nf-border);border-radius:var(--nf-radius-8,8px);grid-template-columns:1fr 1fr;display:grid;overflow:hidden}.zE6uZW_diffColumn{gap:var(--nf-space-6,6px);min-width:0;padding:var(--nf-space-8,8px) var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_diffColumn:first-child{border-right:1px solid var(--nf-border)}.zE6uZW_diffTagOld,.zE6uZW_diffTagNew{font-size:var(--nf-fs-12,11px);border-radius:var(--nf-radius-4,4px);padding:var(--nf-space-2,1px) var(--nf-space-8,7px);letter-spacing:.5px;flex:none;align-self:flex-start;font-weight:700}.zE6uZW_diffTagOld{color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 16%, transparent);border:1px solid color-mix(in srgb, var(--nf-error) 45%, transparent)}.zE6uZW_diffTagNew{color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 16%, transparent);border:1px solid color-mix(in srgb, var(--nf-success) 45%, transparent)}.zE6uZW_diffOld{color:var(--nf-error);white-space:pre-wrap;text-decoration:line-through;text-decoration-color:color-mix(in srgb, var(--nf-error) 55%, transparent)}.zE6uZW_diffNew{color:var(--nf-success);white-space:pre-wrap;font-weight:500}.zE6uZW_diffDel{gap:var(--nf-space-4,4px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);border-radius:var(--nf-radius-6,6px);border:1px solid color-mix(in srgb, var(--nf-error) 35%, transparent);background:color-mix(in srgb, var(--nf-error) 7%, transparent);flex-direction:column;display:flex}.zE6uZW_diffAdd{gap:var(--nf-space-4,4px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);border-radius:var(--nf-radius-6,6px);border:1px solid color-mix(in srgb, var(--nf-success) 35%, transparent);background:color-mix(in srgb, var(--nf-success) 7%, transparent);flex-direction:column;display:flex}.zE6uZW_diffText{white-space:pre-wrap}.zE6uZW_diffDel .zE6uZW_diffText{color:var(--nf-error);text-decoration:line-through;text-decoration-color:color-mix(in srgb, var(--nf-error) 50%, transparent)}.zE6uZW_diffAdd .zE6uZW_diffText{color:var(--nf-success)}.zE6uZW_wsPage{gap:var(--nf-space-10,10px);flex-direction:column;flex:1;min-height:0;display:flex}.zE6uZW_wsPageHeader{align-items:center;gap:var(--nf-space-8,8px);flex-wrap:wrap;flex:none;display:flex}.zE6uZW_wsAppliedBanner{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-12,12px);border:1px solid var(--nf-success);border-radius:var(--nf-radius-10,10px);background:color-mix(in srgb, var(--nf-success) 8%, transparent);font-size:var(--nf-fs-12,12px);flex-wrap:wrap;flex:none;font-weight:600;display:flex}.zE6uZW_wsColumns{gap:var(--nf-space-14,14px);flex:1;grid-template-columns:minmax(0,1fr) minmax(0,1fr);min-height:0;display:grid}.zE6uZW_wsColumn{gap:var(--nf-space-8,8px);flex-direction:column;min-width:0;min-height:0;display:flex}.zE6uZW_wsEditor{resize:vertical;min-height:0;font-family:var(--nf-font);font-size:var(--nf-fs-14,13px);white-space:pre-wrap;flex:1;line-height:1.75}.zE6uZW_wsSelected{border:1px solid var(--nf-accent);border-radius:var(--nf-radius-6,6px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);background:color-mix(in srgb, var(--nf-accent) 8%, transparent);max-height:120px;overflow:auto}.zE6uZW_wsSelectedText{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);white-space:pre-wrap;margin-top:4px}.zE6uZW_wsPreview{border:1px solid var(--nf-border);border-radius:var(--nf-radius-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-10,10px);gap:var(--nf-space-8,8px);background:var(--nf-bg-inset);flex-direction:column;display:flex}.zE6uZW_wsPreviewText{min-height:0;font-size:var(--nf-fs-14,13px);white-space:pre-wrap;color:var(--nf-text);flex:1;margin:0;line-height:1.7;overflow:auto}.zE6uZW_assetGrid{gap:var(--nf-space-10,10px);grid-template-columns:repeat(auto-fit,minmax(150px,1fr));display:grid}.zE6uZW_assetStat{border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-14,14px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);gap:var(--nf-space-4,4px);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(30px)saturate(180%);flex-direction:column;transition:transform .22s,box-shadow .22s;display:flex}.zE6uZW_assetStat:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1px 0 var(--nf-glass-sheen);transform:translateY(-3px)}.zE6uZW_assetStatLabel{font-size:var(--nf-fs-12,11px);color:var(--nf-text-2);opacity:.9}.zE6uZW_assetStatValue{font-size:var(--nf-fs-14,15px);color:var(--nf-text);font-weight:700;line-height:1.2}.zE6uZW_assetStatDetail{font-size:var(--nf-fs-12,11px);color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_dashHero{border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-22,22px);padding:var(--nf-card-pad,20px 22px);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;backdrop-filter:blur(30px)saturate(180%);gap:var(--nf-space-14,14px);flex-direction:column;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.zE6uZW_dashHero:before{content:\"\";border-radius:inherit;pointer-events:none;background:radial-gradient(46% 40% at 92% -10%, color-mix(in srgb, var(--nf-accent) 13%, transparent), transparent 62%), var(--nf-glass-core), linear-gradient(90deg, transparent, var(--nf-glass-sheen), transparent) no-repeat 10% 0 / 80% 1px, linear-gradient(156deg, #ffffff42 0%, #fff0 55%);z-index:0;position:absolute;inset:0}.zE6uZW_dashHero:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.zE6uZW_dashHero:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;transform:translateY(-3px)}.zE6uZW_dashHero>*{z-index:1;position:relative}.zE6uZW_dashHeroEyebrow{align-items:center;gap:var(--nf-space-6,6px);font-size:var(--nf-fs-14,13px);color:var(--nf-accent);font-weight:600;display:inline-flex}.zE6uZW_dashHeroSparkle{font-size:var(--nf-fs-14,14px)}.zE6uZW_dashHeroTitle{gap:var(--nf-space-2,2px);flex-direction:column;display:flex}.zE6uZW_dashHeroBook{font-size:var(--nf-fs-24,24px);letter-spacing:-.3px;margin:0;font-weight:700;line-height:1.25}.zE6uZW_dashHeroAction{align-items:center;gap:var(--nf-space-12,12px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-14,14px);background:var(--nf-glass-inset);box-shadow:inset 0 1px 0 var(--nf-glass-sheen);padding:var(--nf-space-10,10px) var(--nf-space-14,14px);display:flex}.zE6uZW_dashHeroArrow{width:28px;height:var(--nf-ctrl-s,28px);background:var(--nf-accent);color:#fff;font-size:var(--nf-fs-14,14px);border-radius:50%;flex:none;justify-content:center;align-items:center;display:inline-flex}.zE6uZW_dashHeroActionBody{gap:var(--nf-space-2,2px);flex-direction:column;flex:1;min-width:0;display:flex}.zE6uZW_dashHeroActionTitle{font-size:var(--nf-fs-14,14px);font-weight:600}.zE6uZW_dashJourney{gap:var(--nf-space-6,6px);flex-direction:column;display:flex}.zE6uZW_dashJourneyBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);height:6px;overflow:hidden}.zE6uZW_dashJourneyFill{border-radius:var(--nf-radius-999,999px);background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));height:100%;transition:width .4s;display:block}.zE6uZW_dashJourneyStages{gap:var(--nf-space-4,4px);grid-template-columns:repeat(6,minmax(0,1fr));display:grid}.zE6uZW_dashStage{align-items:center;gap:var(--nf-space-4,3px);font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);text-align:center;white-space:nowrap;flex-direction:column;display:flex}.zE6uZW_dashStageDot{border:1px solid var(--nf-border-strong,var(--nf-text-3));width:18px;height:18px;font-size:var(--nf-fs-12,10px);background:var(--nf-bg-base);border-radius:50%;justify-content:center;align-items:center;display:inline-flex}.zE6uZW_dashStageDone{color:var(--nf-text-2)}.zE6uZW_dashStageDone .zE6uZW_dashStageDot{background:var(--nf-success);border-color:var(--nf-success);color:#fff}.zE6uZW_dashStageCurrent{color:var(--nf-accent);font-weight:600}.zE6uZW_dashStageCurrent .zE6uZW_dashStageDot{border-color:var(--nf-accent);color:var(--nf-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--nf-accent) 18%, transparent)}.zE6uZW_dashFacts{gap:var(--nf-space-8,8px);border-top:1px solid var(--nf-border);padding-top:var(--nf-space-12,12px);grid-template-columns:repeat(4,minmax(0,1fr));display:grid}.zE6uZW_dashFact{gap:var(--nf-space-2,2px);flex-direction:column;min-width:0;display:flex}.zE6uZW_dashFact b{font-size:var(--nf-fs-14,13px);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_dashGrid{gap:var(--nf-space-14,14px);grid-template-columns:minmax(0,3fr) minmax(0,2fr);align-items:start;display:grid}.zE6uZW_todoItem{align-items:center;gap:var(--nf-space-10,10px);border-radius:var(--nf-radius-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-12,12px);font-size:var(--nf-fs-12,12.5px);border:1px solid var(--nf-border);display:flex}.zE6uZW_todoDanger{border-color:color-mix(in srgb, var(--nf-error) 40%, transparent);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.zE6uZW_todoWarning{border-color:color-mix(in srgb, var(--nf-warn) 40%, transparent);background:color-mix(in srgb, var(--nf-warn) 8%, transparent)}.zE6uZW_todoInfo{border-color:color-mix(in srgb, var(--nf-info) 40%, transparent);background:color-mix(in srgb, var(--nf-info) 7%, transparent)}.zE6uZW_todoText{gap:var(--nf-space-2,2px);flex-direction:column;flex:1;min-width:0;display:flex}.zE6uZW_outlineReadonly{padding:var(--nf-space-12,12px) var(--nf-space-14,14px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);font-size:var(--nf-fs-12,12.5px);white-space:pre-wrap;user-select:text;max-height:480px;margin:0;line-height:1.8;overflow:auto}.zE6uZW_bookCreateOutline{gap:var(--nf-space-6,6px);flex-direction:column;align-items:flex-start;display:flex}.zE6uZW_assistantFloat{z-index:80;border:1px solid var(--nf-border);border-radius:var(--nf-radius-16,16px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow-lg);flex-direction:column;min-width:320px;min-height:220px;display:flex;position:absolute;overflow:hidden}.zE6uZW_assistantFloatHeader{justify-content:space-between;align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-10,10px) var(--nf-space-8,8px) var(--nf-space-14,14px);cursor:grab;user-select:none;font-size:var(--nf-fs-14,13px);border-bottom:1px solid var(--nf-border);background:var(--nf-bg-inset);flex:none;font-weight:600;display:flex}.zE6uZW_assistantFloatHeader:active{cursor:grabbing}.zE6uZW_assistantFloatBody{min-height:0;padding:var(--nf-space-10,10px);flex:1;display:flex;overflow:hidden}.zE6uZW_assistantFloatBody>*{flex:1;min-width:0}.zE6uZW_assistantResize{cursor:nwse-resize;background:linear-gradient(135deg, transparent 0 55%, var(--nf-border-strong) 55% 62%, transparent 62%) no-repeat 4px 4px / 12px 12px;width:20px;height:20px;position:absolute;bottom:0;right:0}.zE6uZW_coverPreview{border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);flex:none;justify-content:center;align-items:center;width:150px;height:200px;display:flex;overflow:hidden}.zE6uZW_coverPreview img{object-fit:contain;width:100%;height:100%;display:block}.zE6uZW_coverPlaceholder{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3)}.zE6uZW_shelfView{min-height:0;padding:var(--nf-container-pad,20px 22px);gap:var(--nf-container-gap,14px);flex-direction:column;flex:1;display:flex;overflow:auto}.zE6uZW_shelfHeader{gap:var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_shelfHero{gap:var(--nf-space-14,14px);padding:var(--nf-card-pad,20px 22px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-22,22px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1.5px 0 var(--nf-glass-sheen);flex-direction:column;display:flex}.zE6uZW_shelfHero .zE6uZW_panelTitle{font-size:var(--nf-fs-22,22px);letter-spacing:.3px}.zE6uZW_shelfTitleRow{justify-content:space-between;align-items:center;gap:var(--nf-space-10,10px);flex-wrap:wrap;display:flex}.zE6uZW_shelfToolbar{align-items:center;gap:var(--nf-space-10,10px);flex-wrap:wrap;display:flex}.zE6uZW_shelfSearch{flex:1;min-width:180px;max-width:320px}.zE6uZW_shelfStats{gap:var(--nf-space-10,10px);grid-template-columns:repeat(auto-fit,minmax(120px,1fr));display:grid}.zE6uZW_shelfStat{justify-content:space-between;align-items:baseline;gap:var(--nf-space-8,8px);padding:var(--nf-space-10,10px) var(--nf-space-14,14px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-14,14px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);cursor:pointer;user-select:none;transition:border-color .15s,background .15s,box-shadow .15s,transform .1s;display:flex}.zE6uZW_shelfStat:hover{border-color:var(--nf-accent);transform:translateY(-1px)}.zE6uZW_shelfStatActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);box-shadow:0 0 0 2px var(--nf-accent-soft), var(--nf-shadow)}.zE6uZW_shelfStat b{font-size:var(--nf-fs-20,20px);color:var(--nf-accent);font-weight:800}.zE6uZW_shelfStat span{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2)}.zE6uZW_shelfFilters{gap:var(--nf-space-2,2px);padding:var(--nf-space-4,3px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-999,999px);background:var(--nf-bg-inset);display:inline-flex}.zE6uZW_shelfFilter{color:var(--nf-text-2);font-size:var(--nf-fs-12,12.5px);padding:var(--nf-space-6,5px) var(--nf-space-12,12px);border-radius:var(--nf-radius-999,999px);cursor:pointer;align-items:center;gap:var(--nf-space-6,5px);white-space:nowrap;background:0 0;border:none;font-weight:600;transition:background .15s,color .15s,box-shadow .15s;display:inline-flex}.zE6uZW_shelfFilter:hover{color:var(--nf-text)}.zE6uZW_shelfFilterActive{background:linear-gradient(135deg, var(--nf-accent), var(--nf-accent-hover));color:var(--nf-accent-fg);box-shadow:0 3px 12px color-mix(in srgb, var(--nf-accent) 40%, transparent)}.zE6uZW_shelfFilterCount{font-size:var(--nf-fs-12,10.5px);opacity:.8;background:color-mix(in srgb, currentColor 14%, transparent);border-radius:var(--nf-radius-999,999px);padding:0 var(--nf-space-6,6px)}.zE6uZW_shelfEmpty{justify-content:center;align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-40,40px) var(--nf-space-20,20px);border:1px dashed var(--nf-border-strong);border-radius:var(--nf-radius-16,16px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);text-align:center;flex-direction:column;flex:1;display:flex}.zE6uZW_shelfEmptyIcon{font-size:var(--nf-fs-42,42px)}.zE6uZW_shelfEmptyTitle{font-size:var(--nf-fs-16,16px);font-weight:700}.zE6uZW_shelfGrid{gap:var(--nf-container-gap,14px);grid-template-columns:repeat(auto-fill,minmax(190px,1fr));align-content:start;display:grid}.zE6uZW_panel{--nf-container-pad:20px 22px;--nf-container-gap:var(--nf-space-14,14px);--nf-card-pad:20px 22px;--nf-nav-pad:16px 12px 14px}.zE6uZW_panel[data-nf-density=compact]{--nf-container-pad:12px 14px;--nf-container-gap:var(--nf-space-8,8px);--nf-card-pad:12px 14px;--nf-nav-pad:8px 8px}.zE6uZW_panel[data-nf-density=spacious]{--nf-container-pad:24px 28px;--nf-container-gap:var(--nf-space-18,18px);--nf-card-pad:22px 26px;--nf-nav-pad:18px 14px}.zE6uZW_panel[data-nf-mode=light]{color-scheme:light;--nf-bg:#f2f2f7db;--nf-bg-raise:#ffffffb8;--nf-bg-inset:#7676801f;--nf-border:#3c3c4329;--nf-border-strong:#3c3c4352;--nf-text:#1c1c1e;--nf-text-2:#3c3c43;--nf-text-2-alpha:#3c3c43ad;--nf-text-3:#8e8e93;--nf-accent:#00b85c;--nf-accent-hover:#00a04e;--nf-accent-soft:#00b85c1f;--nf-accent-fg:#fff;--nf-hover:#0000000d;--nf-success:#34c759;--nf-error:#ff3b30;--nf-warn:#ff9500;--nf-info:#00b85c;--nf-shadow:0 1px 3px #0000000f, 0 12px 32px #00000014;--nf-shadow-lg:0 4px 12px #00000012, 0 20px 48px #0000001f;--nf-card-shadow:0 2px 6px #0000000f, 0 14px 38px #00000024;--nf-card-shadow-hover:0 4px 10px #00000014, 0 22px 52px #0003;--nf-glass-face:linear-gradient(180deg, #f6f7f9 0%, #f0f2f5 26%, #e9ebef 52%, #e0e3e8 78%, #d6d9df 100%);--nf-glass-core:radial-gradient(30% 24% at 36% 28%, #ffffff80 0%, #ffffff38 45%, #fff0 78%);--nf-glass-sheen:#ffffff8c;--nf-glass-border:#ffffffa6;--nf-glass-inset:#ffffff8c;--nf-glass-orb-a:#00b85c2e;--nf-glass-orb-b:#78a0ff21}.zE6uZW_panel[data-nf-mode=dark]{color-scheme:dark;--nf-bg:#0a0b0ddb;--nf-bg-raise:#1c1c1ec7;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff47;--nf-text:#f2f2f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b8;--nf-text-3:#8e8e93;--nf-accent:#35d07a;--nf-accent-hover:#5ce695;--nf-accent-soft:#35d07a33;--nf-accent-fg:#062b18;--nf-hover:#ffffff17;--nf-success:#30d158;--nf-error:#ff453a;--nf-warn:#ff9f0a;--nf-info:#35d07a;--nf-shadow:0 1px 2px #00000059, 0 10px 30px #0006;--nf-shadow-lg:0 4px 12px #0006, 0 20px 48px #0000008c;--nf-card-shadow:0 2px 6px #00000059, 0 14px 38px #00000073;--nf-card-shadow-hover:0 4px 10px #0006, 0 22px 52px #0000008c;--nf-glass-face:linear-gradient(180deg, #70747a6b 0%, #60646a6b 26%, #52555a6b 52%, #44474c6b 78%, #383a3f6b 100%);--nf-glass-core:radial-gradient(30% 24% at 36% 28%, #ffffff42 0%, #ffffff1a 45%, #fff0 78%);--nf-glass-sheen:#ffffff42;--nf-glass-border:#ffffff24;--nf-glass-inset:#ffffff12;--nf-glass-orb-a:#00ca5247;--nf-glass-orb-b:#bec8d71a}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=macos]{--nf-bg:#1c1c1ee6;--nf-bg-raise:#2c2c2ed1;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff42;--nf-text:#f5f5f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b3;--nf-text-3:#98989d;--nf-accent:#0a84ff;--nf-accent-hover:#3a9bff;--nf-accent-soft:#0a84ff33;--nf-accent-fg:#fff;--nf-hover:#ffffff0f;--nf-info:#bf5af2;--nf-shadow:0 1px 2px #0006, 0 10px 30px #00000073;--nf-shadow-lg:0 4px 12px #00000073, 0 18px 44px #0009;--nf-card-shadow:0 2px 6px #0006, 0 14px 38px #00000080;--nf-card-shadow-hover:0 4px 10px #00000073, 0 22px 52px #0009;--nf-glass-face:#2c2c2ed9;--nf-glass-core:transparent;--nf-glass-sheen:#fff3;--nf-glass-border:#ffffff2e;--nf-glass-inset:#ffffff0f;--nf-glass-orb-a:#0a84ff29;--nf-glass-orb-b:#bf5af214;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=neumorph]{--nf-bg:#2b2f36;--nf-bg-raise:#2b2f36;--nf-bg-inset:#25292f;--nf-border:#0a0c1080;--nf-border-strong:#080a0e99;--nf-text:#d6dae1;--nf-text-2:#a8aeb8;--nf-text-2-alpha:#a8aeb8b3;--nf-text-3:#757c88;--nf-hover:#ffffff0d;--nf-shadow:4px 4px 10px #00000080, -4px -4px 10px #6068763d;--nf-shadow-lg:6px 6px 14px #0000008c, -6px -6px 14px #60687642;--nf-card-shadow:9px 9px 18px #00000080, -9px -9px 18px #6068763d;--nf-card-shadow-hover:12px 12px 24px #0009, -12px -12px 24px #60687647;--nf-glass-face:#2b2f36;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#0c0e1273;--nf-glass-inset:#25292f;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=light][data-nf-theme=neumorph]{--nf-bg:#e4e9f2;--nf-bg-raise:#e4e9f2;--nf-bg-inset:#d9dfe8;--nf-border:#8c9baf59;--nf-border-strong:#78879e80;--nf-text:#3a4250;--nf-text-2:#5b6472;--nf-text-2-alpha:#465060b3;--nf-text-3:#8b94a3;--nf-hover:#5a697d14;--nf-shadow:4px 4px 10px #a3b1c68c, -4px -4px 10px #ffffffd9;--nf-shadow-lg:6px 6px 14px #a3b1c699, -6px -6px 14px #ffffffe6;--nf-card-shadow:9px 9px 18px #a3b1c68c, -9px -9px 18px #ffffffd9;--nf-card-shadow-hover:12px 12px 24px #a3b1c6a6, -12px -12px 24px #fffffff2;--nf-glass-face:#e4e9f2;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#a3b1c666;--nf-glass-inset:#d9dfe8;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_bookCard{gap:var(--nf-space-8,8px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-16,16px);padding:var(--nf-space-12,12px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow);cursor:pointer;flex-direction:column;transition:border-color .15s,transform .1s,box-shadow .15s;display:flex}.zE6uZW_bookCard:hover{border-color:var(--nf-accent);box-shadow:var(--nf-shadow-lg);transform:translateY(-2px)}.zE6uZW_bookCardActive{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft)}.zE6uZW_bookCardCover{aspect-ratio:3/4;border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);flex:none;justify-content:center;align-items:center;display:flex;position:relative;overflow:hidden}.zE6uZW_bookCardCover img{object-fit:cover;width:100%;height:100%;transition:transform .35s;display:block}.zE6uZW_bookCard:hover .zE6uZW_bookCardCover img{transform:scale(1.06)}.zE6uZW_bookCardCover:after{content:\"\";border-radius:inherit;pointer-events:none;opacity:0;background:linear-gradient(#0000 55%,#00000047);transition:opacity .25s;position:absolute;inset:0}.zE6uZW_bookCard:hover .zE6uZW_bookCardCover:after{opacity:1}.zE6uZW_bookCardCoverFallback{justify-content:center;align-items:center;gap:var(--nf-space-6,6px);background:radial-gradient(400px 200px at 80% -20%, color-mix(in srgb, var(--nf-accent) 25%, transparent), transparent 70%), linear-gradient(155deg, var(--nf-bg-inset), color-mix(in srgb, var(--nf-accent) 10%, var(--nf-bg-inset)));flex-direction:column;width:100%;height:100%;display:flex}.zE6uZW_bookCardCoverTitle{font-size:var(--nf-fs-22,22px);color:var(--nf-accent);letter-spacing:2px;font-weight:800}.zE6uZW_bookCardBody{gap:var(--nf-space-6,5px);flex-direction:column;flex:1;min-width:0;display:flex}.zE6uZW_bookCardTitleRow{justify-content:space-between;align-items:center;gap:var(--nf-space-6,6px);display:flex}.zE6uZW_bookCardName{font-weight:700;font-size:var(--nf-fs-14,13.5px);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_bookCardBlurb{-webkit-line-clamp:2;-webkit-box-orient:vertical;min-height:34px;display:-webkit-box;overflow:hidden}.zE6uZW_bookCardMetaRow{justify-content:space-between;align-items:center;gap:var(--nf-space-6,6px);flex-wrap:wrap;display:flex}.zE6uZW_bookCardProgressBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);height:6px;overflow:hidden;box-shadow:inset 0 1px 2px #0000001f}.zE6uZW_bookCardProgressFill{border-radius:var(--nf-radius-999,999px);background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));height:100%;transition:width .3s;display:block}.zE6uZW_bookAddCard{justify-content:center;align-items:center;gap:var(--nf-space-8,8px);text-align:center;color:var(--nf-text-2);border-style:dashed;min-height:260px;transition:border-color .15s,color .15s,background .15s,transform .15s}.zE6uZW_bookAddCard:hover{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent);transform:translateY(-2px)}.zE6uZW_bookAddIcon{font-size:var(--nf-fs-34,34px);color:var(--nf-accent);line-height:1;transition:transform .15s}.zE6uZW_bookAddCard:hover .zE6uZW_bookAddIcon{transform:scale(1.12)}.zE6uZW_bookCreateCard{border-color:var(--nf-accent);min-height:260px}.zE6uZW_createBookView{min-height:0;padding:var(--nf-container-pad,20px 22px);gap:var(--nf-container-gap,14px);flex-direction:column;flex:1;display:flex;overflow:auto}.zE6uZW_createBookTop{align-items:center;display:flex}.zE6uZW_createBookCard{align-self:center;gap:var(--nf-space-12,12px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-20,20px);width:min(520px,100%);padding:var(--nf-card-pad,20px 22px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow-lg);flex-direction:column;display:flex}.zE6uZW_createBookIcon{font-size:var(--nf-fs-34,34px);line-height:1}.zE6uZW_createBookTitle{font-size:var(--nf-fs-22,22px);letter-spacing:-.3px;margin:0;font-weight:800}.zE6uZW_ideaCard{gap:var(--nf-space-8,8px);border:1px dashed var(--nf-border-strong);border-radius:var(--nf-radius-14,14px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);background:color-mix(in srgb, var(--nf-accent) 3%, transparent);flex-direction:column;display:flex}.zE6uZW_ideaToggle{align-items:center;gap:var(--nf-space-6,6px);color:var(--nf-accent);font-size:var(--nf-fs-14,13px);cursor:pointer;text-align:left;background:0 0;border:none;padding:0;font-weight:700;display:flex}.zE6uZW_ideaCandidate{gap:var(--nf-space-6,6px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);background:var(--nf-bg);flex-direction:column;display:flex}.zE6uZW_progressLineDone{color:var(--nf-success);font-weight:600}.zE6uZW_progressLineError{color:var(--nf-error);font-weight:600}.zE6uZW_meta{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);opacity:.9}.zE6uZW_genreDesc{-webkit-line-clamp:2;-webkit-box-orient:vertical;max-width:560px;display:-webkit-box;overflow:hidden}.zE6uZW_fileList{gap:var(--nf-space-4,3px);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);opacity:.9;word-break:break-all;flex-direction:column;display:flex}.zE6uZW_panelContent::-webkit-scrollbar,.zE6uZW_chatScroll::-webkit-scrollbar,.zE6uZW_chapterPreview::-webkit-scrollbar,.zE6uZW_progress::-webkit-scrollbar,.zE6uZW_toolLive::-webkit-scrollbar{width:8px;height:8px}.zE6uZW_panelContent::-webkit-scrollbar-thumb,.zE6uZW_chatScroll::-webkit-scrollbar-thumb,.zE6uZW_chapterPreview::-webkit-scrollbar-thumb,.zE6uZW_progress::-webkit-scrollbar-thumb,.zE6uZW_toolLive::-webkit-scrollbar-thumb{background:var(--nf-border-strong);border-radius:var(--nf-radius-4,4px)}.zE6uZW_panelContent::-webkit-scrollbar-thumb:hover,.zE6uZW_chatScroll::-webkit-scrollbar-thumb:hover,.zE6uZW_chapterPreview::-webkit-scrollbar-thumb:hover,.zE6uZW_progress::-webkit-scrollbar-thumb:hover,.zE6uZW_toolLive::-webkit-scrollbar-thumb:hover{background:var(--nf-text-3)}.zE6uZW_workflowList{flex-direction:column;gap:0;display:flex}.zE6uZW_workflowRow{align-items:flex-start;gap:var(--nf-space-12,12px);padding:var(--nf-space-8,8px) var(--nf-space-4,4px);display:flex;position:relative}.zE6uZW_workflowRow:before{content:\"\";background:var(--nf-border);width:2px;position:absolute;top:34px;bottom:-8px;left:13px}.zE6uZW_workflowRow:last-child:before{display:none}.zE6uZW_workflowDot{width:28px;height:var(--nf-ctrl-s,28px);font-size:var(--nf-fs-12,12px);border:2px solid var(--nf-border-strong);background:var(--nf-bg-raise);color:var(--nf-text-2);z-index:1;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-weight:700;display:inline-flex}.zE6uZW_workflowDotDone{border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 15%, var(--nf-bg-raise));color:var(--nf-success)}.zE6uZW_workflowDotActive{border-color:var(--nf-accent);background:var(--nf-accent);color:var(--nf-accent-fg);box-shadow:0 0 0 4px var(--nf-accent-soft)}.zE6uZW_workflowBody{gap:var(--nf-space-4,4px);min-width:0;padding-top:var(--nf-space-2,2px);flex-direction:column;flex:1;display:flex}.zE6uZW_workflowLabel{font-size:var(--nf-fs-14,13px);color:var(--nf-text);font-weight:600}.zE6uZW_workflowHint{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2)}@keyframes zE6uZW_pulse{0%,to{opacity:1}50%{opacity:.45}}@keyframes zE6uZW_fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.zE6uZW_card{animation:.2s zE6uZW_fadeIn}.zE6uZW_bookshelf{align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-8,8px) var(--nf-space-14,14px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-16,16px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(26px)saturate(175%);z-index:1;flex-wrap:wrap;flex-shrink:0;margin:10px 12px 0;display:flex;position:relative}.zE6uZW_bookshelfLabel{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3);letter-spacing:1px;flex-shrink:0;font-weight:700}.zE6uZW_bookshelfList{align-items:center;gap:var(--nf-space-6,6px);flex-wrap:wrap;flex:1;min-width:0;display:flex}.zE6uZW_bookChip{align-items:center;gap:var(--nf-space-6,6px);padding:var(--nf-space-4,4px) var(--nf-space-8,8px) var(--nf-space-4,4px) var(--nf-space-10,10px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-999,999px);background:var(--nf-bg-inset);cursor:pointer;font-size:var(--nf-fs-12,12px);max-width:220px;transition:border-color .15s,background .15s;display:flex}.zE6uZW_bookChip:hover{border-color:var(--nf-border-strong)}.zE6uZW_bookChipActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.zE6uZW_bookChipName{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.zE6uZW_bookChipMeta{font-size:var(--nf-fs-12,11px);opacity:.7;white-space:nowrap}.zE6uZW_bookChipRemove{color:var(--nf-text-3);cursor:pointer;font-size:var(--nf-fs-14,13px);padding:0 var(--nf-space-2,2px);border-radius:var(--nf-radius-4,4px);background:0 0;border:none;line-height:1}.zE6uZW_bookChipRemove:hover{color:var(--nf-error)}.zE6uZW_bookAdd{border:1px dashed var(--nf-border-strong);color:var(--nf-text-2);cursor:pointer;font-size:var(--nf-fs-12,12px);padding:var(--nf-space-4,4px) var(--nf-space-12,12px);border-radius:var(--nf-radius-999,999px);background:0 0;transition:border-color .15s,color .15s}.zE6uZW_bookAdd:hover{border-color:var(--nf-accent);color:var(--nf-accent)}.zE6uZW_bookCreateForm{align-items:center;gap:var(--nf-space-6,6px);display:flex}.zE6uZW_dropzone{border:2px dashed var(--nf-border-strong);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-18,18px) var(--nf-space-14,14px);text-align:center;font-size:var(--nf-fs-14,13px);color:var(--nf-text-2);cursor:pointer;align-items:center;gap:var(--nf-space-6,6px);flex-direction:column;transition:border-color .15s,background .15s;display:flex}.zE6uZW_dropzone:hover,.zE6uZW_dropzoneActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.zE6uZW_dropzoneIcon{font-size:var(--nf-fs-22,22px);line-height:1}.zE6uZW_bookCardActions{align-items:center;gap:var(--nf-space-6,6px);padding-top:var(--nf-space-8,8px);margin-top:auto;display:flex}.zE6uZW_bookCardActions .zE6uZW_button{flex:1;justify-content:center}.zE6uZW_readerView{flex-direction:column;transition:background .2s,color .2s;display:flex;position:absolute;inset:0;overflow:hidden}.zE6uZW_readerHeader{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-12,12px);border-bottom:1px solid;flex-wrap:wrap;flex:none;display:flex}.zE6uZW_readerTitle{font-weight:700;font-size:var(--nf-fs-14,14px)}.zE6uZW_readerSeg{align-items:center;gap:var(--nf-space-2,2px);border-radius:var(--nf-radius-8,8px);display:flex;overflow:hidden}.zE6uZW_readerSegBtn{font-size:var(--nf-fs-12,12px);padding:var(--nf-space-4,3px) var(--nf-space-8,8px);border-radius:var(--nf-radius-6,6px);cursor:pointer;opacity:.75;background:0 0;border:none}.zE6uZW_readerSegBtn:hover,.zE6uZW_readerSegActive{opacity:1}.zE6uZW_readerBody{flex:1;align-items:stretch;min-height:0;display:flex}.zE6uZW_readerSidebar{width:220px;min-width:220px;padding:var(--nf-space-8,8px) var(--nf-space-6,6px) var(--nf-space-24,24px);scrollbar-width:thin;gap:var(--nf-space-10,10px);border-right:1px solid;flex-direction:column;flex:none;display:flex;overflow-y:auto}.zE6uZW_readerGroup{gap:var(--nf-space-2,1px);flex-direction:column;display:flex}.zE6uZW_readerGroupTitle{align-items:center;gap:var(--nf-space-6,6px);width:100%;font-size:var(--nf-fs-12,12px);padding:var(--nf-space-6,6px) var(--nf-space-8,8px) var(--nf-space-4,4px);opacity:.9;cursor:pointer;text-align:left;border-radius:var(--nf-radius-6,6px);background:0 0;border:none;font-weight:700;display:flex}.zE6uZW_readerGroupTitle:hover{opacity:1;background:#8080801f}.zE6uZW_readerGroupArrow{font-size:var(--nf-fs-12,10px);text-align:center;flex:none;width:12px}.zE6uZW_readerGroupCount{font-size:var(--nf-fs-12,11px);opacity:.6;padding-right:var(--nf-space-2,2px);flex:none;margin-left:auto;font-weight:400}.zE6uZW_readerItem{align-items:center;gap:var(--nf-space-6,6px);border-radius:var(--nf-radius-8,8px);font-size:var(--nf-fs-12,12px);text-align:left;padding:var(--nf-space-4,4px) var(--nf-space-8,8px);cursor:pointer;opacity:.8;background:0 0;border:1px solid;min-width:0;transition:opacity .15s,background .15s;display:flex}.zE6uZW_readerItem:hover{opacity:1}.zE6uZW_readerItemActive{opacity:1;font-weight:700}.zE6uZW_readerItemNo{text-align:right;opacity:.75;flex:none;min-width:26px;font-weight:700}.zE6uZW_readerItemTitle{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.zE6uZW_readerItemBadge{font-size:var(--nf-fs-12,11px);flex:none}.zE6uZW_readerMain{min-height:0;padding:var(--nf-space-20,20px) var(--nf-space-16,16px) var(--nf-space-48,48px);scrollbar-width:thin;flex:1;justify-content:center;display:flex;overflow-y:auto}.zE6uZW_readerArticle{gap:var(--nf-space-12,12px);flex-direction:column;width:100%;display:flex}.zE6uZW_readerChapterTitle{font-size:var(--nf-fs-24,24px);letter-spacing:1px;margin:0;font-weight:800}.zE6uZW_readerChapterMeta{align-items:center;gap:var(--nf-space-8,8px);font-size:var(--nf-fs-12,12px);display:flex}.zE6uZW_readerText{text-align:justify;letter-spacing:.02em}.zE6uZW_readerPara{text-indent:2em;margin:0 0 .85em}.zE6uZW_readerFoot{justify-content:space-between;align-items:center;gap:var(--nf-space-8,8px);padding-top:var(--nf-space-12,12px);border-top:1px dashed;margin-top:12px;display:flex}.zE6uZW_readerLoading,.zE6uZW_readerError{padding:var(--nf-space-32,32px) 0;font-size:var(--nf-fs-14,13px);opacity:.7;align-self:center}.zE6uZW_readerError{color:var(--nf-error)}.zE6uZW_importModalOverlay{z-index:1000;backdrop-filter:blur(4px);padding:var(--nf-space-24,24px);background:#00000073;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.zE6uZW_importModal{gap:var(--nf-space-12,12px);border:1px solid var(--nf-border-strong);border-radius:var(--nf-radius-16,16px);width:min(520px,100%);max-height:85vh;padding:var(--nf-card-pad,20px 22px);background:var(--nf-bg-raise);backdrop-filter:blur(28px)saturate(180%);box-shadow:var(--nf-shadow-lg);flex-direction:column;display:flex;overflow:auto}.zE6uZW_importModalHead{justify-content:space-between;align-items:center;gap:var(--nf-space-10,10px);display:flex}.zE6uZW_importModalTabs{gap:var(--nf-space-8,8px);display:flex}.zE6uZW_importModalTabs .zE6uZW_button{flex:1}.zE6uZW_importModalBody{gap:var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_importField{gap:var(--nf-space-6,5px);font-size:var(--nf-fs-14,13px);color:var(--nf-text-2);flex-direction:column;display:flex}.zE6uZW_importHint{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3);line-height:1.5}.zE6uZW_importError{border:1px solid color-mix(in srgb, var(--nf-danger,#e5484d) 55%, transparent);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-8,8px) var(--nf-space-10,10px);font-size:var(--nf-fs-12,12.5px);color:var(--nf-danger,#e5484d);background:color-mix(in srgb, var(--nf-danger,#e5484d) 10%, transparent);white-space:pre-wrap;word-break:break-all}.zE6uZW_importResult{gap:var(--nf-space-4,4px);border:1px solid color-mix(in srgb, var(--nf-ok,#46a758) 45%, transparent);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);font-size:var(--nf-fs-14,13px);background:color-mix(in srgb, var(--nf-ok,#46a758) 9%, transparent);word-break:break-all;flex-direction:column;display:flex}.zE6uZW_importModalActions{justify-content:flex-end;gap:var(--nf-space-8,8px);display:flex}.zE6uZW_importFileInfo{align-items:center;gap:var(--nf-space-8,8px);font-size:var(--nf-fs-14,13px);color:var(--nf-text-1);flex-wrap:wrap;display:flex}.zE6uZW_importPreview{gap:var(--nf-space-4,4px);border:1px solid var(--nf-border-strong);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);font-size:var(--nf-fs-14,13px);background:var(--nf-bg-inset);flex-direction:column;display:flex}.zE6uZW_importPreviewList{padding-left:var(--nf-space-18,18px);gap:var(--nf-space-2,2px);font-size:var(--nf-fs-12,12.5px);color:var(--nf-text-2);flex-direction:column;max-height:140px;margin:0;display:flex;overflow:auto}.zE6uZW_settingsCard .zE6uZW_fieldLabel{white-space:nowrap;text-overflow:ellipsis;max-width:100%;min-height:18px;line-height:18px;overflow:hidden}.zE6uZW_settingsCard .zE6uZW_row{align-items:flex-start}.zE6uZW_helpTipText{width:280px;max-width:70vw;padding:var(--nf-space-10,10px) var(--nf-space-12,12px);border-radius:var(--nf-radius-10,10px);background:var(--nf-bg-raise);border:1px solid var(--nf-border-strong);box-shadow:var(--nf-shadow-lg);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);white-space:normal;z-index:20;text-align:left;pointer-events:none;font-weight:400;line-height:1.7;display:none;position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%)}.zE6uZW_helpTip:hover .zE6uZW_helpTipText,.zE6uZW_helpTip:focus .zE6uZW_helpTipText,.zE6uZW_helpTip:focus-within .zE6uZW_helpTipText{display:block}.zE6uZW_settingsCard+.zE6uZW_settingsCard{flex:1;min-height:0}.zE6uZW_switch{border-radius:var(--nf-radius-999,999px);border:1px solid var(--nf-border-strong);background:var(--nf-bg-inset);cursor:pointer;flex:none;width:42px;height:24px;padding:0;transition:background .18s,border-color .18s;position:relative}.zE6uZW_switchKnob{background:#fff;border-radius:50%;width:16px;height:16px;transition:transform .18s;position:absolute;top:3px;left:3px;box-shadow:0 1px 3px #0000004d}.zE6uZW_switchOn{background:var(--nf-accent);border-color:var(--nf-accent)}.zE6uZW_switchOn .zE6uZW_switchKnob{transform:translate(18px)}";
|
|
35428
|
+
const css = ".zE6uZW_entry{align-items:center;gap:var(--nf-space-8,8px);width:100%;padding:var(--nf-space-8,8px) var(--nf-space-12,12px);color:var(--dsw-alias-label-primary,#1f1f23);cursor:pointer;text-align:left;border-radius:var(--nf-radius-6,6px);background:0 0;border:none;font-size:14px;transition:background .15s;display:flex}body[data-ds-dark-theme] .zE6uZW_entry{color:var(--dsw-alias-label-primary,#ececf1)}.zE6uZW_entry:hover{background:var(--dsw-alias-interactive-bg-hover,#7f7f7f1f)}.zE6uZW_entry[data-active]{background:var(--dsw-alias-interactive-bg-active,#7f7f7f33)}.zE6uZW_entryIcon{flex-shrink:0;justify-content:center;align-items:center;width:20px;height:20px;display:inline-flex}.zE6uZW_entryLabel{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}[data-pane=conversation]{position:relative}.zE6uZW_view{z-index:60;color-scheme:light;--nf-font:-apple-system, BlinkMacSystemFont, \"SF Pro Display\", \"SF Pro Text\", \"PingFang SC\", \"Hiragino Sans GB\", \"Microsoft YaHei\", \"Segoe UI\", Roboto, \"Helvetica Neue\", sans-serif;--nf-font-mono:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;--nf-bg:#f2f2f7db;--nf-bg-raise:#ffffffb8;--nf-bg-inset:#7676801f;--nf-border:#3c3c4329;--nf-border-strong:#3c3c4352;--nf-text:#1c1c1e;--nf-text-2:#3c3c43;--nf-text-2-alpha:#3c3c43ad;--nf-text-3:#8e8e93;--nf-accent:#00b85c;--nf-accent-hover:#00a04e;--nf-accent-soft:#00b85c1f;--nf-accent-fg:#fff;--nf-hover:#0000000d;--nf-success:#34c759;--nf-error:#ff3b30;--nf-warn:#ff9500;--nf-info:#00b85c;--nf-shadow:0 1px 3px #0000000f, 0 12px 32px #00000014;--nf-shadow-lg:0 4px 12px #00000012, 0 20px 48px #0000001f;--nf-card-shadow:0 2px 6px #0000000f, 0 14px 38px #00000024;--nf-card-shadow-hover:0 4px 10px #00000014, 0 22px 52px #0003;--nf-glass-face:linear-gradient(180deg, #fff6 0%, #ffffff4d 26%, #ffffff3d 52%, #fff3 78%, #ffffff2e 100%);--nf-glass-core:radial-gradient(60% 40% at 30% 0%, #fff9 0%, #fff3 42%, #fff0 78%);--nf-glass-sheen:#ffffff8c;--nf-glass-border:#ffffff80;--nf-glass-inset:#fff6;--nf-glass-orb-a:#00b85c3d;--nf-glass-orb-b:#78a0ff33;--nf-glass-noise:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E\");--nf-card-radius:20px;--nf-card-blur:26px;--nf-card-saturate:170%;--nf-card-brightness:1.04;--nf-card-sheen:#ffffff80;--nf-card-border:1px solid #ffffff59;--nf-ctrl-radius:14px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid #ffffffb3;--nf-ctrl-sheen:#ffffff80;--nf-ctrl-caret:var(--nf-accent);--nf-glass-bg-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='1000'%3E%3Cdefs%3E%3Cfilter id='b' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='110'/%3E%3C/filter%3E%3C/defs%3E%3Cg filter='url(%23b)'%3E%3Ccircle cx='300' cy='180' r='420' fill='%2335d07a' fill-opacity='0.62'/%3E%3Ccircle cx='1240' cy='260' r='470' fill='%233aa7ff' fill-opacity='0.58'/%3E%3Ccircle cx='900' cy='860' r='470' fill='%2340cfc0' fill-opacity='0.5'/%3E%3Ccircle cx='1500' cy='820' r='330' fill='%23ff9fb0' fill-opacity='0.4'/%3E%3Ccircle cx='600' cy='620' r='260' fill='%23b06ef0' fill-opacity='0.42'/%3E%3Ccircle cx='180' cy='600' r='220' fill='%23ffd166' fill-opacity='0.36'/%3E%3C/g%3E%3C/svg%3E\");background:var(--nf-bg);backdrop-filter:blur(30px)saturate(170%)brightness(1.04);color:var(--nf-text);--nf-fs-10:10px;--nf-fs-12:12px;--nf-fs-14:14px;--nf-fs-16:16px;--nf-fs-18:18px;--nf-fs-20:20px;--nf-fs-22:22px;--nf-fs-24:24px;--nf-fs-34:34px;--nf-fs-42:42px;--nf-icon-s:14px;--nf-icon-m:16px;--nf-icon-l:18px;--nf-icon-xl:22px;--nf-space-2:2px;--nf-space-4:4px;--nf-space-6:6px;--nf-space-8:8px;--nf-space-10:10px;--nf-space-12:12px;--nf-space-14:14px;--nf-space-16:16px;--nf-space-18:18px;--nf-space-20:20px;--nf-space-24:24px;--nf-space-28:28px;--nf-space-32:32px;--nf-radius-2:2px;--nf-radius-4:4px;--nf-radius-6:6px;--nf-radius-8:8px;--nf-radius-10:10px;--nf-radius-12:12px;--nf-radius-14:14px;--nf-radius-16:16px;--nf-radius-20:20px;--nf-radius-22:22px;--nf-radius-999:999px;--nf-ctrl-s:28px;--nf-ctrl-m:32px;--nf-ctrl-l:38px;--nf-container-pad:20px 22px;--nf-container-gap:var(--nf-space-14,14px);--nf-card-pad:20px 22px;--nf-nav-pad:16px 12px 14px;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Segoe UI,Roboto,Helvetica Neue,sans-serif;display:none;position:absolute;inset:0;overflow:auto}.zE6uZW_panel[data-nf-mode=dark],body[data-ds-dark-theme] .zE6uZW_panel:not([data-nf-mode]),.zE6uZW_view:has(>.zE6uZW_panel[data-nf-mode=dark]),body[data-ds-dark-theme] .zE6uZW_view:not(:has(>.zE6uZW_panel[data-nf-mode=light])){color-scheme:dark;--nf-bg:#0a0b0ddb;--nf-bg-raise:#1c1c1ec7;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff47;--nf-text:#f2f2f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b8;--nf-text-3:#8e8e93;--nf-accent:#35d07a;--nf-accent-hover:#5ce695;--nf-accent-soft:#35d07a33;--nf-accent-fg:#062b18;--nf-hover:#ffffff17;--nf-success:#30d158;--nf-error:#ff453a;--nf-warn:#ff9f0a;--nf-info:#35d07a;--nf-shadow:0 1px 2px #00000059, 0 10px 30px #0006;--nf-shadow-lg:0 4px 12px #0006, 0 20px 48px #0000008c;--nf-card-shadow:0 2px 6px #00000059, 0 14px 38px #00000073;--nf-card-shadow-hover:0 4px 10px #0006, 0 22px 52px #0000008c;--nf-glass-face:linear-gradient(180deg, #3e424a85 0%, #363a4275 26%, #30343c66 52%, #2a2e365c 78%, #262a3257 100%);--nf-glass-core:radial-gradient(60% 40% at 30% 0%, #ffffff38 0%, #ffffff14 42%, #fff0 78%);--nf-glass-sheen:#ffffff3d;--nf-glass-border:#ffffff24;--nf-glass-inset:#ffffff14;--nf-glass-orb-a:#00ca525c;--nf-glass-orb-b:#78a0ff47;--nf-glass-noise:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E\");--nf-card-radius:20px;--nf-card-blur:28px;--nf-card-saturate:165%;--nf-card-brightness:1;--nf-card-border:1px solid #ffffff24;--nf-card-sheen:#ffffff38;--nf-glass-bg-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='1000'%3E%3Cdefs%3E%3Cfilter id='b' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='110'/%3E%3C/filter%3E%3C/defs%3E%3Cg filter='url(%23b)'%3E%3Ccircle cx='300' cy='180' r='420' fill='%231a9f4d' fill-opacity='0.44'/%3E%3Ccircle cx='1240' cy='260' r='470' fill='%23268bd6' fill-opacity='0.40'/%3E%3Ccircle cx='900' cy='860' r='470' fill='%232a9e94' fill-opacity='0.36'/%3E%3Ccircle cx='1500' cy='820' r='330' fill='%23e07a94' fill-opacity='0.30'/%3E%3Ccircle cx='600' cy='620' r='260' fill='%238c5bd6' fill-opacity='0.32'/%3E%3C/g%3E%3C/svg%3E\");--nf-ctrl-radius:14px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid #ffffff2e;--nf-ctrl-sheen:#fff3;--nf-ctrl-caret:var(--nf-accent)}html[data-dsh-novelforge-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) .zE6uZW_view{display:block}.zE6uZW_panel[data-nf-theme=macos],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-mode=light][data-nf-theme=macos]{--nf-bg:#f5f6f8eb;--nf-bg-raise:#ffffffc7;--nf-bg-inset:#7676801a;--nf-border:#3c3c4324;--nf-border-strong:#3c3c434d;--nf-text:#1d1d1f;--nf-text-2:#3a3a3c;--nf-text-2-alpha:#3a3a3cb3;--nf-text-3:#86868b;--nf-accent:#007aff;--nf-accent-hover:#0071e3;--nf-accent-soft:#007aff1f;--nf-accent-fg:#fff;--nf-hover:#0000000a;--nf-info:#5856d6;--nf-shadow:0 1px 3px #0000000d, 0 10px 28px #00000012;--nf-shadow-lg:0 4px 12px #0000000f, 0 18px 44px #0000001c;--nf-card-shadow:0 2px 6px #0000000d, 0 12px 34px #00000017;--nf-card-shadow-hover:0 4px 10px #00000012, 0 20px 48px #00000024;--nf-glass-face:#ffffffb3;--nf-glass-core:transparent;--nf-glass-sheen:#fffc;--nf-glass-border:#ffffffe6;--nf-glass-inset:#fff9;--nf-glass-orb-a:#007aff14;--nf-glass-orb-b:#5856d612;--nf-glass-noise:none;--nf-card-radius:12px;--nf-card-blur:42px;--nf-card-saturate:150%;--nf-card-border:1px solid var(--nf-border);--nf-card-sheen:#ffffff59;--nf-ctrl-radius:8px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid var(--nf-border-strong);--nf-ctrl-sheen:#ffffff59;--nf-ctrl-caret:var(--nf-accent)}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=macos],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=macos]:not([data-nf-mode]){--nf-bg:#1c1c1ee6;--nf-bg-raise:#2c2c2ed1;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff42;--nf-text:#f5f5f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b3;--nf-text-3:#98989d;--nf-accent:#0a84ff;--nf-accent-hover:#3a9bff;--nf-accent-soft:#0a84ff33;--nf-accent-fg:#fff;--nf-hover:#ffffff0f;--nf-info:#bf5af2;--nf-shadow:0 1px 2px #0006, 0 10px 30px #00000073;--nf-shadow-lg:0 4px 12px #00000073, 0 18px 44px #0009;--nf-card-shadow:0 2px 6px #0006, 0 14px 38px #00000080;--nf-card-shadow-hover:0 4px 10px #00000073, 0 22px 52px #0009;--nf-glass-face:#2c2c2ed9;--nf-glass-core:transparent;--nf-glass-sheen:#fff3;--nf-glass-border:#ffffff2e;--nf-glass-inset:#ffffff0f;--nf-glass-orb-a:#0a84ff29;--nf-glass-orb-b:#bf5af214;--nf-glass-noise:none}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_button{border:1px solid var(--nf-border-strong);background:color-mix(in srgb, var(--nf-bg-raise) 82%, #fff);box-shadow:0 1px 1px #0000000a,inset 0 1px #fff9}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_buttonPrimary{background:linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 90%, #fff), var(--nf-accent));color:var(--nf-accent-fg);box-shadow:0 1px 3px color-mix(in srgb, var(--nf-accent) 45%, transparent), inset 0 1px 0 #ffffff59;border-color:#0000}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_input,.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_textarea{border:1px solid var(--nf-border-strong);background:var(--nf-bg-raise)}.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_input:focus,.zE6uZW_panel[data-nf-theme=macos] .zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft)}.zE6uZW_panel[data-nf-theme=neumorph]{--nf-card-radius:20px;--nf-card-blur:0px;--nf-card-saturate:100%;--nf-card-border:none;--nf-card-sheen:#fff0;--nf-ctrl-radius:10px;--nf-ctrl-bg:var(--nf-bg-inset);--nf-ctrl-border:none;--nf-ctrl-sheen:#fff0;--nf-ctrl-caret:var(--nf-text-3);--nf-glass-bg-image:none}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph]{--nf-bg:#e4e9f2;--nf-bg-raise:#e4e9f2;--nf-bg-inset:#d9dfe8;--nf-border:#8c9baf59;--nf-border-strong:#78879e80;--nf-text:#3a4250;--nf-text-2:#5b6472;--nf-text-2-alpha:#465060b3;--nf-text-3:#8b94a3;--nf-hover:#5a697d14;--nf-shadow:4px 4px 10px #a3b1c68c, -4px -4px 10px #ffffffd9;--nf-shadow-lg:6px 6px 14px #a3b1c699, -6px -6px 14px #ffffffe6;--nf-card-shadow:9px 9px 18px #a3b1c68c, -9px -9px 18px #ffffffd9;--nf-card-shadow-hover:12px 12px 24px #a3b1c6a6, -12px -12px 24px #fffffff2;--nf-glass-face:#e4e9f2;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#a3b1c666;--nf-glass-inset:#d9dfe8;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=neumorph],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph]:not([data-nf-mode]){--nf-bg:#2b2f36;--nf-bg-raise:#2b2f36;--nf-bg-inset:#25292f;--nf-border:#0a0c1080;--nf-border-strong:#080a0e99;--nf-text:#d6dae1;--nf-text-2:#a8aeb8;--nf-text-2-alpha:#a8aeb8b3;--nf-text-3:#757c88;--nf-hover:#ffffff0d;--nf-shadow:4px 4px 10px #00000080, -4px -4px 10px #6068763d;--nf-shadow-lg:6px 6px 14px #0000008c, -6px -6px 14px #60687642;--nf-card-shadow:9px 9px 18px #00000080, -9px -9px 18px #6068763d;--nf-card-shadow-hover:12px 12px 24px #0009, -12px -12px 24px #60687647;--nf-glass-face:#2b2f36;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#0c0e1273;--nf-glass-inset:#25292f;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-theme=clay]{--nf-card-radius:28px;--nf-card-blur:0px;--nf-card-saturate:100%;--nf-card-brightness:1;--nf-card-border:1px solid #fff9;--nf-card-sheen:#ffffffd9;--nf-ctrl-radius:16px;--nf-ctrl-bg:var(--nf-bg-raise);--nf-ctrl-border:1px solid #ffffff8c;--nf-ctrl-sheen:#ffffffb3;--nf-ctrl-caret:var(--nf-accent);--nf-glass-bg-image:none}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay],.zE6uZW_panel[data-nf-mode=light][data-nf-theme=clay]{--nf-bg:#f2eae0;--nf-bg-raise:#efe4d6;--nf-bg-inset:#e6d8c6;--nf-border:#78604829;--nf-border-strong:#78604847;--nf-text:#3a3330;--nf-text-2:#5a4f48;--nf-text-2-alpha:#5a4f48b3;--nf-text-3:#9a8c80;--nf-accent:#e08a5c;--nf-accent-hover:#d67a4a;--nf-accent-soft:#e08a5c29;--nf-accent-fg:#fff;--nf-hover:#78604814;--nf-success:#7fae6a;--nf-error:#c96b63;--nf-warn:#d9a660;--nf-info:#e08a5c;--nf-shadow:0 8px 16px -6px #5a463247, inset 0 6px 10px #ffffff8c, inset 0 -6px 10px #7860481f;--nf-shadow-lg:0 16px 28px -10px #5a463257, inset 0 6px 10px #ffffff8c, inset 0 -6px 10px #78604824;--nf-card-shadow:0 16px 28px -10px #5a463257, inset 0 -8px 12px #78604824, inset 0 8px 12px #fff9;--nf-card-shadow-hover:0 22px 36px -12px #5a463261, inset 0 -8px 12px #78604829, inset 0 8px 12px #ffffffb3;--nf-glass-face:#efe4d6;--nf-glass-core:transparent;--nf-glass-sheen:#ffffffd9;--nf-glass-border:#fff9;--nf-glass-inset:#e6d8c6;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]){--nf-bg:#2a2522;--nf-bg-raise:#37302b;--nf-bg-inset:#2f2925;--nf-border:#ffffff14;--nf-border-strong:#ffffff2e;--nf-text:#efe9e3;--nf-text-2:#c7beb5;--nf-text-2-alpha:#c7beb5b3;--nf-text-3:#8a8078;--nf-accent:#e69a6c;--nf-accent-hover:#f0ac82;--nf-accent-soft:#e69a6c33;--nf-accent-fg:#241b16;--nf-hover:#ffffff0f;--nf-success:#9cba82;--nf-error:#d98f86;--nf-warn:#d9a660;--nf-info:#e69a6c;--nf-shadow:0 8px 16px -6px #0000008c, inset 0 6px 10px #ffffff1f, inset 0 -6px 10px #00000059;--nf-shadow-lg:0 16px 28px -10px #0000009e, inset 0 6px 10px #ffffff1f, inset 0 -6px 10px #0006;--nf-card-shadow:0 16px 28px -10px #0000009e, inset 0 -8px 12px #0006, inset 0 8px 12px #ffffff24;--nf-card-shadow-hover:0 22px 36px -12px #000000ad, inset 0 -8px 12px #00000070, inset 0 8px 12px #ffffff2e;--nf-glass-face:#37302b;--nf-glass-core:transparent;--nf-glass-sheen:#ffffff29;--nf-glass-border:#ffffff29;--nf-glass-inset:#2f2925;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-theme=clay] .zE6uZW_input,.zE6uZW_panel[data-nf-theme=clay] .zE6uZW_textarea{background:var(--nf-bg-inset);border-color:var(--nf-border-strong);box-shadow:inset 3px 3px 7px #78604824,inset -3px -3px 7px #ffffff80}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay] .zE6uZW_button{background:linear-gradient(#f6ecdf,#eee0cf);border-color:#fff9;box-shadow:0 8px 16px -6px #5a463259,inset 0 3px 4px #fffc,inset 0 -3px 5px #78604833}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay] .zE6uZW_button:hover:not([disabled]){box-shadow:0 12px 22px -8px #5a46326b,inset 0 3px 4px #ffffffd9,inset 0 -3px 5px #78604838}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay] .zE6uZW_buttonPrimary{color:var(--nf-accent-fg);background:linear-gradient(#eda178,#e08a5c);border-color:#0000;box-shadow:0 8px 16px -6px #e08a5c8c,inset 0 3px 4px #ffffff80,inset 0 -3px 5px #9646284d}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_button,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_button{background:linear-gradient(#403731,#332c27);border-color:#ffffff29;box-shadow:0 8px 16px -6px #0000008c,inset 0 3px 4px #ffffff24,inset 0 -3px 5px #0006}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_button:hover:not([disabled]),body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_button:hover:not([disabled]){box-shadow:0 12px 22px -8px #0009,inset 0 3px 4px #ffffff29,inset 0 -3px 5px #00000070}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_buttonPrimary,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_buttonPrimary{color:var(--nf-accent-fg);background:linear-gradient(#f0ac82,#d67a4a);border-color:#0000;box-shadow:0 8px 16px -6px #e69a6c80,inset 0 3px 4px #fff6,inset 0 -3px 5px #7832144d}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_input,.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay] .zE6uZW_textarea,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_input,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]) .zE6uZW_textarea{box-shadow:inset 3px 3px 7px #00000073,inset -3px -3px 7px #ffffff14}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input,body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea{background:var(--nf-bg-inset);border-color:#0000;box-shadow:inset 3px 3px 7px #a3b1c68c,inset -3px -3px 7px #ffffffe6}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input:focus,body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:inset 2px 2px 6px #a3b1c680, inset -2px -2px 6px #ffffffd9, 0 0 0 3px var(--nf-accent-soft)}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea{background:var(--nf-bg-inset);border-color:#0000;box-shadow:inset 3px 3px 7px #0000008c,inset -3px -3px 7px #6068763d}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input:focus,body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:inset 2px 2px 6px #00000080, inset -2px -2px 6px #60687638, 0 0 0 3px var(--nf-accent-soft)}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button{background:var(--nf-bg-raise);border-color:#0000;box-shadow:5px 5px 10px #a3b1c68c,-5px -5px 10px #ffffffe6}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:hover:not([disabled]){background:var(--nf-bg-raise);border-color:#0000;box-shadow:7px 7px 14px #a3b1c699,-7px -7px 14px #fffffff2}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #a3b1c68c,inset -3px -3px 7px #ffffffe6}body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_buttonPrimary{background:linear-gradient(#00c563,#00a952);box-shadow:5px 5px 10px #a3b1c699,-5px -5px 10px #ffffffd9}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button{background:var(--nf-bg-raise);border-color:#0000;box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:hover:not([disabled]){background:var(--nf-bg-raise);border-color:#0000;box-shadow:7px 7px 14px #0000008c,-7px -7px 14px #60687642}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #0000008c,inset -3px -3px 7px #6068763d}body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_buttonPrimary{background:linear-gradient(#3ddc86,#27b96a);box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}.zE6uZW_panel{min-width:0;height:100%;font-size:var(--nf-fs-14,14px);flex-direction:column;line-height:1.6;display:flex;position:relative;overflow:hidden}.zE6uZW_panel:before{content:\"\";z-index:0;pointer-events:none;background:linear-gradient(rgba(0, 0, 0, calc(var(--nf-glass-bg-dim,0) / 100)), rgba(0, 0, 0, calc(var(--nf-glass-bg-dim,0) / 100))), var(--nf-glass-bg-image,none) center / cover no-repeat, radial-gradient(46% 36% at 18% 12%, var(--nf-glass-orb-a), transparent 70%), radial-gradient(52% 42% at 88% 22%, var(--nf-glass-orb-b), transparent 72%), radial-gradient(120% 95% at 50% 42%, transparent 55%, #0202031a 100%);position:absolute;inset:0}.zE6uZW_panel[data-nf-theme=macos]{--nf-glass-bg-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1600' height='1000'%3E%3Cdefs%3E%3Cfilter id='b' x='-20%25' y='-20%25' width='140%25' height='140%25'%3E%3CfeGaussianBlur stdDeviation='140'/%3E%3C/filter%3E%3C/defs%3E%3Cg filter='url(%23b)'%3E%3Ccircle cx='320' cy='220' r='320' fill='%230a84ff' fill-opacity='0.34'/%3E%3Ccircle cx='1180' cy='320' r='360' fill='%237f5af0' fill-opacity='0.30'/%3E%3Ccircle cx='920' cy='820' r='380' fill='%2340cfc0' fill-opacity='0.26'/%3E%3Ccircle cx='1460' cy='820' r='260' fill='%23ff9fb0' fill-opacity='0.18'/%3E%3C/g%3E%3C/svg%3E\")}.zE6uZW_panelTitle{font-size:var(--nf-fs-16,16px);letter-spacing:.2px;align-items:center;gap:var(--nf-space-8,8px);margin:0;font-weight:700;display:flex}.zE6uZW_panelTitle:before{content:\"\";border-radius:var(--nf-radius-2,2px);background:linear-gradient(180deg, var(--nf-accent), var(--nf-info));width:4px;height:16px}.zE6uZW_iconButton{cursor:pointer;font-size:var(--nf-fs-16,16px);color:var(--nf-text-2);padding:var(--nf-space-4,4px) var(--nf-space-10,9px);border-radius:var(--nf-radius-10,9px);background:0 0;border:none;transition:background .15s,color .15s,transform .1s}.zE6uZW_iconButton:hover{background:var(--nf-hover);color:var(--nf-text);transform:translateY(-1px)}.zE6uZW_tabBar{gap:var(--nf-space-2,2px);padding:var(--nf-space-8,8px) var(--nf-space-14,14px) 0;border-bottom:1px solid var(--nf-border);background:var(--nf-bg-raise);z-index:4;flex-shrink:0;display:flex;position:sticky;top:45px}.zE6uZW_tab{padding:var(--nf-space-8,7px) var(--nf-space-14,13px);cursor:pointer;border-radius:var(--nf-radius-8,8px) var(--nf-radius-8,8px) 0 0;font-size:var(--nf-fs-14,13.5px);color:var(--nf-text-2);background:0 0;border:none;font-weight:500;transition:color .15s,background .15s;position:relative}.zE6uZW_tab:hover{color:var(--nf-text);background:var(--nf-hover)}.zE6uZW_tab[data-active]{color:var(--nf-accent);font-weight:600}.zE6uZW_tab[data-active]:after{content:\"\";border-radius:var(--nf-radius-2,2px) var(--nf-radius-2,2px) 0 0;background:var(--nf-accent);height:2.5px;position:absolute;bottom:-1px;left:10px;right:10px}.zE6uZW_panelContent{padding:var(--nf-container-pad,20px 22px);gap:var(--nf-container-gap,14px);z-index:1;flex-direction:column;flex:1;display:flex;position:relative;overflow:auto}.zE6uZW_panelBody{z-index:1;flex:1;min-height:0;display:flex;position:relative}.zE6uZW_panelNav{align-self:stretch;gap:var(--nf-space-6,6px);width:216px;padding:var(--nf-nav-pad,16px 12px 14px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-16,18px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(28px)saturate(175%);flex-direction:column;flex:none;margin:10px 0 10px 12px;transition:width .18s;display:flex;overflow-y:auto}.zE6uZW_panelNavCollapsed{width:52px;padding:var(--nf-space-10,10px) var(--nf-space-6,6px)}.zE6uZW_navGroup{gap:var(--nf-space-6,6px);flex-direction:column;display:flex}.zE6uZW_navGroupLabel{font-size:var(--nf-fs-12,12px);letter-spacing:.8px;text-transform:uppercase;color:var(--nf-text-3);padding:var(--nf-space-12,12px) var(--nf-space-10,10px) var(--nf-space-6,6px);user-select:none;font-weight:600}.zE6uZW_navGroupSep{background:var(--nf-border);height:1px;margin:6px 8px 4px}.zE6uZW_navSpacer{flex:1;min-height:8px}.zE6uZW_navAbout{gap:var(--nf-space-4,4px);padding:var(--nf-space-8,8px) var(--nf-space-6,6px) var(--nf-space-4,4px);border-top:1px solid var(--nf-border);flex-direction:column;flex:none;margin-top:4px;display:flex}.zE6uZW_navAboutRow{justify-content:space-between;align-items:center;gap:var(--nf-space-4,4px);cursor:pointer;font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);padding:var(--nf-space-4,4px) var(--nf-space-6,6px);border-radius:var(--nf-radius-8,8px);text-align:left;white-space:nowrap;background:0 0;border:none;transition:color .15s,background .15s;display:flex}.zE6uZW_navAboutRow:hover{color:var(--nf-text);background:var(--nf-hover)}.zE6uZW_navAboutUpdate{background:var(--nf-accent-soft);color:var(--nf-accent);cursor:pointer;font-size:var(--nf-fs-12,10.5px);padding:var(--nf-space-4,4px) var(--nf-space-6,6px);border-radius:var(--nf-radius-8,8px);text-align:left;white-space:nowrap;border:none;font-weight:600}.zE6uZW_navAboutUpdate:hover{color:var(--nf-accent-hover)}.zE6uZW_panelNavCollapsed .zE6uZW_navAbout{padding:var(--nf-space-6,6px) var(--nf-space-2,2px) var(--nf-space-2,2px);align-items:center}.zE6uZW_panelNavCollapsed .zE6uZW_navAboutRow{padding:var(--nf-space-4,4px) 0;justify-content:center;width:100%}.zE6uZW_navTabBadge{min-width:18px;height:18px;padding:0 var(--nf-space-6,5px);border-radius:var(--nf-radius-999,999px);background:var(--nf-accent);color:#fff;font-size:var(--nf-fs-12,10.5px);text-align:center;flex:none;margin-left:auto;font-weight:700;line-height:18px;display:inline-block}.zE6uZW_panelNavCollapsed .zE6uZW_navTabBadge{min-width:18px;height:18px;line-height:18px;font-size:var(--nf-fs-12,9px);padding:0 var(--nf-space-6,5px);position:absolute;top:2px;right:2px}.zE6uZW_navTabBadgeDanger{background:var(--nf-error)}.zE6uZW_navTabBadgeWarn{background:var(--nf-warn)}.zE6uZW_navTabBadgeDone{background:var(--nf-success)}.zE6uZW_navTabBadgeLive{background:var(--nf-success);animation:1.2s ease-in-out infinite zE6uZW_navBadgePulse}@keyframes zE6uZW_navBadgePulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.35;transform:scale(.8)}}.zE6uZW_navTab{align-items:center;gap:var(--nf-space-10,10px);cursor:pointer;border-radius:var(--nf-radius-10,10px);width:100%;padding:var(--nf-space-12,11px) var(--nf-space-12,12px);font-size:var(--nf-fs-14,14px);color:var(--nf-text-2-alpha,var(--nf-text-2));text-align:left;white-space:nowrap;background:0 0;border:1px solid #0000;font-weight:500;transition:color .15s,background .15s,border-color .15s,box-shadow .15s;display:flex;position:relative}.zE6uZW_panelNavCollapsed .zE6uZW_navTab{padding:var(--nf-space-8,8px) 0;justify-content:center}.zE6uZW_navTab:hover{color:var(--nf-text);background:var(--nf-hover)}.zE6uZW_navTab[data-active]{color:var(--nf-accent);background:color-mix(in srgb, var(--nf-text) 8%, transparent);border-color:color-mix(in srgb, var(--nf-text) 16%, transparent);box-shadow:inset 0 1px 0 color-mix(in srgb, var(--nf-text) 6%, transparent);font-weight:600}.zE6uZW_navTab[data-active] .zE6uZW_navTabIcon{color:var(--nf-accent)}.zE6uZW_navTabIcon{text-align:center;width:22px;height:22px;font-size:var(--nf-fs-16,17px);flex:none;justify-content:center;align-items:center;line-height:1;display:inline-flex}.zE6uZW_navTabLabel{text-overflow:ellipsis;overflow:hidden}.zE6uZW_navTitle{align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-2,2px) var(--nf-space-6,6px) var(--nf-space-12,12px);border-bottom:1px solid var(--nf-border);flex:none;min-width:0;margin-bottom:6px;display:flex}.zE6uZW_navTitleLogo{border-radius:var(--nf-radius-10,10px);background:linear-gradient(145deg, var(--nf-accent), var(--nf-accent-hover));width:34px;height:34px;color:var(--nf-accent-fg);font-weight:800;font-size:var(--nf-fs-14,15px);box-shadow:0 6px 16px var(--nf-accent-soft);flex:none;justify-content:center;align-items:center;display:flex}.zE6uZW_navTitleName{font-weight:700;font-size:var(--nf-fs-14,15px);letter-spacing:.2px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_navTitleBook{font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_panelNavCollapsed .zE6uZW_navTitle{padding:var(--nf-space-2,2px) 0 var(--nf-space-10,10px);justify-content:center}.zE6uZW_panelNavCollapsed .zE6uZW_navTitleLogo{width:32px;height:var(--nf-ctrl-m,32px)}.zE6uZW_navActions{gap:var(--nf-space-6,6px);padding-top:var(--nf-space-8,8px);border-top:1px solid var(--nf-border);flex:none;margin-top:8px;display:flex}.zE6uZW_navActionBtn{border:1px solid var(--nf-border);color:var(--nf-text-2);cursor:pointer;border-radius:var(--nf-radius-10,10px);height:var(--nf-ctrl-m,32px);font-size:var(--nf-fs-14,14px);background:0 0;flex:1;justify-content:center;align-items:center;line-height:1;transition:background .15s,color .15s,border-color .15s;display:inline-flex}.zE6uZW_navActionBtn:hover{background:var(--nf-hover);color:var(--nf-text);border-color:var(--nf-border-strong)}.zE6uZW_panelNavCollapsed .zE6uZW_navActions{flex-direction:column;align-items:stretch}.zE6uZW_bookSwitch{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-10,9px);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);cursor:pointer;text-align:left;font:inherit;color:var(--nf-text);flex:none;min-width:0;margin-top:4px;transition:background .15s,border-color .15s;display:flex}.zE6uZW_bookSwitch:hover{background:var(--nf-hover);border-color:var(--nf-border-strong)}.zE6uZW_bookSwitchCover{border-radius:var(--nf-radius-6,5px);background:linear-gradient(160deg, var(--nf-accent), color-mix(in srgb, var(--nf-accent) 45%, #000));width:26px;height:34px;color:var(--nf-accent-fg);font-size:var(--nf-fs-12,11px);flex:none;justify-content:center;align-items:center;font-weight:700;display:flex}.zE6uZW_bookSwitchName{font-size:var(--nf-fs-12,12.5px);text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.zE6uZW_bookSwitchMeta{font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_bookSwitchArrow{color:var(--nf-text-3);font-size:var(--nf-fs-12,12px);flex:none;margin-left:auto}.zE6uZW_statRowD{gap:var(--nf-space-12,12px);grid-template-columns:repeat(auto-fit,minmax(150px,1fr));display:grid}.zE6uZW_statCardD{justify-content:space-between;align-items:flex-start;gap:var(--nf-space-10,10px);padding:var(--nf-space-14,14px) var(--nf-space-16,16px);border-radius:var(--nf-radius-16,16px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);min-width:0;display:flex}.zE6uZW_statCardDLabel{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3)}.zE6uZW_statCardDValue{font-size:var(--nf-fs-22,22px);color:var(--nf-text);margin-top:2px;font-weight:700}.zE6uZW_statCardDUnit{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3);font-weight:400}.zE6uZW_statCardDDetail{font-size:var(--nf-fs-12,11.5px);color:var(--nf-text-3);text-overflow:ellipsis;white-space:nowrap;margin-top:2px;overflow:hidden}.zE6uZW_statCardDDown{color:var(--nf-error)}.zE6uZW_statCardDIcon{width:38px;height:var(--nf-ctrl-l,38px);border-radius:var(--nf-radius-12,12px);font-size:var(--nf-fs-18,18px);background:var(--nf-accent-soft);flex:none;justify-content:center;align-items:center;display:flex}.zE6uZW_statCardDIconRed{background:color-mix(in srgb, var(--nf-error) 13%, transparent)}.zE6uZW_tlBar{gap:var(--nf-space-6,6px);margin-top:8px;display:flex}.zE6uZW_tlSeg{gap:var(--nf-space-4,4px);cursor:pointer;min-width:0;font:inherit;background:0 0;border:none;flex-direction:column;flex:1;padding:0;display:flex}.zE6uZW_tlSegTrack{border-radius:var(--nf-radius-999,999px);background:var(--nf-hover);border:1px solid var(--nf-border);height:8px;overflow:hidden}.zE6uZW_tlSegFill{border-radius:var(--nf-radius-999,999px);background:var(--nf-accent);width:100%;height:100%;display:block}.zE6uZW_tlSegTodo .zE6uZW_tlSegFill{opacity:0}.zE6uZW_tlSegTodo .zE6uZW_tlSegTrack{background:0 0}.zE6uZW_tlSegCurrent .zE6uZW_tlSegTrack{border-color:var(--nf-accent);box-shadow:0 0 0 2px var(--nf-accent-soft)}.zE6uZW_tlSegCurrent .zE6uZW_tlSegFill{opacity:.45}.zE6uZW_tlSegLabel{font-size:var(--nf-fs-12,10.5px);color:var(--nf-text-3);text-align:center;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_tlSegDone .zE6uZW_tlSegLabel{color:var(--nf-accent);font-weight:600}.zE6uZW_tlSeg:hover .zE6uZW_tlSegTrack{border-color:var(--nf-border-strong)}.zE6uZW_card{border:var(--nf-card-border,1px solid var(--nf-glass-border));border-radius:var(--nf-card-radius,22px);padding:var(--nf-card-pad,20px 22px);gap:var(--nf-space-10,10px);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1.5px 0 var(--nf-card-sheen,var(--nf-glass-sheen)), inset 0 -1px 0 #ffffff1a;backdrop-filter:blur(var(--nf-card-blur,30px)) saturate(var(--nf-card-saturate,180%)) brightness(var(--nf-card-brightness,1.06));flex-direction:column;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.zE6uZW_card:before{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-core), linear-gradient(90deg, transparent, var(--nf-card-sheen,var(--nf-glass-sheen)), transparent) no-repeat 10% 0 / 80% 1px, linear-gradient(156deg, #ffffff42 0%, #fff0 55%);z-index:0;position:absolute;inset:0}.zE6uZW_card:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.zE6uZW_card:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1.5px 0 var(--nf-card-sheen,var(--nf-glass-sheen)), inset 0 -1px 0 #ffffff40;transform:translateY(-3px)}.zE6uZW_card>*{z-index:1;position:relative}.zE6uZW_cardTitle{font-size:var(--nf-fs-14,14px);color:var(--nf-text);align-items:center;gap:var(--nf-space-8,8px);margin:0;font-weight:650;display:flex}.zE6uZW_button{border:1px solid var(--nf-ctrl-border,var(--nf-border-strong));background:var(--nf-ctrl-bg,var(--nf-bg-inset));color:var(--nf-text);padding:var(--nf-space-8,7px) var(--nf-space-16,15px);border-radius:var(--nf-ctrl-radius,10px);cursor:pointer;font-size:var(--nf-fs-14,13px);box-shadow:inset 0 1px 0 var(--nf-ctrl-sheen,#ffffff17);white-space:nowrap;font-weight:500;transition:background .15s,border-color .15s,transform .1s,box-shadow .15s}.zE6uZW_button:hover:not([disabled]){background:var(--nf-hover);border-color:var(--nf-border-strong);transform:translateY(-1px)}.zE6uZW_button:active:not([disabled]){transform:translateY(0)scale(.97)}.zE6uZW_button[disabled]{opacity:.45;cursor:not-allowed}.zE6uZW_buttonPrimary{background:linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 88%, #fff), var(--nf-accent));color:var(--nf-accent-fg);border-radius:var(--nf-radius-10,10px);box-shadow:0 2px 10px color-mix(in srgb, var(--nf-accent) 45%, transparent), 0 0 0 .5px color-mix(in srgb, var(--nf-accent) 30%, transparent), inset 0 1px 0 #ffffff73;border-color:#0000}.zE6uZW_buttonPrimary:hover:not([disabled]){background:linear-gradient(180deg, var(--nf-accent-hover), color-mix(in srgb, var(--nf-accent-hover) 85%, #000));box-shadow:0 12px 30px color-mix(in srgb, var(--nf-accent) 50%, transparent), 0 0 0 .5px color-mix(in srgb, var(--nf-accent) 30%, transparent), inset 0 1px 0 #ffffff73;border-color:#0000;transform:translateY(-1px)}.zE6uZW_buttonDanger{border-color:var(--nf-error);color:var(--nf-error)}.zE6uZW_buttonDanger:hover:not([disabled]){background:#ff3b301a}.zE6uZW_buttonSmall{padding:var(--nf-space-4,4px) var(--nf-space-10,10px);font-size:var(--nf-fs-12,12px);border-radius:var(--nf-ctrl-radius,8px)}.zE6uZW_field{gap:var(--nf-space-6,5px);flex-direction:column;display:flex}.zE6uZW_fieldLabel{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);font-weight:500}.zE6uZW_input{border:var(--nf-ctrl-border,1px solid var(--nf-border-strong));background:var(--nf-ctrl-bg,var(--nf-bg-inset));color:var(--nf-text);color-scheme:light;border-radius:var(--nf-ctrl-radius,12px);padding:var(--nf-space-8,7px) var(--nf-space-12,11px);font-size:var(--nf-fs-14,13px);box-sizing:border-box;width:100%;box-shadow:inset 0 1px 0 var(--nf-ctrl-sheen,#ffffff17);transition:border-color .15s,box-shadow .15s}body[data-ds-dark-theme] .zE6uZW_input,.zE6uZW_panel[data-nf-mode=dark] .zE6uZW_input{color-scheme:dark}.zE6uZW_panel[data-nf-mode=light] .zE6uZW_input,body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph] .zE6uZW_input{color-scheme:light}select.zE6uZW_input{cursor:pointer;-webkit-appearance:none;appearance:none;background-image:linear-gradient(45deg, transparent 50%, var(--nf-ctrl-caret,var(--nf-text-3)) 50%), linear-gradient(135deg, var(--nf-ctrl-caret,var(--nf-text-3)) 50%, transparent 50%);background-position:calc(100% - 18px),calc(100% - 12px);background-repeat:no-repeat;background-size:6px 6px,6px 6px;padding-right:30px}.zE6uZW_input option{color:var(--nf-text);background:var(--nf-bg-raise);font-size:var(--nf-fs-14,15px)}.zE6uZW_input:focus,.zE6uZW_textarea:focus{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft);outline:none}.zE6uZW_input::placeholder,.zE6uZW_textarea::placeholder{color:var(--nf-text-3)}.zE6uZW_textarea{border:var(--nf-ctrl-border,1px solid var(--nf-border-strong));background:var(--nf-ctrl-bg,var(--nf-bg-inset));color:var(--nf-text);border-radius:var(--nf-ctrl-radius,12px);padding:var(--nf-space-10,9px) var(--nf-space-12,11px);font-size:var(--nf-fs-14,13px);box-sizing:border-box;resize:vertical;width:100%;min-height:200px;font-family:inherit;line-height:1.7;transition:border-color .15s,box-shadow .15s}.zE6uZW_row{align-items:center;gap:var(--nf-space-8,8px);flex-wrap:wrap;display:flex}.zE6uZW_spaceBetween{justify-content:space-between}.zE6uZW_chapterList{gap:var(--nf-space-8,8px);flex-direction:column;display:flex}.zE6uZW_volumeGroup{gap:var(--nf-space-6,6px);flex-direction:column;display:flex}.zE6uZW_volumeGroupHeader{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);border-radius:var(--nf-radius-10,10px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);cursor:pointer;user-select:none;font-size:var(--nf-fs-14,13px);transition:border-color .15s;display:flex}.zE6uZW_volumeGroupHeader:hover{border-color:var(--nf-accent)}.zE6uZW_volumeGroupToggle{font-size:var(--nf-fs-12,11px);color:var(--nf-text-2);flex:none}.zE6uZW_chapter{align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-10,9px) var(--nf-space-12,12px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);background:var(--nf-bg);transition:border-color .15s,box-shadow .15s,transform .1s;display:flex}.zE6uZW_chapter:hover{border-color:var(--nf-border-strong);box-shadow:var(--nf-shadow)}.zE6uZW_chapterFocus{animation:.9s ease-in-out 3 zE6uZW_chapterFocusPulse;border-color:var(--nf-accent)!important;box-shadow:0 0 0 3px color-mix(in srgb, var(--nf-accent) 35%, transparent)!important}@keyframes zE6uZW_chapterFocusPulse{0%,to{background:var(--nf-bg)}50%{background:color-mix(in srgb, var(--nf-accent) 18%, var(--nf-bg))}}.zE6uZW_chapterNum{min-width:28px;height:var(--nf-ctrl-s,28px);padding:0 var(--nf-space-8,8px);border-radius:var(--nf-radius-8,8px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);flex-shrink:0;justify-content:center;align-items:center;font-weight:700;display:inline-flex}.zE6uZW_chapterMain{flex:1;min-width:0}.zE6uZW_chapterTitle{font-weight:600;font-size:var(--nf-fs-14,13px);align-items:center;gap:var(--nf-space-8,8px);color:var(--nf-text);display:flex}.zE6uZW_chapterBeats{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_chapterActions{gap:var(--nf-space-4,4px);opacity:.85;flex-shrink:0;transition:opacity .15s;display:flex}.zE6uZW_chapter:hover .zE6uZW_chapterActions{opacity:1}.zE6uZW_badge{font-size:var(--nf-fs-12,11px);padding:var(--nf-space-2,2px) var(--nf-space-10,9px);border-radius:var(--nf-radius-999,999px);white-space:nowrap;letter-spacing:.2px;border:1px solid;font-weight:600}.zE6uZW_badgePending{color:var(--nf-info);border-color:var(--nf-info);background:color-mix(in srgb, var(--nf-info) 10%, transparent)}.zE6uZW_badgeGenerating{color:var(--nf-accent);border-color:var(--nf-accent);background:color-mix(in srgb, var(--nf-accent) 12%, transparent);animation:1.2s ease-in-out infinite zE6uZW_pulse}.zE6uZW_badgeWritten{color:var(--nf-warn);border-color:var(--nf-warn);background:color-mix(in srgb, var(--nf-warn) 10%, transparent)}.zE6uZW_badgeRejected{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.zE6uZW_badgeDone{color:var(--nf-success);border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 10%, transparent)}.zE6uZW_badgeError{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.zE6uZW_reviewBox{border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);background:var(--nf-bg-inset);gap:var(--nf-space-6,6px);font-size:var(--nf-fs-12,12.5px);flex-direction:column;display:flex}.zE6uZW_chapterPreview{white-space:pre-wrap;word-break:break-all;max-height:320px;font-size:var(--nf-fs-12,12.5px);color:var(--nf-text);background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);margin:0;font-family:inherit;line-height:1.8;overflow:auto}.zE6uZW_chatScroll{gap:var(--nf-space-10,10px);min-height:240px;max-height:480px;padding:var(--nf-space-14,14px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);flex-direction:column;flex:1;display:flex;overflow-y:auto}.zE6uZW_chatBubbleUser{background:linear-gradient(180deg, var(--nf-accent), var(--nf-accent-hover));max-width:90%;color:var(--nf-accent-fg);border-radius:var(--nf-radius-14,14px) var(--nf-radius-14,14px) var(--nf-radius-4,4px) var(--nf-radius-14,14px);padding:var(--nf-space-10,9px) var(--nf-space-14,14px);font-size:var(--nf-fs-14,13px);align-self:flex-end;box-shadow:0 2px 6px #4d6bfe33}.zE6uZW_chatBubbleAssistant{background:var(--nf-bg-raise);max-width:92%;color:var(--nf-text);border:1px solid var(--nf-border);border-radius:var(--nf-radius-14,14px) var(--nf-radius-14,14px) var(--nf-radius-14,14px) var(--nf-radius-4,4px);padding:var(--nf-space-10,9px) var(--nf-space-14,14px);font-size:var(--nf-fs-14,13px);box-shadow:var(--nf-shadow);align-self:flex-start}.zE6uZW_chatRole{font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);margin-bottom:3px;font-weight:600}.zE6uZW_toolLive{padding:var(--nf-space-8,8px) var(--nf-space-10,10px);border-radius:var(--nf-radius-8,8px);background:var(--nf-bg-inset);border:1px dashed var(--nf-border-strong);font-size:var(--nf-fs-12,12px);white-space:pre-wrap;word-break:break-all;color:var(--nf-text-2);max-height:180px;margin-top:6px;line-height:1.7;overflow-y:auto}.zE6uZW_assistantStatus{padding:var(--nf-space-6,6px) var(--nf-space-12,12px);border-radius:var(--nf-radius-999,999px);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);background:var(--nf-bg-inset);border:1px solid var(--nf-border);align-items:center;gap:var(--nf-space-6,6px);flex:none;margin-top:6px;display:flex}.zE6uZW_assistantStatusBusy{color:var(--nf-accent);border-color:var(--nf-accent);background:var(--nf-accent-soft);font-weight:600}.zE6uZW_toolSteps{gap:var(--nf-space-4,4px);flex-direction:column;margin-top:6px;display:flex}.zE6uZW_toolStep{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-6,5px) var(--nf-space-10,10px);border-radius:var(--nf-radius-8,8px);font-size:var(--nf-fs-12,12px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);display:flex}.zE6uZW_toolStepActive{border-color:var(--nf-accent);background:var(--nf-accent-soft)}.zE6uZW_toolStepError{border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.zE6uZW_toolStepIcon{font-size:var(--nf-fs-14,13px);flex:none}.zE6uZW_toolStepName{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-weight:600;overflow:hidden}.zE6uZW_toolStepStatus{color:var(--nf-text-2);font-size:var(--nf-fs-12,11px);flex:none}.zE6uZW_toolStepActive .zE6uZW_toolStepStatus{color:var(--nf-accent)}.zE6uZW_toolStepError .zE6uZW_toolStepStatus{color:var(--nf-error)}.zE6uZW_toolStepDetail{width:100%;color:var(--nf-error);font-size:var(--nf-fs-12,11px);word-break:break-all}.zE6uZW_progress{border:1px solid var(--nf-border);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-14,14px);font-size:var(--nf-fs-12,12px);white-space:pre-wrap;word-break:break-all;min-height:60px;max-height:220px;color:var(--nf-text-2);font-family:var(--nf-font-mono);background:var(--nf-bg-inset);line-height:1.8;overflow:auto}.zE6uZW_progressLine{color:var(--nf-text-2);opacity:.9}.zE6uZW_progressLineLive{color:var(--nf-accent);align-items:center;gap:var(--nf-space-8,8px);font-weight:600;display:flex}.zE6uZW_progressBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);flex:none;width:110px;height:6px;display:inline-block;overflow:hidden}.zE6uZW_progressBarFill{border-radius:var(--nf-radius-4,3px);background:var(--nf-accent);height:100%;transition:width .3s;display:block}.zE6uZW_busyRow{justify-content:space-between;align-items:center;gap:var(--nf-space-12,12px);flex-wrap:wrap;display:flex}.zE6uZW_liveText{font-size:var(--nf-fs-12,12px);font-variant-numeric:tabular-nums;color:var(--nf-text-2)}.zE6uZW_bigProgressBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);height:8px;margin-top:10px;overflow:hidden}.zE6uZW_bigProgressBarFill{border-radius:var(--nf-radius-999,999px);background:linear-gradient(90deg, var(--nf-accent), var(--nf-accent-2,var(--nf-accent)));height:100%;transition:width .3s;display:block}.zE6uZW_diffLegend{align-items:center;gap:var(--nf-space-14,14px);font-size:var(--nf-fs-12,12px);flex-wrap:wrap;margin:6px 0 8px;display:flex}.zE6uZW_legendOld{color:var(--nf-error);font-weight:700}.zE6uZW_legendNew{color:var(--nf-success);font-weight:700}.zE6uZW_onlyChanges{align-items:center;gap:var(--nf-space-4,4px);color:var(--nf-text-2);cursor:pointer;margin-left:auto;display:inline-flex}.zE6uZW_diffList{border:1px solid var(--nf-border);border-radius:var(--nf-radius-8,8px);background:var(--nf-bg-inset);min-height:0;padding:var(--nf-space-10,10px) var(--nf-space-12,12px);gap:var(--nf-space-8,8px);font-size:var(--nf-fs-14,13px);flex-direction:column;flex:1;line-height:1.7;display:flex;overflow-y:auto}.zE6uZW_diffSame{border:1px dashed var(--nf-border);border-radius:var(--nf-radius-6,6px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);color:var(--nf-text-2);opacity:.85}.zE6uZW_diffSame summary{cursor:pointer;font-size:var(--nf-fs-12,12px);user-select:none}.zE6uZW_diffSameBody{white-space:pre-wrap;margin-top:6px}.zE6uZW_diffChange{border:1px solid var(--nf-border);border-radius:var(--nf-radius-8,8px);grid-template-columns:1fr 1fr;display:grid;overflow:hidden}.zE6uZW_diffColumn{gap:var(--nf-space-6,6px);min-width:0;padding:var(--nf-space-8,8px) var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_diffColumn:first-child{border-right:1px solid var(--nf-border)}.zE6uZW_diffTagOld,.zE6uZW_diffTagNew{font-size:var(--nf-fs-12,11px);border-radius:var(--nf-radius-4,4px);padding:var(--nf-space-2,1px) var(--nf-space-8,7px);letter-spacing:.5px;flex:none;align-self:flex-start;font-weight:700}.zE6uZW_diffTagOld{color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 16%, transparent);border:1px solid color-mix(in srgb, var(--nf-error) 45%, transparent)}.zE6uZW_diffTagNew{color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 16%, transparent);border:1px solid color-mix(in srgb, var(--nf-success) 45%, transparent)}.zE6uZW_diffOld{color:var(--nf-error);white-space:pre-wrap;text-decoration:line-through;text-decoration-color:color-mix(in srgb, var(--nf-error) 55%, transparent)}.zE6uZW_diffNew{color:var(--nf-success);white-space:pre-wrap;font-weight:500}.zE6uZW_diffDel{gap:var(--nf-space-4,4px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);border-radius:var(--nf-radius-6,6px);border:1px solid color-mix(in srgb, var(--nf-error) 35%, transparent);background:color-mix(in srgb, var(--nf-error) 7%, transparent);flex-direction:column;display:flex}.zE6uZW_diffAdd{gap:var(--nf-space-4,4px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);border-radius:var(--nf-radius-6,6px);border:1px solid color-mix(in srgb, var(--nf-success) 35%, transparent);background:color-mix(in srgb, var(--nf-success) 7%, transparent);flex-direction:column;display:flex}.zE6uZW_diffText{white-space:pre-wrap}.zE6uZW_diffDel .zE6uZW_diffText{color:var(--nf-error);text-decoration:line-through;text-decoration-color:color-mix(in srgb, var(--nf-error) 50%, transparent)}.zE6uZW_diffAdd .zE6uZW_diffText{color:var(--nf-success)}.zE6uZW_wsPage{gap:var(--nf-space-10,10px);flex-direction:column;flex:1;min-height:0;display:flex}.zE6uZW_wsPageHeader{align-items:center;gap:var(--nf-space-8,8px);flex-wrap:wrap;flex:none;display:flex}.zE6uZW_wsAppliedBanner{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-12,12px);border:1px solid var(--nf-success);border-radius:var(--nf-radius-10,10px);background:color-mix(in srgb, var(--nf-success) 8%, transparent);font-size:var(--nf-fs-12,12px);flex-wrap:wrap;flex:none;font-weight:600;display:flex}.zE6uZW_wsColumns{gap:var(--nf-space-14,14px);flex:1;grid-template-columns:minmax(0,1fr) minmax(0,1fr);min-height:0;display:grid}.zE6uZW_wsColumn{gap:var(--nf-space-8,8px);flex-direction:column;min-width:0;min-height:0;display:flex}.zE6uZW_wsEditor{resize:vertical;min-height:0;font-family:var(--nf-font);font-size:var(--nf-fs-14,13px);white-space:pre-wrap;flex:1;line-height:1.75}.zE6uZW_wsSelected{border:1px solid var(--nf-accent);border-radius:var(--nf-radius-6,6px);padding:var(--nf-space-6,6px) var(--nf-space-10,10px);background:color-mix(in srgb, var(--nf-accent) 8%, transparent);max-height:120px;overflow:auto}.zE6uZW_wsSelectedText{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);white-space:pre-wrap;margin-top:4px}.zE6uZW_wsPreview{border:1px solid var(--nf-border);border-radius:var(--nf-radius-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-10,10px);gap:var(--nf-space-8,8px);background:var(--nf-bg-inset);flex-direction:column;display:flex}.zE6uZW_wsPreviewText{min-height:0;font-size:var(--nf-fs-14,13px);white-space:pre-wrap;color:var(--nf-text);flex:1;margin:0;line-height:1.7;overflow:auto}.zE6uZW_assetGrid{gap:var(--nf-space-10,10px);grid-template-columns:repeat(auto-fit,minmax(150px,1fr));display:grid}.zE6uZW_assetGroups{gap:var(--nf-space-14,14px);flex-direction:column;display:flex}.zE6uZW_assetGroup{gap:var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_assetGroupHeader{color:var(--nf-accent);border-bottom:1px solid var(--nf-glass-border);align-items:center;gap:8px;padding-bottom:2px;font-size:14px;font-weight:600;display:flex}.zE6uZW_assetStat{border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-14,14px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);gap:var(--nf-space-4,4px);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(30px)saturate(180%);flex-direction:column;transition:transform .22s,box-shadow .22s;display:flex}.zE6uZW_assetStat:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1px 0 var(--nf-glass-sheen);transform:translateY(-3px)}.zE6uZW_assetStatLabel{font-size:var(--nf-fs-12,11px);color:var(--nf-text-2);opacity:.9}.zE6uZW_assetStatValue{font-size:var(--nf-fs-14,15px);color:var(--nf-text);font-weight:700;line-height:1.2}.zE6uZW_assetStatDetail{font-size:var(--nf-fs-12,11px);color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_dashHero{border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-22,22px);padding:var(--nf-card-pad,20px 22px);background:var(--nf-glass-face);box-shadow:var(--nf-card-shadow), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;backdrop-filter:blur(30px)saturate(180%);gap:var(--nf-space-14,14px);flex-direction:column;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.zE6uZW_dashHero:before{content:\"\";border-radius:inherit;pointer-events:none;background:radial-gradient(46% 40% at 92% -10%, color-mix(in srgb, var(--nf-accent) 13%, transparent), transparent 62%), var(--nf-glass-core), linear-gradient(90deg, transparent, var(--nf-glass-sheen), transparent) no-repeat 10% 0 / 80% 1px, linear-gradient(156deg, #ffffff42 0%, #fff0 55%);z-index:0;position:absolute;inset:0}.zE6uZW_dashHero:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.zE6uZW_dashHero:hover{box-shadow:var(--nf-card-shadow-hover), inset 0 1.5px 0 var(--nf-glass-sheen), inset 0 -1px 0 #ffffff40;transform:translateY(-3px)}.zE6uZW_dashHero>*{z-index:1;position:relative}.zE6uZW_dashHeroEyebrow{align-items:center;gap:var(--nf-space-6,6px);font-size:var(--nf-fs-14,13px);color:var(--nf-accent);font-weight:600;display:inline-flex}.zE6uZW_dashHeroSparkle{font-size:var(--nf-fs-14,14px)}.zE6uZW_dashHeroTitle{gap:var(--nf-space-2,2px);flex-direction:column;display:flex}.zE6uZW_dashHeroBook{font-size:var(--nf-fs-24,24px);letter-spacing:-.3px;margin:0;font-weight:700;line-height:1.25}.zE6uZW_dashHeroAction{align-items:center;gap:var(--nf-space-12,12px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-14,14px);background:var(--nf-glass-inset);box-shadow:inset 0 1px 0 var(--nf-glass-sheen);padding:var(--nf-space-10,10px) var(--nf-space-14,14px);display:flex}.zE6uZW_dashHeroArrow{width:28px;height:var(--nf-ctrl-s,28px);background:var(--nf-accent);color:#fff;font-size:var(--nf-fs-14,14px);border-radius:50%;flex:none;justify-content:center;align-items:center;display:inline-flex}.zE6uZW_dashHeroActionBody{gap:var(--nf-space-2,2px);flex-direction:column;flex:1;min-width:0;display:flex}.zE6uZW_dashHeroActionTitle{font-size:var(--nf-fs-14,14px);font-weight:600}.zE6uZW_dashJourney{gap:var(--nf-space-6,6px);flex-direction:column;display:flex}.zE6uZW_dashJourneyBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);height:6px;overflow:hidden}.zE6uZW_dashJourneyFill{border-radius:var(--nf-radius-999,999px);background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));height:100%;transition:width .4s;display:block}.zE6uZW_dashJourneyStages{gap:var(--nf-space-4,4px);grid-template-columns:repeat(6,minmax(0,1fr));display:grid}.zE6uZW_dashStage{align-items:center;gap:var(--nf-space-4,3px);font-size:var(--nf-fs-12,11px);color:var(--nf-text-3);text-align:center;white-space:nowrap;flex-direction:column;display:flex}.zE6uZW_dashStageDot{border:1px solid var(--nf-border-strong,var(--nf-text-3));width:18px;height:18px;font-size:var(--nf-fs-12,10px);background:var(--nf-bg-base);border-radius:50%;justify-content:center;align-items:center;display:inline-flex}.zE6uZW_dashStageDone{color:var(--nf-text-2)}.zE6uZW_dashStageDone .zE6uZW_dashStageDot{background:var(--nf-success);border-color:var(--nf-success);color:#fff}.zE6uZW_dashStageCurrent{color:var(--nf-accent);font-weight:600}.zE6uZW_dashStageCurrent .zE6uZW_dashStageDot{border-color:var(--nf-accent);color:var(--nf-accent);box-shadow:0 0 0 3px color-mix(in srgb, var(--nf-accent) 18%, transparent)}.zE6uZW_dashFacts{gap:var(--nf-space-8,8px);border-top:1px solid var(--nf-border);padding-top:var(--nf-space-12,12px);grid-template-columns:repeat(4,minmax(0,1fr));display:grid}.zE6uZW_dashFact{gap:var(--nf-space-2,2px);flex-direction:column;min-width:0;display:flex}.zE6uZW_dashFact b{font-size:var(--nf-fs-14,13px);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.zE6uZW_dashGrid{gap:var(--nf-space-14,14px);grid-template-columns:minmax(0,3fr) minmax(0,2fr);align-items:start;display:grid}.zE6uZW_todoItem{align-items:center;gap:var(--nf-space-10,10px);border-radius:var(--nf-radius-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-12,12px);font-size:var(--nf-fs-12,12.5px);border:1px solid var(--nf-border);display:flex}.zE6uZW_todoDanger{border-color:color-mix(in srgb, var(--nf-error) 40%, transparent);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.zE6uZW_todoWarning{border-color:color-mix(in srgb, var(--nf-warn) 40%, transparent);background:color-mix(in srgb, var(--nf-warn) 8%, transparent)}.zE6uZW_todoInfo{border-color:color-mix(in srgb, var(--nf-info) 40%, transparent);background:color-mix(in srgb, var(--nf-info) 7%, transparent)}.zE6uZW_todoText{gap:var(--nf-space-2,2px);flex-direction:column;flex:1;min-width:0;display:flex}.zE6uZW_outlineReadonly{padding:var(--nf-space-12,12px) var(--nf-space-14,14px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);font-size:var(--nf-fs-12,12.5px);white-space:pre-wrap;user-select:text;max-height:480px;margin:0;line-height:1.8;overflow:auto}.zE6uZW_bookCreateOutline{gap:var(--nf-space-6,6px);flex-direction:column;align-items:flex-start;display:flex}.zE6uZW_assistantFloat{z-index:80;border:1px solid var(--nf-border);border-radius:var(--nf-radius-16,16px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow-lg);flex-direction:column;min-width:320px;min-height:220px;display:flex;position:absolute;overflow:hidden}.zE6uZW_assistantFloatHeader{justify-content:space-between;align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-10,10px) var(--nf-space-8,8px) var(--nf-space-14,14px);cursor:grab;user-select:none;font-size:var(--nf-fs-14,13px);border-bottom:1px solid var(--nf-border);background:var(--nf-bg-inset);flex:none;font-weight:600;display:flex}.zE6uZW_assistantFloatHeader:active{cursor:grabbing}.zE6uZW_assistantFloatBody{min-height:0;padding:var(--nf-space-10,10px);flex:1;display:flex;overflow:hidden}.zE6uZW_assistantFloatBody>*{flex:1;min-width:0}.zE6uZW_assistantResize{cursor:nwse-resize;background:linear-gradient(135deg, transparent 0 55%, var(--nf-border-strong) 55% 62%, transparent 62%) no-repeat 4px 4px / 12px 12px;width:20px;height:20px;position:absolute;bottom:0;right:0}.zE6uZW_coverPreview{border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);flex:none;justify-content:center;align-items:center;width:150px;height:200px;display:flex;overflow:hidden}.zE6uZW_coverPreview img{object-fit:contain;width:100%;height:100%;display:block}.zE6uZW_coverPlaceholder{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3)}.zE6uZW_shelfView{min-height:0;padding:var(--nf-container-pad,20px 22px);gap:var(--nf-container-gap,14px);flex-direction:column;flex:1;display:flex;overflow:auto}.zE6uZW_authorHome{z-index:1;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.zE6uZW_authorRail{border-right:1px solid var(--nf-glass-border);background:var(--nf-glass-face);flex-direction:column;flex-shrink:0;gap:4px;width:180px;padding:14px 10px;display:flex}.zE6uZW_authorRailTitle{color:var(--nf-accent);align-items:center;gap:8px;padding:4px 8px 12px;font-weight:600;display:flex}.zE6uZW_authorRailBtn{color:var(--nf-text);cursor:pointer;text-align:left;background:0 0;border:1px solid #0000;border-radius:10px;align-items:center;gap:10px;width:100%;padding:8px 12px;font-size:14px;display:flex}.zE6uZW_authorRailBtn:hover{background:color-mix(in srgb, var(--nf-accent) 12%, transparent);color:var(--nf-text)}.zE6uZW_authorRailBtnActive{background:color-mix(in srgb, var(--nf-accent) 16%, var(--nf-glass-face));border-color:var(--nf-accent);color:var(--nf-accent);box-shadow:inset 0 0 0 1px var(--nf-accent);font-weight:600}.zE6uZW_authorRailAbout{padding:8px 12px}.zE6uZW_authorContent{flex-direction:column;flex:1;min-width:0;display:flex;overflow:hidden}.zE6uZW_authorPageBody{padding:var(--nf-container-pad,20px 22px);flex-direction:column;flex:1;gap:14px;min-height:0;display:flex;overflow:auto}.zE6uZW_authorPageHeader{flex-wrap:wrap;justify-content:space-between;align-items:flex-end;gap:14px;display:flex}.zE6uZW_authorPageHero{gap:var(--nf-space-12,12px);padding:var(--nf-card-pad,20px 22px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-22,22px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1.5px 0 var(--nf-glass-sheen);backdrop-filter:blur(26px)saturate(175%);flex-direction:column;display:flex}.zE6uZW_noticeError{background:color-mix(in srgb, var(--nf-error) 14%, transparent);color:var(--nf-error);border:1px solid var(--nf-error);border-radius:10px;padding:10px 14px}.zE6uZW_rowEnd{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.zE6uZW_assetFilterBar{flex-wrap:wrap;gap:8px;display:flex}.zE6uZW_assetFilterChip{border:1px solid var(--nf-glass-border);color:var(--nf-text);cursor:pointer;background:0 0;border-radius:999px;padding:4px 10px}.zE6uZW_assetFilterChipActive{background:var(--nf-accent);color:#fff;border-color:#0000}.zE6uZW_assetEditor{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);border-radius:14px;flex-direction:column;gap:12px;padding:16px;display:flex}.zE6uZW_assetEditorRow{flex-wrap:wrap;gap:12px;display:flex}.zE6uZW_assetLabel{color:var(--nf-muted);flex-direction:column;flex:1;gap:4px;min-width:180px;font-size:12px;display:flex}.zE6uZW_assetTextarea{resize:vertical;min-height:160px;font-family:inherit}.zE6uZW_assetGrid{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:14px;display:grid}.zE6uZW_assetCard{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);border-radius:14px;flex-direction:column;gap:8px;padding:14px;display:flex}.zE6uZW_assetCardTop{justify-content:space-between;align-items:center;gap:8px;display:flex}.zE6uZW_assetKind{font-size:12px;font-weight:600}.zE6uZW_assetCardName{font-weight:600}.zE6uZW_assetCardContent{white-space:pre-wrap;color:var(--nf-text);max-height:150px;font-size:13px;overflow:auto}.zE6uZW_assetCardFooter{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.zE6uZW_iconBtn{color:var(--nf-text);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:8px;justify-content:center;align-items:center;padding:4px;display:inline-flex}.zE6uZW_iconBtn:hover{background:#0000000f}.zE6uZW_adaptInputCard{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);border-radius:14px;flex-direction:column;gap:12px;padding:16px;display:flex}.zE6uZW_adaptTextarea{resize:vertical;min-height:220px}.zE6uZW_adaptResult{flex-direction:column;gap:14px;display:flex}.zE6uZW_adaptOutline{background:var(--nf-glass-face);border:1px solid var(--nf-glass-border);border-radius:12px;padding:10px 14px}.zE6uZW_adaptMatrix{grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:12px;display:grid}.zE6uZW_dimCard{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);border-radius:14px;flex-direction:column;gap:8px;padding:14px;display:flex}.zE6uZW_dimCardHead{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.zE6uZW_dimTitle{font-weight:600}.zE6uZW_dimCurrent{white-space:pre-wrap;font-size:13px}.zE6uZW_dimCardSelected{border-color:var(--nf-accent);box-shadow:0 0 0 1px var(--nf-accent)}.zE6uZW_dimEdit{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.zE6uZW_adaptOutlinePre{white-space:pre-wrap;max-height:260px;margin:0;font-family:inherit;font-size:13px;overflow:auto}.zE6uZW_adaptProposal{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);border-radius:14px;flex-direction:column;gap:8px;padding:14px;display:flex}.zE6uZW_adaptTable{border-collapse:collapse;width:100%;font-size:13px}.zE6uZW_adaptTable th,.zE6uZW_adaptTable td{border:1px solid var(--nf-glass-border);text-align:left;padding:6px 8px}.zE6uZW_adaptImpacts{flex-direction:column;gap:4px;display:flex}.zE6uZW_adaptImpact{font-size:13px}.zE6uZW_progressOverview{grid-template-columns:repeat(auto-fit,minmax(140px,1fr));gap:12px;display:grid}.zE6uZW_progressOverviewCard{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);border-radius:14px;flex-direction:column;gap:4px;padding:14px;display:flex}.zE6uZW_progressOverviewNum{color:var(--nf-accent);font-size:24px;font-weight:700}.zE6uZW_progressTotalBar{background:var(--nf-glass-face);border:1px solid var(--nf-glass-border);border-radius:999px;height:14px;position:relative;overflow:hidden}.zE6uZW_progressTotalFill{background:linear-gradient(90deg, var(--nf-accent), var(--nf-info));border-radius:999px;height:100%;position:absolute;inset:0 auto 0 0}.zE6uZW_progressTotalBar .zE6uZW_meta{color:var(--nf-text);justify-content:center;align-items:center;font-size:11px;font-weight:600;display:flex;position:absolute;inset:0}.zE6uZW_progressBookList{flex-direction:column;gap:12px;display:flex}.zE6uZW_progressBook{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);border-radius:14px;flex-direction:column;gap:8px;padding:14px;display:flex}.zE6uZW_progressBookActive{border-color:var(--nf-accent);box-shadow:0 0 0 1px var(--nf-accent)}.zE6uZW_progressBookHead{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.zE6uZW_progressBookName{font-weight:600}.zE6uZW_progressLive{color:var(--nf-accent);font-weight:600}.zE6uZW_progressBookBar{background:var(--nf-glass-face-hover,#0000000d);border-radius:999px;height:8px;overflow:hidden}.zE6uZW_progressBookFill{background:var(--nf-accent);border-radius:999px;height:100%}.zE6uZW_shelfHeader{gap:var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_shelfHero{gap:var(--nf-space-14,14px);padding:var(--nf-card-pad,20px 22px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-22,22px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1.5px 0 var(--nf-glass-sheen);flex-direction:column;display:flex}.zE6uZW_shelfHero .zE6uZW_panelTitle{font-size:var(--nf-fs-22,22px);letter-spacing:.3px}.zE6uZW_shelfTitleRow{justify-content:space-between;align-items:center;gap:var(--nf-space-10,10px);flex-wrap:wrap;display:flex}.zE6uZW_shelfToolbar{align-items:center;gap:var(--nf-space-10,10px);flex-wrap:wrap;display:flex}.zE6uZW_shelfSearch{flex:1;min-width:180px;max-width:320px}.zE6uZW_shelfStats{gap:var(--nf-space-10,10px);grid-template-columns:repeat(auto-fit,minmax(120px,1fr));display:grid}.zE6uZW_shelfStat{justify-content:space-between;align-items:baseline;gap:var(--nf-space-8,8px);padding:var(--nf-space-10,10px) var(--nf-space-14,14px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-14,14px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);cursor:pointer;user-select:none;transition:border-color .15s,background .15s,box-shadow .15s,transform .1s;display:flex}.zE6uZW_shelfStat:hover{border-color:var(--nf-accent);transform:translateY(-1px)}.zE6uZW_shelfStatActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);box-shadow:0 0 0 2px var(--nf-accent-soft), var(--nf-shadow)}.zE6uZW_shelfStat b{font-size:var(--nf-fs-20,20px);color:var(--nf-accent);font-weight:800}.zE6uZW_shelfStat span{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2)}.zE6uZW_shelfFilters{gap:var(--nf-space-2,2px);padding:var(--nf-space-4,3px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-999,999px);background:var(--nf-bg-inset);display:inline-flex}.zE6uZW_shelfFilter{color:var(--nf-text-2);font-size:var(--nf-fs-12,12.5px);padding:var(--nf-space-6,5px) var(--nf-space-12,12px);border-radius:var(--nf-radius-999,999px);cursor:pointer;align-items:center;gap:var(--nf-space-6,5px);white-space:nowrap;background:0 0;border:none;font-weight:600;transition:background .15s,color .15s,box-shadow .15s;display:inline-flex}.zE6uZW_shelfFilter:hover{color:var(--nf-text)}.zE6uZW_shelfFilterActive{background:linear-gradient(135deg, var(--nf-accent), var(--nf-accent-hover));color:var(--nf-accent-fg);box-shadow:0 3px 12px color-mix(in srgb, var(--nf-accent) 40%, transparent)}.zE6uZW_shelfFilterCount{font-size:var(--nf-fs-12,10.5px);opacity:.8;background:color-mix(in srgb, currentColor 14%, transparent);border-radius:var(--nf-radius-999,999px);padding:0 var(--nf-space-6,6px)}.zE6uZW_shelfEmpty{justify-content:center;align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-40,40px) var(--nf-space-20,20px);border:1px dashed var(--nf-border-strong);border-radius:var(--nf-radius-16,16px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);text-align:center;flex-direction:column;flex:1;display:flex}.zE6uZW_shelfEmptyIcon{font-size:var(--nf-fs-42,42px)}.zE6uZW_shelfEmptyTitle{font-size:var(--nf-fs-16,16px);font-weight:700}.zE6uZW_shelfGrid{gap:var(--nf-container-gap,14px);grid-template-columns:repeat(auto-fill,minmax(190px,1fr));align-content:start;display:grid}.zE6uZW_panel{--nf-container-pad:20px 22px;--nf-container-gap:var(--nf-space-14,14px);--nf-card-pad:20px 22px;--nf-nav-pad:16px 12px 14px}.zE6uZW_panel[data-nf-density=compact]{--nf-container-pad:12px 14px;--nf-container-gap:var(--nf-space-8,8px);--nf-card-pad:12px 14px;--nf-nav-pad:8px 8px}.zE6uZW_panel[data-nf-density=spacious]{--nf-container-pad:24px 28px;--nf-container-gap:var(--nf-space-18,18px);--nf-card-pad:22px 26px;--nf-nav-pad:18px 14px}.zE6uZW_panel[data-nf-mode=light]{color-scheme:light;--nf-bg:#f2f2f7db;--nf-bg-raise:#ffffffb8;--nf-bg-inset:#7676801f;--nf-border:#3c3c4329;--nf-border-strong:#3c3c4352;--nf-text:#1c1c1e;--nf-text-2:#3c3c43;--nf-text-2-alpha:#3c3c43ad;--nf-text-3:#8e8e93;--nf-accent:#00b85c;--nf-accent-hover:#00a04e;--nf-accent-soft:#00b85c1f;--nf-accent-fg:#fff;--nf-hover:#0000000d;--nf-success:#34c759;--nf-error:#ff3b30;--nf-warn:#ff9500;--nf-info:#00b85c;--nf-shadow:0 1px 3px #0000000f, 0 12px 32px #00000014;--nf-shadow-lg:0 4px 12px #00000012, 0 20px 48px #0000001f;--nf-card-shadow:0 2px 6px #0000000f, 0 14px 38px #00000024;--nf-card-shadow-hover:0 4px 10px #00000014, 0 22px 52px #0003;--nf-glass-face:linear-gradient(180deg, #f6f7f9 0%, #f0f2f5 26%, #e9ebef 52%, #e0e3e8 78%, #d6d9df 100%);--nf-glass-core:radial-gradient(30% 24% at 36% 28%, #ffffff80 0%, #ffffff38 45%, #fff0 78%);--nf-glass-sheen:#ffffff8c;--nf-glass-border:#ffffffa6;--nf-glass-inset:#ffffff8c;--nf-glass-orb-a:#00b85c2e;--nf-glass-orb-b:#78a0ff21}.zE6uZW_panel[data-nf-mode=dark]{color-scheme:dark;--nf-bg:#0a0b0ddb;--nf-bg-raise:#1c1c1ec7;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff47;--nf-text:#f2f2f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b8;--nf-text-3:#8e8e93;--nf-accent:#35d07a;--nf-accent-hover:#5ce695;--nf-accent-soft:#35d07a33;--nf-accent-fg:#062b18;--nf-hover:#ffffff17;--nf-success:#30d158;--nf-error:#ff453a;--nf-warn:#ff9f0a;--nf-info:#35d07a;--nf-shadow:0 1px 2px #00000059, 0 10px 30px #0006;--nf-shadow-lg:0 4px 12px #0006, 0 20px 48px #0000008c;--nf-card-shadow:0 2px 6px #00000059, 0 14px 38px #00000073;--nf-card-shadow-hover:0 4px 10px #0006, 0 22px 52px #0000008c;--nf-glass-face:linear-gradient(180deg, #70747a6b 0%, #60646a6b 26%, #52555a6b 52%, #44474c6b 78%, #383a3f6b 100%);--nf-glass-core:radial-gradient(30% 24% at 36% 28%, #ffffff42 0%, #ffffff1a 45%, #fff0 78%);--nf-glass-sheen:#ffffff42;--nf-glass-border:#ffffff24;--nf-glass-inset:#ffffff12;--nf-glass-orb-a:#00ca5247;--nf-glass-orb-b:#bec8d71a}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=macos]{--nf-bg:#1c1c1ee6;--nf-bg-raise:#2c2c2ed1;--nf-bg-inset:#7676802e;--nf-border:#ffffff1f;--nf-border-strong:#ffffff42;--nf-text:#f5f5f7;--nf-text-2:#d1d1d6;--nf-text-2-alpha:#d1d1d6b3;--nf-text-3:#98989d;--nf-accent:#0a84ff;--nf-accent-hover:#3a9bff;--nf-accent-soft:#0a84ff33;--nf-accent-fg:#fff;--nf-hover:#ffffff0f;--nf-info:#bf5af2;--nf-shadow:0 1px 2px #0006, 0 10px 30px #00000073;--nf-shadow-lg:0 4px 12px #00000073, 0 18px 44px #0009;--nf-card-shadow:0 2px 6px #0006, 0 14px 38px #00000080;--nf-card-shadow-hover:0 4px 10px #00000073, 0 22px 52px #0009;--nf-glass-face:#2c2c2ed9;--nf-glass-core:transparent;--nf-glass-sheen:#fff3;--nf-glass-border:#ffffff2e;--nf-glass-inset:#ffffff0f;--nf-glass-orb-a:#0a84ff29;--nf-glass-orb-b:#bf5af214;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=neumorph]{--nf-bg:#2b2f36;--nf-bg-raise:#2b2f36;--nf-bg-inset:#25292f;--nf-border:#0a0c1080;--nf-border-strong:#080a0e99;--nf-text:#d6dae1;--nf-text-2:#a8aeb8;--nf-text-2-alpha:#a8aeb8b3;--nf-text-3:#757c88;--nf-hover:#ffffff0d;--nf-shadow:4px 4px 10px #00000080, -4px -4px 10px #6068763d;--nf-shadow-lg:6px 6px 14px #0000008c, -6px -6px 14px #60687642;--nf-card-shadow:9px 9px 18px #00000080, -9px -9px 18px #6068763d;--nf-card-shadow-hover:12px 12px 24px #0009, -12px -12px 24px #60687647;--nf-glass-face:#2b2f36;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#0c0e1273;--nf-glass-inset:#25292f;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_panel[data-nf-mode=light][data-nf-theme=neumorph]{--nf-bg:#e4e9f2;--nf-bg-raise:#e4e9f2;--nf-bg-inset:#d9dfe8;--nf-border:#8c9baf59;--nf-border-strong:#78879e80;--nf-text:#3a4250;--nf-text-2:#5b6472;--nf-text-2-alpha:#465060b3;--nf-text-3:#8b94a3;--nf-hover:#5a697d14;--nf-shadow:4px 4px 10px #a3b1c68c, -4px -4px 10px #ffffffd9;--nf-shadow-lg:6px 6px 14px #a3b1c699, -6px -6px 14px #ffffffe6;--nf-card-shadow:9px 9px 18px #a3b1c68c, -9px -9px 18px #ffffffd9;--nf-card-shadow-hover:12px 12px 24px #a3b1c6a6, -12px -12px 24px #fffffff2;--nf-glass-face:#e4e9f2;--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:#a3b1c666;--nf-glass-inset:#d9dfe8;--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}.zE6uZW_bookCard{gap:var(--nf-space-8,8px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-16,16px);padding:var(--nf-space-12,12px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow);cursor:pointer;flex-direction:column;transition:border-color .15s,transform .1s,box-shadow .15s;display:flex}.zE6uZW_bookCard:hover{border-color:var(--nf-accent);box-shadow:var(--nf-shadow-lg);transform:translateY(-2px)}.zE6uZW_bookCardActive{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft)}.zE6uZW_bookCardCover{aspect-ratio:3/4;border-radius:var(--nf-radius-12,12px);background:var(--nf-bg-inset);border:1px solid var(--nf-border);flex:none;justify-content:center;align-items:center;display:flex;position:relative;overflow:hidden}.zE6uZW_bookCardCover img{object-fit:cover;width:100%;height:100%;transition:transform .35s;display:block}.zE6uZW_bookCard:hover .zE6uZW_bookCardCover img{transform:scale(1.06)}.zE6uZW_bookCardCover:after{content:\"\";border-radius:inherit;pointer-events:none;opacity:0;background:linear-gradient(#0000 55%,#00000047);transition:opacity .25s;position:absolute;inset:0}.zE6uZW_bookCard:hover .zE6uZW_bookCardCover:after{opacity:1}.zE6uZW_bookCardCoverFallback{justify-content:center;align-items:center;gap:var(--nf-space-6,6px);background:radial-gradient(400px 200px at 80% -20%, color-mix(in srgb, var(--nf-accent) 25%, transparent), transparent 70%), linear-gradient(155deg, var(--nf-bg-inset), color-mix(in srgb, var(--nf-accent) 10%, var(--nf-bg-inset)));flex-direction:column;width:100%;height:100%;display:flex}.zE6uZW_bookCardCoverTitle{font-size:var(--nf-fs-22,22px);color:var(--nf-accent);letter-spacing:2px;font-weight:800}.zE6uZW_bookCardBody{gap:var(--nf-space-6,5px);flex-direction:column;flex:1;min-width:0;display:flex}.zE6uZW_bookCardTitleRow{justify-content:space-between;align-items:center;gap:var(--nf-space-6,6px);display:flex}.zE6uZW_bookCardName{font-weight:700;font-size:var(--nf-fs-14,13.5px);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.zE6uZW_bookCardBlurb{-webkit-line-clamp:2;-webkit-box-orient:vertical;min-height:34px;display:-webkit-box;overflow:hidden}.zE6uZW_bookCardMetaRow{justify-content:space-between;align-items:center;gap:var(--nf-space-6,6px);flex-wrap:wrap;display:flex}.zE6uZW_bookCardProgressBar{border-radius:var(--nf-radius-999,999px);background:var(--nf-border);height:6px;overflow:hidden;box-shadow:inset 0 1px 2px #0000001f}.zE6uZW_bookCardProgressFill{border-radius:var(--nf-radius-999,999px);background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));height:100%;transition:width .3s;display:block}.zE6uZW_bookAddCard{justify-content:center;align-items:center;gap:var(--nf-space-8,8px);text-align:center;color:var(--nf-text-2);border-style:dashed;min-height:260px;transition:border-color .15s,color .15s,background .15s,transform .15s}.zE6uZW_bookAddCard:hover{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent);transform:translateY(-2px)}.zE6uZW_bookAddIcon{font-size:var(--nf-fs-34,34px);color:var(--nf-accent);line-height:1;transition:transform .15s}.zE6uZW_bookAddCard:hover .zE6uZW_bookAddIcon{transform:scale(1.12)}.zE6uZW_bookCreateCard{border-color:var(--nf-accent);min-height:260px}.zE6uZW_createBookView{min-height:0;padding:var(--nf-container-pad,20px 22px);gap:var(--nf-container-gap,14px);flex-direction:column;flex:1;display:flex;overflow:auto}.zE6uZW_createBookTop{align-items:center;display:flex}.zE6uZW_createBookCard{align-self:center;gap:var(--nf-space-12,12px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-20,20px);width:min(520px,100%);padding:var(--nf-card-pad,20px 22px);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow-lg);flex-direction:column;display:flex}.zE6uZW_createBookIcon{font-size:var(--nf-fs-34,34px);line-height:1}.zE6uZW_createBookTitle{font-size:var(--nf-fs-22,22px);letter-spacing:-.3px;margin:0;font-weight:800}.zE6uZW_ideaCard{gap:var(--nf-space-8,8px);border:1px dashed var(--nf-border-strong);border-radius:var(--nf-radius-14,14px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);background:color-mix(in srgb, var(--nf-accent) 3%, transparent);flex-direction:column;display:flex}.zE6uZW_ideaToggle{align-items:center;gap:var(--nf-space-6,6px);color:var(--nf-accent);font-size:var(--nf-fs-14,13px);cursor:pointer;text-align:left;background:0 0;border:none;padding:0;font-weight:700;display:flex}.zE6uZW_ideaCandidate{gap:var(--nf-space-6,6px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-12,12px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);background:var(--nf-bg);flex-direction:column;display:flex}.zE6uZW_progressLineDone{color:var(--nf-success);font-weight:600}.zE6uZW_progressLineError{color:var(--nf-error);font-weight:600}.zE6uZW_meta{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);opacity:.9}.zE6uZW_genreDesc{-webkit-line-clamp:2;-webkit-box-orient:vertical;max-width:560px;display:-webkit-box;overflow:hidden}.zE6uZW_fileList{gap:var(--nf-space-4,3px);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);opacity:.9;word-break:break-all;flex-direction:column;display:flex}.zE6uZW_panelContent::-webkit-scrollbar,.zE6uZW_chatScroll::-webkit-scrollbar,.zE6uZW_chapterPreview::-webkit-scrollbar,.zE6uZW_progress::-webkit-scrollbar,.zE6uZW_toolLive::-webkit-scrollbar{width:8px;height:8px}.zE6uZW_panelContent::-webkit-scrollbar-thumb,.zE6uZW_chatScroll::-webkit-scrollbar-thumb,.zE6uZW_chapterPreview::-webkit-scrollbar-thumb,.zE6uZW_progress::-webkit-scrollbar-thumb,.zE6uZW_toolLive::-webkit-scrollbar-thumb{background:var(--nf-border-strong);border-radius:var(--nf-radius-4,4px)}.zE6uZW_panelContent::-webkit-scrollbar-thumb:hover,.zE6uZW_chatScroll::-webkit-scrollbar-thumb:hover,.zE6uZW_chapterPreview::-webkit-scrollbar-thumb:hover,.zE6uZW_progress::-webkit-scrollbar-thumb:hover,.zE6uZW_toolLive::-webkit-scrollbar-thumb:hover{background:var(--nf-text-3)}.zE6uZW_workflowList{flex-direction:column;gap:0;display:flex}.zE6uZW_workflowRow{align-items:flex-start;gap:var(--nf-space-12,12px);padding:var(--nf-space-8,8px) var(--nf-space-4,4px);display:flex;position:relative}.zE6uZW_workflowRow:before{content:\"\";background:var(--nf-border);width:2px;position:absolute;top:34px;bottom:-8px;left:13px}.zE6uZW_workflowRow:last-child:before{display:none}.zE6uZW_workflowDot{width:28px;height:var(--nf-ctrl-s,28px);font-size:var(--nf-fs-12,12px);border:2px solid var(--nf-border-strong);background:var(--nf-bg-raise);color:var(--nf-text-2);z-index:1;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-weight:700;display:inline-flex}.zE6uZW_workflowDotDone{border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 15%, var(--nf-bg-raise));color:var(--nf-success)}.zE6uZW_workflowDotActive{border-color:var(--nf-accent);background:var(--nf-accent);color:var(--nf-accent-fg);box-shadow:0 0 0 4px var(--nf-accent-soft)}.zE6uZW_workflowBody{gap:var(--nf-space-4,4px);min-width:0;padding-top:var(--nf-space-2,2px);flex-direction:column;flex:1;display:flex}.zE6uZW_workflowLabel{font-size:var(--nf-fs-14,13px);color:var(--nf-text);font-weight:600}.zE6uZW_workflowHint{font-size:var(--nf-fs-12,12px);color:var(--nf-text-2)}@keyframes zE6uZW_pulse{0%,to{opacity:1}50%{opacity:.45}}@keyframes zE6uZW_fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.zE6uZW_card{animation:.2s zE6uZW_fadeIn}.zE6uZW_bookshelf{align-items:center;gap:var(--nf-space-10,10px);padding:var(--nf-space-8,8px) var(--nf-space-14,14px);border:1px solid var(--nf-glass-border);border-radius:var(--nf-radius-16,16px);background:var(--nf-glass-face);box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(26px)saturate(175%);z-index:1;flex-wrap:wrap;flex-shrink:0;margin:10px 12px 0;display:flex;position:relative}.zE6uZW_bookshelfLabel{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3);letter-spacing:1px;flex-shrink:0;font-weight:700}.zE6uZW_bookshelfList{align-items:center;gap:var(--nf-space-6,6px);flex-wrap:wrap;flex:1;min-width:0;display:flex}.zE6uZW_bookChip{align-items:center;gap:var(--nf-space-6,6px);padding:var(--nf-space-4,4px) var(--nf-space-8,8px) var(--nf-space-4,4px) var(--nf-space-10,10px);border:1px solid var(--nf-border);border-radius:var(--nf-radius-999,999px);background:var(--nf-bg-inset);cursor:pointer;font-size:var(--nf-fs-12,12px);max-width:220px;transition:border-color .15s,background .15s;display:flex}.zE6uZW_bookChip:hover{border-color:var(--nf-border-strong)}.zE6uZW_bookChipActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.zE6uZW_bookChipName{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.zE6uZW_bookChipMeta{font-size:var(--nf-fs-12,11px);opacity:.7;white-space:nowrap}.zE6uZW_bookChipRemove{color:var(--nf-text-3);cursor:pointer;font-size:var(--nf-fs-14,13px);padding:0 var(--nf-space-2,2px);border-radius:var(--nf-radius-4,4px);background:0 0;border:none;line-height:1}.zE6uZW_bookChipRemove:hover{color:var(--nf-error)}.zE6uZW_bookAdd{border:1px dashed var(--nf-border-strong);color:var(--nf-text-2);cursor:pointer;font-size:var(--nf-fs-12,12px);padding:var(--nf-space-4,4px) var(--nf-space-12,12px);border-radius:var(--nf-radius-999,999px);background:0 0;transition:border-color .15s,color .15s}.zE6uZW_bookAdd:hover{border-color:var(--nf-accent);color:var(--nf-accent)}.zE6uZW_bookCreateForm{align-items:center;gap:var(--nf-space-6,6px);display:flex}.zE6uZW_dropzone{border:2px dashed var(--nf-border-strong);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-18,18px) var(--nf-space-14,14px);text-align:center;font-size:var(--nf-fs-14,13px);color:var(--nf-text-2);cursor:pointer;align-items:center;gap:var(--nf-space-6,6px);flex-direction:column;transition:border-color .15s,background .15s;display:flex}.zE6uZW_dropzone:hover,.zE6uZW_dropzoneActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.zE6uZW_dropzoneIcon{font-size:var(--nf-fs-22,22px);line-height:1}.zE6uZW_bookCardActions{align-items:center;gap:var(--nf-space-6,6px);padding-top:var(--nf-space-8,8px);margin-top:auto;display:flex}.zE6uZW_bookCardActions .zE6uZW_button{flex:1;justify-content:center}.zE6uZW_readerView{flex-direction:column;transition:background .2s,color .2s;display:flex;position:absolute;inset:0;overflow:hidden}.zE6uZW_readerHeader{align-items:center;gap:var(--nf-space-8,8px);padding:var(--nf-space-8,8px) var(--nf-space-12,12px);border-bottom:1px solid;flex-wrap:wrap;flex:none;display:flex}.zE6uZW_readerTitle{font-weight:700;font-size:var(--nf-fs-14,14px)}.zE6uZW_readerSeg{align-items:center;gap:var(--nf-space-2,2px);border-radius:var(--nf-radius-8,8px);display:flex;overflow:hidden}.zE6uZW_readerSegBtn{font-size:var(--nf-fs-12,12px);padding:var(--nf-space-4,3px) var(--nf-space-8,8px);border-radius:var(--nf-radius-6,6px);cursor:pointer;opacity:.75;background:0 0;border:none}.zE6uZW_readerSegBtn:hover,.zE6uZW_readerSegActive{opacity:1}.zE6uZW_readerBody{flex:1;align-items:stretch;min-height:0;display:flex}.zE6uZW_readerSidebar{width:220px;min-width:220px;padding:var(--nf-space-8,8px) var(--nf-space-6,6px) var(--nf-space-24,24px);scrollbar-width:thin;gap:var(--nf-space-10,10px);border-right:1px solid;flex-direction:column;flex:none;display:flex;overflow-y:auto}.zE6uZW_readerGroup{gap:var(--nf-space-2,1px);flex-direction:column;display:flex}.zE6uZW_readerGroupTitle{align-items:center;gap:var(--nf-space-6,6px);width:100%;font-size:var(--nf-fs-12,12px);padding:var(--nf-space-6,6px) var(--nf-space-8,8px) var(--nf-space-4,4px);opacity:.9;cursor:pointer;text-align:left;border-radius:var(--nf-radius-6,6px);background:0 0;border:none;font-weight:700;display:flex}.zE6uZW_readerGroupTitle:hover{opacity:1;background:#8080801f}.zE6uZW_readerGroupArrow{font-size:var(--nf-fs-12,10px);text-align:center;flex:none;width:12px}.zE6uZW_readerGroupCount{font-size:var(--nf-fs-12,11px);opacity:.6;padding-right:var(--nf-space-2,2px);flex:none;margin-left:auto;font-weight:400}.zE6uZW_readerItem{align-items:center;gap:var(--nf-space-6,6px);border-radius:var(--nf-radius-8,8px);font-size:var(--nf-fs-12,12px);text-align:left;padding:var(--nf-space-4,4px) var(--nf-space-8,8px);cursor:pointer;opacity:.8;background:0 0;border:1px solid;min-width:0;transition:opacity .15s,background .15s;display:flex}.zE6uZW_readerItem:hover{opacity:1}.zE6uZW_readerItemActive{opacity:1;font-weight:700}.zE6uZW_readerItemNo{text-align:right;opacity:.75;flex:none;min-width:26px;font-weight:700}.zE6uZW_readerItemTitle{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.zE6uZW_readerItemBadge{font-size:var(--nf-fs-12,11px);flex:none}.zE6uZW_readerMain{min-height:0;padding:var(--nf-space-20,20px) var(--nf-space-16,16px) var(--nf-space-48,48px);scrollbar-width:thin;flex:1;justify-content:center;display:flex;overflow-y:auto}.zE6uZW_readerArticle{gap:var(--nf-space-12,12px);flex-direction:column;width:100%;display:flex}.zE6uZW_readerChapterTitle{font-size:var(--nf-fs-24,24px);letter-spacing:1px;margin:0;font-weight:800}.zE6uZW_readerChapterMeta{align-items:center;gap:var(--nf-space-8,8px);font-size:var(--nf-fs-12,12px);display:flex}.zE6uZW_readerText{text-align:justify;letter-spacing:.02em}.zE6uZW_readerPara{text-indent:2em;margin:0 0 .85em}.zE6uZW_readerFoot{justify-content:space-between;align-items:center;gap:var(--nf-space-8,8px);padding-top:var(--nf-space-12,12px);border-top:1px dashed;margin-top:12px;display:flex}.zE6uZW_readerLoading,.zE6uZW_readerError{padding:var(--nf-space-32,32px) 0;font-size:var(--nf-fs-14,13px);opacity:.7;align-self:center}.zE6uZW_readerError{color:var(--nf-error)}.zE6uZW_importModalOverlay{z-index:1000;backdrop-filter:blur(4px);padding:var(--nf-space-24,24px);background:#00000073;justify-content:center;align-items:center;display:flex;position:fixed;inset:0}.zE6uZW_importModal{gap:var(--nf-space-12,12px);border:1px solid var(--nf-border-strong);border-radius:var(--nf-radius-16,16px);width:min(520px,100%);max-height:85vh;padding:var(--nf-card-pad,20px 22px);background:var(--nf-bg-raise);backdrop-filter:blur(28px)saturate(180%);box-shadow:var(--nf-shadow-lg);flex-direction:column;display:flex;overflow:auto}.zE6uZW_importModalHead{justify-content:space-between;align-items:center;gap:var(--nf-space-10,10px);display:flex}.zE6uZW_importModalTabs{gap:var(--nf-space-8,8px);display:flex}.zE6uZW_importModalTabs .zE6uZW_button{flex:1}.zE6uZW_importModalBody{gap:var(--nf-space-10,10px);flex-direction:column;display:flex}.zE6uZW_importField{gap:var(--nf-space-6,5px);font-size:var(--nf-fs-14,13px);color:var(--nf-text-2);flex-direction:column;display:flex}.zE6uZW_importHint{font-size:var(--nf-fs-12,12px);color:var(--nf-text-3);line-height:1.5}.zE6uZW_importError{border:1px solid color-mix(in srgb, var(--nf-danger,#e5484d) 55%, transparent);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-8,8px) var(--nf-space-10,10px);font-size:var(--nf-fs-12,12.5px);color:var(--nf-danger,#e5484d);background:color-mix(in srgb, var(--nf-danger,#e5484d) 10%, transparent);white-space:pre-wrap;word-break:break-all}.zE6uZW_importResult{gap:var(--nf-space-4,4px);border:1px solid color-mix(in srgb, var(--nf-ok,#46a758) 45%, transparent);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);font-size:var(--nf-fs-14,13px);background:color-mix(in srgb, var(--nf-ok,#46a758) 9%, transparent);word-break:break-all;flex-direction:column;display:flex}.zE6uZW_importModalActions{justify-content:flex-end;gap:var(--nf-space-8,8px);display:flex}.zE6uZW_importFileInfo{align-items:center;gap:var(--nf-space-8,8px);font-size:var(--nf-fs-14,13px);color:var(--nf-text-1);flex-wrap:wrap;display:flex}.zE6uZW_importPreview{gap:var(--nf-space-4,4px);border:1px solid var(--nf-border-strong);border-radius:var(--nf-radius-10,10px);padding:var(--nf-space-10,10px) var(--nf-space-12,12px);font-size:var(--nf-fs-14,13px);background:var(--nf-bg-inset);flex-direction:column;display:flex}.zE6uZW_importPreviewList{padding-left:var(--nf-space-18,18px);gap:var(--nf-space-2,2px);font-size:var(--nf-fs-12,12.5px);color:var(--nf-text-2);flex-direction:column;max-height:140px;margin:0;display:flex;overflow:auto}.zE6uZW_settingsCard .zE6uZW_fieldLabel{white-space:nowrap;text-overflow:ellipsis;max-width:100%;min-height:18px;line-height:18px;overflow:hidden}.zE6uZW_settingsCard .zE6uZW_row{align-items:flex-start}.zE6uZW_helpTipText{width:280px;max-width:70vw;padding:var(--nf-space-10,10px) var(--nf-space-12,12px);border-radius:var(--nf-radius-10,10px);background:var(--nf-bg-raise);border:1px solid var(--nf-border-strong);box-shadow:var(--nf-shadow-lg);font-size:var(--nf-fs-12,12px);color:var(--nf-text-2);white-space:normal;z-index:20;text-align:left;pointer-events:none;font-weight:400;line-height:1.7;display:none;position:absolute;bottom:calc(100% + 8px);left:50%;transform:translate(-50%)}.zE6uZW_helpTip:hover .zE6uZW_helpTipText,.zE6uZW_helpTip:focus .zE6uZW_helpTipText,.zE6uZW_helpTip:focus-within .zE6uZW_helpTipText{display:block}.zE6uZW_settingsCard+.zE6uZW_settingsCard{flex:1;min-height:0}.zE6uZW_switch{border-radius:var(--nf-radius-999,999px);border:1px solid var(--nf-border-strong);background:var(--nf-bg-inset);cursor:pointer;flex:none;width:42px;height:24px;padding:0;transition:background .18s,border-color .18s;position:relative}.zE6uZW_switchKnob{background:#fff;border-radius:50%;width:16px;height:16px;transition:transform .18s;position:absolute;top:3px;left:3px;box-shadow:0 1px 3px #0000004d}.zE6uZW_switchOn{background:var(--nf-accent);border-color:var(--nf-accent)}.zE6uZW_switchOn .zE6uZW_switchKnob{transform:translate(18px)}.zE6uZW_panel[data-nf-theme=neumorph]:not([data-nf-mode=dark]),body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=neumorph][data-nf-mode=light]{--nf-glass-face:color-mix(in srgb, #e4e9f2, transparent calc(100% - var(--nf-glass-opacity,100%)));--nf-bg-raise:color-mix(in srgb, #e4e9f2, transparent calc(100% - var(--nf-glass-opacity,100%)))}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=neumorph],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=neumorph]:not([data-nf-mode]){--nf-glass-face:color-mix(in srgb, #2b2f36, transparent calc(100% - var(--nf-glass-opacity,100%)));--nf-bg-raise:color-mix(in srgb, #2b2f36, transparent calc(100% - var(--nf-glass-opacity,100%)))}.zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode=dark]),body:not([data-ds-dark-theme]) .zE6uZW_panel[data-nf-theme=clay][data-nf-mode=light]{--nf-glass-face:color-mix(in srgb, #efe4d6, transparent calc(100% - var(--nf-glass-opacity,100%)));--nf-bg-raise:color-mix(in srgb, #efe4d6, transparent calc(100% - var(--nf-glass-opacity,100%)))}.zE6uZW_panel[data-nf-mode=dark][data-nf-theme=clay],body[data-ds-dark-theme] .zE6uZW_panel[data-nf-theme=clay]:not([data-nf-mode]){--nf-glass-face:color-mix(in srgb, #37302b, transparent calc(100% - var(--nf-glass-opacity,100%)));--nf-bg-raise:color-mix(in srgb, #37302b, transparent calc(100% - var(--nf-glass-opacity,100%)))}";
|
|
35225
35429
|
const tagId = "@waterwx/dsh-novel-forge/panel.module.css";
|
|
35226
35430
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
35227
35431
|
const tag = document.createElement("style");
|
|
@@ -35231,311 +35435,1100 @@ window.__ModuleLoader__.load({
|
|
|
35231
35435
|
document.head.appendChild(tag);
|
|
35232
35436
|
}
|
|
35233
35437
|
var panel_module_css_default = {
|
|
35234
|
-
"
|
|
35235
|
-
"
|
|
35236
|
-
"workflowDotDone": "zE6uZW_workflowDotDone",
|
|
35237
|
-
"statCardDIconRed": "zE6uZW_statCardDIconRed",
|
|
35238
|
-
"navTitleLogo": "zE6uZW_navTitleLogo",
|
|
35239
|
-
"badgePending": "zE6uZW_badgePending",
|
|
35438
|
+
"diffAdd": "zE6uZW_diffAdd",
|
|
35439
|
+
"progressOverviewCard": "zE6uZW_progressOverviewCard",
|
|
35240
35440
|
"toolStep": "zE6uZW_toolStep",
|
|
35241
|
-
"
|
|
35242
|
-
"
|
|
35243
|
-
"
|
|
35244
|
-
"
|
|
35245
|
-
"
|
|
35246
|
-
"
|
|
35247
|
-
"
|
|
35248
|
-
"
|
|
35249
|
-
"
|
|
35250
|
-
"
|
|
35251
|
-
"
|
|
35252
|
-
"
|
|
35253
|
-
"
|
|
35254
|
-
"
|
|
35441
|
+
"volumeGroupHeader": "zE6uZW_volumeGroupHeader",
|
|
35442
|
+
"authorRail": "zE6uZW_authorRail",
|
|
35443
|
+
"rowEnd": "zE6uZW_rowEnd",
|
|
35444
|
+
"readerSidebar": "zE6uZW_readerSidebar",
|
|
35445
|
+
"readerItemTitle": "zE6uZW_readerItemTitle",
|
|
35446
|
+
"importFileInfo": "zE6uZW_importFileInfo",
|
|
35447
|
+
"authorRailBtn": "zE6uZW_authorRailBtn",
|
|
35448
|
+
"adaptOutlinePre": "zE6uZW_adaptOutlinePre",
|
|
35449
|
+
"switchOn": "zE6uZW_switchOn",
|
|
35450
|
+
"progressLineLive": "zE6uZW_progressLineLive",
|
|
35451
|
+
"dashHeroTitle": "zE6uZW_dashHeroTitle",
|
|
35452
|
+
"bookSwitchCover": "zE6uZW_bookSwitchCover",
|
|
35453
|
+
"shelfStats": "zE6uZW_shelfStats",
|
|
35454
|
+
"wsSelectedText": "zE6uZW_wsSelectedText",
|
|
35455
|
+
"chatBubbleUser": "zE6uZW_chatBubbleUser",
|
|
35456
|
+
"badgeError": "zE6uZW_badgeError",
|
|
35457
|
+
"progressLive": "zE6uZW_progressLive",
|
|
35458
|
+
"readerBody": "zE6uZW_readerBody",
|
|
35459
|
+
"dashStageDot": "zE6uZW_dashStageDot",
|
|
35460
|
+
"assistantFloat": "zE6uZW_assistantFloat",
|
|
35461
|
+
"importError": "zE6uZW_importError",
|
|
35462
|
+
"adaptResult": "zE6uZW_adaptResult",
|
|
35463
|
+
"bookshelfLabel": "zE6uZW_bookshelfLabel",
|
|
35464
|
+
"bookChipRemove": "zE6uZW_bookChipRemove",
|
|
35465
|
+
"importField": "zE6uZW_importField",
|
|
35466
|
+
"tlBar": "zE6uZW_tlBar",
|
|
35467
|
+
"bookCardName": "zE6uZW_bookCardName",
|
|
35468
|
+
"bookCardCover": "zE6uZW_bookCardCover",
|
|
35469
|
+
"toolLive": "zE6uZW_toolLive",
|
|
35470
|
+
"shelfHeader": "zE6uZW_shelfHeader",
|
|
35255
35471
|
"view": "zE6uZW_view",
|
|
35256
|
-
"
|
|
35257
|
-
"
|
|
35258
|
-
"
|
|
35259
|
-
"
|
|
35260
|
-
"bookshelfList": "zE6uZW_bookshelfList",
|
|
35261
|
-
"readerItemActive": "zE6uZW_readerItemActive",
|
|
35262
|
-
"chapterFocus": "zE6uZW_chapterFocus",
|
|
35263
|
-
"fieldLabel": "zE6uZW_fieldLabel",
|
|
35264
|
-
"bookCardActions": "zE6uZW_bookCardActions",
|
|
35265
|
-
"shelfStat": "zE6uZW_shelfStat",
|
|
35266
|
-
"buttonDanger": "zE6uZW_buttonDanger",
|
|
35267
|
-
"badgeWritten": "zE6uZW_badgeWritten",
|
|
35472
|
+
"bookAdd": "zE6uZW_bookAdd",
|
|
35473
|
+
"diffChange": "zE6uZW_diffChange",
|
|
35474
|
+
"navBadgePulse": "zE6uZW_navBadgePulse",
|
|
35475
|
+
"badgePending": "zE6uZW_badgePending",
|
|
35268
35476
|
"assistantStatusBusy": "zE6uZW_assistantStatusBusy",
|
|
35269
|
-
"
|
|
35270
|
-
"
|
|
35271
|
-
"
|
|
35272
|
-
"
|
|
35273
|
-
"
|
|
35274
|
-
"readerGroupArrow": "zE6uZW_readerGroupArrow",
|
|
35275
|
-
"entry": "zE6uZW_entry",
|
|
35276
|
-
"navTab": "zE6uZW_navTab",
|
|
35277
|
-
"bookCreateCard": "zE6uZW_bookCreateCard",
|
|
35278
|
-
"chapterNum": "zE6uZW_chapterNum",
|
|
35279
|
-
"reviewBox": "zE6uZW_reviewBox",
|
|
35280
|
-
"bookCardName": "zE6uZW_bookCardName",
|
|
35281
|
-
"bookSwitchName": "zE6uZW_bookSwitchName",
|
|
35282
|
-
"chapterList": "zE6uZW_chapterList",
|
|
35283
|
-
"toolStepError": "zE6uZW_toolStepError",
|
|
35284
|
-
"dashJourney": "zE6uZW_dashJourney",
|
|
35285
|
-
"busyRow": "zE6uZW_busyRow",
|
|
35286
|
-
"navTabBadge": "zE6uZW_navTabBadge",
|
|
35287
|
-
"tlBar": "zE6uZW_tlBar",
|
|
35288
|
-
"tlSegDone": "zE6uZW_tlSegDone",
|
|
35289
|
-
"todoDanger": "zE6uZW_todoDanger",
|
|
35290
|
-
"navActions": "zE6uZW_navActions",
|
|
35291
|
-
"toolStepDetail": "zE6uZW_toolStepDetail",
|
|
35292
|
-
"bookCardCoverTitle": "zE6uZW_bookCardCoverTitle",
|
|
35293
|
-
"panelNav": "zE6uZW_panelNav",
|
|
35294
|
-
"onlyChanges": "zE6uZW_onlyChanges",
|
|
35295
|
-
"card": "zE6uZW_card",
|
|
35296
|
-
"dashJourneyFill": "zE6uZW_dashJourneyFill",
|
|
35297
|
-
"navAboutUpdate": "zE6uZW_navAboutUpdate",
|
|
35298
|
-
"wsSelectedText": "zE6uZW_wsSelectedText",
|
|
35299
|
-
"wsPreviewText": "zE6uZW_wsPreviewText",
|
|
35300
|
-
"progressLineDone": "zE6uZW_progressLineDone",
|
|
35301
|
-
"iconButton": "zE6uZW_iconButton",
|
|
35302
|
-
"readerFoot": "zE6uZW_readerFoot",
|
|
35303
|
-
"importModalActions": "zE6uZW_importModalActions",
|
|
35304
|
-
"badgeRejected": "zE6uZW_badgeRejected",
|
|
35305
|
-
"chatRole": "zE6uZW_chatRole",
|
|
35306
|
-
"navAbout": "zE6uZW_navAbout",
|
|
35307
|
-
"navTabLabel": "zE6uZW_navTabLabel",
|
|
35308
|
-
"dropzoneActive": "zE6uZW_dropzoneActive",
|
|
35309
|
-
"shelfEmptyTitle": "zE6uZW_shelfEmptyTitle",
|
|
35477
|
+
"readerPara": "zE6uZW_readerPara",
|
|
35478
|
+
"chapterFocus": "zE6uZW_chapterFocus",
|
|
35479
|
+
"badgeDone": "zE6uZW_badgeDone",
|
|
35480
|
+
"dashHero": "zE6uZW_dashHero",
|
|
35481
|
+
"bookshelf": "zE6uZW_bookshelf",
|
|
35310
35482
|
"importModalOverlay": "zE6uZW_importModalOverlay",
|
|
35311
|
-
"
|
|
35312
|
-
"
|
|
35483
|
+
"importHint": "zE6uZW_importHint",
|
|
35484
|
+
"workflowBody": "zE6uZW_workflowBody",
|
|
35485
|
+
"outlineReadonly": "zE6uZW_outlineReadonly",
|
|
35486
|
+
"progressBookFill": "zE6uZW_progressBookFill",
|
|
35313
35487
|
"bookChipActive": "zE6uZW_bookChipActive",
|
|
35488
|
+
"bookChipName": "zE6uZW_bookChipName",
|
|
35489
|
+
"createBookView": "zE6uZW_createBookView",
|
|
35490
|
+
"diffNew": "zE6uZW_diffNew",
|
|
35491
|
+
"dashHeroSparkle": "zE6uZW_dashHeroSparkle",
|
|
35492
|
+
"assetLabel": "zE6uZW_assetLabel",
|
|
35493
|
+
"assetCardContent": "zE6uZW_assetCardContent",
|
|
35494
|
+
"readerFoot": "zE6uZW_readerFoot",
|
|
35495
|
+
"workflowDot": "zE6uZW_workflowDot",
|
|
35496
|
+
"dashFacts": "zE6uZW_dashFacts",
|
|
35497
|
+
"ideaCandidate": "zE6uZW_ideaCandidate",
|
|
35314
35498
|
"workflowDotActive": "zE6uZW_workflowDotActive",
|
|
35315
|
-
"
|
|
35316
|
-
"
|
|
35317
|
-
"
|
|
35318
|
-
"shelfToolbar": "zE6uZW_shelfToolbar",
|
|
35319
|
-
"bookChip": "zE6uZW_bookChip",
|
|
35320
|
-
"navTabBadgeDone": "zE6uZW_navTabBadgeDone",
|
|
35321
|
-
"readerArticle": "zE6uZW_readerArticle",
|
|
35322
|
-
"importModal": "zE6uZW_importModal",
|
|
35323
|
-
"badgeDone": "zE6uZW_badgeDone",
|
|
35324
|
-
"dashHeroActionTitle": "zE6uZW_dashHeroActionTitle",
|
|
35499
|
+
"bookCardActions": "zE6uZW_bookCardActions",
|
|
35500
|
+
"liveText": "zE6uZW_liveText",
|
|
35501
|
+
"pulse": "zE6uZW_pulse",
|
|
35325
35502
|
"diffSame": "zE6uZW_diffSame",
|
|
35326
|
-
"
|
|
35327
|
-
"bookCardBody": "zE6uZW_bookCardBody",
|
|
35328
|
-
"panelNavCollapsed": "zE6uZW_panelNavCollapsed",
|
|
35329
|
-
"input": "zE6uZW_input",
|
|
35330
|
-
"workflowDot": "zE6uZW_workflowDot",
|
|
35331
|
-
"workflowBody": "zE6uZW_workflowBody",
|
|
35332
|
-
"navBadgePulse": "zE6uZW_navBadgePulse",
|
|
35333
|
-
"importResult": "zE6uZW_importResult",
|
|
35334
|
-
"bookAddCard": "zE6uZW_bookAddCard",
|
|
35335
|
-
"dashGrid": "zE6uZW_dashGrid",
|
|
35336
|
-
"assistantResize": "zE6uZW_assistantResize",
|
|
35337
|
-
"diffText": "zE6uZW_diffText",
|
|
35338
|
-
"bookCard": "zE6uZW_bookCard",
|
|
35339
|
-
"progressLineLive": "zE6uZW_progressLineLive",
|
|
35340
|
-
"readerError": "zE6uZW_readerError",
|
|
35341
|
-
"diffColumn": "zE6uZW_diffColumn",
|
|
35342
|
-
"shelfSearch": "zE6uZW_shelfSearch",
|
|
35343
|
-
"chatBubbleAssistant": "zE6uZW_chatBubbleAssistant",
|
|
35344
|
-
"readerSidebar": "zE6uZW_readerSidebar",
|
|
35345
|
-
"statCardDValue": "zE6uZW_statCardDValue",
|
|
35346
|
-
"navTabBadgeWarn": "zE6uZW_navTabBadgeWarn",
|
|
35347
|
-
"progress": "zE6uZW_progress",
|
|
35348
|
-
"switchOn": "zE6uZW_switchOn",
|
|
35349
|
-
"chapterPreview": "zE6uZW_chapterPreview",
|
|
35350
|
-
"cardTitle": "zE6uZW_cardTitle",
|
|
35351
|
-
"badgeError": "zE6uZW_badgeError",
|
|
35352
|
-
"tabBar": "zE6uZW_tabBar",
|
|
35353
|
-
"dashHero": "zE6uZW_dashHero",
|
|
35354
|
-
"dropzoneIcon": "zE6uZW_dropzoneIcon",
|
|
35355
|
-
"importModalHead": "zE6uZW_importModalHead",
|
|
35356
|
-
"wsSelected": "zE6uZW_wsSelected",
|
|
35357
|
-
"bookCardTitleRow": "zE6uZW_bookCardTitleRow",
|
|
35358
|
-
"bookCardProgressBar": "zE6uZW_bookCardProgressBar",
|
|
35359
|
-
"coverPlaceholder": "zE6uZW_coverPlaceholder",
|
|
35360
|
-
"dashHeroAction": "zE6uZW_dashHeroAction",
|
|
35361
|
-
"chapterFocusPulse": "zE6uZW_chapterFocusPulse",
|
|
35362
|
-
"wsEditor": "zE6uZW_wsEditor",
|
|
35503
|
+
"fieldLabel": "zE6uZW_fieldLabel",
|
|
35363
35504
|
"diffList": "zE6uZW_diffList",
|
|
35364
|
-
"workflowLabel": "zE6uZW_workflowLabel",
|
|
35365
|
-
"workflowHint": "zE6uZW_workflowHint",
|
|
35366
|
-
"field": "zE6uZW_field",
|
|
35367
|
-
"panelContent": "zE6uZW_panelContent",
|
|
35368
35505
|
"navGroupLabel": "zE6uZW_navGroupLabel",
|
|
35369
|
-
"
|
|
35370
|
-
"
|
|
35371
|
-
"
|
|
35372
|
-
"
|
|
35373
|
-
"
|
|
35374
|
-
"
|
|
35375
|
-
"
|
|
35506
|
+
"assetGroup": "zE6uZW_assetGroup",
|
|
35507
|
+
"assistantFloatHeader": "zE6uZW_assistantFloatHeader",
|
|
35508
|
+
"dimCurrent": "zE6uZW_dimCurrent",
|
|
35509
|
+
"progressBookHead": "zE6uZW_progressBookHead",
|
|
35510
|
+
"diffLegend": "zE6uZW_diffLegend",
|
|
35511
|
+
"noticeError": "zE6uZW_noticeError",
|
|
35512
|
+
"bookCreateCard": "zE6uZW_bookCreateCard",
|
|
35513
|
+
"readerTitle": "zE6uZW_readerTitle",
|
|
35376
35514
|
"bookSwitchMeta": "zE6uZW_bookSwitchMeta",
|
|
35377
|
-
"
|
|
35378
|
-
"
|
|
35379
|
-
"
|
|
35380
|
-
"bookCardCoverFallback": "zE6uZW_bookCardCoverFallback",
|
|
35381
|
-
"diffTagNew": "zE6uZW_diffTagNew",
|
|
35382
|
-
"bookSwitch": "zE6uZW_bookSwitch",
|
|
35383
|
-
"readerGroup": "zE6uZW_readerGroup",
|
|
35384
|
-
"bookCardActive": "zE6uZW_bookCardActive",
|
|
35385
|
-
"volumeGroupHeader": "zE6uZW_volumeGroupHeader",
|
|
35386
|
-
"toolStepName": "zE6uZW_toolStepName",
|
|
35387
|
-
"tab": "zE6uZW_tab",
|
|
35388
|
-
"shelfView": "zE6uZW_shelfView",
|
|
35389
|
-
"genreDesc": "zE6uZW_genreDesc",
|
|
35390
|
-
"readerText": "zE6uZW_readerText",
|
|
35391
|
-
"helpTip": "zE6uZW_helpTip",
|
|
35392
|
-
"switchKnob": "zE6uZW_switchKnob",
|
|
35393
|
-
"wsPage": "zE6uZW_wsPage",
|
|
35515
|
+
"statCardD": "zE6uZW_statCardD",
|
|
35516
|
+
"wsColumns": "zE6uZW_wsColumns",
|
|
35517
|
+
"adaptTextarea": "zE6uZW_adaptTextarea",
|
|
35394
35518
|
"diffTagOld": "zE6uZW_diffTagOld",
|
|
35395
35519
|
"statRowD": "zE6uZW_statRowD",
|
|
35396
|
-
"
|
|
35397
|
-
"
|
|
35520
|
+
"tlSegFill": "zE6uZW_tlSegFill",
|
|
35521
|
+
"diffOld": "zE6uZW_diffOld",
|
|
35522
|
+
"workflowHint": "zE6uZW_workflowHint",
|
|
35523
|
+
"navTitleName": "zE6uZW_navTitleName",
|
|
35524
|
+
"chapterPreview": "zE6uZW_chapterPreview",
|
|
35525
|
+
"toolStepActive": "zE6uZW_toolStepActive",
|
|
35526
|
+
"progressBarFill": "zE6uZW_progressBarFill",
|
|
35527
|
+
"wsPreview": "zE6uZW_wsPreview",
|
|
35528
|
+
"assetStatValue": "zE6uZW_assetStatValue",
|
|
35529
|
+
"dashGrid": "zE6uZW_dashGrid",
|
|
35530
|
+
"shelfGrid": "zE6uZW_shelfGrid",
|
|
35531
|
+
"entry": "zE6uZW_entry",
|
|
35532
|
+
"progressLineDone": "zE6uZW_progressLineDone",
|
|
35533
|
+
"shelfFilterCount": "zE6uZW_shelfFilterCount",
|
|
35534
|
+
"fadeIn": "zE6uZW_fadeIn",
|
|
35535
|
+
"statCardDIcon": "zE6uZW_statCardDIcon",
|
|
35536
|
+
"readerText": "zE6uZW_readerText",
|
|
35398
35537
|
"navTitleBook": "zE6uZW_navTitleBook",
|
|
35399
|
-
"
|
|
35400
|
-
"
|
|
35538
|
+
"readerLoading": "zE6uZW_readerLoading",
|
|
35539
|
+
"importPreview": "zE6uZW_importPreview",
|
|
35540
|
+
"buttonDanger": "zE6uZW_buttonDanger",
|
|
35541
|
+
"diffColumn": "zE6uZW_diffColumn",
|
|
35542
|
+
"wsPreviewText": "zE6uZW_wsPreviewText",
|
|
35543
|
+
"chatRole": "zE6uZW_chatRole",
|
|
35544
|
+
"chapterBeats": "zE6uZW_chapterBeats",
|
|
35545
|
+
"bookCreateOutline": "zE6uZW_bookCreateOutline",
|
|
35546
|
+
"volumeGroup": "zE6uZW_volumeGroup",
|
|
35547
|
+
"assistantResize": "zE6uZW_assistantResize",
|
|
35548
|
+
"panelTitle": "zE6uZW_panelTitle",
|
|
35549
|
+
"progressBook": "zE6uZW_progressBook",
|
|
35401
35550
|
"readerChapterTitle": "zE6uZW_readerChapterTitle",
|
|
35402
|
-
"
|
|
35403
|
-
"
|
|
35404
|
-
"
|
|
35405
|
-
"
|
|
35406
|
-
"
|
|
35407
|
-
"
|
|
35408
|
-
"
|
|
35409
|
-
"
|
|
35410
|
-
"
|
|
35411
|
-
"
|
|
35412
|
-
"
|
|
35413
|
-
"
|
|
35414
|
-
"
|
|
35415
|
-
"
|
|
35416
|
-
"
|
|
35417
|
-
"
|
|
35418
|
-
"
|
|
35419
|
-
"
|
|
35420
|
-
"
|
|
35421
|
-
"
|
|
35551
|
+
"statCardDUnit": "zE6uZW_statCardDUnit",
|
|
35552
|
+
"readerError": "zE6uZW_readerError",
|
|
35553
|
+
"bookChip": "zE6uZW_bookChip",
|
|
35554
|
+
"dropzoneActive": "zE6uZW_dropzoneActive",
|
|
35555
|
+
"iconButton": "zE6uZW_iconButton",
|
|
35556
|
+
"toolStepName": "zE6uZW_toolStepName",
|
|
35557
|
+
"navGroupSep": "zE6uZW_navGroupSep",
|
|
35558
|
+
"readerSegBtn": "zE6uZW_readerSegBtn",
|
|
35559
|
+
"bigProgressBarFill": "zE6uZW_bigProgressBarFill",
|
|
35560
|
+
"bookCardBody": "zE6uZW_bookCardBody",
|
|
35561
|
+
"authorRailAbout": "zE6uZW_authorRailAbout",
|
|
35562
|
+
"readerHeader": "zE6uZW_readerHeader",
|
|
35563
|
+
"createBookTitle": "zE6uZW_createBookTitle",
|
|
35564
|
+
"statCardDValue": "zE6uZW_statCardDValue",
|
|
35565
|
+
"todoText": "zE6uZW_todoText",
|
|
35566
|
+
"dashStageCurrent": "zE6uZW_dashStageCurrent",
|
|
35567
|
+
"progressBookList": "zE6uZW_progressBookList",
|
|
35568
|
+
"bookCardCoverTitle": "zE6uZW_bookCardCoverTitle",
|
|
35569
|
+
"bookCardBlurb": "zE6uZW_bookCardBlurb",
|
|
35570
|
+
"ideaToggle": "zE6uZW_ideaToggle",
|
|
35571
|
+
"readerItem": "zE6uZW_readerItem",
|
|
35572
|
+
"fileList": "zE6uZW_fileList",
|
|
35573
|
+
"badgeRejected": "zE6uZW_badgeRejected",
|
|
35574
|
+
"dashJourneyFill": "zE6uZW_dashJourneyFill",
|
|
35575
|
+
"dashJourneyStages": "zE6uZW_dashJourneyStages",
|
|
35576
|
+
"assetFilterBar": "zE6uZW_assetFilterBar",
|
|
35577
|
+
"assetKind": "zE6uZW_assetKind",
|
|
35578
|
+
"dashHeroBook": "zE6uZW_dashHeroBook",
|
|
35422
35579
|
"shelfFilters": "zE6uZW_shelfFilters",
|
|
35423
|
-
"
|
|
35424
|
-
"
|
|
35425
|
-
"
|
|
35426
|
-
"
|
|
35427
|
-
"
|
|
35428
|
-
"
|
|
35580
|
+
"shelfFilter": "zE6uZW_shelfFilter",
|
|
35581
|
+
"shelfStatActive": "zE6uZW_shelfStatActive",
|
|
35582
|
+
"shelfEmptyIcon": "zE6uZW_shelfEmptyIcon",
|
|
35583
|
+
"shelfFilterActive": "zE6uZW_shelfFilterActive",
|
|
35584
|
+
"createBookTop": "zE6uZW_createBookTop",
|
|
35585
|
+
"bookSwitchArrow": "zE6uZW_bookSwitchArrow",
|
|
35429
35586
|
"shelfTitleRow": "zE6uZW_shelfTitleRow",
|
|
35430
|
-
"
|
|
35431
|
-
"
|
|
35432
|
-
"
|
|
35587
|
+
"bookshelfList": "zE6uZW_bookshelfList",
|
|
35588
|
+
"navAbout": "zE6uZW_navAbout",
|
|
35589
|
+
"progressTotalFill": "zE6uZW_progressTotalFill",
|
|
35590
|
+
"navTitle": "zE6uZW_navTitle",
|
|
35591
|
+
"chatBubbleAssistant": "zE6uZW_chatBubbleAssistant",
|
|
35592
|
+
"assetStatLabel": "zE6uZW_assetStatLabel",
|
|
35593
|
+
"dashHeroArrow": "zE6uZW_dashHeroArrow",
|
|
35594
|
+
"shelfHero": "zE6uZW_shelfHero",
|
|
35595
|
+
"adaptInputCard": "zE6uZW_adaptInputCard",
|
|
35596
|
+
"shelfStat": "zE6uZW_shelfStat",
|
|
35597
|
+
"ideaCard": "zE6uZW_ideaCard",
|
|
35433
35598
|
"readerSeg": "zE6uZW_readerSeg",
|
|
35434
|
-
"
|
|
35435
|
-
"
|
|
35436
|
-
"
|
|
35437
|
-
"
|
|
35438
|
-
"
|
|
35439
|
-
"
|
|
35440
|
-
"
|
|
35599
|
+
"spaceBetween": "zE6uZW_spaceBetween",
|
|
35600
|
+
"readerItemBadge": "zE6uZW_readerItemBadge",
|
|
35601
|
+
"shelfView": "zE6uZW_shelfView",
|
|
35602
|
+
"switch": "zE6uZW_switch",
|
|
35603
|
+
"navTitleLogo": "zE6uZW_navTitleLogo",
|
|
35604
|
+
"importModalTabs": "zE6uZW_importModalTabs",
|
|
35605
|
+
"assetEditorRow": "zE6uZW_assetEditorRow",
|
|
35606
|
+
"navTabBadgeDanger": "zE6uZW_navTabBadgeDanger",
|
|
35607
|
+
"reviewBox": "zE6uZW_reviewBox",
|
|
35608
|
+
"toolSteps": "zE6uZW_toolSteps",
|
|
35441
35609
|
"todoInfo": "zE6uZW_todoInfo",
|
|
35442
|
-
"
|
|
35443
|
-
"
|
|
35444
|
-
"
|
|
35445
|
-
"
|
|
35446
|
-
"
|
|
35447
|
-
"
|
|
35448
|
-
"navTabIcon": "zE6uZW_navTabIcon",
|
|
35449
|
-
"fadeIn": "zE6uZW_fadeIn",
|
|
35450
|
-
"tlSegTodo": "zE6uZW_tlSegTodo",
|
|
35451
|
-
"tlSegTrack": "zE6uZW_tlSegTrack",
|
|
35452
|
-
"dashHeroBook": "zE6uZW_dashHeroBook",
|
|
35453
|
-
"readerItemTitle": "zE6uZW_readerItemTitle",
|
|
35454
|
-
"shelfFilter": "zE6uZW_shelfFilter",
|
|
35455
|
-
"navAboutRow": "zE6uZW_navAboutRow",
|
|
35456
|
-
"fileList": "zE6uZW_fileList",
|
|
35610
|
+
"dimTitle": "zE6uZW_dimTitle",
|
|
35611
|
+
"field": "zE6uZW_field",
|
|
35612
|
+
"assistantStatus": "zE6uZW_assistantStatus",
|
|
35613
|
+
"adaptProposal": "zE6uZW_adaptProposal",
|
|
35614
|
+
"legendOld": "zE6uZW_legendOld",
|
|
35615
|
+
"navActions": "zE6uZW_navActions",
|
|
35457
35616
|
"volumeGroupToggle": "zE6uZW_volumeGroupToggle",
|
|
35458
|
-
"
|
|
35459
|
-
"
|
|
35460
|
-
"
|
|
35617
|
+
"settingsCard": "zE6uZW_settingsCard",
|
|
35618
|
+
"dimCard": "zE6uZW_dimCard",
|
|
35619
|
+
"toolStepStatus": "zE6uZW_toolStepStatus",
|
|
35620
|
+
"wsAppliedBanner": "zE6uZW_wsAppliedBanner",
|
|
35621
|
+
"buttonSmall": "zE6uZW_buttonSmall",
|
|
35461
35622
|
"buttonPrimary": "zE6uZW_buttonPrimary",
|
|
35462
|
-
"
|
|
35463
|
-
"
|
|
35464
|
-
"
|
|
35465
|
-
"
|
|
35466
|
-
"
|
|
35467
|
-
"
|
|
35468
|
-
"toolStepActive": "zE6uZW_toolStepActive",
|
|
35469
|
-
"chatBubbleUser": "zE6uZW_chatBubbleUser",
|
|
35470
|
-
"switch": "zE6uZW_switch",
|
|
35623
|
+
"diffDel": "zE6uZW_diffDel",
|
|
35624
|
+
"assetFilterChip": "zE6uZW_assetFilterChip",
|
|
35625
|
+
"switchKnob": "zE6uZW_switchKnob",
|
|
35626
|
+
"tlSegLabel": "zE6uZW_tlSegLabel",
|
|
35627
|
+
"navActionBtn": "zE6uZW_navActionBtn",
|
|
35628
|
+
"bookAddIcon": "zE6uZW_bookAddIcon",
|
|
35471
35629
|
"chapterMain": "zE6uZW_chapterMain",
|
|
35472
|
-
"
|
|
35473
|
-
"
|
|
35474
|
-
"navTitleName": "zE6uZW_navTitleName",
|
|
35630
|
+
"workflowLabel": "zE6uZW_workflowLabel",
|
|
35631
|
+
"tlSegDone": "zE6uZW_tlSegDone",
|
|
35475
35632
|
"assistantFloatBody": "zE6uZW_assistantFloatBody",
|
|
35476
|
-
"
|
|
35477
|
-
"
|
|
35478
|
-
"
|
|
35633
|
+
"input": "zE6uZW_input",
|
|
35634
|
+
"diffText": "zE6uZW_diffText",
|
|
35635
|
+
"dashStage": "zE6uZW_dashStage",
|
|
35636
|
+
"coverPlaceholder": "zE6uZW_coverPlaceholder",
|
|
35637
|
+
"statCardDDown": "zE6uZW_statCardDDown",
|
|
35638
|
+
"bigProgressBar": "zE6uZW_bigProgressBar",
|
|
35639
|
+
"onlyChanges": "zE6uZW_onlyChanges",
|
|
35640
|
+
"assetGroupHeader": "zE6uZW_assetGroupHeader",
|
|
35641
|
+
"todoItem": "zE6uZW_todoItem",
|
|
35642
|
+
"assetFilterChipActive": "zE6uZW_assetFilterChipActive",
|
|
35643
|
+
"assetCard": "zE6uZW_assetCard",
|
|
35644
|
+
"shelfEmptyTitle": "zE6uZW_shelfEmptyTitle",
|
|
35645
|
+
"readerGroupArrow": "zE6uZW_readerGroupArrow",
|
|
35646
|
+
"busyRow": "zE6uZW_busyRow",
|
|
35647
|
+
"shelfToolbar": "zE6uZW_shelfToolbar",
|
|
35648
|
+
"bookCardTitleRow": "zE6uZW_bookCardTitleRow",
|
|
35649
|
+
"card": "zE6uZW_card",
|
|
35650
|
+
"chapterTitle": "zE6uZW_chapterTitle",
|
|
35651
|
+
"adaptMatrix": "zE6uZW_adaptMatrix",
|
|
35652
|
+
"dimCardHead": "zE6uZW_dimCardHead",
|
|
35653
|
+
"bookAddCard": "zE6uZW_bookAddCard",
|
|
35654
|
+
"createBookCard": "zE6uZW_createBookCard",
|
|
35655
|
+
"importModalActions": "zE6uZW_importModalActions",
|
|
35656
|
+
"workflowRow": "zE6uZW_workflowRow",
|
|
35657
|
+
"adaptOutline": "zE6uZW_adaptOutline",
|
|
35658
|
+
"diffSameBody": "zE6uZW_diffSameBody",
|
|
35659
|
+
"authorRailTitle": "zE6uZW_authorRailTitle",
|
|
35660
|
+
"panelContent": "zE6uZW_panelContent",
|
|
35661
|
+
"navAboutRow": "zE6uZW_navAboutRow",
|
|
35662
|
+
"panelNav": "zE6uZW_panelNav",
|
|
35663
|
+
"chapterFocusPulse": "zE6uZW_chapterFocusPulse",
|
|
35664
|
+
"entryIcon": "zE6uZW_entryIcon",
|
|
35665
|
+
"toolStepError": "zE6uZW_toolStepError",
|
|
35666
|
+
"progress": "zE6uZW_progress",
|
|
35667
|
+
"tab": "zE6uZW_tab",
|
|
35668
|
+
"dashHeroAction": "zE6uZW_dashHeroAction",
|
|
35669
|
+
"todoDanger": "zE6uZW_todoDanger",
|
|
35670
|
+
"dimEdit": "zE6uZW_dimEdit",
|
|
35671
|
+
"adaptImpact": "zE6uZW_adaptImpact",
|
|
35672
|
+
"progressOverview": "zE6uZW_progressOverview",
|
|
35673
|
+
"tlSegCurrent": "zE6uZW_tlSegCurrent",
|
|
35674
|
+
"bookCardMetaRow": "zE6uZW_bookCardMetaRow",
|
|
35675
|
+
"dropzoneIcon": "zE6uZW_dropzoneIcon",
|
|
35479
35676
|
"statCardDDetail": "zE6uZW_statCardDDetail",
|
|
35480
|
-
"
|
|
35481
|
-
"
|
|
35677
|
+
"dashFact": "zE6uZW_dashFact",
|
|
35678
|
+
"navTabBadgeLive": "zE6uZW_navTabBadgeLive",
|
|
35679
|
+
"readerArticle": "zE6uZW_readerArticle",
|
|
35680
|
+
"toolStepIcon": "zE6uZW_toolStepIcon",
|
|
35681
|
+
"progressTotalBar": "zE6uZW_progressTotalBar",
|
|
35682
|
+
"wsColumn": "zE6uZW_wsColumn",
|
|
35683
|
+
"dashJourney": "zE6uZW_dashJourney",
|
|
35684
|
+
"chapterNum": "zE6uZW_chapterNum",
|
|
35685
|
+
"progressBookActive": "zE6uZW_progressBookActive",
|
|
35686
|
+
"navTabBadgeDone": "zE6uZW_navTabBadgeDone",
|
|
35687
|
+
"dashHeroActionBody": "zE6uZW_dashHeroActionBody",
|
|
35688
|
+
"shelfSearch": "zE6uZW_shelfSearch",
|
|
35689
|
+
"bookCardActive": "zE6uZW_bookCardActive",
|
|
35690
|
+
"assetCardFooter": "zE6uZW_assetCardFooter",
|
|
35482
35691
|
"tlSeg": "zE6uZW_tlSeg",
|
|
35483
|
-
"
|
|
35484
|
-
"
|
|
35485
|
-
"
|
|
35486
|
-
"
|
|
35487
|
-
"
|
|
35488
|
-
"
|
|
35489
|
-
"
|
|
35490
|
-
"
|
|
35491
|
-
"
|
|
35492
|
-
"
|
|
35493
|
-
"
|
|
35692
|
+
"navTabBadgeWarn": "zE6uZW_navTabBadgeWarn",
|
|
35693
|
+
"authorRailBtnActive": "zE6uZW_authorRailBtnActive",
|
|
35694
|
+
"genreDesc": "zE6uZW_genreDesc",
|
|
35695
|
+
"wsEditor": "zE6uZW_wsEditor",
|
|
35696
|
+
"progressLineError": "zE6uZW_progressLineError",
|
|
35697
|
+
"importModal": "zE6uZW_importModal",
|
|
35698
|
+
"readerItemNo": "zE6uZW_readerItemNo",
|
|
35699
|
+
"navAboutUpdate": "zE6uZW_navAboutUpdate",
|
|
35700
|
+
"tlSegTodo": "zE6uZW_tlSegTodo",
|
|
35701
|
+
"authorContent": "zE6uZW_authorContent",
|
|
35702
|
+
"row": "zE6uZW_row",
|
|
35703
|
+
"authorPageBody": "zE6uZW_authorPageBody",
|
|
35704
|
+
"readerView": "zE6uZW_readerView",
|
|
35705
|
+
"assetCardName": "zE6uZW_assetCardName",
|
|
35706
|
+
"navTabBadge": "zE6uZW_navTabBadge",
|
|
35707
|
+
"dashHeroEyebrow": "zE6uZW_dashHeroEyebrow",
|
|
35708
|
+
"readerItemActive": "zE6uZW_readerItemActive",
|
|
35709
|
+
"assetStatDetail": "zE6uZW_assetStatDetail",
|
|
35710
|
+
"chapterActions": "zE6uZW_chapterActions",
|
|
35711
|
+
"statCardDIconRed": "zE6uZW_statCardDIconRed",
|
|
35494
35712
|
"panel": "zE6uZW_panel",
|
|
35495
|
-
"
|
|
35496
|
-
"
|
|
35497
|
-
"shelfGrid": "zE6uZW_shelfGrid",
|
|
35498
|
-
"navSpacer": "zE6uZW_navSpacer",
|
|
35499
|
-
"chapterTitle": "zE6uZW_chapterTitle",
|
|
35500
|
-
"ideaCandidate": "zE6uZW_ideaCandidate",
|
|
35501
|
-
"readerGroupCount": "zE6uZW_readerGroupCount",
|
|
35502
|
-
"readerSegBtn": "zE6uZW_readerSegBtn",
|
|
35503
|
-
"importModalTabs": "zE6uZW_importModalTabs",
|
|
35504
|
-
"importModalBody": "zE6uZW_importModalBody",
|
|
35505
|
-
"statCardDLabel": "zE6uZW_statCardDLabel",
|
|
35506
|
-
"bookChipMeta": "zE6uZW_bookChipMeta",
|
|
35507
|
-
"assetStatLabel": "zE6uZW_assetStatLabel",
|
|
35713
|
+
"textarea": "zE6uZW_textarea",
|
|
35714
|
+
"wsPageHeader": "zE6uZW_wsPageHeader",
|
|
35508
35715
|
"dashJourneyBar": "zE6uZW_dashJourneyBar",
|
|
35509
|
-
"readerItem": "zE6uZW_readerItem",
|
|
35510
|
-
"toolSteps": "zE6uZW_toolSteps",
|
|
35511
|
-
"dashHeroSparkle": "zE6uZW_dashHeroSparkle",
|
|
35512
|
-
"assistantFloatHeader": "zE6uZW_assistantFloatHeader",
|
|
35513
|
-
"diffLegend": "zE6uZW_diffLegend",
|
|
35514
|
-
"diffChange": "zE6uZW_diffChange",
|
|
35515
|
-
"createBookView": "zE6uZW_createBookView",
|
|
35516
|
-
"badge": "zE6uZW_badge",
|
|
35517
|
-
"shelfFilterActive": "zE6uZW_shelfFilterActive",
|
|
35518
|
-
"createBookTop": "zE6uZW_createBookTop",
|
|
35519
35716
|
"panelBody": "zE6uZW_panelBody",
|
|
35520
|
-
"
|
|
35521
|
-
"
|
|
35522
|
-
"
|
|
35523
|
-
"
|
|
35524
|
-
"
|
|
35525
|
-
"
|
|
35526
|
-
|
|
35527
|
-
|
|
35528
|
-
|
|
35529
|
-
|
|
35530
|
-
|
|
35531
|
-
|
|
35532
|
-
|
|
35533
|
-
|
|
35534
|
-
|
|
35535
|
-
|
|
35536
|
-
|
|
35537
|
-
|
|
35538
|
-
|
|
35717
|
+
"meta": "zE6uZW_meta",
|
|
35718
|
+
"navTabLabel": "zE6uZW_navTabLabel",
|
|
35719
|
+
"chapterList": "zE6uZW_chapterList",
|
|
35720
|
+
"badge": "zE6uZW_badge",
|
|
35721
|
+
"assetGroups": "zE6uZW_assetGroups",
|
|
35722
|
+
"todoWarning": "zE6uZW_todoWarning",
|
|
35723
|
+
"assetEditor": "zE6uZW_assetEditor",
|
|
35724
|
+
"progressBookBar": "zE6uZW_progressBookBar",
|
|
35725
|
+
"dropzone": "zE6uZW_dropzone",
|
|
35726
|
+
"readerGroupTitle": "zE6uZW_readerGroupTitle",
|
|
35727
|
+
"readerGroupCount": "zE6uZW_readerGroupCount",
|
|
35728
|
+
"legendNew": "zE6uZW_legendNew",
|
|
35729
|
+
"diffTagNew": "zE6uZW_diffTagNew",
|
|
35730
|
+
"cardTitle": "zE6uZW_cardTitle",
|
|
35731
|
+
"shelfEmpty": "zE6uZW_shelfEmpty",
|
|
35732
|
+
"statCardDLabel": "zE6uZW_statCardDLabel",
|
|
35733
|
+
"readerMain": "zE6uZW_readerMain",
|
|
35734
|
+
"importPreviewList": "zE6uZW_importPreviewList",
|
|
35735
|
+
"dashHeroActionTitle": "zE6uZW_dashHeroActionTitle",
|
|
35736
|
+
"bookCard": "zE6uZW_bookCard",
|
|
35737
|
+
"workflowList": "zE6uZW_workflowList",
|
|
35738
|
+
"bookCreateForm": "zE6uZW_bookCreateForm",
|
|
35739
|
+
"navTabIcon": "zE6uZW_navTabIcon",
|
|
35740
|
+
"navSpacer": "zE6uZW_navSpacer",
|
|
35741
|
+
"navGroup": "zE6uZW_navGroup",
|
|
35742
|
+
"workflowDotDone": "zE6uZW_workflowDotDone",
|
|
35743
|
+
"wsSelected": "zE6uZW_wsSelected",
|
|
35744
|
+
"progressBookName": "zE6uZW_progressBookName",
|
|
35745
|
+
"assetCardTop": "zE6uZW_assetCardTop",
|
|
35746
|
+
"progressOverviewNum": "zE6uZW_progressOverviewNum",
|
|
35747
|
+
"adaptTable": "zE6uZW_adaptTable",
|
|
35748
|
+
"bookSwitch": "zE6uZW_bookSwitch",
|
|
35749
|
+
"entryLabel": "zE6uZW_entryLabel",
|
|
35750
|
+
"adaptImpacts": "zE6uZW_adaptImpacts",
|
|
35751
|
+
"bookCardCoverFallback": "zE6uZW_bookCardCoverFallback",
|
|
35752
|
+
"importModalHead": "zE6uZW_importModalHead",
|
|
35753
|
+
"badgeGenerating": "zE6uZW_badgeGenerating",
|
|
35754
|
+
"badgeWritten": "zE6uZW_badgeWritten",
|
|
35755
|
+
"createBookIcon": "zE6uZW_createBookIcon",
|
|
35756
|
+
"tlSegTrack": "zE6uZW_tlSegTrack",
|
|
35757
|
+
"toolStepDetail": "zE6uZW_toolStepDetail",
|
|
35758
|
+
"bookSwitchName": "zE6uZW_bookSwitchName",
|
|
35759
|
+
"assetGrid": "zE6uZW_assetGrid",
|
|
35760
|
+
"panelNavCollapsed": "zE6uZW_panelNavCollapsed",
|
|
35761
|
+
"authorPageHero": "zE6uZW_authorPageHero",
|
|
35762
|
+
"chapter": "zE6uZW_chapter",
|
|
35763
|
+
"chatScroll": "zE6uZW_chatScroll",
|
|
35764
|
+
"iconBtn": "zE6uZW_iconBtn",
|
|
35765
|
+
"navTab": "zE6uZW_navTab",
|
|
35766
|
+
"bookCardProgressFill": "zE6uZW_bookCardProgressFill",
|
|
35767
|
+
"bookChipMeta": "zE6uZW_bookChipMeta",
|
|
35768
|
+
"readerSegActive": "zE6uZW_readerSegActive",
|
|
35769
|
+
"bookCardProgressBar": "zE6uZW_bookCardProgressBar",
|
|
35770
|
+
"readerGroup": "zE6uZW_readerGroup",
|
|
35771
|
+
"readerChapterMeta": "zE6uZW_readerChapterMeta",
|
|
35772
|
+
"dimCardSelected": "zE6uZW_dimCardSelected",
|
|
35773
|
+
"tabBar": "zE6uZW_tabBar",
|
|
35774
|
+
"button": "zE6uZW_button",
|
|
35775
|
+
"progressLine": "zE6uZW_progressLine",
|
|
35776
|
+
"dashStageDone": "zE6uZW_dashStageDone",
|
|
35777
|
+
"importModalBody": "zE6uZW_importModalBody",
|
|
35778
|
+
"assetTextarea": "zE6uZW_assetTextarea",
|
|
35779
|
+
"helpTip": "zE6uZW_helpTip",
|
|
35780
|
+
"authorHome": "zE6uZW_authorHome",
|
|
35781
|
+
"progressBar": "zE6uZW_progressBar",
|
|
35782
|
+
"importResult": "zE6uZW_importResult",
|
|
35783
|
+
"helpTipText": "zE6uZW_helpTipText",
|
|
35784
|
+
"wsPage": "zE6uZW_wsPage",
|
|
35785
|
+
"authorPageHeader": "zE6uZW_authorPageHeader",
|
|
35786
|
+
"coverPreview": "zE6uZW_coverPreview",
|
|
35787
|
+
"assetStat": "zE6uZW_assetStat"
|
|
35788
|
+
};
|
|
35789
|
+
//#endregion
|
|
35790
|
+
//#region src/client/panel/ModelManager.tsx
|
|
35791
|
+
/**
|
|
35792
|
+
* 模型管理(DSH 风格):两块分区——
|
|
35793
|
+
* ① 模型(提供方管理):提供方卡片(编辑/删除)+ 添加提供方 / 添加自定义提供方;
|
|
35794
|
+
* ② 当前写作模型:提供商/模型下拉 + 测试连通 + 推理强度。
|
|
35795
|
+
*/
|
|
35796
|
+
/** 目录不可用时回退的内置预设(历史行为)。 */
|
|
35797
|
+
const FALLBACK_MODEL_PRESETS = [
|
|
35798
|
+
"deepseek-v4-flash",
|
|
35799
|
+
"deepseek-v4-pro",
|
|
35800
|
+
"deepseek-chat",
|
|
35801
|
+
"deepseek-reasoner"
|
|
35802
|
+
];
|
|
35803
|
+
const CUSTOM = "__custom__";
|
|
35804
|
+
function fallbackVendors() {
|
|
35805
|
+
return LLM_VENDORS.map((v) => ({
|
|
35806
|
+
id: v.route,
|
|
35807
|
+
name: v.name,
|
|
35808
|
+
models: v.models,
|
|
35809
|
+
apiKeyEnv: v.apiKeyEnv,
|
|
35810
|
+
builtin: v.builtin
|
|
35811
|
+
}));
|
|
35812
|
+
}
|
|
35813
|
+
function ModelManager({ api, provider, model, onProvider, onModel }) {
|
|
35814
|
+
const [configuredProviders, setConfiguredProviders] = (0, react.useState)([]);
|
|
35815
|
+
const [providerModels, setProviderModels] = (0, react.useState)([]);
|
|
35816
|
+
const [modelsLoading, setModelsLoading] = (0, react.useState)(false);
|
|
35817
|
+
const [providerCustom, setProviderCustom] = (0, react.useState)(false);
|
|
35818
|
+
const [modelCustom, setModelCustom] = (0, react.useState)(false);
|
|
35819
|
+
const [test, setTest] = (0, react.useState)({ testing: false });
|
|
35820
|
+
const [vendors, setVendors] = (0, react.useState)(fallbackVendors());
|
|
35821
|
+
const [addPanel, setAddPanel] = (0, react.useState)("none");
|
|
35822
|
+
const [editTarget, setEditTarget] = (0, react.useState)("");
|
|
35823
|
+
const [vendorId, setVendorId] = (0, react.useState)("zai-coding-cn");
|
|
35824
|
+
const [addModel, setAddModel] = (0, react.useState)("");
|
|
35825
|
+
const [addApiKey, setAddApiKey] = (0, react.useState)("");
|
|
35826
|
+
const [addName, setAddName] = (0, react.useState)("");
|
|
35827
|
+
const [custProvider, setCustProvider] = (0, react.useState)("");
|
|
35828
|
+
const [custName, setCustName] = (0, react.useState)("");
|
|
35829
|
+
const [custBaseURL, setCustBaseURL] = (0, react.useState)("");
|
|
35830
|
+
const [custProtocol, setCustProtocol] = (0, react.useState)("openai-completions");
|
|
35831
|
+
const [custModel, setCustModel] = (0, react.useState)("");
|
|
35832
|
+
const [custApiKey, setCustApiKey] = (0, react.useState)("");
|
|
35833
|
+
const [savingAdd, setSavingAdd] = (0, react.useState)(false);
|
|
35834
|
+
const [addMsg, setAddMsg] = (0, react.useState)("");
|
|
35835
|
+
const [addErr, setAddErr] = (0, react.useState)("");
|
|
35836
|
+
const loadProviders = (0, react.useCallback)(async () => {
|
|
35837
|
+
try {
|
|
35838
|
+
const r = await api.llmProviders();
|
|
35839
|
+
if (r.providers.length > 0) setConfiguredProviders(r.providers);
|
|
35840
|
+
} catch {}
|
|
35841
|
+
}, [api]);
|
|
35842
|
+
const loadVendors = (0, react.useCallback)(async () => {
|
|
35843
|
+
try {
|
|
35844
|
+
const r = await api.llmVendors();
|
|
35845
|
+
if (r.vendors.length > 0) setVendors(r.vendors);
|
|
35846
|
+
} catch {}
|
|
35847
|
+
}, [api]);
|
|
35848
|
+
const loadProviderModels = (0, react.useCallback)(async (p) => {
|
|
35849
|
+
setModelsLoading(true);
|
|
35850
|
+
try {
|
|
35851
|
+
const r = await api.llmModels(p);
|
|
35852
|
+
setProviderModels(r.models);
|
|
35853
|
+
} catch {
|
|
35854
|
+
setProviderModels([]);
|
|
35855
|
+
} finally {
|
|
35856
|
+
setModelsLoading(false);
|
|
35857
|
+
}
|
|
35858
|
+
}, [api]);
|
|
35859
|
+
(0, react.useEffect)(() => {
|
|
35860
|
+
loadProviders();
|
|
35861
|
+
loadVendors();
|
|
35862
|
+
}, [
|
|
35863
|
+
api,
|
|
35864
|
+
loadProviders,
|
|
35865
|
+
loadVendors
|
|
35866
|
+
]);
|
|
35867
|
+
(0, react.useEffect)(() => {
|
|
35868
|
+
if (provider !== "") loadProviderModels(provider);
|
|
35869
|
+
}, [provider, loadProviderModels]);
|
|
35870
|
+
const currentVendor = vendors.find((v) => v.id === vendorId);
|
|
35871
|
+
const runTest = async () => {
|
|
35872
|
+
const p = provider.trim();
|
|
35873
|
+
const m = model.trim();
|
|
35874
|
+
if (p === "" || m === "" || test.testing) return;
|
|
35875
|
+
setTest({ testing: true });
|
|
35876
|
+
try {
|
|
35877
|
+
const r = await api.llmTest(p, m);
|
|
35878
|
+
setTest({
|
|
35879
|
+
testing: false,
|
|
35880
|
+
ok: r.ok,
|
|
35881
|
+
ms: r.ms,
|
|
35882
|
+
message: r.message
|
|
35883
|
+
});
|
|
35884
|
+
} catch (err) {
|
|
35885
|
+
setTest({
|
|
35886
|
+
testing: false,
|
|
35887
|
+
ok: false,
|
|
35888
|
+
message: err.message
|
|
35889
|
+
});
|
|
35890
|
+
}
|
|
35891
|
+
};
|
|
35892
|
+
const openPanel = (panel, target = "") => {
|
|
35893
|
+
setAddPanel(panel);
|
|
35894
|
+
setEditTarget(target);
|
|
35895
|
+
setAddMsg("");
|
|
35896
|
+
setAddErr("");
|
|
35897
|
+
if (panel === "standard") {
|
|
35898
|
+
setVendorId(target !== "" ? target : "zai-coding-cn");
|
|
35899
|
+
setAddModel("");
|
|
35900
|
+
setAddApiKey("");
|
|
35901
|
+
setAddName("");
|
|
35902
|
+
} else if (panel === "custom") {
|
|
35903
|
+
setCustProvider(target);
|
|
35904
|
+
setCustName("");
|
|
35905
|
+
setCustBaseURL("");
|
|
35906
|
+
setCustModel("");
|
|
35907
|
+
setCustApiKey("");
|
|
35908
|
+
}
|
|
35909
|
+
};
|
|
35910
|
+
const saveStandard = async () => {
|
|
35911
|
+
if (vendorId.trim() === "") {
|
|
35912
|
+
setAddErr("请选择提供方");
|
|
35913
|
+
return;
|
|
35914
|
+
}
|
|
35915
|
+
if (addApiKey.trim() === "") {
|
|
35916
|
+
setAddErr("请填写 API 密钥(或留空使用环境认证)");
|
|
35917
|
+
return;
|
|
35918
|
+
}
|
|
35919
|
+
const modelId = addModel.trim();
|
|
35920
|
+
setSavingAdd(true);
|
|
35921
|
+
setAddMsg("");
|
|
35922
|
+
setAddErr("");
|
|
35923
|
+
try {
|
|
35924
|
+
const res = await api.addModel({
|
|
35925
|
+
mode: "vendor",
|
|
35926
|
+
vendor: vendorId,
|
|
35927
|
+
model: modelId || vendorId,
|
|
35928
|
+
apiKey: addApiKey.trim(),
|
|
35929
|
+
apiKeyEnv: currentVendor?.apiKeyEnv,
|
|
35930
|
+
name: addName.trim() || void 0
|
|
35931
|
+
});
|
|
35932
|
+
setAddMsg(res.message ?? "已保存");
|
|
35933
|
+
setAddPanel("none");
|
|
35934
|
+
setAddApiKey("");
|
|
35935
|
+
setAddModel("");
|
|
35936
|
+
setAddName("");
|
|
35937
|
+
setEditTarget("");
|
|
35938
|
+
await loadProviders();
|
|
35939
|
+
} catch (err) {
|
|
35940
|
+
setAddErr(err.message);
|
|
35941
|
+
} finally {
|
|
35942
|
+
setSavingAdd(false);
|
|
35943
|
+
}
|
|
35944
|
+
};
|
|
35945
|
+
const saveCustom = async () => {
|
|
35946
|
+
if (custProvider.trim() === "") {
|
|
35947
|
+
setAddErr("请填 Provider ID");
|
|
35948
|
+
return;
|
|
35949
|
+
}
|
|
35950
|
+
if (custBaseURL.trim() === "") {
|
|
35951
|
+
setAddErr("请填 API 地址");
|
|
35952
|
+
return;
|
|
35953
|
+
}
|
|
35954
|
+
if (custApiKey.trim() === "") {
|
|
35955
|
+
setAddErr("请填 API 密钥(或留空使用环境认证)");
|
|
35956
|
+
return;
|
|
35957
|
+
}
|
|
35958
|
+
if (custModel.trim() === "") {
|
|
35959
|
+
setAddErr("请填模型 id(或点“获取可用模型”)");
|
|
35960
|
+
return;
|
|
35961
|
+
}
|
|
35962
|
+
setSavingAdd(true);
|
|
35963
|
+
setAddMsg("");
|
|
35964
|
+
setAddErr("");
|
|
35965
|
+
try {
|
|
35966
|
+
const res = await api.addModel({
|
|
35967
|
+
mode: "custom",
|
|
35968
|
+
provider: custProvider.trim(),
|
|
35969
|
+
model: custModel.trim(),
|
|
35970
|
+
apiKey: custApiKey.trim(),
|
|
35971
|
+
baseURL: custBaseURL.trim(),
|
|
35972
|
+
name: custName.trim() || void 0
|
|
35973
|
+
});
|
|
35974
|
+
setAddMsg(res.message ?? "已创建提供方");
|
|
35975
|
+
setAddPanel("none");
|
|
35976
|
+
setCustProvider("");
|
|
35977
|
+
setCustName("");
|
|
35978
|
+
setCustBaseURL("");
|
|
35979
|
+
setCustModel("");
|
|
35980
|
+
setCustApiKey("");
|
|
35981
|
+
await loadProviders();
|
|
35982
|
+
} catch (err) {
|
|
35983
|
+
setAddErr(err.message);
|
|
35984
|
+
} finally {
|
|
35985
|
+
setSavingAdd(false);
|
|
35986
|
+
}
|
|
35987
|
+
};
|
|
35988
|
+
const removeProvider = async (p) => {
|
|
35989
|
+
if (!window.confirm("删除提供方「" + (p.name !== "" ? p.name : p.id) + "」?将移除 DSH 配置与 API 密钥。")) return;
|
|
35990
|
+
try {
|
|
35991
|
+
const vendor = vendors.find((v) => v.id === p.id);
|
|
35992
|
+
await api.removeProvider({
|
|
35993
|
+
provider: p.id,
|
|
35994
|
+
apiKeyEnv: vendor?.apiKeyEnv
|
|
35995
|
+
});
|
|
35996
|
+
await loadProviders();
|
|
35997
|
+
} catch (err) {
|
|
35998
|
+
setAddErr(err.message);
|
|
35999
|
+
}
|
|
36000
|
+
};
|
|
36001
|
+
const providerOptions = configuredProviders.some((p) => p.id === provider) ? configuredProviders : provider !== "" && provider !== CUSTOM ? [{
|
|
36002
|
+
id: provider,
|
|
36003
|
+
name: provider
|
|
36004
|
+
}, ...configuredProviders] : configuredProviders;
|
|
36005
|
+
const modelOptions = modelCustom ? [] : provider === "deepseek-official" ? [...FALLBACK_MODEL_PRESETS.map((id) => ({
|
|
36006
|
+
id,
|
|
36007
|
+
name: id
|
|
36008
|
+
})), ...providerModels.filter((m) => !FALLBACK_MODEL_PRESETS.includes(m.id))] : providerModels;
|
|
36009
|
+
const modelInList = modelOptions.some((m) => m.id === model);
|
|
36010
|
+
const modelValue = modelCustom || !modelInList && model !== "" && modelOptions.length > 0 ? CUSTOM : model;
|
|
36011
|
+
const providerValue = providerCustom ? CUSTOM : provider;
|
|
36012
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36013
|
+
style: {
|
|
36014
|
+
display: "flex",
|
|
36015
|
+
flexDirection: "column",
|
|
36016
|
+
gap: "var(--nf-space-24)"
|
|
36017
|
+
},
|
|
36018
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36019
|
+
className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
|
|
36020
|
+
style: { gap: "var(--nf-space-16)" },
|
|
36021
|
+
children: [
|
|
36022
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36023
|
+
className: panel_module_css_default.cardTitle,
|
|
36024
|
+
children: "模型"
|
|
36025
|
+
}),
|
|
36026
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36027
|
+
className: panel_module_css_default.meta,
|
|
36028
|
+
children: "填入各提供方的 API 密钥即可使用其模型。"
|
|
36029
|
+
}),
|
|
36030
|
+
configuredProviders.map((p) => {
|
|
36031
|
+
const isBuiltin = p.id === "deepseek-official";
|
|
36032
|
+
const isKnownVendor = vendors.some((v) => v.id === p.id);
|
|
36033
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36034
|
+
style: {
|
|
36035
|
+
border: "1px solid var(--nf-border)",
|
|
36036
|
+
borderRadius: "var(--nf-radius-12)",
|
|
36037
|
+
padding: "var(--nf-space-12)",
|
|
36038
|
+
display: "flex",
|
|
36039
|
+
alignItems: "center",
|
|
36040
|
+
gap: "var(--nf-space-8)",
|
|
36041
|
+
flexWrap: "wrap",
|
|
36042
|
+
justifyContent: "space-between"
|
|
36043
|
+
},
|
|
36044
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36045
|
+
style: {
|
|
36046
|
+
display: "flex",
|
|
36047
|
+
alignItems: "center",
|
|
36048
|
+
gap: "var(--nf-space-8)"
|
|
36049
|
+
},
|
|
36050
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36051
|
+
style: { fontWeight: 600 },
|
|
36052
|
+
children: p.name !== "" && p.name !== p.id ? p.name : p.id
|
|
36053
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { style: {
|
|
36054
|
+
width: 8,
|
|
36055
|
+
height: 8,
|
|
36056
|
+
borderRadius: "50%",
|
|
36057
|
+
background: "var(--nf-success)"
|
|
36058
|
+
} })]
|
|
36059
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36060
|
+
style: {
|
|
36061
|
+
display: "flex",
|
|
36062
|
+
gap: "var(--nf-space-6)",
|
|
36063
|
+
alignItems: "center"
|
|
36064
|
+
},
|
|
36065
|
+
children: [!isBuiltin && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36066
|
+
type: "button",
|
|
36067
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
36068
|
+
onClick: () => openPanel(isKnownVendor ? "standard" : "custom", p.id),
|
|
36069
|
+
children: tt("settings.edit")
|
|
36070
|
+
}), !isBuiltin && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36071
|
+
type: "button",
|
|
36072
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
36073
|
+
style: { color: "var(--nf-error)" },
|
|
36074
|
+
onClick: () => {
|
|
36075
|
+
removeProvider(p);
|
|
36076
|
+
},
|
|
36077
|
+
children: tt("settings.delete")
|
|
36078
|
+
})]
|
|
36079
|
+
})]
|
|
36080
|
+
}, p.id);
|
|
36081
|
+
}),
|
|
36082
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36083
|
+
className: panel_module_css_default.row,
|
|
36084
|
+
style: {
|
|
36085
|
+
gap: "var(--nf-space-10)",
|
|
36086
|
+
flexWrap: "wrap"
|
|
36087
|
+
},
|
|
36088
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
36089
|
+
type: "button",
|
|
36090
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
36091
|
+
onClick: () => openPanel("standard"),
|
|
36092
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Plus, {
|
|
36093
|
+
size: 13,
|
|
36094
|
+
style: { verticalAlign: -2 }
|
|
36095
|
+
}), " 添加提供方"]
|
|
36096
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
36097
|
+
type: "button",
|
|
36098
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
36099
|
+
onClick: () => openPanel("custom"),
|
|
36100
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Plus, {
|
|
36101
|
+
size: 13,
|
|
36102
|
+
style: { verticalAlign: -2 }
|
|
36103
|
+
}), " 添加自定义提供方"]
|
|
36104
|
+
})]
|
|
36105
|
+
}),
|
|
36106
|
+
addPanel !== "none" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36107
|
+
style: {
|
|
36108
|
+
border: "1px solid var(--nf-border)",
|
|
36109
|
+
borderRadius: "var(--nf-radius-12)",
|
|
36110
|
+
padding: "var(--nf-space-12)",
|
|
36111
|
+
display: "flex",
|
|
36112
|
+
flexDirection: "column",
|
|
36113
|
+
gap: "var(--nf-space-12)"
|
|
36114
|
+
},
|
|
36115
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36116
|
+
className: panel_module_css_default.row,
|
|
36117
|
+
style: {
|
|
36118
|
+
justifyContent: "space-between",
|
|
36119
|
+
alignItems: "center"
|
|
36120
|
+
},
|
|
36121
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36122
|
+
className: panel_module_css_default.fieldLabel,
|
|
36123
|
+
children: addPanel === "standard" ? editTarget !== "" ? "编辑提供方" : "添加提供方" : "自定义提供方"
|
|
36124
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
36125
|
+
type: "button",
|
|
36126
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
36127
|
+
onClick: () => openPanel("none"),
|
|
36128
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.X, {
|
|
36129
|
+
size: 13,
|
|
36130
|
+
style: { verticalAlign: -2 }
|
|
36131
|
+
}), " 关闭"]
|
|
36132
|
+
})]
|
|
36133
|
+
}), addPanel === "standard" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
36134
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36135
|
+
className: panel_module_css_default.field,
|
|
36136
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
36137
|
+
className: panel_module_css_default.fieldLabel,
|
|
36138
|
+
children: "提供方"
|
|
36139
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
36140
|
+
className: panel_module_css_default.input,
|
|
36141
|
+
value: vendorId,
|
|
36142
|
+
onChange: (e) => setVendorId(e.target.value),
|
|
36143
|
+
children: vendors.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
36144
|
+
value: v.id,
|
|
36145
|
+
children: v.name
|
|
36146
|
+
}, v.id))
|
|
36147
|
+
})]
|
|
36148
|
+
}),
|
|
36149
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36150
|
+
className: panel_module_css_default.field,
|
|
36151
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
36152
|
+
className: panel_module_css_default.fieldLabel,
|
|
36153
|
+
children: "API 密钥"
|
|
36154
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
36155
|
+
className: panel_module_css_default.input,
|
|
36156
|
+
type: "password",
|
|
36157
|
+
value: addApiKey,
|
|
36158
|
+
onChange: (e) => setAddApiKey(e.target.value),
|
|
36159
|
+
placeholder: "输入 API 密钥,或留空使用环境认证"
|
|
36160
|
+
})]
|
|
36161
|
+
}),
|
|
36162
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36163
|
+
className: panel_module_css_default.field,
|
|
36164
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
36165
|
+
className: panel_module_css_default.fieldLabel,
|
|
36166
|
+
children: "模型 id(可选)"
|
|
36167
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
36168
|
+
className: panel_module_css_default.input,
|
|
36169
|
+
value: addModel,
|
|
36170
|
+
onChange: (e) => setAddModel(e.target.value),
|
|
36171
|
+
placeholder: "例如 glm-5.3-flash"
|
|
36172
|
+
})]
|
|
36173
|
+
}),
|
|
36174
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36175
|
+
className: panel_module_css_default.row,
|
|
36176
|
+
style: {
|
|
36177
|
+
justifyContent: "flex-end",
|
|
36178
|
+
gap: "var(--nf-space-8)"
|
|
36179
|
+
},
|
|
36180
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36181
|
+
type: "button",
|
|
36182
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
36183
|
+
onClick: () => openPanel("none"),
|
|
36184
|
+
children: "取消"
|
|
36185
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36186
|
+
type: "button",
|
|
36187
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall + " " + panel_module_css_default.buttonPrimary,
|
|
36188
|
+
disabled: savingAdd,
|
|
36189
|
+
onClick: () => {
|
|
36190
|
+
saveStandard();
|
|
36191
|
+
},
|
|
36192
|
+
children: savingAdd ? "保存中…" : "保存"
|
|
36193
|
+
})]
|
|
36194
|
+
})
|
|
36195
|
+
] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
36196
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36197
|
+
className: panel_module_css_default.field,
|
|
36198
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
36199
|
+
className: panel_module_css_default.fieldLabel,
|
|
36200
|
+
children: "Provider ID"
|
|
36201
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
36202
|
+
className: panel_module_css_default.input,
|
|
36203
|
+
value: custProvider,
|
|
36204
|
+
onChange: (e) => setCustProvider(e.target.value),
|
|
36205
|
+
placeholder: "acme-gateway"
|
|
36206
|
+
})]
|
|
36207
|
+
}),
|
|
36208
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36209
|
+
className: panel_module_css_default.field,
|
|
36210
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
36211
|
+
className: panel_module_css_default.fieldLabel,
|
|
36212
|
+
children: "显示名称"
|
|
36213
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
36214
|
+
className: panel_module_css_default.input,
|
|
36215
|
+
value: custName,
|
|
36216
|
+
onChange: (e) => setCustName(e.target.value),
|
|
36217
|
+
placeholder: "显示名称"
|
|
36218
|
+
})]
|
|
36219
|
+
}),
|
|
36220
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36221
|
+
className: panel_module_css_default.field,
|
|
36222
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
36223
|
+
className: panel_module_css_default.fieldLabel,
|
|
36224
|
+
children: "API 地址"
|
|
36225
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
36226
|
+
className: panel_module_css_default.input,
|
|
36227
|
+
value: custBaseURL,
|
|
36228
|
+
onChange: (e) => setCustBaseURL(e.target.value),
|
|
36229
|
+
placeholder: "https://gateway.example/v1"
|
|
36230
|
+
})]
|
|
36231
|
+
}),
|
|
36232
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36233
|
+
className: panel_module_css_default.field,
|
|
36234
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
36235
|
+
className: panel_module_css_default.fieldLabel,
|
|
36236
|
+
children: "API 协议"
|
|
36237
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
36238
|
+
className: panel_module_css_default.input,
|
|
36239
|
+
value: custProtocol,
|
|
36240
|
+
onChange: (e) => setCustProtocol(e.target.value),
|
|
36241
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
36242
|
+
value: "openai-completions",
|
|
36243
|
+
children: "openai-completions"
|
|
36244
|
+
})
|
|
36245
|
+
})]
|
|
36246
|
+
}),
|
|
36247
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36248
|
+
className: panel_module_css_default.field,
|
|
36249
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
36250
|
+
className: panel_module_css_default.fieldLabel,
|
|
36251
|
+
children: "API 密钥"
|
|
36252
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
36253
|
+
className: panel_module_css_default.input,
|
|
36254
|
+
type: "password",
|
|
36255
|
+
value: custApiKey,
|
|
36256
|
+
onChange: (e) => setCustApiKey(e.target.value),
|
|
36257
|
+
placeholder: "输入 API 密钥"
|
|
36258
|
+
})]
|
|
36259
|
+
}),
|
|
36260
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36261
|
+
className: panel_module_css_default.field,
|
|
36262
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
36263
|
+
className: panel_module_css_default.fieldLabel,
|
|
36264
|
+
children: "模型目录 / 模型 id"
|
|
36265
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
36266
|
+
className: panel_module_css_default.input,
|
|
36267
|
+
value: custModel,
|
|
36268
|
+
onChange: (e) => setCustModel(e.target.value),
|
|
36269
|
+
placeholder: "例如 glm-5.3-flash"
|
|
36270
|
+
})]
|
|
36271
|
+
}),
|
|
36272
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36273
|
+
className: panel_module_css_default.row,
|
|
36274
|
+
style: {
|
|
36275
|
+
justifyContent: "flex-end",
|
|
36276
|
+
gap: "var(--nf-space-8)"
|
|
36277
|
+
},
|
|
36278
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36279
|
+
type: "button",
|
|
36280
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
36281
|
+
onClick: () => openPanel("none"),
|
|
36282
|
+
children: "取消"
|
|
36283
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36284
|
+
type: "button",
|
|
36285
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall + " " + panel_module_css_default.buttonPrimary,
|
|
36286
|
+
disabled: savingAdd,
|
|
36287
|
+
onClick: () => {
|
|
36288
|
+
saveCustom();
|
|
36289
|
+
},
|
|
36290
|
+
children: savingAdd ? "创建中…" : "创建提供方"
|
|
36291
|
+
})]
|
|
36292
|
+
})
|
|
36293
|
+
] })]
|
|
36294
|
+
}),
|
|
36295
|
+
addMsg !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
36296
|
+
className: panel_module_css_default.meta,
|
|
36297
|
+
style: { color: "var(--nf-success)" },
|
|
36298
|
+
children: ["✓ ", addMsg]
|
|
36299
|
+
}),
|
|
36300
|
+
addErr !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
36301
|
+
className: panel_module_css_default.meta,
|
|
36302
|
+
style: { color: "var(--nf-error)" },
|
|
36303
|
+
children: ["✗ ", addErr]
|
|
36304
|
+
})
|
|
36305
|
+
]
|
|
36306
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36307
|
+
className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
|
|
36308
|
+
style: { gap: "var(--nf-space-16)" },
|
|
36309
|
+
children: [
|
|
36310
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36311
|
+
className: panel_module_css_default.cardTitle,
|
|
36312
|
+
children: "当前写作模型"
|
|
36313
|
+
}),
|
|
36314
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36315
|
+
className: panel_module_css_default.field,
|
|
36316
|
+
children: [
|
|
36317
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
36318
|
+
className: panel_module_css_default.fieldLabel,
|
|
36319
|
+
children: tt("settings.provider")
|
|
36320
|
+
}),
|
|
36321
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
36322
|
+
className: panel_module_css_default.input,
|
|
36323
|
+
value: providerValue,
|
|
36324
|
+
onChange: (e) => {
|
|
36325
|
+
const v = e.target.value;
|
|
36326
|
+
if (v === CUSTOM) setProviderCustom(true);
|
|
36327
|
+
else {
|
|
36328
|
+
setProviderCustom(false);
|
|
36329
|
+
onProvider(v);
|
|
36330
|
+
}
|
|
36331
|
+
},
|
|
36332
|
+
children: [providerOptions.map((p) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
36333
|
+
value: p.id,
|
|
36334
|
+
children: p.name !== "" && p.name !== p.id ? p.name + "(" + p.id + ")" : p.id
|
|
36335
|
+
}, p.id)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
36336
|
+
value: CUSTOM,
|
|
36337
|
+
children: tt("settings.customProvider")
|
|
36338
|
+
})]
|
|
36339
|
+
}),
|
|
36340
|
+
providerCustom && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
36341
|
+
className: panel_module_css_default.input,
|
|
36342
|
+
style: { marginTop: "var(--nf-space-6)" },
|
|
36343
|
+
value: provider,
|
|
36344
|
+
placeholder: "provider 路由 id",
|
|
36345
|
+
onChange: (e) => onProvider(e.target.value)
|
|
36346
|
+
})
|
|
36347
|
+
]
|
|
36348
|
+
}),
|
|
36349
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36350
|
+
className: panel_module_css_default.field,
|
|
36351
|
+
children: [
|
|
36352
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
36353
|
+
className: panel_module_css_default.fieldLabel,
|
|
36354
|
+
children: tt("settings.model")
|
|
36355
|
+
}),
|
|
36356
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36357
|
+
className: panel_module_css_default.row,
|
|
36358
|
+
style: {
|
|
36359
|
+
gap: "var(--nf-space-8)",
|
|
36360
|
+
flexWrap: "wrap"
|
|
36361
|
+
},
|
|
36362
|
+
children: [
|
|
36363
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
36364
|
+
className: panel_module_css_default.input,
|
|
36365
|
+
style: {
|
|
36366
|
+
flex: 1,
|
|
36367
|
+
minWidth: 200
|
|
36368
|
+
},
|
|
36369
|
+
value: modelValue,
|
|
36370
|
+
onChange: (e) => {
|
|
36371
|
+
const v = e.target.value;
|
|
36372
|
+
if (v === CUSTOM) setModelCustom(true);
|
|
36373
|
+
else {
|
|
36374
|
+
setModelCustom(false);
|
|
36375
|
+
onModel(v);
|
|
36376
|
+
}
|
|
36377
|
+
},
|
|
36378
|
+
children: [modelOptions.map((m) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
36379
|
+
value: m.id,
|
|
36380
|
+
children: m.name !== "" && m.name !== m.id ? m.name + "(" + m.id + ")" : m.id
|
|
36381
|
+
}, m.id)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
36382
|
+
value: CUSTOM,
|
|
36383
|
+
children: tt("settings.modelCustom")
|
|
36384
|
+
})]
|
|
36385
|
+
}),
|
|
36386
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
36387
|
+
type: "button",
|
|
36388
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
36389
|
+
disabled: modelsLoading || provider === "",
|
|
36390
|
+
title: "刷新模型",
|
|
36391
|
+
onClick: () => {
|
|
36392
|
+
loadProviderModels(provider);
|
|
36393
|
+
},
|
|
36394
|
+
children: [
|
|
36395
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.RefreshCw, {
|
|
36396
|
+
size: 13,
|
|
36397
|
+
style: { verticalAlign: -2 }
|
|
36398
|
+
}),
|
|
36399
|
+
" ",
|
|
36400
|
+
modelsLoading ? "…" : tt("settings.refreshModels")
|
|
36401
|
+
]
|
|
36402
|
+
}),
|
|
36403
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
36404
|
+
type: "button",
|
|
36405
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
36406
|
+
disabled: test.testing || provider.trim() === "" || model.trim() === "",
|
|
36407
|
+
onClick: () => {
|
|
36408
|
+
runTest();
|
|
36409
|
+
},
|
|
36410
|
+
title: tt("settings.testHint"),
|
|
36411
|
+
children: [
|
|
36412
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.PlugZap, {
|
|
36413
|
+
size: 13,
|
|
36414
|
+
style: { verticalAlign: -2 }
|
|
36415
|
+
}),
|
|
36416
|
+
" ",
|
|
36417
|
+
test.testing ? tt("settings.testRunning") : tt("settings.testConnection")
|
|
36418
|
+
]
|
|
36419
|
+
})
|
|
36420
|
+
]
|
|
36421
|
+
}),
|
|
36422
|
+
modelCustom && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
36423
|
+
className: panel_module_css_default.input,
|
|
36424
|
+
style: { marginTop: "var(--nf-space-6)" },
|
|
36425
|
+
value: model,
|
|
36426
|
+
placeholder: tt("settings.modelCustomPlaceholder"),
|
|
36427
|
+
onChange: (e) => onModel(e.target.value)
|
|
36428
|
+
}),
|
|
36429
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36430
|
+
className: panel_module_css_default.meta,
|
|
36431
|
+
style: { color: test.ok === true ? "var(--nf-success)" : test.ok === false ? "var(--nf-error)" : void 0 },
|
|
36432
|
+
children: test.testing ? tt("settings.testRunning") + "…" : test.ok === true ? "✓ " + tt("settings.testOk") + " · " + (test.ms ?? "?") + "ms" : test.ok === false ? "✗ " + tt("settings.testFail") + (test.message !== void 0 ? ":" + test.message : "") : tt("settings.testHint")
|
|
36433
|
+
})
|
|
36434
|
+
]
|
|
36435
|
+
})
|
|
36436
|
+
]
|
|
36437
|
+
})]
|
|
36438
|
+
});
|
|
36439
|
+
}
|
|
36440
|
+
//#endregion
|
|
36441
|
+
//#region src/client/panel/ReasoningSection.tsx
|
|
36442
|
+
/**
|
|
36443
|
+
* 推理强度(思考强度)独立容器:写作类/分析类两个 reasoningEffort 下拉。
|
|
36444
|
+
*/
|
|
36445
|
+
const REASONING_OPTIONS = [
|
|
36446
|
+
"off",
|
|
36447
|
+
"low",
|
|
36448
|
+
"high",
|
|
36449
|
+
"max"
|
|
36450
|
+
];
|
|
36451
|
+
const REASONING_LABEL = {
|
|
36452
|
+
off: tt("settings.reasoning.off"),
|
|
36453
|
+
low: tt("settings.reasoning.low"),
|
|
36454
|
+
high: tt("settings.reasoning.high"),
|
|
36455
|
+
max: tt("settings.reasoning.max")
|
|
36456
|
+
};
|
|
36457
|
+
function ReasoningSection({ reasoningEffort, analysisReasoning, onChange }) {
|
|
36458
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36459
|
+
className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
|
|
36460
|
+
style: { gap: "var(--nf-space-24)" },
|
|
36461
|
+
children: [
|
|
36462
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
36463
|
+
className: panel_module_css_default.cardTitle,
|
|
36464
|
+
children: [
|
|
36465
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Brain, {
|
|
36466
|
+
size: 18,
|
|
36467
|
+
style: { verticalAlign: -3 }
|
|
36468
|
+
}),
|
|
36469
|
+
" ",
|
|
36470
|
+
tt("settings.reasoningSection")
|
|
36471
|
+
]
|
|
36472
|
+
}),
|
|
36473
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36474
|
+
className: panel_module_css_default.field,
|
|
36475
|
+
children: [
|
|
36476
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
36477
|
+
className: panel_module_css_default.fieldLabel,
|
|
36478
|
+
children: tt("settings.reasoningEffort")
|
|
36479
|
+
}),
|
|
36480
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
36481
|
+
className: panel_module_css_default.input,
|
|
36482
|
+
value: reasoningEffort ?? "off",
|
|
36483
|
+
onChange: (e) => onChange({ reasoningEffort: e.target.value }),
|
|
36484
|
+
children: REASONING_OPTIONS.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
36485
|
+
value: v,
|
|
36486
|
+
children: REASONING_LABEL[v]
|
|
36487
|
+
}, v))
|
|
36488
|
+
}),
|
|
36489
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36490
|
+
className: panel_module_css_default.meta,
|
|
36491
|
+
children: tt("settings.reasoningHint")
|
|
36492
|
+
})
|
|
36493
|
+
]
|
|
36494
|
+
}),
|
|
36495
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36496
|
+
className: panel_module_css_default.field,
|
|
36497
|
+
children: [
|
|
36498
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
36499
|
+
className: panel_module_css_default.fieldLabel,
|
|
36500
|
+
children: tt("settings.analysisReasoning")
|
|
36501
|
+
}),
|
|
36502
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
36503
|
+
className: panel_module_css_default.input,
|
|
36504
|
+
value: analysisReasoning ?? "low",
|
|
36505
|
+
onChange: (e) => onChange({ analysisReasoning: e.target.value }),
|
|
36506
|
+
children: REASONING_OPTIONS.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
36507
|
+
value: v,
|
|
36508
|
+
children: REASONING_LABEL[v]
|
|
36509
|
+
}, v))
|
|
36510
|
+
}),
|
|
36511
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36512
|
+
className: panel_module_css_default.meta,
|
|
36513
|
+
children: tt("settings.analysisReasoningHint")
|
|
36514
|
+
})
|
|
36515
|
+
]
|
|
36516
|
+
})
|
|
36517
|
+
]
|
|
36518
|
+
});
|
|
36519
|
+
}
|
|
36520
|
+
//#endregion
|
|
36521
|
+
//#region src/client/panel/AssistantTab.tsx
|
|
36522
|
+
/**
|
|
36523
|
+
* AI 助手(编辑老师):与 AI 编辑对话讨论剧情,助手通过动作指令直接修改
|
|
36524
|
+
* 大纲 / 设定圣经 / 章节。流式渲染回复;工具调用显示为步骤卡片(中文名 +
|
|
36525
|
+
* 状态 + 耗时),顶部状态条展示当前在做什么;支持清空对话记录。
|
|
36526
|
+
*/
|
|
36527
|
+
/** 工具中文名 + 图标映射(作者看得懂)。 */
|
|
36528
|
+
const TOOL_LABELS = {
|
|
36529
|
+
book_overview: {
|
|
36530
|
+
icon: "📖",
|
|
36531
|
+
label: "读取全书上下文"
|
|
35539
36532
|
},
|
|
35540
36533
|
impact_analysis: {
|
|
35541
36534
|
icon: "🔗",
|
|
@@ -37126,6 +38119,2252 @@ window.__ModuleLoader__.load({
|
|
|
37126
38119
|
});
|
|
37127
38120
|
}
|
|
37128
38121
|
//#endregion
|
|
38122
|
+
//#region src/client/text.ts
|
|
38123
|
+
/**
|
|
38124
|
+
* 客户端文件文本智能解码:兼容 UTF-8 BOM / UTF-16 / UTF-8 / GB18030(GBK)。
|
|
38125
|
+
* 浏览器 File.text() 固定按 UTF-8 解码,GBK 中文网文 txt 会乱码,这里兜底。
|
|
38126
|
+
*/
|
|
38127
|
+
/**
|
|
38128
|
+
* 读取一个 File 的文本,按编码探测兜底解码。
|
|
38129
|
+
* @returns 解码后的文本。
|
|
38130
|
+
*/
|
|
38131
|
+
async function readFileTextSmart(file) {
|
|
38132
|
+
const buf = await file.arrayBuffer();
|
|
38133
|
+
const u8 = new Uint8Array(buf);
|
|
38134
|
+
if (u8.length >= 3 && u8[0] === 239 && u8[1] === 187 && u8[2] === 191) return new TextDecoder("utf-8").decode(u8.subarray(3));
|
|
38135
|
+
if (u8.length >= 2 && u8[0] === 255 && u8[1] === 254) return new TextDecoder("utf-16le").decode(u8.subarray(2));
|
|
38136
|
+
if (u8.length >= 2 && u8[0] === 254 && u8[1] === 255) return new TextDecoder("utf-16be").decode(u8.subarray(2));
|
|
38137
|
+
const utf8 = new TextDecoder("utf-8", { fatal: false }).decode(u8);
|
|
38138
|
+
if (!utf8.includes("�")) return utf8;
|
|
38139
|
+
try {
|
|
38140
|
+
return new TextDecoder("gb18030").decode(u8);
|
|
38141
|
+
} catch {
|
|
38142
|
+
return utf8;
|
|
38143
|
+
}
|
|
38144
|
+
}
|
|
38145
|
+
//#endregion
|
|
38146
|
+
//#region src/client/panel/AdaptModeView.tsx
|
|
38147
|
+
/**
|
|
38148
|
+
* 改编模式:P0 分析 → P1 改编方案(勾选/填新值→映射表/规则/影响) → P2 术语替换执行。
|
|
38149
|
+
*/
|
|
38150
|
+
const MUTABILITY_LABEL = {
|
|
38151
|
+
locked: "🔒 建议保留",
|
|
38152
|
+
big: "🟡 可改影响大",
|
|
38153
|
+
small: "🟢 可改影响小",
|
|
38154
|
+
free: "🟣 可自由改",
|
|
38155
|
+
visual: "📦 仅视觉包装"
|
|
38156
|
+
};
|
|
38157
|
+
const MUTABILITY_CLS = {
|
|
38158
|
+
locked: "var(--nf-muted)",
|
|
38159
|
+
big: "var(--nf-warn)",
|
|
38160
|
+
small: "var(--nf-info)",
|
|
38161
|
+
free: "var(--nf-accent)",
|
|
38162
|
+
visual: "var(--nf-muted)"
|
|
38163
|
+
};
|
|
38164
|
+
const RISK_LABEL = {
|
|
38165
|
+
high: "高风险",
|
|
38166
|
+
medium: "中风险",
|
|
38167
|
+
low: "低风险"
|
|
38168
|
+
};
|
|
38169
|
+
function AdaptModeView({ api }) {
|
|
38170
|
+
const [text, setText] = (0, react.useState)("");
|
|
38171
|
+
const [result, setResult] = (0, react.useState)(null);
|
|
38172
|
+
const [edits, setEdits] = (0, react.useState)({});
|
|
38173
|
+
const [proposal, setProposal] = (0, react.useState)(null);
|
|
38174
|
+
const [executed, setExecuted] = (0, react.useState)(null);
|
|
38175
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
38176
|
+
const [busyLabel, setBusyLabel] = (0, react.useState)("");
|
|
38177
|
+
const [error, setError] = (0, react.useState)("");
|
|
38178
|
+
const fileRef = (0, react.useRef)(null);
|
|
38179
|
+
const onFile = async (e) => {
|
|
38180
|
+
const file = e.target.files?.[0];
|
|
38181
|
+
if (file === void 0) return;
|
|
38182
|
+
try {
|
|
38183
|
+
setText(await readFileTextSmart(file));
|
|
38184
|
+
} catch (err) {
|
|
38185
|
+
setError(err.message);
|
|
38186
|
+
}
|
|
38187
|
+
e.target.value = "";
|
|
38188
|
+
};
|
|
38189
|
+
const analyze = async () => {
|
|
38190
|
+
if (text.trim().length < 200) {
|
|
38191
|
+
setError("请粘贴或上传完整小说全文(至少 200 字符)");
|
|
38192
|
+
return;
|
|
38193
|
+
}
|
|
38194
|
+
setBusy(true);
|
|
38195
|
+
setBusyLabel("分析中…");
|
|
38196
|
+
setError("");
|
|
38197
|
+
setProposal(null);
|
|
38198
|
+
setExecuted(null);
|
|
38199
|
+
try {
|
|
38200
|
+
const res = await api.adaptAnalyze(text);
|
|
38201
|
+
setResult(res);
|
|
38202
|
+
const next = {};
|
|
38203
|
+
for (const d of res.dimensions) next[d.key] = {
|
|
38204
|
+
enabled: d.mutability !== "locked",
|
|
38205
|
+
target: d.candidates?.[0] ?? ""
|
|
38206
|
+
};
|
|
38207
|
+
setEdits(next);
|
|
38208
|
+
} catch (err) {
|
|
38209
|
+
setError(err.message);
|
|
38210
|
+
} finally {
|
|
38211
|
+
setBusy(false);
|
|
38212
|
+
setBusyLabel("");
|
|
38213
|
+
}
|
|
38214
|
+
};
|
|
38215
|
+
const setEdit = (key, patch) => {
|
|
38216
|
+
setEdits((prev) => ({
|
|
38217
|
+
...prev,
|
|
38218
|
+
[key]: {
|
|
38219
|
+
...prev[key],
|
|
38220
|
+
...patch
|
|
38221
|
+
}
|
|
38222
|
+
}));
|
|
38223
|
+
};
|
|
38224
|
+
const selectedDims = result === null ? [] : result.dimensions.filter((d) => {
|
|
38225
|
+
const e = edits[d.key];
|
|
38226
|
+
return e?.enabled === true && (e.target ?? "").trim() !== "";
|
|
38227
|
+
});
|
|
38228
|
+
const buildSelections = () => selectedDims.map((d) => ({
|
|
38229
|
+
key: d.key,
|
|
38230
|
+
title: d.title,
|
|
38231
|
+
current: d.current,
|
|
38232
|
+
target: (edits[d.key]?.target ?? "").trim(),
|
|
38233
|
+
mutability: d.mutability
|
|
38234
|
+
}));
|
|
38235
|
+
const propose = async () => {
|
|
38236
|
+
if (result === null || text.trim().length < 200) {
|
|
38237
|
+
setError("请先分析");
|
|
38238
|
+
return;
|
|
38239
|
+
}
|
|
38240
|
+
const selections = buildSelections();
|
|
38241
|
+
if (selections.length === 0) {
|
|
38242
|
+
setError("请至少选择一条要改的维度并填写新值");
|
|
38243
|
+
return;
|
|
38244
|
+
}
|
|
38245
|
+
setBusy(true);
|
|
38246
|
+
setBusyLabel("生成改编方案…");
|
|
38247
|
+
setError("");
|
|
38248
|
+
setExecuted(null);
|
|
38249
|
+
try {
|
|
38250
|
+
const res = await api.adaptPropose({
|
|
38251
|
+
text,
|
|
38252
|
+
selections,
|
|
38253
|
+
dimensions: result.dimensions
|
|
38254
|
+
});
|
|
38255
|
+
setProposal(res.proposal);
|
|
38256
|
+
} catch (err) {
|
|
38257
|
+
setError(err.message);
|
|
38258
|
+
} finally {
|
|
38259
|
+
setBusy(false);
|
|
38260
|
+
setBusyLabel("");
|
|
38261
|
+
}
|
|
38262
|
+
};
|
|
38263
|
+
const execute = async () => {
|
|
38264
|
+
if (proposal === null || proposal.mappings.length === 0) {
|
|
38265
|
+
setError("请先生成改编方案");
|
|
38266
|
+
return;
|
|
38267
|
+
}
|
|
38268
|
+
setBusy(true);
|
|
38269
|
+
setBusyLabel("执行术语替换…");
|
|
38270
|
+
setError("");
|
|
38271
|
+
try {
|
|
38272
|
+
const res = await api.adaptExecute({
|
|
38273
|
+
text,
|
|
38274
|
+
mappings: proposal.mappings,
|
|
38275
|
+
mode: "replace"
|
|
38276
|
+
});
|
|
38277
|
+
setExecuted(res);
|
|
38278
|
+
} catch (err) {
|
|
38279
|
+
setError(err.message);
|
|
38280
|
+
} finally {
|
|
38281
|
+
setBusy(false);
|
|
38282
|
+
setBusyLabel("");
|
|
38283
|
+
}
|
|
38284
|
+
};
|
|
38285
|
+
const downloadAdapted = () => {
|
|
38286
|
+
if (executed === null) return;
|
|
38287
|
+
const blob = new Blob([executed.adaptedText], { type: "text/markdown;charset=utf-8" });
|
|
38288
|
+
const url = URL.createObjectURL(blob);
|
|
38289
|
+
const a = document.createElement("a");
|
|
38290
|
+
a.href = url;
|
|
38291
|
+
a.download = result?.bookName !== void 0 && result.bookName !== "" ? result.bookName + "·改编版.md" : "改编版.md";
|
|
38292
|
+
a.click();
|
|
38293
|
+
URL.revokeObjectURL(url);
|
|
38294
|
+
};
|
|
38295
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38296
|
+
className: panel_module_css_default.authorPageBody,
|
|
38297
|
+
children: [
|
|
38298
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38299
|
+
className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
|
|
38300
|
+
style: { gap: "var(--nf-space-6)" },
|
|
38301
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
38302
|
+
className: panel_module_css_default.panelTitle,
|
|
38303
|
+
style: { margin: 0 },
|
|
38304
|
+
children: "🎬 改编模式"
|
|
38305
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38306
|
+
className: panel_module_css_default.meta,
|
|
38307
|
+
children: "上传全文 → 分析可改范围 → 勾选/填新值 → 生成映射表 → 术语替换执行。"
|
|
38308
|
+
})]
|
|
38309
|
+
}),
|
|
38310
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38311
|
+
className: panel_module_css_default.adaptInputCard,
|
|
38312
|
+
children: [
|
|
38313
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38314
|
+
className: panel_module_css_default.rowEnd,
|
|
38315
|
+
style: { justifyContent: "space-between" },
|
|
38316
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38317
|
+
className: panel_module_css_default.meta,
|
|
38318
|
+
children: "粘贴全文,或上传 txt/md 文件"
|
|
38319
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
38320
|
+
type: "button",
|
|
38321
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
38322
|
+
onClick: () => fileRef.current?.click(),
|
|
38323
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Upload, {
|
|
38324
|
+
size: 13,
|
|
38325
|
+
style: { verticalAlign: -2 }
|
|
38326
|
+
}), " 上传文件"]
|
|
38327
|
+
})]
|
|
38328
|
+
}),
|
|
38329
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
38330
|
+
ref: fileRef,
|
|
38331
|
+
type: "file",
|
|
38332
|
+
accept: ".txt,.md,text/plain,text/markdown",
|
|
38333
|
+
style: { display: "none" },
|
|
38334
|
+
onChange: (e) => {
|
|
38335
|
+
onFile(e);
|
|
38336
|
+
}
|
|
38337
|
+
}),
|
|
38338
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
38339
|
+
className: panel_module_css_default.input + " " + panel_module_css_default.adaptTextarea,
|
|
38340
|
+
value: text,
|
|
38341
|
+
onChange: (e) => setText(e.target.value),
|
|
38342
|
+
placeholder: "粘贴小说全文(含章节标题/分卷更好)…"
|
|
38343
|
+
}),
|
|
38344
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38345
|
+
className: panel_module_css_default.rowEnd,
|
|
38346
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
38347
|
+
className: panel_module_css_default.meta,
|
|
38348
|
+
children: [
|
|
38349
|
+
"已输入 ",
|
|
38350
|
+
text.length,
|
|
38351
|
+
" 字"
|
|
38352
|
+
]
|
|
38353
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
38354
|
+
type: "button",
|
|
38355
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonPrimary,
|
|
38356
|
+
onClick: () => {
|
|
38357
|
+
analyze();
|
|
38358
|
+
},
|
|
38359
|
+
disabled: busy,
|
|
38360
|
+
children: [
|
|
38361
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Wand2, {
|
|
38362
|
+
size: 14,
|
|
38363
|
+
style: { verticalAlign: -2 }
|
|
38364
|
+
}),
|
|
38365
|
+
" ",
|
|
38366
|
+
busy && busyLabel === "分析中…" ? "分析中…" : "开始分析"
|
|
38367
|
+
]
|
|
38368
|
+
})]
|
|
38369
|
+
})
|
|
38370
|
+
]
|
|
38371
|
+
}),
|
|
38372
|
+
error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
38373
|
+
className: panel_module_css_default.noticeError,
|
|
38374
|
+
children: error
|
|
38375
|
+
}),
|
|
38376
|
+
result === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38377
|
+
className: panel_module_css_default.shelfEmpty,
|
|
38378
|
+
style: { minHeight: 160 },
|
|
38379
|
+
children: [
|
|
38380
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38381
|
+
className: panel_module_css_default.shelfEmptyIcon,
|
|
38382
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.FileText, { size: 30 })
|
|
38383
|
+
}),
|
|
38384
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38385
|
+
className: panel_module_css_default.shelfEmptyTitle,
|
|
38386
|
+
children: "等待分析"
|
|
38387
|
+
}),
|
|
38388
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38389
|
+
className: panel_module_css_default.meta,
|
|
38390
|
+
children: "分析会读取全文并提炼「原文设定卡片」与「可改范围矩阵」。"
|
|
38391
|
+
})
|
|
38392
|
+
]
|
|
38393
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38394
|
+
className: panel_module_css_default.adaptResult,
|
|
38395
|
+
children: [
|
|
38396
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38397
|
+
className: panel_module_css_default.authorPageHeader,
|
|
38398
|
+
style: { alignItems: "center" },
|
|
38399
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("h3", {
|
|
38400
|
+
style: { margin: 0 },
|
|
38401
|
+
children: [
|
|
38402
|
+
"《",
|
|
38403
|
+
result.bookName,
|
|
38404
|
+
"》 · ",
|
|
38405
|
+
result.chapters,
|
|
38406
|
+
" 章"
|
|
38407
|
+
]
|
|
38408
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38409
|
+
className: panel_module_css_default.meta,
|
|
38410
|
+
children: result.note
|
|
38411
|
+
})]
|
|
38412
|
+
}),
|
|
38413
|
+
result.outline !== void 0 && result.outline !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
38414
|
+
className: panel_module_css_default.adaptOutline,
|
|
38415
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: "反推大纲(点击展开)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
38416
|
+
className: panel_module_css_default.adaptOutlinePre,
|
|
38417
|
+
children: result.outline
|
|
38418
|
+
})]
|
|
38419
|
+
}),
|
|
38420
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38421
|
+
className: panel_module_css_default.authorPageHeader,
|
|
38422
|
+
style: { alignItems: "center" },
|
|
38423
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "可改范围矩阵(勾选要改 + 填新值)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
38424
|
+
type: "button",
|
|
38425
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonPrimary,
|
|
38426
|
+
onClick: () => {
|
|
38427
|
+
propose();
|
|
38428
|
+
},
|
|
38429
|
+
disabled: busy,
|
|
38430
|
+
children: [
|
|
38431
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.ListChecks, {
|
|
38432
|
+
size: 13,
|
|
38433
|
+
style: { verticalAlign: -2 }
|
|
38434
|
+
}),
|
|
38435
|
+
" ",
|
|
38436
|
+
busy && busyLabel === "生成改编方案…" ? "生成中…" : "生成改编方案",
|
|
38437
|
+
" (",
|
|
38438
|
+
selectedDims.length,
|
|
38439
|
+
")"
|
|
38440
|
+
]
|
|
38441
|
+
})]
|
|
38442
|
+
}),
|
|
38443
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
38444
|
+
className: panel_module_css_default.adaptMatrix,
|
|
38445
|
+
children: result.dimensions.map((d, i) => {
|
|
38446
|
+
const e = edits[d.key];
|
|
38447
|
+
const enabled = e?.enabled === true;
|
|
38448
|
+
const target = e?.target ?? "";
|
|
38449
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38450
|
+
className: panel_module_css_default.dimCard + (enabled ? " " + panel_module_css_default.dimCardSelected : ""),
|
|
38451
|
+
children: [
|
|
38452
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38453
|
+
className: panel_module_css_default.dimCardHead,
|
|
38454
|
+
children: [
|
|
38455
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38456
|
+
className: panel_module_css_default.dimTitle,
|
|
38457
|
+
children: d.title
|
|
38458
|
+
}),
|
|
38459
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38460
|
+
className: panel_module_css_default.badge,
|
|
38461
|
+
style: { color: MUTABILITY_CLS[d.mutability] ?? "var(--nf-muted)" },
|
|
38462
|
+
children: MUTABILITY_LABEL[d.mutability] ?? d.mutability
|
|
38463
|
+
}),
|
|
38464
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
38465
|
+
className: panel_module_css_default.meta,
|
|
38466
|
+
children: ["风险:", RISK_LABEL[d.risk] ?? d.risk]
|
|
38467
|
+
})
|
|
38468
|
+
]
|
|
38469
|
+
}),
|
|
38470
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38471
|
+
className: panel_module_css_default.dimCurrent,
|
|
38472
|
+
children: [
|
|
38473
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "当前值" }),
|
|
38474
|
+
":",
|
|
38475
|
+
d.current
|
|
38476
|
+
]
|
|
38477
|
+
}),
|
|
38478
|
+
d.mutability !== "locked" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38479
|
+
className: panel_module_css_default.dimEdit,
|
|
38480
|
+
children: [
|
|
38481
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
38482
|
+
type: "checkbox",
|
|
38483
|
+
checked: enabled,
|
|
38484
|
+
onChange: (e2) => setEdit(d.key, { enabled: e2.target.checked })
|
|
38485
|
+
}),
|
|
38486
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
38487
|
+
className: panel_module_css_default.input,
|
|
38488
|
+
value: target,
|
|
38489
|
+
disabled: !enabled,
|
|
38490
|
+
placeholder: "改为什么?",
|
|
38491
|
+
onChange: (e2) => setEdit(d.key, { target: e2.target.value })
|
|
38492
|
+
}),
|
|
38493
|
+
(d.candidates ?? []).length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
38494
|
+
className: panel_module_css_default.meta,
|
|
38495
|
+
children: ["候选:", (d.candidates ?? []).join(" / ")]
|
|
38496
|
+
})
|
|
38497
|
+
]
|
|
38498
|
+
}),
|
|
38499
|
+
d.evidence !== void 0 && d.evidence !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38500
|
+
className: panel_module_css_default.meta,
|
|
38501
|
+
children: ["证据:", d.evidence]
|
|
38502
|
+
}),
|
|
38503
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38504
|
+
className: panel_module_css_default.meta,
|
|
38505
|
+
children: ["影响:", d.impact]
|
|
38506
|
+
})
|
|
38507
|
+
]
|
|
38508
|
+
}, d.key + "-" + i);
|
|
38509
|
+
})
|
|
38510
|
+
}),
|
|
38511
|
+
proposal !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38512
|
+
className: panel_module_css_default.adaptProposal,
|
|
38513
|
+
children: [
|
|
38514
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38515
|
+
className: panel_module_css_default.authorPageHeader,
|
|
38516
|
+
style: { alignItems: "center" },
|
|
38517
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "改编方案" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
38518
|
+
type: "button",
|
|
38519
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonPrimary,
|
|
38520
|
+
onClick: () => {
|
|
38521
|
+
execute();
|
|
38522
|
+
},
|
|
38523
|
+
disabled: busy,
|
|
38524
|
+
children: [
|
|
38525
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Play, {
|
|
38526
|
+
size: 13,
|
|
38527
|
+
style: { verticalAlign: -2 }
|
|
38528
|
+
}),
|
|
38529
|
+
" ",
|
|
38530
|
+
busy && busyLabel === "执行术语替换…" ? "执行中…" : "执行改编(术语替换)"
|
|
38531
|
+
]
|
|
38532
|
+
})]
|
|
38533
|
+
}),
|
|
38534
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
38535
|
+
style: { margin: "10px 0 4px" },
|
|
38536
|
+
children: "映射表"
|
|
38537
|
+
}),
|
|
38538
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
|
|
38539
|
+
className: panel_module_css_default.adaptTable,
|
|
38540
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
|
|
38541
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: "原值" }),
|
|
38542
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: "新值" }),
|
|
38543
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", { children: "范围" })
|
|
38544
|
+
] }) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: proposal.mappings.map((m, i2) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("tr", { children: [
|
|
38545
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: m.source }),
|
|
38546
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: m.target }),
|
|
38547
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", { children: m.scope })
|
|
38548
|
+
] }, i2)) })]
|
|
38549
|
+
}),
|
|
38550
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
38551
|
+
style: { margin: "10px 0 4px" },
|
|
38552
|
+
children: "改编规则"
|
|
38553
|
+
}),
|
|
38554
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38555
|
+
className: panel_module_css_default.meta,
|
|
38556
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "保留:" }), proposal.rules.preserve.join(";") || "—"]
|
|
38557
|
+
}),
|
|
38558
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38559
|
+
className: panel_module_css_default.meta,
|
|
38560
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "允许变:" }), proposal.rules.change.join(";") || "—"]
|
|
38561
|
+
}),
|
|
38562
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38563
|
+
className: panel_module_css_default.meta,
|
|
38564
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "红线:" }), proposal.rules.constraints.join(";") || "—"]
|
|
38565
|
+
}),
|
|
38566
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
38567
|
+
style: { margin: "10px 0 4px" },
|
|
38568
|
+
children: "联动影响"
|
|
38569
|
+
}),
|
|
38570
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
38571
|
+
className: panel_module_css_default.adaptImpacts,
|
|
38572
|
+
children: proposal.impacts.map((im, i3) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38573
|
+
className: panel_module_css_default.adaptImpact,
|
|
38574
|
+
children: [
|
|
38575
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", {
|
|
38576
|
+
style: { color: im.risk === "high" ? "var(--nf-error)" : im.risk === "medium" ? "var(--nf-warn)" : "var(--nf-info)" },
|
|
38577
|
+
children: [
|
|
38578
|
+
"[",
|
|
38579
|
+
RISK_LABEL[im.risk] ?? im.risk,
|
|
38580
|
+
"]"
|
|
38581
|
+
]
|
|
38582
|
+
}),
|
|
38583
|
+
" ",
|
|
38584
|
+
im.item,
|
|
38585
|
+
":",
|
|
38586
|
+
im.detail,
|
|
38587
|
+
im.chapters !== void 0 && im.chapters.length > 0 ? `(章:${im.chapters.join(",")})` : ""
|
|
38588
|
+
]
|
|
38589
|
+
}, i3))
|
|
38590
|
+
})
|
|
38591
|
+
]
|
|
38592
|
+
}),
|
|
38593
|
+
executed !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38594
|
+
className: panel_module_css_default.adaptProposal,
|
|
38595
|
+
children: [
|
|
38596
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38597
|
+
className: panel_module_css_default.authorPageHeader,
|
|
38598
|
+
style: { alignItems: "center" },
|
|
38599
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "改编结果(术语替换)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
38600
|
+
type: "button",
|
|
38601
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
38602
|
+
onClick: downloadAdapted,
|
|
38603
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Download, {
|
|
38604
|
+
size: 13,
|
|
38605
|
+
style: { verticalAlign: -2 }
|
|
38606
|
+
}), " 下载改编版"]
|
|
38607
|
+
})]
|
|
38608
|
+
}),
|
|
38609
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38610
|
+
className: panel_module_css_default.meta,
|
|
38611
|
+
children: ["命中:", executed.hits.filter((h) => h.count > 0).map((h) => h.source + "→" + h.target + "×" + h.count).join(",") || "无命中"]
|
|
38612
|
+
}),
|
|
38613
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
38614
|
+
className: panel_module_css_default.adaptOutline,
|
|
38615
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", { children: "改编正文预览(点击展开)" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
38616
|
+
className: panel_module_css_default.adaptOutlinePre,
|
|
38617
|
+
children: executed.adaptedText.slice(0, 8e3)
|
|
38618
|
+
})]
|
|
38619
|
+
})
|
|
38620
|
+
]
|
|
38621
|
+
})
|
|
38622
|
+
]
|
|
38623
|
+
})
|
|
38624
|
+
]
|
|
38625
|
+
});
|
|
38626
|
+
}
|
|
38627
|
+
//#endregion
|
|
38628
|
+
//#region src/client/panel/AuthorAssetsView.tsx
|
|
38629
|
+
/**
|
|
38630
|
+
* 作者资产库/总数据页:跨书可复用的笔法/红线/套路/角色模板/世界观模板。
|
|
38631
|
+
* 支持 新增 / 编辑 / 删除;数据持久化到 ~/.dsh/dsh-novel-forge-author-assets.json。
|
|
38632
|
+
*/
|
|
38633
|
+
const KIND_LABELS = {
|
|
38634
|
+
style: "笔法",
|
|
38635
|
+
antiAi: "红线/反AI",
|
|
38636
|
+
progression: "推进模式",
|
|
38637
|
+
genre: "题材",
|
|
38638
|
+
roleTemplate: "角色模板",
|
|
38639
|
+
worldTemplate: "世界观模板",
|
|
38640
|
+
custom: "自定义"
|
|
38641
|
+
};
|
|
38642
|
+
const KIND_OPTIONS = Object.keys(KIND_LABELS);
|
|
38643
|
+
const KIND_COLORS = {
|
|
38644
|
+
style: "var(--nf-info)",
|
|
38645
|
+
antiAi: "var(--nf-warn)",
|
|
38646
|
+
progression: "var(--nf-accent)",
|
|
38647
|
+
genre: "var(--nf-info)",
|
|
38648
|
+
roleTemplate: "var(--nf-accent)",
|
|
38649
|
+
worldTemplate: "var(--nf-warn)",
|
|
38650
|
+
custom: "var(--nf-muted)"
|
|
38651
|
+
};
|
|
38652
|
+
/** 计算资产的分组(分类):题材按顶层题材名('/' 之前),其余按类型。 */
|
|
38653
|
+
function assetCategory(a) {
|
|
38654
|
+
if (a.kind === "genre") {
|
|
38655
|
+
const top = a.name.split("/")[0]?.trim();
|
|
38656
|
+
return top !== void 0 && top !== "" ? top : "题材";
|
|
38657
|
+
}
|
|
38658
|
+
return KIND_LABELS[a.kind] ?? "其他";
|
|
38659
|
+
}
|
|
38660
|
+
function emptyEditor() {
|
|
38661
|
+
return {
|
|
38662
|
+
name: "",
|
|
38663
|
+
kind: "style",
|
|
38664
|
+
summary: "",
|
|
38665
|
+
content: "",
|
|
38666
|
+
tags: "",
|
|
38667
|
+
sourceBooks: ""
|
|
38668
|
+
};
|
|
38669
|
+
}
|
|
38670
|
+
function AuthorAssetsView({ api }) {
|
|
38671
|
+
const [assets, setAssets] = (0, react.useState)([]);
|
|
38672
|
+
const [editing, setEditing] = (0, react.useState)(null);
|
|
38673
|
+
const [error, setError] = (0, react.useState)("");
|
|
38674
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
38675
|
+
const [kindFilter, setKindFilter] = (0, react.useState)("all");
|
|
38676
|
+
const load = async () => {
|
|
38677
|
+
try {
|
|
38678
|
+
const res = await api.authorAssets();
|
|
38679
|
+
setAssets(res.assets.items);
|
|
38680
|
+
} catch (err) {
|
|
38681
|
+
setError(err.message);
|
|
38682
|
+
}
|
|
38683
|
+
};
|
|
38684
|
+
/** 导入默认:把书架书的写作资产/角色 + 内置全局库批量沉淀到作者资产库。 */
|
|
38685
|
+
const importDefaults = async () => {
|
|
38686
|
+
setBusy(true);
|
|
38687
|
+
setError("");
|
|
38688
|
+
try {
|
|
38689
|
+
const res = await api.authorAssetsImportDefault();
|
|
38690
|
+
setAssets(res.assets.items);
|
|
38691
|
+
} catch (err) {
|
|
38692
|
+
setError(err.message);
|
|
38693
|
+
} finally {
|
|
38694
|
+
setBusy(false);
|
|
38695
|
+
}
|
|
38696
|
+
};
|
|
38697
|
+
(0, react.useEffect)(() => {
|
|
38698
|
+
let cancelled = false;
|
|
38699
|
+
(async () => {
|
|
38700
|
+
try {
|
|
38701
|
+
const res = await api.authorAssets();
|
|
38702
|
+
if (cancelled) return;
|
|
38703
|
+
if (res.assets.items.length === 0) {
|
|
38704
|
+
const imp = await api.authorAssetsImportDefault();
|
|
38705
|
+
if (!cancelled) setAssets(imp.assets.items);
|
|
38706
|
+
} else setAssets(res.assets.items);
|
|
38707
|
+
} catch (err) {
|
|
38708
|
+
if (!cancelled) setError(err.message);
|
|
38709
|
+
}
|
|
38710
|
+
})();
|
|
38711
|
+
return () => {
|
|
38712
|
+
cancelled = true;
|
|
38713
|
+
};
|
|
38714
|
+
}, [api]);
|
|
38715
|
+
const startNew = () => {
|
|
38716
|
+
setEditing(emptyEditor());
|
|
38717
|
+
setError("");
|
|
38718
|
+
};
|
|
38719
|
+
const startEdit = (a) => {
|
|
38720
|
+
setEditing({
|
|
38721
|
+
id: a.id,
|
|
38722
|
+
name: a.name,
|
|
38723
|
+
kind: a.kind,
|
|
38724
|
+
summary: a.summary,
|
|
38725
|
+
content: a.content,
|
|
38726
|
+
tags: a.tags.join("、"),
|
|
38727
|
+
sourceBooks: a.sourceBooks.join("、")
|
|
38728
|
+
});
|
|
38729
|
+
setError("");
|
|
38730
|
+
};
|
|
38731
|
+
const save = async () => {
|
|
38732
|
+
if (editing === null) return;
|
|
38733
|
+
if (editing.name.trim() === "") {
|
|
38734
|
+
setError("请填写资产名");
|
|
38735
|
+
return;
|
|
38736
|
+
}
|
|
38737
|
+
setBusy(true);
|
|
38738
|
+
setError("");
|
|
38739
|
+
try {
|
|
38740
|
+
const asset = {
|
|
38741
|
+
id: editing.id ?? "",
|
|
38742
|
+
name: editing.name.trim(),
|
|
38743
|
+
kind: editing.kind,
|
|
38744
|
+
summary: editing.summary.trim(),
|
|
38745
|
+
content: editing.content.trim(),
|
|
38746
|
+
sourceBooks: editing.sourceBooks.split(/[、,,\s]+/).map((s) => s.trim()).filter(Boolean),
|
|
38747
|
+
tags: editing.tags.split(/[、,,\s]+/).map((s) => s.trim()).filter(Boolean),
|
|
38748
|
+
createdAt: "",
|
|
38749
|
+
updatedAt: ""
|
|
38750
|
+
};
|
|
38751
|
+
await api.authorAssetsUpsert(asset);
|
|
38752
|
+
setEditing(null);
|
|
38753
|
+
await load();
|
|
38754
|
+
} catch (err) {
|
|
38755
|
+
setError(err.message);
|
|
38756
|
+
} finally {
|
|
38757
|
+
setBusy(false);
|
|
38758
|
+
}
|
|
38759
|
+
};
|
|
38760
|
+
const del = async (id) => {
|
|
38761
|
+
setBusy(true);
|
|
38762
|
+
setError("");
|
|
38763
|
+
try {
|
|
38764
|
+
await api.authorAssetsRemove(id);
|
|
38765
|
+
await load();
|
|
38766
|
+
} catch (err) {
|
|
38767
|
+
setError(err.message);
|
|
38768
|
+
} finally {
|
|
38769
|
+
setBusy(false);
|
|
38770
|
+
}
|
|
38771
|
+
};
|
|
38772
|
+
const visible = (0, react.useMemo)(() => kindFilter === "all" ? assets : assets.filter((a) => a.kind === kindFilter), [assets, kindFilter]);
|
|
38773
|
+
/** 按分类分组展示(题材按顶层题材名,其余按类型)。 */
|
|
38774
|
+
const grouped = (0, react.useMemo)(() => {
|
|
38775
|
+
const map = /* @__PURE__ */ new Map();
|
|
38776
|
+
for (const a of visible) {
|
|
38777
|
+
const cat = assetCategory(a);
|
|
38778
|
+
const arr = map.get(cat) ?? [];
|
|
38779
|
+
arr.push(a);
|
|
38780
|
+
map.set(cat, arr);
|
|
38781
|
+
}
|
|
38782
|
+
return Array.from(map.entries()).sort((x, y) => x[0].localeCompare(y[0], "zh"));
|
|
38783
|
+
}, [visible]);
|
|
38784
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38785
|
+
className: panel_module_css_default.authorPageBody,
|
|
38786
|
+
children: [
|
|
38787
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38788
|
+
className: panel_module_css_default.authorPageHero,
|
|
38789
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38790
|
+
className: panel_module_css_default.authorPageHeader,
|
|
38791
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
38792
|
+
className: panel_module_css_default.panelTitle,
|
|
38793
|
+
style: { margin: 0 },
|
|
38794
|
+
children: "🧬 作者资产库 · 总数据"
|
|
38795
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38796
|
+
className: panel_module_css_default.meta,
|
|
38797
|
+
children: "跨书可复用的笔法/红线/套路/角色模板/世界观模板。任意新书与改编都能调用。"
|
|
38798
|
+
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38799
|
+
className: panel_module_css_default.rowEnd,
|
|
38800
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
38801
|
+
type: "button",
|
|
38802
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
38803
|
+
onClick: () => {
|
|
38804
|
+
importDefaults();
|
|
38805
|
+
},
|
|
38806
|
+
disabled: busy,
|
|
38807
|
+
title: "把书架里所有书的写作资产/角色 + 内置题材/反AI/风格模板/推进模式批量导入",
|
|
38808
|
+
children: "导入默认资产"
|
|
38809
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
38810
|
+
type: "button",
|
|
38811
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonPrimary,
|
|
38812
|
+
onClick: startNew,
|
|
38813
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Plus, {
|
|
38814
|
+
size: 14,
|
|
38815
|
+
style: { verticalAlign: -2 }
|
|
38816
|
+
}), " 新增资产"]
|
|
38817
|
+
})]
|
|
38818
|
+
})]
|
|
38819
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
38820
|
+
className: panel_module_css_default.assetFilterBar,
|
|
38821
|
+
children: KIND_OPTIONS.map((k) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
38822
|
+
type: "button",
|
|
38823
|
+
className: panel_module_css_default.assetFilterChip + (kindFilter === k ? " " + panel_module_css_default.assetFilterChipActive : ""),
|
|
38824
|
+
onClick: () => setKindFilter(kindFilter === k ? "all" : k),
|
|
38825
|
+
children: [
|
|
38826
|
+
KIND_LABELS[k],
|
|
38827
|
+
" ",
|
|
38828
|
+
assets.filter((a) => a.kind === k).length
|
|
38829
|
+
]
|
|
38830
|
+
}, k))
|
|
38831
|
+
})]
|
|
38832
|
+
}),
|
|
38833
|
+
error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
38834
|
+
className: panel_module_css_default.noticeError,
|
|
38835
|
+
children: error
|
|
38836
|
+
}),
|
|
38837
|
+
editing !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38838
|
+
className: panel_module_css_default.assetEditor,
|
|
38839
|
+
children: [
|
|
38840
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
38841
|
+
style: { margin: 0 },
|
|
38842
|
+
children: editing.id !== "" && editing.id !== void 0 ? "编辑资产" : "新增资产"
|
|
38843
|
+
}),
|
|
38844
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38845
|
+
className: panel_module_css_default.assetEditorRow,
|
|
38846
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
38847
|
+
className: panel_module_css_default.assetLabel,
|
|
38848
|
+
children: ["资产名 ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
38849
|
+
className: panel_module_css_default.input,
|
|
38850
|
+
value: editing.name,
|
|
38851
|
+
onChange: (e) => setEditing({
|
|
38852
|
+
...editing,
|
|
38853
|
+
name: e.target.value
|
|
38854
|
+
}),
|
|
38855
|
+
placeholder: "如:短句快节奏爽文风"
|
|
38856
|
+
})]
|
|
38857
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
38858
|
+
className: panel_module_css_default.assetLabel,
|
|
38859
|
+
children: ["类型 ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
38860
|
+
className: panel_module_css_default.input,
|
|
38861
|
+
value: editing.kind,
|
|
38862
|
+
onChange: (e) => setEditing({
|
|
38863
|
+
...editing,
|
|
38864
|
+
kind: e.target.value
|
|
38865
|
+
}),
|
|
38866
|
+
children: KIND_OPTIONS.map((k) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
38867
|
+
value: k,
|
|
38868
|
+
children: KIND_LABELS[k]
|
|
38869
|
+
}, k))
|
|
38870
|
+
})]
|
|
38871
|
+
})]
|
|
38872
|
+
}),
|
|
38873
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
38874
|
+
className: panel_module_css_default.assetLabel,
|
|
38875
|
+
children: ["一句话摘要 ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
38876
|
+
className: panel_module_css_default.input,
|
|
38877
|
+
value: editing.summary,
|
|
38878
|
+
onChange: (e) => setEditing({
|
|
38879
|
+
...editing,
|
|
38880
|
+
summary: e.target.value
|
|
38881
|
+
}),
|
|
38882
|
+
placeholder: "这个资产解决什么问题 / 有什么特点"
|
|
38883
|
+
})]
|
|
38884
|
+
}),
|
|
38885
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
38886
|
+
className: panel_module_css_default.assetLabel,
|
|
38887
|
+
children: ["内容(按类型约定的描述 / 规则 / 结构化文本)", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
38888
|
+
className: `${panel_module_css_default.input} ${panel_module_css_default.assetTextarea}`,
|
|
38889
|
+
value: editing.content,
|
|
38890
|
+
onChange: (e) => setEditing({
|
|
38891
|
+
...editing,
|
|
38892
|
+
content: e.target.value
|
|
38893
|
+
}),
|
|
38894
|
+
placeholder: "角色模板示例:\n姓名:林越\n定位:痞坏型主角\n口头禅:\"有点意思\"\n性格:表面懒散、内里狠辣\n成长弧线:从底层游街到一方枭雄"
|
|
38895
|
+
})]
|
|
38896
|
+
}),
|
|
38897
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38898
|
+
className: panel_module_css_default.assetEditorRow,
|
|
38899
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
38900
|
+
className: panel_module_css_default.assetLabel,
|
|
38901
|
+
children: ["标签(顿号分隔) ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
38902
|
+
className: panel_module_css_default.input,
|
|
38903
|
+
value: editing.tags,
|
|
38904
|
+
onChange: (e) => setEditing({
|
|
38905
|
+
...editing,
|
|
38906
|
+
tags: e.target.value
|
|
38907
|
+
}),
|
|
38908
|
+
placeholder: "扮猪吃虎、快节奏、冷面"
|
|
38909
|
+
})]
|
|
38910
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
38911
|
+
className: panel_module_css_default.assetLabel,
|
|
38912
|
+
children: ["来源书(顿号分隔) ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
38913
|
+
className: panel_module_css_default.input,
|
|
38914
|
+
value: editing.sourceBooks,
|
|
38915
|
+
onChange: (e) => setEditing({
|
|
38916
|
+
...editing,
|
|
38917
|
+
sourceBooks: e.target.value
|
|
38918
|
+
}),
|
|
38919
|
+
placeholder: "《某某传》《某某录》"
|
|
38920
|
+
})]
|
|
38921
|
+
})]
|
|
38922
|
+
}),
|
|
38923
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38924
|
+
className: panel_module_css_default.rowEnd,
|
|
38925
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
38926
|
+
type: "button",
|
|
38927
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonPrimary}`,
|
|
38928
|
+
onClick: save,
|
|
38929
|
+
disabled: busy,
|
|
38930
|
+
children: busy ? "保存中…" : "保存"
|
|
38931
|
+
}), editing.id !== "" && editing.id !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
38932
|
+
type: "button",
|
|
38933
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
38934
|
+
onClick: () => setEditing(null),
|
|
38935
|
+
children: "取消"
|
|
38936
|
+
})]
|
|
38937
|
+
})
|
|
38938
|
+
]
|
|
38939
|
+
}) : null,
|
|
38940
|
+
visible.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38941
|
+
className: panel_module_css_default.shelfEmpty,
|
|
38942
|
+
style: { minHeight: 160 },
|
|
38943
|
+
children: [
|
|
38944
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38945
|
+
className: panel_module_css_default.shelfEmptyIcon,
|
|
38946
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Plus, { size: 30 })
|
|
38947
|
+
}),
|
|
38948
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38949
|
+
className: panel_module_css_default.shelfEmptyTitle,
|
|
38950
|
+
children: "还没有资产"
|
|
38951
|
+
}),
|
|
38952
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38953
|
+
className: panel_module_css_default.meta,
|
|
38954
|
+
children: "点「新增资产」收藏你的笔法/角色模板/套路,跨书调用。"
|
|
38955
|
+
})
|
|
38956
|
+
]
|
|
38957
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
38958
|
+
className: panel_module_css_default.assetGroups,
|
|
38959
|
+
children: grouped.map(([cat, items]) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38960
|
+
className: panel_module_css_default.assetGroup,
|
|
38961
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38962
|
+
className: panel_module_css_default.assetGroupHeader,
|
|
38963
|
+
children: [
|
|
38964
|
+
cat,
|
|
38965
|
+
" ",
|
|
38966
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38967
|
+
className: panel_module_css_default.meta,
|
|
38968
|
+
children: items.length
|
|
38969
|
+
})
|
|
38970
|
+
]
|
|
38971
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
38972
|
+
className: panel_module_css_default.assetGrid,
|
|
38973
|
+
children: items.map((a) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38974
|
+
className: panel_module_css_default.assetCard,
|
|
38975
|
+
children: [
|
|
38976
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38977
|
+
className: panel_module_css_default.assetCardTop,
|
|
38978
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38979
|
+
className: panel_module_css_default.assetKind,
|
|
38980
|
+
style: { color: KIND_COLORS[a.kind] },
|
|
38981
|
+
children: KIND_LABELS[a.kind]
|
|
38982
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
38983
|
+
className: panel_module_css_default.rowEnd,
|
|
38984
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
38985
|
+
type: "button",
|
|
38986
|
+
className: panel_module_css_default.iconBtn,
|
|
38987
|
+
title: "编辑",
|
|
38988
|
+
onClick: () => startEdit(a),
|
|
38989
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Pencil, { size: 13 })
|
|
38990
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
38991
|
+
type: "button",
|
|
38992
|
+
className: panel_module_css_default.iconBtn,
|
|
38993
|
+
title: "删除",
|
|
38994
|
+
onClick: () => {
|
|
38995
|
+
del(a.id);
|
|
38996
|
+
},
|
|
38997
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Trash2, { size: 13 })
|
|
38998
|
+
})]
|
|
38999
|
+
})]
|
|
39000
|
+
}),
|
|
39001
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
39002
|
+
className: panel_module_css_default.assetCardName,
|
|
39003
|
+
children: a.name
|
|
39004
|
+
}),
|
|
39005
|
+
a.summary !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
39006
|
+
className: panel_module_css_default.meta,
|
|
39007
|
+
children: a.summary
|
|
39008
|
+
}),
|
|
39009
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
39010
|
+
className: panel_module_css_default.assetCardContent,
|
|
39011
|
+
children: a.content
|
|
39012
|
+
}),
|
|
39013
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39014
|
+
className: panel_module_css_default.assetCardFooter,
|
|
39015
|
+
children: [a.tags.map((t) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
39016
|
+
className: panel_module_css_default.badge,
|
|
39017
|
+
children: t
|
|
39018
|
+
}, t)), a.sourceBooks.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
39019
|
+
className: panel_module_css_default.meta,
|
|
39020
|
+
children: ["来源:", a.sourceBooks.join(" / ")]
|
|
39021
|
+
})]
|
|
39022
|
+
})
|
|
39023
|
+
]
|
|
39024
|
+
}, a.id))
|
|
39025
|
+
})]
|
|
39026
|
+
}, cat))
|
|
39027
|
+
})
|
|
39028
|
+
]
|
|
39029
|
+
});
|
|
39030
|
+
}
|
|
39031
|
+
//#endregion
|
|
39032
|
+
//#region src/client/panel/ProgressConsole.tsx
|
|
39033
|
+
/**
|
|
39034
|
+
* 共享「AI 进度」实时控制台:当前任务大进度条 + 全量活动日志。
|
|
39035
|
+
* 书内与首页共用一个表现,内容来自同一份进度状态。
|
|
39036
|
+
*/
|
|
39037
|
+
function ProgressConsole({ progress, busy, busyLabel, liveBar, onClear }) {
|
|
39038
|
+
const endRef = (0, react.useRef)(null);
|
|
39039
|
+
(0, react.useEffect)(() => {
|
|
39040
|
+
endRef.current?.scrollIntoView({
|
|
39041
|
+
behavior: "smooth",
|
|
39042
|
+
block: "nearest"
|
|
39043
|
+
});
|
|
39044
|
+
}, [progress]);
|
|
39045
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39046
|
+
style: {
|
|
39047
|
+
display: "flex",
|
|
39048
|
+
flexDirection: "column",
|
|
39049
|
+
gap: "var(--nf-space-10)",
|
|
39050
|
+
height: "100%",
|
|
39051
|
+
minHeight: 0
|
|
39052
|
+
},
|
|
39053
|
+
children: [
|
|
39054
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39055
|
+
style: {
|
|
39056
|
+
display: "flex",
|
|
39057
|
+
alignItems: "center",
|
|
39058
|
+
justifyContent: "space-between"
|
|
39059
|
+
},
|
|
39060
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
39061
|
+
style: { fontWeight: 600 },
|
|
39062
|
+
children: "📊 AI 进度"
|
|
39063
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
39064
|
+
type: "button",
|
|
39065
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
39066
|
+
onClick: onClear,
|
|
39067
|
+
title: "清空活动记录",
|
|
39068
|
+
children: "清空"
|
|
39069
|
+
})]
|
|
39070
|
+
}),
|
|
39071
|
+
busy && (busyLabel !== "" || liveBar !== null) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39072
|
+
style: {
|
|
39073
|
+
border: "1px solid var(--nf-accent)",
|
|
39074
|
+
borderRadius: "var(--nf-radius-10)",
|
|
39075
|
+
padding: "var(--nf-space-8) var(--nf-space-12)",
|
|
39076
|
+
display: "flex",
|
|
39077
|
+
flexDirection: "column",
|
|
39078
|
+
gap: "var(--nf-space-6)",
|
|
39079
|
+
background: "color-mix(in srgb, var(--nf-accent) 6%, transparent)"
|
|
39080
|
+
},
|
|
39081
|
+
children: [
|
|
39082
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
39083
|
+
style: {
|
|
39084
|
+
fontSize: "var(--nf-fs-12)",
|
|
39085
|
+
fontWeight: 600,
|
|
39086
|
+
color: "var(--nf-accent)"
|
|
39087
|
+
},
|
|
39088
|
+
children: [
|
|
39089
|
+
"✍ ",
|
|
39090
|
+
busyLabel !== "" ? busyLabel : liveBar?.text ?? "任务进行中",
|
|
39091
|
+
"…"
|
|
39092
|
+
]
|
|
39093
|
+
}),
|
|
39094
|
+
liveBar?.ratio !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
39095
|
+
className: panel_module_css_default.bigProgressBar,
|
|
39096
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
39097
|
+
className: panel_module_css_default.bigProgressBarFill,
|
|
39098
|
+
style: { width: Math.round(liveBar.ratio * 100) + "%" }
|
|
39099
|
+
})
|
|
39100
|
+
}),
|
|
39101
|
+
liveBar?.text !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
39102
|
+
className: panel_module_css_default.liveText,
|
|
39103
|
+
children: liveBar.text
|
|
39104
|
+
})
|
|
39105
|
+
]
|
|
39106
|
+
}),
|
|
39107
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39108
|
+
className: panel_module_css_default.progress,
|
|
39109
|
+
style: {
|
|
39110
|
+
flex: 1,
|
|
39111
|
+
minHeight: 0,
|
|
39112
|
+
overflowY: "auto",
|
|
39113
|
+
border: "1px solid var(--nf-border)",
|
|
39114
|
+
borderRadius: "var(--nf-radius-10)",
|
|
39115
|
+
background: "var(--nf-bg-inset)",
|
|
39116
|
+
padding: "var(--nf-space-8)",
|
|
39117
|
+
display: "flex",
|
|
39118
|
+
flexDirection: "column"
|
|
39119
|
+
},
|
|
39120
|
+
children: [progress.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39121
|
+
style: {
|
|
39122
|
+
flex: 1,
|
|
39123
|
+
display: "flex",
|
|
39124
|
+
flexDirection: "column",
|
|
39125
|
+
alignItems: "center",
|
|
39126
|
+
justifyContent: "center",
|
|
39127
|
+
gap: "var(--nf-space-4)",
|
|
39128
|
+
color: "var(--nf-text-3)",
|
|
39129
|
+
fontSize: "var(--nf-fs-12)",
|
|
39130
|
+
minHeight: 120
|
|
39131
|
+
},
|
|
39132
|
+
children: [
|
|
39133
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
39134
|
+
style: { fontSize: "var(--nf-fs-22)" },
|
|
39135
|
+
children: "📭"
|
|
39136
|
+
}),
|
|
39137
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "暂无活动记录" }),
|
|
39138
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "生成、审稿等操作会显示在这里" })
|
|
39139
|
+
]
|
|
39140
|
+
}) : progress.map((line) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39141
|
+
className: line.kind === "done" ? panel_module_css_default.progressLineDone : line.kind === "error" ? panel_module_css_default.progressLineError : line.live === true ? panel_module_css_default.progressLineLive : panel_module_css_default.progressLine,
|
|
39142
|
+
children: [line.live === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
39143
|
+
className: panel_module_css_default.progressBar,
|
|
39144
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
39145
|
+
className: panel_module_css_default.progressBarFill,
|
|
39146
|
+
style: { width: Math.round((line.ratio ?? 0) * 100) + "%" }
|
|
39147
|
+
})
|
|
39148
|
+
}), line.text]
|
|
39149
|
+
}, line.id)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { ref: endRef })]
|
|
39150
|
+
})
|
|
39151
|
+
]
|
|
39152
|
+
});
|
|
39153
|
+
}
|
|
39154
|
+
//#endregion
|
|
39155
|
+
//#region src/client/panel/SettingsView.tsx
|
|
39156
|
+
/**
|
|
39157
|
+
* 共享设置页(作者首页「设置」与书内「设置」同入口)。
|
|
39158
|
+
* 自给自足:挂载时通过 api.status() 拉取全局配置,支持 model/writing/image/files/appearance 五组,
|
|
39159
|
+
* 保存走 api.patchConfig。不与某个书绑定,因此新装用户无书也能用。
|
|
39160
|
+
*/
|
|
39161
|
+
const SETTINGS_SECTIONS$1 = [
|
|
39162
|
+
{
|
|
39163
|
+
id: "model",
|
|
39164
|
+
label: "模型与推理",
|
|
39165
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Brain, { size: 16 })
|
|
39166
|
+
},
|
|
39167
|
+
{
|
|
39168
|
+
id: "writing",
|
|
39169
|
+
label: "写作与审稿",
|
|
39170
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.PenLine, { size: 16 })
|
|
39171
|
+
},
|
|
39172
|
+
{
|
|
39173
|
+
id: "image",
|
|
39174
|
+
label: "生图模型",
|
|
39175
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Palette, { size: 16 })
|
|
39176
|
+
},
|
|
39177
|
+
{
|
|
39178
|
+
id: "files",
|
|
39179
|
+
label: "路径与文件",
|
|
39180
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Folder, { size: 16 })
|
|
39181
|
+
},
|
|
39182
|
+
{
|
|
39183
|
+
id: "appearance",
|
|
39184
|
+
label: "外观与主题",
|
|
39185
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Sparkles, { size: 16 })
|
|
39186
|
+
}
|
|
39187
|
+
];
|
|
39188
|
+
function readLS(key, fallback, allowed) {
|
|
39189
|
+
try {
|
|
39190
|
+
const v = window.localStorage.getItem(key);
|
|
39191
|
+
return v !== null && allowed.includes(v) ? v : fallback;
|
|
39192
|
+
} catch {
|
|
39193
|
+
return fallback;
|
|
39194
|
+
}
|
|
39195
|
+
}
|
|
39196
|
+
function SettingsView({ api, onTheme, onSettingsTab, onEditorFontSize, onBackground, onOpacity }) {
|
|
39197
|
+
const [config, setConfig] = (0, react.useState)(null);
|
|
39198
|
+
const [configDraft, setConfigDraft] = (0, react.useState)(null);
|
|
39199
|
+
const [busy, setBusy] = (0, react.useState)(false);
|
|
39200
|
+
const [error, setError] = (0, react.useState)("");
|
|
39201
|
+
const [notice, setNotice] = (0, react.useState)("");
|
|
39202
|
+
const [settingsTab, setSettingsTabState] = (0, react.useState)(() => readLS("dsh-novel-forge.settings.tab", "model", [
|
|
39203
|
+
"model",
|
|
39204
|
+
"writing",
|
|
39205
|
+
"image",
|
|
39206
|
+
"files",
|
|
39207
|
+
"appearance"
|
|
39208
|
+
]));
|
|
39209
|
+
const [imageTestState, setImageTestState] = (0, react.useState)({});
|
|
39210
|
+
const [editorFontSize, setEditorFontSize] = (0, react.useState)(() => {
|
|
39211
|
+
try {
|
|
39212
|
+
const v = Number(window.localStorage.getItem("dsh-novel-forge.editor.fontSize"));
|
|
39213
|
+
return v >= 12 && v <= 24 ? v : 14;
|
|
39214
|
+
} catch {
|
|
39215
|
+
return 14;
|
|
39216
|
+
}
|
|
39217
|
+
});
|
|
39218
|
+
const [panelTheme, setPanelTheme] = (0, react.useState)(() => readLS("dsh-novel-forge.theme", "liquid", [
|
|
39219
|
+
"liquid",
|
|
39220
|
+
"neumorph",
|
|
39221
|
+
"macos",
|
|
39222
|
+
"clay"
|
|
39223
|
+
]));
|
|
39224
|
+
const [themeMode, setThemeMode] = (0, react.useState)(() => readLS("dsh-novel-forge.theme.mode", "system", [
|
|
39225
|
+
"system",
|
|
39226
|
+
"light",
|
|
39227
|
+
"dark"
|
|
39228
|
+
]));
|
|
39229
|
+
const [themeDensity, setThemeDensity] = (0, react.useState)(() => readLS("dsh-novel-forge.theme.density", "comfort", [
|
|
39230
|
+
"comfort",
|
|
39231
|
+
"compact",
|
|
39232
|
+
"spacious"
|
|
39233
|
+
]));
|
|
39234
|
+
const loadConfig = async () => {
|
|
39235
|
+
try {
|
|
39236
|
+
const res = await api.status();
|
|
39237
|
+
setConfig(res.config);
|
|
39238
|
+
setConfigDraft(res.config);
|
|
39239
|
+
} catch (err) {
|
|
39240
|
+
setError(err.message);
|
|
39241
|
+
}
|
|
39242
|
+
};
|
|
39243
|
+
(0, react.useEffect)(() => {
|
|
39244
|
+
loadConfig();
|
|
39245
|
+
}, []);
|
|
39246
|
+
(0, react.useEffect)(() => {
|
|
39247
|
+
try {
|
|
39248
|
+
window.localStorage.setItem("dsh-novel-forge.settings.tab", settingsTab);
|
|
39249
|
+
} catch {}
|
|
39250
|
+
}, [settingsTab]);
|
|
39251
|
+
const changeSettingsTab = (next) => {
|
|
39252
|
+
setSettingsTabState(next);
|
|
39253
|
+
onSettingsTab?.(next);
|
|
39254
|
+
};
|
|
39255
|
+
const save = async () => {
|
|
39256
|
+
if (configDraft === null) return;
|
|
39257
|
+
setBusy(true);
|
|
39258
|
+
setError("");
|
|
39259
|
+
setNotice("");
|
|
39260
|
+
try {
|
|
39261
|
+
const result = await api.patchConfig({
|
|
39262
|
+
outlinePath: configDraft.outlinePath,
|
|
39263
|
+
outputDir: configDraft.outputDir,
|
|
39264
|
+
provider: configDraft.provider,
|
|
39265
|
+
model: configDraft.model,
|
|
39266
|
+
reasoningEffort: configDraft.reasoningEffort ?? "off",
|
|
39267
|
+
chapterChars: configDraft.chapterChars,
|
|
39268
|
+
maxTokens: configDraft.maxTokens,
|
|
39269
|
+
reviewPassScore: configDraft.reviewPassScore,
|
|
39270
|
+
autoReview: configDraft.autoReview,
|
|
39271
|
+
autoAuthorReview: configDraft.autoAuthorReview,
|
|
39272
|
+
autoReviewAfterRevise: configDraft.autoReviewAfterRevise,
|
|
39273
|
+
imageApiKey: configDraft.imageApiKey,
|
|
39274
|
+
imageApiModel: configDraft.imageApiModel,
|
|
39275
|
+
imageApiEnabled: configDraft.imageApiEnabled ?? false,
|
|
39276
|
+
themeBackground: configDraft.themeBackground ?? "",
|
|
39277
|
+
themeBackgroundBlur: configDraft.themeBackgroundBlur ?? 0,
|
|
39278
|
+
themeOpacity: configDraft.themeOpacity ?? 100,
|
|
39279
|
+
imageModels: configDraft.imageModels ?? [],
|
|
39280
|
+
savedModels: configDraft.savedModels ?? []
|
|
39281
|
+
});
|
|
39282
|
+
setConfig(result.config);
|
|
39283
|
+
setConfigDraft(result.config);
|
|
39284
|
+
setNotice(tt("settings.saved"));
|
|
39285
|
+
} catch (err) {
|
|
39286
|
+
setError(err.message);
|
|
39287
|
+
} finally {
|
|
39288
|
+
setBusy(false);
|
|
39289
|
+
}
|
|
39290
|
+
};
|
|
39291
|
+
const patchImageModel = (id, patch) => {
|
|
39292
|
+
setConfigDraft((prev) => prev === null ? prev : {
|
|
39293
|
+
...prev,
|
|
39294
|
+
imageModels: (prev.imageModels ?? []).map((m) => m.id === id ? {
|
|
39295
|
+
...m,
|
|
39296
|
+
...patch
|
|
39297
|
+
} : m)
|
|
39298
|
+
});
|
|
39299
|
+
};
|
|
39300
|
+
const addImageModel = () => {
|
|
39301
|
+
setConfigDraft((prev) => prev === null ? prev : {
|
|
39302
|
+
...prev,
|
|
39303
|
+
imageModels: [...prev.imageModels ?? [], {
|
|
39304
|
+
id: "img-" + Date.now().toString(36),
|
|
39305
|
+
name: "",
|
|
39306
|
+
baseURL: "",
|
|
39307
|
+
apiKey: "",
|
|
39308
|
+
model: "",
|
|
39309
|
+
enabled: (prev.imageModels ?? []).length === 0
|
|
39310
|
+
}]
|
|
39311
|
+
});
|
|
39312
|
+
};
|
|
39313
|
+
const removeImageModel = (id) => {
|
|
39314
|
+
setConfigDraft((prev) => prev === null ? prev : {
|
|
39315
|
+
...prev,
|
|
39316
|
+
imageModels: (prev.imageModels ?? []).filter((m) => m.id !== id)
|
|
39317
|
+
});
|
|
39318
|
+
};
|
|
39319
|
+
const enableImageModel = (id) => {
|
|
39320
|
+
setConfigDraft((prev) => prev === null ? prev : {
|
|
39321
|
+
...prev,
|
|
39322
|
+
imageModels: (prev.imageModels ?? []).map((m) => ({
|
|
39323
|
+
...m,
|
|
39324
|
+
enabled: m.id === id
|
|
39325
|
+
}))
|
|
39326
|
+
});
|
|
39327
|
+
};
|
|
39328
|
+
const testImageModel = async (m) => {
|
|
39329
|
+
if (m.baseURL.trim() === "" || m.apiKey.trim() === "") {
|
|
39330
|
+
setImageTestState((prev) => ({
|
|
39331
|
+
...prev,
|
|
39332
|
+
[m.id]: {
|
|
39333
|
+
testing: false,
|
|
39334
|
+
ok: false,
|
|
39335
|
+
message: "请先填写接口地址和 API Key"
|
|
39336
|
+
}
|
|
39337
|
+
}));
|
|
39338
|
+
return;
|
|
39339
|
+
}
|
|
39340
|
+
setImageTestState((prev) => ({
|
|
39341
|
+
...prev,
|
|
39342
|
+
[m.id]: { testing: true }
|
|
39343
|
+
}));
|
|
39344
|
+
try {
|
|
39345
|
+
const r = await api.imageTest({
|
|
39346
|
+
baseURL: m.baseURL,
|
|
39347
|
+
apiKey: m.apiKey,
|
|
39348
|
+
model: m.model
|
|
39349
|
+
});
|
|
39350
|
+
setImageTestState((prev) => ({
|
|
39351
|
+
...prev,
|
|
39352
|
+
[m.id]: {
|
|
39353
|
+
testing: false,
|
|
39354
|
+
ok: r.ok,
|
|
39355
|
+
ms: r.ms,
|
|
39356
|
+
message: r.message
|
|
39357
|
+
}
|
|
39358
|
+
}));
|
|
39359
|
+
} catch (err) {
|
|
39360
|
+
setImageTestState((prev) => ({
|
|
39361
|
+
...prev,
|
|
39362
|
+
[m.id]: {
|
|
39363
|
+
testing: false,
|
|
39364
|
+
ok: false,
|
|
39365
|
+
message: err.message
|
|
39366
|
+
}
|
|
39367
|
+
}));
|
|
39368
|
+
}
|
|
39369
|
+
};
|
|
39370
|
+
const changeTheme = (theme, mode, density) => {
|
|
39371
|
+
setPanelTheme(theme);
|
|
39372
|
+
setThemeMode(mode);
|
|
39373
|
+
setThemeDensity(density);
|
|
39374
|
+
try {
|
|
39375
|
+
window.localStorage.setItem("dsh-novel-forge.theme", theme);
|
|
39376
|
+
window.localStorage.setItem("dsh-novel-forge.theme.mode", mode);
|
|
39377
|
+
window.localStorage.setItem("dsh-novel-forge.theme.density", density);
|
|
39378
|
+
} catch {}
|
|
39379
|
+
onTheme?.(theme, mode, density);
|
|
39380
|
+
};
|
|
39381
|
+
const changeEditorFont = (n) => {
|
|
39382
|
+
const v = Math.min(24, Math.max(12, n));
|
|
39383
|
+
setEditorFontSize(v);
|
|
39384
|
+
try {
|
|
39385
|
+
window.localStorage.setItem("dsh-novel-forge.editor.fontSize", String(v));
|
|
39386
|
+
} catch {}
|
|
39387
|
+
onEditorFontSize?.(v);
|
|
39388
|
+
};
|
|
39389
|
+
const bgFileRef = (0, react.useRef)(null);
|
|
39390
|
+
const applyBackground = (bg) => {
|
|
39391
|
+
setConfigDraft((prev) => prev === null ? prev : {
|
|
39392
|
+
...prev,
|
|
39393
|
+
themeBackground: bg ?? ""
|
|
39394
|
+
});
|
|
39395
|
+
onBackground?.(bg ?? void 0, configDraft?.themeBackgroundBlur ?? 0);
|
|
39396
|
+
};
|
|
39397
|
+
const applyBlur = (blur) => {
|
|
39398
|
+
setConfigDraft((prev) => prev === null ? prev : {
|
|
39399
|
+
...prev,
|
|
39400
|
+
themeBackgroundBlur: blur
|
|
39401
|
+
});
|
|
39402
|
+
onBackground?.(configDraft?.themeBackground ?? void 0, blur);
|
|
39403
|
+
};
|
|
39404
|
+
const applyOpacity = (n) => {
|
|
39405
|
+
setConfigDraft((prev) => prev === null ? prev : {
|
|
39406
|
+
...prev,
|
|
39407
|
+
themeOpacity: n
|
|
39408
|
+
});
|
|
39409
|
+
onOpacity?.(n);
|
|
39410
|
+
};
|
|
39411
|
+
const onBgFile = async (file) => {
|
|
39412
|
+
if (file === void 0) return;
|
|
39413
|
+
const dataUrl = await new Promise((resolve, reject) => {
|
|
39414
|
+
const fr = new FileReader();
|
|
39415
|
+
fr.onload = () => resolve(fr.result);
|
|
39416
|
+
fr.onerror = () => reject(fr.error ?? /* @__PURE__ */ new Error("读取失败"));
|
|
39417
|
+
fr.readAsDataURL(file);
|
|
39418
|
+
});
|
|
39419
|
+
try {
|
|
39420
|
+
const res = await api.themeBackgroundUpload(dataUrl);
|
|
39421
|
+
applyBackground(res.url);
|
|
39422
|
+
} catch (err) {
|
|
39423
|
+
setError(err.message);
|
|
39424
|
+
}
|
|
39425
|
+
};
|
|
39426
|
+
const resetTheme = () => {
|
|
39427
|
+
try {
|
|
39428
|
+
window.localStorage.removeItem("dsh-novel-forge.theme");
|
|
39429
|
+
window.localStorage.removeItem("dsh-novel-forge.theme.mode");
|
|
39430
|
+
window.localStorage.removeItem("dsh-novel-forge.theme.density");
|
|
39431
|
+
} catch {}
|
|
39432
|
+
changeTheme("liquid", "system", "comfort");
|
|
39433
|
+
};
|
|
39434
|
+
if (configDraft === null) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39435
|
+
className: panel_module_css_default.authorPageBody,
|
|
39436
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
39437
|
+
className: panel_module_css_default.meta,
|
|
39438
|
+
children: "正在加载设置…"
|
|
39439
|
+
}), error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
39440
|
+
className: panel_module_css_default.noticeError,
|
|
39441
|
+
children: error
|
|
39442
|
+
})]
|
|
39443
|
+
});
|
|
39444
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39445
|
+
className: panel_module_css_default.authorPageBody,
|
|
39446
|
+
"data-nf-theme": panelTheme,
|
|
39447
|
+
"data-nf-mode": themeMode === "system" ? void 0 : themeMode,
|
|
39448
|
+
"data-nf-density": themeDensity,
|
|
39449
|
+
children: [
|
|
39450
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39451
|
+
className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
|
|
39452
|
+
style: { gap: "var(--nf-space-6)" },
|
|
39453
|
+
children: [
|
|
39454
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
39455
|
+
className: panel_module_css_default.panelTitle,
|
|
39456
|
+
style: { margin: 0 },
|
|
39457
|
+
children: "⚙️ 设置"
|
|
39458
|
+
}),
|
|
39459
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
39460
|
+
className: panel_module_css_default.meta,
|
|
39461
|
+
children: [
|
|
39462
|
+
"当前模型:",
|
|
39463
|
+
config?.provider,
|
|
39464
|
+
" / ",
|
|
39465
|
+
config?.model
|
|
39466
|
+
]
|
|
39467
|
+
}),
|
|
39468
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
39469
|
+
className: panel_module_css_default.meta,
|
|
39470
|
+
children: ["输出目录:", config?.outputDir]
|
|
39471
|
+
})
|
|
39472
|
+
]
|
|
39473
|
+
}),
|
|
39474
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
39475
|
+
className: panel_module_css_default.row,
|
|
39476
|
+
style: {
|
|
39477
|
+
gap: "var(--nf-space-8)",
|
|
39478
|
+
flexWrap: "wrap"
|
|
39479
|
+
},
|
|
39480
|
+
children: SETTINGS_SECTIONS$1.map((s) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
39481
|
+
type: "button",
|
|
39482
|
+
className: panel_module_css_default.button + (settingsTab === s.id ? " " + panel_module_css_default.buttonPrimary : ""),
|
|
39483
|
+
style: {
|
|
39484
|
+
flex: 1,
|
|
39485
|
+
minWidth: 104,
|
|
39486
|
+
justifyContent: "center"
|
|
39487
|
+
},
|
|
39488
|
+
onClick: () => changeSettingsTab(s.id),
|
|
39489
|
+
children: [
|
|
39490
|
+
s.icon,
|
|
39491
|
+
" ",
|
|
39492
|
+
s.label
|
|
39493
|
+
]
|
|
39494
|
+
}, s.id))
|
|
39495
|
+
}),
|
|
39496
|
+
error !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
39497
|
+
className: panel_module_css_default.noticeError,
|
|
39498
|
+
children: error
|
|
39499
|
+
}),
|
|
39500
|
+
notice !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
39501
|
+
className: panel_module_css_default.meta,
|
|
39502
|
+
children: notice
|
|
39503
|
+
}),
|
|
39504
|
+
settingsTab === "model" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39505
|
+
className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
|
|
39506
|
+
style: { gap: "var(--nf-space-24)" },
|
|
39507
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
39508
|
+
className: panel_module_css_default.cardTitle,
|
|
39509
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Brain, {
|
|
39510
|
+
size: 18,
|
|
39511
|
+
style: { verticalAlign: -3 }
|
|
39512
|
+
}), " 模型与推理"]
|
|
39513
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelManager, {
|
|
39514
|
+
api,
|
|
39515
|
+
provider: configDraft.provider,
|
|
39516
|
+
model: configDraft.model,
|
|
39517
|
+
savedModels: configDraft.savedModels ?? [],
|
|
39518
|
+
onProvider: (v) => setConfigDraft({
|
|
39519
|
+
...configDraft,
|
|
39520
|
+
provider: v
|
|
39521
|
+
}),
|
|
39522
|
+
onModel: (v) => setConfigDraft({
|
|
39523
|
+
...configDraft,
|
|
39524
|
+
model: v
|
|
39525
|
+
}),
|
|
39526
|
+
onSavedModels: (models) => setConfigDraft({
|
|
39527
|
+
...configDraft,
|
|
39528
|
+
savedModels: models
|
|
39529
|
+
})
|
|
39530
|
+
})]
|
|
39531
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReasoningSection, {
|
|
39532
|
+
reasoningEffort: configDraft.reasoningEffort ?? "off",
|
|
39533
|
+
analysisReasoning: configDraft.analysisReasoning ?? "low",
|
|
39534
|
+
onChange: (patch) => setConfigDraft({
|
|
39535
|
+
...configDraft,
|
|
39536
|
+
...patch
|
|
39537
|
+
})
|
|
39538
|
+
})] }),
|
|
39539
|
+
settingsTab === "writing" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39540
|
+
className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
|
|
39541
|
+
style: { gap: "var(--nf-space-24)" },
|
|
39542
|
+
children: [
|
|
39543
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
39544
|
+
className: panel_module_css_default.cardTitle,
|
|
39545
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.PenLine, {
|
|
39546
|
+
size: 18,
|
|
39547
|
+
style: { verticalAlign: -3 }
|
|
39548
|
+
}), " 写作与审稿"]
|
|
39549
|
+
}),
|
|
39550
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39551
|
+
className: panel_module_css_default.field,
|
|
39552
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39553
|
+
className: panel_module_css_default.fieldLabel,
|
|
39554
|
+
children: tt("settings.chapterChars")
|
|
39555
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
39556
|
+
className: panel_module_css_default.input,
|
|
39557
|
+
type: "number",
|
|
39558
|
+
min: 1e3,
|
|
39559
|
+
max: 2e4,
|
|
39560
|
+
value: configDraft.chapterChars,
|
|
39561
|
+
onChange: (e) => setConfigDraft({
|
|
39562
|
+
...configDraft,
|
|
39563
|
+
chapterChars: Number(e.target.value)
|
|
39564
|
+
})
|
|
39565
|
+
})]
|
|
39566
|
+
}),
|
|
39567
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39568
|
+
className: panel_module_css_default.field,
|
|
39569
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39570
|
+
className: panel_module_css_default.fieldLabel,
|
|
39571
|
+
children: tt("settings.maxTokens")
|
|
39572
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
39573
|
+
className: panel_module_css_default.input,
|
|
39574
|
+
type: "number",
|
|
39575
|
+
min: 2e3,
|
|
39576
|
+
max: 64e3,
|
|
39577
|
+
value: configDraft.maxTokens,
|
|
39578
|
+
onChange: (e) => setConfigDraft({
|
|
39579
|
+
...configDraft,
|
|
39580
|
+
maxTokens: Number(e.target.value)
|
|
39581
|
+
})
|
|
39582
|
+
})]
|
|
39583
|
+
}),
|
|
39584
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39585
|
+
className: panel_module_css_default.field,
|
|
39586
|
+
children: [
|
|
39587
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39588
|
+
className: panel_module_css_default.fieldLabel,
|
|
39589
|
+
children: tt("settings.reviewPassScore")
|
|
39590
|
+
}),
|
|
39591
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
39592
|
+
className: panel_module_css_default.input,
|
|
39593
|
+
type: "number",
|
|
39594
|
+
min: 0,
|
|
39595
|
+
max: 100,
|
|
39596
|
+
value: configDraft.reviewPassScore,
|
|
39597
|
+
onChange: (e) => setConfigDraft({
|
|
39598
|
+
...configDraft,
|
|
39599
|
+
reviewPassScore: Number(e.target.value)
|
|
39600
|
+
})
|
|
39601
|
+
}),
|
|
39602
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
39603
|
+
className: panel_module_css_default.meta,
|
|
39604
|
+
children: "通过判定:综合评分 ≥ 此分数(默认 70),或无 high 级问题且评分 ≥ 60;建议设 60-80。"
|
|
39605
|
+
})
|
|
39606
|
+
]
|
|
39607
|
+
}),
|
|
39608
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39609
|
+
className: panel_module_css_default.field,
|
|
39610
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39611
|
+
className: panel_module_css_default.fieldLabel,
|
|
39612
|
+
children: tt("settings.autoReview")
|
|
39613
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
39614
|
+
className: panel_module_css_default.input,
|
|
39615
|
+
value: configDraft.autoReview ? "1" : "0",
|
|
39616
|
+
onChange: (e) => setConfigDraft({
|
|
39617
|
+
...configDraft,
|
|
39618
|
+
autoReview: e.target.value === "1"
|
|
39619
|
+
}),
|
|
39620
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
39621
|
+
value: "1",
|
|
39622
|
+
children: "✓ 是"
|
|
39623
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
39624
|
+
value: "0",
|
|
39625
|
+
children: "✗ 否"
|
|
39626
|
+
})]
|
|
39627
|
+
})]
|
|
39628
|
+
}),
|
|
39629
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39630
|
+
className: panel_module_css_default.field,
|
|
39631
|
+
children: [
|
|
39632
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39633
|
+
className: panel_module_css_default.fieldLabel,
|
|
39634
|
+
children: tt("settings.autoAuthorReview")
|
|
39635
|
+
}),
|
|
39636
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
39637
|
+
className: panel_module_css_default.input,
|
|
39638
|
+
value: configDraft.autoAuthorReview ? "1" : "0",
|
|
39639
|
+
onChange: (e) => setConfigDraft({
|
|
39640
|
+
...configDraft,
|
|
39641
|
+
autoAuthorReview: e.target.value === "1"
|
|
39642
|
+
}),
|
|
39643
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
39644
|
+
value: "1",
|
|
39645
|
+
children: "✓ 是"
|
|
39646
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
39647
|
+
value: "0",
|
|
39648
|
+
children: "✗ 否"
|
|
39649
|
+
})]
|
|
39650
|
+
}),
|
|
39651
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
39652
|
+
className: panel_module_css_default.meta,
|
|
39653
|
+
children: tt("settings.autoAuthorReviewHint")
|
|
39654
|
+
})
|
|
39655
|
+
]
|
|
39656
|
+
}),
|
|
39657
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39658
|
+
className: panel_module_css_default.field,
|
|
39659
|
+
children: [
|
|
39660
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39661
|
+
className: panel_module_css_default.fieldLabel,
|
|
39662
|
+
children: tt("settings.autoReviewAfterRevise")
|
|
39663
|
+
}),
|
|
39664
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
39665
|
+
className: panel_module_css_default.input,
|
|
39666
|
+
value: configDraft.autoReviewAfterRevise ? "1" : "0",
|
|
39667
|
+
onChange: (e) => setConfigDraft({
|
|
39668
|
+
...configDraft,
|
|
39669
|
+
autoReviewAfterRevise: e.target.value === "1"
|
|
39670
|
+
}),
|
|
39671
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
39672
|
+
value: "1",
|
|
39673
|
+
children: "✓ 是"
|
|
39674
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
39675
|
+
value: "0",
|
|
39676
|
+
children: "✗ 否"
|
|
39677
|
+
})]
|
|
39678
|
+
}),
|
|
39679
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
39680
|
+
className: panel_module_css_default.meta,
|
|
39681
|
+
children: tt("settings.autoReviewAfterReviseHint")
|
|
39682
|
+
})
|
|
39683
|
+
]
|
|
39684
|
+
}),
|
|
39685
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39686
|
+
className: panel_module_css_default.field,
|
|
39687
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39688
|
+
className: panel_module_css_default.fieldLabel,
|
|
39689
|
+
children: "编辑器字号(正文编辑 / 工作区)"
|
|
39690
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
39691
|
+
className: panel_module_css_default.input,
|
|
39692
|
+
value: editorFontSize,
|
|
39693
|
+
onChange: (e) => changeEditorFont(Number(e.target.value)),
|
|
39694
|
+
children: [
|
|
39695
|
+
12,
|
|
39696
|
+
13,
|
|
39697
|
+
14,
|
|
39698
|
+
15,
|
|
39699
|
+
16,
|
|
39700
|
+
18,
|
|
39701
|
+
20,
|
|
39702
|
+
22,
|
|
39703
|
+
24
|
|
39704
|
+
].map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
|
|
39705
|
+
value: v,
|
|
39706
|
+
children: [v, "px"]
|
|
39707
|
+
}, v))
|
|
39708
|
+
})]
|
|
39709
|
+
})
|
|
39710
|
+
]
|
|
39711
|
+
}),
|
|
39712
|
+
settingsTab === "image" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39713
|
+
className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
|
|
39714
|
+
style: { gap: "var(--nf-space-24)" },
|
|
39715
|
+
children: [
|
|
39716
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39717
|
+
className: panel_module_css_default.row,
|
|
39718
|
+
style: {
|
|
39719
|
+
justifyContent: "space-between",
|
|
39720
|
+
flexWrap: "wrap",
|
|
39721
|
+
alignItems: "center"
|
|
39722
|
+
},
|
|
39723
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
39724
|
+
className: panel_module_css_default.cardTitle,
|
|
39725
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Palette, {
|
|
39726
|
+
size: 18,
|
|
39727
|
+
style: { verticalAlign: -3 }
|
|
39728
|
+
}), " 生图模型"]
|
|
39729
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
39730
|
+
className: panel_module_css_default.row,
|
|
39731
|
+
style: {
|
|
39732
|
+
gap: "var(--nf-space-8)",
|
|
39733
|
+
alignItems: "center"
|
|
39734
|
+
},
|
|
39735
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
39736
|
+
className: panel_module_css_default.meta,
|
|
39737
|
+
children: "启用生图功能"
|
|
39738
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
39739
|
+
type: "button",
|
|
39740
|
+
role: "switch",
|
|
39741
|
+
"aria-checked": configDraft.imageApiEnabled === true,
|
|
39742
|
+
className: `${panel_module_css_default.switch} ${configDraft.imageApiEnabled === true ? panel_module_css_default.switchOn : ""}`,
|
|
39743
|
+
onClick: () => {
|
|
39744
|
+
setConfigDraft((prev) => prev === null ? prev : {
|
|
39745
|
+
...prev,
|
|
39746
|
+
imageApiEnabled: prev.imageApiEnabled !== true
|
|
39747
|
+
});
|
|
39748
|
+
},
|
|
39749
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: panel_module_css_default.switchKnob })
|
|
39750
|
+
})]
|
|
39751
|
+
})]
|
|
39752
|
+
}),
|
|
39753
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
39754
|
+
className: panel_module_css_default.meta,
|
|
39755
|
+
children: "支持多套 OpenAI 兼容生图接口(豆包 / 即梦 / 其他平台);启用一条作为生成模型。"
|
|
39756
|
+
}),
|
|
39757
|
+
(configDraft.imageModels ?? []).map((m) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39758
|
+
style: {
|
|
39759
|
+
border: m.enabled ? "1px solid var(--nf-accent)" : "1px solid var(--nf-border)",
|
|
39760
|
+
borderRadius: "var(--nf-radius-12)",
|
|
39761
|
+
padding: "var(--nf-space-14)",
|
|
39762
|
+
display: "flex",
|
|
39763
|
+
flexDirection: "column",
|
|
39764
|
+
gap: "var(--nf-space-12)",
|
|
39765
|
+
background: m.enabled ? "var(--nf-accent-soft)" : "transparent"
|
|
39766
|
+
},
|
|
39767
|
+
children: [
|
|
39768
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39769
|
+
className: panel_module_css_default.row,
|
|
39770
|
+
style: {
|
|
39771
|
+
alignItems: "flex-end",
|
|
39772
|
+
flexWrap: "wrap"
|
|
39773
|
+
},
|
|
39774
|
+
children: [
|
|
39775
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39776
|
+
className: panel_module_css_default.field,
|
|
39777
|
+
style: {
|
|
39778
|
+
flex: 1,
|
|
39779
|
+
minWidth: 160
|
|
39780
|
+
},
|
|
39781
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39782
|
+
className: panel_module_css_default.fieldLabel,
|
|
39783
|
+
children: "名称"
|
|
39784
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
39785
|
+
className: panel_module_css_default.input,
|
|
39786
|
+
value: m.name,
|
|
39787
|
+
onChange: (e) => patchImageModel(m.id, { name: e.target.value })
|
|
39788
|
+
})]
|
|
39789
|
+
}),
|
|
39790
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39791
|
+
className: panel_module_css_default.field,
|
|
39792
|
+
style: {
|
|
39793
|
+
flex: 1,
|
|
39794
|
+
minWidth: 150
|
|
39795
|
+
},
|
|
39796
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39797
|
+
className: panel_module_css_default.fieldLabel,
|
|
39798
|
+
children: "模型 id"
|
|
39799
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
39800
|
+
className: panel_module_css_default.input,
|
|
39801
|
+
value: m.model,
|
|
39802
|
+
onChange: (e) => patchImageModel(m.id, { model: e.target.value })
|
|
39803
|
+
})]
|
|
39804
|
+
}),
|
|
39805
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39806
|
+
className: panel_module_css_default.field,
|
|
39807
|
+
style: {
|
|
39808
|
+
flex: 1,
|
|
39809
|
+
minWidth: 200
|
|
39810
|
+
},
|
|
39811
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39812
|
+
className: panel_module_css_default.fieldLabel,
|
|
39813
|
+
children: "接口地址"
|
|
39814
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
39815
|
+
className: panel_module_css_default.input,
|
|
39816
|
+
value: m.baseURL,
|
|
39817
|
+
onChange: (e) => patchImageModel(m.id, { baseURL: e.target.value })
|
|
39818
|
+
})]
|
|
39819
|
+
})
|
|
39820
|
+
]
|
|
39821
|
+
}),
|
|
39822
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39823
|
+
className: panel_module_css_default.field,
|
|
39824
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39825
|
+
className: panel_module_css_default.fieldLabel,
|
|
39826
|
+
children: "API Key"
|
|
39827
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
39828
|
+
className: panel_module_css_default.input,
|
|
39829
|
+
type: "password",
|
|
39830
|
+
value: m.apiKey,
|
|
39831
|
+
onChange: (e) => patchImageModel(m.id, { apiKey: e.target.value })
|
|
39832
|
+
})]
|
|
39833
|
+
}),
|
|
39834
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39835
|
+
className: panel_module_css_default.row,
|
|
39836
|
+
style: {
|
|
39837
|
+
gap: "var(--nf-space-8)",
|
|
39838
|
+
flexWrap: "wrap",
|
|
39839
|
+
alignItems: "center"
|
|
39840
|
+
},
|
|
39841
|
+
children: [
|
|
39842
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
39843
|
+
type: "button",
|
|
39844
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall + (m.enabled ? " " + panel_module_css_default.buttonPrimary : ""),
|
|
39845
|
+
onClick: () => enableImageModel(m.id),
|
|
39846
|
+
children: m.enabled ? "✓ 已启用" : "设为启用"
|
|
39847
|
+
}),
|
|
39848
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
39849
|
+
type: "button",
|
|
39850
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
39851
|
+
disabled: imageTestState[m.id]?.testing === true,
|
|
39852
|
+
onClick: () => {
|
|
39853
|
+
testImageModel(m);
|
|
39854
|
+
},
|
|
39855
|
+
children: [
|
|
39856
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.PlugZap, {
|
|
39857
|
+
size: 13,
|
|
39858
|
+
style: { verticalAlign: -2 }
|
|
39859
|
+
}),
|
|
39860
|
+
" ",
|
|
39861
|
+
imageTestState[m.id]?.testing === true ? "测试中…" : "测试"
|
|
39862
|
+
]
|
|
39863
|
+
}),
|
|
39864
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
39865
|
+
type: "button",
|
|
39866
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
39867
|
+
onClick: () => removeImageModel(m.id),
|
|
39868
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Trash2, {
|
|
39869
|
+
size: 13,
|
|
39870
|
+
style: { verticalAlign: -2 }
|
|
39871
|
+
}), " 删除"]
|
|
39872
|
+
})
|
|
39873
|
+
]
|
|
39874
|
+
})
|
|
39875
|
+
]
|
|
39876
|
+
}, m.id)),
|
|
39877
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
39878
|
+
className: panel_module_css_default.row,
|
|
39879
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
39880
|
+
type: "button",
|
|
39881
|
+
className: panel_module_css_default.button,
|
|
39882
|
+
onClick: addImageModel,
|
|
39883
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Plus, {
|
|
39884
|
+
size: 13,
|
|
39885
|
+
style: { verticalAlign: -2 }
|
|
39886
|
+
}), " 添加生图模型"]
|
|
39887
|
+
})
|
|
39888
|
+
})
|
|
39889
|
+
]
|
|
39890
|
+
}),
|
|
39891
|
+
settingsTab === "files" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39892
|
+
className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
|
|
39893
|
+
style: { gap: "var(--nf-space-24)" },
|
|
39894
|
+
children: [
|
|
39895
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
39896
|
+
className: panel_module_css_default.cardTitle,
|
|
39897
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Folder, {
|
|
39898
|
+
size: 18,
|
|
39899
|
+
style: { verticalAlign: -3 }
|
|
39900
|
+
}), " 路径与文件"]
|
|
39901
|
+
}),
|
|
39902
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39903
|
+
className: panel_module_css_default.field,
|
|
39904
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39905
|
+
className: panel_module_css_default.fieldLabel,
|
|
39906
|
+
children: tt("settings.outlinePath")
|
|
39907
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
39908
|
+
className: panel_module_css_default.input,
|
|
39909
|
+
value: configDraft.outlinePath,
|
|
39910
|
+
onChange: (e) => setConfigDraft({
|
|
39911
|
+
...configDraft,
|
|
39912
|
+
outlinePath: e.target.value
|
|
39913
|
+
})
|
|
39914
|
+
})]
|
|
39915
|
+
}),
|
|
39916
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39917
|
+
className: panel_module_css_default.field,
|
|
39918
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39919
|
+
className: panel_module_css_default.fieldLabel,
|
|
39920
|
+
children: tt("settings.outputDir")
|
|
39921
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
39922
|
+
className: panel_module_css_default.input,
|
|
39923
|
+
value: configDraft.outputDir,
|
|
39924
|
+
onChange: (e) => setConfigDraft({
|
|
39925
|
+
...configDraft,
|
|
39926
|
+
outputDir: e.target.value
|
|
39927
|
+
})
|
|
39928
|
+
})]
|
|
39929
|
+
}),
|
|
39930
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
39931
|
+
className: panel_module_css_default.row,
|
|
39932
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
39933
|
+
type: "button",
|
|
39934
|
+
className: panel_module_css_default.button,
|
|
39935
|
+
onClick: () => {
|
|
39936
|
+
api.openFolder();
|
|
39937
|
+
},
|
|
39938
|
+
children: tt("settings.openFolder")
|
|
39939
|
+
})
|
|
39940
|
+
})
|
|
39941
|
+
]
|
|
39942
|
+
}),
|
|
39943
|
+
settingsTab === "appearance" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39944
|
+
className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
|
|
39945
|
+
children: [
|
|
39946
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
39947
|
+
className: panel_module_css_default.cardTitle,
|
|
39948
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Sparkles, {
|
|
39949
|
+
size: 18,
|
|
39950
|
+
style: { verticalAlign: -3 }
|
|
39951
|
+
}), " 外观与主题"]
|
|
39952
|
+
}),
|
|
39953
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39954
|
+
className: panel_module_css_default.field,
|
|
39955
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39956
|
+
className: panel_module_css_default.fieldLabel,
|
|
39957
|
+
children: "显示模式"
|
|
39958
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
39959
|
+
className: panel_module_css_default.input,
|
|
39960
|
+
value: themeMode,
|
|
39961
|
+
onChange: (e) => changeTheme(panelTheme, e.target.value, themeDensity),
|
|
39962
|
+
children: [
|
|
39963
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
39964
|
+
value: "system",
|
|
39965
|
+
children: "跟随系统"
|
|
39966
|
+
}),
|
|
39967
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
39968
|
+
value: "light",
|
|
39969
|
+
children: "浅色"
|
|
39970
|
+
}),
|
|
39971
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
39972
|
+
value: "dark",
|
|
39973
|
+
children: "深色"
|
|
39974
|
+
})
|
|
39975
|
+
]
|
|
39976
|
+
})]
|
|
39977
|
+
}),
|
|
39978
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
39979
|
+
className: panel_module_css_default.field,
|
|
39980
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
39981
|
+
className: panel_module_css_default.fieldLabel,
|
|
39982
|
+
children: "主题风格"
|
|
39983
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
39984
|
+
className: panel_module_css_default.input,
|
|
39985
|
+
value: panelTheme,
|
|
39986
|
+
onChange: (e) => changeTheme(e.target.value, themeMode, themeDensity),
|
|
39987
|
+
children: [
|
|
39988
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
39989
|
+
value: "liquid",
|
|
39990
|
+
children: "液态玻璃 · 清新绿(默认)"
|
|
39991
|
+
}),
|
|
39992
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
39993
|
+
value: "neumorph",
|
|
39994
|
+
children: "新拟物 · 柔和浅色"
|
|
39995
|
+
}),
|
|
39996
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
39997
|
+
value: "macos",
|
|
39998
|
+
children: "macOS · 玻璃(蓝,随外观浅/深)"
|
|
39999
|
+
}),
|
|
40000
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
40001
|
+
value: "clay",
|
|
40002
|
+
children: "粘土拟态 · 柔和黏土"
|
|
40003
|
+
})
|
|
40004
|
+
]
|
|
40005
|
+
})]
|
|
40006
|
+
}),
|
|
40007
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40008
|
+
className: panel_module_css_default.field,
|
|
40009
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
40010
|
+
className: panel_module_css_default.fieldLabel,
|
|
40011
|
+
children: "界面密度"
|
|
40012
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
40013
|
+
className: panel_module_css_default.input,
|
|
40014
|
+
value: themeDensity,
|
|
40015
|
+
onChange: (e) => changeTheme(panelTheme, themeMode, e.target.value),
|
|
40016
|
+
children: [
|
|
40017
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
40018
|
+
value: "comfort",
|
|
40019
|
+
children: "舒适(默认)"
|
|
40020
|
+
}),
|
|
40021
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
40022
|
+
value: "compact",
|
|
40023
|
+
children: "紧凑"
|
|
40024
|
+
}),
|
|
40025
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
40026
|
+
value: "spacious",
|
|
40027
|
+
children: "宽松"
|
|
40028
|
+
})
|
|
40029
|
+
]
|
|
40030
|
+
})]
|
|
40031
|
+
}),
|
|
40032
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40033
|
+
className: panel_module_css_default.field,
|
|
40034
|
+
children: [
|
|
40035
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
40036
|
+
className: panel_module_css_default.fieldLabel,
|
|
40037
|
+
children: "玻璃透明度(0-100)"
|
|
40038
|
+
}),
|
|
40039
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
40040
|
+
className: panel_module_css_default.input,
|
|
40041
|
+
type: "range",
|
|
40042
|
+
min: 0,
|
|
40043
|
+
max: 100,
|
|
40044
|
+
value: configDraft.themeOpacity ?? 100,
|
|
40045
|
+
onChange: (e) => applyOpacity(Number(e.target.value))
|
|
40046
|
+
}),
|
|
40047
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
40048
|
+
className: panel_module_css_default.meta,
|
|
40049
|
+
children: "100=当前主题原样;调低会让玻璃/卡片变透,新拟态、黏土等实色主题能透出背景图。"
|
|
40050
|
+
})
|
|
40051
|
+
]
|
|
40052
|
+
}),
|
|
40053
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
40054
|
+
className: panel_module_css_default.row,
|
|
40055
|
+
style: { justifyContent: "flex-end" },
|
|
40056
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
40057
|
+
type: "button",
|
|
40058
|
+
className: panel_module_css_default.button,
|
|
40059
|
+
onClick: resetTheme,
|
|
40060
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.RotateCcw, {
|
|
40061
|
+
size: 14,
|
|
40062
|
+
style: { verticalAlign: -2 }
|
|
40063
|
+
}), " 恢复默认主题"]
|
|
40064
|
+
})
|
|
40065
|
+
})
|
|
40066
|
+
]
|
|
40067
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40068
|
+
className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
|
|
40069
|
+
style: { gap: "var(--nf-space-12)" },
|
|
40070
|
+
children: [
|
|
40071
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
40072
|
+
className: panel_module_css_default.cardTitle,
|
|
40073
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Image, {
|
|
40074
|
+
size: 18,
|
|
40075
|
+
style: { verticalAlign: -3 }
|
|
40076
|
+
}), " 自定义背景"]
|
|
40077
|
+
}),
|
|
40078
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
40079
|
+
className: panel_module_css_default.meta,
|
|
40080
|
+
children: "填图片 URL 或上传图片作为小说工坊背景(首页 + 书内)。留空 = 使用主题默认背景。"
|
|
40081
|
+
}),
|
|
40082
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40083
|
+
className: panel_module_css_default.row,
|
|
40084
|
+
style: {
|
|
40085
|
+
gap: "var(--nf-space-8)",
|
|
40086
|
+
flexWrap: "wrap"
|
|
40087
|
+
},
|
|
40088
|
+
children: [
|
|
40089
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
40090
|
+
className: panel_module_css_default.input,
|
|
40091
|
+
style: {
|
|
40092
|
+
flex: 1,
|
|
40093
|
+
minWidth: 220
|
|
40094
|
+
},
|
|
40095
|
+
placeholder: "https://… 图片地址",
|
|
40096
|
+
value: (configDraft.themeBackground ?? "").startsWith("data:") ? "" : configDraft.themeBackground ?? "",
|
|
40097
|
+
onChange: (e) => applyBackground(e.target.value.trim() !== "" ? e.target.value.trim() : void 0)
|
|
40098
|
+
}),
|
|
40099
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
40100
|
+
type: "button",
|
|
40101
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
40102
|
+
onClick: () => bgFileRef.current?.click(),
|
|
40103
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Upload, {
|
|
40104
|
+
size: 13,
|
|
40105
|
+
style: { verticalAlign: -2 }
|
|
40106
|
+
}), " 上传图片"]
|
|
40107
|
+
}),
|
|
40108
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
40109
|
+
type: "button",
|
|
40110
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonSmall,
|
|
40111
|
+
onClick: () => applyBackground(void 0),
|
|
40112
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.X, {
|
|
40113
|
+
size: 13,
|
|
40114
|
+
style: { verticalAlign: -2 }
|
|
40115
|
+
}), " 清除"]
|
|
40116
|
+
})
|
|
40117
|
+
]
|
|
40118
|
+
}),
|
|
40119
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
40120
|
+
ref: bgFileRef,
|
|
40121
|
+
type: "file",
|
|
40122
|
+
accept: "image/*",
|
|
40123
|
+
style: { display: "none" },
|
|
40124
|
+
onChange: (e) => {
|
|
40125
|
+
onBgFile(e.target.files?.[0]);
|
|
40126
|
+
e.target.value = "";
|
|
40127
|
+
}
|
|
40128
|
+
}),
|
|
40129
|
+
(configDraft.themeBackground ?? "") !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40130
|
+
className: panel_module_css_default.adaptInputCard,
|
|
40131
|
+
style: { padding: 8 },
|
|
40132
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
40133
|
+
width: 180,
|
|
40134
|
+
height: 100,
|
|
40135
|
+
borderRadius: 10,
|
|
40136
|
+
backgroundImage: "url(" + configDraft.themeBackground + ")",
|
|
40137
|
+
backgroundSize: "cover",
|
|
40138
|
+
backgroundPosition: "center"
|
|
40139
|
+
} }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
40140
|
+
className: panel_module_css_default.meta,
|
|
40141
|
+
children: "已设置背景(预览)"
|
|
40142
|
+
})]
|
|
40143
|
+
}),
|
|
40144
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40145
|
+
className: panel_module_css_default.field,
|
|
40146
|
+
children: [
|
|
40147
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
40148
|
+
className: panel_module_css_default.fieldLabel,
|
|
40149
|
+
children: "遮罩 / 模糊强度(0-80)"
|
|
40150
|
+
}),
|
|
40151
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
40152
|
+
className: panel_module_css_default.input,
|
|
40153
|
+
type: "range",
|
|
40154
|
+
min: 0,
|
|
40155
|
+
max: 80,
|
|
40156
|
+
value: configDraft.themeBackgroundBlur ?? 0,
|
|
40157
|
+
onChange: (e) => applyBlur(Number(e.target.value))
|
|
40158
|
+
}),
|
|
40159
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
40160
|
+
className: panel_module_css_default.meta,
|
|
40161
|
+
children: "越大背景越暗,保证文字可读(图很花时调高)。"
|
|
40162
|
+
})
|
|
40163
|
+
]
|
|
40164
|
+
})
|
|
40165
|
+
]
|
|
40166
|
+
})] }),
|
|
40167
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
40168
|
+
className: panel_module_css_default.row,
|
|
40169
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
40170
|
+
type: "button",
|
|
40171
|
+
className: panel_module_css_default.button + " " + panel_module_css_default.buttonPrimary,
|
|
40172
|
+
disabled: busy,
|
|
40173
|
+
onClick: () => {
|
|
40174
|
+
save();
|
|
40175
|
+
},
|
|
40176
|
+
children: busy ? "保存中…" : tt("settings.save")
|
|
40177
|
+
})
|
|
40178
|
+
})
|
|
40179
|
+
]
|
|
40180
|
+
});
|
|
40181
|
+
}
|
|
40182
|
+
//#endregion
|
|
40183
|
+
//#region src/client/panel/AuthorHome.tsx
|
|
40184
|
+
/**
|
|
40185
|
+
* 作者级首页容器:书架页左侧导航 + 内容区。
|
|
40186
|
+
* 导航复用工作区 .panelNav 玻璃卡片样式(同款),导航项为作者级:书架/改编/资产库/全局资产库/AI 进度/设置。
|
|
40187
|
+
*/
|
|
40188
|
+
const PLUGIN_VERSION$1 = "1.9.0";
|
|
40189
|
+
const NAV_ITEMS = [
|
|
40190
|
+
{
|
|
40191
|
+
id: "shelf",
|
|
40192
|
+
label: "书架",
|
|
40193
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Library, { size: 18 }),
|
|
40194
|
+
hint: "我的书"
|
|
40195
|
+
},
|
|
40196
|
+
{
|
|
40197
|
+
id: "adapt",
|
|
40198
|
+
label: "改编模式",
|
|
40199
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Wand2, { size: 18 }),
|
|
40200
|
+
hint: "上传全文→可改范围"
|
|
40201
|
+
},
|
|
40202
|
+
{
|
|
40203
|
+
id: "assets",
|
|
40204
|
+
label: "作者资产库",
|
|
40205
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Boxes, { size: 18 }),
|
|
40206
|
+
hint: "跨书总数据"
|
|
40207
|
+
},
|
|
40208
|
+
{
|
|
40209
|
+
id: "library",
|
|
40210
|
+
label: "全局写作资产库",
|
|
40211
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Brush, { size: 18 }),
|
|
40212
|
+
hint: "内置题材/规则/模板"
|
|
40213
|
+
},
|
|
40214
|
+
{
|
|
40215
|
+
id: "progress",
|
|
40216
|
+
label: "AI 进度",
|
|
40217
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BarChart3, { size: 18 }),
|
|
40218
|
+
hint: "书架级聚合进度"
|
|
40219
|
+
}
|
|
40220
|
+
];
|
|
40221
|
+
function Placeholder({ title, hint }) {
|
|
40222
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40223
|
+
className: panel_module_css_default.authorPageBody,
|
|
40224
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40225
|
+
className: panel_module_css_default.card + " " + panel_module_css_default.settingsCard,
|
|
40226
|
+
style: { gap: "var(--nf-space-6)" },
|
|
40227
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
40228
|
+
className: panel_module_css_default.panelTitle,
|
|
40229
|
+
style: { margin: 0 },
|
|
40230
|
+
children: title
|
|
40231
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
40232
|
+
className: panel_module_css_default.meta,
|
|
40233
|
+
children: hint
|
|
40234
|
+
})]
|
|
40235
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40236
|
+
className: panel_module_css_default.shelfEmpty,
|
|
40237
|
+
style: { minHeight: 160 },
|
|
40238
|
+
children: [
|
|
40239
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
40240
|
+
className: panel_module_css_default.shelfEmptyIcon,
|
|
40241
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Info, { size: 30 })
|
|
40242
|
+
}),
|
|
40243
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
40244
|
+
className: panel_module_css_default.shelfEmptyTitle,
|
|
40245
|
+
children: "此入口为占位"
|
|
40246
|
+
}),
|
|
40247
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
40248
|
+
className: panel_module_css_default.meta,
|
|
40249
|
+
children: "后续版本实现。当前「全局写作资产库」可进入某本书「创作资产」页查看内置题材库/反AI规则库/风格模板;「设置」为独立设置页。"
|
|
40250
|
+
})
|
|
40251
|
+
]
|
|
40252
|
+
})]
|
|
40253
|
+
});
|
|
40254
|
+
}
|
|
40255
|
+
function AuthorHome({ api, shelf, onOpenBook, onReadBook, onAddBook, onImportBook, onOpenSettings, onTheme, onBackground, onOpacity, adaptEnabled, progress, busy, busyLabel, liveBar, onClearProgress }) {
|
|
40256
|
+
const [nav, setNav] = (0, react.useState)("shelf");
|
|
40257
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40258
|
+
className: panel_module_css_default.authorHome,
|
|
40259
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
|
|
40260
|
+
className: panel_module_css_default.panelNav,
|
|
40261
|
+
"aria-label": "作者级导航",
|
|
40262
|
+
children: [
|
|
40263
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40264
|
+
className: panel_module_css_default.navTitle,
|
|
40265
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
40266
|
+
className: panel_module_css_default.navTitleLogo,
|
|
40267
|
+
children: "书"
|
|
40268
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40269
|
+
style: { minWidth: 0 },
|
|
40270
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
40271
|
+
className: panel_module_css_default.navTitleName,
|
|
40272
|
+
children: "小说工坊"
|
|
40273
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
40274
|
+
className: panel_module_css_default.navTitleBook,
|
|
40275
|
+
children: "作者级 · 跨书"
|
|
40276
|
+
})]
|
|
40277
|
+
})]
|
|
40278
|
+
}),
|
|
40279
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40280
|
+
className: panel_module_css_default.navGroup,
|
|
40281
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
40282
|
+
className: panel_module_css_default.navGroupLabel,
|
|
40283
|
+
children: "作者"
|
|
40284
|
+
}), NAV_ITEMS.filter((item) => item.id !== "adapt" || adaptEnabled).map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
40285
|
+
type: "button",
|
|
40286
|
+
role: "tab",
|
|
40287
|
+
"aria-selected": nav === item.id,
|
|
40288
|
+
"data-active": nav === item.id ? "" : void 0,
|
|
40289
|
+
className: panel_module_css_default.navTab,
|
|
40290
|
+
title: item.hint,
|
|
40291
|
+
onClick: () => setNav(item.id),
|
|
40292
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
40293
|
+
className: panel_module_css_default.navTabIcon,
|
|
40294
|
+
children: item.icon
|
|
40295
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
40296
|
+
className: panel_module_css_default.navTabLabel,
|
|
40297
|
+
children: item.label
|
|
40298
|
+
})]
|
|
40299
|
+
}, item.id))]
|
|
40300
|
+
}),
|
|
40301
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: panel_module_css_default.navSpacer }),
|
|
40302
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
40303
|
+
type: "button",
|
|
40304
|
+
role: "tab",
|
|
40305
|
+
"aria-selected": nav === "settings",
|
|
40306
|
+
"data-active": nav === "settings" ? "" : void 0,
|
|
40307
|
+
className: panel_module_css_default.navTab,
|
|
40308
|
+
title: "设置",
|
|
40309
|
+
onClick: () => setNav("settings"),
|
|
40310
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
40311
|
+
className: panel_module_css_default.navTabIcon,
|
|
40312
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Settings, { size: 18 })
|
|
40313
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
40314
|
+
className: panel_module_css_default.navTabLabel,
|
|
40315
|
+
children: "设置"
|
|
40316
|
+
})]
|
|
40317
|
+
}),
|
|
40318
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
40319
|
+
className: panel_module_css_default.navAbout,
|
|
40320
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
40321
|
+
className: panel_module_css_default.navAboutRow,
|
|
40322
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
40323
|
+
"ℹ️ v",
|
|
40324
|
+
PLUGIN_VERSION$1,
|
|
40325
|
+
" · 改编/资产库"
|
|
40326
|
+
] })
|
|
40327
|
+
})
|
|
40328
|
+
})
|
|
40329
|
+
]
|
|
40330
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
40331
|
+
className: panel_module_css_default.authorContent,
|
|
40332
|
+
children: [
|
|
40333
|
+
nav === "shelf" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ShelfView, {
|
|
40334
|
+
api,
|
|
40335
|
+
shelf,
|
|
40336
|
+
onOpenBook,
|
|
40337
|
+
onReadBook,
|
|
40338
|
+
onAddBook,
|
|
40339
|
+
onImportBook
|
|
40340
|
+
}),
|
|
40341
|
+
nav === "adapt" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AdaptModeView, { api }),
|
|
40342
|
+
nav === "assets" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AuthorAssetsView, { api }),
|
|
40343
|
+
nav === "library" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Placeholder, {
|
|
40344
|
+
title: "🎨 全局写作资产库",
|
|
40345
|
+
hint: "内置题材基底库 / 反AI规则库 / 风格模板 / 推进模式(跨书)"
|
|
40346
|
+
}),
|
|
40347
|
+
nav === "progress" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
40348
|
+
className: panel_module_css_default.authorPageBody,
|
|
40349
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProgressConsole, {
|
|
40350
|
+
progress: progress ?? [],
|
|
40351
|
+
busy: busy ?? false,
|
|
40352
|
+
busyLabel: busyLabel ?? "",
|
|
40353
|
+
liveBar: liveBar ?? null,
|
|
40354
|
+
onClear: () => onClearProgress?.()
|
|
40355
|
+
})
|
|
40356
|
+
}),
|
|
40357
|
+
nav === "settings" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SettingsView, {
|
|
40358
|
+
api,
|
|
40359
|
+
onTheme,
|
|
40360
|
+
onBackground,
|
|
40361
|
+
onOpacity
|
|
40362
|
+
})
|
|
40363
|
+
]
|
|
40364
|
+
})]
|
|
40365
|
+
});
|
|
40366
|
+
}
|
|
40367
|
+
//#endregion
|
|
37129
40368
|
//#region src/client/panel/ReaderView.tsx
|
|
37130
40369
|
/**
|
|
37131
40370
|
* 阅读页:沉浸式章节阅读(纯只读,零 LLM 消耗)。
|
|
@@ -38969,7 +42208,7 @@ window.__ModuleLoader__.load({
|
|
|
38969
42208
|
setFileName(file.name);
|
|
38970
42209
|
setPreviewing(true);
|
|
38971
42210
|
try {
|
|
38972
|
-
const text = await file
|
|
42211
|
+
const text = await readFileTextSmart(file);
|
|
38973
42212
|
setFileText(text);
|
|
38974
42213
|
const p = await api.bookImportTextPreview(text, file.name);
|
|
38975
42214
|
setPreview(p);
|
|
@@ -44927,32 +48166,32 @@ window.__ModuleLoader__.load({
|
|
|
44927
48166
|
{
|
|
44928
48167
|
id: "workflow",
|
|
44929
48168
|
label: tt("tab.workflow"),
|
|
44930
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Wrench, { size:
|
|
48169
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Wrench, { size: 18 })
|
|
44931
48170
|
},
|
|
44932
48171
|
{
|
|
44933
48172
|
id: "overview",
|
|
44934
48173
|
label: tt("tab.overview"),
|
|
44935
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.FileText, { size:
|
|
48174
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.FileText, { size: 18 })
|
|
44936
48175
|
},
|
|
44937
48176
|
{
|
|
44938
48177
|
id: "blurb",
|
|
44939
48178
|
label: "简介 / 封面",
|
|
44940
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BookOpen, { size:
|
|
48179
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BookOpen, { size: 18 })
|
|
44941
48180
|
},
|
|
44942
48181
|
{
|
|
44943
48182
|
id: "plan",
|
|
44944
48183
|
label: tt("tab.plan"),
|
|
44945
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BookMarked, { size:
|
|
48184
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BookMarked, { size: 18 })
|
|
44946
48185
|
},
|
|
44947
48186
|
{
|
|
44948
48187
|
id: "plotlines",
|
|
44949
48188
|
label: "长线管理",
|
|
44950
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.ScrollText, { size:
|
|
48189
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.ScrollText, { size: 18 })
|
|
44951
48190
|
},
|
|
44952
48191
|
{
|
|
44953
48192
|
id: "book",
|
|
44954
48193
|
label: "本书设定",
|
|
44955
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Library, { size:
|
|
48194
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Library, { size: 18 })
|
|
44956
48195
|
}
|
|
44957
48196
|
]
|
|
44958
48197
|
},
|
|
@@ -44963,27 +48202,27 @@ window.__ModuleLoader__.load({
|
|
|
44963
48202
|
{
|
|
44964
48203
|
id: "assistant",
|
|
44965
48204
|
label: tt("tab.assistant"),
|
|
44966
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.MessageSquare, { size:
|
|
48205
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.MessageSquare, { size: 18 })
|
|
44967
48206
|
},
|
|
44968
48207
|
{
|
|
44969
48208
|
id: "progress",
|
|
44970
48209
|
label: "AI 进度",
|
|
44971
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BarChart3, { size:
|
|
48210
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.BarChart3, { size: 18 })
|
|
44972
48211
|
},
|
|
44973
48212
|
{
|
|
44974
48213
|
id: "breakdown",
|
|
44975
48214
|
label: "拆书分析",
|
|
44976
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Search, { size:
|
|
48215
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Search, { size: 18 })
|
|
44977
48216
|
},
|
|
44978
48217
|
{
|
|
44979
48218
|
id: "manhua",
|
|
44980
48219
|
label: "漫剧工作台",
|
|
44981
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Clapperboard, { size:
|
|
48220
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Clapperboard, { size: 18 })
|
|
44982
48221
|
},
|
|
44983
48222
|
{
|
|
44984
48223
|
id: "run",
|
|
44985
48224
|
label: "生产单",
|
|
44986
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Factory, { size:
|
|
48225
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Factory, { size: 18 })
|
|
44987
48226
|
}
|
|
44988
48227
|
]
|
|
44989
48228
|
},
|
|
@@ -44993,7 +48232,7 @@ window.__ModuleLoader__.load({
|
|
|
44993
48232
|
items: [{
|
|
44994
48233
|
id: "assets",
|
|
44995
48234
|
label: "创作资产",
|
|
44996
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Wrench, { size:
|
|
48235
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Wrench, { size: 18 })
|
|
44997
48236
|
}]
|
|
44998
48237
|
}
|
|
44999
48238
|
];
|
|
@@ -45001,21 +48240,8 @@ window.__ModuleLoader__.load({
|
|
|
45001
48240
|
const SETTINGS_TAB = {
|
|
45002
48241
|
id: "settings",
|
|
45003
48242
|
label: tt("tab.settings"),
|
|
45004
|
-
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Settings, { size:
|
|
48243
|
+
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Settings, { size: 18 })
|
|
45005
48244
|
};
|
|
45006
|
-
/** Common DeepSeek model presets shown in settings; users can also type any model id. */
|
|
45007
|
-
const MODEL_PRESETS = [
|
|
45008
|
-
"deepseek-v4-flash",
|
|
45009
|
-
"deepseek-v4-pro",
|
|
45010
|
-
"deepseek-chat",
|
|
45011
|
-
"deepseek-reasoner"
|
|
45012
|
-
];
|
|
45013
|
-
const REASONING_OPTIONS = [
|
|
45014
|
-
"off",
|
|
45015
|
-
"low",
|
|
45016
|
-
"high",
|
|
45017
|
-
"max"
|
|
45018
|
-
];
|
|
45019
48245
|
/** 设置页内子导航分组。 */
|
|
45020
48246
|
const SETTINGS_SECTIONS = [
|
|
45021
48247
|
{
|
|
@@ -45044,7 +48270,7 @@ window.__ModuleLoader__.load({
|
|
|
45044
48270
|
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(import_lucide_react.Sparkles, { size: 16 })
|
|
45045
48271
|
}
|
|
45046
48272
|
];
|
|
45047
|
-
const PLUGIN_VERSION = "1.
|
|
48273
|
+
const PLUGIN_VERSION = "1.9.0";
|
|
45048
48274
|
/** GitHub 仓库地址(关于区块点击跳转)。 */
|
|
45049
48275
|
const REPO_URL = "https://github.com/watersxya/dsh-novel-forge";
|
|
45050
48276
|
/** Whether any chapter is being generated right now. */
|
|
@@ -45300,6 +48526,12 @@ window.__ModuleLoader__.load({
|
|
|
45300
48526
|
function NovelPanel({ controller, api }) {
|
|
45301
48527
|
const [activeTab, setActiveTab] = (0, react.useState)("workflow");
|
|
45302
48528
|
const [config, setConfig] = (0, react.useState)(null);
|
|
48529
|
+
/** 自定义背景(URL / dataURL),覆盖主题默认背景。 */
|
|
48530
|
+
const [themeBg, setThemeBg] = (0, react.useState)(void 0);
|
|
48531
|
+
/** 自定义背景遮罩/模糊强度 0-80。 */
|
|
48532
|
+
const [themeBgBlur, setThemeBgBlur] = (0, react.useState)(0);
|
|
48533
|
+
/** 玻璃透明度 0-100(100=主题原样)。 */
|
|
48534
|
+
const [themeOpacity, setThemeOpacity] = (0, react.useState)(100);
|
|
45303
48535
|
const [project, setProject] = (0, react.useState)(null);
|
|
45304
48536
|
const [generatedFiles, setGeneratedFiles] = (0, react.useState)([]);
|
|
45305
48537
|
const [outlineText, setOutlineText] = (0, react.useState)("");
|
|
@@ -45314,7 +48546,6 @@ window.__ModuleLoader__.load({
|
|
|
45314
48546
|
const [notice, setNotice] = (0, react.useState)("");
|
|
45315
48547
|
const [progress, setProgress] = (0, react.useState)([]);
|
|
45316
48548
|
const [configDraft, setConfigDraft] = (0, react.useState)(null);
|
|
45317
|
-
const [modelCustomMode, setModelCustomMode] = (0, react.useState)(false);
|
|
45318
48549
|
const [expandedChapter, setExpandedChapter] = (0, react.useState)(null);
|
|
45319
48550
|
/** 复盘记录页:当前展开的章节号。 */
|
|
45320
48551
|
const [expandedReviewChapter, setExpandedReviewChapter] = (0, react.useState)(null);
|
|
@@ -45736,7 +48967,6 @@ window.__ModuleLoader__.load({
|
|
|
45736
48967
|
const status = await api.status();
|
|
45737
48968
|
setConfig(status.config);
|
|
45738
48969
|
setConfigDraft(status.config);
|
|
45739
|
-
setModelCustomMode(!MODEL_PRESETS.includes(status.config.model));
|
|
45740
48970
|
setAuditStatus(status.audit ?? null);
|
|
45741
48971
|
setProject(status.project ?? null);
|
|
45742
48972
|
if (status.project?.roleStatus !== void 0) setCharCards(status.project.roleStatus);
|
|
@@ -45777,6 +49007,16 @@ window.__ModuleLoader__.load({
|
|
|
45777
49007
|
refresh,
|
|
45778
49008
|
refreshShelf
|
|
45779
49009
|
]);
|
|
49010
|
+
/** 首页「设置」与书内设置同入口:激活当前/首选书并跳到设置页。 */
|
|
49011
|
+
const openSettingsFromHome = async () => {
|
|
49012
|
+
const targetId = shelf?.activeBookId ?? shelf?.books[0]?.id ?? null;
|
|
49013
|
+
if (targetId === null || targetId === void 0) {
|
|
49014
|
+
setError("请先在书架开一本书;设置页以书籍工作台为入口");
|
|
49015
|
+
return;
|
|
49016
|
+
}
|
|
49017
|
+
await activateBook(targetId, "workspace");
|
|
49018
|
+
setActiveTab("settings");
|
|
49019
|
+
};
|
|
45780
49020
|
/** Handle a docx file (pick or drag): parse locally, save outline. */
|
|
45781
49021
|
const handleDocxFile = (0, react.useCallback)(async (file) => {
|
|
45782
49022
|
setBusy(true);
|
|
@@ -47112,7 +50352,8 @@ window.__ModuleLoader__.load({
|
|
|
47112
50352
|
imageApiKey: configDraft.imageApiKey,
|
|
47113
50353
|
imageApiModel: configDraft.imageApiModel,
|
|
47114
50354
|
imageApiEnabled: configDraft.imageApiEnabled ?? false,
|
|
47115
|
-
imageModels: configDraft.imageModels ?? []
|
|
50355
|
+
imageModels: configDraft.imageModels ?? [],
|
|
50356
|
+
savedModels: configDraft.savedModels ?? []
|
|
47116
50357
|
});
|
|
47117
50358
|
setConfig(result.config);
|
|
47118
50359
|
setConfigDraft(result.config);
|
|
@@ -47523,13 +50764,22 @@ window.__ModuleLoader__.load({
|
|
|
47523
50764
|
n += assets?.antiAiRules?.length ?? 0;
|
|
47524
50765
|
return n;
|
|
47525
50766
|
})();
|
|
50767
|
+
/** 自定义背景:优先用户显式选择(themeBg),否则用 config 里的持久化值。 */
|
|
50768
|
+
const effectiveBg = themeBg !== void 0 && themeBg !== "" ? themeBg : config?.themeBackground ?? "";
|
|
50769
|
+
const effectiveBgBlur = themeBgBlur > 0 ? themeBgBlur : config?.themeBackgroundBlur ?? 0;
|
|
50770
|
+
const effectiveOpacity = themeOpacity > 0 ? themeOpacity : config?.themeOpacity ?? 100;
|
|
50771
|
+
const panelBgStyle = {};
|
|
50772
|
+
if (effectiveBg !== "") panelBgStyle["--nf-glass-bg-image"] = "url(" + effectiveBg + ")";
|
|
50773
|
+
if (effectiveBgBlur > 0) panelBgStyle["--nf-glass-bg-dim"] = String(effectiveBgBlur);
|
|
50774
|
+
panelBgStyle["--nf-glass-opacity"] = String(effectiveOpacity) + "%";
|
|
47526
50775
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
47527
50776
|
className: panel_module_css_default.panel,
|
|
47528
50777
|
"data-nf-theme": panelTheme,
|
|
47529
50778
|
"data-nf-mode": themeMode === "system" ? void 0 : themeMode,
|
|
47530
50779
|
"data-nf-density": themeDensity,
|
|
50780
|
+
style: panelBgStyle,
|
|
47531
50781
|
children: [
|
|
47532
|
-
viewMode === "shelf" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
50782
|
+
viewMode === "shelf" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AuthorHome, {
|
|
47533
50783
|
api,
|
|
47534
50784
|
shelf: shelf ?? {
|
|
47535
50785
|
books: [],
|
|
@@ -47546,6 +50796,29 @@ window.__ModuleLoader__.load({
|
|
|
47546
50796
|
},
|
|
47547
50797
|
onImportBook: () => {
|
|
47548
50798
|
setShowImport(true);
|
|
50799
|
+
},
|
|
50800
|
+
onOpenSettings: () => {
|
|
50801
|
+
openSettingsFromHome();
|
|
50802
|
+
},
|
|
50803
|
+
onTheme: (t, m, d) => {
|
|
50804
|
+
changePanelTheme(t);
|
|
50805
|
+
changeThemeMode(m);
|
|
50806
|
+
changeThemeDensity(d);
|
|
50807
|
+
},
|
|
50808
|
+
onBackground: (bg, blur) => {
|
|
50809
|
+
setThemeBg(bg);
|
|
50810
|
+
setThemeBgBlur(blur);
|
|
50811
|
+
},
|
|
50812
|
+
onOpacity: (n) => {
|
|
50813
|
+
setThemeOpacity(n);
|
|
50814
|
+
},
|
|
50815
|
+
adaptEnabled: config?.enableAdaptMode === true,
|
|
50816
|
+
progress,
|
|
50817
|
+
busy,
|
|
50818
|
+
busyLabel,
|
|
50819
|
+
liveBar,
|
|
50820
|
+
onClearProgress: () => {
|
|
50821
|
+
setProgress([]);
|
|
47549
50822
|
}
|
|
47550
50823
|
}) : viewMode === "create" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CreateBookView, {
|
|
47551
50824
|
api,
|
|
@@ -50208,7 +53481,7 @@ window.__ModuleLoader__.load({
|
|
|
50208
53481
|
}, s.id))
|
|
50209
53482
|
})]
|
|
50210
53483
|
}),
|
|
50211
|
-
settingsTab === "model" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
53484
|
+
settingsTab === "model" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
50212
53485
|
className: `${panel_module_css_default.card} ${panel_module_css_default.settingsCard}`,
|
|
50213
53486
|
style: { gap: "var(--nf-space-24)" },
|
|
50214
53487
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
@@ -50217,129 +53490,36 @@ window.__ModuleLoader__.load({
|
|
|
50217
53490
|
size: 18,
|
|
50218
53491
|
style: { verticalAlign: -3 }
|
|
50219
53492
|
}), " 模型与推理"]
|
|
50220
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
50221
|
-
|
|
50222
|
-
|
|
50223
|
-
|
|
50224
|
-
|
|
53493
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelManager, {
|
|
53494
|
+
api,
|
|
53495
|
+
provider: configDraft.provider,
|
|
53496
|
+
model: configDraft.model,
|
|
53497
|
+
savedModels: configDraft.savedModels ?? [],
|
|
53498
|
+
onProvider: (v) => {
|
|
53499
|
+
setConfigDraft({
|
|
53500
|
+
...configDraft,
|
|
53501
|
+
provider: v
|
|
53502
|
+
});
|
|
50225
53503
|
},
|
|
50226
|
-
|
|
50227
|
-
|
|
50228
|
-
|
|
50229
|
-
|
|
50230
|
-
|
|
50231
|
-
|
|
50232
|
-
|
|
50233
|
-
|
|
50234
|
-
|
|
50235
|
-
|
|
50236
|
-
setConfigDraft({
|
|
50237
|
-
...configDraft,
|
|
50238
|
-
provider: e.target.value
|
|
50239
|
-
});
|
|
50240
|
-
}
|
|
50241
|
-
})]
|
|
50242
|
-
}),
|
|
50243
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
50244
|
-
className: panel_module_css_default.field,
|
|
50245
|
-
children: [
|
|
50246
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
50247
|
-
className: panel_module_css_default.fieldLabel,
|
|
50248
|
-
children: tt("settings.model")
|
|
50249
|
-
}),
|
|
50250
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
50251
|
-
className: panel_module_css_default.input,
|
|
50252
|
-
value: modelCustomMode ? "__custom__" : configDraft.model,
|
|
50253
|
-
onChange: (e) => {
|
|
50254
|
-
const v = e.target.value;
|
|
50255
|
-
if (v === "__custom__") setModelCustomMode(true);
|
|
50256
|
-
else {
|
|
50257
|
-
setModelCustomMode(false);
|
|
50258
|
-
setConfigDraft({
|
|
50259
|
-
...configDraft,
|
|
50260
|
-
model: v
|
|
50261
|
-
});
|
|
50262
|
-
}
|
|
50263
|
-
},
|
|
50264
|
-
children: [MODEL_PRESETS.map((m) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
50265
|
-
value: m,
|
|
50266
|
-
children: m
|
|
50267
|
-
}, m)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
50268
|
-
value: "__custom__",
|
|
50269
|
-
children: tt("settings.modelCustom")
|
|
50270
|
-
})]
|
|
50271
|
-
}),
|
|
50272
|
-
modelCustomMode && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
50273
|
-
className: panel_module_css_default.input,
|
|
50274
|
-
style: { marginTop: "var(--nf-space-6)" },
|
|
50275
|
-
value: configDraft.model,
|
|
50276
|
-
placeholder: tt("settings.modelCustomPlaceholder"),
|
|
50277
|
-
onChange: (e) => {
|
|
50278
|
-
setConfigDraft({
|
|
50279
|
-
...configDraft,
|
|
50280
|
-
model: e.target.value
|
|
50281
|
-
});
|
|
50282
|
-
}
|
|
50283
|
-
})
|
|
50284
|
-
]
|
|
50285
|
-
}),
|
|
50286
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
50287
|
-
className: panel_module_css_default.field,
|
|
50288
|
-
children: [
|
|
50289
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
50290
|
-
className: panel_module_css_default.fieldLabel,
|
|
50291
|
-
children: tt("settings.reasoningEffort")
|
|
50292
|
-
}),
|
|
50293
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
50294
|
-
className: panel_module_css_default.input,
|
|
50295
|
-
value: configDraft.reasoningEffort ?? "off",
|
|
50296
|
-
onChange: (e) => {
|
|
50297
|
-
setConfigDraft({
|
|
50298
|
-
...configDraft,
|
|
50299
|
-
reasoningEffort: e.target.value
|
|
50300
|
-
});
|
|
50301
|
-
},
|
|
50302
|
-
children: REASONING_OPTIONS.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
50303
|
-
value: v,
|
|
50304
|
-
children: tt(`settings.reasoning.${v}`)
|
|
50305
|
-
}, v))
|
|
50306
|
-
}),
|
|
50307
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
50308
|
-
className: panel_module_css_default.meta,
|
|
50309
|
-
children: tt("settings.reasoningHint")
|
|
50310
|
-
})
|
|
50311
|
-
]
|
|
50312
|
-
}),
|
|
50313
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
50314
|
-
className: panel_module_css_default.field,
|
|
50315
|
-
children: [
|
|
50316
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
50317
|
-
className: panel_module_css_default.fieldLabel,
|
|
50318
|
-
children: tt("settings.analysisReasoning")
|
|
50319
|
-
}),
|
|
50320
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("select", {
|
|
50321
|
-
className: panel_module_css_default.input,
|
|
50322
|
-
value: configDraft.analysisReasoning ?? "low",
|
|
50323
|
-
onChange: (e) => {
|
|
50324
|
-
setConfigDraft({
|
|
50325
|
-
...configDraft,
|
|
50326
|
-
analysisReasoning: e.target.value
|
|
50327
|
-
});
|
|
50328
|
-
},
|
|
50329
|
-
children: REASONING_OPTIONS.map((v) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
50330
|
-
value: v,
|
|
50331
|
-
children: tt(`settings.reasoning.${v}`)
|
|
50332
|
-
}, v))
|
|
50333
|
-
}),
|
|
50334
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
50335
|
-
className: panel_module_css_default.meta,
|
|
50336
|
-
children: tt("settings.analysisReasoningHint")
|
|
50337
|
-
})
|
|
50338
|
-
]
|
|
50339
|
-
})
|
|
50340
|
-
]
|
|
53504
|
+
onModel: (v) => {
|
|
53505
|
+
setConfigDraft({
|
|
53506
|
+
...configDraft,
|
|
53507
|
+
model: v
|
|
53508
|
+
});
|
|
53509
|
+
},
|
|
53510
|
+
onSavedModels: (models) => setConfigDraft({
|
|
53511
|
+
...configDraft,
|
|
53512
|
+
savedModels: models
|
|
53513
|
+
})
|
|
50341
53514
|
})]
|
|
50342
|
-
}),
|
|
53515
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReasoningSection, {
|
|
53516
|
+
reasoningEffort: configDraft.reasoningEffort ?? "off",
|
|
53517
|
+
analysisReasoning: configDraft.analysisReasoning ?? "low",
|
|
53518
|
+
onChange: (patch) => setConfigDraft({
|
|
53519
|
+
...configDraft,
|
|
53520
|
+
...patch
|
|
53521
|
+
})
|
|
53522
|
+
})] }),
|
|
50343
53523
|
settingsTab === "writing" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
50344
53524
|
className: `${panel_module_css_default.card} ${panel_module_css_default.settingsCard}`,
|
|
50345
53525
|
style: { gap: "var(--nf-space-24)" },
|
|
@@ -52406,7 +55586,7 @@ window.__ModuleLoader__.load({
|
|
|
52406
55586
|
entry.className = panel_module_css_default.entry;
|
|
52407
55587
|
entry.setAttribute("aria-label", tt("entry.label"));
|
|
52408
55588
|
entry.setAttribute("title", tt("entry.tooltip"));
|
|
52409
|
-
entry.innerHTML = "<span class=\"" + panel_module_css_default.entryIcon + "\"><svg viewBox=\"0 0
|
|
55589
|
+
entry.innerHTML = "<span class=\"" + panel_module_css_default.entryIcon + "\"><svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"><path d=\"M12.67 19a2 2 0 0 0 1.416-.588l6.154-6.172a6 6 0 0 0-8.49-8.49L5.586 9.914A2 2 0 0 0 5 11.328V18a1 1 0 0 0 1 1z\"/><path d=\"M16 8 2 22\"/><path d=\"M17.5 15H9\"/></svg></span><span class=\"" + panel_module_css_default.entryLabel + "\">" + tt("entry.label") + "</span>";
|
|
52410
55590
|
entry.addEventListener("click", () => {
|
|
52411
55591
|
controller.toggle();
|
|
52412
55592
|
});
|