@waterwx/dsh-novel-forge 1.1.4 → 1.1.6
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/README.md +5 -0
- package/lib/client.js +1438 -1000
- package/lib/client.js.map +1 -1
- package/lib/index.js +893 -533
- package/lib/index.js.map +1 -1
- package/lib/types/client/api.d.ts +12 -0
- package/lib/types/client/panel/NovelPanel.d.ts +1 -1
- package/lib/types/client/panel/helpers.d.ts +10 -0
- package/lib/types/client/panel/views.d.ts +77 -0
- package/lib/types/engine.d.ts +10 -1
- package/lib/types/protocol.d.ts +47 -0
- package/package.json +1 -1
- package/src/assistant.ts +86 -6
- package/src/client/api.ts +15 -0
- package/src/client/panel/NovelPanel.tsx +341 -306
- package/src/client/panel/helpers.ts +50 -0
- package/src/client/panel/views.tsx +314 -0
- package/src/engine.ts +138 -12
- package/src/protocol.ts +50 -0
- package/src/routes.ts +128 -0
package/lib/client.js
CHANGED
|
@@ -65,8 +65,14 @@ window.__ModuleLoader__.load({
|
|
|
65
65
|
cover: "/api/dsh-novel-forge/blurb/cover",
|
|
66
66
|
/** 剧情线管理:增删改 + 关联章节。 */
|
|
67
67
|
plotlines: "/api/dsh-novel-forge/plotlines",
|
|
68
|
+
/** 角色库:AI 提炼 / 采纳 / 更新 / 删除。 */
|
|
69
|
+
roles: "/api/dsh-novel-forge/roles",
|
|
68
70
|
/** 作者复盘补跑:对已写章节补齐 authorReview(全书流式 / 单章 JSON)。 */
|
|
69
71
|
reviewBackfill: "/api/dsh-novel-forge/review/backfill",
|
|
72
|
+
/** 章节复位:generating 卡死 → pending(可重新生成)。 */
|
|
73
|
+
chapterReset: "/api/dsh-novel-forge/chapter/reset",
|
|
74
|
+
/** 章节直接通过:作者对 rejected/written 章节行使最终决定权。 */
|
|
75
|
+
chapterApprove: "/api/dsh-novel-forge/chapter/approve",
|
|
70
76
|
/** 敏感词检查:全书已写章节或指定文本。 */
|
|
71
77
|
sensitiveCheck: "/api/dsh-novel-forge/sensitive-check",
|
|
72
78
|
config: "/api/dsh-novel-forge/config",
|
|
@@ -220,6 +226,18 @@ window.__ModuleLoader__.load({
|
|
|
220
226
|
async reviewBackfillAll(onFrame) {
|
|
221
227
|
await this.streamJob(NOVEL_API.reviewBackfill, {}, onFrame);
|
|
222
228
|
}
|
|
229
|
+
/** 章节复位:generating 卡死 → pending。 */
|
|
230
|
+
async chapterReset(no) {
|
|
231
|
+
return postJson(NOVEL_API.chapterReset, { chapterNo: no });
|
|
232
|
+
}
|
|
233
|
+
/** 章节直接通过(作者行使最终决定权)。 */
|
|
234
|
+
async chapterApprove(no) {
|
|
235
|
+
return postJson(NOVEL_API.chapterApprove, { chapterNo: no });
|
|
236
|
+
}
|
|
237
|
+
/** 角色库:AI 提炼 / 采纳 / 更新 / 删除。 */
|
|
238
|
+
async roles(req) {
|
|
239
|
+
return postJson(NOVEL_API.roles, req);
|
|
240
|
+
}
|
|
223
241
|
/** 小说简介:AI 生成/补全(partial 留空 = 全量),或手动保存。 */
|
|
224
242
|
async blurb(action, text, partial) {
|
|
225
243
|
return postJson(NOVEL_API.blurb, {
|
|
@@ -753,6 +771,49 @@ window.__ModuleLoader__.load({
|
|
|
753
771
|
if (params !== void 0) for (const [name, value] of Object.entries(params)) text = text.replaceAll(`{${name}}`, String(value));
|
|
754
772
|
return text;
|
|
755
773
|
}
|
|
774
|
+
/** 角色定位中文名(角色库/提炼候选共用,收敛自多份复制)。 */
|
|
775
|
+
const ROLE_LABELS = {
|
|
776
|
+
protagonist: "主角",
|
|
777
|
+
female_lead: "女主",
|
|
778
|
+
female_support: "女配",
|
|
779
|
+
support: "配角",
|
|
780
|
+
antagonist: "反派",
|
|
781
|
+
extra: "路人"
|
|
782
|
+
};
|
|
783
|
+
/** 角色定位徽章颜色。 */
|
|
784
|
+
function roleColor(label) {
|
|
785
|
+
if (label === "protagonist") return "var(--nf-success)";
|
|
786
|
+
if (label === "female_lead") return "var(--nf-accent)";
|
|
787
|
+
if (label === "antagonist") return "var(--nf-error)";
|
|
788
|
+
return "var(--nf-text-3)";
|
|
789
|
+
}
|
|
790
|
+
/** 剧情线类型中文名(与 locale 对齐)。 */
|
|
791
|
+
function kindLabel(kind) {
|
|
792
|
+
switch (kind) {
|
|
793
|
+
case "main": return tt("plotlines.kindMain");
|
|
794
|
+
case "branch": return tt("plotlines.kindBranch");
|
|
795
|
+
case "character": return tt("plotlines.kindCharacter");
|
|
796
|
+
case "mystery": return tt("plotlines.kindMystery");
|
|
797
|
+
default: return kind;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
/** 剧情线状态中文名。 */
|
|
801
|
+
function plotlineStatusLabel(status) {
|
|
802
|
+
switch (status) {
|
|
803
|
+
case "active": return tt("plotlines.statusActive");
|
|
804
|
+
case "paused": return tt("plotlines.statusPaused");
|
|
805
|
+
case "resolved": return tt("plotlines.statusResolved");
|
|
806
|
+
case "abandoned": return tt("plotlines.statusAbandoned");
|
|
807
|
+
default: return status;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
/** 剧情线状态颜色。 */
|
|
811
|
+
function plotlineStatusColor(status) {
|
|
812
|
+
if (status === "resolved") return "var(--nf-success)";
|
|
813
|
+
if (status === "abandoned") return "var(--nf-text-3)";
|
|
814
|
+
if (status === "paused") return "var(--nf-warn)";
|
|
815
|
+
return "var(--nf-accent)";
|
|
816
|
+
}
|
|
756
817
|
//#endregion
|
|
757
818
|
//#region \0dsh-css:C:\Users\Ryan\Desktop\111\novel-forge\src\client\panel\panel.module.css.mjs
|
|
758
819
|
const css = ".CUIYUW_entry{width:100%;color:var(--dsw-alias-label-primary,#1f1f23);cursor:pointer;text-align:left;background:0 0;border:none;border-radius:6px;align-items:center;gap:8px;padding:8px 12px;font-size:13px;transition:background .15s;display:flex}body[data-ds-dark-theme] .CUIYUW_entry{color:var(--dsw-alias-label-primary,#ececf1)}.CUIYUW_entry:hover{background:var(--dsw-alias-interactive-bg-hover,#7f7f7f1f)}.CUIYUW_entry[data-active]{background:var(--dsw-alias-interactive-bg-active,#7f7f7f33)}.CUIYUW_entryIcon{flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.CUIYUW_entryLabel{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}[data-pane=conversation]{position:relative}.CUIYUW_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, #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:#00b85c24;--nf-glass-orb-b:#78a0ff1a;--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\");background:var(--nf-bg);backdrop-filter:blur(32px)saturate(180%);color:var(--nf-text);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}body[data-ds-dark-theme] .CUIYUW_view{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:#00ca5233;--nf-glass-orb-b:#bec8d712;--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\")}html[data-dsh-novelforge-active]:not([data-dsh-taskboard-active]):not([data-dsh-ssh-active]) .CUIYUW_view{display:block}.CUIYUW_panel[data-nf-theme=classic]{--nf-accent:#007aff;--nf-accent-hover:#0071e3;--nf-accent-soft:#007aff1f;--nf-accent-fg:#fff;--nf-info:#5856d6;--nf-glass-face:var(--nf-bg-raise);--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:var(--nf-border);--nf-glass-inset:var(--nf-bg-inset);--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=classic]{--nf-accent:#0a84ff;--nf-accent-hover:#3a9bff;--nf-accent-soft:#0a84ff33;--nf-accent-fg:#fff;--nf-info:#bf5af2;--nf-glass-face:var(--nf-bg-raise);--nf-glass-core:transparent;--nf-glass-sheen:#fff0;--nf-glass-border:var(--nf-border);--nf-glass-inset:var(--nf-bg-inset);--nf-glass-orb-a:transparent;--nf-glass-orb-b:transparent;--nf-glass-noise:none}body:not([data-ds-dark-theme]) .CUIYUW_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}body[data-ds-dark-theme] .CUIYUW_panel[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}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_input,body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_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]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_input:focus,body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_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] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_input,body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_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] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_input:focus,body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_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]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_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]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_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]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #a3b1c68c,inset -3px -3px 7px #ffffffe6}body:not([data-ds-dark-theme]) .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_buttonPrimary{background:linear-gradient(#00c563,#00a952);box-shadow:5px 5px 10px #a3b1c699,-5px -5px 10px #ffffffd9}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button{background:var(--nf-bg-raise);border-color:#0000;box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_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] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_button:active:not([disabled]){box-shadow:inset 3px 3px 7px #0000008c,inset -3px -3px 7px #6068763d}body[data-ds-dark-theme] .CUIYUW_panel[data-nf-theme=neumorph] .CUIYUW_buttonPrimary{background:linear-gradient(#3ddc86,#27b96a);box-shadow:5px 5px 10px #00000080,-5px -5px 10px #6068763d}.CUIYUW_panel{flex-direction:column;min-width:0;height:100%;font-size:14px;line-height:1.6;display:flex;position:relative;overflow:hidden}.CUIYUW_panel:before{content:\"\";z-index:0;pointer-events:none;background: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}.CUIYUW_panelHeader{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);backdrop-filter:blur(28px)saturate(175%);z-index:5;border-radius:18px;flex-shrink:0;justify-content:space-between;align-items:center;margin:10px 12px 0;padding:10px 16px;display:flex;position:sticky;top:10px}.CUIYUW_panelTitle{letter-spacing:.2px;align-items:center;gap:8px;margin:0;font-size:16px;font-weight:700;display:flex}.CUIYUW_panelTitle:before{content:\"\";background:linear-gradient(180deg, var(--nf-accent), var(--nf-info));border-radius:2px;width:4px;height:16px}.CUIYUW_iconButton{cursor:pointer;color:var(--nf-text-2);background:0 0;border:none;border-radius:8px;padding:4px 9px;font-size:16px;transition:background .15s,color .15s}.CUIYUW_iconButton:hover{background:var(--nf-hover);color:var(--nf-text)}.CUIYUW_tabBar{border-bottom:1px solid var(--nf-border);background:var(--nf-bg-raise);z-index:4;flex-shrink:0;gap:2px;padding:8px 14px 0;display:flex;position:sticky;top:45px}.CUIYUW_tab{cursor:pointer;color:var(--nf-text-2);background:0 0;border:none;border-radius:8px 8px 0 0;padding:7px 13px;font-size:13.5px;font-weight:500;transition:color .15s,background .15s;position:relative}.CUIYUW_tab:hover{color:var(--nf-text);background:var(--nf-hover)}.CUIYUW_tab[data-active]{color:var(--nf-accent);font-weight:600}.CUIYUW_tab[data-active]:after{content:\"\";background:var(--nf-accent);border-radius:2px 2px 0 0;height:2.5px;position:absolute;bottom:-1px;left:10px;right:10px}.CUIYUW_panelContent{z-index:1;flex-direction:column;flex:1;gap:14px;padding:16px 18px 20px;display:flex;position:relative;overflow:auto}.CUIYUW_panelBody{z-index:1;flex:1;min-height:0;display:flex;position:relative}.CUIYUW_panelNav{border:1px solid var(--nf-glass-border);background:var(--nf-glass-face);width:142px;box-shadow:var(--nf-shadow), inset 0 1px 0 var(--nf-glass-sheen);backdrop-filter:blur(28px)saturate(175%);border-radius:16px;flex-direction:column;flex:none;align-self:flex-start;gap:4px;margin:10px 0 10px 12px;padding:10px 8px;transition:width .18s;display:flex;overflow-y:auto}.CUIYUW_panelNavCollapsed{width:52px;padding:10px 6px}.CUIYUW_navGroup{flex-direction:column;gap:4px;display:flex}.CUIYUW_navGroupLabel{letter-spacing:.6px;text-transform:uppercase;color:var(--nf-text-3);user-select:none;padding:8px 10px 3px;font-size:10.5px;font-weight:600}.CUIYUW_navGroupSep{background:var(--nf-border);height:1px;margin:6px 8px 4px}.CUIYUW_navSpacer{flex:1;min-height:8px}.CUIYUW_navAbout{border-top:1px solid var(--nf-border);flex-direction:column;flex:none;gap:4px;margin-top:4px;padding:8px 6px 4px;display:flex}.CUIYUW_navAboutRow{cursor:pointer;color:var(--nf-text-3);text-align:left;white-space:nowrap;background:0 0;border:none;border-radius:8px;justify-content:space-between;align-items:center;gap:4px;padding:4px 6px;font-size:11px;transition:color .15s,background .15s;display:flex}.CUIYUW_navAboutRow:hover{color:var(--nf-text);background:var(--nf-hover)}.CUIYUW_navAboutUpdate{background:var(--nf-accent-soft);color:var(--nf-accent);cursor:pointer;text-align:left;white-space:nowrap;border:none;border-radius:8px;padding:4px 6px;font-size:10.5px;font-weight:600}.CUIYUW_navAboutUpdate:hover{color:var(--nf-accent-hover)}.CUIYUW_panelNavCollapsed .CUIYUW_navAbout{align-items:center;padding:6px 2px 2px}.CUIYUW_panelNavCollapsed .CUIYUW_navAboutRow{justify-content:center;width:100%;padding:4px 0}.CUIYUW_navTabBadge{background:var(--nf-accent);color:#fff;text-align:center;border-radius:999px;flex:none;min-width:18px;height:18px;margin-left:auto;padding:0 5px;font-size:10.5px;font-weight:700;line-height:18px;display:inline-block}.CUIYUW_panelNavCollapsed .CUIYUW_navTabBadge{min-width:14px;height:14px;padding:0 3px;font-size:9px;line-height:14px;position:absolute;top:2px;right:2px}.CUIYUW_navTabBadgeDanger{background:var(--nf-error)}.CUIYUW_navTabBadgeWarn{background:var(--nf-warn)}.CUIYUW_navTabBadgeDone{background:var(--nf-success)}.CUIYUW_navTab{cursor:pointer;width:100%;color:var(--nf-text-2-alpha,var(--nf-text-2));text-align:left;white-space:nowrap;background:0 0;border:none;border-radius:12px;align-items:center;gap:8px;padding:8px 10px;font-size:13px;font-weight:500;transition:color .15s,background .15s;display:flex;position:relative}.CUIYUW_panelNavCollapsed .CUIYUW_navTab{justify-content:center;padding:8px 0}.CUIYUW_navTab:hover{color:var(--nf-text);background:var(--nf-hover)}.CUIYUW_navTab[data-active]{color:var(--nf-accent);background:var(--nf-accent-soft);font-weight:600}.CUIYUW_navTab[data-active]:before{content:\"\";background:var(--nf-accent);border-radius:999px;width:3px;position:absolute;top:20%;bottom:20%;left:-8px}.CUIYUW_panelNavCollapsed .CUIYUW_navTab[data-active]:before{left:-6px}.CUIYUW_navTabIcon{flex:none;font-size:15px;line-height:1}.CUIYUW_navTabLabel{text-overflow:ellipsis;overflow:hidden}.CUIYUW_panelSubtitle{color:var(--nf-text-2);white-space:nowrap;flex-wrap:wrap;align-items:center;gap:8px;min-width:0;padding:0 4px 2px;font-size:12px;display:flex}.CUIYUW_headerProgress{color:var(--nf-text-2);white-space:nowrap;align-items:center;gap:6px;margin-left:0;font-size:12px;font-weight:400;display:inline-flex}.CUIYUW_headerProgress b{color:var(--nf-accent);font-weight:700}.CUIYUW_headerProgressDot{background:var(--nf-border-strong,var(--nf-text-3));border-radius:50%;width:3px;height:3px;display:inline-block}.CUIYUW_card{border:1px solid var(--nf-glass-border);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%);border-radius:22px;flex-direction:column;gap:10px;padding:16px 18px;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.CUIYUW_card:before{content:\"\";border-radius:inherit;pointer-events:none;background: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}.CUIYUW_card:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.CUIYUW_card: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)}.CUIYUW_card>*{z-index:1;position:relative}.CUIYUW_cardTitle{color:var(--nf-text);align-items:center;gap:8px;margin:0;font-size:14px;font-weight:650;display:flex}.CUIYUW_button{border:1px solid var(--nf-border-strong);background:var(--nf-bg-inset);color:var(--nf-text);cursor:pointer;white-space:nowrap;border-radius:12px;padding:6px 14px;font-size:13px;font-weight:500;transition:background .15s,border-color .15s,transform .1s,box-shadow .15s}.CUIYUW_button:hover:not([disabled]){background:var(--nf-hover);border-color:var(--nf-border-strong)}.CUIYUW_button:active:not([disabled]){transform:scale(.96)}.CUIYUW_button[disabled]{opacity:.45;cursor:not-allowed}.CUIYUW_buttonPrimary{background:linear-gradient(180deg, color-mix(in srgb, var(--nf-accent) 88%, #fff), var(--nf-accent));color:var(--nf-accent-fg);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);border-color:#0000}.CUIYUW_buttonPrimary:hover:not([disabled]){background:linear-gradient(180deg, var(--nf-accent-hover), color-mix(in srgb, var(--nf-accent-hover) 85%, #000));border-color:#0000}.CUIYUW_buttonDanger{border-color:var(--nf-error);color:var(--nf-error)}.CUIYUW_buttonDanger:hover:not([disabled]){background:#ff3b301a}.CUIYUW_buttonSmall{border-radius:9px;padding:3px 10px;font-size:12px}.CUIYUW_field{flex-direction:column;gap:5px;display:flex}.CUIYUW_fieldLabel{color:var(--nf-text-2);font-size:12px;font-weight:500}.CUIYUW_input{border:1px solid var(--nf-border-strong);background:var(--nf-bg-inset);color:var(--nf-text);box-sizing:border-box;border-radius:12px;width:100%;padding:7px 11px;font-size:13px;transition:border-color .15s,box-shadow .15s}.CUIYUW_input:focus,.CUIYUW_textarea:focus{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft);outline:none}.CUIYUW_input::placeholder,.CUIYUW_textarea::placeholder{color:var(--nf-text-3)}.CUIYUW_textarea{border:1px solid var(--nf-border-strong);background:var(--nf-bg-inset);color:var(--nf-text);box-sizing:border-box;resize:vertical;border-radius:12px;width:100%;min-height:200px;padding:9px 11px;font-family:inherit;font-size:13px;line-height:1.7;transition:border-color .15s,box-shadow .15s}.CUIYUW_row{flex-wrap:wrap;align-items:center;gap:8px;display:flex}.CUIYUW_spaceBetween{justify-content:space-between}.CUIYUW_chapterList{flex-direction:column;gap:8px;display:flex}.CUIYUW_volumeGroup{flex-direction:column;gap:6px;display:flex}.CUIYUW_volumeGroupHeader{background:var(--nf-bg-inset);border:1px solid var(--nf-border);cursor:pointer;user-select:none;border-radius:10px;align-items:center;gap:8px;padding:6px 10px;font-size:13px;transition:border-color .15s;display:flex}.CUIYUW_volumeGroupHeader:hover{border-color:var(--nf-accent)}.CUIYUW_volumeGroupToggle{color:var(--nf-text-2);flex:none;font-size:11px}.CUIYUW_chapter{border:1px solid var(--nf-border);background:var(--nf-bg);border-radius:10px;align-items:center;gap:10px;padding:9px 12px;transition:border-color .15s,box-shadow .15s,transform .1s;display:flex}.CUIYUW_chapter:hover{border-color:var(--nf-border-strong);box-shadow:var(--nf-shadow)}.CUIYUW_chapterNum{background:var(--nf-bg-inset);border:1px solid var(--nf-border);min-width:28px;height:28px;color:var(--nf-text-2);border-radius:8px;flex-shrink:0;justify-content:center;align-items:center;padding:0 8px;font-size:12px;font-weight:700;display:inline-flex}.CUIYUW_chapterMain{flex:1;min-width:0}.CUIYUW_chapterTitle{color:var(--nf-text);align-items:center;gap:8px;font-size:13px;font-weight:600;display:flex}.CUIYUW_chapterBeats{color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.CUIYUW_chapterActions{opacity:.85;flex-shrink:0;gap:4px;transition:opacity .15s;display:flex}.CUIYUW_chapter:hover .CUIYUW_chapterActions{opacity:1}.CUIYUW_badge{white-space:nowrap;letter-spacing:.2px;border:1px solid;border-radius:999px;padding:2px 9px;font-size:11px;font-weight:600}.CUIYUW_badgePending{color:var(--nf-info);border-color:var(--nf-info);background:color-mix(in srgb, var(--nf-info) 10%, transparent)}.CUIYUW_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 CUIYUW_pulse}.CUIYUW_badgeWritten{color:var(--nf-warn);border-color:var(--nf-warn);background:color-mix(in srgb, var(--nf-warn) 10%, transparent)}.CUIYUW_badgeRejected{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.CUIYUW_badgeDone{color:var(--nf-success);border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 10%, transparent)}.CUIYUW_badgeError{color:var(--nf-error);border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 10%, transparent)}.CUIYUW_reviewBox{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:10px;flex-direction:column;gap:6px;padding:10px 12px;font-size:12.5px;display:flex}.CUIYUW_chapterPreview{white-space:pre-wrap;word-break:break-all;max-height:320px;color:var(--nf-text);background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:10px;margin:0;padding:10px 12px;font-family:inherit;font-size:12.5px;line-height:1.8;overflow:auto}.CUIYUW_chatScroll{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:12px;flex-direction:column;flex:1;gap:10px;min-height:240px;max-height:480px;padding:14px;display:flex;overflow-y:auto}.CUIYUW_chatBubbleUser{background:linear-gradient(180deg, var(--nf-accent), var(--nf-accent-hover));max-width:90%;color:var(--nf-accent-fg);border-radius:14px 14px 4px;align-self:flex-end;padding:9px 14px;font-size:13px;box-shadow:0 2px 6px #4d6bfe33}.CUIYUW_chatBubbleAssistant{background:var(--nf-bg-raise);max-width:92%;color:var(--nf-text);border:1px solid var(--nf-border);box-shadow:var(--nf-shadow);border-radius:14px 14px 14px 4px;align-self:flex-start;padding:9px 14px;font-size:13px}.CUIYUW_chatRole{color:var(--nf-text-3);margin-bottom:3px;font-size:11px;font-weight:600}.CUIYUW_toolLive{background:var(--nf-bg-inset);border:1px dashed var(--nf-border-strong);white-space:pre-wrap;word-break:break-all;color:var(--nf-text-2);border-radius:8px;max-height:180px;margin-top:6px;padding:8px 10px;font-size:12px;line-height:1.7;overflow-y:auto}.CUIYUW_assistantStatus{color:var(--nf-text-2);background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:999px;flex:none;align-items:center;gap:6px;margin-top:6px;padding:6px 12px;font-size:12px;display:flex}.CUIYUW_assistantStatusBusy{color:var(--nf-accent);border-color:var(--nf-accent);background:var(--nf-accent-soft);font-weight:600}.CUIYUW_toolSteps{flex-direction:column;gap:4px;margin-top:6px;display:flex}.CUIYUW_toolStep{background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:8px;align-items:center;gap:8px;padding:5px 10px;font-size:12px;display:flex}.CUIYUW_toolStepActive{border-color:var(--nf-accent);background:var(--nf-accent-soft)}.CUIYUW_toolStepError{border-color:var(--nf-error);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.CUIYUW_toolStepIcon{flex:none;font-size:13px}.CUIYUW_toolStepName{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-weight:600;overflow:hidden}.CUIYUW_toolStepStatus{color:var(--nf-text-2);flex:none;font-size:11px}.CUIYUW_toolStepActive .CUIYUW_toolStepStatus{color:var(--nf-accent)}.CUIYUW_toolStepError .CUIYUW_toolStepStatus{color:var(--nf-error)}.CUIYUW_toolStepDetail{width:100%;color:var(--nf-error);word-break:break-all;font-size:11px}.CUIYUW_progress{border:1px solid var(--nf-border);white-space:pre-wrap;word-break:break-all;min-height:60px;max-height:220px;color:var(--nf-text-2);font-size:12px;font-family:var(--nf-font-mono);background:var(--nf-bg-inset);border-radius:10px;padding:10px 14px;line-height:1.8;overflow:auto}.CUIYUW_progressLine{color:var(--nf-text-2);opacity:.9}.CUIYUW_progressLineLive{color:var(--nf-accent);align-items:center;gap:8px;font-weight:600;display:flex}.CUIYUW_progressBar{background:var(--nf-border);border-radius:999px;flex:none;width:110px;height:6px;display:inline-block;overflow:hidden}.CUIYUW_progressBarFill{background:var(--nf-accent);border-radius:3px;height:100%;transition:width .3s;display:block}.CUIYUW_busyRow{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:12px;display:flex}.CUIYUW_liveText{font-variant-numeric:tabular-nums;color:var(--nf-text-2);font-size:12px}.CUIYUW_bigProgressBar{background:var(--nf-border);border-radius:999px;height:8px;margin-top:10px;overflow:hidden}.CUIYUW_bigProgressBarFill{background:linear-gradient(90deg, var(--nf-accent), var(--nf-accent-2,var(--nf-accent)));border-radius:999px;height:100%;transition:width .3s;display:block}.CUIYUW_diffLegend{flex-wrap:wrap;align-items:center;gap:14px;margin:6px 0 8px;font-size:12px;display:flex}.CUIYUW_legendOld{color:var(--nf-error);font-weight:700}.CUIYUW_legendNew{color:var(--nf-success);font-weight:700}.CUIYUW_onlyChanges{color:var(--nf-text-2);cursor:pointer;align-items:center;gap:4px;margin-left:auto;display:inline-flex}.CUIYUW_diffList{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:8px;flex-direction:column;flex:1;gap:8px;min-height:0;padding:10px 12px;font-size:13px;line-height:1.7;display:flex;overflow-y:auto}.CUIYUW_diffSame{border:1px dashed var(--nf-border);color:var(--nf-text-2);opacity:.85;border-radius:6px;padding:6px 10px}.CUIYUW_diffSame summary{cursor:pointer;user-select:none;font-size:12px}.CUIYUW_diffSameBody{white-space:pre-wrap;margin-top:6px}.CUIYUW_diffChange{border:1px solid var(--nf-border);border-radius:8px;grid-template-columns:1fr 1fr;display:grid;overflow:hidden}.CUIYUW_diffColumn{flex-direction:column;gap:6px;min-width:0;padding:8px 10px;display:flex}.CUIYUW_diffColumn:first-child{border-right:1px solid var(--nf-border)}.CUIYUW_diffTagOld,.CUIYUW_diffTagNew{letter-spacing:.5px;border-radius:4px;flex:none;align-self:flex-start;padding:1px 7px;font-size:11px;font-weight:700}.CUIYUW_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)}.CUIYUW_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)}.CUIYUW_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)}.CUIYUW_diffNew{color:var(--nf-success);white-space:pre-wrap;font-weight:500}.CUIYUW_diffDel{border:1px solid color-mix(in srgb, var(--nf-error) 35%, transparent);background:color-mix(in srgb, var(--nf-error) 7%, transparent);border-radius:6px;flex-direction:column;gap:4px;padding:6px 10px;display:flex}.CUIYUW_diffAdd{border:1px solid color-mix(in srgb, var(--nf-success) 35%, transparent);background:color-mix(in srgb, var(--nf-success) 7%, transparent);border-radius:6px;flex-direction:column;gap:4px;padding:6px 10px;display:flex}.CUIYUW_diffText{white-space:pre-wrap}.CUIYUW_diffDel .CUIYUW_diffText{color:var(--nf-error);text-decoration:line-through;text-decoration-color:color-mix(in srgb, var(--nf-error) 50%, transparent)}.CUIYUW_diffAdd .CUIYUW_diffText{color:var(--nf-success)}.CUIYUW_wsPage{flex-direction:column;flex:1;gap:10px;min-height:0;display:flex}.CUIYUW_wsPageHeader{flex-wrap:wrap;flex:none;align-items:center;gap:8px;display:flex}.CUIYUW_wsColumns{flex:1;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px;min-height:0;display:grid}.CUIYUW_wsColumn{flex-direction:column;gap:8px;min-width:0;min-height:0;display:flex}.CUIYUW_wsEditor{resize:vertical;min-height:0;font-family:var(--nf-font);white-space:pre-wrap;flex:1;font-size:13px;line-height:1.75}.CUIYUW_wsSelected{border:1px solid var(--nf-accent);background:color-mix(in srgb, var(--nf-accent) 8%, transparent);border-radius:6px;max-height:120px;padding:6px 10px;overflow:auto}.CUIYUW_wsSelectedText{color:var(--nf-text-2);white-space:pre-wrap;margin-top:4px;font-size:12px}.CUIYUW_wsPreview{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:8px;flex-direction:column;gap:8px;padding:8px 10px;display:flex}.CUIYUW_wsPreviewText{white-space:pre-wrap;min-height:0;color:var(--nf-text);flex:1;margin:0;font-size:13px;line-height:1.7;overflow:auto}.CUIYUW_assetGrid{grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px;display:grid}.CUIYUW_assetStat{border:1px solid var(--nf-glass-border);background:var(--nf-glass-inset);box-shadow:inset 0 1px 0 var(--nf-glass-sheen);border-radius:14px;flex-direction:column;gap:4px;padding:10px 12px;display:flex}.CUIYUW_assetStatLabel{color:var(--nf-text-2);opacity:.9;font-size:11px}.CUIYUW_assetStatValue{color:var(--nf-text);font-size:15px;font-weight:700;line-height:1.2}.CUIYUW_assetStatDetail{color:var(--nf-text-2);opacity:.85;text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.CUIYUW_dashHero{border:1px solid var(--nf-glass-border);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%);border-radius:22px;flex-direction:column;gap:14px;padding:18px 20px;transition:transform .22s,box-shadow .22s;display:flex;position:relative}.CUIYUW_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}.CUIYUW_dashHero:after{content:\"\";border-radius:inherit;pointer-events:none;background:var(--nf-glass-noise);opacity:.06;z-index:0;position:absolute;inset:0}.CUIYUW_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)}.CUIYUW_dashHero>*{z-index:1;position:relative}.CUIYUW_dashHeroEyebrow{color:var(--nf-accent);align-items:center;gap:6px;font-size:13px;font-weight:600;display:inline-flex}.CUIYUW_dashHeroSparkle{font-size:14px}.CUIYUW_dashHeroTitle{flex-direction:column;gap:2px;display:flex}.CUIYUW_dashHeroBook{letter-spacing:-.3px;margin:0;font-size:24px;font-weight:700;line-height:1.25}.CUIYUW_dashHeroAction{border:1px solid var(--nf-glass-border);background:var(--nf-glass-inset);box-shadow:inset 0 1px 0 var(--nf-glass-sheen);border-radius:14px;align-items:center;gap:12px;padding:10px 14px;display:flex}.CUIYUW_dashHeroArrow{background:var(--nf-accent);color:#fff;border-radius:50%;flex:none;justify-content:center;align-items:center;width:28px;height:28px;font-size:14px;display:inline-flex}.CUIYUW_dashHeroActionBody{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.CUIYUW_dashHeroActionTitle{font-size:14px;font-weight:600}.CUIYUW_dashJourney{flex-direction:column;gap:6px;display:flex}.CUIYUW_dashJourneyBar{background:var(--nf-border);border-radius:999px;height:6px;overflow:hidden}.CUIYUW_dashJourneyFill{background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));border-radius:999px;height:100%;transition:width .4s;display:block}.CUIYUW_dashJourneyStages{grid-template-columns:repeat(6,minmax(0,1fr));gap:4px;display:grid}.CUIYUW_dashStage{color:var(--nf-text-3);text-align:center;white-space:nowrap;flex-direction:column;align-items:center;gap:3px;font-size:11px;display:flex}.CUIYUW_dashStageDot{border:1px solid var(--nf-border-strong,var(--nf-text-3));background:var(--nf-bg-base);border-radius:50%;justify-content:center;align-items:center;width:18px;height:18px;font-size:10px;display:inline-flex}.CUIYUW_dashStageDone{color:var(--nf-text-2)}.CUIYUW_dashStageDone .CUIYUW_dashStageDot{background:var(--nf-success);border-color:var(--nf-success);color:#fff}.CUIYUW_dashStageCurrent{color:var(--nf-accent);font-weight:600}.CUIYUW_dashStageCurrent .CUIYUW_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)}.CUIYUW_dashFacts{border-top:1px solid var(--nf-border);grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;padding-top:12px;display:grid}.CUIYUW_dashFact{flex-direction:column;gap:2px;min-width:0;display:flex}.CUIYUW_dashFact b{white-space:nowrap;text-overflow:ellipsis;font-size:13px;overflow:hidden}.CUIYUW_dashGrid{grid-template-columns:minmax(0,3fr) minmax(0,2fr);align-items:start;gap:14px;display:grid}.CUIYUW_todoItem{border:1px solid var(--nf-border);border-radius:8px;align-items:center;gap:10px;padding:8px 12px;font-size:12.5px;display:flex}.CUIYUW_todoDanger{border-color:color-mix(in srgb, var(--nf-error) 40%, transparent);background:color-mix(in srgb, var(--nf-error) 8%, transparent)}.CUIYUW_todoWarning{border-color:color-mix(in srgb, var(--nf-warn) 40%, transparent);background:color-mix(in srgb, var(--nf-warn) 8%, transparent)}.CUIYUW_todoInfo{border-color:color-mix(in srgb, var(--nf-info) 40%, transparent);background:color-mix(in srgb, var(--nf-info) 7%, transparent)}.CUIYUW_todoText{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.CUIYUW_outlineReadonly{border:1px solid var(--nf-border);background:var(--nf-bg-inset);white-space:pre-wrap;user-select:text;border-radius:12px;max-height:480px;margin:0;padding:12px 14px;font-size:12.5px;line-height:1.8;overflow:auto}.CUIYUW_bookCreateOutline{flex-direction:column;align-items:flex-start;gap:6px;display:flex}.CUIYUW_assistantFloat{z-index:80;border:1px solid var(--nf-border);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow-lg);border-radius:16px;flex-direction:column;min-width:320px;min-height:220px;display:flex;position:absolute;overflow:hidden}.CUIYUW_assistantFloatHeader{cursor:grab;user-select:none;border-bottom:1px solid var(--nf-border);background:var(--nf-bg-inset);flex:none;justify-content:space-between;align-items:center;gap:8px;padding:8px 10px 8px 14px;font-size:13px;font-weight:600;display:flex}.CUIYUW_assistantFloatHeader:active{cursor:grabbing}.CUIYUW_assistantFloatBody{flex:1;min-height:0;padding:10px;display:flex;overflow:hidden}.CUIYUW_assistantFloatBody>*{flex:1;min-width:0}.CUIYUW_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}.CUIYUW_coverPreview{border:1px solid var(--nf-border);background:var(--nf-bg-inset);border-radius:12px;flex:none;justify-content:center;align-items:center;width:150px;height:200px;display:flex;overflow:hidden}.CUIYUW_coverPreview img{object-fit:contain;width:100%;height:100%;display:block}.CUIYUW_coverPlaceholder{color:var(--nf-text-3);font-size:12px}.CUIYUW_shelfView{flex-direction:column;flex:1;gap:16px;min-height:0;padding:18px;display:flex;overflow:auto}.CUIYUW_shelfHeader{flex-direction:column;gap:2px;display:flex}.CUIYUW_shelfGrid{grid-template-columns:repeat(auto-fill,minmax(190px,1fr));align-content:start;gap:14px;display:grid}.CUIYUW_bookCard{border:1px solid var(--nf-border);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);box-shadow:var(--nf-shadow);cursor:pointer;border-radius:16px;flex-direction:column;gap:8px;padding:12px;transition:border-color .15s,transform .1s,box-shadow .15s;display:flex}.CUIYUW_bookCard:hover{border-color:var(--nf-accent);box-shadow:var(--nf-shadow-lg);transform:translateY(-2px)}.CUIYUW_bookCardActive{border-color:var(--nf-accent);box-shadow:0 0 0 3px var(--nf-accent-soft)}.CUIYUW_bookCardCover{aspect-ratio:3/4;background:var(--nf-bg-inset);border:1px solid var(--nf-border);border-radius:12px;flex:none;justify-content:center;align-items:center;display:flex;overflow:hidden}.CUIYUW_bookCardCover img{object-fit:contain;width:100%;height:100%;display:block}.CUIYUW_bookCardCoverFallback{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;justify-content:center;align-items:center;gap:6px;width:100%;height:100%;display:flex}.CUIYUW_bookCardCoverTitle{color:var(--nf-accent);letter-spacing:2px;font-size:22px;font-weight:800}.CUIYUW_bookCardBody{flex-direction:column;gap:5px;min-width:0;display:flex}.CUIYUW_bookCardTitleRow{justify-content:space-between;align-items:center;gap:6px;display:flex}.CUIYUW_bookCardName{text-overflow:ellipsis;white-space:nowrap;font-size:13.5px;font-weight:700;overflow:hidden}.CUIYUW_bookCardBlurb{-webkit-line-clamp:2;-webkit-box-orient:vertical;min-height:34px;display:-webkit-box;overflow:hidden}.CUIYUW_bookCardProgressBar{background:var(--nf-border);border-radius:999px;height:5px;overflow:hidden}.CUIYUW_bookCardProgressFill{background:linear-gradient(90deg, var(--nf-info), var(--nf-accent));border-radius:999px;height:100%;transition:width .3s;display:block}.CUIYUW_bookAddCard{text-align:center;color:var(--nf-text-2);border-style:dashed;justify-content:center;align-items:center;gap:8px;min-height:260px}.CUIYUW_bookAddCard:hover{color:var(--nf-accent)}.CUIYUW_bookAddIcon{color:var(--nf-accent);font-size:34px;line-height:1}.CUIYUW_bookCreateCard{border-color:var(--nf-accent);min-height:260px}.CUIYUW_createBookView{flex-direction:column;flex:1;gap:14px;min-height:0;padding:14px 18px 24px;display:flex;overflow:auto}.CUIYUW_createBookTop{align-items:center;display:flex}.CUIYUW_createBookCard{border:1px solid var(--nf-border);background:var(--nf-bg-raise);backdrop-filter:blur(24px)saturate(180%);width:min(520px,100%);box-shadow:var(--nf-shadow-lg);border-radius:20px;flex-direction:column;align-self:center;gap:12px;padding:26px 28px;display:flex}.CUIYUW_createBookIcon{font-size:34px;line-height:1}.CUIYUW_createBookTitle{letter-spacing:-.3px;margin:0;font-size:22px;font-weight:800}.CUIYUW_progressLineDone{color:var(--nf-success);font-weight:600}.CUIYUW_progressLineError{color:var(--nf-error);font-weight:600}.CUIYUW_meta{color:var(--nf-text-2);opacity:.9;font-size:12px}.CUIYUW_genreDesc{-webkit-line-clamp:2;-webkit-box-orient:vertical;max-width:560px;display:-webkit-box;overflow:hidden}.CUIYUW_fileList{color:var(--nf-text-2);opacity:.9;word-break:break-all;flex-direction:column;gap:3px;font-size:12px;display:flex}.CUIYUW_panelContent::-webkit-scrollbar,.CUIYUW_chatScroll::-webkit-scrollbar,.CUIYUW_chapterPreview::-webkit-scrollbar,.CUIYUW_progress::-webkit-scrollbar,.CUIYUW_toolLive::-webkit-scrollbar{width:8px;height:8px}.CUIYUW_panelContent::-webkit-scrollbar-thumb,.CUIYUW_chatScroll::-webkit-scrollbar-thumb,.CUIYUW_chapterPreview::-webkit-scrollbar-thumb,.CUIYUW_progress::-webkit-scrollbar-thumb,.CUIYUW_toolLive::-webkit-scrollbar-thumb{background:var(--nf-border-strong);border-radius:4px}.CUIYUW_panelContent::-webkit-scrollbar-thumb:hover,.CUIYUW_chatScroll::-webkit-scrollbar-thumb:hover,.CUIYUW_chapterPreview::-webkit-scrollbar-thumb:hover,.CUIYUW_progress::-webkit-scrollbar-thumb:hover,.CUIYUW_toolLive::-webkit-scrollbar-thumb:hover{background:var(--nf-text-3)}.CUIYUW_workflowList{flex-direction:column;gap:0;display:flex}.CUIYUW_workflowRow{align-items:flex-start;gap:12px;padding:8px 4px;display:flex;position:relative}.CUIYUW_workflowRow:before{content:\"\";background:var(--nf-border);width:2px;position:absolute;top:34px;bottom:-8px;left:13px}.CUIYUW_workflowRow:last-child:before{display:none}.CUIYUW_workflowDot{border:2px solid var(--nf-border-strong);background:var(--nf-bg-raise);width:28px;height:28px;color:var(--nf-text-2);z-index:1;border-radius:50%;flex-shrink:0;justify-content:center;align-items:center;font-size:12px;font-weight:700;display:inline-flex}.CUIYUW_workflowDotDone{border-color:var(--nf-success);background:color-mix(in srgb, var(--nf-success) 15%, var(--nf-bg-raise));color:var(--nf-success)}.CUIYUW_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)}.CUIYUW_workflowBody{flex-direction:column;flex:1;gap:4px;min-width:0;padding-top:2px;display:flex}.CUIYUW_workflowLabel{color:var(--nf-text);font-size:13px;font-weight:600}.CUIYUW_workflowHint{color:var(--nf-text-2);font-size:12px}@keyframes CUIYUW_pulse{0%,to{opacity:1}50%{opacity:.45}}@keyframes CUIYUW_fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.CUIYUW_card{animation:.2s CUIYUW_fadeIn}.CUIYUW_bookshelf{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);backdrop-filter:blur(26px)saturate(175%);z-index:1;border-radius:16px;flex-wrap:wrap;flex-shrink:0;align-items:center;gap:10px;margin:10px 12px 0;padding:8px 14px;display:flex;position:relative}.CUIYUW_bookshelfLabel{color:var(--nf-text-3);letter-spacing:1px;flex-shrink:0;font-size:12px;font-weight:700}.CUIYUW_bookshelfList{flex-wrap:wrap;flex:1;align-items:center;gap:6px;min-width:0;display:flex}.CUIYUW_bookChip{border:1px solid var(--nf-border);background:var(--nf-bg-inset);cursor:pointer;border-radius:999px;align-items:center;gap:6px;max-width:220px;padding:4px 8px 4px 10px;font-size:12px;transition:border-color .15s,background .15s;display:flex}.CUIYUW_bookChip:hover{border-color:var(--nf-border-strong)}.CUIYUW_bookChipActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.CUIYUW_bookChipName{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.CUIYUW_bookChipMeta{opacity:.7;white-space:nowrap;font-size:11px}.CUIYUW_bookChipRemove{color:var(--nf-text-3);cursor:pointer;background:0 0;border:none;border-radius:4px;padding:0 2px;font-size:13px;line-height:1}.CUIYUW_bookChipRemove:hover{color:var(--nf-error)}.CUIYUW_bookAdd{border:1px dashed var(--nf-border-strong);color:var(--nf-text-2);cursor:pointer;background:0 0;border-radius:999px;padding:4px 12px;font-size:12px;transition:border-color .15s,color .15s}.CUIYUW_bookAdd:hover{border-color:var(--nf-accent);color:var(--nf-accent)}.CUIYUW_bookCreateForm{align-items:center;gap:6px;display:flex}.CUIYUW_dropzone{border:2px dashed var(--nf-border-strong);text-align:center;color:var(--nf-text-2);cursor:pointer;border-radius:10px;flex-direction:column;align-items:center;gap:6px;padding:18px 14px;font-size:13px;transition:border-color .15s,background .15s;display:flex}.CUIYUW_dropzone:hover,.CUIYUW_dropzoneActive{border-color:var(--nf-accent);background:var(--nf-accent-soft);color:var(--nf-accent)}.CUIYUW_dropzoneIcon{font-size:22px;line-height:1}";
|
|
@@ -765,205 +826,205 @@ window.__ModuleLoader__.load({
|
|
|
765
826
|
document.head.appendChild(tag);
|
|
766
827
|
}
|
|
767
828
|
var panel_module_css_default = {
|
|
768
|
-
"
|
|
769
|
-
"progressBar": "CUIYUW_progressBar",
|
|
770
|
-
"navAboutUpdate": "CUIYUW_navAboutUpdate",
|
|
771
|
-
"progressLineDone": "CUIYUW_progressLineDone",
|
|
772
|
-
"cardTitle": "CUIYUW_cardTitle",
|
|
773
|
-
"buttonPrimary": "CUIYUW_buttonPrimary",
|
|
774
|
-
"dashJourney": "CUIYUW_dashJourney",
|
|
775
|
-
"volumeGroup": "CUIYUW_volumeGroup",
|
|
776
|
-
"chatScroll": "CUIYUW_chatScroll",
|
|
777
|
-
"toolSteps": "CUIYUW_toolSteps",
|
|
778
|
-
"createBookTitle": "CUIYUW_createBookTitle",
|
|
779
|
-
"coverPreview": "CUIYUW_coverPreview",
|
|
780
|
-
"dashStage": "CUIYUW_dashStage",
|
|
781
|
-
"legendNew": "CUIYUW_legendNew",
|
|
782
|
-
"dashJourneyBar": "CUIYUW_dashJourneyBar",
|
|
829
|
+
"diffNew": "CUIYUW_diffNew",
|
|
783
830
|
"outlineReadonly": "CUIYUW_outlineReadonly",
|
|
784
|
-
"
|
|
785
|
-
"
|
|
786
|
-
"badgeError": "CUIYUW_badgeError",
|
|
831
|
+
"workflowDot": "CUIYUW_workflowDot",
|
|
832
|
+
"panel": "CUIYUW_panel",
|
|
787
833
|
"dashStageCurrent": "CUIYUW_dashStageCurrent",
|
|
834
|
+
"todoInfo": "CUIYUW_todoInfo",
|
|
835
|
+
"dropzone": "CUIYUW_dropzone",
|
|
836
|
+
"navTab": "CUIYUW_navTab",
|
|
837
|
+
"createBookTitle": "CUIYUW_createBookTitle",
|
|
838
|
+
"dashHeroActionTitle": "CUIYUW_dashHeroActionTitle",
|
|
839
|
+
"dashJourneyFill": "CUIYUW_dashJourneyFill",
|
|
840
|
+
"textarea": "CUIYUW_textarea",
|
|
841
|
+
"assistantFloatBody": "CUIYUW_assistantFloatBody",
|
|
842
|
+
"bookChip": "CUIYUW_bookChip",
|
|
843
|
+
"bookChipActive": "CUIYUW_bookChipActive",
|
|
788
844
|
"toolStep": "CUIYUW_toolStep",
|
|
845
|
+
"diffList": "CUIYUW_diffList",
|
|
846
|
+
"dashJourneyBar": "CUIYUW_dashJourneyBar",
|
|
789
847
|
"navGroupSep": "CUIYUW_navGroupSep",
|
|
790
|
-
"
|
|
791
|
-
"diffAdd": "CUIYUW_diffAdd",
|
|
792
|
-
"wsSelected": "CUIYUW_wsSelected",
|
|
793
|
-
"todoInfo": "CUIYUW_todoInfo",
|
|
794
|
-
"panelSubtitle": "CUIYUW_panelSubtitle",
|
|
848
|
+
"panelNavCollapsed": "CUIYUW_panelNavCollapsed",
|
|
795
849
|
"meta": "CUIYUW_meta",
|
|
796
|
-
"
|
|
850
|
+
"workflowDotActive": "CUIYUW_workflowDotActive",
|
|
851
|
+
"workflowBody": "CUIYUW_workflowBody",
|
|
852
|
+
"chatBubbleUser": "CUIYUW_chatBubbleUser",
|
|
853
|
+
"chapterPreview": "CUIYUW_chapterPreview",
|
|
854
|
+
"assetGrid": "CUIYUW_assetGrid",
|
|
855
|
+
"navSpacer": "CUIYUW_navSpacer",
|
|
856
|
+
"todoDanger": "CUIYUW_todoDanger",
|
|
857
|
+
"bookCardCover": "CUIYUW_bookCardCover",
|
|
797
858
|
"chapterTitle": "CUIYUW_chapterTitle",
|
|
859
|
+
"assetStat": "CUIYUW_assetStat",
|
|
860
|
+
"navAboutUpdate": "CUIYUW_navAboutUpdate",
|
|
861
|
+
"badge": "CUIYUW_badge",
|
|
862
|
+
"entry": "CUIYUW_entry",
|
|
798
863
|
"diffText": "CUIYUW_diffText",
|
|
799
|
-
"
|
|
800
|
-
"
|
|
801
|
-
"
|
|
802
|
-
"
|
|
864
|
+
"panelSubtitle": "CUIYUW_panelSubtitle",
|
|
865
|
+
"badgePending": "CUIYUW_badgePending",
|
|
866
|
+
"progressLineDone": "CUIYUW_progressLineDone",
|
|
867
|
+
"panelTitle": "CUIYUW_panelTitle",
|
|
803
868
|
"assistantStatusBusy": "CUIYUW_assistantStatusBusy",
|
|
804
|
-
"
|
|
805
|
-
"
|
|
806
|
-
"
|
|
807
|
-
"
|
|
808
|
-
"chapterMain": "CUIYUW_chapterMain",
|
|
809
|
-
"busyRow": "CUIYUW_busyRow",
|
|
810
|
-
"diffTagNew": "CUIYUW_diffTagNew",
|
|
811
|
-
"bookCardName": "CUIYUW_bookCardName",
|
|
812
|
-
"button": "CUIYUW_button",
|
|
813
|
-
"dashStageDone": "CUIYUW_dashStageDone",
|
|
814
|
-
"navTabIcon": "CUIYUW_navTabIcon",
|
|
815
|
-
"bookChipName": "CUIYUW_bookChipName",
|
|
816
|
-
"badge": "CUIYUW_badge",
|
|
817
|
-
"navTabBadgeWarn": "CUIYUW_navTabBadgeWarn",
|
|
818
|
-
"tab": "CUIYUW_tab",
|
|
819
|
-
"navTabLabel": "CUIYUW_navTabLabel",
|
|
820
|
-
"bigProgressBarFill": "CUIYUW_bigProgressBarFill",
|
|
821
|
-
"wsPageHeader": "CUIYUW_wsPageHeader",
|
|
822
|
-
"navTabBadge": "CUIYUW_navTabBadge",
|
|
823
|
-
"dashHeroBook": "CUIYUW_dashHeroBook",
|
|
824
|
-
"toolStepName": "CUIYUW_toolStepName",
|
|
825
|
-
"todoItem": "CUIYUW_todoItem",
|
|
826
|
-
"coverPlaceholder": "CUIYUW_coverPlaceholder",
|
|
827
|
-
"createBookTop": "CUIYUW_createBookTop",
|
|
828
|
-
"navTabBadgeDanger": "CUIYUW_navTabBadgeDanger",
|
|
829
|
-
"dashHeroEyebrow": "CUIYUW_dashHeroEyebrow",
|
|
869
|
+
"headerProgress": "CUIYUW_headerProgress",
|
|
870
|
+
"bookAdd": "CUIYUW_bookAdd",
|
|
871
|
+
"progressLine": "CUIYUW_progressLine",
|
|
872
|
+
"dashStage": "CUIYUW_dashStage",
|
|
830
873
|
"toolStepStatus": "CUIYUW_toolStepStatus",
|
|
831
|
-
"
|
|
832
|
-
"
|
|
833
|
-
"
|
|
834
|
-
"assistantFloatHeader": "CUIYUW_assistantFloatHeader",
|
|
835
|
-
"chapterBeats": "CUIYUW_chapterBeats",
|
|
836
|
-
"workflowDotActive": "CUIYUW_workflowDotActive",
|
|
837
|
-
"iconButton": "CUIYUW_iconButton",
|
|
838
|
-
"assistantStatus": "CUIYUW_assistantStatus",
|
|
839
|
-
"workflowHint": "CUIYUW_workflowHint",
|
|
840
|
-
"bookChipActive": "CUIYUW_bookChipActive",
|
|
841
|
-
"entry": "CUIYUW_entry",
|
|
842
|
-
"badgeDone": "CUIYUW_badgeDone",
|
|
843
|
-
"diffSameBody": "CUIYUW_diffSameBody",
|
|
844
|
-
"shelfView": "CUIYUW_shelfView",
|
|
845
|
-
"workflowBody": "CUIYUW_workflowBody",
|
|
846
|
-
"buttonSmall": "CUIYUW_buttonSmall",
|
|
847
|
-
"assetStat": "CUIYUW_assetStat",
|
|
874
|
+
"dashStageDot": "CUIYUW_dashStageDot",
|
|
875
|
+
"input": "CUIYUW_input",
|
|
876
|
+
"diffChange": "CUIYUW_diffChange",
|
|
848
877
|
"field": "CUIYUW_field",
|
|
849
|
-
"
|
|
850
|
-
"
|
|
851
|
-
"progressLine": "CUIYUW_progressLine",
|
|
852
|
-
"chapterActions": "CUIYUW_chapterActions",
|
|
853
|
-
"progressBarFill": "CUIYUW_progressBarFill",
|
|
854
|
-
"bookshelf": "CUIYUW_bookshelf",
|
|
855
|
-
"assetGrid": "CUIYUW_assetGrid",
|
|
856
|
-
"navAbout": "CUIYUW_navAbout",
|
|
857
|
-
"badgeRejected": "CUIYUW_badgeRejected",
|
|
878
|
+
"headerProgressDot": "CUIYUW_headerProgressDot",
|
|
879
|
+
"toolSteps": "CUIYUW_toolSteps",
|
|
858
880
|
"assetStatValue": "CUIYUW_assetStatValue",
|
|
859
|
-
"
|
|
860
|
-
"
|
|
861
|
-
"bookCardProgressBar": "CUIYUW_bookCardProgressBar",
|
|
862
|
-
"badgePending": "CUIYUW_badgePending",
|
|
881
|
+
"reviewBox": "CUIYUW_reviewBox",
|
|
882
|
+
"dashFacts": "CUIYUW_dashFacts",
|
|
863
883
|
"dashHeroActionBody": "CUIYUW_dashHeroActionBody",
|
|
864
|
-
"
|
|
865
|
-
"shelfGrid": "CUIYUW_shelfGrid",
|
|
866
|
-
"entryLabel": "CUIYUW_entryLabel",
|
|
867
|
-
"bookCardCoverFallback": "CUIYUW_bookCardCoverFallback",
|
|
868
|
-
"textarea": "CUIYUW_textarea",
|
|
869
|
-
"diffOld": "CUIYUW_diffOld",
|
|
870
|
-
"headerProgress": "CUIYUW_headerProgress",
|
|
871
|
-
"assistantFloatBody": "CUIYUW_assistantFloatBody",
|
|
872
|
-
"todoDanger": "CUIYUW_todoDanger",
|
|
873
|
-
"chatBubbleAssistant": "CUIYUW_chatBubbleAssistant",
|
|
874
|
-
"wsColumn": "CUIYUW_wsColumn",
|
|
875
|
-
"wsEditor": "CUIYUW_wsEditor",
|
|
876
|
-
"diffList": "CUIYUW_diffList",
|
|
877
|
-
"liveText": "CUIYUW_liveText",
|
|
878
|
-
"progressLineLive": "CUIYUW_progressLineLive",
|
|
879
|
-
"wsPreview": "CUIYUW_wsPreview",
|
|
884
|
+
"bookCard": "CUIYUW_bookCard",
|
|
880
885
|
"assetStatLabel": "CUIYUW_assetStatLabel",
|
|
881
|
-
"
|
|
882
|
-
"dashHeroSparkle": "CUIYUW_dashHeroSparkle",
|
|
883
|
-
"bookCardProgressFill": "CUIYUW_bookCardProgressFill",
|
|
884
|
-
"bookAddIcon": "CUIYUW_bookAddIcon",
|
|
885
|
-
"workflowList": "CUIYUW_workflowList",
|
|
886
|
-
"chatBubbleUser": "CUIYUW_chatBubbleUser",
|
|
887
|
-
"bigProgressBar": "CUIYUW_bigProgressBar",
|
|
888
|
-
"dashHeroActionTitle": "CUIYUW_dashHeroActionTitle",
|
|
889
|
-
"bookCardTitleRow": "CUIYUW_bookCardTitleRow",
|
|
886
|
+
"bookAddCard": "CUIYUW_bookAddCard",
|
|
890
887
|
"diffDel": "CUIYUW_diffDel",
|
|
891
|
-
"dashHeroArrow": "CUIYUW_dashHeroArrow",
|
|
892
|
-
"progressLineError": "CUIYUW_progressLineError",
|
|
893
|
-
"wsColumns": "CUIYUW_wsColumns",
|
|
894
|
-
"fadeIn": "CUIYUW_fadeIn",
|
|
895
|
-
"bookChipMeta": "CUIYUW_bookChipMeta",
|
|
896
|
-
"toolLive": "CUIYUW_toolLive",
|
|
897
888
|
"createBookView": "CUIYUW_createBookView",
|
|
898
|
-
"
|
|
899
|
-
"
|
|
900
|
-
"
|
|
901
|
-
"
|
|
889
|
+
"cardTitle": "CUIYUW_cardTitle",
|
|
890
|
+
"bookChipName": "CUIYUW_bookChipName",
|
|
891
|
+
"chatRole": "CUIYUW_chatRole",
|
|
892
|
+
"workflowList": "CUIYUW_workflowList",
|
|
893
|
+
"progress": "CUIYUW_progress",
|
|
894
|
+
"entryLabel": "CUIYUW_entryLabel",
|
|
895
|
+
"chapterBeats": "CUIYUW_chapterBeats",
|
|
896
|
+
"card": "CUIYUW_card",
|
|
902
897
|
"badgeWritten": "CUIYUW_badgeWritten",
|
|
903
|
-
"
|
|
904
|
-
"
|
|
905
|
-
"
|
|
906
|
-
"
|
|
907
|
-
"
|
|
908
|
-
"
|
|
909
|
-
"
|
|
898
|
+
"onlyChanges": "CUIYUW_onlyChanges",
|
|
899
|
+
"diffTagOld": "CUIYUW_diffTagOld",
|
|
900
|
+
"navTabIcon": "CUIYUW_navTabIcon",
|
|
901
|
+
"liveText": "CUIYUW_liveText",
|
|
902
|
+
"diffSameBody": "CUIYUW_diffSameBody",
|
|
903
|
+
"wsColumns": "CUIYUW_wsColumns",
|
|
904
|
+
"dashStageDone": "CUIYUW_dashStageDone",
|
|
905
|
+
"bookCardBlurb": "CUIYUW_bookCardBlurb",
|
|
906
|
+
"createBookCard": "CUIYUW_createBookCard",
|
|
907
|
+
"spaceBetween": "CUIYUW_spaceBetween",
|
|
908
|
+
"diffLegend": "CUIYUW_diffLegend",
|
|
910
909
|
"dashHero": "CUIYUW_dashHero",
|
|
911
|
-
"
|
|
912
|
-
"
|
|
913
|
-
"panelHeader": "CUIYUW_panelHeader",
|
|
914
|
-
"badgeGenerating": "CUIYUW_badgeGenerating",
|
|
915
|
-
"entryIcon": "CUIYUW_entryIcon",
|
|
916
|
-
"assetStatDetail": "CUIYUW_assetStatDetail",
|
|
917
|
-
"workflowRow": "CUIYUW_workflowRow",
|
|
918
|
-
"workflowDot": "CUIYUW_workflowDot",
|
|
919
|
-
"navSpacer": "CUIYUW_navSpacer",
|
|
910
|
+
"createBookTop": "CUIYUW_createBookTop",
|
|
911
|
+
"bookCardName": "CUIYUW_bookCardName",
|
|
920
912
|
"fileList": "CUIYUW_fileList",
|
|
921
|
-
"
|
|
922
|
-
"
|
|
923
|
-
"
|
|
924
|
-
"panelNavCollapsed": "CUIYUW_panelNavCollapsed",
|
|
925
|
-
"dashHeroTitle": "CUIYUW_dashHeroTitle",
|
|
926
|
-
"bookCard": "CUIYUW_bookCard",
|
|
927
|
-
"diffChange": "CUIYUW_diffChange",
|
|
913
|
+
"assistantStatus": "CUIYUW_assistantStatus",
|
|
914
|
+
"workflowHint": "CUIYUW_workflowHint",
|
|
915
|
+
"bookCreateForm": "CUIYUW_bookCreateForm",
|
|
928
916
|
"wsPreviewText": "CUIYUW_wsPreviewText",
|
|
929
|
-
"
|
|
930
|
-
"
|
|
917
|
+
"assetStatDetail": "CUIYUW_assetStatDetail",
|
|
918
|
+
"chapterActions": "CUIYUW_chapterActions",
|
|
919
|
+
"dashHeroBook": "CUIYUW_dashHeroBook",
|
|
920
|
+
"dashGrid": "CUIYUW_dashGrid",
|
|
921
|
+
"coverPreview": "CUIYUW_coverPreview",
|
|
931
922
|
"panelNav": "CUIYUW_panelNav",
|
|
932
|
-
"panelBody": "CUIYUW_panelBody",
|
|
933
|
-
"toolStepIcon": "CUIYUW_toolStepIcon",
|
|
934
|
-
"legendOld": "CUIYUW_legendOld",
|
|
935
|
-
"bookCardBlurb": "CUIYUW_bookCardBlurb",
|
|
936
|
-
"todoText": "CUIYUW_todoText",
|
|
937
|
-
"progress": "CUIYUW_progress",
|
|
938
|
-
"diffColumn": "CUIYUW_diffColumn",
|
|
939
|
-
"headerProgressDot": "CUIYUW_headerProgressDot",
|
|
940
|
-
"pulse": "CUIYUW_pulse",
|
|
941
|
-
"onlyChanges": "CUIYUW_onlyChanges",
|
|
942
|
-
"diffLegend": "CUIYUW_diffLegend",
|
|
943
|
-
"dashHeroAction": "CUIYUW_dashHeroAction",
|
|
944
|
-
"row": "CUIYUW_row",
|
|
945
|
-
"dashStageDot": "CUIYUW_dashStageDot",
|
|
946
|
-
"card": "CUIYUW_card",
|
|
947
|
-
"createBookCard": "CUIYUW_createBookCard",
|
|
948
|
-
"workflowLabel": "CUIYUW_workflowLabel",
|
|
949
923
|
"bookChipRemove": "CUIYUW_bookChipRemove",
|
|
950
|
-
"
|
|
951
|
-
"
|
|
952
|
-
"
|
|
953
|
-
"
|
|
954
|
-
"panelContent": "CUIYUW_panelContent",
|
|
955
|
-
"toolStepActive": "CUIYUW_toolStepActive",
|
|
956
|
-
"wsPage": "CUIYUW_wsPage",
|
|
957
|
-
"chapterPreview": "CUIYUW_chapterPreview",
|
|
958
|
-
"tabBar": "CUIYUW_tabBar",
|
|
924
|
+
"dashHeroEyebrow": "CUIYUW_dashHeroEyebrow",
|
|
925
|
+
"toolLive": "CUIYUW_toolLive",
|
|
926
|
+
"navTabBadgeDone": "CUIYUW_navTabBadgeDone",
|
|
927
|
+
"buttonDanger": "CUIYUW_buttonDanger",
|
|
959
928
|
"view": "CUIYUW_view",
|
|
960
|
-
"
|
|
961
|
-
"
|
|
962
|
-
"
|
|
929
|
+
"panelBody": "CUIYUW_panelBody",
|
|
930
|
+
"navGroupLabel": "CUIYUW_navGroupLabel",
|
|
931
|
+
"badgeRejected": "CUIYUW_badgeRejected",
|
|
932
|
+
"dashHeroAction": "CUIYUW_dashHeroAction",
|
|
933
|
+
"assistantFloatHeader": "CUIYUW_assistantFloatHeader",
|
|
934
|
+
"wsPageHeader": "CUIYUW_wsPageHeader",
|
|
935
|
+
"chapterNum": "CUIYUW_chapterNum",
|
|
963
936
|
"wsSelectedText": "CUIYUW_wsSelectedText",
|
|
964
|
-
"
|
|
937
|
+
"navTabLabel": "CUIYUW_navTabLabel",
|
|
938
|
+
"toolStepActive": "CUIYUW_toolStepActive",
|
|
939
|
+
"chatScroll": "CUIYUW_chatScroll",
|
|
940
|
+
"bookCardActive": "CUIYUW_bookCardActive",
|
|
941
|
+
"bookCardCoverFallback": "CUIYUW_bookCardCoverFallback",
|
|
942
|
+
"dashJourney": "CUIYUW_dashJourney",
|
|
943
|
+
"createBookIcon": "CUIYUW_createBookIcon",
|
|
944
|
+
"navAbout": "CUIYUW_navAbout",
|
|
945
|
+
"todoWarning": "CUIYUW_todoWarning",
|
|
946
|
+
"todoText": "CUIYUW_todoText",
|
|
947
|
+
"shelfGrid": "CUIYUW_shelfGrid",
|
|
948
|
+
"navAboutRow": "CUIYUW_navAboutRow",
|
|
949
|
+
"fieldLabel": "CUIYUW_fieldLabel",
|
|
950
|
+
"panelHeader": "CUIYUW_panelHeader",
|
|
951
|
+
"chatBubbleAssistant": "CUIYUW_chatBubbleAssistant",
|
|
952
|
+
"dashFact": "CUIYUW_dashFact",
|
|
953
|
+
"progressLineError": "CUIYUW_progressLineError",
|
|
954
|
+
"diffColumn": "CUIYUW_diffColumn",
|
|
955
|
+
"genreDesc": "CUIYUW_genreDesc",
|
|
956
|
+
"volumeGroupHeader": "CUIYUW_volumeGroupHeader",
|
|
957
|
+
"workflowDotDone": "CUIYUW_workflowDotDone",
|
|
958
|
+
"bookCreateCard": "CUIYUW_bookCreateCard",
|
|
959
|
+
"busyRow": "CUIYUW_busyRow",
|
|
960
|
+
"progressBar": "CUIYUW_progressBar",
|
|
965
961
|
"diffSame": "CUIYUW_diffSame",
|
|
966
|
-
"
|
|
962
|
+
"shelfHeader": "CUIYUW_shelfHeader",
|
|
963
|
+
"bookshelfList": "CUIYUW_bookshelfList",
|
|
964
|
+
"panelContent": "CUIYUW_panelContent",
|
|
965
|
+
"dropzoneActive": "CUIYUW_dropzoneActive",
|
|
966
|
+
"bookCreateOutline": "CUIYUW_bookCreateOutline",
|
|
967
|
+
"progressBarFill": "CUIYUW_progressBarFill",
|
|
968
|
+
"button": "CUIYUW_button",
|
|
969
|
+
"bookChipMeta": "CUIYUW_bookChipMeta",
|
|
970
|
+
"iconButton": "CUIYUW_iconButton",
|
|
971
|
+
"tabBar": "CUIYUW_tabBar",
|
|
972
|
+
"wsEditor": "CUIYUW_wsEditor",
|
|
973
|
+
"fadeIn": "CUIYUW_fadeIn",
|
|
974
|
+
"toolStepDetail": "CUIYUW_toolStepDetail",
|
|
975
|
+
"volumeGroupToggle": "CUIYUW_volumeGroupToggle",
|
|
976
|
+
"legendOld": "CUIYUW_legendOld",
|
|
977
|
+
"navTabBadge": "CUIYUW_navTabBadge",
|
|
978
|
+
"row": "CUIYUW_row",
|
|
979
|
+
"wsColumn": "CUIYUW_wsColumn",
|
|
980
|
+
"bookCardProgressBar": "CUIYUW_bookCardProgressBar",
|
|
981
|
+
"shelfView": "CUIYUW_shelfView",
|
|
982
|
+
"bookCardProgressFill": "CUIYUW_bookCardProgressFill",
|
|
983
|
+
"volumeGroup": "CUIYUW_volumeGroup",
|
|
984
|
+
"bookAddIcon": "CUIYUW_bookAddIcon",
|
|
985
|
+
"diffTagNew": "CUIYUW_diffTagNew",
|
|
986
|
+
"bookCardTitleRow": "CUIYUW_bookCardTitleRow",
|
|
987
|
+
"chapterMain": "CUIYUW_chapterMain",
|
|
988
|
+
"dashHeroTitle": "CUIYUW_dashHeroTitle",
|
|
989
|
+
"diffOld": "CUIYUW_diffOld",
|
|
990
|
+
"chapter": "CUIYUW_chapter",
|
|
991
|
+
"dashHeroSparkle": "CUIYUW_dashHeroSparkle",
|
|
992
|
+
"assistantResize": "CUIYUW_assistantResize",
|
|
993
|
+
"workflowRow": "CUIYUW_workflowRow",
|
|
994
|
+
"bookshelf": "CUIYUW_bookshelf",
|
|
995
|
+
"bigProgressBarFill": "CUIYUW_bigProgressBarFill",
|
|
996
|
+
"navTabBadgeWarn": "CUIYUW_navTabBadgeWarn",
|
|
997
|
+
"dashJourneyStages": "CUIYUW_dashJourneyStages",
|
|
998
|
+
"toolStepError": "CUIYUW_toolStepError",
|
|
999
|
+
"badgeGenerating": "CUIYUW_badgeGenerating",
|
|
1000
|
+
"pulse": "CUIYUW_pulse",
|
|
1001
|
+
"workflowLabel": "CUIYUW_workflowLabel",
|
|
1002
|
+
"toolStepName": "CUIYUW_toolStepName",
|
|
1003
|
+
"navTabBadgeDanger": "CUIYUW_navTabBadgeDanger",
|
|
1004
|
+
"badgeError": "CUIYUW_badgeError",
|
|
1005
|
+
"dashHeroArrow": "CUIYUW_dashHeroArrow",
|
|
1006
|
+
"progressLineLive": "CUIYUW_progressLineLive",
|
|
1007
|
+
"coverPlaceholder": "CUIYUW_coverPlaceholder",
|
|
1008
|
+
"badgeDone": "CUIYUW_badgeDone",
|
|
1009
|
+
"bookCardCoverTitle": "CUIYUW_bookCardCoverTitle",
|
|
1010
|
+
"bigProgressBar": "CUIYUW_bigProgressBar",
|
|
1011
|
+
"wsPreview": "CUIYUW_wsPreview",
|
|
1012
|
+
"bookCardBody": "CUIYUW_bookCardBody",
|
|
1013
|
+
"wsSelected": "CUIYUW_wsSelected",
|
|
1014
|
+
"chapterList": "CUIYUW_chapterList",
|
|
1015
|
+
"bookshelfLabel": "CUIYUW_bookshelfLabel",
|
|
1016
|
+
"buttonSmall": "CUIYUW_buttonSmall",
|
|
1017
|
+
"wsPage": "CUIYUW_wsPage",
|
|
1018
|
+
"todoItem": "CUIYUW_todoItem",
|
|
1019
|
+
"buttonPrimary": "CUIYUW_buttonPrimary",
|
|
1020
|
+
"navGroup": "CUIYUW_navGroup",
|
|
1021
|
+
"assistantFloat": "CUIYUW_assistantFloat",
|
|
1022
|
+
"legendNew": "CUIYUW_legendNew",
|
|
1023
|
+
"entryIcon": "CUIYUW_entryIcon",
|
|
1024
|
+
"toolStepIcon": "CUIYUW_toolStepIcon",
|
|
1025
|
+
"diffAdd": "CUIYUW_diffAdd",
|
|
1026
|
+
"dropzoneIcon": "CUIYUW_dropzoneIcon",
|
|
1027
|
+
"tab": "CUIYUW_tab"
|
|
967
1028
|
};
|
|
968
1029
|
//#endregion
|
|
969
1030
|
//#region src/client/panel/AssistantTab.tsx
|
|
@@ -3313,68 +3374,672 @@ window.__ModuleLoader__.load({
|
|
|
3313
3374
|
}, i))
|
|
3314
3375
|
})]
|
|
3315
3376
|
}),
|
|
3316
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3317
|
-
className: panel_module_css_default.card,
|
|
3377
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3378
|
+
className: panel_module_css_default.card,
|
|
3379
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3380
|
+
className: panel_module_css_default.row,
|
|
3381
|
+
style: { justifyContent: "space-between" },
|
|
3382
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3383
|
+
className: panel_module_css_default.cardTitle,
|
|
3384
|
+
children: [
|
|
3385
|
+
"势力分布(",
|
|
3386
|
+
draft.factions.length,
|
|
3387
|
+
")"
|
|
3388
|
+
]
|
|
3389
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3390
|
+
type: "button",
|
|
3391
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
3392
|
+
onClick: () => {
|
|
3393
|
+
setFactions([...draft.factions, {
|
|
3394
|
+
name: "",
|
|
3395
|
+
kind: "宗门",
|
|
3396
|
+
description: ""
|
|
3397
|
+
}]);
|
|
3398
|
+
},
|
|
3399
|
+
children: "+ 新增势力"
|
|
3400
|
+
})]
|
|
3401
|
+
}), draft.factions.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3402
|
+
className: panel_module_css_default.meta,
|
|
3403
|
+
children: "暂无势力 — 宗门 / 家族 / 王朝 / 组织…"
|
|
3404
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3405
|
+
style: {
|
|
3406
|
+
display: "flex",
|
|
3407
|
+
flexDirection: "column",
|
|
3408
|
+
gap: 6
|
|
3409
|
+
},
|
|
3410
|
+
children: draft.factions.map((faction, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditableRow, {
|
|
3411
|
+
name: `${faction.name}(${faction.kind})`,
|
|
3412
|
+
detail: faction.description,
|
|
3413
|
+
onName: (v) => {
|
|
3414
|
+
const next = [...draft.factions];
|
|
3415
|
+
const match = /^(.*)((.*))$/.exec(v);
|
|
3416
|
+
next[i] = {
|
|
3417
|
+
...next[i],
|
|
3418
|
+
name: (match?.[1] ?? v).trim(),
|
|
3419
|
+
kind: (match?.[2] ?? next[i].kind).trim() || "宗门"
|
|
3420
|
+
};
|
|
3421
|
+
setFactions(next);
|
|
3422
|
+
},
|
|
3423
|
+
onDetail: (v) => {
|
|
3424
|
+
const next = [...draft.factions];
|
|
3425
|
+
next[i] = {
|
|
3426
|
+
...next[i],
|
|
3427
|
+
description: v
|
|
3428
|
+
};
|
|
3429
|
+
setFactions(next);
|
|
3430
|
+
},
|
|
3431
|
+
onRemove: () => {
|
|
3432
|
+
setFactions(draft.factions.filter((_, idx) => idx !== i));
|
|
3433
|
+
},
|
|
3434
|
+
namePlaceholder: "势力名(类型)如:青云宗(宗门)",
|
|
3435
|
+
detailPlaceholder: "描述…"
|
|
3436
|
+
}, i))
|
|
3437
|
+
})]
|
|
3438
|
+
})
|
|
3439
|
+
]
|
|
3440
|
+
});
|
|
3441
|
+
}
|
|
3442
|
+
//#endregion
|
|
3443
|
+
//#region src/client/panel/views.tsx
|
|
3444
|
+
/** 统计格:状态摘要条 / 资产健康通用。 */
|
|
3445
|
+
function StatCell(props) {
|
|
3446
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3447
|
+
className: panel_module_css_default.assetStat,
|
|
3448
|
+
children: [
|
|
3449
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3450
|
+
className: panel_module_css_default.assetStatLabel,
|
|
3451
|
+
children: props.label
|
|
3452
|
+
}),
|
|
3453
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3454
|
+
className: panel_module_css_default.assetStatValue,
|
|
3455
|
+
style: {
|
|
3456
|
+
color: props.valueColor,
|
|
3457
|
+
fontSize: props.valueFontSize
|
|
3458
|
+
},
|
|
3459
|
+
children: props.value
|
|
3460
|
+
}),
|
|
3461
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3462
|
+
className: panel_module_css_default.assetStatDetail,
|
|
3463
|
+
title: props.detailTitle,
|
|
3464
|
+
children: props.detail
|
|
3465
|
+
})
|
|
3466
|
+
]
|
|
3467
|
+
});
|
|
3468
|
+
}
|
|
3469
|
+
/** 待办队列行。 */
|
|
3470
|
+
function TodoRow(props) {
|
|
3471
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3472
|
+
className: `${panel_module_css_default.todoItem} ${props.tone === "danger" ? panel_module_css_default.todoDanger : props.tone === "warning" ? panel_module_css_default.todoWarning : panel_module_css_default.todoInfo}`,
|
|
3473
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3474
|
+
className: panel_module_css_default.todoText,
|
|
3475
|
+
children: [props.title, props.description !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3476
|
+
className: panel_module_css_default.meta,
|
|
3477
|
+
children: [" — ", props.description]
|
|
3478
|
+
})]
|
|
3479
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3480
|
+
type: "button",
|
|
3481
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
3482
|
+
disabled: props.disabled,
|
|
3483
|
+
onClick: props.onAction,
|
|
3484
|
+
children: props.actionLabel
|
|
3485
|
+
})]
|
|
3486
|
+
});
|
|
3487
|
+
}
|
|
3488
|
+
/** 全书质检问题行。 */
|
|
3489
|
+
function AuditIssueRow(props) {
|
|
3490
|
+
const { issue } = props;
|
|
3491
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3492
|
+
className: `${panel_module_css_default.todoItem} ${issue.severity === "high" ? panel_module_css_default.todoDanger : issue.severity === "medium" ? panel_module_css_default.todoWarning : panel_module_css_default.todoInfo}`,
|
|
3493
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3494
|
+
className: panel_module_css_default.todoText,
|
|
3495
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [
|
|
3496
|
+
issue.chapterNo > 0 ? `第 ${issue.chapterNo} 章` : "未定位章节",
|
|
3497
|
+
" · [",
|
|
3498
|
+
issue.severity,
|
|
3499
|
+
"] ",
|
|
3500
|
+
issue.item
|
|
3501
|
+
] }), issue.suggestion !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3502
|
+
className: panel_module_css_default.meta,
|
|
3503
|
+
children: ["建议:", issue.suggestion]
|
|
3504
|
+
})]
|
|
3505
|
+
}), issue.chapterNo > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3506
|
+
type: "button",
|
|
3507
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
3508
|
+
disabled: props.disabled,
|
|
3509
|
+
onClick: props.onFix,
|
|
3510
|
+
children: "去修订"
|
|
3511
|
+
})]
|
|
3512
|
+
});
|
|
3513
|
+
}
|
|
3514
|
+
/** 剧情线卡片(列表主体)。 */
|
|
3515
|
+
function PlotlineCard(props) {
|
|
3516
|
+
const { line } = props;
|
|
3517
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3518
|
+
style: {
|
|
3519
|
+
border: "1px solid var(--nf-border)",
|
|
3520
|
+
borderRadius: 10,
|
|
3521
|
+
padding: "8px 12px",
|
|
3522
|
+
fontSize: 12,
|
|
3523
|
+
display: "flex",
|
|
3524
|
+
flexDirection: "column",
|
|
3525
|
+
gap: 4
|
|
3526
|
+
},
|
|
3527
|
+
children: [
|
|
3528
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3529
|
+
className: panel_module_css_default.row,
|
|
3530
|
+
style: {
|
|
3531
|
+
justifyContent: "space-between",
|
|
3532
|
+
flexWrap: "wrap"
|
|
3533
|
+
},
|
|
3534
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3535
|
+
style: {
|
|
3536
|
+
display: "flex",
|
|
3537
|
+
alignItems: "center",
|
|
3538
|
+
gap: 6,
|
|
3539
|
+
flexWrap: "wrap"
|
|
3540
|
+
},
|
|
3541
|
+
children: [
|
|
3542
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: line.name }),
|
|
3543
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3544
|
+
className: panel_module_css_default.badge,
|
|
3545
|
+
style: {
|
|
3546
|
+
borderColor: "var(--nf-accent)",
|
|
3547
|
+
color: "var(--nf-accent)"
|
|
3548
|
+
},
|
|
3549
|
+
children: kindLabel(line.kind)
|
|
3550
|
+
}),
|
|
3551
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3552
|
+
className: panel_module_css_default.badge,
|
|
3553
|
+
style: {
|
|
3554
|
+
borderColor: plotlineStatusColor(line.status),
|
|
3555
|
+
color: plotlineStatusColor(line.status)
|
|
3556
|
+
},
|
|
3557
|
+
children: plotlineStatusLabel(line.status)
|
|
3558
|
+
})
|
|
3559
|
+
]
|
|
3560
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3561
|
+
style: {
|
|
3562
|
+
display: "flex",
|
|
3563
|
+
gap: 6
|
|
3564
|
+
},
|
|
3565
|
+
children: [
|
|
3566
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3567
|
+
type: "button",
|
|
3568
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
3569
|
+
disabled: props.disabled,
|
|
3570
|
+
onClick: props.onRefresh,
|
|
3571
|
+
title: "AI 结合编年录与章节摘要,自动更新这条线的当前进度",
|
|
3572
|
+
children: "↻ AI 刷新进度"
|
|
3573
|
+
}),
|
|
3574
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3575
|
+
type: "button",
|
|
3576
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
3577
|
+
disabled: props.disabled,
|
|
3578
|
+
onClick: props.onEdit,
|
|
3579
|
+
children: tt("plotlines.edit")
|
|
3580
|
+
}),
|
|
3581
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3582
|
+
type: "button",
|
|
3583
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
3584
|
+
disabled: props.disabled,
|
|
3585
|
+
onClick: props.onRemove,
|
|
3586
|
+
children: tt("plotlines.remove")
|
|
3587
|
+
})
|
|
3588
|
+
]
|
|
3589
|
+
})]
|
|
3590
|
+
}),
|
|
3591
|
+
line.goal !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3592
|
+
className: panel_module_css_default.meta,
|
|
3593
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [tt("plotlines.goal"), ":"] }), line.goal]
|
|
3594
|
+
}),
|
|
3595
|
+
line.progress !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3596
|
+
className: panel_module_css_default.meta,
|
|
3597
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [tt("plotlines.progress"), ":"] }), line.progress]
|
|
3598
|
+
}),
|
|
3599
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3600
|
+
className: panel_module_css_default.meta,
|
|
3601
|
+
children: [
|
|
3602
|
+
tt("plotlines.chapters"),
|
|
3603
|
+
":",
|
|
3604
|
+
line.chapters.length > 0 ? line.chapters.map((n) => `第${n}章`).join("、") : "—"
|
|
3605
|
+
]
|
|
3606
|
+
})
|
|
3607
|
+
]
|
|
3608
|
+
}, line.id);
|
|
3609
|
+
}
|
|
3610
|
+
/** AI 候选角色行(提炼结果,可采纳/修改后采纳)。 */
|
|
3611
|
+
function RoleCandidateRow(props) {
|
|
3612
|
+
const { candidate: r } = props;
|
|
3613
|
+
const label = ROLE_LABELS[r.roleLabel] ?? r.roleLabel;
|
|
3614
|
+
const color = roleColor(r.roleLabel);
|
|
3615
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3616
|
+
style: {
|
|
3617
|
+
border: "1px solid var(--nf-border)",
|
|
3618
|
+
borderRadius: 8,
|
|
3619
|
+
padding: "6px 10px",
|
|
3620
|
+
fontSize: 12
|
|
3621
|
+
},
|
|
3622
|
+
children: [
|
|
3623
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3624
|
+
className: panel_module_css_default.row,
|
|
3625
|
+
style: {
|
|
3626
|
+
justifyContent: "space-between",
|
|
3627
|
+
flexWrap: "wrap"
|
|
3628
|
+
},
|
|
3629
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3630
|
+
style: {
|
|
3631
|
+
display: "flex",
|
|
3632
|
+
alignItems: "center",
|
|
3633
|
+
gap: 6,
|
|
3634
|
+
flexWrap: "wrap"
|
|
3635
|
+
},
|
|
3636
|
+
children: [
|
|
3637
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: r.name }),
|
|
3638
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3639
|
+
className: panel_module_css_default.badge,
|
|
3640
|
+
style: {
|
|
3641
|
+
borderColor: color,
|
|
3642
|
+
color
|
|
3643
|
+
},
|
|
3644
|
+
children: label
|
|
3645
|
+
}),
|
|
3646
|
+
r.identity !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3647
|
+
className: panel_module_css_default.meta,
|
|
3648
|
+
children: r.identity
|
|
3649
|
+
})
|
|
3650
|
+
]
|
|
3651
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3652
|
+
style: {
|
|
3653
|
+
display: "flex",
|
|
3654
|
+
gap: 6
|
|
3655
|
+
},
|
|
3656
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3657
|
+
type: "button",
|
|
3658
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
3659
|
+
disabled: props.disabled,
|
|
3660
|
+
onClick: props.onAdopt,
|
|
3661
|
+
children: "+ 采纳"
|
|
3662
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3663
|
+
type: "button",
|
|
3664
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
3665
|
+
disabled: props.disabled,
|
|
3666
|
+
onClick: props.onEdit,
|
|
3667
|
+
title: "修改后再采纳(候选列表保留)",
|
|
3668
|
+
children: "✏️ 修改后采纳"
|
|
3669
|
+
})]
|
|
3670
|
+
})]
|
|
3671
|
+
}),
|
|
3672
|
+
r.goals !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3673
|
+
className: panel_module_css_default.meta,
|
|
3674
|
+
children: ["目标:", r.goals]
|
|
3675
|
+
}),
|
|
3676
|
+
r.relations.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3677
|
+
className: panel_module_css_default.meta,
|
|
3678
|
+
children: ["关系:", r.relations.join("、")]
|
|
3679
|
+
})
|
|
3680
|
+
]
|
|
3681
|
+
}, r.name);
|
|
3682
|
+
}
|
|
3683
|
+
/** 已收录角色卡(含从编年录刷新的当前状态行)。 */
|
|
3684
|
+
function RoleCard(props) {
|
|
3685
|
+
const { role: r, status: st } = props;
|
|
3686
|
+
const label = ROLE_LABELS[r.roleLabel] ?? r.roleLabel;
|
|
3687
|
+
const color = roleColor(r.roleLabel);
|
|
3688
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3689
|
+
style: {
|
|
3690
|
+
border: "1px solid var(--nf-border)",
|
|
3691
|
+
borderRadius: 8,
|
|
3692
|
+
padding: "6px 10px",
|
|
3693
|
+
fontSize: 12
|
|
3694
|
+
},
|
|
3695
|
+
children: [
|
|
3696
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3697
|
+
className: panel_module_css_default.row,
|
|
3698
|
+
style: {
|
|
3699
|
+
justifyContent: "space-between",
|
|
3700
|
+
flexWrap: "wrap"
|
|
3701
|
+
},
|
|
3702
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3703
|
+
style: {
|
|
3704
|
+
display: "flex",
|
|
3705
|
+
alignItems: "center",
|
|
3706
|
+
gap: 6,
|
|
3707
|
+
flexWrap: "wrap"
|
|
3708
|
+
},
|
|
3709
|
+
children: [
|
|
3710
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: r.name }),
|
|
3711
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3712
|
+
className: panel_module_css_default.badge,
|
|
3713
|
+
style: {
|
|
3714
|
+
borderColor: color,
|
|
3715
|
+
color
|
|
3716
|
+
},
|
|
3717
|
+
children: label
|
|
3718
|
+
}),
|
|
3719
|
+
r.identity !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3720
|
+
className: panel_module_css_default.meta,
|
|
3721
|
+
children: r.identity
|
|
3722
|
+
})
|
|
3723
|
+
]
|
|
3724
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3725
|
+
style: {
|
|
3726
|
+
display: "flex",
|
|
3727
|
+
gap: 6
|
|
3728
|
+
},
|
|
3729
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3730
|
+
type: "button",
|
|
3731
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
3732
|
+
disabled: props.disabled,
|
|
3733
|
+
onClick: props.onEdit,
|
|
3734
|
+
children: "编辑"
|
|
3735
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3736
|
+
type: "button",
|
|
3737
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
3738
|
+
disabled: props.disabled,
|
|
3739
|
+
onClick: props.onRemove,
|
|
3740
|
+
children: "删除"
|
|
3741
|
+
})]
|
|
3742
|
+
})]
|
|
3743
|
+
}),
|
|
3744
|
+
r.goals !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3745
|
+
className: panel_module_css_default.meta,
|
|
3746
|
+
children: ["目标:", r.goals]
|
|
3747
|
+
}),
|
|
3748
|
+
st !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3749
|
+
className: panel_module_css_default.meta,
|
|
3750
|
+
style: { color: "var(--nf-accent)" },
|
|
3751
|
+
children: [
|
|
3752
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "当前状态:" }),
|
|
3753
|
+
st.status !== "" ? st.status : "(编年录暂无该角色记录)",
|
|
3754
|
+
" · 出场 ",
|
|
3755
|
+
st.appearances,
|
|
3756
|
+
" 次 · 最近 第 ",
|
|
3757
|
+
st.lastChapter,
|
|
3758
|
+
" 章"
|
|
3759
|
+
]
|
|
3760
|
+
}),
|
|
3761
|
+
r.relations.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3762
|
+
className: panel_module_css_default.meta,
|
|
3763
|
+
children: ["关系:", r.relations.join("、")]
|
|
3764
|
+
}),
|
|
3765
|
+
r.arc.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3766
|
+
className: panel_module_css_default.meta,
|
|
3767
|
+
children: ["成长线:", r.arc.join(" → ")]
|
|
3768
|
+
}),
|
|
3769
|
+
r.knowledge.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3770
|
+
className: panel_module_css_default.meta,
|
|
3771
|
+
children: ["知情度:", r.knowledge.join(";")]
|
|
3772
|
+
})
|
|
3773
|
+
]
|
|
3774
|
+
}, r.name);
|
|
3775
|
+
}
|
|
3776
|
+
/** 🩺 剧情健康检查报告面板。 */
|
|
3777
|
+
function PlotlineHealthPanel(props) {
|
|
3778
|
+
const { report } = props;
|
|
3779
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3780
|
+
style: {
|
|
3781
|
+
display: "flex",
|
|
3782
|
+
flexDirection: "column",
|
|
3783
|
+
gap: 6,
|
|
3784
|
+
border: "1px solid var(--nf-info)",
|
|
3785
|
+
borderRadius: 12,
|
|
3786
|
+
padding: 10
|
|
3787
|
+
},
|
|
3788
|
+
children: [
|
|
3789
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3790
|
+
className: panel_module_css_default.row,
|
|
3791
|
+
style: {
|
|
3792
|
+
justifyContent: "space-between",
|
|
3793
|
+
flexWrap: "wrap"
|
|
3794
|
+
},
|
|
3795
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "🩺 剧情健康检查" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3796
|
+
style: {
|
|
3797
|
+
display: "flex",
|
|
3798
|
+
gap: 8
|
|
3799
|
+
},
|
|
3800
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3801
|
+
type: "button",
|
|
3802
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
3803
|
+
disabled: props.disabled,
|
|
3804
|
+
onClick: props.onPlan,
|
|
3805
|
+
title: "基于本次诊断生成下一阶段剧情方案",
|
|
3806
|
+
children: "✨ 基于此设计方案"
|
|
3807
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3808
|
+
type: "button",
|
|
3809
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
3810
|
+
onClick: props.onClose,
|
|
3811
|
+
children: "收起"
|
|
3812
|
+
})]
|
|
3813
|
+
})]
|
|
3814
|
+
}),
|
|
3815
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3816
|
+
style: {
|
|
3817
|
+
fontSize: 12,
|
|
3818
|
+
fontWeight: 700,
|
|
3819
|
+
color: "var(--nf-accent)"
|
|
3820
|
+
},
|
|
3821
|
+
children: ["判定:", report.verdict]
|
|
3822
|
+
}),
|
|
3823
|
+
report.timing !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3824
|
+
className: panel_module_css_default.meta,
|
|
3825
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "建议时机:" }), report.timing]
|
|
3826
|
+
}),
|
|
3827
|
+
report.reasons.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3828
|
+
style: {
|
|
3829
|
+
display: "flex",
|
|
3830
|
+
flexDirection: "column",
|
|
3831
|
+
gap: 2,
|
|
3832
|
+
fontSize: 12
|
|
3833
|
+
},
|
|
3834
|
+
children: report.reasons.map((r, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3835
|
+
className: panel_module_css_default.meta,
|
|
3836
|
+
children: ["· ", r]
|
|
3837
|
+
}, i))
|
|
3838
|
+
}),
|
|
3839
|
+
report.lines.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3840
|
+
style: {
|
|
3841
|
+
display: "flex",
|
|
3842
|
+
flexDirection: "column",
|
|
3843
|
+
gap: 4,
|
|
3844
|
+
fontSize: 12
|
|
3845
|
+
},
|
|
3846
|
+
children: report.lines.map((l, i) => {
|
|
3847
|
+
const color = l.health === "ok" ? "var(--nf-success)" : l.health === "warning" ? "var(--nf-warn)" : "var(--nf-error)";
|
|
3848
|
+
const label = l.health === "ok" ? "健康" : l.health === "warning" ? "预警" : "搁置过久";
|
|
3849
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3850
|
+
style: {
|
|
3851
|
+
display: "flex",
|
|
3852
|
+
gap: 8,
|
|
3853
|
+
alignItems: "flex-start"
|
|
3854
|
+
},
|
|
3855
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3856
|
+
className: panel_module_css_default.badge,
|
|
3857
|
+
style: {
|
|
3858
|
+
borderColor: color,
|
|
3859
|
+
color,
|
|
3860
|
+
flex: "none",
|
|
3861
|
+
marginTop: 1
|
|
3862
|
+
},
|
|
3863
|
+
children: label
|
|
3864
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3865
|
+
className: panel_module_css_default.meta,
|
|
3866
|
+
children: [
|
|
3867
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: l.name }),
|
|
3868
|
+
":",
|
|
3869
|
+
l.note
|
|
3870
|
+
]
|
|
3871
|
+
})]
|
|
3872
|
+
}, i);
|
|
3873
|
+
})
|
|
3874
|
+
})
|
|
3875
|
+
]
|
|
3876
|
+
});
|
|
3877
|
+
}
|
|
3878
|
+
/** ✨ AI 剧情方案面板。 */
|
|
3879
|
+
function PlotlinePlanPanel(props) {
|
|
3880
|
+
const { plan } = props;
|
|
3881
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3882
|
+
style: {
|
|
3883
|
+
display: "flex",
|
|
3884
|
+
flexDirection: "column",
|
|
3885
|
+
gap: 6,
|
|
3886
|
+
border: "1px solid var(--nf-accent)",
|
|
3887
|
+
borderRadius: 12,
|
|
3888
|
+
padding: 10
|
|
3889
|
+
},
|
|
3890
|
+
children: [
|
|
3891
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3892
|
+
className: panel_module_css_default.row,
|
|
3893
|
+
style: {
|
|
3894
|
+
justifyContent: "space-between",
|
|
3895
|
+
flexWrap: "wrap"
|
|
3896
|
+
},
|
|
3897
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "✨ AI 剧情方案" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3898
|
+
type: "button",
|
|
3899
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
3900
|
+
onClick: props.onClose,
|
|
3901
|
+
children: "收起"
|
|
3902
|
+
})]
|
|
3903
|
+
}),
|
|
3904
|
+
plan.direction !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3905
|
+
className: panel_module_css_default.meta,
|
|
3906
|
+
style: { fontSize: 12 },
|
|
3907
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "下一阶段方向:" }), plan.direction]
|
|
3908
|
+
}),
|
|
3909
|
+
plan.suggestions.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3910
|
+
style: {
|
|
3911
|
+
display: "flex",
|
|
3912
|
+
flexDirection: "column",
|
|
3913
|
+
gap: 4,
|
|
3914
|
+
fontSize: 12
|
|
3915
|
+
},
|
|
3916
|
+
children: plan.suggestions.map((s, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3917
|
+
style: {
|
|
3918
|
+
border: "1px solid var(--nf-border)",
|
|
3919
|
+
borderRadius: 8,
|
|
3920
|
+
padding: "6px 10px"
|
|
3921
|
+
},
|
|
3922
|
+
children: [
|
|
3923
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3924
|
+
className: panel_module_css_default.row,
|
|
3925
|
+
style: {
|
|
3926
|
+
justifyContent: "space-between",
|
|
3927
|
+
flexWrap: "wrap"
|
|
3928
|
+
},
|
|
3929
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3930
|
+
style: {
|
|
3931
|
+
display: "flex",
|
|
3932
|
+
alignItems: "center",
|
|
3933
|
+
gap: 6,
|
|
3934
|
+
flexWrap: "wrap"
|
|
3935
|
+
},
|
|
3936
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: s.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3937
|
+
className: panel_module_css_default.badge,
|
|
3938
|
+
style: {
|
|
3939
|
+
borderColor: "var(--nf-accent)",
|
|
3940
|
+
color: "var(--nf-accent)"
|
|
3941
|
+
},
|
|
3942
|
+
children: kindLabel(s.kind)
|
|
3943
|
+
})]
|
|
3944
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3945
|
+
type: "button",
|
|
3946
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
3947
|
+
disabled: props.disabled,
|
|
3948
|
+
onClick: () => {
|
|
3949
|
+
props.onAdopt(s);
|
|
3950
|
+
},
|
|
3951
|
+
children: "+ 采纳"
|
|
3952
|
+
})]
|
|
3953
|
+
}),
|
|
3954
|
+
s.goal !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3955
|
+
className: panel_module_css_default.meta,
|
|
3956
|
+
children: s.goal
|
|
3957
|
+
}),
|
|
3958
|
+
s.progress !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3959
|
+
className: panel_module_css_default.meta,
|
|
3960
|
+
children: ["初始进度:", s.progress]
|
|
3961
|
+
})
|
|
3962
|
+
]
|
|
3963
|
+
}, i))
|
|
3964
|
+
})
|
|
3965
|
+
]
|
|
3966
|
+
});
|
|
3967
|
+
}
|
|
3968
|
+
/** ✨ AI 建议剧情线面板。 */
|
|
3969
|
+
function PlotlineSuggestionPanel(props) {
|
|
3970
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3971
|
+
style: {
|
|
3972
|
+
display: "flex",
|
|
3973
|
+
flexDirection: "column",
|
|
3974
|
+
gap: 6,
|
|
3975
|
+
border: "1px solid var(--nf-info)",
|
|
3976
|
+
borderRadius: 12,
|
|
3977
|
+
padding: 10
|
|
3978
|
+
},
|
|
3979
|
+
children: [
|
|
3980
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3981
|
+
className: panel_module_css_default.row,
|
|
3982
|
+
style: {
|
|
3983
|
+
justifyContent: "space-between",
|
|
3984
|
+
flexWrap: "wrap"
|
|
3985
|
+
},
|
|
3986
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [
|
|
3987
|
+
"✨ AI 建议(",
|
|
3988
|
+
props.suggestions.length,
|
|
3989
|
+
" 条)"
|
|
3990
|
+
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3991
|
+
type: "button",
|
|
3992
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
3993
|
+
onClick: props.onClose,
|
|
3994
|
+
children: "收起"
|
|
3995
|
+
})]
|
|
3996
|
+
}),
|
|
3997
|
+
props.suggestions.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3998
|
+
className: panel_module_css_default.meta,
|
|
3999
|
+
children: "没有候选线。"
|
|
4000
|
+
}),
|
|
4001
|
+
props.suggestions.map((s, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4002
|
+
style: {
|
|
4003
|
+
border: "1px solid var(--nf-border)",
|
|
4004
|
+
borderRadius: 8,
|
|
4005
|
+
padding: "6px 10px",
|
|
4006
|
+
fontSize: 12
|
|
4007
|
+
},
|
|
3318
4008
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3319
4009
|
className: panel_module_css_default.row,
|
|
3320
|
-
style: {
|
|
4010
|
+
style: {
|
|
4011
|
+
justifyContent: "space-between",
|
|
4012
|
+
flexWrap: "wrap"
|
|
4013
|
+
},
|
|
3321
4014
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
"
|
|
3325
|
-
|
|
3326
|
-
"
|
|
3327
|
-
|
|
4015
|
+
style: {
|
|
4016
|
+
display: "flex",
|
|
4017
|
+
alignItems: "center",
|
|
4018
|
+
gap: 6,
|
|
4019
|
+
flexWrap: "wrap"
|
|
4020
|
+
},
|
|
4021
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: s.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4022
|
+
className: panel_module_css_default.badge,
|
|
4023
|
+
style: {
|
|
4024
|
+
borderColor: "var(--nf-accent)",
|
|
4025
|
+
color: "var(--nf-accent)"
|
|
4026
|
+
},
|
|
4027
|
+
children: kindLabel(s.kind)
|
|
4028
|
+
})]
|
|
3328
4029
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
3329
4030
|
type: "button",
|
|
3330
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
4031
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
4032
|
+
disabled: props.disabled,
|
|
3331
4033
|
onClick: () => {
|
|
3332
|
-
|
|
3333
|
-
name: "",
|
|
3334
|
-
kind: "宗门",
|
|
3335
|
-
description: ""
|
|
3336
|
-
}]);
|
|
4034
|
+
props.onAdopt(s);
|
|
3337
4035
|
},
|
|
3338
|
-
children: "+
|
|
4036
|
+
children: "+ 采纳"
|
|
3339
4037
|
})]
|
|
3340
|
-
}),
|
|
4038
|
+
}), s.goal !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3341
4039
|
className: panel_module_css_default.meta,
|
|
3342
|
-
children:
|
|
3343
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3344
|
-
style: {
|
|
3345
|
-
display: "flex",
|
|
3346
|
-
flexDirection: "column",
|
|
3347
|
-
gap: 6
|
|
3348
|
-
},
|
|
3349
|
-
children: draft.factions.map((faction, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(EditableRow, {
|
|
3350
|
-
name: `${faction.name}(${faction.kind})`,
|
|
3351
|
-
detail: faction.description,
|
|
3352
|
-
onName: (v) => {
|
|
3353
|
-
const next = [...draft.factions];
|
|
3354
|
-
const match = /^(.*)((.*))$/.exec(v);
|
|
3355
|
-
next[i] = {
|
|
3356
|
-
...next[i],
|
|
3357
|
-
name: (match?.[1] ?? v).trim(),
|
|
3358
|
-
kind: (match?.[2] ?? next[i].kind).trim() || "宗门"
|
|
3359
|
-
};
|
|
3360
|
-
setFactions(next);
|
|
3361
|
-
},
|
|
3362
|
-
onDetail: (v) => {
|
|
3363
|
-
const next = [...draft.factions];
|
|
3364
|
-
next[i] = {
|
|
3365
|
-
...next[i],
|
|
3366
|
-
description: v
|
|
3367
|
-
};
|
|
3368
|
-
setFactions(next);
|
|
3369
|
-
},
|
|
3370
|
-
onRemove: () => {
|
|
3371
|
-
setFactions(draft.factions.filter((_, idx) => idx !== i));
|
|
3372
|
-
},
|
|
3373
|
-
namePlaceholder: "势力名(类型)如:青云宗(宗门)",
|
|
3374
|
-
detailPlaceholder: "描述…"
|
|
3375
|
-
}, i))
|
|
4040
|
+
children: s.goal
|
|
3376
4041
|
})]
|
|
3377
|
-
})
|
|
4042
|
+
}, i))
|
|
3378
4043
|
]
|
|
3379
4044
|
});
|
|
3380
4045
|
}
|
|
@@ -3447,8 +4112,8 @@ window.__ModuleLoader__.load({
|
|
|
3447
4112
|
icon: "🌍"
|
|
3448
4113
|
},
|
|
3449
4114
|
{
|
|
3450
|
-
id: "
|
|
3451
|
-
label: "
|
|
4115
|
+
id: "roles",
|
|
4116
|
+
label: "角色库",
|
|
3452
4117
|
icon: "👥"
|
|
3453
4118
|
},
|
|
3454
4119
|
{
|
|
@@ -3500,7 +4165,7 @@ window.__ModuleLoader__.load({
|
|
|
3500
4165
|
label: tt("tab.settings"),
|
|
3501
4166
|
icon: "⚙️"
|
|
3502
4167
|
};
|
|
3503
|
-
const PLUGIN_VERSION = "1.1.
|
|
4168
|
+
const PLUGIN_VERSION = "1.1.6";
|
|
3504
4169
|
/** GitHub 仓库地址(关于区块点击跳转)。 */
|
|
3505
4170
|
const REPO_URL = "https://github.com/watersxya/dsh-novel-forge";
|
|
3506
4171
|
/** Whether any chapter is being generated right now. */
|
|
@@ -3850,6 +4515,26 @@ window.__ModuleLoader__.load({
|
|
|
3850
4515
|
const [plotlineDraft, setPlotlineDraft] = (0, react.useState)(null);
|
|
3851
4516
|
/** 角色知情度编辑草稿(角色名 → 文本,每行一条)。 */
|
|
3852
4517
|
const [knowledgeDraft, setKnowledgeDraft] = (0, react.useState)({});
|
|
4518
|
+
/** 角色库:AI 提炼候选(null = 未运行;localStorage 持久化,刷新不丢)。 */
|
|
4519
|
+
const [roleCandidates, setRoleCandidates] = (0, react.useState)(() => {
|
|
4520
|
+
try {
|
|
4521
|
+
const raw = window.localStorage.getItem("dsh-novel-forge.role.candidates");
|
|
4522
|
+
if (raw !== null) {
|
|
4523
|
+
const parsed = JSON.parse(raw);
|
|
4524
|
+
return Array.isArray(parsed) && parsed.length > 0 ? parsed : null;
|
|
4525
|
+
}
|
|
4526
|
+
} catch {}
|
|
4527
|
+
return null;
|
|
4528
|
+
});
|
|
4529
|
+
/** 角色库:编辑草稿(null = 不在编辑)。 */
|
|
4530
|
+
const [roleDraft, setRoleDraft] = (0, react.useState)(null);
|
|
4531
|
+
/** 角色库候选持久化:提炼/采纳后写回 localStorage。 */
|
|
4532
|
+
(0, react.useEffect)(() => {
|
|
4533
|
+
try {
|
|
4534
|
+
if (roleCandidates !== null && roleCandidates.length > 0) window.localStorage.setItem("dsh-novel-forge.role.candidates", JSON.stringify(roleCandidates));
|
|
4535
|
+
else window.localStorage.removeItem("dsh-novel-forge.role.candidates");
|
|
4536
|
+
} catch {}
|
|
4537
|
+
}, [roleCandidates]);
|
|
3853
4538
|
/** 全书敏感词检查结果(null = 未运行)。 */
|
|
3854
4539
|
const [sensHits, setSensHits] = (0, react.useState)(null);
|
|
3855
4540
|
const [sensScanned, setSensScanned] = (0, react.useState)(0);
|
|
@@ -4056,6 +4741,8 @@ window.__ModuleLoader__.load({
|
|
|
4056
4741
|
setConfig(status.config);
|
|
4057
4742
|
setConfigDraft(status.config);
|
|
4058
4743
|
setProject(status.project ?? null);
|
|
4744
|
+
if (status.project?.roleStatus !== void 0) setCharCards(status.project.roleStatus);
|
|
4745
|
+
else setCharCards(null);
|
|
4059
4746
|
setGeneratedFiles(status.generatedFiles);
|
|
4060
4747
|
const withDraft = status.project?.chapters.find((c) => c.pendingDraft !== void 0 && c.pendingDraft !== "");
|
|
4061
4748
|
setDraftNo(withDraft?.no ?? null);
|
|
@@ -4164,15 +4851,20 @@ window.__ModuleLoader__.load({
|
|
|
4164
4851
|
/** 角色卡刷新。 */
|
|
4165
4852
|
const handleCharactersRefresh = async () => {
|
|
4166
4853
|
setBusy(true);
|
|
4167
|
-
setBusyLabel("
|
|
4854
|
+
setBusyLabel("聚合角色状态中…");
|
|
4168
4855
|
setError("");
|
|
4169
4856
|
try {
|
|
4170
4857
|
const result = await api.charactersRefresh();
|
|
4171
4858
|
setCharCards(result.cards);
|
|
4172
|
-
|
|
4859
|
+
setProject((prev) => prev === null ? prev : {
|
|
4860
|
+
...prev,
|
|
4861
|
+
roleStatus: result.cards,
|
|
4862
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4863
|
+
});
|
|
4864
|
+
pushProgress(`角色状态已刷新:${result.cards.length} 个角色`, "done");
|
|
4173
4865
|
} catch (err) {
|
|
4174
4866
|
setError(err.message);
|
|
4175
|
-
pushProgress(
|
|
4867
|
+
pushProgress(`角色状态刷新失败:${err.message}`, "error");
|
|
4176
4868
|
} finally {
|
|
4177
4869
|
setBusy(false);
|
|
4178
4870
|
setBusyLabel("");
|
|
@@ -4196,6 +4888,50 @@ window.__ModuleLoader__.load({
|
|
|
4196
4888
|
setBusyLabel("");
|
|
4197
4889
|
}
|
|
4198
4890
|
};
|
|
4891
|
+
/** 章节复位:generating 卡死 → pending(可重新生成)。 */
|
|
4892
|
+
const handleChapterReset = async (no) => {
|
|
4893
|
+
setBusy(true);
|
|
4894
|
+
setError("");
|
|
4895
|
+
try {
|
|
4896
|
+
await api.chapterReset(no);
|
|
4897
|
+
setProject((prev) => prev === null ? prev : {
|
|
4898
|
+
...prev,
|
|
4899
|
+
chapters: prev.chapters.map((c) => c.no === no ? {
|
|
4900
|
+
...c,
|
|
4901
|
+
status: "pending",
|
|
4902
|
+
error: void 0
|
|
4903
|
+
} : c)
|
|
4904
|
+
});
|
|
4905
|
+
pushProgress(`第 ${no} 章已复位为待生成,可重新生成`, "info");
|
|
4906
|
+
} catch (err) {
|
|
4907
|
+
setError(err.message);
|
|
4908
|
+
pushProgress(`复位失败:${err.message}`, "error");
|
|
4909
|
+
} finally {
|
|
4910
|
+
setBusy(false);
|
|
4911
|
+
}
|
|
4912
|
+
};
|
|
4913
|
+
/** 章节直接通过(作者行使最终决定权)。 */
|
|
4914
|
+
const handleChapterApprove = async (no) => {
|
|
4915
|
+
if (!window.confirm(`确定直接通过第 ${no} 章?(跳过审稿判定,保留审稿记录)`)) return;
|
|
4916
|
+
setBusy(true);
|
|
4917
|
+
setError("");
|
|
4918
|
+
try {
|
|
4919
|
+
await api.chapterApprove(no);
|
|
4920
|
+
setProject((prev) => prev === null ? prev : {
|
|
4921
|
+
...prev,
|
|
4922
|
+
chapters: prev.chapters.map((c) => c.no === no ? {
|
|
4923
|
+
...c,
|
|
4924
|
+
status: "approved"
|
|
4925
|
+
} : c)
|
|
4926
|
+
});
|
|
4927
|
+
pushProgress(`第 ${no} 章已直接通过`, "done");
|
|
4928
|
+
} catch (err) {
|
|
4929
|
+
setError(err.message);
|
|
4930
|
+
pushProgress(`操作失败:${err.message}`, "error");
|
|
4931
|
+
} finally {
|
|
4932
|
+
setBusy(false);
|
|
4933
|
+
}
|
|
4934
|
+
};
|
|
4199
4935
|
/** 剧情线:保存草稿(新增或更新)。 */
|
|
4200
4936
|
const handlePlotlineSave = async () => {
|
|
4201
4937
|
if (plotlineDraft === null) return;
|
|
@@ -4446,26 +5182,94 @@ window.__ModuleLoader__.load({
|
|
|
4446
5182
|
setBusyLabel("");
|
|
4447
5183
|
}
|
|
4448
5184
|
};
|
|
4449
|
-
/**
|
|
4450
|
-
const
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4455
|
-
|
|
5185
|
+
/** 角色库:AI 从全书提炼角色候选。 */
|
|
5186
|
+
const handleRolesExtract = async () => {
|
|
5187
|
+
setBusy(true);
|
|
5188
|
+
setBusyLabel("✨ 提炼角色库中…");
|
|
5189
|
+
setError("");
|
|
5190
|
+
try {
|
|
5191
|
+
const result = await api.roles({ op: "extract" });
|
|
5192
|
+
const inLibrary = new Set((project?.roles ?? []).map((r) => r.name));
|
|
5193
|
+
const fresh = (result.candidates ?? []).filter((r) => !inLibrary.has(r.name));
|
|
5194
|
+
setRoleCandidates((prev) => {
|
|
5195
|
+
return [...(prev ?? []).filter((p) => !fresh.some((f) => f.name === p.name)), ...fresh];
|
|
5196
|
+
});
|
|
5197
|
+
pushProgress(`AI 提炼出 ${fresh.length} 个新角色(已排除 ${(result.candidates?.length ?? 0) - fresh.length} 个已收录)`, "done");
|
|
5198
|
+
} catch (err) {
|
|
5199
|
+
setError(err.message);
|
|
5200
|
+
pushProgress(`角色提炼失败:${err.message}`, "error");
|
|
5201
|
+
} finally {
|
|
5202
|
+
setBusy(false);
|
|
5203
|
+
setBusyLabel("");
|
|
5204
|
+
}
|
|
5205
|
+
};
|
|
5206
|
+
/** 角色库:采纳候选(或修改后采纳)。 */
|
|
5207
|
+
const handleRoleAdopt = async (role) => {
|
|
4456
5208
|
setBusy(true);
|
|
4457
5209
|
setError("");
|
|
4458
5210
|
try {
|
|
4459
|
-
const result = await api.
|
|
4460
|
-
|
|
5211
|
+
const result = await api.roles({
|
|
5212
|
+
op: "adopt",
|
|
5213
|
+
role
|
|
5214
|
+
});
|
|
5215
|
+
setProject((prev) => prev === null ? prev : {
|
|
4461
5216
|
...prev,
|
|
4462
|
-
|
|
5217
|
+
roles: result.roles,
|
|
5218
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5219
|
+
});
|
|
5220
|
+
setRoleCandidates((prev) => prev === null ? prev : prev.filter((r) => r !== role));
|
|
5221
|
+
pushProgress(`已加入角色库:${role.name}`, "done");
|
|
5222
|
+
} catch (err) {
|
|
5223
|
+
setError(err.message);
|
|
5224
|
+
} finally {
|
|
5225
|
+
setBusy(false);
|
|
5226
|
+
}
|
|
5227
|
+
};
|
|
5228
|
+
/** 角色库:保存编辑草稿。 */
|
|
5229
|
+
const handleRoleSave = async () => {
|
|
5230
|
+
if (roleDraft === null) return;
|
|
5231
|
+
if (roleDraft.name.trim() === "") {
|
|
5232
|
+
setError("角色名不能为空");
|
|
5233
|
+
return;
|
|
5234
|
+
}
|
|
5235
|
+
setBusy(true);
|
|
5236
|
+
setError("");
|
|
5237
|
+
try {
|
|
5238
|
+
const result = await api.roles({
|
|
5239
|
+
op: "update",
|
|
5240
|
+
role: roleDraft
|
|
5241
|
+
});
|
|
5242
|
+
setProject((prev) => prev === null ? prev : {
|
|
5243
|
+
...prev,
|
|
5244
|
+
roles: result.roles,
|
|
5245
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5246
|
+
});
|
|
5247
|
+
setRoleDraft(null);
|
|
5248
|
+
pushProgress(`角色已保存:${roleDraft.name}`, "done");
|
|
5249
|
+
} catch (err) {
|
|
5250
|
+
setError(err.message);
|
|
5251
|
+
} finally {
|
|
5252
|
+
setBusy(false);
|
|
5253
|
+
}
|
|
5254
|
+
};
|
|
5255
|
+
/** 角色库:删除角色。 */
|
|
5256
|
+
const handleRoleRemove = async (name) => {
|
|
5257
|
+
if (!window.confirm(`确定从角色库删除「${name}」?`)) return;
|
|
5258
|
+
setBusy(true);
|
|
5259
|
+
setError("");
|
|
5260
|
+
try {
|
|
5261
|
+
const result = await api.roles({
|
|
5262
|
+
op: "remove",
|
|
5263
|
+
name
|
|
5264
|
+
});
|
|
5265
|
+
setProject((prev) => prev === null ? prev : {
|
|
5266
|
+
...prev,
|
|
5267
|
+
roles: result.roles,
|
|
4463
5268
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4464
5269
|
});
|
|
4465
|
-
pushProgress(
|
|
5270
|
+
pushProgress(`已从角色库删除:${name}`, "info");
|
|
4466
5271
|
} catch (err) {
|
|
4467
5272
|
setError(err.message);
|
|
4468
|
-
pushProgress(`保存知情度失败:${err.message}`, "error");
|
|
4469
5273
|
} finally {
|
|
4470
5274
|
setBusy(false);
|
|
4471
5275
|
}
|
|
@@ -5079,17 +5883,6 @@ window.__ModuleLoader__.load({
|
|
|
5079
5883
|
setBusyLabel("");
|
|
5080
5884
|
}
|
|
5081
5885
|
};
|
|
5082
|
-
/** Approve a chapter manually. */
|
|
5083
|
-
const handleApprove = (no) => {
|
|
5084
|
-
setProject((prev) => prev === null ? prev : {
|
|
5085
|
-
...prev,
|
|
5086
|
-
chapters: prev.chapters.map((c) => c.no === no ? {
|
|
5087
|
-
...c,
|
|
5088
|
-
status: "approved"
|
|
5089
|
-
} : c),
|
|
5090
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5091
|
-
});
|
|
5092
|
-
};
|
|
5093
5886
|
/** Toggle chapter preview. */
|
|
5094
5887
|
const handleToggleChapter = async (no) => {
|
|
5095
5888
|
if (expandedChapter === no) {
|
|
@@ -6119,135 +6912,46 @@ window.__ModuleLoader__.load({
|
|
|
6119
6912
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6120
6913
|
className: panel_module_css_default.assetGrid,
|
|
6121
6914
|
children: [
|
|
6122
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
children: "全书进度"
|
|
6128
|
-
}),
|
|
6129
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6130
|
-
className: panel_module_css_default.assetStatValue,
|
|
6131
|
-
style: { color: "var(--nf-accent)" },
|
|
6132
|
-
children: [
|
|
6133
|
-
doneCount,
|
|
6134
|
-
"/",
|
|
6135
|
-
chapters.length,
|
|
6136
|
-
" 章"
|
|
6137
|
-
]
|
|
6138
|
-
}),
|
|
6139
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6140
|
-
className: panel_module_css_default.assetStatDetail,
|
|
6141
|
-
children: [chapters.length > 0 ? Math.round(doneCount / chapters.length * 100) : 0, "%"]
|
|
6142
|
-
})
|
|
6143
|
-
]
|
|
6144
|
-
}),
|
|
6145
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6146
|
-
className: panel_module_css_default.assetStat,
|
|
6147
|
-
children: [
|
|
6148
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6149
|
-
className: panel_module_css_default.assetStatLabel,
|
|
6150
|
-
children: "已通过审稿"
|
|
6151
|
-
}),
|
|
6152
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6153
|
-
className: panel_module_css_default.assetStatValue,
|
|
6154
|
-
style: { color: approvedCount > 0 ? "var(--nf-success)" : void 0 },
|
|
6155
|
-
children: approvedCount
|
|
6156
|
-
}),
|
|
6157
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6158
|
-
className: panel_module_css_default.assetStatDetail,
|
|
6159
|
-
children: "章节已 approved"
|
|
6160
|
-
})
|
|
6161
|
-
]
|
|
6915
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatCell, {
|
|
6916
|
+
label: "全书进度",
|
|
6917
|
+
value: `${doneCount}/${chapters.length} 章`,
|
|
6918
|
+
valueColor: "var(--nf-accent)",
|
|
6919
|
+
detail: `${chapters.length > 0 ? Math.round(doneCount / chapters.length * 100) : 0}%`
|
|
6162
6920
|
}),
|
|
6163
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6164
|
-
|
|
6165
|
-
|
|
6166
|
-
|
|
6167
|
-
|
|
6168
|
-
children: "待生成"
|
|
6169
|
-
}),
|
|
6170
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6171
|
-
className: panel_module_css_default.assetStatValue,
|
|
6172
|
-
style: { color: pendingCount > 0 ? "var(--nf-warn)" : void 0 },
|
|
6173
|
-
children: pendingCount
|
|
6174
|
-
}),
|
|
6175
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6176
|
-
className: panel_module_css_default.assetStatDetail,
|
|
6177
|
-
children: "pending + error"
|
|
6178
|
-
})
|
|
6179
|
-
]
|
|
6921
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatCell, {
|
|
6922
|
+
label: "已通过审稿",
|
|
6923
|
+
value: String(approvedCount),
|
|
6924
|
+
valueColor: approvedCount > 0 ? "var(--nf-success)" : void 0,
|
|
6925
|
+
detail: "章节已 approved"
|
|
6180
6926
|
}),
|
|
6181
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
|
|
6186
|
-
children: "待审稿"
|
|
6187
|
-
}),
|
|
6188
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6189
|
-
className: panel_module_css_default.assetStatValue,
|
|
6190
|
-
style: { color: reviewPendingCount > 0 ? "var(--nf-info)" : void 0 },
|
|
6191
|
-
children: reviewPendingCount
|
|
6192
|
-
}),
|
|
6193
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6194
|
-
className: panel_module_css_default.assetStatDetail,
|
|
6195
|
-
children: "written + rejected"
|
|
6196
|
-
})
|
|
6197
|
-
]
|
|
6927
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatCell, {
|
|
6928
|
+
label: "待生成",
|
|
6929
|
+
value: String(pendingCount),
|
|
6930
|
+
valueColor: pendingCount > 0 ? "var(--nf-warn)" : void 0,
|
|
6931
|
+
detail: "pending + error"
|
|
6198
6932
|
}),
|
|
6199
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
children: "总字数"
|
|
6205
|
-
}),
|
|
6206
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6207
|
-
className: panel_module_css_default.assetStatValue,
|
|
6208
|
-
children: totalChars
|
|
6209
|
-
}),
|
|
6210
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6211
|
-
className: panel_module_css_default.assetStatDetail,
|
|
6212
|
-
children: "已生成正文累计"
|
|
6213
|
-
})
|
|
6214
|
-
]
|
|
6933
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatCell, {
|
|
6934
|
+
label: "待审稿",
|
|
6935
|
+
value: String(reviewPendingCount),
|
|
6936
|
+
valueColor: reviewPendingCount > 0 ? "var(--nf-info)" : void 0,
|
|
6937
|
+
detail: "written + rejected"
|
|
6215
6938
|
}),
|
|
6216
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6217
|
-
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
className: panel_module_css_default.assetStatLabel,
|
|
6221
|
-
children: "当前卷"
|
|
6222
|
-
}),
|
|
6223
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6224
|
-
className: panel_module_css_default.assetStatValue,
|
|
6225
|
-
style: { fontSize: 13 },
|
|
6226
|
-
children: currentVolumeName
|
|
6227
|
-
}),
|
|
6228
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6229
|
-
className: panel_module_css_default.assetStatDetail,
|
|
6230
|
-
children: "正在推进的卷"
|
|
6231
|
-
})
|
|
6232
|
-
]
|
|
6939
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatCell, {
|
|
6940
|
+
label: "总字数",
|
|
6941
|
+
value: String(totalChars),
|
|
6942
|
+
detail: "已生成正文累计"
|
|
6233
6943
|
}),
|
|
6234
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
|
|
6242
|
-
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
}),
|
|
6246
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6247
|
-
className: panel_module_css_default.assetStatDetail,
|
|
6248
|
-
children: "最近生成/编辑时间"
|
|
6249
|
-
})
|
|
6250
|
-
]
|
|
6944
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatCell, {
|
|
6945
|
+
label: "当前卷",
|
|
6946
|
+
value: currentVolumeName,
|
|
6947
|
+
valueFontSize: 13,
|
|
6948
|
+
detail: "正在推进的卷"
|
|
6949
|
+
}),
|
|
6950
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatCell, {
|
|
6951
|
+
label: "最近创作",
|
|
6952
|
+
value: lastUpdated,
|
|
6953
|
+
valueFontSize: 13,
|
|
6954
|
+
detail: "最近生成/编辑时间"
|
|
6251
6955
|
})
|
|
6252
6956
|
]
|
|
6253
6957
|
}),
|
|
@@ -6272,83 +6976,30 @@ window.__ModuleLoader__.load({
|
|
|
6272
6976
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6273
6977
|
className: panel_module_css_default.assetGrid,
|
|
6274
6978
|
children: [
|
|
6275
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
children: "道藏"
|
|
6281
|
-
}),
|
|
6282
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6283
|
-
className: panel_module_css_default.assetStatValue,
|
|
6284
|
-
style: { color: bible !== void 0 ? "var(--nf-success)" : "var(--nf-text-3)" },
|
|
6285
|
-
children: bible !== void 0 ? `✓ ${bible.worldRules.length} 条规则` : "未生成"
|
|
6286
|
-
}),
|
|
6287
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6288
|
-
className: panel_module_css_default.assetStatDetail,
|
|
6289
|
-
children: bible !== void 0 ? `${bible.characters.length} 人物 · ${bible.redLines.length} 红线` : "提炼人设 / 世界观 / 金手指"
|
|
6290
|
-
})
|
|
6291
|
-
]
|
|
6979
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatCell, {
|
|
6980
|
+
label: "道藏",
|
|
6981
|
+
value: bible !== void 0 ? `✓ ${bible.worldRules.length} 条规则` : "未生成",
|
|
6982
|
+
valueColor: bible !== void 0 ? "var(--nf-success)" : "var(--nf-text-3)",
|
|
6983
|
+
detail: bible !== void 0 ? `${bible.characters.length} 人物 · ${bible.redLines.length} 红线` : "提炼人设 / 世界观 / 金手指"
|
|
6292
6984
|
}),
|
|
6293
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6298
|
-
|
|
6299
|
-
}),
|
|
6300
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6301
|
-
className: panel_module_css_default.assetStatValue,
|
|
6302
|
-
style: { color: volumes !== void 0 ? "var(--nf-success)" : "var(--nf-text-3)" },
|
|
6303
|
-
children: volumes !== void 0 ? `${volumes.length} 卷` : "未生成"
|
|
6304
|
-
}),
|
|
6305
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6306
|
-
className: panel_module_css_default.assetStatDetail,
|
|
6307
|
-
title: volumes?.map((v) => v.title).join(" / "),
|
|
6308
|
-
children: volumes !== void 0 ? volumes.map((v) => v.title).join(" / ") : "按剧情弧线划分全书"
|
|
6309
|
-
})
|
|
6310
|
-
]
|
|
6985
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatCell, {
|
|
6986
|
+
label: "卷计划",
|
|
6987
|
+
value: volumes !== void 0 ? `${volumes.length} 卷` : "未生成",
|
|
6988
|
+
valueColor: volumes !== void 0 ? "var(--nf-success)" : "var(--nf-text-3)",
|
|
6989
|
+
detail: volumes !== void 0 ? volumes.map((v) => v.title).join(" / ") : "按剧情弧线划分全书",
|
|
6990
|
+
detailTitle: volumes?.map((v) => v.title).join(" / ")
|
|
6311
6991
|
}),
|
|
6312
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6313
|
-
|
|
6314
|
-
|
|
6315
|
-
|
|
6316
|
-
|
|
6317
|
-
|
|
6318
|
-
}),
|
|
6319
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6320
|
-
className: panel_module_css_default.assetStatValue,
|
|
6321
|
-
style: { color: assetCount > 0 ? "var(--nf-success)" : "var(--nf-text-3)" },
|
|
6322
|
-
children: [assetCount, " 项"]
|
|
6323
|
-
}),
|
|
6324
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6325
|
-
className: panel_module_css_default.assetStatDetail,
|
|
6326
|
-
title: assetSummary,
|
|
6327
|
-
children: assetSummary
|
|
6328
|
-
})
|
|
6329
|
-
]
|
|
6992
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatCell, {
|
|
6993
|
+
label: "写作资产",
|
|
6994
|
+
value: `${assetCount} 项`,
|
|
6995
|
+
valueColor: assetCount > 0 ? "var(--nf-success)" : "var(--nf-text-3)",
|
|
6996
|
+
detail: assetSummary,
|
|
6997
|
+
detailTitle: assetSummary
|
|
6330
6998
|
}),
|
|
6331
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
className: panel_module_css_default.assetStatLabel,
|
|
6336
|
-
children: "伏笔"
|
|
6337
|
-
}),
|
|
6338
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6339
|
-
className: panel_module_css_default.assetStatValue,
|
|
6340
|
-
children: [foreshadows.length, " 条"]
|
|
6341
|
-
}),
|
|
6342
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6343
|
-
className: panel_module_css_default.assetStatDetail,
|
|
6344
|
-
children: [
|
|
6345
|
-
foreshadows.filter((f) => f.status === "planned").length,
|
|
6346
|
-
" 待埋 · ",
|
|
6347
|
-
foreshadows.filter((f) => f.status === "resolved").length,
|
|
6348
|
-
" 已回收"
|
|
6349
|
-
]
|
|
6350
|
-
})
|
|
6351
|
-
]
|
|
6999
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatCell, {
|
|
7000
|
+
label: "伏笔",
|
|
7001
|
+
value: `${foreshadows.length} 条`,
|
|
7002
|
+
detail: `${foreshadows.filter((f) => f.status === "planned").length} 待埋 · ${foreshadows.filter((f) => f.status === "resolved").length} 已回收`
|
|
6352
7003
|
})
|
|
6353
7004
|
]
|
|
6354
7005
|
})]
|
|
@@ -6513,29 +7164,12 @@ window.__ModuleLoader__.load({
|
|
|
6513
7164
|
flexDirection: "column",
|
|
6514
7165
|
gap: 6
|
|
6515
7166
|
},
|
|
6516
|
-
children: auditIssues.map((issue, i) => /* @__PURE__ */ (0, react_jsx_runtime.
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
" · [",
|
|
6523
|
-
issue.severity,
|
|
6524
|
-
"] ",
|
|
6525
|
-
issue.item
|
|
6526
|
-
] }), issue.suggestion !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
6527
|
-
className: panel_module_css_default.meta,
|
|
6528
|
-
children: ["建议:", issue.suggestion]
|
|
6529
|
-
})]
|
|
6530
|
-
}), issue.chapterNo > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6531
|
-
type: "button",
|
|
6532
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
6533
|
-
disabled: busy,
|
|
6534
|
-
onClick: () => {
|
|
6535
|
-
openWorkspace(issue.chapterNo, `按质检意见修订:${issue.item}(建议:${issue.suggestion})`);
|
|
6536
|
-
},
|
|
6537
|
-
children: "去修订"
|
|
6538
|
-
})]
|
|
7167
|
+
children: auditIssues.map((issue, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AuditIssueRow, {
|
|
7168
|
+
issue,
|
|
7169
|
+
disabled: busy,
|
|
7170
|
+
onFix: () => {
|
|
7171
|
+
openWorkspace(issue.chapterNo, `按质检意见修订:${issue.item}(建议:${issue.suggestion})`);
|
|
7172
|
+
}
|
|
6539
7173
|
}, i))
|
|
6540
7174
|
})]
|
|
6541
7175
|
}),
|
|
@@ -6547,23 +7181,13 @@ window.__ModuleLoader__.load({
|
|
|
6547
7181
|
}), todos.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6548
7182
|
className: panel_module_css_default.meta,
|
|
6549
7183
|
children: "🎉 暂无待办,一切顺畅"
|
|
6550
|
-
}) : todos.map((todo, i) => /* @__PURE__ */ (0, react_jsx_runtime.
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
})]
|
|
6558
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6559
|
-
type: "button",
|
|
6560
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
6561
|
-
disabled: busy,
|
|
6562
|
-
onClick: () => {
|
|
6563
|
-
todo.onClick();
|
|
6564
|
-
},
|
|
6565
|
-
children: todo.actionLabel
|
|
6566
|
-
})]
|
|
7184
|
+
}) : todos.map((todo, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TodoRow, {
|
|
7185
|
+
tone: todo.tone,
|
|
7186
|
+
title: todo.title,
|
|
7187
|
+
description: todo.description,
|
|
7188
|
+
actionLabel: todo.actionLabel,
|
|
7189
|
+
disabled: busy,
|
|
7190
|
+
onAction: todo.onClick
|
|
6567
7191
|
}, i))]
|
|
6568
7192
|
})
|
|
6569
7193
|
] }),
|
|
@@ -7339,6 +7963,16 @@ window.__ModuleLoader__.load({
|
|
|
7339
7963
|
},
|
|
7340
7964
|
children: tt("plan.write")
|
|
7341
7965
|
}),
|
|
7966
|
+
chapter.status === "generating" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7967
|
+
type: "button",
|
|
7968
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
7969
|
+
disabled: busy,
|
|
7970
|
+
onClick: () => {
|
|
7971
|
+
handleChapterReset(chapter.no);
|
|
7972
|
+
},
|
|
7973
|
+
title: "生成卡死/中断时可复位为待生成,重新生成",
|
|
7974
|
+
children: "🔄 复位"
|
|
7975
|
+
}),
|
|
7342
7976
|
(chapter.status === "written" || chapter.status === "rejected") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7343
7977
|
type: "button",
|
|
7344
7978
|
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
@@ -7348,14 +7982,15 @@ window.__ModuleLoader__.load({
|
|
|
7348
7982
|
},
|
|
7349
7983
|
children: tt("plan.review")
|
|
7350
7984
|
}),
|
|
7351
|
-
chapter.status === "written" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7985
|
+
(chapter.status === "written" || chapter.status === "rejected") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7352
7986
|
type: "button",
|
|
7353
7987
|
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
7354
7988
|
disabled: busy || busyAny,
|
|
7355
7989
|
onClick: () => {
|
|
7356
|
-
|
|
7990
|
+
handleChapterApprove(chapter.no);
|
|
7357
7991
|
},
|
|
7358
|
-
|
|
7992
|
+
title: "作者行使最终决定权:直接通过(不重审,保留审稿记录,落盘保存)",
|
|
7993
|
+
children: "✔ 直接通过"
|
|
7359
7994
|
}),
|
|
7360
7995
|
(chapter.status === "written" || chapter.status === "rejected" || chapter.status === "approved") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7361
7996
|
type: "button",
|
|
@@ -7776,147 +8411,303 @@ window.__ModuleLoader__.load({
|
|
|
7776
8411
|
pushProgress(`大世界已保存:${w.realms.length} 境界 · ${w.regions.length} 区域 · ${w.factions.length} 势力`, "done");
|
|
7777
8412
|
}
|
|
7778
8413
|
}),
|
|
7779
|
-
activeTab === "
|
|
8414
|
+
activeTab === "roles" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7780
8415
|
className: panel_module_css_default.card,
|
|
8416
|
+
style: {
|
|
8417
|
+
flex: 1,
|
|
8418
|
+
minHeight: 0
|
|
8419
|
+
},
|
|
7781
8420
|
children: [
|
|
7782
8421
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7783
8422
|
className: panel_module_css_default.row,
|
|
7784
|
-
style: {
|
|
7785
|
-
|
|
8423
|
+
style: {
|
|
8424
|
+
justifyContent: "space-between",
|
|
8425
|
+
flexWrap: "wrap"
|
|
8426
|
+
},
|
|
8427
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
7786
8428
|
className: panel_module_css_default.cardTitle,
|
|
7787
|
-
children:
|
|
8429
|
+
children: [
|
|
8430
|
+
"👥 角色库(",
|
|
8431
|
+
(project?.roles ?? []).length,
|
|
8432
|
+
" 个)"
|
|
8433
|
+
]
|
|
7788
8434
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7789
8435
|
className: panel_module_css_default.row,
|
|
7790
8436
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7791
8437
|
type: "button",
|
|
7792
8438
|
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
7793
|
-
disabled: busy ||
|
|
8439
|
+
disabled: busy || (project?.facts ?? []).length === 0,
|
|
7794
8440
|
onClick: () => {
|
|
7795
|
-
|
|
8441
|
+
handleCharactersRefresh();
|
|
7796
8442
|
},
|
|
7797
|
-
title: "
|
|
7798
|
-
children: "
|
|
8443
|
+
title: "从编年录聚合各角色当前状态(境界/伤势/心境/出场统计),显示在每张卡上",
|
|
8444
|
+
children: "↻ 从编年录刷新状态"
|
|
7799
8445
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7800
8446
|
type: "button",
|
|
7801
8447
|
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
7802
|
-
disabled: busy ||
|
|
8448
|
+
disabled: busy || doneCount === 0,
|
|
7803
8449
|
onClick: () => {
|
|
7804
|
-
|
|
8450
|
+
handleRolesExtract();
|
|
7805
8451
|
},
|
|
7806
|
-
|
|
8452
|
+
title: "AI 扫描大纲/编年录/已写章节,提炼完整角色库(含女主/女配/反派定位)",
|
|
8453
|
+
children: "✨ 从全书提炼角色"
|
|
7807
8454
|
})]
|
|
7808
8455
|
})]
|
|
7809
8456
|
}),
|
|
7810
|
-
|
|
7811
|
-
className: panel_module_css_default.meta,
|
|
7812
|
-
children: (project?.facts ?? []).length === 0 ? "暂无编年录(生成章节后自动积累人物状态/境界/资源/关系等事实),刷新按钮将在有事实后可用。" : "点击「从编年录刷新」聚合各人物当前状态(境界/资源/伤势/心境)。"
|
|
7813
|
-
}) : charCards.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8457
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7814
8458
|
className: panel_module_css_default.meta,
|
|
7815
|
-
children: "
|
|
7816
|
-
})
|
|
8459
|
+
children: "角色库是全书角色主表:定位(女主/女配/配角/反派)、身份、关系网、成长线、知情度——生成与审稿都会按定位规格刻画互动。点「从编年录刷新状态」可在每张卡上显示角色当前状态。"
|
|
8460
|
+
}),
|
|
8461
|
+
roleCandidates !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7817
8462
|
style: {
|
|
7818
8463
|
display: "flex",
|
|
7819
8464
|
flexDirection: "column",
|
|
7820
|
-
gap: 6
|
|
8465
|
+
gap: 6,
|
|
8466
|
+
border: "1px solid var(--nf-info)",
|
|
8467
|
+
borderRadius: 12,
|
|
8468
|
+
padding: 10
|
|
7821
8469
|
},
|
|
7822
|
-
children:
|
|
7823
|
-
|
|
7824
|
-
border: "1px solid var(--nf-border)",
|
|
7825
|
-
borderRadius: 8,
|
|
7826
|
-
padding: "6px 10px",
|
|
7827
|
-
fontSize: 12
|
|
7828
|
-
},
|
|
7829
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8470
|
+
children: [
|
|
8471
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7830
8472
|
className: panel_module_css_default.row,
|
|
7831
|
-
style: {
|
|
7832
|
-
|
|
7833
|
-
|
|
7834
|
-
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
8473
|
+
style: {
|
|
8474
|
+
justifyContent: "space-between",
|
|
8475
|
+
flexWrap: "wrap"
|
|
8476
|
+
},
|
|
8477
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [
|
|
8478
|
+
"✨ AI 提炼候选(",
|
|
8479
|
+
roleCandidates.length,
|
|
8480
|
+
")"
|
|
8481
|
+
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8482
|
+
type: "button",
|
|
8483
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
8484
|
+
onClick: () => {
|
|
8485
|
+
setRoleCandidates(null);
|
|
8486
|
+
},
|
|
8487
|
+
children: "收起"
|
|
8488
|
+
})]
|
|
8489
|
+
}),
|
|
8490
|
+
roleCandidates.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8491
|
+
className: panel_module_css_default.meta,
|
|
8492
|
+
children: "未提炼到角色。"
|
|
8493
|
+
}),
|
|
8494
|
+
roleCandidates.map((r, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RoleCandidateRow, {
|
|
8495
|
+
candidate: r,
|
|
8496
|
+
disabled: busy,
|
|
8497
|
+
onAdopt: () => {
|
|
8498
|
+
handleRoleAdopt(r);
|
|
8499
|
+
},
|
|
8500
|
+
onEdit: () => {
|
|
8501
|
+
setRoleDraft(r);
|
|
8502
|
+
}
|
|
8503
|
+
}, i))
|
|
8504
|
+
]
|
|
8505
|
+
}),
|
|
8506
|
+
roleDraft !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8507
|
+
style: {
|
|
8508
|
+
display: "flex",
|
|
8509
|
+
flexDirection: "column",
|
|
8510
|
+
gap: 8,
|
|
8511
|
+
border: "1px solid var(--nf-accent)",
|
|
8512
|
+
borderRadius: 12,
|
|
8513
|
+
padding: 10
|
|
8514
|
+
},
|
|
8515
|
+
children: [
|
|
8516
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8517
|
+
className: panel_module_css_default.row,
|
|
8518
|
+
style: { flexWrap: "wrap" },
|
|
8519
|
+
children: [
|
|
8520
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8521
|
+
className: panel_module_css_default.field,
|
|
8522
|
+
style: {
|
|
8523
|
+
flex: 1,
|
|
8524
|
+
minWidth: 140
|
|
8525
|
+
},
|
|
8526
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8527
|
+
className: panel_module_css_default.fieldLabel,
|
|
8528
|
+
children: "角色名"
|
|
8529
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
8530
|
+
className: panel_module_css_default.input,
|
|
8531
|
+
value: roleDraft.name,
|
|
8532
|
+
onChange: (e) => {
|
|
8533
|
+
setRoleDraft({
|
|
8534
|
+
...roleDraft,
|
|
8535
|
+
name: e.target.value
|
|
8536
|
+
});
|
|
8537
|
+
}
|
|
8538
|
+
})]
|
|
8539
|
+
}),
|
|
8540
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8541
|
+
className: panel_module_css_default.field,
|
|
8542
|
+
style: { flex: 1 },
|
|
8543
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8544
|
+
className: panel_module_css_default.fieldLabel,
|
|
8545
|
+
children: "定位"
|
|
8546
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
8547
|
+
className: panel_module_css_default.input,
|
|
8548
|
+
value: roleDraft.roleLabel,
|
|
8549
|
+
onChange: (e) => {
|
|
8550
|
+
setRoleDraft({
|
|
8551
|
+
...roleDraft,
|
|
8552
|
+
roleLabel: e.target.value
|
|
8553
|
+
});
|
|
8554
|
+
},
|
|
8555
|
+
children: [
|
|
8556
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8557
|
+
value: "protagonist",
|
|
8558
|
+
children: "主角"
|
|
8559
|
+
}),
|
|
8560
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8561
|
+
value: "female_lead",
|
|
8562
|
+
children: "女主"
|
|
8563
|
+
}),
|
|
8564
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8565
|
+
value: "female_support",
|
|
8566
|
+
children: "女配"
|
|
8567
|
+
}),
|
|
8568
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8569
|
+
value: "support",
|
|
8570
|
+
children: "配角"
|
|
8571
|
+
}),
|
|
8572
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8573
|
+
value: "antagonist",
|
|
8574
|
+
children: "反派"
|
|
8575
|
+
}),
|
|
8576
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
8577
|
+
value: "extra",
|
|
8578
|
+
children: "路人"
|
|
8579
|
+
})
|
|
8580
|
+
]
|
|
8581
|
+
})]
|
|
8582
|
+
}),
|
|
8583
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8584
|
+
className: panel_module_css_default.field,
|
|
8585
|
+
style: { flex: 2 },
|
|
8586
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8587
|
+
className: panel_module_css_default.fieldLabel,
|
|
8588
|
+
children: "身份"
|
|
8589
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
8590
|
+
className: panel_module_css_default.input,
|
|
8591
|
+
value: roleDraft.identity,
|
|
8592
|
+
onChange: (e) => {
|
|
8593
|
+
setRoleDraft({
|
|
8594
|
+
...roleDraft,
|
|
8595
|
+
identity: e.target.value
|
|
8596
|
+
});
|
|
8597
|
+
}
|
|
8598
|
+
})]
|
|
8599
|
+
})
|
|
8600
|
+
]
|
|
8601
|
+
}),
|
|
8602
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8603
|
+
className: panel_module_css_default.field,
|
|
8604
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8605
|
+
className: panel_module_css_default.fieldLabel,
|
|
8606
|
+
children: "目标"
|
|
8607
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
8608
|
+
className: panel_module_css_default.textarea,
|
|
8609
|
+
style: { minHeight: 44 },
|
|
8610
|
+
value: roleDraft.goals,
|
|
8611
|
+
onChange: (e) => {
|
|
8612
|
+
setRoleDraft({
|
|
8613
|
+
...roleDraft,
|
|
8614
|
+
goals: e.target.value
|
|
8615
|
+
});
|
|
8616
|
+
}
|
|
8617
|
+
})]
|
|
8618
|
+
}),
|
|
8619
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8620
|
+
className: panel_module_css_default.field,
|
|
8621
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8622
|
+
className: panel_module_css_default.fieldLabel,
|
|
8623
|
+
children: "关系网(每行一条:角色名(关系))"
|
|
8624
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
8625
|
+
className: panel_module_css_default.textarea,
|
|
8626
|
+
style: { minHeight: 44 },
|
|
8627
|
+
value: roleDraft.relations.join("\n"),
|
|
8628
|
+
onChange: (e) => {
|
|
8629
|
+
setRoleDraft({
|
|
8630
|
+
...roleDraft,
|
|
8631
|
+
relations: e.target.value.split("\n").map((l) => l.trim()).filter((l) => l !== "")
|
|
8632
|
+
});
|
|
8633
|
+
}
|
|
8634
|
+
})]
|
|
8635
|
+
}),
|
|
8636
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8637
|
+
className: panel_module_css_default.field,
|
|
8638
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8639
|
+
className: panel_module_css_default.fieldLabel,
|
|
8640
|
+
children: "成长线(每行一条:阶段:说明)"
|
|
8641
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
8642
|
+
className: panel_module_css_default.textarea,
|
|
8643
|
+
style: { minHeight: 44 },
|
|
8644
|
+
value: roleDraft.arc.join("\n"),
|
|
8645
|
+
onChange: (e) => {
|
|
8646
|
+
setRoleDraft({
|
|
8647
|
+
...roleDraft,
|
|
8648
|
+
arc: e.target.value.split("\n").map((l) => l.trim()).filter((l) => l !== "")
|
|
8649
|
+
});
|
|
8650
|
+
}
|
|
8651
|
+
})]
|
|
8652
|
+
}),
|
|
8653
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8654
|
+
className: panel_module_css_default.field,
|
|
8655
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
|
|
8656
|
+
className: panel_module_css_default.fieldLabel,
|
|
8657
|
+
children: "知情度(每行一条该角色知道的信息)"
|
|
8658
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
8659
|
+
className: panel_module_css_default.textarea,
|
|
8660
|
+
style: { minHeight: 44 },
|
|
8661
|
+
value: roleDraft.knowledge.join("\n"),
|
|
8662
|
+
onChange: (e) => {
|
|
8663
|
+
setRoleDraft({
|
|
8664
|
+
...roleDraft,
|
|
8665
|
+
knowledge: e.target.value.split("\n").map((l) => l.trim()).filter((l) => l !== "")
|
|
8666
|
+
});
|
|
8667
|
+
}
|
|
8668
|
+
})]
|
|
8669
|
+
}),
|
|
8670
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8671
|
+
className: panel_module_css_default.row,
|
|
8672
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8673
|
+
type: "button",
|
|
8674
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
8675
|
+
disabled: busy,
|
|
8676
|
+
onClick: () => {
|
|
8677
|
+
handleRoleSave();
|
|
8678
|
+
},
|
|
8679
|
+
children: "保存"
|
|
8680
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8681
|
+
type: "button",
|
|
8682
|
+
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
8683
|
+
onClick: () => {
|
|
8684
|
+
setRoleDraft(null);
|
|
8685
|
+
},
|
|
8686
|
+
children: "取消"
|
|
7842
8687
|
})]
|
|
7843
|
-
})
|
|
7844
|
-
|
|
7845
|
-
children: ["状态:", card.status]
|
|
7846
|
-
})]
|
|
7847
|
-
}, card.name))
|
|
7848
|
-
}),
|
|
7849
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7850
|
-
className: panel_module_css_default.meta,
|
|
7851
|
-
children: "人物志由「道藏」人物名单 + 「编年录」聚合而来,随章节生成自动保持最新。"
|
|
7852
|
-
})
|
|
7853
|
-
]
|
|
7854
|
-
}),
|
|
7855
|
-
activeTab === "characters" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7856
|
-
className: panel_module_css_default.card,
|
|
7857
|
-
children: [
|
|
7858
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7859
|
-
className: panel_module_css_default.row,
|
|
7860
|
-
style: {
|
|
7861
|
-
justifyContent: "space-between",
|
|
7862
|
-
flexWrap: "wrap"
|
|
7863
|
-
},
|
|
7864
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7865
|
-
className: panel_module_css_default.cardTitle,
|
|
7866
|
-
children: "角色知情度(信息差管理)"
|
|
7867
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7868
|
-
type: "button",
|
|
7869
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
7870
|
-
disabled: busy || (bible?.characters ?? []).length === 0,
|
|
7871
|
-
onClick: () => {
|
|
7872
|
-
handleKnowledgeSave();
|
|
7873
|
-
},
|
|
7874
|
-
children: "💾 保存知情度"
|
|
7875
|
-
})]
|
|
7876
|
-
}),
|
|
7877
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7878
|
-
className: panel_module_css_default.meta,
|
|
7879
|
-
children: "填写每个角色「已经知道」的事实/秘密(每行一条)。生成与审稿会严格遵守:未列出的信息该角色一律不知道——避免\"不该知道的人知道了\"。"
|
|
8688
|
+
})
|
|
8689
|
+
]
|
|
7880
8690
|
}),
|
|
7881
|
-
(
|
|
8691
|
+
(project?.roles ?? []).length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7882
8692
|
className: panel_module_css_default.meta,
|
|
7883
|
-
children: "
|
|
8693
|
+
children: "角色库为空——点「✨ 从全书提炼角色」自动建立,或手动新增。"
|
|
7884
8694
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7885
8695
|
style: {
|
|
7886
8696
|
display: "flex",
|
|
7887
8697
|
flexDirection: "column",
|
|
7888
|
-
gap:
|
|
8698
|
+
gap: 6
|
|
7889
8699
|
},
|
|
7890
|
-
children:
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
8700
|
+
children: (project?.roles ?? []).map((r) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(RoleCard, {
|
|
8701
|
+
role: r,
|
|
8702
|
+
status: (project?.roleStatus ?? []).find((s) => s.name === r.name),
|
|
8703
|
+
disabled: busy,
|
|
8704
|
+
onEdit: () => {
|
|
8705
|
+
setRoleDraft(r);
|
|
7896
8706
|
},
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
className: panel_module_css_default.meta,
|
|
7902
|
-
children: card.role === "protagonist" ? "主角" : card.role === "supporting" ? "配角" : card.role === "antagonist" ? "反派" : "其他"
|
|
7903
|
-
})]
|
|
7904
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
7905
|
-
className: panel_module_css_default.textarea,
|
|
7906
|
-
style: {
|
|
7907
|
-
minHeight: 52,
|
|
7908
|
-
fontSize: 12
|
|
7909
|
-
},
|
|
7910
|
-
placeholder: "每行一条该角色知道的信息,例如:林越的真实身份 / 古玉残片的秘密…",
|
|
7911
|
-
value: knowledgeDraft[card.name] ?? (card.knowledge ?? []).join("\n"),
|
|
7912
|
-
onChange: (e) => {
|
|
7913
|
-
setKnowledgeDraft((prev) => ({
|
|
7914
|
-
...prev,
|
|
7915
|
-
[card.name]: e.target.value
|
|
7916
|
-
}));
|
|
7917
|
-
}
|
|
7918
|
-
})]
|
|
7919
|
-
}, card.name))
|
|
8707
|
+
onRemove: () => {
|
|
8708
|
+
handleRoleRemove(r.name);
|
|
8709
|
+
}
|
|
8710
|
+
}, r.name))
|
|
7920
8711
|
})
|
|
7921
8712
|
]
|
|
7922
8713
|
}),
|
|
@@ -8535,288 +9326,35 @@ window.__ModuleLoader__.load({
|
|
|
8535
9326
|
className: panel_module_css_default.meta,
|
|
8536
9327
|
children: tt("plotlines.hint")
|
|
8537
9328
|
}),
|
|
8538
|
-
plotlineHealth !== null && /* @__PURE__ */ (0, react_jsx_runtime.
|
|
8539
|
-
|
|
8540
|
-
|
|
8541
|
-
|
|
8542
|
-
|
|
8543
|
-
border: "1px solid var(--nf-info)",
|
|
8544
|
-
borderRadius: 12,
|
|
8545
|
-
padding: 10
|
|
9329
|
+
plotlineHealth !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlotlineHealthPanel, {
|
|
9330
|
+
report: plotlineHealth,
|
|
9331
|
+
disabled: busy,
|
|
9332
|
+
onPlan: () => {
|
|
9333
|
+
handlePlotlinePlan();
|
|
8546
9334
|
},
|
|
8547
|
-
|
|
8548
|
-
|
|
8549
|
-
|
|
8550
|
-
style: {
|
|
8551
|
-
justifyContent: "space-between",
|
|
8552
|
-
flexWrap: "wrap"
|
|
8553
|
-
},
|
|
8554
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "🩺 剧情健康检查" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8555
|
-
style: {
|
|
8556
|
-
display: "flex",
|
|
8557
|
-
gap: 8
|
|
8558
|
-
},
|
|
8559
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8560
|
-
type: "button",
|
|
8561
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
8562
|
-
disabled: busy,
|
|
8563
|
-
onClick: () => {
|
|
8564
|
-
handlePlotlinePlan();
|
|
8565
|
-
},
|
|
8566
|
-
title: "基于本次诊断生成下一阶段剧情方案",
|
|
8567
|
-
children: "✨ 基于此设计方案"
|
|
8568
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8569
|
-
type: "button",
|
|
8570
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
8571
|
-
onClick: () => {
|
|
8572
|
-
setPlotlineHealth(null);
|
|
8573
|
-
},
|
|
8574
|
-
children: "收起"
|
|
8575
|
-
})]
|
|
8576
|
-
})]
|
|
8577
|
-
}),
|
|
8578
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8579
|
-
style: {
|
|
8580
|
-
fontSize: 12,
|
|
8581
|
-
fontWeight: 700,
|
|
8582
|
-
color: "var(--nf-accent)"
|
|
8583
|
-
},
|
|
8584
|
-
children: ["判定:", plotlineHealth.verdict]
|
|
8585
|
-
}),
|
|
8586
|
-
plotlineHealth.timing !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8587
|
-
className: panel_module_css_default.meta,
|
|
8588
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "建议时机:" }), plotlineHealth.timing]
|
|
8589
|
-
}),
|
|
8590
|
-
plotlineHealth.reasons.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8591
|
-
style: {
|
|
8592
|
-
display: "flex",
|
|
8593
|
-
flexDirection: "column",
|
|
8594
|
-
gap: 2,
|
|
8595
|
-
fontSize: 12
|
|
8596
|
-
},
|
|
8597
|
-
children: plotlineHealth.reasons.map((r, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8598
|
-
className: panel_module_css_default.meta,
|
|
8599
|
-
children: ["· ", r]
|
|
8600
|
-
}, i))
|
|
8601
|
-
}),
|
|
8602
|
-
plotlineHealth.lines.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8603
|
-
style: {
|
|
8604
|
-
display: "flex",
|
|
8605
|
-
flexDirection: "column",
|
|
8606
|
-
gap: 4,
|
|
8607
|
-
fontSize: 12
|
|
8608
|
-
},
|
|
8609
|
-
children: plotlineHealth.lines.map((l, i) => {
|
|
8610
|
-
const color = l.health === "ok" ? "var(--nf-success)" : l.health === "warning" ? "var(--nf-warn)" : "var(--nf-error)";
|
|
8611
|
-
const label = l.health === "ok" ? "健康" : l.health === "warning" ? "预警" : "搁置过久";
|
|
8612
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8613
|
-
style: {
|
|
8614
|
-
display: "flex",
|
|
8615
|
-
gap: 8,
|
|
8616
|
-
alignItems: "flex-start"
|
|
8617
|
-
},
|
|
8618
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8619
|
-
className: panel_module_css_default.badge,
|
|
8620
|
-
style: {
|
|
8621
|
-
borderColor: color,
|
|
8622
|
-
color,
|
|
8623
|
-
flex: "none",
|
|
8624
|
-
marginTop: 1
|
|
8625
|
-
},
|
|
8626
|
-
children: label
|
|
8627
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8628
|
-
className: panel_module_css_default.meta,
|
|
8629
|
-
children: [
|
|
8630
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: l.name }),
|
|
8631
|
-
":",
|
|
8632
|
-
l.note
|
|
8633
|
-
]
|
|
8634
|
-
})]
|
|
8635
|
-
}, i);
|
|
8636
|
-
})
|
|
8637
|
-
})
|
|
8638
|
-
]
|
|
9335
|
+
onClose: () => {
|
|
9336
|
+
setPlotlineHealth(null);
|
|
9337
|
+
}
|
|
8639
9338
|
}),
|
|
8640
|
-
plotlinePlan !== null && /* @__PURE__ */ (0, react_jsx_runtime.
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
|
|
8644
|
-
|
|
8645
|
-
border: "1px solid var(--nf-accent)",
|
|
8646
|
-
borderRadius: 12,
|
|
8647
|
-
padding: 10
|
|
9339
|
+
plotlinePlan !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlotlinePlanPanel, {
|
|
9340
|
+
plan: plotlinePlan,
|
|
9341
|
+
disabled: busy,
|
|
9342
|
+
onAdopt: (s) => {
|
|
9343
|
+
handlePlanAdopt(s);
|
|
8648
9344
|
},
|
|
8649
|
-
|
|
8650
|
-
|
|
8651
|
-
|
|
8652
|
-
style: {
|
|
8653
|
-
justifyContent: "space-between",
|
|
8654
|
-
flexWrap: "wrap"
|
|
8655
|
-
},
|
|
8656
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "✨ AI 剧情方案" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8657
|
-
type: "button",
|
|
8658
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
8659
|
-
onClick: () => {
|
|
8660
|
-
setPlotlinePlan(null);
|
|
8661
|
-
},
|
|
8662
|
-
children: "收起"
|
|
8663
|
-
})]
|
|
8664
|
-
}),
|
|
8665
|
-
plotlinePlan.direction !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8666
|
-
className: panel_module_css_default.meta,
|
|
8667
|
-
style: { fontSize: 12 },
|
|
8668
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: "下一阶段方向:" }), plotlinePlan.direction]
|
|
8669
|
-
}),
|
|
8670
|
-
plotlinePlan.suggestions.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8671
|
-
style: {
|
|
8672
|
-
display: "flex",
|
|
8673
|
-
flexDirection: "column",
|
|
8674
|
-
gap: 4,
|
|
8675
|
-
fontSize: 12
|
|
8676
|
-
},
|
|
8677
|
-
children: plotlinePlan.suggestions.map((s, i) => {
|
|
8678
|
-
const kindLabel = {
|
|
8679
|
-
main: tt("plotlines.kindMain"),
|
|
8680
|
-
branch: tt("plotlines.kindBranch"),
|
|
8681
|
-
character: tt("plotlines.kindCharacter"),
|
|
8682
|
-
mystery: tt("plotlines.kindMystery")
|
|
8683
|
-
}[s.kind];
|
|
8684
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8685
|
-
style: {
|
|
8686
|
-
border: "1px solid var(--nf-border)",
|
|
8687
|
-
borderRadius: 8,
|
|
8688
|
-
padding: "6px 10px"
|
|
8689
|
-
},
|
|
8690
|
-
children: [
|
|
8691
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8692
|
-
className: panel_module_css_default.row,
|
|
8693
|
-
style: {
|
|
8694
|
-
justifyContent: "space-between",
|
|
8695
|
-
flexWrap: "wrap"
|
|
8696
|
-
},
|
|
8697
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8698
|
-
style: {
|
|
8699
|
-
display: "flex",
|
|
8700
|
-
alignItems: "center",
|
|
8701
|
-
gap: 6,
|
|
8702
|
-
flexWrap: "wrap"
|
|
8703
|
-
},
|
|
8704
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: s.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8705
|
-
className: panel_module_css_default.badge,
|
|
8706
|
-
style: {
|
|
8707
|
-
borderColor: "var(--nf-accent)",
|
|
8708
|
-
color: "var(--nf-accent)"
|
|
8709
|
-
},
|
|
8710
|
-
children: kindLabel
|
|
8711
|
-
})]
|
|
8712
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8713
|
-
type: "button",
|
|
8714
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
8715
|
-
disabled: busy,
|
|
8716
|
-
onClick: () => {
|
|
8717
|
-
handlePlanAdopt(s);
|
|
8718
|
-
},
|
|
8719
|
-
children: "+ 采纳"
|
|
8720
|
-
})]
|
|
8721
|
-
}),
|
|
8722
|
-
s.goal !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8723
|
-
className: panel_module_css_default.meta,
|
|
8724
|
-
children: s.goal
|
|
8725
|
-
}),
|
|
8726
|
-
s.progress !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8727
|
-
className: panel_module_css_default.meta,
|
|
8728
|
-
children: ["初始进度:", s.progress]
|
|
8729
|
-
})
|
|
8730
|
-
]
|
|
8731
|
-
}, i);
|
|
8732
|
-
})
|
|
8733
|
-
})
|
|
8734
|
-
]
|
|
9345
|
+
onClose: () => {
|
|
9346
|
+
setPlotlinePlan(null);
|
|
9347
|
+
}
|
|
8735
9348
|
}),
|
|
8736
|
-
plotlineSuggestions !== null && /* @__PURE__ */ (0, react_jsx_runtime.
|
|
8737
|
-
|
|
8738
|
-
|
|
8739
|
-
|
|
8740
|
-
|
|
8741
|
-
border: "1px solid var(--nf-info)",
|
|
8742
|
-
borderRadius: 12,
|
|
8743
|
-
padding: 10
|
|
9349
|
+
plotlineSuggestions !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlotlineSuggestionPanel, {
|
|
9350
|
+
suggestions: plotlineSuggestions,
|
|
9351
|
+
disabled: busy,
|
|
9352
|
+
onAdopt: (s) => {
|
|
9353
|
+
handlePlotlineAdopt(s);
|
|
8744
9354
|
},
|
|
8745
|
-
|
|
8746
|
-
|
|
8747
|
-
|
|
8748
|
-
style: {
|
|
8749
|
-
justifyContent: "space-between",
|
|
8750
|
-
flexWrap: "wrap"
|
|
8751
|
-
},
|
|
8752
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [
|
|
8753
|
-
"✨ AI 建议(",
|
|
8754
|
-
plotlineSuggestions.length,
|
|
8755
|
-
" 条)"
|
|
8756
|
-
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8757
|
-
type: "button",
|
|
8758
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
8759
|
-
onClick: () => {
|
|
8760
|
-
setPlotlineSuggestions(null);
|
|
8761
|
-
},
|
|
8762
|
-
children: "收起"
|
|
8763
|
-
})]
|
|
8764
|
-
}),
|
|
8765
|
-
plotlineSuggestions.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8766
|
-
className: panel_module_css_default.meta,
|
|
8767
|
-
children: "没有候选线。"
|
|
8768
|
-
}),
|
|
8769
|
-
plotlineSuggestions.map((s, i) => {
|
|
8770
|
-
const kindLabel = {
|
|
8771
|
-
main: tt("plotlines.kindMain"),
|
|
8772
|
-
branch: tt("plotlines.kindBranch"),
|
|
8773
|
-
character: tt("plotlines.kindCharacter"),
|
|
8774
|
-
mystery: tt("plotlines.kindMystery")
|
|
8775
|
-
}[s.kind];
|
|
8776
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8777
|
-
style: {
|
|
8778
|
-
border: "1px solid var(--nf-border)",
|
|
8779
|
-
borderRadius: 8,
|
|
8780
|
-
padding: "6px 10px",
|
|
8781
|
-
fontSize: 12
|
|
8782
|
-
},
|
|
8783
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8784
|
-
className: panel_module_css_default.row,
|
|
8785
|
-
style: {
|
|
8786
|
-
justifyContent: "space-between",
|
|
8787
|
-
flexWrap: "wrap"
|
|
8788
|
-
},
|
|
8789
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8790
|
-
style: {
|
|
8791
|
-
display: "flex",
|
|
8792
|
-
alignItems: "center",
|
|
8793
|
-
gap: 6,
|
|
8794
|
-
flexWrap: "wrap"
|
|
8795
|
-
},
|
|
8796
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: s.name }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8797
|
-
className: panel_module_css_default.badge,
|
|
8798
|
-
style: {
|
|
8799
|
-
borderColor: "var(--nf-accent)",
|
|
8800
|
-
color: "var(--nf-accent)"
|
|
8801
|
-
},
|
|
8802
|
-
children: kindLabel
|
|
8803
|
-
})]
|
|
8804
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
8805
|
-
type: "button",
|
|
8806
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall} ${panel_module_css_default.buttonPrimary}`,
|
|
8807
|
-
disabled: busy,
|
|
8808
|
-
onClick: () => {
|
|
8809
|
-
handlePlotlineAdopt(s);
|
|
8810
|
-
},
|
|
8811
|
-
children: "+ 采纳"
|
|
8812
|
-
})]
|
|
8813
|
-
}), s.goal !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8814
|
-
className: panel_module_css_default.meta,
|
|
8815
|
-
children: s.goal
|
|
8816
|
-
})]
|
|
8817
|
-
}, i);
|
|
8818
|
-
})
|
|
8819
|
-
]
|
|
9355
|
+
onClose: () => {
|
|
9356
|
+
setPlotlineSuggestions(null);
|
|
9357
|
+
}
|
|
8820
9358
|
}),
|
|
8821
9359
|
plotlineDraft !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8822
9360
|
style: {
|
|
@@ -8993,126 +9531,26 @@ window.__ModuleLoader__.load({
|
|
|
8993
9531
|
flex: 1,
|
|
8994
9532
|
minHeight: 0
|
|
8995
9533
|
},
|
|
8996
|
-
children: (project?.plotlines ?? []).map((line) => {
|
|
8997
|
-
|
|
8998
|
-
|
|
8999
|
-
|
|
9000
|
-
|
|
9001
|
-
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
|
|
9005
|
-
|
|
9006
|
-
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
|
|
9016
|
-
display: "flex",
|
|
9017
|
-
flexDirection: "column",
|
|
9018
|
-
gap: 4
|
|
9019
|
-
},
|
|
9020
|
-
children: [
|
|
9021
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9022
|
-
className: panel_module_css_default.row,
|
|
9023
|
-
style: {
|
|
9024
|
-
justifyContent: "space-between",
|
|
9025
|
-
flexWrap: "wrap"
|
|
9026
|
-
},
|
|
9027
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
9028
|
-
style: {
|
|
9029
|
-
display: "flex",
|
|
9030
|
-
alignItems: "center",
|
|
9031
|
-
gap: 6,
|
|
9032
|
-
flexWrap: "wrap"
|
|
9033
|
-
},
|
|
9034
|
-
children: [
|
|
9035
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("b", { children: line.name }),
|
|
9036
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9037
|
-
className: panel_module_css_default.badge,
|
|
9038
|
-
style: {
|
|
9039
|
-
borderColor: "var(--nf-accent)",
|
|
9040
|
-
color: "var(--nf-accent)"
|
|
9041
|
-
},
|
|
9042
|
-
children: kindLabel
|
|
9043
|
-
}),
|
|
9044
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
9045
|
-
className: panel_module_css_default.badge,
|
|
9046
|
-
style: {
|
|
9047
|
-
borderColor: statusColor,
|
|
9048
|
-
color: statusColor
|
|
9049
|
-
},
|
|
9050
|
-
children: statusLabel
|
|
9051
|
-
})
|
|
9052
|
-
]
|
|
9053
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
9054
|
-
style: {
|
|
9055
|
-
display: "flex",
|
|
9056
|
-
gap: 6
|
|
9057
|
-
},
|
|
9058
|
-
children: [
|
|
9059
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
9060
|
-
type: "button",
|
|
9061
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
9062
|
-
disabled: busy,
|
|
9063
|
-
onClick: () => {
|
|
9064
|
-
handlePlotlineRefresh(line.id);
|
|
9065
|
-
},
|
|
9066
|
-
title: "AI 结合编年录与章节摘要,自动更新这条线的当前进度",
|
|
9067
|
-
children: "↻ AI 刷新进度"
|
|
9068
|
-
}),
|
|
9069
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
9070
|
-
type: "button",
|
|
9071
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
9072
|
-
disabled: busy,
|
|
9073
|
-
onClick: () => {
|
|
9074
|
-
setPlotlineDraft({
|
|
9075
|
-
id: line.id,
|
|
9076
|
-
name: line.name,
|
|
9077
|
-
kind: line.kind,
|
|
9078
|
-
goal: line.goal,
|
|
9079
|
-
progress: line.progress,
|
|
9080
|
-
status: line.status
|
|
9081
|
-
});
|
|
9082
|
-
},
|
|
9083
|
-
children: tt("plotlines.edit")
|
|
9084
|
-
}),
|
|
9085
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
9086
|
-
type: "button",
|
|
9087
|
-
className: `${panel_module_css_default.button} ${panel_module_css_default.buttonSmall}`,
|
|
9088
|
-
disabled: busy,
|
|
9089
|
-
onClick: () => {
|
|
9090
|
-
handlePlotlineRemove(line.id);
|
|
9091
|
-
},
|
|
9092
|
-
children: tt("plotlines.remove")
|
|
9093
|
-
})
|
|
9094
|
-
]
|
|
9095
|
-
})]
|
|
9096
|
-
}),
|
|
9097
|
-
line.goal !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9098
|
-
className: panel_module_css_default.meta,
|
|
9099
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [tt("plotlines.goal"), ":"] }), line.goal]
|
|
9100
|
-
}),
|
|
9101
|
-
line.progress !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9102
|
-
className: panel_module_css_default.meta,
|
|
9103
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("b", { children: [tt("plotlines.progress"), ":"] }), line.progress]
|
|
9104
|
-
}),
|
|
9105
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9106
|
-
className: panel_module_css_default.meta,
|
|
9107
|
-
children: [
|
|
9108
|
-
tt("plotlines.chapters"),
|
|
9109
|
-
":",
|
|
9110
|
-
line.chapters.length > 0 ? line.chapters.map((n) => `第${n}章`).join("、") : "—"
|
|
9111
|
-
]
|
|
9112
|
-
})
|
|
9113
|
-
]
|
|
9114
|
-
}, line.id);
|
|
9115
|
-
})
|
|
9534
|
+
children: (project?.plotlines ?? []).map((line) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PlotlineCard, {
|
|
9535
|
+
line,
|
|
9536
|
+
disabled: busy,
|
|
9537
|
+
onRefresh: () => {
|
|
9538
|
+
handlePlotlineRefresh(line.id);
|
|
9539
|
+
},
|
|
9540
|
+
onEdit: () => {
|
|
9541
|
+
setPlotlineDraft({
|
|
9542
|
+
id: line.id,
|
|
9543
|
+
name: line.name,
|
|
9544
|
+
kind: line.kind,
|
|
9545
|
+
goal: line.goal,
|
|
9546
|
+
progress: line.progress,
|
|
9547
|
+
status: line.status
|
|
9548
|
+
});
|
|
9549
|
+
},
|
|
9550
|
+
onRemove: () => {
|
|
9551
|
+
handlePlotlineRemove(line.id);
|
|
9552
|
+
}
|
|
9553
|
+
}, line.id))
|
|
9116
9554
|
})
|
|
9117
9555
|
]
|
|
9118
9556
|
})
|