luckytri 1.2.0 → 1.2.2
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.en.md +12 -14
- package/README.md +1 -3
- package/docs/en/CHANGELOG.md +17 -1
- package/docs/en/architecture.md +2 -2
- package/docs/en/guide.md +2 -0
- package/docs/en/npm-release.md +6 -0
- package/docs/zh/CHANGELOG.md +17 -1
- package/docs/zh/architecture.md +2 -2
- package/docs/zh/guide.md +2 -0
- package/docs/zh/npm-release.md +8 -0
- package/package.json +25 -3
- package/public/app/assets/{ChatsPage-eDqFIg97.js → ChatsPage-GGOaUl3H.js} +1 -1
- package/public/app/assets/{Empty-CAGOJsfD.js → Empty-BSmsWoGM.js} +1 -1
- package/public/app/assets/{Field-CRz-JmN1.js → Field-tUGp0-YL.js} +1 -1
- package/public/app/assets/{HeartPage-BGWoeMrC.js → HeartPage-B5_e1hI9.js} +1 -1
- package/public/app/assets/{LifePage-iao3o3wt.js → LifePage-D5P5kTzy.js} +1 -1
- package/public/app/assets/{MemoryPage-Dwi2yi7E.js → MemoryPage-BrSPiqOS.js} +1 -1
- package/public/app/assets/{NaturePage-DniImo9U.js → NaturePage-C0BdvfFu.js} +1 -1
- package/public/app/assets/{PeoplePage-D-MC3JEt.js → PeoplePage-DBT70lu7.js} +1 -1
- package/public/app/assets/{PluginsPage-D7dJTf96.js → PluginsPage-QBiQg3Jc.js} +1 -1
- package/public/app/assets/{SystemPage-C_Y5M7JU.css → SystemPage-Cf8lKh5C.css} +1 -1
- package/public/app/assets/{SystemPage-C5CUHjGh.js → SystemPage-EFOEvom-.js} +1 -1
- package/public/app/assets/{TimePage-Dwhr3-92.js → TimePage-BuNKjCgN.js} +1 -1
- package/public/app/assets/{index-L0bHax8C.js → index-BaXEYeFH.js} +3 -3
- package/public/app/assets/{knowledge-BTDNafzl.js → knowledge-COyBves6.js} +1 -1
- package/public/app/assets/{media-BBzOAfNG.js → media-8uRD5Ocs.js} +1 -1
- package/public/app/assets/{mind-CBTkFje2.js → mind-CQkvddhx.js} +1 -1
- package/public/app/index.html +3 -3
- package/public/guide.en.html +14 -3
- package/public/guide.html +15 -3
- package/public/tutorial.en.md +2 -0
- package/public/tutorial.md +2 -0
- package/scripts/service-supervisor.js +8 -13
- package/scripts/start-server.js +8 -1
- package/scripts/update-instance.js +93 -27
- package/server/core/context-builder.js +4 -1
- package/server/core/dialogue-contract.js +1 -1
- package/server/core/response-validator.js +18 -2
- package/server/core/turn.js +30 -1
- package/server/i18n/errors.js +36 -0
- package/server/mind/affect.js +4 -2
- package/server/mind/view.js +4 -1
- package/server/runtime/update-errors.js +73 -0
- package/server/runtime/update-execution.js +13 -8
- package/server/runtime/update-manager.js +30 -8
- package/docs/en/evolution.md +0 -35
- package/docs/en/vision.md +0 -50
- package/docs/zh/evolution.md +0 -35
- package/docs/zh/vision.md +0 -50
|
@@ -1 +1 @@
|
|
|
1
|
-
.connect[data-v-6f4553ed]{gap:var(--gap);grid-template-columns:minmax(0,1.25fr) minmax(290px,.9fr);align-items:start;display:grid}.connection[data-v-6f4553ed]{gap:20px;display:grid}.connection-details[data-v-6f4553ed]{gap:10px;display:grid}.detail[data-v-6f4553ed]{border:1px solid var(--line);background:color-mix(in srgb, var(--surface-strong) 70%, transparent);border-radius:14px;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 16px;padding:13px 16px;display:flex}.detail code[data-v-6f4553ed]{overflow-wrap:anywhere}.warn-text[data-v-6f4553ed]{color:var(--warn);overflow-wrap:anywhere}.instructions[data-v-6f4553ed]{gap:11px;margin:0;padding-left:22px;line-height:1.65;display:grid}.notes[data-v-6f4553ed]{gap:8px;margin:0;padding-left:20px;font-size:13px;line-height:1.6;display:grid}.note[data-v-6f4553ed]{margin:-8px 0 0;font-size:12px}.checks[data-v-6f4553ed]{gap:8px;margin:0;padding:0;list-style:none;display:grid}.checks li[data-v-6f4553ed]{background:color-mix(in srgb, var(--surface-strong) 70%, transparent);border:1px solid var(--line);border-radius:14px;align-items:center;gap:12px;padding:10px 12px;display:flex}.checks li>div[data-v-6f4553ed]{flex:1;min-width:0;display:grid}.checks small[data-v-6f4553ed]{font-size:12px}.mark[data-v-6f4553ed]{border:2px solid var(--line);border-radius:50%;flex:none;place-items:center;width:22px;height:22px;font-size:11px;font-weight:700;display:grid}.done .mark[data-v-6f4553ed]{border-color:var(--ok);background:var(--ok);color:var(--accent-ink)}@media (width<=1000px){.connect[data-v-6f4553ed]{grid-template-columns:minmax(0,1fr)}}.embedding-profile[data-v-944d9f50]{min-width:0}.secret[data-v-944d9f50]{-webkit-text-security:disc}.fields[data-v-944d9f50]{grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:14px;margin:16px 0;display:grid}.save-bar[data-v-944d9f50]{position:relative;bottom:auto}.stats[data-v-cdde3f37]{flex-wrap:wrap;gap:8px;margin:12px 0;display:flex}.pill[data-v-cdde3f37]{background:var(--surface-2,#7f7f7f1f);border-radius:999px;padding:2px 10px;font-size:.85em}.pill.strong[data-v-cdde3f37]{font-weight:600}.pill.warn[data-v-cdde3f37]{color:var(--danger,#c0392b)}.waiting[data-v-cdde3f37]{margin:8px 0;padding-left:18px;font-size:.85em}.probe[data-v-cdde3f37]{grid-template-columns:minmax(140px,1fr) minmax(200px,3fr) auto;gap:8px;margin-top:12px;display:grid}.result ol[data-v-cdde3f37]{padding-left:20px}.result li[data-v-cdde3f37]{margin:6px 0}.library[data-v-8a9bd858]{gap:var(--gap);grid-template-columns:minmax(0,1fr);display:grid}.model-workspace[data-v-8a9bd858]{gap:var(--gap);grid-template-columns:minmax(260px,.32fr) minmax(0,1fr);align-items:start;display:grid}.shelf[data-v-8a9bd858]{background:radial-gradient(ellipse at 0 0, color-mix(in srgb, var(--glow-a) 23%, transparent), transparent 56%), var(--surface);gap:15px;display:grid;position:sticky;top:14px}.detail[data-v-8a9bd858]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-b) 16%, transparent), transparent 47%), var(--surface)}.usage-panel[data-v-8a9bd858]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 25%, transparent), transparent 42%), radial-gradient(ellipse at 0 100%, color-mix(in srgb, var(--glow-b) 20%, transparent), transparent 46%), var(--surface);grid-column:1/-1;gap:18px;display:grid;overflow:hidden}.usage-intro[data-v-8a9bd858]{justify-content:space-between;align-items:end;gap:20px;display:flex}.usage-intro h2[data-v-8a9bd858]{letter-spacing:-.04em;margin:5px 0 4px;font-size:22px}.usage-intro p[data-v-8a9bd858],.usage-foot small[data-v-8a9bd858]{color:var(--ink-soft);font-size:12px}.usage-total[data-v-8a9bd858]{flex:none;justify-items:end;display:grid}.usage-total strong[data-v-8a9bd858]{color:var(--accent);font:700 clamp(28px, 4vw, 42px) var(--font-display);letter-spacing:-.055em;font-variant-numeric:tabular-nums;line-height:1.05}.usage-total span[data-v-8a9bd858]{color:var(--ink-soft);font-size:12px}.usage-detail[data-v-8a9bd858]{grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;display:grid}.usage-stat[data-v-8a9bd858]{background:#ffffff5c;border:1px solid #ffffffc7;border-radius:18px;gap:5px;min-width:0;padding:14px 16px;display:grid;box-shadow:inset 0 1px #fff}.usage-stat span[data-v-8a9bd858]{color:var(--ink-soft);font-size:12px}.usage-stat span small[data-v-8a9bd858]{font-size:10px}.usage-stat b[data-v-8a9bd858]{font-variant-numeric:tabular-nums;text-overflow:ellipsis;font-size:19px;overflow:hidden}.usage-foot[data-v-8a9bd858]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px;display:flex}.usage-error[data-v-8a9bd858]{color:var(--danger)!important}.usage-refresh[data-v-8a9bd858]{color:var(--accent);font-size:12px}.shelf-head[data-v-8a9bd858]{justify-content:space-between;align-items:center;gap:8px;display:flex}.shelf-head h2[data-v-8a9bd858]{letter-spacing:-.04em;font-size:21px}.shelf-head small[data-v-8a9bd858]{color:var(--ink-soft);font-size:12px}.rows[data-v-8a9bd858]{gap:8px;max-height:520px;display:grid;overflow:auto}.saved-vendor[data-v-8a9bd858]{background:#fff3;border:1px solid #ffffffad;border-radius:17px;overflow:hidden;box-shadow:inset 0 1px #ffffffb8}.saved-vendor>summary[data-v-8a9bd858]{color:var(--ink);cursor:pointer;justify-content:space-between;align-items:center;gap:8px;padding:11px 13px;font-size:12px;font-weight:700;list-style:none;display:flex}.saved-vendor>summary[data-v-8a9bd858]::-webkit-details-marker{display:none}.vendor-summary[data-v-8a9bd858]::-webkit-details-marker{display:none}.saved-vendor>summary[data-v-8a9bd858]:after{color:var(--accent);content:"⌄";transition:transform .24s var(--spring);font-size:15px}.saved-vendor[open]>summary[data-v-8a9bd858]{background:#ffffff40;border-bottom:1px solid #fff9}.saved-vendor[open]>summary[data-v-8a9bd858]:after{transform:rotate(180deg)}.saved-vendor>summary small[data-v-8a9bd858]{color:var(--ink-soft);margin-left:auto;font-size:10px;font-weight:500}.vendor-models[data-v-8a9bd858]{gap:6px;padding:7px;display:grid}.entity-row[data-v-8a9bd858]{text-align:left;-webkit-backdrop-filter:blur(16px)saturate(1.5);backdrop-filter:blur(16px)saturate(1.5);width:100%;transition:transform .32s var(--spring), background-color .2s, box-shadow .25s;background:#ffffff5c;border:1px solid #ffffffbf;border-radius:18px;align-items:center;gap:10px;padding:11px 12px;display:flex;box-shadow:inset 0 1px #fff}.entity-row[data-v-8a9bd858]:hover:not(:disabled){box-shadow:0 12px 22px -19px var(--accent);background:#ffffffa8;transform:translate(4px)scale(1.01)}.entity-row.selected[data-v-8a9bd858]{border-color:color-mix(in srgb, var(--accent) 22%, white);background:linear-gradient(115deg, white, color-mix(in srgb, var(--accent-soft) 60%, white));box-shadow:inset 0 1px 0 white, 0 13px 23px -20px var(--accent)}.badge[data-v-8a9bd858]{background:linear-gradient(145deg, white, hsl(var(--hue) 70% 88%));width:36px;height:36px;color:hsl(var(--hue) 45% 25%);box-shadow:inset 0 1px 0 white, 0 5px 13px -10px hsl(var(--hue) 45% 32%);border-radius:14px;flex:none;place-items:center;font-weight:700;display:grid}.who[data-v-8a9bd858]{min-width:0;line-height:1.35;display:grid}.who b[data-v-8a9bd858]{text-overflow:ellipsis;white-space:nowrap;font-size:13.5px;overflow:hidden}.who small[data-v-8a9bd858]{color:var(--ink-soft);font-size:11.5px;font-weight:500}fieldset[data-v-8a9bd858]{background:linear-gradient(142deg, #ffffffa1, #ffffff47), var(--surface);box-shadow:inset 0 1px 0 white, 0 14px 30px -27px var(--accent);-webkit-backdrop-filter:blur(20px)saturate(1.6);backdrop-filter:blur(20px)saturate(1.6);border:1px solid #ffffffcf;border-radius:24px;gap:10px;margin:0;padding:20px;display:grid}legend[data-v-8a9bd858]{padding:0 8px;font-size:13px;font-weight:700}.advanced summary[data-v-8a9bd858]{color:var(--accent);transition:transform .3s var(--spring), background-color .2s;background:#ffffff6b;border:1px solid #fffc;border-radius:14px;padding:12px 15px;font-weight:600;box-shadow:inset 0 1px #fff}.advanced summary[data-v-8a9bd858]:hover{background:#ffffffa6;transform:translate(3px)}.advanced[open] summary[data-v-8a9bd858]{margin-bottom:12px}.caps[data-v-8a9bd858]{flex-wrap:wrap;gap:8px 18px;margin-top:10px;display:flex}.actions[data-v-8a9bd858]{flex-wrap:wrap;gap:8px;display:flex}.actions .push[data-v-8a9bd858]{margin-left:auto}.model-picker[data-v-8a9bd858]{gap:16px;display:grid}.catalog-search[data-v-8a9bd858]{color:var(--ink-soft);gap:6px;font-size:12px;font-weight:600;display:grid}.catalog-search input[data-v-8a9bd858]{width:100%;min-height:42px;color:var(--ink);-webkit-backdrop-filter:blur(14px)saturate(1.4);backdrop-filter:blur(14px)saturate(1.4);background:#ffffff9e;border:1px solid #ffffffd9;border-radius:14px;outline:none;padding:0 13px;box-shadow:inset 0 1px #fff}.catalog-search input[data-v-8a9bd858]:focus{border-color:color-mix(in srgb, var(--accent) 42%, white);box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 10%, transparent)}.vendor[data-v-8a9bd858]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 13%, transparent), transparent 48%), #ffffff3b;-webkit-backdrop-filter:blur(18px)saturate(1.35);backdrop-filter:blur(18px)saturate(1.35);border:1px solid #ffffffb8;border-radius:21px;overflow:hidden;box-shadow:inset 0 1px #ffffffc7}.vendor-summary[data-v-8a9bd858]{cursor:pointer;justify-content:space-between;align-items:center;gap:12px;min-height:62px;padding:12px 17px;list-style:none;transition:background-color .2s;display:flex}.vendor-summary[data-v-8a9bd858]:hover{background:#ffffff57}.vendor-name[data-v-8a9bd858]{align-items:center;gap:10px;min-width:0;display:flex}.vendor-name b[data-v-8a9bd858]{font-size:13px}.vendor-name small[data-v-8a9bd858]{color:var(--ink-soft);font-size:10px}.vendor-chevron[data-v-8a9bd858]{color:var(--accent);transition:transform .28s var(--spring);font-size:20px;line-height:1}.vendor[open] .vendor-chevron[data-v-8a9bd858]{transform:rotate(180deg)}.vendor[open] .presets[data-v-8a9bd858]{animation:vendor-reveal-8a9bd858 .24s var(--spring) both}@keyframes vendor-reveal-8a9bd858{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}.search-empty[data-v-8a9bd858]{margin:0}.presets[data-v-8a9bd858]{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px;padding:0 12px 12px;display:grid}.preset-card[data-v-8a9bd858]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 22%, transparent), transparent 55%), #ffffff80;box-shadow:inset 0 1px 0 white, 0 12px 22px -20px var(--accent);text-align:left;-webkit-backdrop-filter:blur(16px)saturate(1.5);backdrop-filter:blur(16px)saturate(1.5);transition:transform .42s var(--spring), box-shadow .25s;border:1px solid #ffffffd1;border-radius:21px;justify-items:start;gap:3px;padding:17px;font-weight:500;display:grid}.preset-card[data-v-8a9bd858]:hover:not(:disabled){box-shadow:inset 0 1px 0 white, 0 22px 33px -22px var(--accent);transform:translateY(-6px)rotate(-.5deg)scale(1.025)}.preset-card small[data-v-8a9bd858]{color:var(--ink-soft);font-size:11.5px}@media (width<=900px){.model-workspace[data-v-8a9bd858]{grid-template-columns:minmax(0,1fr)}.usage-panel[data-v-8a9bd858]{grid-column:auto}.shelf[data-v-8a9bd858]{position:static}}@media (width<=620px){.usage-intro[data-v-8a9bd858]{flex-direction:column;align-items:start}.usage-total[data-v-8a9bd858]{justify-items:start}.usage-detail[data-v-8a9bd858]{grid-template-columns:repeat(2,minmax(0,1fr))}}.runtime-grid[data-v-1f197523]{gap:var(--gap);grid-template-columns:minmax(0,1.55fr) minmax(260px,.8fr);align-items:start;display:grid}.runtime-grid>.card[data-v-1f197523]{background:radial-gradient(ellipse at 90% 0, color-mix(in srgb, var(--glow-a) 20%, transparent), transparent 55%), var(--surface)}.runtime-grid .card-head h2[data-v-1f197523]{letter-spacing:-.035em;margin-top:5px;font-size:23px}.switches[data-v-1f197523]{gap:12px;margin-bottom:20px;display:grid}.switches[data-v-1f197523] .switch{box-shadow:inset 0 1px 0 white, 0 10px 22px -23px var(--accent);-webkit-backdrop-filter:blur(18px)saturate(1.5);backdrop-filter:blur(18px)saturate(1.5);transition:transform .35s var(--spring), background-color .2s;background:#ffffff69;border:1px solid #ffffffc7;border-radius:22px;align-items:flex-start;padding:18px}.switches[data-v-1f197523] .switch:hover{background:#ffffffa3;transform:translateY(-3px)scale(1.008)}.switches[data-v-1f197523] .switch>span{gap:2px;display:grid}.switches small[data-v-1f197523]{color:var(--ink-soft);font-size:12.5px;font-weight:400}.numbers[data-v-1f197523]{gap:12px;display:grid}.numbers button[data-v-1f197523],.numbers .stat[data-v-1f197523]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-b) 24%, transparent), transparent 63%), #ffffff70;box-shadow:inset 0 1px 0 white, 0 12px 26px -24px var(--accent);text-align:left;-webkit-backdrop-filter:blur(18px)saturate(1.55);backdrop-filter:blur(18px)saturate(1.55);transition:transform .38s var(--spring), box-shadow .23s;border:1px solid #ffffffd4;border-radius:22px;justify-items:start;gap:2px;padding:20px 21px;display:grid}.numbers button[data-v-1f197523]:hover:not(:disabled){box-shadow:inset 0 1px 0 white, 0 18px 28px -22px var(--accent);transform:translate(5px)scale(1.018)}.numbers b[data-v-1f197523]{font:750 29px var(--font-display);color:var(--accent)}.numbers .stat.warn b[data-v-1f197523]{color:var(--warn)}.numbers .stat.danger b[data-v-1f197523]{color:var(--danger)}.numbers span[data-v-1f197523]{color:var(--ink-soft);font-size:12.5px;font-weight:500}@media (width<=900px){.runtime-grid[data-v-1f197523]{grid-template-columns:minmax(0,1fr)}}.search-profile[data-v-e874d8b6]{gap:16px;min-width:0;display:grid}.search-profile form[data-v-e874d8b6]{gap:18px;display:grid}.search-fields[data-v-e874d8b6]{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;display:grid}.search-fields label[data-v-e874d8b6]{gap:8px;min-width:0;display:grid}.search-fields input[data-v-e874d8b6],.search-fields .menu-select[data-v-e874d8b6]{width:100%;min-width:0}.search-usage[data-v-e874d8b6]{flex-wrap:wrap;align-items:center;gap:12px;display:flex}.search-result[data-v-e874d8b6]{border:1px solid var(--line);background:var(--surface);overflow-wrap:anywhere;border-radius:16px;padding:14px 16px}.search-result.failed[data-v-e874d8b6]{border-color:color-mix(in srgb, var(--warn) 40%, var(--line))}@media (width<=620px){.search-fields[data-v-e874d8b6]{grid-template-columns:minmax(0,1fr)}}.data-transfer[data-v-ea16c0c1]{min-width:0}.data-transfer h2[data-v-ea16c0c1]{margin:8px 0 14px;font-size:clamp(23px,3vw,32px)}.transfer-note[data-v-ea16c0c1]{color:var(--ink-soft);overflow-wrap:anywhere;font-size:13px;line-height:1.7}.transfer-actions[data-v-ea16c0c1]{flex-wrap:wrap;gap:10px;margin:18px 0;display:flex}.transfer-actions button[data-v-ea16c0c1]{border-radius:16px;padding:11px 17px}.transfer-actions button[data-v-ea16c0c1]:not(.primary){background:#ffffffb8}.transfer-file[data-v-ea16c0c1]{display:none}.transfer-preview[data-v-ea16c0c1]{overflow-wrap:anywhere;background:#fff6;border:1px solid #ffffffd9;border-radius:22px;margin-top:20px;padding:20px}.transfer-preview h3[data-v-ea16c0c1]{margin:8px 0}.transfer-counts[data-v-ea16c0c1]{flex-wrap:wrap;gap:10px;display:flex}.transfer-counts>div[data-v-ea16c0c1]{background:#ffffffa6;border-radius:14px;gap:4px;min-width:70px;padding:12px;display:grid}.transfer-counts b[data-v-ea16c0c1],.transfer-progress[data-v-ea16c0c1]{color:var(--accent)}.transfer-counts span[data-v-ea16c0c1]{color:var(--ink-soft);font-size:12px}.transfer-error[data-v-ea16c0c1]{color:var(--danger);overflow-wrap:anywhere}.storage-page[data-v-4593780e]{gap:var(--gap);display:grid}.storage-page>.card[data-v-4593780e],.storage-grid>.card[data-v-4593780e]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 20%, transparent), transparent 60%), var(--surface)}.storage-overview h2[data-v-4593780e]{margin:8px 0;font-size:clamp(24px,3vw,36px)}.storage-overview p[data-v-4593780e],.storage-note[data-v-4593780e]{color:var(--ink-soft);font-size:13px;line-height:1.65}.storage-metrics[data-v-4593780e]{flex-wrap:wrap;gap:12px;margin-top:22px;display:flex}.storage-metrics>div[data-v-4593780e]{background:#ffffff6b;border:1px solid #fffc;border-radius:18px;gap:3px;min-width:150px;padding:15px 20px;display:grid}.storage-metrics b[data-v-4593780e]{color:var(--accent);font-size:23px}.storage-metrics span[data-v-4593780e]{color:var(--ink-soft);font-size:12px}.storage-grid[data-v-4593780e]{gap:var(--gap);grid-template-columns:minmax(270px,.8fr) minmax(0,1.5fr);align-items:start;display:grid}.storage-grid .card-head h2[data-v-4593780e]{margin:4px 0 16px;font-size:23px}.storage-check[data-v-4593780e]{align-items:center;gap:9px;margin-bottom:16px;display:flex}.storage-fields[data-v-4593780e]{gap:13px;display:grid}.storage-fields label[data-v-4593780e]{color:var(--ink-soft);gap:6px;font-size:12px;font-weight:700;display:grid}.storage-fields input[data-v-4593780e]{border:1px solid color-mix(in srgb, var(--accent) 25%, white);width:100%;min-width:0;color:var(--ink);background:#ffffffb3;border-radius:15px;padding:11px 13px}.storage-policy .primary[data-v-4593780e]{margin-top:14px}.storage-actions[data-v-4593780e]{flex-wrap:wrap;gap:8px;margin:16px 0;display:flex}.storage-actions button[data-v-4593780e]{background:#ffffffa6;border-radius:999px;padding:8px 12px}.storage-scroll[data-v-4593780e]{gap:7px;max-height:520px;padding:2px;display:grid;overflow:auto}.storage-row[data-v-4593780e]{cursor:pointer;background:#ffffff7a;border:1px solid #ffffffbf;border-radius:16px;align-items:center;gap:12px;min-width:0;padding:10px 12px;display:flex}.storage-row.protected[data-v-4593780e]{opacity:.7;cursor:default}.storage-item[data-v-4593780e]{flex:1;gap:3px;min-width:0;display:grid}.storage-item strong[data-v-4593780e]{text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.storage-item small[data-v-4593780e]{color:var(--ink-soft);font-size:11px}.storage-row>b[data-v-4593780e]{white-space:nowrap;color:var(--accent);font-size:12px}.storage-footer[data-v-4593780e]{color:var(--ink-soft);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px;padding-top:18px;font-size:12px;display:flex}.storage-error[data-v-4593780e]{color:var(--danger);overflow-wrap:anywhere}@media (width<=900px){.storage-grid[data-v-4593780e]{grid-template-columns:minmax(0,1fr)}}@media (width<=560px){.storage-row[data-v-4593780e]{flex-wrap:wrap;align-items:flex-start}.storage-row>b[data-v-4593780e]{margin-left:26px}.storage-metrics>div[data-v-4593780e]{flex:1;min-width:130px}}.password-settings[data-v-36cd9f70]{margin-top:24px}form[data-v-36cd9f70]{gap:16px;max-width:520px;display:grid}label[data-v-36cd9f70]{gap:8px;display:grid}input[data-v-36cd9f70]{box-sizing:border-box;width:100%}.update-settings[data-v-c54db2fd]{gap:14px;display:grid}header[data-v-c54db2fd]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:14px;display:flex}h2[data-v-c54db2fd]{margin-top:5px}.version-state[data-v-c54db2fd]{font-weight:700}.version-state.available[data-v-c54db2fd]{color:var(--accent)}.small-text[data-v-c54db2fd]{font-size:12px}.update-how[data-v-c54db2fd]{border:1px solid var(--line);background:var(--surface);border-radius:18px;padding:14px}code[data-v-c54db2fd]{white-space:pre-wrap;overflow-wrap:anywhere;margin-top:9px;display:block}.update-links[data-v-c54db2fd]{gap:18px;font-size:13px;display:flex}.system[data-v-a12a372e]{gap:var(--gap);display:grid}.system-intro[data-v-a12a372e]{background:radial-gradient(ellipse at 90% 7%, color-mix(in srgb, var(--glow-a) 48%, transparent), transparent 51%), radial-gradient(ellipse at 62% 115%, color-mix(in srgb, var(--glow-b) 38%, transparent), transparent 55%), linear-gradient(115deg, #fffc, #ffffff4d);min-height:190px;box-shadow:inset 0 2px 0 white, 0 25px 54px -35px color-mix(in srgb, var(--accent) 43%, transparent);-webkit-backdrop-filter:blur(28px)saturate(1.8);backdrop-filter:blur(28px)saturate(1.8);border:1px solid #ffffffd9;border-radius:36px;flex-wrap:wrap;justify-content:space-between;align-items:end;gap:20px;padding:32px clamp(26px,5vw,60px);display:flex;position:relative;overflow:hidden}.system-intro[data-v-a12a372e]:before{content:"";width:350px;height:350px;box-shadow:0 0 0 29px #ffffff21, 0 0 0 58px color-mix(in srgb, var(--glow-b) 12%, transparent);pointer-events:none;border:1px solid #ffffffb8;border-radius:50%;animation:10s ease-in-out infinite alternate system-bob-a12a372e;position:absolute;top:-85%;right:13%}.system-intro h1[data-v-a12a372e]{letter-spacing:-.055em;margin:10px 0 7px;font-size:clamp(28px,3.25vw,42px)}.system-intro h1 em[data-v-a12a372e]{color:var(--accent);font-style:normal}.system-intro p[data-v-a12a372e]{max-width:560px;color:var(--ink-soft);font-size:13.5px;position:relative}.system-status[data-v-a12a372e]{z-index:1;box-shadow:inset 0 1px 0 white, 0 7px 19px -15px var(--accent);white-space:nowrap;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);background:#ffffff87;border:1px solid #fff;border-radius:999px;align-items:center;gap:9px;padding:10px 16px;font-size:12.5px;font-weight:700;display:inline-flex}.system-status i[data-v-a12a372e]{background:var(--ok);width:9px;height:9px;box-shadow:0 0 0 4px color-mix(in srgb, var(--ok) 18%, transparent);border-radius:50%;animation:2.6s ease-in-out infinite pulse-soft}.system-status i.off[data-v-a12a372e]{background:var(--ink-faint);box-shadow:0 0 0 4px color-mix(in srgb, var(--ink-faint) 14%, transparent);animation:none}.system>.tabs[data-v-a12a372e]{box-shadow:inset 0 1px 0 white, 0 10px 30px -24px var(--accent);-webkit-backdrop-filter:blur(22px)saturate(1.7);backdrop-filter:blur(22px)saturate(1.7);border:1px solid #fffc;justify-self:start;padding:5px}.system[data-v-a12a372e]>.tabs button{transition:transform .35s var(--spring), background-color .2s, box-shadow .2s;border-radius:999px;padding:9px 18px}.system[data-v-a12a372e]>.tabs button:hover{transform:translateY(-2px)scale(1.03)}.system[data-v-a12a372e] .connect .step,.system[data-v-a12a372e] .connect .checks li{background:linear-gradient(145deg, #ffffffad, #ffffff47), var(--surface);box-shadow:inset 0 1px 0 white, 0 12px 24px -24px var(--accent);-webkit-backdrop-filter:blur(18px)saturate(1.55);backdrop-filter:blur(18px)saturate(1.55);transition:transform .35s var(--spring), box-shadow .25s;border:1px solid #ffffffd9;border-radius:22px}.system[data-v-a12a372e] .connect .step:hover,.system[data-v-a12a372e] .connect .checks li:hover{box-shadow:inset 0 1px 0 white, 0 16px 28px -21px var(--accent);transform:translateY(-3px)}.system[data-v-a12a372e] .connect .num{background:linear-gradient(145deg, white, color-mix(in srgb, var(--glow-a) 75%, white));box-shadow:inset 0 1px 0 white, 0 5px 14px -9px var(--accent);color:var(--accent);border:1px solid #fff}@keyframes system-bob-a12a372e{to{transform:translateY(22px)scale(1.08)}}@media (width<=760px){.system-intro[data-v-a12a372e]{min-height:0;padding:27px 23px}}
|
|
1
|
+
.connect[data-v-6f4553ed]{gap:var(--gap);grid-template-columns:minmax(0,1.25fr) minmax(290px,.9fr);align-items:start;display:grid}.connection[data-v-6f4553ed]{gap:20px;display:grid}.connection-details[data-v-6f4553ed]{gap:10px;display:grid}.detail[data-v-6f4553ed]{border:1px solid var(--line);background:color-mix(in srgb, var(--surface-strong) 70%, transparent);border-radius:14px;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:8px 16px;padding:13px 16px;display:flex}.detail code[data-v-6f4553ed]{overflow-wrap:anywhere}.warn-text[data-v-6f4553ed]{color:var(--warn);overflow-wrap:anywhere}.instructions[data-v-6f4553ed]{gap:11px;margin:0;padding-left:22px;line-height:1.65;display:grid}.notes[data-v-6f4553ed]{gap:8px;margin:0;padding-left:20px;font-size:13px;line-height:1.6;display:grid}.note[data-v-6f4553ed]{margin:-8px 0 0;font-size:12px}.checks[data-v-6f4553ed]{gap:8px;margin:0;padding:0;list-style:none;display:grid}.checks li[data-v-6f4553ed]{background:color-mix(in srgb, var(--surface-strong) 70%, transparent);border:1px solid var(--line);border-radius:14px;align-items:center;gap:12px;padding:10px 12px;display:flex}.checks li>div[data-v-6f4553ed]{flex:1;min-width:0;display:grid}.checks small[data-v-6f4553ed]{font-size:12px}.mark[data-v-6f4553ed]{border:2px solid var(--line);border-radius:50%;flex:none;place-items:center;width:22px;height:22px;font-size:11px;font-weight:700;display:grid}.done .mark[data-v-6f4553ed]{border-color:var(--ok);background:var(--ok);color:var(--accent-ink)}@media (width<=1000px){.connect[data-v-6f4553ed]{grid-template-columns:minmax(0,1fr)}}.embedding-profile[data-v-944d9f50]{min-width:0}.secret[data-v-944d9f50]{-webkit-text-security:disc}.fields[data-v-944d9f50]{grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:14px;margin:16px 0;display:grid}.save-bar[data-v-944d9f50]{position:relative;bottom:auto}.stats[data-v-cdde3f37]{flex-wrap:wrap;gap:8px;margin:12px 0;display:flex}.pill[data-v-cdde3f37]{background:var(--surface-2,#7f7f7f1f);border-radius:999px;padding:2px 10px;font-size:.85em}.pill.strong[data-v-cdde3f37]{font-weight:600}.pill.warn[data-v-cdde3f37]{color:var(--danger,#c0392b)}.waiting[data-v-cdde3f37]{margin:8px 0;padding-left:18px;font-size:.85em}.probe[data-v-cdde3f37]{grid-template-columns:minmax(140px,1fr) minmax(200px,3fr) auto;gap:8px;margin-top:12px;display:grid}.result ol[data-v-cdde3f37]{padding-left:20px}.result li[data-v-cdde3f37]{margin:6px 0}.library[data-v-8a9bd858]{gap:var(--gap);grid-template-columns:minmax(0,1fr);display:grid}.model-workspace[data-v-8a9bd858]{gap:var(--gap);grid-template-columns:minmax(260px,.32fr) minmax(0,1fr);align-items:start;display:grid}.shelf[data-v-8a9bd858]{background:radial-gradient(ellipse at 0 0, color-mix(in srgb, var(--glow-a) 23%, transparent), transparent 56%), var(--surface);gap:15px;display:grid;position:sticky;top:14px}.detail[data-v-8a9bd858]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-b) 16%, transparent), transparent 47%), var(--surface)}.usage-panel[data-v-8a9bd858]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 25%, transparent), transparent 42%), radial-gradient(ellipse at 0 100%, color-mix(in srgb, var(--glow-b) 20%, transparent), transparent 46%), var(--surface);grid-column:1/-1;gap:18px;display:grid;overflow:hidden}.usage-intro[data-v-8a9bd858]{justify-content:space-between;align-items:end;gap:20px;display:flex}.usage-intro h2[data-v-8a9bd858]{letter-spacing:-.04em;margin:5px 0 4px;font-size:22px}.usage-intro p[data-v-8a9bd858],.usage-foot small[data-v-8a9bd858]{color:var(--ink-soft);font-size:12px}.usage-total[data-v-8a9bd858]{flex:none;justify-items:end;display:grid}.usage-total strong[data-v-8a9bd858]{color:var(--accent);font:700 clamp(28px, 4vw, 42px) var(--font-display);letter-spacing:-.055em;font-variant-numeric:tabular-nums;line-height:1.05}.usage-total span[data-v-8a9bd858]{color:var(--ink-soft);font-size:12px}.usage-detail[data-v-8a9bd858]{grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;display:grid}.usage-stat[data-v-8a9bd858]{background:#ffffff5c;border:1px solid #ffffffc7;border-radius:18px;gap:5px;min-width:0;padding:14px 16px;display:grid;box-shadow:inset 0 1px #fff}.usage-stat span[data-v-8a9bd858]{color:var(--ink-soft);font-size:12px}.usage-stat span small[data-v-8a9bd858]{font-size:10px}.usage-stat b[data-v-8a9bd858]{font-variant-numeric:tabular-nums;text-overflow:ellipsis;font-size:19px;overflow:hidden}.usage-foot[data-v-8a9bd858]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px;display:flex}.usage-error[data-v-8a9bd858]{color:var(--danger)!important}.usage-refresh[data-v-8a9bd858]{color:var(--accent);font-size:12px}.shelf-head[data-v-8a9bd858]{justify-content:space-between;align-items:center;gap:8px;display:flex}.shelf-head h2[data-v-8a9bd858]{letter-spacing:-.04em;font-size:21px}.shelf-head small[data-v-8a9bd858]{color:var(--ink-soft);font-size:12px}.rows[data-v-8a9bd858]{gap:8px;max-height:520px;display:grid;overflow:auto}.saved-vendor[data-v-8a9bd858]{background:#fff3;border:1px solid #ffffffad;border-radius:17px;overflow:hidden;box-shadow:inset 0 1px #ffffffb8}.saved-vendor>summary[data-v-8a9bd858]{color:var(--ink);cursor:pointer;justify-content:space-between;align-items:center;gap:8px;padding:11px 13px;font-size:12px;font-weight:700;list-style:none;display:flex}.saved-vendor>summary[data-v-8a9bd858]::-webkit-details-marker{display:none}.vendor-summary[data-v-8a9bd858]::-webkit-details-marker{display:none}.saved-vendor>summary[data-v-8a9bd858]:after{color:var(--accent);content:"⌄";transition:transform .24s var(--spring);font-size:15px}.saved-vendor[open]>summary[data-v-8a9bd858]{background:#ffffff40;border-bottom:1px solid #fff9}.saved-vendor[open]>summary[data-v-8a9bd858]:after{transform:rotate(180deg)}.saved-vendor>summary small[data-v-8a9bd858]{color:var(--ink-soft);margin-left:auto;font-size:10px;font-weight:500}.vendor-models[data-v-8a9bd858]{gap:6px;padding:7px;display:grid}.entity-row[data-v-8a9bd858]{text-align:left;-webkit-backdrop-filter:blur(16px)saturate(1.5);backdrop-filter:blur(16px)saturate(1.5);width:100%;transition:transform .32s var(--spring), background-color .2s, box-shadow .25s;background:#ffffff5c;border:1px solid #ffffffbf;border-radius:18px;align-items:center;gap:10px;padding:11px 12px;display:flex;box-shadow:inset 0 1px #fff}.entity-row[data-v-8a9bd858]:hover:not(:disabled){box-shadow:0 12px 22px -19px var(--accent);background:#ffffffa8;transform:translate(4px)scale(1.01)}.entity-row.selected[data-v-8a9bd858]{border-color:color-mix(in srgb, var(--accent) 22%, white);background:linear-gradient(115deg, white, color-mix(in srgb, var(--accent-soft) 60%, white));box-shadow:inset 0 1px 0 white, 0 13px 23px -20px var(--accent)}.badge[data-v-8a9bd858]{background:linear-gradient(145deg, white, hsl(var(--hue) 70% 88%));width:36px;height:36px;color:hsl(var(--hue) 45% 25%);box-shadow:inset 0 1px 0 white, 0 5px 13px -10px hsl(var(--hue) 45% 32%);border-radius:14px;flex:none;place-items:center;font-weight:700;display:grid}.who[data-v-8a9bd858]{min-width:0;line-height:1.35;display:grid}.who b[data-v-8a9bd858]{text-overflow:ellipsis;white-space:nowrap;font-size:13.5px;overflow:hidden}.who small[data-v-8a9bd858]{color:var(--ink-soft);font-size:11.5px;font-weight:500}fieldset[data-v-8a9bd858]{background:linear-gradient(142deg, #ffffffa1, #ffffff47), var(--surface);box-shadow:inset 0 1px 0 white, 0 14px 30px -27px var(--accent);-webkit-backdrop-filter:blur(20px)saturate(1.6);backdrop-filter:blur(20px)saturate(1.6);border:1px solid #ffffffcf;border-radius:24px;gap:10px;margin:0;padding:20px;display:grid}legend[data-v-8a9bd858]{padding:0 8px;font-size:13px;font-weight:700}.advanced summary[data-v-8a9bd858]{color:var(--accent);transition:transform .3s var(--spring), background-color .2s;background:#ffffff6b;border:1px solid #fffc;border-radius:14px;padding:12px 15px;font-weight:600;box-shadow:inset 0 1px #fff}.advanced summary[data-v-8a9bd858]:hover{background:#ffffffa6;transform:translate(3px)}.advanced[open] summary[data-v-8a9bd858]{margin-bottom:12px}.caps[data-v-8a9bd858]{flex-wrap:wrap;gap:8px 18px;margin-top:10px;display:flex}.actions[data-v-8a9bd858]{flex-wrap:wrap;gap:8px;display:flex}.actions .push[data-v-8a9bd858]{margin-left:auto}.model-picker[data-v-8a9bd858]{gap:16px;display:grid}.catalog-search[data-v-8a9bd858]{color:var(--ink-soft);gap:6px;font-size:12px;font-weight:600;display:grid}.catalog-search input[data-v-8a9bd858]{width:100%;min-height:42px;color:var(--ink);-webkit-backdrop-filter:blur(14px)saturate(1.4);backdrop-filter:blur(14px)saturate(1.4);background:#ffffff9e;border:1px solid #ffffffd9;border-radius:14px;outline:none;padding:0 13px;box-shadow:inset 0 1px #fff}.catalog-search input[data-v-8a9bd858]:focus{border-color:color-mix(in srgb, var(--accent) 42%, white);box-shadow:0 0 0 3px color-mix(in srgb, var(--accent) 10%, transparent)}.vendor[data-v-8a9bd858]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 13%, transparent), transparent 48%), #ffffff3b;-webkit-backdrop-filter:blur(18px)saturate(1.35);backdrop-filter:blur(18px)saturate(1.35);border:1px solid #ffffffb8;border-radius:21px;overflow:hidden;box-shadow:inset 0 1px #ffffffc7}.vendor-summary[data-v-8a9bd858]{cursor:pointer;justify-content:space-between;align-items:center;gap:12px;min-height:62px;padding:12px 17px;list-style:none;transition:background-color .2s;display:flex}.vendor-summary[data-v-8a9bd858]:hover{background:#ffffff57}.vendor-name[data-v-8a9bd858]{align-items:center;gap:10px;min-width:0;display:flex}.vendor-name b[data-v-8a9bd858]{font-size:13px}.vendor-name small[data-v-8a9bd858]{color:var(--ink-soft);font-size:10px}.vendor-chevron[data-v-8a9bd858]{color:var(--accent);transition:transform .28s var(--spring);font-size:20px;line-height:1}.vendor[open] .vendor-chevron[data-v-8a9bd858]{transform:rotate(180deg)}.vendor[open] .presets[data-v-8a9bd858]{animation:vendor-reveal-8a9bd858 .24s var(--spring) both}@keyframes vendor-reveal-8a9bd858{0%{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:translateY(0)}}.search-empty[data-v-8a9bd858]{margin:0}.presets[data-v-8a9bd858]{grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:8px;padding:0 12px 12px;display:grid}.preset-card[data-v-8a9bd858]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 22%, transparent), transparent 55%), #ffffff80;box-shadow:inset 0 1px 0 white, 0 12px 22px -20px var(--accent);text-align:left;-webkit-backdrop-filter:blur(16px)saturate(1.5);backdrop-filter:blur(16px)saturate(1.5);transition:transform .42s var(--spring), box-shadow .25s;border:1px solid #ffffffd1;border-radius:21px;justify-items:start;gap:3px;padding:17px;font-weight:500;display:grid}.preset-card[data-v-8a9bd858]:hover:not(:disabled){box-shadow:inset 0 1px 0 white, 0 22px 33px -22px var(--accent);transform:translateY(-6px)rotate(-.5deg)scale(1.025)}.preset-card small[data-v-8a9bd858]{color:var(--ink-soft);font-size:11.5px}@media (width<=900px){.model-workspace[data-v-8a9bd858]{grid-template-columns:minmax(0,1fr)}.usage-panel[data-v-8a9bd858]{grid-column:auto}.shelf[data-v-8a9bd858]{position:static}}@media (width<=620px){.usage-intro[data-v-8a9bd858]{flex-direction:column;align-items:start}.usage-total[data-v-8a9bd858]{justify-items:start}.usage-detail[data-v-8a9bd858]{grid-template-columns:repeat(2,minmax(0,1fr))}}.runtime-grid[data-v-1f197523]{gap:var(--gap);grid-template-columns:minmax(0,1.55fr) minmax(260px,.8fr);align-items:start;display:grid}.runtime-grid>.card[data-v-1f197523]{background:radial-gradient(ellipse at 90% 0, color-mix(in srgb, var(--glow-a) 20%, transparent), transparent 55%), var(--surface)}.runtime-grid .card-head h2[data-v-1f197523]{letter-spacing:-.035em;margin-top:5px;font-size:23px}.switches[data-v-1f197523]{gap:12px;margin-bottom:20px;display:grid}.switches[data-v-1f197523] .switch{box-shadow:inset 0 1px 0 white, 0 10px 22px -23px var(--accent);-webkit-backdrop-filter:blur(18px)saturate(1.5);backdrop-filter:blur(18px)saturate(1.5);transition:transform .35s var(--spring), background-color .2s;background:#ffffff69;border:1px solid #ffffffc7;border-radius:22px;align-items:flex-start;padding:18px}.switches[data-v-1f197523] .switch:hover{background:#ffffffa3;transform:translateY(-3px)scale(1.008)}.switches[data-v-1f197523] .switch>span{gap:2px;display:grid}.switches small[data-v-1f197523]{color:var(--ink-soft);font-size:12.5px;font-weight:400}.numbers[data-v-1f197523]{gap:12px;display:grid}.numbers button[data-v-1f197523],.numbers .stat[data-v-1f197523]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-b) 24%, transparent), transparent 63%), #ffffff70;box-shadow:inset 0 1px 0 white, 0 12px 26px -24px var(--accent);text-align:left;-webkit-backdrop-filter:blur(18px)saturate(1.55);backdrop-filter:blur(18px)saturate(1.55);transition:transform .38s var(--spring), box-shadow .23s;border:1px solid #ffffffd4;border-radius:22px;justify-items:start;gap:2px;padding:20px 21px;display:grid}.numbers button[data-v-1f197523]:hover:not(:disabled){box-shadow:inset 0 1px 0 white, 0 18px 28px -22px var(--accent);transform:translate(5px)scale(1.018)}.numbers b[data-v-1f197523]{font:750 29px var(--font-display);color:var(--accent)}.numbers .stat.warn b[data-v-1f197523]{color:var(--warn)}.numbers .stat.danger b[data-v-1f197523]{color:var(--danger)}.numbers span[data-v-1f197523]{color:var(--ink-soft);font-size:12.5px;font-weight:500}@media (width<=900px){.runtime-grid[data-v-1f197523]{grid-template-columns:minmax(0,1fr)}}.search-profile[data-v-e874d8b6]{gap:16px;min-width:0;display:grid}.search-profile form[data-v-e874d8b6]{gap:18px;display:grid}.search-fields[data-v-e874d8b6]{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;display:grid}.search-fields label[data-v-e874d8b6]{gap:8px;min-width:0;display:grid}.search-fields input[data-v-e874d8b6],.search-fields .menu-select[data-v-e874d8b6]{width:100%;min-width:0}.search-usage[data-v-e874d8b6]{flex-wrap:wrap;align-items:center;gap:12px;display:flex}.search-result[data-v-e874d8b6]{border:1px solid var(--line);background:var(--surface);overflow-wrap:anywhere;border-radius:16px;padding:14px 16px}.search-result.failed[data-v-e874d8b6]{border-color:color-mix(in srgb, var(--warn) 40%, var(--line))}@media (width<=620px){.search-fields[data-v-e874d8b6]{grid-template-columns:minmax(0,1fr)}}.data-transfer[data-v-ea16c0c1]{min-width:0}.data-transfer h2[data-v-ea16c0c1]{margin:8px 0 14px;font-size:clamp(23px,3vw,32px)}.transfer-note[data-v-ea16c0c1]{color:var(--ink-soft);overflow-wrap:anywhere;font-size:13px;line-height:1.7}.transfer-actions[data-v-ea16c0c1]{flex-wrap:wrap;gap:10px;margin:18px 0;display:flex}.transfer-actions button[data-v-ea16c0c1]{border-radius:16px;padding:11px 17px}.transfer-actions button[data-v-ea16c0c1]:not(.primary){background:#ffffffb8}.transfer-file[data-v-ea16c0c1]{display:none}.transfer-preview[data-v-ea16c0c1]{overflow-wrap:anywhere;background:#fff6;border:1px solid #ffffffd9;border-radius:22px;margin-top:20px;padding:20px}.transfer-preview h3[data-v-ea16c0c1]{margin:8px 0}.transfer-counts[data-v-ea16c0c1]{flex-wrap:wrap;gap:10px;display:flex}.transfer-counts>div[data-v-ea16c0c1]{background:#ffffffa6;border-radius:14px;gap:4px;min-width:70px;padding:12px;display:grid}.transfer-counts b[data-v-ea16c0c1],.transfer-progress[data-v-ea16c0c1]{color:var(--accent)}.transfer-counts span[data-v-ea16c0c1]{color:var(--ink-soft);font-size:12px}.transfer-error[data-v-ea16c0c1]{color:var(--danger);overflow-wrap:anywhere}.storage-page[data-v-4593780e]{gap:var(--gap);display:grid}.storage-page>.card[data-v-4593780e],.storage-grid>.card[data-v-4593780e]{background:radial-gradient(ellipse at 100% 0, color-mix(in srgb, var(--glow-a) 20%, transparent), transparent 60%), var(--surface)}.storage-overview h2[data-v-4593780e]{margin:8px 0;font-size:clamp(24px,3vw,36px)}.storage-overview p[data-v-4593780e],.storage-note[data-v-4593780e]{color:var(--ink-soft);font-size:13px;line-height:1.65}.storage-metrics[data-v-4593780e]{flex-wrap:wrap;gap:12px;margin-top:22px;display:flex}.storage-metrics>div[data-v-4593780e]{background:#ffffff6b;border:1px solid #fffc;border-radius:18px;gap:3px;min-width:150px;padding:15px 20px;display:grid}.storage-metrics b[data-v-4593780e]{color:var(--accent);font-size:23px}.storage-metrics span[data-v-4593780e]{color:var(--ink-soft);font-size:12px}.storage-grid[data-v-4593780e]{gap:var(--gap);grid-template-columns:minmax(270px,.8fr) minmax(0,1.5fr);align-items:start;display:grid}.storage-grid .card-head h2[data-v-4593780e]{margin:4px 0 16px;font-size:23px}.storage-check[data-v-4593780e]{align-items:center;gap:9px;margin-bottom:16px;display:flex}.storage-fields[data-v-4593780e]{gap:13px;display:grid}.storage-fields label[data-v-4593780e]{color:var(--ink-soft);gap:6px;font-size:12px;font-weight:700;display:grid}.storage-fields input[data-v-4593780e]{border:1px solid color-mix(in srgb, var(--accent) 25%, white);width:100%;min-width:0;color:var(--ink);background:#ffffffb3;border-radius:15px;padding:11px 13px}.storage-policy .primary[data-v-4593780e]{margin-top:14px}.storage-actions[data-v-4593780e]{flex-wrap:wrap;gap:8px;margin:16px 0;display:flex}.storage-actions button[data-v-4593780e]{background:#ffffffa6;border-radius:999px;padding:8px 12px}.storage-scroll[data-v-4593780e]{gap:7px;max-height:520px;padding:2px;display:grid;overflow:auto}.storage-row[data-v-4593780e]{cursor:pointer;background:#ffffff7a;border:1px solid #ffffffbf;border-radius:16px;align-items:center;gap:12px;min-width:0;padding:10px 12px;display:flex}.storage-row.protected[data-v-4593780e]{opacity:.7;cursor:default}.storage-item[data-v-4593780e]{flex:1;gap:3px;min-width:0;display:grid}.storage-item strong[data-v-4593780e]{text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.storage-item small[data-v-4593780e]{color:var(--ink-soft);font-size:11px}.storage-row>b[data-v-4593780e]{white-space:nowrap;color:var(--accent);font-size:12px}.storage-footer[data-v-4593780e]{color:var(--ink-soft);flex-wrap:wrap;justify-content:space-between;align-items:center;gap:10px;padding-top:18px;font-size:12px;display:flex}.storage-error[data-v-4593780e]{color:var(--danger);overflow-wrap:anywhere}@media (width<=900px){.storage-grid[data-v-4593780e]{grid-template-columns:minmax(0,1fr)}}@media (width<=560px){.storage-row[data-v-4593780e]{flex-wrap:wrap;align-items:flex-start}.storage-row>b[data-v-4593780e]{margin-left:26px}.storage-metrics>div[data-v-4593780e]{flex:1;min-width:130px}}.password-settings[data-v-36cd9f70]{margin-top:24px}form[data-v-36cd9f70]{gap:16px;max-width:520px;display:grid}label[data-v-36cd9f70]{gap:8px;display:grid}input[data-v-36cd9f70]{box-sizing:border-box;width:100%}.update-settings[data-v-afcb3dd7]{gap:14px;display:grid}header[data-v-afcb3dd7]{flex-wrap:wrap;justify-content:space-between;align-items:center;gap:14px;display:flex}h2[data-v-afcb3dd7]{margin-top:5px}.version-state[data-v-afcb3dd7]{font-weight:700}.version-state.available[data-v-afcb3dd7]{color:var(--accent)}.small-text[data-v-afcb3dd7]{font-size:12px}.update-how[data-v-afcb3dd7]{border:1px solid var(--line);background:var(--surface);border-radius:18px;padding:14px}code[data-v-afcb3dd7]{white-space:pre-wrap;overflow-wrap:anywhere;margin-top:9px;display:block}.update-links[data-v-afcb3dd7]{gap:18px;font-size:13px;display:flex}.system[data-v-a12a372e]{gap:var(--gap);display:grid}.system-intro[data-v-a12a372e]{background:radial-gradient(ellipse at 90% 7%, color-mix(in srgb, var(--glow-a) 48%, transparent), transparent 51%), radial-gradient(ellipse at 62% 115%, color-mix(in srgb, var(--glow-b) 38%, transparent), transparent 55%), linear-gradient(115deg, #fffc, #ffffff4d);min-height:190px;box-shadow:inset 0 2px 0 white, 0 25px 54px -35px color-mix(in srgb, var(--accent) 43%, transparent);-webkit-backdrop-filter:blur(28px)saturate(1.8);backdrop-filter:blur(28px)saturate(1.8);border:1px solid #ffffffd9;border-radius:36px;flex-wrap:wrap;justify-content:space-between;align-items:end;gap:20px;padding:32px clamp(26px,5vw,60px);display:flex;position:relative;overflow:hidden}.system-intro[data-v-a12a372e]:before{content:"";width:350px;height:350px;box-shadow:0 0 0 29px #ffffff21, 0 0 0 58px color-mix(in srgb, var(--glow-b) 12%, transparent);pointer-events:none;border:1px solid #ffffffb8;border-radius:50%;animation:10s ease-in-out infinite alternate system-bob-a12a372e;position:absolute;top:-85%;right:13%}.system-intro h1[data-v-a12a372e]{letter-spacing:-.055em;margin:10px 0 7px;font-size:clamp(28px,3.25vw,42px)}.system-intro h1 em[data-v-a12a372e]{color:var(--accent);font-style:normal}.system-intro p[data-v-a12a372e]{max-width:560px;color:var(--ink-soft);font-size:13.5px;position:relative}.system-status[data-v-a12a372e]{z-index:1;box-shadow:inset 0 1px 0 white, 0 7px 19px -15px var(--accent);white-space:nowrap;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);background:#ffffff87;border:1px solid #fff;border-radius:999px;align-items:center;gap:9px;padding:10px 16px;font-size:12.5px;font-weight:700;display:inline-flex}.system-status i[data-v-a12a372e]{background:var(--ok);width:9px;height:9px;box-shadow:0 0 0 4px color-mix(in srgb, var(--ok) 18%, transparent);border-radius:50%;animation:2.6s ease-in-out infinite pulse-soft}.system-status i.off[data-v-a12a372e]{background:var(--ink-faint);box-shadow:0 0 0 4px color-mix(in srgb, var(--ink-faint) 14%, transparent);animation:none}.system>.tabs[data-v-a12a372e]{box-shadow:inset 0 1px 0 white, 0 10px 30px -24px var(--accent);-webkit-backdrop-filter:blur(22px)saturate(1.7);backdrop-filter:blur(22px)saturate(1.7);border:1px solid #fffc;justify-self:start;padding:5px}.system[data-v-a12a372e]>.tabs button{transition:transform .35s var(--spring), background-color .2s, box-shadow .2s;border-radius:999px;padding:9px 18px}.system[data-v-a12a372e]>.tabs button:hover{transform:translateY(-2px)scale(1.03)}.system[data-v-a12a372e] .connect .step,.system[data-v-a12a372e] .connect .checks li{background:linear-gradient(145deg, #ffffffad, #ffffff47), var(--surface);box-shadow:inset 0 1px 0 white, 0 12px 24px -24px var(--accent);-webkit-backdrop-filter:blur(18px)saturate(1.55);backdrop-filter:blur(18px)saturate(1.55);transition:transform .35s var(--spring), box-shadow .25s;border:1px solid #ffffffd9;border-radius:22px}.system[data-v-a12a372e] .connect .step:hover,.system[data-v-a12a372e] .connect .checks li:hover{box-shadow:inset 0 1px 0 white, 0 16px 28px -21px var(--accent);transform:translateY(-3px)}.system[data-v-a12a372e] .connect .num{background:linear-gradient(145deg, white, color-mix(in srgb, var(--glow-a) 75%, white));box-shadow:inset 0 1px 0 white, 0 5px 14px -9px var(--accent);color:var(--accent);border:1px solid #fff}@keyframes system-bob-a12a372e{to{transform:translateY(22px)scale(1.08)}}@media (width<=760px){.system-intro[data-v-a12a372e]{min-height:0;padding:27px 23px}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Dt as e,E as t,Et as n,G as r,H as i,I as a,J as o,M as s,N as c,P as l,Q as u,S as d,St as f,T as p,Tt as m,V as h,W as g,X as _,Y as v,Z as y,_t as b,a as x,b as S,bt as C,dt as w,et as T,f as E,ft as D,gt as O,h as k,i as A,it as j,j as M,lt as N,m as P,n as F,o as I,p as L,pt as R,rt as z,s as B,st as V,t as ee,tt as H,ut as U,v as W,w as G,wt as K,xt as te,yt as q,z as J}from"./Empty-CAGOJsfD.js";import{v as ne}from"./mind-CBTkFje2.js";import{c as Y,f as re,l as X,n as ie,o as ae}from"./index-L0bHax8C.js";var oe={class:`connect`},Z={class:`card connection`},Q={class:`card-head`},se={class:`eyebrow`},ce={class:`pill`},le={key:0,class:`notice`,role:`note`},ue={class:`muted`},de={class:`connection-details`},fe={class:`detail`},pe={class:`instructions`},me={class:`muted`},$={class:`muted note`},he={key:0,class:`row`},ge=[`disabled`],_e={class:`muted`},ve=[`disabled`,`placeholder`],ye={key:0,class:`faint`},be=[`disabled`,`placeholder`],xe={key:0,class:`faint`},Se={class:`row`},Ce=[`disabled`],we={key:0,class:`faint`},Te={key:0,class:`connection-details`},Ee={class:`detail`},De={"data-state":``},Oe={key:0,class:`detail`},ke={class:`warn-text`},Ae={key:1,class:`detail`},je={class:`detail`},Me={class:`detail`},Ne={key:1,class:`notice`,role:`note`},Pe={class:`instructions`},Fe={class:`muted notes`},Ie={class:`card checklist`},Le={class:`card-head`},Re={class:`eyebrow`},ze={class:`chip`},Be={class:`checks`},Ve={class:`mark`,"aria-hidden":`true`},He={class:`muted`},Ue=[`data-fix`,`onClick`],We=F(z({__name:`ConnectQQ`,emits:[`open`],setup(n,{emit:s}){let c=s,d=o(()=>B.health.connection||{}),p=o(()=>d.value.channel===`qqbot`?`qqbot`:`onebot`),h=o(()=>!!d.value.locked),_=o(()=>!!d.value.online);o(()=>d.value.onebot||{});let S=o(()=>d.value.qqbot||{}),E=o(()=>String(B.health.settings.qqbotAppId||``)),O=o(()=>!!B.health.settings.hasQqbotSecret),k=f(p.value);b(p,e=>k.value=e);let j=o(()=>`${location.protocol===`https:`?`wss`:`ws`}://${location.host}/onebot/v11/ws`),N=o(()=>[{key:`onebot`,label:a(`OneBot 11`),count:p.value===`onebot`?a(`使用中`):``},{key:`qqbot`,label:a(`QQ 官方机器人`),count:p.value===`qqbot`?a(`使用中`):``}]),F=te({appId:E.value,secret:``}),I=f(!1),L=o(()=>F.appId.trim()!==E.value||!!F.secret.trim());b(L,e=>{B.dirty=e}),b(E,e=>{L.value||(F.appId=e)}),U(()=>{B.dirty=!1});let R=o(()=>!!F.appId.trim()&&(O.value||!!F.secret.trim())),z=l({idle:M(`未启用`),unconfigured:M(`尚未填写 AppID 与 AppSecret`),connecting:M(`正在连接开放平台`),ready:M(`已连接`),closed:M(`连接已断开,正在重连`),error:M(`连接出错`)}),V=l({all:M(`全部群消息`),mentions:M(`只有 @ 她的消息`),unknown:M(`尚未收到群消息`)}),ee=o(()=>z[S.value.state||`idle`]??z.idle),G=o(()=>V[S.value.groupMessages||`unknown`]??V.unknown),q=o(()=>p.value===`qqbot`&&S.value.groupMessages===`mentions`);async function J(e){if(I.value||h.value||e===p.value)return;let n=a(e===`qqbot`?`QQ 官方机器人`:`OneBot 11`);if(!_.value||await t(a(`切换后会断开当前连接。原来方式下的会话仍可查看,但不能再向它们发送消息。`),{title:a(`切换连接方式`),confirmText:a(`切换`),cancelText:a(`先不切换`)})){I.value=!0;try{await P(`/settings`,`PATCH`,{channel:e}),await x(),W(a(`已切换为 {name}`,{name:n}))}catch(e){W(e.message,!0)}finally{I.value=!1}}}async function ne(){if(!I.value){if(!R.value){W(a(`请填写 AppID 和 AppSecret`),!0);return}I.value=!0;try{let e={qqbotAppId:F.appId.trim()};F.secret.trim()&&(e.qqbotSecret=F.secret.trim()),p.value!==`qqbot`&&!h.value&&(e.channel=`qqbot`),await P(`/settings`,`PATCH`,e),F.secret=``,await x(),W(a(`已保存`))}catch(e){W(e.message,!0)}finally{I.value=!1}}}let Y={token:[``,`connect`],credentials:[``,`connect`],qq:[``,`connect`],model:[``,`models`],mode:[``,`runtime`],session:[`chats`,``],persona:[`nature`,``]};function re(e){let[t,n]=Y[e]||[``,`connect`];t?A(t):c(`open`,n)}return(t,n)=>(w(),u(`div`,oe,[v(`section`,Z,[v(`div`,Q,[v(`div`,null,[v(`span`,se,e(K(a)(`QQ`)),1),v(`h2`,null,e(K(a)(`连接 QQ`)),1),v(`p`,null,e(K(a)(`两种连接方式二选一,同一时间只使用一种。她的记忆、心情和行为完全一致,区别只在消息怎么到达。`)),1)]),v(`span`,ce,[v(`span`,{class:m([`dot`,{off:!_.value}])},null,2),T(` `+e(_.value?K(a)(`QQ 已连接`):K(a)(`等待连接`)),1)])]),H(ie,{modelValue:k.value,"onUpdate:modelValue":n[0]||=e=>k.value=e,label:K(a)(`连接方式`),items:N.value},null,8,[`modelValue`,`label`,`items`]),h.value?(w(),u(`p`,le,e(K(a)(`连接方式由环境变量 LUCKYTRI_CHANNEL 指定,在这里不能更改。去掉该变量后即可在此选择。`)),1)):y(``,!0),k.value===`onebot`?(w(),u(r,{key:1},[v(`p`,ue,e(K(a)(`自备接入端,通过反向 WebSocket 连接。能看到全部群消息。`)),1),v(`div`,de,[v(`div`,fe,[v(`span`,null,e(K(a)(`反向 WebSocket 地址`)),1),v(`code`,null,e(j.value),1)])]),v(`ol`,pe,[v(`li`,null,e(K(a)(`同一台电脑上的接入端无需单独配置连接令牌。`)),1),v(`li`,null,e(K(a)(`在接入端启用反向 WebSocket 客户端,填写上方地址,消息格式选择数组。已有的地址配置可以继续使用。`)),1),v(`li`,null,e(K(a)(`在接入端完成 QQ 登录。连接成功后,本页状态会更新;新会话仍需在「对话」中开启参与。`)),1)]),v(`p`,me,e(K(a)(`远程接入时,连接密码使用管理密码;已有的远程连接令牌仍兼容。`)),1),v(`p`,$,e(K(a)(`LuckyTri 只负责接收,不提供、不安装也不管理接入端。`)),1),p.value===`onebot`?y(``,!0):(w(),u(`div`,he,[v(`button`,{class:`primary`,"data-use":`onebot`,disabled:I.value||h.value,onClick:n[1]||=e=>J(`onebot`)},e(K(a)(`改用这种方式`)),9,ge)]))],64)):(w(),u(r,{key:2},[v(`p`,_e,e(K(a)(`只需 AppID 与 AppSecret,无需额外软件。群里默认只收到 @ 她的消息。`)),1),v(`form`,{class:`stack tight`,onSubmit:g(ne,[`prevent`])},[v(`label`,null,[T(e(K(a)(`AppID`))+` `,1),C(v(`input`,{"onUpdate:modelValue":n[2]||=e=>F.appId=e,name:`qqbotAppId`,autocomplete:`off`,inputmode:`numeric`,maxlength:`40`,disabled:I.value||S.value.appIdFromEnv,placeholder:K(a)(`机器人的 AppID`)},null,8,ve),[[i,F.appId]]),S.value.appIdFromEnv?(w(),u(`small`,ye,e(K(a)(`由环境变量指定,在这里不能修改`)),1)):y(``,!0)]),v(`label`,null,[T(e(K(a)(`AppSecret`))+` `,1),C(v(`input`,{"onUpdate:modelValue":n[3]||=e=>F.secret=e,name:`qqbotSecret`,type:`password`,autocomplete:`new-password`,maxlength:`200`,disabled:I.value||S.value.secretFromEnv,placeholder:O.value||S.value.secretFromEnv?K(a)(`已保存,留空保留`):K(a)(`机器人的 AppSecret`)},null,8,be),[[i,F.secret]]),S.value.secretFromEnv?(w(),u(`small`,xe,e(K(a)(`由环境变量指定,在这里不能修改`)),1)):y(``,!0)]),v(`div`,Se,[v(`button`,{class:`primary`,"data-save":`qqbot`,disabled:I.value||S.value.appIdFromEnv&&S.value.secretFromEnv},e(p.value===`qqbot`||h.value?K(a)(`保存`):K(a)(`保存并使用`)),9,Ce),L.value?(w(),u(`span`,we,e(K(a)(`有尚未保存的修改`)),1)):y(``,!0)])],32),p.value===`qqbot`?(w(),u(`div`,Te,[v(`div`,Ee,[v(`span`,null,e(K(a)(`连接状态`)),1),v(`strong`,De,e(ee.value),1)]),S.value.error?(w(),u(`div`,Oe,[n[4]||=v(`span`,null,null,-1),v(`small`,ke,e(S.value.error),1)])):y(``,!0),S.value.botName?(w(),u(`div`,Ae,[v(`span`,null,e(K(a)(`机器人`)),1),v(`strong`,null,e(S.value.botName),1)])):y(``,!0),v(`div`,je,[v(`span`,null,e(K(a)(`最近收到消息`)),1),v(`strong`,null,e(S.value.lastEventAt?K(X)(S.value.lastEventAt):K(a)(`还没有`)),1)]),v(`div`,Me,[v(`span`,null,e(K(a)(`群消息范围`)),1),v(`strong`,null,e(G.value),1)])])):y(``,!0),q.value?(w(),u(`p`,Ne,e(K(a)(`目前只收到 @ 她的群消息。想让她看到群里的全部消息,请在开放平台的机器人设置里开启「接收所有消息」。`)),1)):y(``,!0),v(`ol`,Pe,[v(`li`,null,e(K(a)(`在 QQ 开放平台创建机器人,取得 AppID 与 AppSecret。`)),1),v(`li`,null,e(K(a)(`把运行 LuckyTri 的这台机器的出口 IP 加入机器人的 IP 白名单。`)),1),v(`li`,null,e(K(a)(`可选:开启「接收所有消息」,她才能看到群里没有 @ 她的话;不开启时只会收到 @ 她的消息。`)),1),v(`li`,null,e(K(a)(`填写上方的 AppID 与 AppSecret 并保存。状态变为「已连接」后,在群里 @ 她或私聊她,新会话会出现在「对话」中。`)),1)]),v(`ul`,Fe,[v(`li`,null,e(K(a)(`官方平台不提供群名称:新会话以占位名出现,可以在「对话」中为它改名。`)),1),v(`li`,null,e(K(a)(`官方平台上,同一个人在不同的群里标识不同。像只在不同的房间见过对方一样,平台给出统一身份之前,她不会把两处的人当成同一个人。`)),1),v(`li`,null,e(K(a)(`对方关闭了机器人的主动消息时,她不会去打扰,会等对方来找她。`)),1)])],64))]),v(`section`,Ie,[v(`div`,Le,[v(`div`,null,[v(`span`,Re,e(K(a)(`就绪检查`)),1),v(`h2`,null,e(K(a)(`还差哪一步`)),1)]),v(`span`,ze,e(K(B).health.readiness?.completed??0)+` / `+e(K(B).health.readiness?.total??0),1)]),v(`ol`,Be,[(w(!0),u(r,null,D(K(B).health.readiness?.checks||[],t=>(w(),u(`li`,{key:t.id,class:m({done:t.done})},[v(`span`,Ve,e(t.done?`✓`:``),1),v(`div`,null,[v(`b`,null,e(t.name),1),v(`small`,He,e(t.detail),1)]),v(`button`,{class:`small`,"data-fix":t.id,onClick:e=>re(t.id)},e(t.done?K(a)(`查看`):K(a)(`去处理`)),9,Ue)],2))),128))])])]))}}),[[`__scopeId`,`data-v-6f4553ed`]]);async function Ge(e){return P(`/core/models`,`PUT`,{models:e})}async function Ke(e){return P(`/core/models/`+encodeURIComponent(e),`DELETE`,{})}async function qe(e){return P(`/model/test`,`POST`,{modelId:e})}var Je={class:`card embedding-profile`,"aria-labelledby":`embedding-title`},Ye={id:`embedding-title`},Xe={class:`muted`},Ze={key:0,class:`faint`},Qe={class:`check`},$e={class:`fields`},et=[`required`],tt=[`placeholder`],nt=[`placeholder`],rt={class:`fields`},it={value:`openai`},at={value:`multimodal`},ot={class:`save-bar`},st=[`disabled`],ct=[`disabled`],lt={class:`faint`},ut={key:2,role:`status`},dt=F(z({__name:`EmbeddingProfile`,setup(t){let n=te({enabled:!1,label:a(`知识向量`),baseUrl:``,model:``,apiKey:``,dimensions:0,batchSize:10,timeoutMs:9e4,protocol:`openai`}),r=f(!1),o=f(!1),s=f(!1),c=f(``);async function l(){try{Object.assign(n,await P(`/core/knowledge/embedding`),{apiKey:``}),s.value=!0}catch(e){c.value=e.message}}async function d(){r.value=!0;try{Object.assign(n,await P(`/core/knowledge/embedding`,`PATCH`,n),{apiKey:``}),o.value=!1,W(a(`知识向量模型已保存`))}catch(e){W(e.message,!0)}finally{r.value=!1}}async function p(){r.value=!0;try{let e=await P(`/core/knowledge/embedding/test`,`POST`,{});c.value=a(`连接成功,向量维度 {dimensions}`,{dimensions:e.dimensions})}catch(e){c.value=e.message}finally{r.value=!1}}return N(l),(t,l)=>(w(),u(`section`,Je,[v(`h2`,Ye,e(K(a)(`知识向量模型`)),1),v(`p`,Xe,e(K(a)(`填写任意 OpenAI 兼容向量服务(/embeddings)的请求地址、模型名和密钥。火山方舟地址可以不填模型名,会用 doubao-embedding-vision。维度填 0 表示用模型自己的长度(doubao-embedding-vision 是 2048),写明长度就按写的请求。不启用或连不上时,对话和关键词回忆照常进行。`)),1),s.value&&!n.configured?(w(),u(`p`,Ze,e(K(a)(`当前兼容旧配置,跟随默认模型。保存后改用独立配置。`)),1)):y(``,!0),s.value?(w(),u(`form`,{key:1,autocomplete:`off`,onSubmit:g(d,[`prevent`]),onInput:l[7]||=e=>o.value=!0,onChange:l[8]||=e=>o.value=!0},[v(`label`,Qe,[C(v(`input`,{"onUpdate:modelValue":l[0]||=e=>n.enabled=e,type:`checkbox`,name:`embeddingEnabled`},null,512),[[J,n.enabled]]),T(e(K(a)(`启用知识向量`)),1)]),v(`div`,$e,[v(`label`,null,[T(e(K(a)(`请求地址`)),1),C(v(`input`,{"onUpdate:modelValue":l[1]||=e=>n.baseUrl=e,name:`embeddingBaseUrl`,type:`url`,inputmode:`url`,autocomplete:`off`,spellcheck:`false`,placeholder:`https://example.com/v1`,required:n.enabled},null,8,et),[[i,n.baseUrl]])]),v(`label`,null,[T(e(K(a)(`模型名称`)),1),C(v(`input`,{"onUpdate:modelValue":l[2]||=e=>n.model=e,name:`embeddingModelName`,autocomplete:`off`,spellcheck:`false`,placeholder:K(a)(`火山方舟可留空`)},null,8,tt),[[i,n.model]])]),v(`label`,null,[T(e(K(a)(`向量服务密钥`)),1),C(v(`input`,{"onUpdate:modelValue":l[3]||=e=>n.apiKey=e,name:`embeddingApiKey`,type:`text`,class:`secret`,autocomplete:`off`,spellcheck:`false`,"data-1p-ignore":``,"data-lpignore":`true`,placeholder:n.hasApiKey?K(a)(`已保存,留空保留`):K(a)(`填写向量服务密钥`)},null,8,nt),[[i,n.apiKey]])])]),v(`details`,null,[v(`summary`,null,e(K(a)(`自动选择的细节`)),1),v(`div`,rt,[v(`label`,null,[T(e(K(a)(`向量维度(0 表示自动)`)),1),C(v(`input`,{"onUpdate:modelValue":l[4]||=e=>n.dimensions=e,name:`embeddingDimensions`,type:`number`,min:`0`,max:`65536`},null,512),[[i,n.dimensions,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`每批段落数`)),1),C(v(`input`,{"onUpdate:modelValue":l[5]||=e=>n.batchSize=e,name:`embeddingBatchSize`,type:`number`,min:`1`,max:`128`},null,512),[[i,n.batchSize,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`请求格式`)),1),C(v(`select`,{"onUpdate:modelValue":l[6]||=e=>n.protocol=e,name:`embeddingProtocol`},[v(`option`,it,e(K(a)(`OpenAI 兼容(可批量)`)),1),v(`option`,at,e(K(a)(`方舟多模态接口(逐条)`)),1)],512),[[h,n.protocol]])])])]),v(`div`,ot,[v(`button`,{class:`primary`,disabled:r.value},e(K(a)(`保存向量模型`)),9,st),v(`button`,{type:`button`,disabled:r.value||o.value||!n.enabled||!n.configured,onClick:p},e(K(a)(`测试向量连接`)),9,ct),v(`small`,lt,e(o.value?K(a)(`有未保存的修改`):K(a)(`配置已载入`)),1)])],32)):y(``,!0),c.value?(w(),u(`p`,ut,e(c.value),1)):y(``,!0)]))}}),[[`__scopeId`,`data-v-944d9f50`]]),ft={class:`card recall-panel`,"aria-labelledby":`recall-title`},pt={id:`recall-title`},mt={class:`muted`},ht={key:0,class:`stats`},gt={key:0,class:`pill strong`},_t={key:1,class:`pill`},vt={key:2,class:`pill warn`},yt={key:1,class:`waiting`},bt={key:2,class:`waiting`},xt={value:``,disabled:``},St=[`value`],Ct=[`placeholder`],wt=[`disabled`],Tt={key:3,role:`status`},Et={key:4,class:`result`},Dt={class:`faint`},Ot={class:`faint`},kt={key:0,class:`faint`},At=F(z({__name:`RecallPanel`,setup(t){let n=f(null),s=f(``),c=o(()=>B.core?.sessions||[]),l=f(``),d=f(``),p=f(null),m=f(!1),_={fact:a(`事实`),episode:a(`情景`),meeting:a(`相遇`),self:a(`自我线索`),thought:a(`念头`),diary:a(`日记`),period:a(`回顾`),anticipation:a(`约定`),message:a(`原话`)},b={meaning:a(`意思相关`),words:a(`说到了`),person:a(`关于这个人`)},x=o(()=>{let e=n.value?.coverage;return e?.total?`${e.embedded||0} / ${e.total}`:``});async function S(){try{n.value=await P(`/mind/recall`),s.value=``}catch(e){s.value=e.message}}async function E(){if(l.value&&d.value.trim()){m.value=!0;try{p.value=await P(`/mind/recall/probe`,`POST`,{session:l.value,text:d.value}),s.value=``}catch(e){s.value=e.message}finally{m.value=!1}}}return N(S),(t,o)=>(w(),u(`section`,ft,[v(`h2`,pt,e(K(a)(`回忆索引`)),1),v(`p`,mt,e(K(a)(`她的事实、情景、自我线索和近一个月的原话都在同一个索引里,按意思、字词和相关的人一起检索。向量还没覆盖的部分先按字词找。`)),1),n.value?(w(),u(`div`,ht,[(w(!0),u(r,null,D(n.value.items,t=>(w(),u(`span`,{key:t.kind,class:`pill`},e(_[t.kind]||t.kind)+` `+e(t.n),1))),128)),x.value?(w(),u(`span`,gt,e(K(a)(`已有向量`))+` `+e(x.value),1)):y(``,!0),n.value.embedding?.latencyMs?(w(),u(`span`,_t,e(K(a)(`向量延迟`))+` `+e(n.value.embedding.latencyMs.p50)+` ms`,1)):y(``,!0),n.value.embedding?.lastError?(w(),u(`span`,vt,e(n.value.embedding.lastError),1)):y(``,!0)])):y(``,!0),n.value?.waiting?.length?(w(),u(`ul`,yt,[(w(!0),u(r,null,D(n.value.waiting,t=>(w(),u(`li`,{key:t.key},e(K(a)(`等待重试`))+` `+e(t.key)+` × `+e(t.failures)+`:`+e(t.lastError),1))),128))])):y(``,!0),n.value?.unavailableModels?.length?(w(),u(`ul`,bt,[(w(!0),u(r,null,D(n.value.unavailableModels,t=>(w(),u(`li`,{key:t.key},e(K(a)(`暂时停用的备用模型`))+` `+e(t.label)+`:`+e(t.reason),1))),128))])):y(``,!0),v(`form`,{class:`probe`,onSubmit:g(E,[`prevent`])},[C(v(`select`,{"onUpdate:modelValue":o[0]||=e=>l.value=e,name:`recallSession`,required:``},[v(`option`,xt,e(K(a)(`选择会话`)),1),(w(!0),u(r,null,D(c.value,t=>(w(),u(`option`,{key:t.id,value:t.id},e(t.name||t.id),9,St))),128))],512),[[h,l.value]]),C(v(`input`,{"onUpdate:modelValue":o[1]||=e=>d.value=e,name:`recallText`,maxlength:`500`,placeholder:K(a)(`输入一句话,看她会想起什么`)},null,8,Ct),[[i,d.value]]),v(`button`,{disabled:m.value||!l.value||!d.value.trim()},e(K(a)(`试试回忆`)),9,wt)],32),s.value?(w(),u(`p`,Tt,e(s.value),1)):y(``,!0),p.value?(w(),u(`div`,Et,[v(`p`,Dt,e(p.value.mode===`hybrid`?K(a)(`意思与字词一起`):K(a)(`仅字词`))+` · `+e(K(a)(`候选`))+` `+e(p.value.candidates),1),v(`ol`,null,[(w(!0),u(r,null,D(p.value.items,t=>(w(),u(`li`,{key:t.id},[v(`strong`,null,e(_[t.kind]||t.kind),1),T(` `+e(t.text)+` `,1),v(`small`,Ot,[T(e(b[t.why])+` `,1),t.standsOut===null?y(``,!0):(w(),u(r,{key:0},[T(` · `+e(K(a)(`突出度`))+` `+e(t.standsOut),1)],64)),T(` · `+e(K(a)(`共有字词`))+` `+e(t.sharedWords),1)])]))),128))]),p.value.items.length?y(``,!0):(w(),u(`p`,kt,e(K(a)(`没有想起什么`)),1))])):y(``,!0)]))}}),[[`__scopeId`,`data-v-cdde3f37`]]),jt={class:`library`},Mt={class:`model-workspace`},Nt={class:`card shelf`},Pt={class:`shelf-head`},Ft={class:`faint`},It={class:`rows`},Lt={key:0,class:`muted`},Rt=[`open`,`data-saved-vendor`,`onToggle`],zt={class:`vendor-models`},Bt=[`onClick`],Vt={class:`who`},Ht={key:0,class:`card detail`},Ut={class:`card-head`},Wt={class:`eyebrow`},Gt=[`data-tone`],Kt={class:`form-grid`},qt={key:0},Jt=[`placeholder`],Yt={class:`wide`},Xt=[`placeholder`],Zt={class:`faint`},Qt={class:`form-grid`},$t={key:0},en={key:1},tn={class:`advanced`},nn={class:`form-grid`},rn=[`placeholder`],an={class:`faint`},on={class:`caps`},sn=[`onUpdate:modelValue`,`name`],cn={key:0,id:`modelTestResult`,class:`notice`,role:`status`},ln={class:`actions`},un=[`disabled`],dn={class:`faint`},fn={key:0,class:`check`},pn=[`checked`],mn=[`disabled`],hn={key:1,class:`card detail`},gn={class:`card usage-panel`,"aria-labelledby":`token-usage-title`},_n={class:`usage-intro`},vn={class:`eyebrow`},yn={id:`token-usage-title`},bn={class:`usage-total`},xn={class:`usage-detail`},Sn={class:`usage-stat`},Cn={class:`usage-stat`},wn={class:`usage-stat cache-stat`},Tn={class:`usage-stat`},En={class:`usage-foot`},Dn={key:0},On={key:1,class:`usage-error`},kn={key:2},An=[`disabled`],jn={class:`model-picker`},Mn={class:`muted`},Nn={class:`catalog-search`},Pn=[`placeholder`],Fn=[`data-vendor`],In={class:`vendor-summary`},Ln={class:`vendor-name`},Rn={class:`presets`},zn=[`data-preset`,`onClick`],Bn={key:0,class:`muted search-empty`},Vn=F(z({__name:`ModelLibrary`,setup(c){let l=o(()=>B.health?.modelCatalog||[]),d=o(()=>B.health?.effortLabels||{none:a(`关闭`),minimal:a(`极低`),low:a(`低`),medium:a(`中`),high:a(`高`),xhigh:a(`极高`),max:a(`最深`)}),p=f(B.core.models.map(e=>({...e}))),h=f(p.value.length?0:-1),_=f(p.value.length?Q(p.value[0]):``),S=f(!1),E=f(!1),O=f(!1),k=f(``),A=f(``),j=f(null),M=f(!1),F=f(``),I=te(Z());p.value[0]&&Object.assign(I,p.value[0],{apiKey:``});let L=o(()=>h.value>=0&&!!I.id),R=o(()=>{let e=[];for(let t of l.value){if(t.id===`custom`)continue;let n=e.find(e=>e.vendor===t.vendor);n||(n={vendor:t.vendor,models:[]},e.push(n)),n.models.push(t)}return e}),z=o(()=>{let e=k.value.trim().toLocaleLowerCase();return e?R.value.map(t=>({...t,models:t.models.filter(n=>[t.vendor,n.label,n.model,n.summary].filter(Boolean).join(` `).toLocaleLowerCase().includes(e))})).filter(e=>e.models.length):R.value}),V=o(()=>{let e=[];return p.value.forEach((t,n)=>{let r=Q(t),i=e.find(e=>e.vendor===r);i||(i={vendor:r,models:[]},e.push(i)),i.models.push({model:t,index:n})}),e}),U=o(()=>l.value.find(e=>e.id===`custom`)),G=o(()=>l.value.filter(e=>e.vendor&&e.vendor===I.vendor)),ne=o(()=>l.value.find(e=>e.id===I.presetId)||l.value.find(e=>e.model&&e.model===I.model&&e.baseUrl===I.baseUrl)),X=o(()=>{let e=ne.value?.contextWindows||[];if(e.length<2)return[];let t=Number(I.contextWindow);return e.some(e=>e.contextWindow===t)?e:[...e,{label:a(`已保存 {value}`,{value:fe(t)}),contextWindow:t,maxInputTokens:Number(I.maxInputTokens),maxOutputTokens:Number(I.maxOutputTokens)}]}),ie=o(()=>{let e=Array.isArray(I.reasoningEfforts)&&I.reasoningEfforts.length?[...I.reasoningEfforts]:[`none`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`];return I.reasoningEffort&&!e.includes(I.reasoningEffort)&&e.unshift(I.reasoningEffort),e}),oe=o(()=>B.core.models.some(e=>e.id===I.id));function Z(){return{id:``,presetId:``,label:``,provider:``,vendor:``,baseUrl:``,model:``,apiKey:``,hasApiKey:!1,contextWindow:128e3,maxInputTokens:119808,maxOutputTokens:8192,vision:!1,system:!0,json:!0,tools:!1,embedding:!1,embeddingModel:``,reasoningEffort:`none`,reasoningEfforts:[`none`,`low`,`medium`,`high`],thinkingStyle:`openai`,tokenField:`max_tokens`,omitSampling:!1,temperature:.85,topP:1,timeoutMs:9e4,isDefault:!1,enabled:!0}}function Q(e){let t={"volcengine-coding-plan":a(`火山方舟 Coding Plan`),"opencode-go":`OpenCode Go`,"opencode-zen":`OpenCode Zen`,deepseek:`DeepSeek`,openai:`OpenAI`,bedrock:a(`亚马逊 Bedrock`),qwen:a(`通义千问`),moonshot:`Kimi`,kimi:`Kimi`,zhipu:a(`智谱 GLM`),glm:a(`智谱 GLM`),mimo:a(`小米 MiMo`),siliconflow:`SiliconFlow`,openrouter:`OpenRouter`};return String(e?.vendor||``).trim()||t[String(e?.provider||``).toLowerCase()]||String(e?.provider||a(`自定义供应商`))}function se(e,t){let n=t.currentTarget;_.value=n.open?e:``}function ce(e){let{summary:t,contextWindows:n,...r}=e;return{...r,presetId:e.id}}function le(e){let{contextWindows:t,...n}=e;return n}function ue(e){let t=Number(e.contextWindow),n=Number(e.maxOutputTokens),r=Number(e.maxInputTokens);return(!Number.isFinite(t)||t<2)&&(t=2),(!Number.isFinite(n)||n<1)&&(n=1),n>=t&&(n=t-1),(!Number.isFinite(r)||r<1)&&(r=t-n),r+n>t&&(r=t-n),{contextWindow:t,maxInputTokens:r,maxOutputTokens:n}}function de(e){let t=Number(e.target.value),n=X.value.find(e=>e.contextWindow===t);n&&(I.contextWindow=n.contextWindow,I.maxInputTokens=n.maxInputTokens,I.maxOutputTokens=n.maxOutputTokens,B.dirty=!0)}function fe(e){let t=Number(e)||0;return t>=1e6?(t%1048576==0?t/1048576:Number((t/1e6).toFixed(2)))+`M`:t>=1e3?(t%1e3==0?t/1e3:t%1024==0?t/1024:Math.round(t/1e3))+`K`:String(t)}function pe(e){if(e.id===`openrouter`)return a(`按所选模型填写上下文和输出参数`);if(!e.model)return a(`填写模型 ID 和对应参数`);let t=e.contextWindows||[],n=t.length?t.map(e=>e.label).join(` / `):fe(e.contextWindow);return a(`上下文 {context} · 输出 {v}`,{context:n,v:fe(e.maxOutputTokens)})}function me(e){return[`mimo`,`qwen`,`kimi-toggle`].includes(I.thinkingStyle)?a(e===`none`?`关闭`:`开启`):`${d.value[e]||e} / ${e}`}function $(e){return new Intl.NumberFormat(s()).format(Number(e)||0)}async function he(){if(!M.value){M.value=!0;try{j.value=await P(`/core/usage`),F.value=``}catch(e){F.value=e.message}finally{M.value=!1}}}N(()=>void he()),b(()=>B.tick,()=>void he());async function ge(){return B.dirty?await t(a(`放弃当前模型草稿?`),{title:a(`草稿还没保存`),confirmText:a(`放弃`),cancelText:a(`留下`)})?(B.dirty=!1,!0):!1:!0}async function _e(e){let t=p.value[e];t&&t.id!==I.id&&await ge()&&(p.value=p.value.filter(e=>e.id===t.id||B.core.models.some(t=>t.id===e.id)),h.value=p.value.findIndex(e=>e.id===t.id),_.value=Q(t),Object.assign(I,Z(),t,{apiKey:``}),A.value=``)}async function ve(){if(!await ge())return;p.value=B.core.models.map(e=>({...e})),p.value.length?p.value.some(e=>e.id===I.id)||(h.value=0,Object.assign(I,Z(),p.value[0],{apiKey:``})):(h.value=-1,Object.assign(I,Z()));let e=p.value[h.value]||p.value[0];_.value=e?Q(e):``,k.value=``,O.value=!0}function ye(e){p.value=B.core.models.map(e=>({...e}));let t={...Z(),...ce(e),id:`model-`+Date.now(),apiKey:``,hasApiKey:!1,isDefault:p.value.length===0};p.value.push(t),h.value=p.value.length-1,_.value=Q(t),Object.assign(I,t),A.value=``,O.value=!1,B.dirty=!0}function be(e){let t=e.target.value,n=l.value.find(e=>e.id===t);if(!n)return;Object.assign(I,Z(),ce(n),{id:I.id,apiKey:I.apiKey,hasApiKey:I.hasApiKey,isDefault:I.isDefault});let r=p.value[h.value];r&&(r.label=I.label),B.dirty=!0}function xe(){for(let e of p.value)e.isDefault=e.id===I.id;I.isDefault=!0,B.dirty=!0}async function Se(){let e=ue(I),t=p.value.map((t,n)=>le(n===h.value?{...I,...e,isDefault:!!I.isDefault,enabled:I.isDefault?!0:I.enabled!==!1,timeoutMs:Number(I.timeoutMs),temperature:Number(I.temperature),topP:Number(I.topP)}:{...t,isDefault:!!t.isDefault&&t.id!==I.id}));if(!t.some(e=>e.isDefault)&&t.length&&(t[0].isDefault=!0),!S.value){S.value=!0;try{await Ge(t),B.dirty=!1,await x(),p.value=B.core.models.map(e=>({...e})),Object.assign(I,Z(),p.value[h.value],{apiKey:``}),W(a(`已保存并应用`))}catch(e){W(e.message,!0)}finally{S.value=!1}}}async function Ce(){if(await t(a(`确定删除这个模型?`),{title:a(`删除模型`),confirmText:a(`删除`),danger:!0})){if(B.core.models.some(e=>e.id===I.id)&&await Ke(I.id),B.dirty=!1,await x(),p.value=B.core.models.map(e=>({...e})),A.value=``,!p.value.length){h.value=-1,_.value=``,Object.assign(I,Z());return}h.value=0,_.value=Q(p.value[0]),Object.assign(I,Z(),p.value[0],{apiKey:``})}}async function we(){if(!(!oe.value||B.dirty||E.value)){E.value=!0,A.value=a(`正在测试「{v}」…`,{v:I.label||I.model});try{let e=await qe(I.id);A.value=a(`✓ {v} 连接成功 · {latency} ms`,{v:I.label||e.model,latency:e.latency}),await x()}catch(e){A.value=e.message}finally{E.value=!1}}}return(t,o)=>(w(),u(`div`,jt,[v(`div`,Mt,[v(`aside`,Nt,[v(`div`,Pt,[v(`h2`,null,[T(e(K(a)(`模型库`))+` `,1),v(`small`,null,e(p.value.length),1)]),v(`button`,{id:`addModel`,class:`small primary`,onClick:ve},e(K(a)(`+ 新增模型`)),1)]),v(`p`,Ft,e(K(a)(`群聊、私聊和独处都使用默认模型。其余已启用的模型按这里的顺序作为备用。关掉的模型不会被调用。`)),1),v(`div`,It,[p.value.length?y(``,!0):(w(),u(`p`,Lt,e(K(a)(`还没有模型。`)),1)),(w(!0),u(r,null,D(V.value,t=>(w(),u(`details`,{key:t.vendor,class:`saved-vendor`,open:_.value===t.vendor,"data-saved-vendor":t.vendor,onToggle:e=>se(t.vendor,e)},[v(`summary`,null,[v(`span`,null,e(t.vendor),1),v(`small`,null,e(K(a)(`{length} 个模型`,{length:t.models.length})),1)]),v(`div`,zt,[(w(!0),u(r,null,D(t.models,t=>(w(),u(`button`,{key:t.model.id,class:m([`entity-row`,{selected:h.value===t.index}]),onClick:e=>_e(t.index)},[v(`span`,{class:`badge`,style:n({"--hue":K(re)(t.model.label||t.model.model||t.model.id)})},e(String(t.model.label||t.model.model||`?`).slice(0,1).toUpperCase()),5),v(`span`,Vt,[v(`b`,null,e(t.model.label||t.model.model),1),v(`small`,null,e(t.model.enabled===!1?K(a)(`已关闭`):t.model.isDefault?K(a)(`默认模型`):K(a)(`备用模型`)),1)])],10,Bt))),128))])],40,Rt))),128))])]),L.value?(w(),u(`section`,Ht,[v(`div`,Ut,[v(`div`,null,[v(`span`,Wt,e(K(a)(`模型档案`)),1),v(`h2`,null,e(I.label||K(a)(`新模型`)),1)]),v(`span`,{class:`chip`,"data-tone":I.hasApiKey?`ok`:`warn`},e((I.isDefault?K(a)(`默认模型 · `):``)+(I.hasApiKey?K(a)(`密钥已保存`):K(a)(`待填写密钥`))),9,Gt)]),v(`form`,{id:`modelForm`,class:`stack`,onSubmit:g(Se,[`prevent`]),onInput:o[14]||=e=>K(B).dirty=!0},[v(`fieldset`,null,[v(`legend`,null,e(K(a)(`连接`)),1),v(`div`,Kt,[G.value.length>1?(w(),u(`label`,qt,[T(e(K(a)(`同厂商模型`))+` `,1),H(Y,{"model-value":I.presetId,"aria-label":K(a)(`同厂商模型`),options:G.value.map(e=>({value:e.id,label:e.label})),onChange:be},null,8,[`model-value`,`aria-label`,`options`])])):y(``,!0),v(`label`,null,[T(e(K(a)(`显示名称`)),1),C(v(`input`,{"onUpdate:modelValue":o[0]||=e=>I.label=e,name:`label`,required:``},null,512),[[i,I.label]])]),v(`label`,null,[T(e(K(a)(`供应商`)),1),C(v(`input`,{"onUpdate:modelValue":o[1]||=e=>I.provider=e,name:`provider`,placeholder:K(a)(`例如 deepseek、openai`)},null,8,Jt),[[i,I.provider]])]),v(`label`,null,[T(e(K(a)(`API 地址`)),1),C(v(`input`,{"onUpdate:modelValue":o[2]||=e=>I.baseUrl=e,name:`baseUrl`,type:`url`,required:``},null,512),[[i,I.baseUrl]])]),v(`label`,null,[T(e(K(a)(`模型名称`)),1),C(v(`input`,{"onUpdate:modelValue":o[3]||=e=>I.model=e,name:`model`,required:``},null,512),[[i,I.model]])]),v(`label`,Yt,[o[18]||=T(` API Key `,-1),C(v(`input`,{"onUpdate:modelValue":o[4]||=e=>I.apiKey=e,name:`apiKey`,type:`password`,autocomplete:`new-password`,placeholder:I.hasApiKey?K(a)(`已保存,留空则保留`):K(a)(`填写供应商提供的密钥`)},null,8,Xt),[[i,I.apiKey]])])])]),v(`fieldset`,null,[v(`legend`,null,e(K(a)(`容量与思考`)),1),v(`p`,Zt,e(K(a)(`官方按输入长度分档计价的模型可以在标准和百万之间切换;输出上限默认是官方最大值,思考强度只列出这个模型支持的档位。`)),1),v(`div`,Qt,[X.value.length?(w(),u(`label`,$t,[T(e(K(a)(`上下文容量`))+` `,1),H(Y,{name:`contextWindow`,"model-value":I.contextWindow,options:X.value.map(e=>({value:e.contextWindow,label:e.label})),onChange:de},null,8,[`model-value`,`options`])])):(w(),u(`label`,en,[T(e(K(a)(`上下文容量`)),1),C(v(`input`,{"onUpdate:modelValue":o[5]||=e=>I.contextWindow=e,name:`contextWindow`,type:`number`},null,512),[[i,I.contextWindow,void 0,{number:!0}]])])),v(`label`,null,[T(e(K(a)(`最大输入 Token`)),1),C(v(`input`,{"onUpdate:modelValue":o[6]||=e=>I.maxInputTokens=e,name:`maxInputTokens`,type:`number`},null,512),[[i,I.maxInputTokens,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`最大输出 Token`)),1),C(v(`input`,{"onUpdate:modelValue":o[7]||=e=>I.maxOutputTokens=e,name:`maxOutputTokens`,type:`number`},null,512),[[i,I.maxOutputTokens,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`思考强度`))+` `,1),H(Y,{modelValue:I.reasoningEffort,"onUpdate:modelValue":o[8]||=e=>I.reasoningEffort=e,name:`reasoningEffort`,"aria-label":K(a)(`思考强度`),options:ie.value.map(e=>({value:e,label:me(e)}))},null,8,[`modelValue`,`aria-label`,`options`])])])]),v(`details`,tn,[v(`summary`,null,e(K(a)(`高级参数与模型能力`)),1),v(`div`,nn,[v(`label`,null,[T(e(K(a)(`随机程度 Temperature`)),1),C(v(`input`,{"onUpdate:modelValue":o[9]||=e=>I.temperature=e,name:`temperature`,type:`number`,step:`0.05`},null,512),[[i,I.temperature,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`采样范围 Top P`)),1),C(v(`input`,{"onUpdate:modelValue":o[10]||=e=>I.topP=e,name:`topP`,type:`number`,step:`0.05`},null,512),[[i,I.topP,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`超时(毫秒)`)),1),C(v(`input`,{"onUpdate:modelValue":o[11]||=e=>I.timeoutMs=e,name:`timeoutMs`,type:`number`},null,512),[[i,I.timeoutMs,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`知识检索模型`)),1),C(v(`input`,{"onUpdate:modelValue":o[12]||=e=>I.embeddingModel=e,name:`embeddingModel`,placeholder:K(a)(`留空跟随对话模型`)},null,8,rn),[[i,I.embeddingModel]])])]),v(`p`,an,e(K(a)(`打开图片理解后,聊天里的图片会先在本机读取,再连同画面交给这个模型。主模型不能看图时,到会话设置另选一个打开了图片理解的视觉兼容模型。`)),1),v(`div`,on,[(w(!0),u(r,null,D({vision:K(a)(`图片理解`),system:`System Prompt`,json:K(a)(`JSON 输出`),tools:K(a)(`工具调用`),embedding:K(a)(`知识向量`)},(t,n)=>(w(),u(`label`,{key:n,class:`check`},[C(v(`input`,{"onUpdate:modelValue":e=>I[n]=e,name:n,type:`checkbox`},null,8,sn),[[J,I[n]]]),T(e(t),1)]))),128))])]),A.value?(w(),u(`div`,cn,e(A.value),1)):y(``,!0),v(`div`,ln,[v(`button`,{class:`primary`,disabled:S.value},e(S.value?K(a)(`正在保存…`):K(a)(`保存模型`)),9,un),v(`small`,dn,e(K(B).dirty?K(a)(`有未保存的修改`):K(a)(`已保存的模型才会用来测试和回复`)),1),I.isDefault?y(``,!0):(w(),u(`label`,fn,[v(`input`,{type:`checkbox`,checked:I.enabled!==!1,onChange:o[13]||=e=>{I.enabled=e.target.checked,K(B).dirty=!0}},null,40,pn),T(e(K(a)(`启用这个备用模型`)),1)])),I.isDefault?y(``,!0):(w(),u(`button`,{key:1,id:`setDefaultModel`,type:`button`,onClick:xe},e(K(a)(`设为默认模型`)),1)),oe.value?(w(),u(`button`,{key:2,id:`testModel`,type:`button`,disabled:S.value||E.value||K(B).dirty,onClick:we},e(E.value?K(a)(`正在测试…`):K(B).dirty?K(a)(`保存后测试此模型`):K(a)(`测试此模型连接`)),9,mn)):y(``,!0),v(`button`,{id:`deleteModel`,type:`button`,class:`danger push`,onClick:Ce},e(K(a)(`删除模型`)),1)])],32)])):(w(),u(`section`,hn,[H(ee,{title:K(a)(`还没有模型`),text:K(a)(`常见厂商会预填模型参数;OpenRouter 可选 GPT-6 预设,也可用自选模型手动填写模型 ID 和参数。`)},{default:q(()=>[v(`button`,{class:`primary`,onClick:ve},e(K(a)(`+ 新增模型`)),1)]),_:1},8,[`title`,`text`])]))]),H(dt),H(At),v(`section`,gn,[v(`div`,_n,[v(`div`,null,[v(`span`,vn,e(K(a)(`TOKEN LEDGER · 累计用量`)),1),v(`h2`,yn,e(K(a)(`一路聊到现在`)),1),v(`p`,null,e(K(a)(`统计本机账本记录的模型调用;缓存 Token 已包含在输入量里。`)),1)]),v(`div`,bn,[v(`strong`,null,e($(j.value?.total)),1),v(`span`,null,e(K(a)(`累计 Token`)),1)])]),v(`div`,xn,[v(`div`,Sn,[v(`span`,null,e(K(a)(`输入`)),1),v(`b`,null,e($(j.value?.input)),1)]),v(`div`,Cn,[v(`span`,null,e(K(a)(`输出`)),1),v(`b`,null,e($(j.value?.output)),1)]),v(`div`,wn,[v(`span`,null,[T(e(K(a)(`缓存命中`))+` `,1),v(`small`,null,e(K(a)(`(输入子项)`)),1)]),v(`b`,null,e($(j.value?.cached)),1)]),v(`div`,Tn,[v(`span`,null,e(K(a)(`调用次数`)),1),v(`b`,null,e($(j.value?.calls)),1)])]),v(`div`,En,[j.value?.since?(w(),u(`small`,Dn,[T(e(K(a)(`从 {v} 开始记录 · {v2} 为模型返回用量`,{v:new Date(j.value.since).toLocaleDateString(K(s)()),v2:$(j.value.reportedTokens)}))+` `,1),j.value.estimatedCalls?(w(),u(r,{key:0},[T(e(K(a)(`· {v} 次调用按文本估算`,{v:$(j.value.estimatedCalls)})),1)],64)):y(``,!0)])):F.value?(w(),u(`small`,On,e(F.value),1)):(w(),u(`small`,kn,e(K(a)(`还没有模型调用记录。`)),1)),v(`button`,{type:`button`,class:`usage-refresh`,disabled:M.value,onClick:he},e(M.value?K(a)(`更新中…`):K(a)(`刷新统计 ↻`)),9,An)])]),H(ae,{open:O.value,title:K(a)(`选择模型`),eyebrow:`MODELS`,width:`880px`,onClose:o[17]||=e=>O.value=!1},{default:q(()=>[v(`div`,jn,[v(`p`,Mn,e(K(a)(`先选供应商,再挑具体模型;支持搜索。火山方舟 Coding Plan 已预填套餐专用接口与型号参数,请勿换成普通推理 API 地址。`)),1),v(`label`,Nn,[v(`span`,null,e(K(a)(`搜索模型或供应商`)),1),C(v(`input`,{"onUpdate:modelValue":o[15]||=e=>k.value=e,type:`search`,placeholder:K(a)(`例如:火山方舟、Kimi K3、DeepSeek`)},null,8,Pn),[[i,k.value]])]),(w(!0),u(r,null,D(z.value,t=>(w(),u(`details`,{key:t.vendor,class:`vendor`,"data-vendor":t.vendor},[v(`summary`,In,[v(`span`,Ln,[v(`b`,null,e(t.vendor),1),v(`small`,null,e(K(a)(`{length} 个预设`,{length:t.models.length})),1)]),o[19]||=v(`span`,{class:`vendor-chevron`,"aria-hidden":`true`},`⌄`,-1)]),v(`div`,Rn,[(w(!0),u(r,null,D(t.models,t=>(w(),u(`button`,{key:t.id,type:`button`,class:`preset-card`,"data-preset":t.id,onClick:e=>ye(t)},[v(`b`,null,e(t.label),1),v(`small`,null,e(t.model||K(a)(`填写你在 OpenRouter 选择的模型 ID`)),1),v(`small`,null,e(pe(t)),1),v(`small`,null,e(t.summary),1)],8,zn))),128))])],8,Fn))),128)),z.value.length?y(``,!0):(w(),u(`p`,Bn,e(K(a)(`没有找到匹配的模型预设。`)),1)),U.value?(w(),u(`button`,{key:1,type:`button`,class:`preset-card custom`,"data-preset":`custom`,onClick:o[16]||=e=>ye(U.value)},[v(`b`,null,e(U.value.label),1),v(`small`,null,e(U.value.summary),1)])):y(``,!0)])]),_:1},8,[`open`,`title`])]))}}),[[`__scopeId`,`data-v-8a9bd858`]]),Hn={class:`switch`},Un=[`name`,`disabled`],Wn=z({__name:`Toggle`,props:j({name:{},disabled:{type:Boolean}},{modelValue:{type:Boolean,default:!1},modelModifiers:{}}),emits:[`update:modelValue`],setup(e){let t=O(e,`modelValue`);return(n,r)=>(w(),u(`label`,Hn,[C(v(`input`,{"onUpdate:modelValue":r[0]||=e=>t.value=e,type:`checkbox`,name:e.name,disabled:e.disabled},null,8,Un),[[J,t.value]]),v(`span`,null,[R(n.$slots,`default`)])]))}}),Gn={class:`runtime-grid`},Kn={class:`card-head`},qn={class:`eyebrow`},Jn={class:`switches`},Yn={class:`save-bar`},Xn={class:`primary`,type:`submit`},Zn={class:`faint`},Qn={class:`card numbers`},$n=[`title`],er=F(z({__name:`Runtime`,setup(t){let n=f(!!B.health.settings.enabled),r=f(!!B.health.settings.demo),i=o(()=>(B.core.sessions||[]).filter(e=>e.enabled&&!e.archived).length),s=o(()=>{let e=B.health.backup;if(!e)return null;if(!e.enabled)return{value:a(`已关闭`),caption:a(`自动备份`),tone:`warn`,title:``};if(e.lastError)return{value:a(`失败`),caption:a(`自动备份出错,稍后重试`),tone:`danger`,title:e.lastError.message};if(!e.latest)return{value:a(`还没有`),caption:a(`自动备份,运行一阵后会做第一份`),tone:``,title:``};let t=Math.max(1,Math.round(e.latest.bytes/1048576));return{value:X(e.latest.at),caption:a(`上次自动备份 · {mb} MB · 已留 {count}/{keep} 份`,{mb:t,count:e.count,keep:e.keep}),tone:``,title:e.latest.name}});async function c(){try{await L({enabled:n.value,demo:r.value}),B.dirty=!1,B.health=await E(),W(a(`已保存并应用`))}catch(e){W(e.message,!0)}}return(t,o)=>(w(),u(`div`,Gn,[v(`form`,{id:`runtime`,class:`card`,onSubmit:g(c,[`prevent`]),onChange:o[2]||=e=>K(B).dirty=!0},[v(`div`,Kn,[v(`div`,null,[v(`span`,qn,e(K(a)(`运行开关`)),1),v(`h2`,null,e(K(a)(`TA 现在可以说话吗`)),1)])]),v(`div`,Jn,[H(Wn,{modelValue:n.value,"onUpdate:modelValue":o[0]||=e=>n.value=e,name:`enabled`},{default:q(()=>[v(`b`,null,e(K(a)(`允许参与聊天`)),1),v(`small`,null,e(K(a)(`总开关。关掉后 TA 不看也不回任何会话,心智照常保存。`)),1)]),_:1},8,[`modelValue`]),H(Wn,{modelValue:r.value,"onUpdate:modelValue":o[1]||=e=>r.value=e,name:`demo`},{default:q(()=>[v(`b`,null,e(K(a)(`仅模拟运行,不向 QQ 发送`)),1),v(`small`,null,e(K(a)(`模拟模式下,「对话」里可以发模拟消息走完整流程;它们写进模拟会话,不进入真实记忆。`)),1)]),_:1},8,[`modelValue`])]),v(`div`,Yn,[v(`button`,Xn,e(K(a)(`保存运行状态`)),1),v(`small`,Zn,e(K(B).dirty?K(a)(`有未保存的修改`):K(a)(`已保存,立刻生效`)),1)])],32),v(`section`,Qn,[v(`button`,{onClick:o[3]||=e=>K(A)(`chats`)},[v(`b`,null,e(i.value),1),v(`span`,null,e(K(a)(`参与中的会话`)),1)]),v(`button`,{onClick:o[4]||=e=>K(A)(`system`,`models`)},[v(`b`,null,e(K(B).core.models.length),1),v(`span`,null,e(K(a)(`可用模型`)),1)]),v(`button`,{onClick:o[5]||=e=>K(A)(`system`,`connect`)},[v(`b`,null,e(K(B).health.connection?.online?K(a)(`在线`):K(a)(`离线`)),1),v(`span`,null,e(K(a)(`QQ 连接`)),1)]),s.value?(w(),u(`button`,{key:0,class:m([`stat`,s.value.tone]),title:s.value.title,"data-testid":`backup-status`,type:`button`,onClick:o[6]||=e=>K(A)(`system`,`storage`)},[v(`b`,null,e(s.value.value),1),v(`span`,null,e(s.value.caption),1)],10,$n)):y(``,!0)])]))}}),[[`__scopeId`,`data-v-1f197523`]]),tr={class:`card search-profile`},nr={class:`eyebrow`},rr={class:`muted`},ir={key:0,class:`faint`},ar={class:`check`},or=[`disabled`],sr={class:`search-fields`},cr=[`disabled`],lr=[`disabled`,`placeholder`],ur=[`disabled`],dr=[`disabled`],fr=[`disabled`],pr={class:`faint`},mr={class:`search-usage`,role:`status`},hr={class:`chip`},gr={class:`faint`},_r={class:`faint`},vr={class:`row`},yr=[`disabled`],br=[`disabled`],xr={key:0,class:`faint`},Sr=[`role`],Cr=F(z({__name:`SearchProfile`,setup(t){let n=[`provider`,`enabled`,`baseUrl`,`timeoutMs`,`maxResults`,`dailyLimit`],r=te({provider:`tavily`,enabled:!0,baseUrl:``,apiKey:``,timeoutMs:2e4,maxResults:5,dailyLimit:12}),s=f(null),c=f(!1),l=f(!1),d=f(``),p=f(!1),h=new Map,_=`tavily`,x=o(()=>l.value&&(!!r.apiKey.trim()||n.some(e=>r[e]!==s.value?.[e]))),S=e=>e===`brave`?`Brave`:`Tavily`,E=o(()=>s.value?.dailyLimit===0?a(`不限`):s.value?.dailyLimit??12);b(x,e=>{B.dirty=e}),b(()=>[B.tick,B.pulse],()=>{l.value&&!c.value&&B.page===`system`&&B.sub===`search`&&D().catch(()=>{})});async function D(){s.value=await P(`/mind/time/search`)}async function O(){try{await D(),Object.assign(r,s.value,{apiKey:``}),_=r.provider,l.value=!0}catch(e){W(e.message,!0)}}async function k(){if(c.value)return;c.value=!0;let e=r.provider;h.set(_,{...r,provider:_});try{Object.assign(r,h.get(e)||{...await P(`/mind/time/search?provider=`+e),apiKey:``}),_=e,d.value=``}catch(e){r.provider=_,W(e.message,!0)}finally{c.value=!1}}function A(){return Object.fromEntries([...n,`apiKey`].map(e=>[e,r[e]]))}async function j(){if(!c.value){c.value=!0;try{let e=await P(`/mind/time/search`,`PATCH`,A());s.value=e,Object.assign(r,e,{apiKey:``}),h.set(r.provider,{...r}),_=r.provider,W(a(`搜索配置已保存并生效`))}catch(e){W(e.message,!0)}finally{c.value=!1}}}async function M(){if(!c.value){c.value=!0,d.value=``,p.value=!1;try{let e=await P(`/mind/time/search/test`,`POST`,A()),t={source:e.profile.mode===`web`?a(`{provider} 联网检索`,{provider:S(e.profile.provider)}):e.profile.materialLabel,count:e.results.length};d.value=x.value?a(`{source}测试通过,返回 {count} 条资料。测试不占用每日查询额度;当前填写的配置尚未保存。`,t):a(`{source}测试通过,返回 {count} 条资料。测试不占用每日查询额度。`,t)}catch(e){p.value=!0,d.value=a(`{error}。本次测试不占用每日查询额度。`,{error:e.message})}finally{try{await D()}catch{}c.value=!1}}}return N(O),U(()=>{B.dirty=!1}),(t,n)=>(w(),u(`section`,tr,[v(`span`,nr,e(K(a)(`SEARCH · 独立搜索`)),1),v(`h2`,null,e(K(a)(`接触世界的资料`)),1),v(`p`,rr,e(K(a)(`配置后优先联网检索。未配置密钥或关闭独立搜索时,使用当前模型整理已有知识。`)),1),l.value?(w(),u(`p`,ir,e(K(a)(`当前生效:{v}。表单修改保存后生效。`,{v:s.value.mode===`web`?K(a)(`{provider} · 联网检索资料`,{provider:S(s.value.provider)}):s.value.materialLabel})),1)):y(``,!0),l.value?(w(),u(`form`,{key:1,onSubmit:g(j,[`prevent`])},[v(`label`,ar,[C(v(`input`,{"onUpdate:modelValue":n[0]||=e=>r.enabled=e,type:`checkbox`,disabled:c.value},null,8,or),[[J,r.enabled]]),T(e(K(a)(`启用独立搜索`)),1)]),v(`div`,sr,[v(`label`,null,[T(e(K(a)(`提供方`)),1),H(Y,{modelValue:r.provider,"onUpdate:modelValue":n[1]||=e=>r.provider=e,"aria-label":K(a)(`搜索提供方`),disabled:c.value,options:[{value:`tavily`,label:`Tavily`},{value:`brave`,label:`Brave`}],onChange:k},null,8,[`modelValue`,`aria-label`,`disabled`])]),v(`label`,null,[T(e(K(a)(`搜索地址`)),1),C(v(`input`,{"onUpdate:modelValue":n[2]||=e=>r.baseUrl=e,type:`url`,required:``,name:`searchUrl`,disabled:c.value},null,8,cr),[[i,r.baseUrl]])]),v(`label`,null,[T(e(K(a)(`独立密钥`)),1),C(v(`input`,{"onUpdate:modelValue":n[3]||=e=>r.apiKey=e,type:`password`,autocomplete:`new-password`,name:`searchKey`,disabled:c.value,placeholder:r.hasApiKey?K(a)(`已保存,留空保留`):K(a)(`填写该提供方的搜索密钥`)},null,8,lr),[[i,r.apiKey]])]),v(`label`,null,[T(e(K(a)(`超时(毫秒)`)),1),C(v(`input`,{"onUpdate:modelValue":n[4]||=e=>r.timeoutMs=e,type:`number`,min:`1000`,max:`120000`,disabled:c.value},null,8,ur),[[i,r.timeoutMs,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`每次结果数`)),1),C(v(`input`,{"onUpdate:modelValue":n[5]||=e=>r.maxResults=e,type:`number`,min:`1`,max:`20`,disabled:c.value},null,8,dr),[[i,r.maxResults,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`每日查询上限`)),1),C(v(`input`,{"onUpdate:modelValue":n[6]||=e=>r.dailyLimit=e,name:`searchDailyLimit`,type:`number`,min:`0`,max:`100000`,disabled:c.value},null,8,fr),[[i,r.dailyLimit,void 0,{number:!0}]]),v(`small`,pr,e(K(a)(`可手动调整;0 表示不限。保存后立即生效。`)),1)])]),v(`div`,mr,[v(`span`,hr,e(K(a)(`今日有效查询 {v} / {limitLabel}`,{v:s.value.used||0,limitLabel:E.value})),1),v(`small`,gr,e(K(a)(`{v} 次进行中 · {v2} 次失败 · {v3} 次测试`,{v:s.value.usage?.running||0,v2:s.value.usage?.failed||0,v3:s.value.usage?.diagnostics||0})),1)]),v(`p`,_r,e(K(a)(`测试当前填写的配置,不会自动保存。失败与连接测试不占本地每日额度;提供方的账户额度由提供方管理。`)),1),v(`div`,vr,[v(`button`,{class:`primary`,disabled:c.value},e(K(a)(`保存搜索`)),9,yr),v(`button`,{type:`button`,disabled:c.value,onClick:M},e(c.value?K(a)(`处理中…`):K(a)(`测试连接`)),9,br),x.value?(w(),u(`span`,xr,e(K(a)(`有尚未保存的修改`)),1)):y(``,!0)]),d.value?(w(),u(`p`,{key:0,role:p.value?`alert`:`status`,class:m([`search-result`,{failed:p.value}])},e(d.value),11,Sr)):y(``,!0)],32)):y(``,!0)]))}}),[[`__scopeId`,`data-v-e874d8b6`]]),wr={key:0,class:`card data-transfer`,"aria-labelledby":`data-transfer-title`},Tr={class:`eyebrow`},Er={id:`data-transfer-title`},Dr={class:`transfer-note`},Or={class:`transfer-note`},kr={class:`transfer-actions`},Ar=[`disabled`],jr=[`disabled`],Mr=[`aria-label`],Nr={class:`transfer-note`},Pr={key:0,class:`transfer-progress`,role:`status`},Fr={key:1,class:`transfer-error`,role:`alert`},Ir={key:2,class:`transfer-note`},Lr={key:3,class:`transfer-preview`},Rr={class:`eyebrow`},zr={class:`transfer-note`},Br={class:`transfer-counts`},Vr={class:`transfer-actions`},Hr=[`disabled`],Ur=[`disabled`],Wr=F(z({__name:`DataTransfer`,setup(n){let i=f(null),s=f(null),l=f(),m=f(``),h=f(``),g=!0,_=null,b=o(()=>!!m.value),x=o(()=>m.value===`restarting`?a(`正在保留快照并重启加载,请等待…`):m.value===`uploading`?a(`正在上传数据文件…`):m.value===`exporting`?a(`正在生成完整数据包…`):a(`正在校验数据文件…`)),S=o(()=>{let e=s.value?.summary?.tables||{};return[[a(`聊天记录`),e.core_events||e.messages||0],[a(`记忆`),e.core_memories||e.memories||0],[a(`待办`),e.mind_time_tasks||0],[a(`作品`),e.mind_time_works||0],[a(`日记`),e.mind_diary||0]]}),C=()=>new Promise(e=>setTimeout(e,800));async function T(e,t=!1){for(let n=0;n<4500&&g;n++){try{let n=await P(`/storage/transfer/jobs/`+e);if(n.status===`error`)throw Error(n.error||a(`数据处理失败`));if(n.status===(t?`done`:`ready`))return n;if(n.status===`expired`)throw Error(a(`数据文件已过期,请重新选择`))}catch(e){if(!t||!(e instanceof TypeError)&&e.message!==a(`请求失败`))throw e}await C()}throw Error(a(`等待数据处理超时,请检查实例运行状态`))}async function E(){if(!b.value){m.value=`exporting`,h.value=``;try{let e=await P(`/storage/transfer/export`,`POST`,{});if(await T(e.id),!g)return;let t=document.createElement(`a`);t.href=`/api/storage/transfer/download/`+e.id,t.download=``,document.body.appendChild(t),t.click(),t.remove(),W(a(`数据包已生成,浏览器将开始下载`))}catch(e){g&&(h.value=e.message)}finally{g&&(m.value=``)}}}async function O(e){let t=e.target,n=t.files?.[0];if(t.value=``,n&&!b.value){if(h.value=``,s.value=null,n.size>(i.value?.maxBytes||0)){h.value=a(`数据文件超过导入大小限制`);return}m.value=`uploading`,_=new AbortController;try{await p();let e=await fetch(`/api/storage/transfer/upload`,{method:`POST`,credentials:`same-origin`,headers:{"Content-Type":`application/octet-stream`,"X-LuckyTri-Filename":encodeURIComponent(n.name),"X-LuckyTri-Locale":c.value},body:n,signal:_.signal});if(e.status===401)throw d(),Error(a(`请先登录管理台`));let t=await e.json().catch(()=>({}));if(!e.ok)throw Error(t.error||a(`数据上传失败`));m.value=`checking`;let r=await T(t.id);g&&(s.value=r)}catch(e){g&&(h.value=e.message)}finally{_=null,g&&(m.value=``)}}}async function A(){if(s.value&&!b.value)try{await P(`/storage/transfer/jobs/`+s.value.id,`DELETE`),s.value=null}catch(e){h.value=e.message}}async function j(){if(!s.value||b.value||!await t(a(`用这份数据替换当前数据,并保留导入前快照。实例将重启,导入后自动回复关闭。本机管理密码与 QQ 连接配置保持不变。`),{title:a(`确认导入数据`),confirmText:a(`导入并重启`),danger:!0}))return;m.value=`restarting`,h.value=``;let e=s.value.id;try{if(await P(`/storage/transfer/import`,`POST`,{id:e}),await T(e,!0),!g)return;k(),location.reload()}catch(e){g&&(h.value=e.message)}finally{g&&(m.value=``)}}return N(async()=>{try{i.value=await P(`/storage/transfer`)}catch(e){g&&(h.value=e.message)}}),V(()=>{g=!1,_?.abort()}),(t,n)=>i.value?.available?(w(),u(`section`,wr,[v(`span`,Tr,e(K(a)(`DATA · 导入与导出`)),1),v(`h2`,Er,e(K(a)(`带上记忆,继续生活。`)),1),v(`p`,Dr,e(K(a)(`导出数据库内的聊天、记忆、待办、作品、知识与设置。插件文件、知识库原始文件和本机 .env 不在数据包中。`)),1),v(`p`,Or,e(K(a)(`数据包包含私聊内容和模型设置中的密钥,请存放在你信任的位置。导入前会校验,确认后才替换当前数据。`)),1),v(`div`,kr,[v(`button`,{class:`primary`,type:`button`,disabled:b.value,onClick:E},e(K(a)(`导出数据包`)),9,Ar),v(`button`,{type:`button`,disabled:b.value,onClick:n[0]||=e=>l.value?.click()},e(K(a)(`选择导入文件`)),9,jr),v(`input`,{ref_key:`input`,ref:l,class:`transfer-file`,type:`file`,accept:`.luckytri,.db,.sqlite,.sqlite3`,"aria-label":K(a)(`导入数据文件`),onChange:O},null,40,Mr)]),v(`p`,Nr,e(K(a)(`支持 .luckytri 数据包和已有 SQLite 备份,单个文件最多 {size} GiB。`,{size:(i.value.maxBytes/1073741824).toFixed(0)})),1),b.value?(w(),u(`p`,Pr,e(x.value),1)):y(``,!0),h.value?(w(),u(`p`,Fr,e(h.value),1)):y(``,!0),i.value.lastImport?.status===`done`?(w(),u(`p`,Ir,e(K(a)(`上次数据导入已完成,自动回复在导入时关闭。请检查连接、模型和待办后再开启;插件需重新安装或确认权限。`)),1)):y(``,!0),s.value?(w(),u(`div`,Lr,[v(`span`,Rr,e(K(a)(`校验通过 · 尚未导入`)),1),v(`h3`,null,e(s.value.summary?.name),1),v(`p`,zr,e(s.value.name)+` · `+e(K(a)(`数据库版本 {from} → {to}`,{from:s.value.originalVersion,to:s.value.summary?.schemaVersion})),1),v(`div`,Br,[(w(!0),u(r,null,D(S.value,([t,n])=>(w(),u(`div`,{key:t},[v(`b`,null,e(n),1),v(`span`,null,e(t),1)]))),128))]),v(`div`,Vr,[v(`button`,{class:`primary`,type:`button`,disabled:b.value,onClick:j},e(K(a)(`导入并重启`)),9,Hr),v(`button`,{type:`button`,disabled:b.value,onClick:A},e(K(a)(`取消导入`)),9,Ur)])])):y(``,!0)])):y(``,!0)}}),[[`__scopeId`,`data-v-ea16c0c1`]]),Gr={class:`storage-page`},Kr={class:`card storage-overview`},qr={class:`eyebrow`},Jr={key:0,class:`storage-metrics`},Yr={key:0,class:`storage-error`,role:`alert`},Xr={key:1,class:`storage-grid`},Zr={class:`card-head`},Qr={class:`eyebrow`},$r={class:`storage-check`},ei={class:`storage-fields`},ti=[`aria-label`],ni=[`aria-label`],ri=[`aria-label`],ii={class:`storage-note`},ai={key:0,class:`storage-note`},oi={key:1,class:`storage-error`},si=[`disabled`],ci={class:`card storage-list`},li={class:`card-head`},ui={class:`eyebrow`},di={class:`storage-note`},fi={class:`storage-actions`},pi=[`disabled`],mi=[`disabled`],hi=[`disabled`],gi={class:`storage-scroll`},_i=[`checked`,`disabled`,`aria-label`,`onChange`],vi={class:`storage-item`},yi={key:0,class:`storage-error`,role:`alert`},bi={class:`storage-footer`},xi=[`disabled`],Si=F(z({__name:`BackupManager`,setup(n){let c=f(null),l=f({enabled:!0,time:`04:30`,retainDays:14,keepFull:2}),d=f([]),p=f(!1),h=f(``),_=f([]),b=!0,x=e=>`${e.scope}:${e.name}`,S=o(()=>c.value?.entries.filter(e=>d.value.includes(x(e)))||[]),E=o(()=>S.value.reduce((e,t)=>e+t.bytes,0)),O=e=>e===0?`0 B`:e>=1073741824?`${(e/1073741824).toFixed(2)} GiB`:`${Math.max(.01,e/1048576).toFixed(2)} MiB`,k=e=>new Date(e).toLocaleString(s()),A=e=>({auto:a(`自动备份`),full:a(`完整备份`),migration:a(`迁移快照`),legacy:a(`旧版本备份`),snapshot:a(`升级前快照`),import:a(`导入前快照`)})[e];async function j(e=!1){try{h.value=``;let t=await P(`/storage/cleanup`);if(!b)return;if(c.value=t,e)l.value={...c.value.policy},d.value=[],B.dirty=!1;else{let e=new Set(c.value.entries.filter(e=>!e.protected).map(x));d.value=d.value.filter(t=>e.has(t))}}catch(e){b&&(h.value=e.message)}}function M(){B.dirty=!0}function F(e){let t=x(e);d.value=d.value.includes(t)?d.value.filter(e=>e!==t):[...d.value,t]}function I(){d.value=(c.value?.plan.items||[]).map(x)}function L(){d.value=(c.value?.entries||[]).filter(e=>e.kind===`full`&&!e.protected).map(x)}async function R(){if(!p.value){p.value=!0;try{let e=await P(`/storage/cleanup`,`PATCH`,{enabled:l.value.enabled,time:l.value.time,retainDays:Number(l.value.retainDays),keepFull:Number(l.value.keepFull)});c.value=e,l.value={...e.policy},B.dirty=!1,W(a(`备份整理规则已保存`))}catch(e){W(e.message,!0)}finally{p.value=!1}}}async function z(){if(!S.value.length||p.value)return;let e=S.value.map(({scope:e,name:t,bytes:n,modified:r})=>({scope:e,name:t,bytes:n,modified:r}));if(await t(a(`将清理选中的 {count} 份备份,释放约 {size}。这些历史恢复点清理后无法从本机找回。`,{count:e.length,size:O(E.value)}),{title:a(`清理所选备份`),confirmText:a(`清理所选`),danger:!0})){p.value=!0;try{let t=await P(`/storage/cleanup/manual`,`POST`,{items:e});_.value=t.failures||[];let n=new Set((t.failures||[]).map(e=>`${e.scope}:${e.name}`));d.value=d.value.filter(e=>n.has(e)),await j(),W(a(`已清理 {count} 份备份,释放 {size}`,{count:t.removed.length,size:O(t.bytes)})+(_.value.length?a(`;部分未清理,详情见列表`):``),_.value.length>0)}catch(e){W(e.message,!0),await j()}finally{p.value=!1}}}return N(()=>j(!0)),V(()=>{b=!1}),(t,n)=>(w(),u(`div`,Gr,[v(`section`,Kr,[v(`span`,qr,e(K(a)(`DATA · 数据与备份`)),1),v(`h2`,null,e(K(a)(`留住重要的,整理重复的。`)),1),v(`p`,null,e(K(a)(`这里管理历史备份。聊天、记忆和作品仍在正在运行的数据库里,不会被列入清理。`)),1),c.value?(w(),u(`div`,Jr,[v(`div`,null,[v(`b`,null,e(O(c.value.totalBytes)),1),v(`span`,null,e(K(a)(`可管理的历史备份`)),1)]),v(`div`,null,[v(`b`,null,e(c.value.entries.length),1),v(`span`,null,e(K(a)(`份数据库副本`)),1)]),v(`div`,null,[v(`b`,null,e(O(c.value.plan.bytes)),1),v(`span`,null,e(K(a)(`按当前规则可定时整理`)),1)])])):y(``,!0)]),h.value?(w(),u(`p`,Yr,e(h.value),1)):y(``,!0),H(Wr),c.value?(w(),u(`div`,Xr,[v(`form`,{class:`card storage-policy`,onSubmit:g(R,[`prevent`])},[v(`div`,Zr,[v(`div`,null,[v(`span`,Qr,e(K(a)(`定时整理`)),1),v(`h2`,null,e(K(a)(`每天给备份留一点空间`)),1)])]),v(`label`,$r,[C(v(`input`,{"onUpdate:modelValue":n[0]||=e=>l.value.enabled=e,type:`checkbox`,onChange:M},null,544),[[J,l.value.enabled]]),T(e(K(a)(`启用定时整理`)),1)]),v(`div`,ei,[v(`label`,null,[T(e(K(a)(`每天执行时间`)),1),C(v(`input`,{"onUpdate:modelValue":n[1]||=e=>l.value.time=e,type:`text`,inputmode:`numeric`,maxlength:`5`,placeholder:`04:30`,"aria-label":K(a)(`每天执行时间`),onInput:M},null,40,ti),[[i,l.value.time]])]),v(`label`,null,[T(e(K(a)(`完整备份保留天数`)),1),C(v(`input`,{"onUpdate:modelValue":n[2]||=e=>l.value.retainDays=e,type:`number`,min:`1`,max:`3650`,"aria-label":K(a)(`完整备份保留天数`),onInput:M},null,40,ni),[[i,l.value.retainDays,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`完整备份最多保留份数`)),1),C(v(`input`,{"onUpdate:modelValue":n[3]||=e=>l.value.keepFull=e,type:`number`,min:`0`,max:`100`,"aria-label":K(a)(`完整备份最多保留份数`),onInput:M},null,40,ri),[[i,l.value.keepFull,void 0,{number:!0}]])])]),v(`p`,ii,e(K(a)(`时间按服务器本地时区 {zone}。完整备份超过保留天数或数量上限便会定时整理;数量填 0 表示不保留完整备份。手动清理可选择完整备份和迁移快照,执行前会校验同一实例的近期自动恢复点。`,{zone:c.value.serverTimeZone})),1),c.value.last?(w(),u(`p`,ai,e(c.value.last.error&&c.value.last.removed===0?K(a)(`上次整理未执行:{error}`,{error:c.value.last.error}):K(a)(`上次整理:{time} · {count} 份 · {size}`,{time:k(c.value.last.at),count:c.value.last.removed,size:O(c.value.last.bytes)})),1)):y(``,!0),c.value.last?.error&&c.value.last.removed>0?(w(),u(`p`,oi,e(c.value.last.error),1)):y(``,!0),v(`button`,{class:`primary`,type:`submit`,disabled:p.value},e(p.value?K(a)(`处理中…`):K(a)(`保存整理规则`)),9,si)],32),v(`section`,ci,[v(`div`,li,[v(`div`,null,[v(`span`,ui,e(K(a)(`手动整理`)),1),v(`h2`,null,e(K(a)(`挑选历史恢复点`)),1)])]),v(`p`,di,e(K(a)(`自动备份已有自己的轮换规则。迁移、旧版本和升级前快照只由你手动挑选;清理前会再次核对文件和恢复点。`)),1),v(`div`,fi,[v(`button`,{type:`button`,disabled:p.value||!c.value.plan.items.length,onClick:I},e(K(a)(`选中规则建议`)),9,pi),v(`button`,{type:`button`,disabled:p.value,onClick:L},e(K(a)(`选中完整备份`)),9,mi),v(`button`,{type:`button`,disabled:p.value||!d.value.length,onClick:n[4]||=e=>d.value=[]},e(K(a)(`取消选择`)),9,hi)]),v(`div`,gi,[(w(!0),u(r,null,D(c.value.entries,t=>(w(),u(`label`,{key:x(t),class:m([`storage-row`,{protected:t.protected}])},[v(`input`,{type:`checkbox`,checked:d.value.includes(x(t)),disabled:p.value||t.protected||c.value.running,"aria-label":t.name,onChange:e=>F(t)},null,40,_i),v(`span`,vi,[v(`strong`,null,e(t.name),1),v(`small`,null,e(A(t.kind))+` · `+e(k(t.at))+` · `+e(t.manifest?K(a)(`有校验清单`):K(a)(`旧备份无清单`))+e(t.protected?` · `+(t.protectionReason||K(a)(`保留恢复点`)):``),1)]),v(`b`,null,e(O(t.bytes)),1)],2))),128))]),_.value.length?(w(),u(`div`,yi,[v(`p`,null,e(K(a)(`部分备份未清理,请刷新列表后重试`)),1),(w(!0),u(r,null,D(_.value,t=>(w(),u(`p`,{key:t.name},e(t.name)+` · `+e(t.error),1))),128))])):y(``,!0),v(`div`,bi,[v(`span`,null,e(K(a)(`已选 {count} 份 · 约 {size}`,{count:S.value.length,size:O(E.value)})),1),v(`button`,{class:`primary`,type:`button`,disabled:p.value||c.value.running||!S.value.length,onClick:z},e(K(a)(`清理所选`)),9,xi)])])])):y(``,!0)]))}}),[[`__scopeId`,`data-v-4593780e`]]),Ci={class:`card password-settings`},wi={class:`row`},Ti=[`disabled`],Ei=F(z({__name:`PasswordSettings`,setup(t){let n=f(``),r=f(``),o=f(``),s=f(!1);async function c(){if(!s.value){if(r.value!==o.value){W(a(`两次输入的密码不一致`),!0);return}s.value=!0;try{await S(`password`,{currentPassword:n.value,password:r.value}),n.value=r.value=o.value=``,W(a(`管理密码已更新`))}catch(e){W(e.message,!0)}finally{s.value=!1}}}return(t,l)=>(w(),u(`section`,Ci,[v(`h2`,null,e(K(a)(`管理密码`)),1),v(`p`,null,e(K(a)(`一个密码管理这个小世界。修改后,其他浏览器需要重新登录。`)),1),v(`form`,{onSubmit:g(c,[`prevent`])},[v(`label`,null,[T(e(K(a)(`当前密码`)),1),C(v(`input`,{"onUpdate:modelValue":l[0]||=e=>n.value=e,name:`currentPassword`,type:`password`,autocomplete:`current-password`,required:``},null,512),[[i,n.value]])]),v(`label`,null,[T(e(K(a)(`新密码`)),1),C(v(`input`,{"onUpdate:modelValue":l[1]||=e=>r.value=e,name:`newPassword`,type:`password`,autocomplete:`new-password`,minlength:`8`,maxlength:`256`,required:``},null,512),[[i,r.value]])]),v(`label`,null,[T(e(K(a)(`确认密码`)),1),C(v(`input`,{"onUpdate:modelValue":l[2]||=e=>o.value=e,name:`confirmNewPassword`,type:`password`,autocomplete:`new-password`,minlength:`8`,maxlength:`256`,required:``},null,512),[[i,o.value]])]),v(`div`,wi,[v(`button`,{class:`primary`,disabled:s.value},e(K(a)(`修改密码`)),9,Ti),v(`button`,{type:`button`,onClick:l[3]||=(...e)=>K(G)&&K(G)(...e)},e(K(a)(`退出登录`)),1)])],32)]))}}),[[`__scopeId`,`data-v-36cd9f70`]]),Di={class:`card update-settings`,"aria-labelledby":`update-title`},Oi={id:`update-title`},ki=[`disabled`],Ai={class:`kv`},ji={key:0,class:`muted`,role:`alert`},Mi={class:`muted small-text`},Ni={key:1,class:`update-how stack tight`},Pi=[`disabled`],Fi={key:1,role:`status`},Ii={key:2,class:`error-text`,role:`alert`},Li={key:3,class:`muted`},Ri={class:`update-links`},zi=[`href`],Bi=[`href`],Vi=F(z({__name:`UpdateSettings`,setup(n){let i=f(null),o=f(!1),s=f(!1),c,d=!1,p=l({queued:M(`更新已开始`),downloading:M(`正在下载新版本…`),checking:M(`正在检查新程序…`),stopping:M(`正在保存当下并停止实例…`),backup:M(`正在保留更新前的校验备份…`),migrating:M(`正在整理并校验记忆与数据…`),restarting:M(`正在切换版本并重启…`),verifying:M(`正在确认新实例就绪…`),restoring:M(`正在恢复原版本和数据…`),done:M(`更新与重启已完成`),error:M(`更新未完成`)});function h(e){return e&&![`done`,`error`].includes(e.status)}async function g(){if(!d){try{let e=await P(`/system/update`);if(i.value=e,e.operation?.status===`done`){s.value=!1,location.reload();return}s.value=!!h(e.operation)}catch{}s.value&&!d&&(c=setTimeout(g,1800))}}U(()=>{d=!0,clearTimeout(c)});let _=l({unchecked:M(`尚未检查更新`),available:M(`有新版本可用`),current:M(`已是最新发布版本`),ahead:M(`当前版本领先于 npm 发布版本`),unavailable:M(`暂时无法检查更新`)});N(async()=>{try{i.value=await P(`/system/update`),s.value=!!h(i.value.operation),s.value&&(c=setTimeout(g,1800))}catch(e){W(e.message,!0)}});async function b(){if(!o.value){o.value=!0;try{i.value=await P(`/system/update/check`,`POST`,{})}catch(e){W(e.message,!0)}finally{o.value=!1}}}async function x(){if(!(s.value||o.value||i.value?.status!==`available`)&&await t(a(`更新到 {version} 并重启当前实例?先下载校验,再保留数据恢复点;启动失败时尝试恢复原版本。`,{version:i.value.latest}),{title:a(`更新并重启`),confirmText:a(`开始更新`)})){s.value=!0;try{i.value.operation=await P(`/system/update/install`,`POST`,{version:i.value.latest}),c=setTimeout(g,800)}catch(e){s.value=!1,W(e.message,!0)}}}return(t,n)=>(w(),u(`section`,Di,[v(`header`,null,[v(`div`,null,[n[0]||=v(`span`,{class:`eyebrow`},`LUCKYTRI / VERSION`,-1),v(`h2`,Oi,e(K(a)(`版本与更新`)),1)]),v(`button`,{disabled:o.value||s.value||!i.value,onClick:b},e(o.value?K(a)(`正在检查…`):K(a)(`检查更新`)),9,ki)]),i.value?(w(),u(r,{key:0},[v(`p`,{class:m([`version-state`,{available:i.value.status===`available`}]),role:`status`},e(K(_)[i.value.status]||K(_).unchecked),3),v(`dl`,Ai,[v(`dt`,null,e(K(a)(`当前版本`)),1),v(`dd`,null,e(i.value.current),1),v(`dt`,null,e(K(a)(`npm 最新版本`)),1),v(`dd`,null,e(i.value.latest||`—`),1),v(`dt`,null,e(K(a)(`上次成功检查`)),1),v(`dd`,null,e(i.value.checkedAt?K(ne)(i.value.checkedAt):`—`),1)]),i.value.error?(w(),u(`p`,ji,e(K(a)(`暂时无法连接 npm 或读取版本信息,请稍后重试。`)),1)):y(``,!0),v(`p`,Mi,e(K(a)(`点击时才检查,五分钟内复用结果。检查更新不会自动安装或重启。`)),1),i.value.status===`available`||i.value.operation?(w(),u(`div`,Ni,[v(`p`,null,e(K(a)(`下载期间继续运行,切换前保留数据恢复点。更新完成后此页面会自动重新连接。`)),1),i.value.status===`available`?(w(),u(`button`,{key:0,class:`primary`,disabled:s.value||o.value,onClick:x},e(s.value?K(a)(`正在更新…`):K(a)(`更新并重启`)),9,Pi)):y(``,!0),i.value.operation?(w(),u(`p`,Fi,e(K(p)[i.value.operation.status])+` · `+e(i.value.operation.version),1)):y(``,!0),i.value.operation?.error?(w(),u(`p`,Ii,e(i.value.operation.error),1)):y(``,!0),i.value.operation?.restored?(w(),u(`p`,Li,e(K(a)(`已恢复原版本和更新前的数据。`)),1)):y(``,!0)])):y(``,!0),v(`nav`,Ri,[v(`a`,{href:i.value.npmUrl,target:`_blank`,rel:`noopener noreferrer`},`npm`,8,zi),v(`a`,{href:i.value.releaseUrl,target:`_blank`,rel:`noopener noreferrer`},e(K(a)(`发布说明`))+` ↗`,9,Bi)])],64)):y(``,!0)]))}}),[[`__scopeId`,`data-v-c54db2fd`]]),Hi={class:`page system`},Ui={class:`system-intro`},Wi={class:`eyebrow`},Gi={class:`system-status`},Ki=F(z({__name:`SystemPage`,setup(n){let i=[`connect`,`models`,`search`,`runtime`,`storage`],o=f(i.includes(B.sub)?B.sub:`connect`);async function s(e){e!==o.value&&(!B.dirty||await t(a(`当前设置还没保存,离开这个分区吗?`),{title:a(`未保存的修改`),confirmText:a(`放弃修改`),cancelText:a(`继续编辑`)}))&&(B.dirty=!1,o.value=e)}return b(o,e=>I(e)),b(()=>B.sub,e=>{i.includes(e)&&(o.value=e)}),(t,n)=>(w(),u(`div`,Hi,[v(`header`,Ui,[v(`div`,null,[v(`span`,Wi,e(K(a)(`THE WORLD AROUND HER · 系统`)),1),v(`h1`,null,[T(e(K(a)(`让她与世界,`)),1),v(`em`,null,e(K(a)(`温柔相连。`)),1)]),v(`p`,null,e(K(a)(`连接、模型与运行方式都在这里。每一处改变,都可以看见结果。`)),1)]),v(`span`,Gi,[v(`i`,{class:m({off:!K(B).health.connection?.online})},null,2),T(` `+e(K(B).health.connection?.online?K(a)(`正在与 QQ 相连`):K(a)(`等待 QQ 连接`)),1)])]),H(ie,{"model-value":o.value,"onUpdate:modelValue":s,label:K(a)(`系统的分区`),items:[{key:`connect`,label:K(a)(`连接 QQ`)},{key:`models`,label:K(a)(`模型库`)},{key:`search`,label:K(a)(`独立搜索`)},{key:`runtime`,label:K(a)(`运行开关`)},{key:`storage`,label:K(a)(`数据与备份`)}]},null,8,[`model-value`,`label`,`items`]),o.value===`connect`?(w(),_(We,{key:0,onOpen:s})):o.value===`models`?(w(),_(Vn,{key:1})):o.value===`search`?(w(),_(Cr,{key:2})):o.value===`runtime`?(w(),u(r,{key:3},[H(er),H(Vi),H(Ei)],64)):(w(),_(Si,{key:4}))]))}}),[[`__scopeId`,`data-v-a12a372e`]]);export{Ki as default};
|
|
1
|
+
import{Dt as e,E as t,Et as n,G as r,H as i,I as a,J as o,M as s,N as c,P as l,Q as u,S as d,St as f,T as p,Tt as m,V as h,W as g,X as _,Y as v,Z as y,_t as b,a as x,b as S,bt as C,dt as w,et as T,f as E,ft as D,gt as O,h as k,i as A,it as j,j as M,lt as N,m as P,n as F,o as I,p as L,pt as R,rt as z,s as B,st as V,t as ee,tt as H,ut as U,v as W,w as G,wt as K,xt as te,yt as q,z as J}from"./Empty-BSmsWoGM.js";import{v as ne}from"./mind-CQkvddhx.js";import{c as Y,f as re,l as X,n as ie,o as ae}from"./index-BaXEYeFH.js";var oe={class:`connect`},Z={class:`card connection`},Q={class:`card-head`},se={class:`eyebrow`},ce={class:`pill`},le={key:0,class:`notice`,role:`note`},ue={class:`muted`},de={class:`connection-details`},fe={class:`detail`},pe={class:`instructions`},me={class:`muted`},$={class:`muted note`},he={key:0,class:`row`},ge=[`disabled`],_e={class:`muted`},ve=[`disabled`,`placeholder`],ye={key:0,class:`faint`},be=[`disabled`,`placeholder`],xe={key:0,class:`faint`},Se={class:`row`},Ce=[`disabled`],we={key:0,class:`faint`},Te={key:0,class:`connection-details`},Ee={class:`detail`},De={"data-state":``},Oe={key:0,class:`detail`},ke={class:`warn-text`},Ae={key:1,class:`detail`},je={class:`detail`},Me={class:`detail`},Ne={key:1,class:`notice`,role:`note`},Pe={class:`instructions`},Fe={class:`muted notes`},Ie={class:`card checklist`},Le={class:`card-head`},Re={class:`eyebrow`},ze={class:`chip`},Be={class:`checks`},Ve={class:`mark`,"aria-hidden":`true`},He={class:`muted`},Ue=[`data-fix`,`onClick`],We=F(z({__name:`ConnectQQ`,emits:[`open`],setup(n,{emit:s}){let c=s,d=o(()=>B.health.connection||{}),p=o(()=>d.value.channel===`qqbot`?`qqbot`:`onebot`),h=o(()=>!!d.value.locked),_=o(()=>!!d.value.online);o(()=>d.value.onebot||{});let S=o(()=>d.value.qqbot||{}),E=o(()=>String(B.health.settings.qqbotAppId||``)),O=o(()=>!!B.health.settings.hasQqbotSecret),k=f(p.value);b(p,e=>k.value=e);let j=o(()=>`${location.protocol===`https:`?`wss`:`ws`}://${location.host}/onebot/v11/ws`),N=o(()=>[{key:`onebot`,label:a(`OneBot 11`),count:p.value===`onebot`?a(`使用中`):``},{key:`qqbot`,label:a(`QQ 官方机器人`),count:p.value===`qqbot`?a(`使用中`):``}]),F=te({appId:E.value,secret:``}),I=f(!1),L=o(()=>F.appId.trim()!==E.value||!!F.secret.trim());b(L,e=>{B.dirty=e}),b(E,e=>{L.value||(F.appId=e)}),U(()=>{B.dirty=!1});let R=o(()=>!!F.appId.trim()&&(O.value||!!F.secret.trim())),z=l({idle:M(`未启用`),unconfigured:M(`尚未填写 AppID 与 AppSecret`),connecting:M(`正在连接开放平台`),ready:M(`已连接`),closed:M(`连接已断开,正在重连`),error:M(`连接出错`)}),V=l({all:M(`全部群消息`),mentions:M(`只有 @ 她的消息`),unknown:M(`尚未收到群消息`)}),ee=o(()=>z[S.value.state||`idle`]??z.idle),G=o(()=>V[S.value.groupMessages||`unknown`]??V.unknown),q=o(()=>p.value===`qqbot`&&S.value.groupMessages===`mentions`);async function J(e){if(I.value||h.value||e===p.value)return;let n=a(e===`qqbot`?`QQ 官方机器人`:`OneBot 11`);if(!_.value||await t(a(`切换后会断开当前连接。原来方式下的会话仍可查看,但不能再向它们发送消息。`),{title:a(`切换连接方式`),confirmText:a(`切换`),cancelText:a(`先不切换`)})){I.value=!0;try{await P(`/settings`,`PATCH`,{channel:e}),await x(),W(a(`已切换为 {name}`,{name:n}))}catch(e){W(e.message,!0)}finally{I.value=!1}}}async function ne(){if(!I.value){if(!R.value){W(a(`请填写 AppID 和 AppSecret`),!0);return}I.value=!0;try{let e={qqbotAppId:F.appId.trim()};F.secret.trim()&&(e.qqbotSecret=F.secret.trim()),p.value!==`qqbot`&&!h.value&&(e.channel=`qqbot`),await P(`/settings`,`PATCH`,e),F.secret=``,await x(),W(a(`已保存`))}catch(e){W(e.message,!0)}finally{I.value=!1}}}let Y={token:[``,`connect`],credentials:[``,`connect`],qq:[``,`connect`],model:[``,`models`],mode:[``,`runtime`],session:[`chats`,``],persona:[`nature`,``]};function re(e){let[t,n]=Y[e]||[``,`connect`];t?A(t):c(`open`,n)}return(t,n)=>(w(),u(`div`,oe,[v(`section`,Z,[v(`div`,Q,[v(`div`,null,[v(`span`,se,e(K(a)(`QQ`)),1),v(`h2`,null,e(K(a)(`连接 QQ`)),1),v(`p`,null,e(K(a)(`两种连接方式二选一,同一时间只使用一种。她的记忆、心情和行为完全一致,区别只在消息怎么到达。`)),1)]),v(`span`,ce,[v(`span`,{class:m([`dot`,{off:!_.value}])},null,2),T(` `+e(_.value?K(a)(`QQ 已连接`):K(a)(`等待连接`)),1)])]),H(ie,{modelValue:k.value,"onUpdate:modelValue":n[0]||=e=>k.value=e,label:K(a)(`连接方式`),items:N.value},null,8,[`modelValue`,`label`,`items`]),h.value?(w(),u(`p`,le,e(K(a)(`连接方式由环境变量 LUCKYTRI_CHANNEL 指定,在这里不能更改。去掉该变量后即可在此选择。`)),1)):y(``,!0),k.value===`onebot`?(w(),u(r,{key:1},[v(`p`,ue,e(K(a)(`自备接入端,通过反向 WebSocket 连接。能看到全部群消息。`)),1),v(`div`,de,[v(`div`,fe,[v(`span`,null,e(K(a)(`反向 WebSocket 地址`)),1),v(`code`,null,e(j.value),1)])]),v(`ol`,pe,[v(`li`,null,e(K(a)(`同一台电脑上的接入端无需单独配置连接令牌。`)),1),v(`li`,null,e(K(a)(`在接入端启用反向 WebSocket 客户端,填写上方地址,消息格式选择数组。已有的地址配置可以继续使用。`)),1),v(`li`,null,e(K(a)(`在接入端完成 QQ 登录。连接成功后,本页状态会更新;新会话仍需在「对话」中开启参与。`)),1)]),v(`p`,me,e(K(a)(`远程接入时,连接密码使用管理密码;已有的远程连接令牌仍兼容。`)),1),v(`p`,$,e(K(a)(`LuckyTri 只负责接收,不提供、不安装也不管理接入端。`)),1),p.value===`onebot`?y(``,!0):(w(),u(`div`,he,[v(`button`,{class:`primary`,"data-use":`onebot`,disabled:I.value||h.value,onClick:n[1]||=e=>J(`onebot`)},e(K(a)(`改用这种方式`)),9,ge)]))],64)):(w(),u(r,{key:2},[v(`p`,_e,e(K(a)(`只需 AppID 与 AppSecret,无需额外软件。群里默认只收到 @ 她的消息。`)),1),v(`form`,{class:`stack tight`,onSubmit:g(ne,[`prevent`])},[v(`label`,null,[T(e(K(a)(`AppID`))+` `,1),C(v(`input`,{"onUpdate:modelValue":n[2]||=e=>F.appId=e,name:`qqbotAppId`,autocomplete:`off`,inputmode:`numeric`,maxlength:`40`,disabled:I.value||S.value.appIdFromEnv,placeholder:K(a)(`机器人的 AppID`)},null,8,ve),[[i,F.appId]]),S.value.appIdFromEnv?(w(),u(`small`,ye,e(K(a)(`由环境变量指定,在这里不能修改`)),1)):y(``,!0)]),v(`label`,null,[T(e(K(a)(`AppSecret`))+` `,1),C(v(`input`,{"onUpdate:modelValue":n[3]||=e=>F.secret=e,name:`qqbotSecret`,type:`password`,autocomplete:`new-password`,maxlength:`200`,disabled:I.value||S.value.secretFromEnv,placeholder:O.value||S.value.secretFromEnv?K(a)(`已保存,留空保留`):K(a)(`机器人的 AppSecret`)},null,8,be),[[i,F.secret]]),S.value.secretFromEnv?(w(),u(`small`,xe,e(K(a)(`由环境变量指定,在这里不能修改`)),1)):y(``,!0)]),v(`div`,Se,[v(`button`,{class:`primary`,"data-save":`qqbot`,disabled:I.value||S.value.appIdFromEnv&&S.value.secretFromEnv},e(p.value===`qqbot`||h.value?K(a)(`保存`):K(a)(`保存并使用`)),9,Ce),L.value?(w(),u(`span`,we,e(K(a)(`有尚未保存的修改`)),1)):y(``,!0)])],32),p.value===`qqbot`?(w(),u(`div`,Te,[v(`div`,Ee,[v(`span`,null,e(K(a)(`连接状态`)),1),v(`strong`,De,e(ee.value),1)]),S.value.error?(w(),u(`div`,Oe,[n[4]||=v(`span`,null,null,-1),v(`small`,ke,e(S.value.error),1)])):y(``,!0),S.value.botName?(w(),u(`div`,Ae,[v(`span`,null,e(K(a)(`机器人`)),1),v(`strong`,null,e(S.value.botName),1)])):y(``,!0),v(`div`,je,[v(`span`,null,e(K(a)(`最近收到消息`)),1),v(`strong`,null,e(S.value.lastEventAt?K(X)(S.value.lastEventAt):K(a)(`还没有`)),1)]),v(`div`,Me,[v(`span`,null,e(K(a)(`群消息范围`)),1),v(`strong`,null,e(G.value),1)])])):y(``,!0),q.value?(w(),u(`p`,Ne,e(K(a)(`目前只收到 @ 她的群消息。想让她看到群里的全部消息,请在开放平台的机器人设置里开启「接收所有消息」。`)),1)):y(``,!0),v(`ol`,Pe,[v(`li`,null,e(K(a)(`在 QQ 开放平台创建机器人,取得 AppID 与 AppSecret。`)),1),v(`li`,null,e(K(a)(`把运行 LuckyTri 的这台机器的出口 IP 加入机器人的 IP 白名单。`)),1),v(`li`,null,e(K(a)(`可选:开启「接收所有消息」,她才能看到群里没有 @ 她的话;不开启时只会收到 @ 她的消息。`)),1),v(`li`,null,e(K(a)(`填写上方的 AppID 与 AppSecret 并保存。状态变为「已连接」后,在群里 @ 她或私聊她,新会话会出现在「对话」中。`)),1)]),v(`ul`,Fe,[v(`li`,null,e(K(a)(`官方平台不提供群名称:新会话以占位名出现,可以在「对话」中为它改名。`)),1),v(`li`,null,e(K(a)(`官方平台上,同一个人在不同的群里标识不同。像只在不同的房间见过对方一样,平台给出统一身份之前,她不会把两处的人当成同一个人。`)),1),v(`li`,null,e(K(a)(`对方关闭了机器人的主动消息时,她不会去打扰,会等对方来找她。`)),1)])],64))]),v(`section`,Ie,[v(`div`,Le,[v(`div`,null,[v(`span`,Re,e(K(a)(`就绪检查`)),1),v(`h2`,null,e(K(a)(`还差哪一步`)),1)]),v(`span`,ze,e(K(B).health.readiness?.completed??0)+` / `+e(K(B).health.readiness?.total??0),1)]),v(`ol`,Be,[(w(!0),u(r,null,D(K(B).health.readiness?.checks||[],t=>(w(),u(`li`,{key:t.id,class:m({done:t.done})},[v(`span`,Ve,e(t.done?`✓`:``),1),v(`div`,null,[v(`b`,null,e(t.name),1),v(`small`,He,e(t.detail),1)]),v(`button`,{class:`small`,"data-fix":t.id,onClick:e=>re(t.id)},e(t.done?K(a)(`查看`):K(a)(`去处理`)),9,Ue)],2))),128))])])]))}}),[[`__scopeId`,`data-v-6f4553ed`]]);async function Ge(e){return P(`/core/models`,`PUT`,{models:e})}async function Ke(e){return P(`/core/models/`+encodeURIComponent(e),`DELETE`,{})}async function qe(e){return P(`/model/test`,`POST`,{modelId:e})}var Je={class:`card embedding-profile`,"aria-labelledby":`embedding-title`},Ye={id:`embedding-title`},Xe={class:`muted`},Ze={key:0,class:`faint`},Qe={class:`check`},$e={class:`fields`},et=[`required`],tt=[`placeholder`],nt=[`placeholder`],rt={class:`fields`},it={value:`openai`},at={value:`multimodal`},ot={class:`save-bar`},st=[`disabled`],ct=[`disabled`],lt={class:`faint`},ut={key:2,role:`status`},dt=F(z({__name:`EmbeddingProfile`,setup(t){let n=te({enabled:!1,label:a(`知识向量`),baseUrl:``,model:``,apiKey:``,dimensions:0,batchSize:10,timeoutMs:9e4,protocol:`openai`}),r=f(!1),o=f(!1),s=f(!1),c=f(``);async function l(){try{Object.assign(n,await P(`/core/knowledge/embedding`),{apiKey:``}),s.value=!0}catch(e){c.value=e.message}}async function d(){r.value=!0;try{Object.assign(n,await P(`/core/knowledge/embedding`,`PATCH`,n),{apiKey:``}),o.value=!1,W(a(`知识向量模型已保存`))}catch(e){W(e.message,!0)}finally{r.value=!1}}async function p(){r.value=!0;try{let e=await P(`/core/knowledge/embedding/test`,`POST`,{});c.value=a(`连接成功,向量维度 {dimensions}`,{dimensions:e.dimensions})}catch(e){c.value=e.message}finally{r.value=!1}}return N(l),(t,l)=>(w(),u(`section`,Je,[v(`h2`,Ye,e(K(a)(`知识向量模型`)),1),v(`p`,Xe,e(K(a)(`填写任意 OpenAI 兼容向量服务(/embeddings)的请求地址、模型名和密钥。火山方舟地址可以不填模型名,会用 doubao-embedding-vision。维度填 0 表示用模型自己的长度(doubao-embedding-vision 是 2048),写明长度就按写的请求。不启用或连不上时,对话和关键词回忆照常进行。`)),1),s.value&&!n.configured?(w(),u(`p`,Ze,e(K(a)(`当前兼容旧配置,跟随默认模型。保存后改用独立配置。`)),1)):y(``,!0),s.value?(w(),u(`form`,{key:1,autocomplete:`off`,onSubmit:g(d,[`prevent`]),onInput:l[7]||=e=>o.value=!0,onChange:l[8]||=e=>o.value=!0},[v(`label`,Qe,[C(v(`input`,{"onUpdate:modelValue":l[0]||=e=>n.enabled=e,type:`checkbox`,name:`embeddingEnabled`},null,512),[[J,n.enabled]]),T(e(K(a)(`启用知识向量`)),1)]),v(`div`,$e,[v(`label`,null,[T(e(K(a)(`请求地址`)),1),C(v(`input`,{"onUpdate:modelValue":l[1]||=e=>n.baseUrl=e,name:`embeddingBaseUrl`,type:`url`,inputmode:`url`,autocomplete:`off`,spellcheck:`false`,placeholder:`https://example.com/v1`,required:n.enabled},null,8,et),[[i,n.baseUrl]])]),v(`label`,null,[T(e(K(a)(`模型名称`)),1),C(v(`input`,{"onUpdate:modelValue":l[2]||=e=>n.model=e,name:`embeddingModelName`,autocomplete:`off`,spellcheck:`false`,placeholder:K(a)(`火山方舟可留空`)},null,8,tt),[[i,n.model]])]),v(`label`,null,[T(e(K(a)(`向量服务密钥`)),1),C(v(`input`,{"onUpdate:modelValue":l[3]||=e=>n.apiKey=e,name:`embeddingApiKey`,type:`text`,class:`secret`,autocomplete:`off`,spellcheck:`false`,"data-1p-ignore":``,"data-lpignore":`true`,placeholder:n.hasApiKey?K(a)(`已保存,留空保留`):K(a)(`填写向量服务密钥`)},null,8,nt),[[i,n.apiKey]])])]),v(`details`,null,[v(`summary`,null,e(K(a)(`自动选择的细节`)),1),v(`div`,rt,[v(`label`,null,[T(e(K(a)(`向量维度(0 表示自动)`)),1),C(v(`input`,{"onUpdate:modelValue":l[4]||=e=>n.dimensions=e,name:`embeddingDimensions`,type:`number`,min:`0`,max:`65536`},null,512),[[i,n.dimensions,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`每批段落数`)),1),C(v(`input`,{"onUpdate:modelValue":l[5]||=e=>n.batchSize=e,name:`embeddingBatchSize`,type:`number`,min:`1`,max:`128`},null,512),[[i,n.batchSize,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`请求格式`)),1),C(v(`select`,{"onUpdate:modelValue":l[6]||=e=>n.protocol=e,name:`embeddingProtocol`},[v(`option`,it,e(K(a)(`OpenAI 兼容(可批量)`)),1),v(`option`,at,e(K(a)(`方舟多模态接口(逐条)`)),1)],512),[[h,n.protocol]])])])]),v(`div`,ot,[v(`button`,{class:`primary`,disabled:r.value},e(K(a)(`保存向量模型`)),9,st),v(`button`,{type:`button`,disabled:r.value||o.value||!n.enabled||!n.configured,onClick:p},e(K(a)(`测试向量连接`)),9,ct),v(`small`,lt,e(o.value?K(a)(`有未保存的修改`):K(a)(`配置已载入`)),1)])],32)):y(``,!0),c.value?(w(),u(`p`,ut,e(c.value),1)):y(``,!0)]))}}),[[`__scopeId`,`data-v-944d9f50`]]),ft={class:`card recall-panel`,"aria-labelledby":`recall-title`},pt={id:`recall-title`},mt={class:`muted`},ht={key:0,class:`stats`},gt={key:0,class:`pill strong`},_t={key:1,class:`pill`},vt={key:2,class:`pill warn`},yt={key:1,class:`waiting`},bt={key:2,class:`waiting`},xt={value:``,disabled:``},St=[`value`],Ct=[`placeholder`],wt=[`disabled`],Tt={key:3,role:`status`},Et={key:4,class:`result`},Dt={class:`faint`},Ot={class:`faint`},kt={key:0,class:`faint`},At=F(z({__name:`RecallPanel`,setup(t){let n=f(null),s=f(``),c=o(()=>B.core?.sessions||[]),l=f(``),d=f(``),p=f(null),m=f(!1),_={fact:a(`事实`),episode:a(`情景`),meeting:a(`相遇`),self:a(`自我线索`),thought:a(`念头`),diary:a(`日记`),period:a(`回顾`),anticipation:a(`约定`),message:a(`原话`)},b={meaning:a(`意思相关`),words:a(`说到了`),person:a(`关于这个人`)},x=o(()=>{let e=n.value?.coverage;return e?.total?`${e.embedded||0} / ${e.total}`:``});async function S(){try{n.value=await P(`/mind/recall`),s.value=``}catch(e){s.value=e.message}}async function E(){if(l.value&&d.value.trim()){m.value=!0;try{p.value=await P(`/mind/recall/probe`,`POST`,{session:l.value,text:d.value}),s.value=``}catch(e){s.value=e.message}finally{m.value=!1}}}return N(S),(t,o)=>(w(),u(`section`,ft,[v(`h2`,pt,e(K(a)(`回忆索引`)),1),v(`p`,mt,e(K(a)(`她的事实、情景、自我线索和近一个月的原话都在同一个索引里,按意思、字词和相关的人一起检索。向量还没覆盖的部分先按字词找。`)),1),n.value?(w(),u(`div`,ht,[(w(!0),u(r,null,D(n.value.items,t=>(w(),u(`span`,{key:t.kind,class:`pill`},e(_[t.kind]||t.kind)+` `+e(t.n),1))),128)),x.value?(w(),u(`span`,gt,e(K(a)(`已有向量`))+` `+e(x.value),1)):y(``,!0),n.value.embedding?.latencyMs?(w(),u(`span`,_t,e(K(a)(`向量延迟`))+` `+e(n.value.embedding.latencyMs.p50)+` ms`,1)):y(``,!0),n.value.embedding?.lastError?(w(),u(`span`,vt,e(n.value.embedding.lastError),1)):y(``,!0)])):y(``,!0),n.value?.waiting?.length?(w(),u(`ul`,yt,[(w(!0),u(r,null,D(n.value.waiting,t=>(w(),u(`li`,{key:t.key},e(K(a)(`等待重试`))+` `+e(t.key)+` × `+e(t.failures)+`:`+e(t.lastError),1))),128))])):y(``,!0),n.value?.unavailableModels?.length?(w(),u(`ul`,bt,[(w(!0),u(r,null,D(n.value.unavailableModels,t=>(w(),u(`li`,{key:t.key},e(K(a)(`暂时停用的备用模型`))+` `+e(t.label)+`:`+e(t.reason),1))),128))])):y(``,!0),v(`form`,{class:`probe`,onSubmit:g(E,[`prevent`])},[C(v(`select`,{"onUpdate:modelValue":o[0]||=e=>l.value=e,name:`recallSession`,required:``},[v(`option`,xt,e(K(a)(`选择会话`)),1),(w(!0),u(r,null,D(c.value,t=>(w(),u(`option`,{key:t.id,value:t.id},e(t.name||t.id),9,St))),128))],512),[[h,l.value]]),C(v(`input`,{"onUpdate:modelValue":o[1]||=e=>d.value=e,name:`recallText`,maxlength:`500`,placeholder:K(a)(`输入一句话,看她会想起什么`)},null,8,Ct),[[i,d.value]]),v(`button`,{disabled:m.value||!l.value||!d.value.trim()},e(K(a)(`试试回忆`)),9,wt)],32),s.value?(w(),u(`p`,Tt,e(s.value),1)):y(``,!0),p.value?(w(),u(`div`,Et,[v(`p`,Dt,e(p.value.mode===`hybrid`?K(a)(`意思与字词一起`):K(a)(`仅字词`))+` · `+e(K(a)(`候选`))+` `+e(p.value.candidates),1),v(`ol`,null,[(w(!0),u(r,null,D(p.value.items,t=>(w(),u(`li`,{key:t.id},[v(`strong`,null,e(_[t.kind]||t.kind),1),T(` `+e(t.text)+` `,1),v(`small`,Ot,[T(e(b[t.why])+` `,1),t.standsOut===null?y(``,!0):(w(),u(r,{key:0},[T(` · `+e(K(a)(`突出度`))+` `+e(t.standsOut),1)],64)),T(` · `+e(K(a)(`共有字词`))+` `+e(t.sharedWords),1)])]))),128))]),p.value.items.length?y(``,!0):(w(),u(`p`,kt,e(K(a)(`没有想起什么`)),1))])):y(``,!0)]))}}),[[`__scopeId`,`data-v-cdde3f37`]]),jt={class:`library`},Mt={class:`model-workspace`},Nt={class:`card shelf`},Pt={class:`shelf-head`},Ft={class:`faint`},It={class:`rows`},Lt={key:0,class:`muted`},Rt=[`open`,`data-saved-vendor`,`onToggle`],zt={class:`vendor-models`},Bt=[`onClick`],Vt={class:`who`},Ht={key:0,class:`card detail`},Ut={class:`card-head`},Wt={class:`eyebrow`},Gt=[`data-tone`],Kt={class:`form-grid`},qt={key:0},Jt=[`placeholder`],Yt={class:`wide`},Xt=[`placeholder`],Zt={class:`faint`},Qt={class:`form-grid`},$t={key:0},en={key:1},tn={class:`advanced`},nn={class:`form-grid`},rn=[`placeholder`],an={class:`faint`},on={class:`caps`},sn=[`onUpdate:modelValue`,`name`],cn={key:0,id:`modelTestResult`,class:`notice`,role:`status`},ln={class:`actions`},un=[`disabled`],dn={class:`faint`},fn={key:0,class:`check`},pn=[`checked`],mn=[`disabled`],hn={key:1,class:`card detail`},gn={class:`card usage-panel`,"aria-labelledby":`token-usage-title`},_n={class:`usage-intro`},vn={class:`eyebrow`},yn={id:`token-usage-title`},bn={class:`usage-total`},xn={class:`usage-detail`},Sn={class:`usage-stat`},Cn={class:`usage-stat`},wn={class:`usage-stat cache-stat`},Tn={class:`usage-stat`},En={class:`usage-foot`},Dn={key:0},On={key:1,class:`usage-error`},kn={key:2},An=[`disabled`],jn={class:`model-picker`},Mn={class:`muted`},Nn={class:`catalog-search`},Pn=[`placeholder`],Fn=[`data-vendor`],In={class:`vendor-summary`},Ln={class:`vendor-name`},Rn={class:`presets`},zn=[`data-preset`,`onClick`],Bn={key:0,class:`muted search-empty`},Vn=F(z({__name:`ModelLibrary`,setup(c){let l=o(()=>B.health?.modelCatalog||[]),d=o(()=>B.health?.effortLabels||{none:a(`关闭`),minimal:a(`极低`),low:a(`低`),medium:a(`中`),high:a(`高`),xhigh:a(`极高`),max:a(`最深`)}),p=f(B.core.models.map(e=>({...e}))),h=f(p.value.length?0:-1),_=f(p.value.length?Q(p.value[0]):``),S=f(!1),E=f(!1),O=f(!1),k=f(``),A=f(``),j=f(null),M=f(!1),F=f(``),I=te(Z());p.value[0]&&Object.assign(I,p.value[0],{apiKey:``});let L=o(()=>h.value>=0&&!!I.id),R=o(()=>{let e=[];for(let t of l.value){if(t.id===`custom`)continue;let n=e.find(e=>e.vendor===t.vendor);n||(n={vendor:t.vendor,models:[]},e.push(n)),n.models.push(t)}return e}),z=o(()=>{let e=k.value.trim().toLocaleLowerCase();return e?R.value.map(t=>({...t,models:t.models.filter(n=>[t.vendor,n.label,n.model,n.summary].filter(Boolean).join(` `).toLocaleLowerCase().includes(e))})).filter(e=>e.models.length):R.value}),V=o(()=>{let e=[];return p.value.forEach((t,n)=>{let r=Q(t),i=e.find(e=>e.vendor===r);i||(i={vendor:r,models:[]},e.push(i)),i.models.push({model:t,index:n})}),e}),U=o(()=>l.value.find(e=>e.id===`custom`)),G=o(()=>l.value.filter(e=>e.vendor&&e.vendor===I.vendor)),ne=o(()=>l.value.find(e=>e.id===I.presetId)||l.value.find(e=>e.model&&e.model===I.model&&e.baseUrl===I.baseUrl)),X=o(()=>{let e=ne.value?.contextWindows||[];if(e.length<2)return[];let t=Number(I.contextWindow);return e.some(e=>e.contextWindow===t)?e:[...e,{label:a(`已保存 {value}`,{value:fe(t)}),contextWindow:t,maxInputTokens:Number(I.maxInputTokens),maxOutputTokens:Number(I.maxOutputTokens)}]}),ie=o(()=>{let e=Array.isArray(I.reasoningEfforts)&&I.reasoningEfforts.length?[...I.reasoningEfforts]:[`none`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`];return I.reasoningEffort&&!e.includes(I.reasoningEffort)&&e.unshift(I.reasoningEffort),e}),oe=o(()=>B.core.models.some(e=>e.id===I.id));function Z(){return{id:``,presetId:``,label:``,provider:``,vendor:``,baseUrl:``,model:``,apiKey:``,hasApiKey:!1,contextWindow:128e3,maxInputTokens:119808,maxOutputTokens:8192,vision:!1,system:!0,json:!0,tools:!1,embedding:!1,embeddingModel:``,reasoningEffort:`none`,reasoningEfforts:[`none`,`low`,`medium`,`high`],thinkingStyle:`openai`,tokenField:`max_tokens`,omitSampling:!1,temperature:.85,topP:1,timeoutMs:9e4,isDefault:!1,enabled:!0}}function Q(e){let t={"volcengine-coding-plan":a(`火山方舟 Coding Plan`),"opencode-go":`OpenCode Go`,"opencode-zen":`OpenCode Zen`,deepseek:`DeepSeek`,openai:`OpenAI`,bedrock:a(`亚马逊 Bedrock`),qwen:a(`通义千问`),moonshot:`Kimi`,kimi:`Kimi`,zhipu:a(`智谱 GLM`),glm:a(`智谱 GLM`),mimo:a(`小米 MiMo`),siliconflow:`SiliconFlow`,openrouter:`OpenRouter`};return String(e?.vendor||``).trim()||t[String(e?.provider||``).toLowerCase()]||String(e?.provider||a(`自定义供应商`))}function se(e,t){let n=t.currentTarget;_.value=n.open?e:``}function ce(e){let{summary:t,contextWindows:n,...r}=e;return{...r,presetId:e.id}}function le(e){let{contextWindows:t,...n}=e;return n}function ue(e){let t=Number(e.contextWindow),n=Number(e.maxOutputTokens),r=Number(e.maxInputTokens);return(!Number.isFinite(t)||t<2)&&(t=2),(!Number.isFinite(n)||n<1)&&(n=1),n>=t&&(n=t-1),(!Number.isFinite(r)||r<1)&&(r=t-n),r+n>t&&(r=t-n),{contextWindow:t,maxInputTokens:r,maxOutputTokens:n}}function de(e){let t=Number(e.target.value),n=X.value.find(e=>e.contextWindow===t);n&&(I.contextWindow=n.contextWindow,I.maxInputTokens=n.maxInputTokens,I.maxOutputTokens=n.maxOutputTokens,B.dirty=!0)}function fe(e){let t=Number(e)||0;return t>=1e6?(t%1048576==0?t/1048576:Number((t/1e6).toFixed(2)))+`M`:t>=1e3?(t%1e3==0?t/1e3:t%1024==0?t/1024:Math.round(t/1e3))+`K`:String(t)}function pe(e){if(e.id===`openrouter`)return a(`按所选模型填写上下文和输出参数`);if(!e.model)return a(`填写模型 ID 和对应参数`);let t=e.contextWindows||[],n=t.length?t.map(e=>e.label).join(` / `):fe(e.contextWindow);return a(`上下文 {context} · 输出 {v}`,{context:n,v:fe(e.maxOutputTokens)})}function me(e){return[`mimo`,`qwen`,`kimi-toggle`].includes(I.thinkingStyle)?a(e===`none`?`关闭`:`开启`):`${d.value[e]||e} / ${e}`}function $(e){return new Intl.NumberFormat(s()).format(Number(e)||0)}async function he(){if(!M.value){M.value=!0;try{j.value=await P(`/core/usage`),F.value=``}catch(e){F.value=e.message}finally{M.value=!1}}}N(()=>void he()),b(()=>B.tick,()=>void he());async function ge(){return B.dirty?await t(a(`放弃当前模型草稿?`),{title:a(`草稿还没保存`),confirmText:a(`放弃`),cancelText:a(`留下`)})?(B.dirty=!1,!0):!1:!0}async function _e(e){let t=p.value[e];t&&t.id!==I.id&&await ge()&&(p.value=p.value.filter(e=>e.id===t.id||B.core.models.some(t=>t.id===e.id)),h.value=p.value.findIndex(e=>e.id===t.id),_.value=Q(t),Object.assign(I,Z(),t,{apiKey:``}),A.value=``)}async function ve(){if(!await ge())return;p.value=B.core.models.map(e=>({...e})),p.value.length?p.value.some(e=>e.id===I.id)||(h.value=0,Object.assign(I,Z(),p.value[0],{apiKey:``})):(h.value=-1,Object.assign(I,Z()));let e=p.value[h.value]||p.value[0];_.value=e?Q(e):``,k.value=``,O.value=!0}function ye(e){p.value=B.core.models.map(e=>({...e}));let t={...Z(),...ce(e),id:`model-`+Date.now(),apiKey:``,hasApiKey:!1,isDefault:p.value.length===0};p.value.push(t),h.value=p.value.length-1,_.value=Q(t),Object.assign(I,t),A.value=``,O.value=!1,B.dirty=!0}function be(e){let t=e.target.value,n=l.value.find(e=>e.id===t);if(!n)return;Object.assign(I,Z(),ce(n),{id:I.id,apiKey:I.apiKey,hasApiKey:I.hasApiKey,isDefault:I.isDefault});let r=p.value[h.value];r&&(r.label=I.label),B.dirty=!0}function xe(){for(let e of p.value)e.isDefault=e.id===I.id;I.isDefault=!0,B.dirty=!0}async function Se(){let e=ue(I),t=p.value.map((t,n)=>le(n===h.value?{...I,...e,isDefault:!!I.isDefault,enabled:I.isDefault?!0:I.enabled!==!1,timeoutMs:Number(I.timeoutMs),temperature:Number(I.temperature),topP:Number(I.topP)}:{...t,isDefault:!!t.isDefault&&t.id!==I.id}));if(!t.some(e=>e.isDefault)&&t.length&&(t[0].isDefault=!0),!S.value){S.value=!0;try{await Ge(t),B.dirty=!1,await x(),p.value=B.core.models.map(e=>({...e})),Object.assign(I,Z(),p.value[h.value],{apiKey:``}),W(a(`已保存并应用`))}catch(e){W(e.message,!0)}finally{S.value=!1}}}async function Ce(){if(await t(a(`确定删除这个模型?`),{title:a(`删除模型`),confirmText:a(`删除`),danger:!0})){if(B.core.models.some(e=>e.id===I.id)&&await Ke(I.id),B.dirty=!1,await x(),p.value=B.core.models.map(e=>({...e})),A.value=``,!p.value.length){h.value=-1,_.value=``,Object.assign(I,Z());return}h.value=0,_.value=Q(p.value[0]),Object.assign(I,Z(),p.value[0],{apiKey:``})}}async function we(){if(!(!oe.value||B.dirty||E.value)){E.value=!0,A.value=a(`正在测试「{v}」…`,{v:I.label||I.model});try{let e=await qe(I.id);A.value=a(`✓ {v} 连接成功 · {latency} ms`,{v:I.label||e.model,latency:e.latency}),await x()}catch(e){A.value=e.message}finally{E.value=!1}}}return(t,o)=>(w(),u(`div`,jt,[v(`div`,Mt,[v(`aside`,Nt,[v(`div`,Pt,[v(`h2`,null,[T(e(K(a)(`模型库`))+` `,1),v(`small`,null,e(p.value.length),1)]),v(`button`,{id:`addModel`,class:`small primary`,onClick:ve},e(K(a)(`+ 新增模型`)),1)]),v(`p`,Ft,e(K(a)(`群聊、私聊和独处都使用默认模型。其余已启用的模型按这里的顺序作为备用。关掉的模型不会被调用。`)),1),v(`div`,It,[p.value.length?y(``,!0):(w(),u(`p`,Lt,e(K(a)(`还没有模型。`)),1)),(w(!0),u(r,null,D(V.value,t=>(w(),u(`details`,{key:t.vendor,class:`saved-vendor`,open:_.value===t.vendor,"data-saved-vendor":t.vendor,onToggle:e=>se(t.vendor,e)},[v(`summary`,null,[v(`span`,null,e(t.vendor),1),v(`small`,null,e(K(a)(`{length} 个模型`,{length:t.models.length})),1)]),v(`div`,zt,[(w(!0),u(r,null,D(t.models,t=>(w(),u(`button`,{key:t.model.id,class:m([`entity-row`,{selected:h.value===t.index}]),onClick:e=>_e(t.index)},[v(`span`,{class:`badge`,style:n({"--hue":K(re)(t.model.label||t.model.model||t.model.id)})},e(String(t.model.label||t.model.model||`?`).slice(0,1).toUpperCase()),5),v(`span`,Vt,[v(`b`,null,e(t.model.label||t.model.model),1),v(`small`,null,e(t.model.enabled===!1?K(a)(`已关闭`):t.model.isDefault?K(a)(`默认模型`):K(a)(`备用模型`)),1)])],10,Bt))),128))])],40,Rt))),128))])]),L.value?(w(),u(`section`,Ht,[v(`div`,Ut,[v(`div`,null,[v(`span`,Wt,e(K(a)(`模型档案`)),1),v(`h2`,null,e(I.label||K(a)(`新模型`)),1)]),v(`span`,{class:`chip`,"data-tone":I.hasApiKey?`ok`:`warn`},e((I.isDefault?K(a)(`默认模型 · `):``)+(I.hasApiKey?K(a)(`密钥已保存`):K(a)(`待填写密钥`))),9,Gt)]),v(`form`,{id:`modelForm`,class:`stack`,onSubmit:g(Se,[`prevent`]),onInput:o[14]||=e=>K(B).dirty=!0},[v(`fieldset`,null,[v(`legend`,null,e(K(a)(`连接`)),1),v(`div`,Kt,[G.value.length>1?(w(),u(`label`,qt,[T(e(K(a)(`同厂商模型`))+` `,1),H(Y,{"model-value":I.presetId,"aria-label":K(a)(`同厂商模型`),options:G.value.map(e=>({value:e.id,label:e.label})),onChange:be},null,8,[`model-value`,`aria-label`,`options`])])):y(``,!0),v(`label`,null,[T(e(K(a)(`显示名称`)),1),C(v(`input`,{"onUpdate:modelValue":o[0]||=e=>I.label=e,name:`label`,required:``},null,512),[[i,I.label]])]),v(`label`,null,[T(e(K(a)(`供应商`)),1),C(v(`input`,{"onUpdate:modelValue":o[1]||=e=>I.provider=e,name:`provider`,placeholder:K(a)(`例如 deepseek、openai`)},null,8,Jt),[[i,I.provider]])]),v(`label`,null,[T(e(K(a)(`API 地址`)),1),C(v(`input`,{"onUpdate:modelValue":o[2]||=e=>I.baseUrl=e,name:`baseUrl`,type:`url`,required:``},null,512),[[i,I.baseUrl]])]),v(`label`,null,[T(e(K(a)(`模型名称`)),1),C(v(`input`,{"onUpdate:modelValue":o[3]||=e=>I.model=e,name:`model`,required:``},null,512),[[i,I.model]])]),v(`label`,Yt,[o[18]||=T(` API Key `,-1),C(v(`input`,{"onUpdate:modelValue":o[4]||=e=>I.apiKey=e,name:`apiKey`,type:`password`,autocomplete:`new-password`,placeholder:I.hasApiKey?K(a)(`已保存,留空则保留`):K(a)(`填写供应商提供的密钥`)},null,8,Xt),[[i,I.apiKey]])])])]),v(`fieldset`,null,[v(`legend`,null,e(K(a)(`容量与思考`)),1),v(`p`,Zt,e(K(a)(`官方按输入长度分档计价的模型可以在标准和百万之间切换;输出上限默认是官方最大值,思考强度只列出这个模型支持的档位。`)),1),v(`div`,Qt,[X.value.length?(w(),u(`label`,$t,[T(e(K(a)(`上下文容量`))+` `,1),H(Y,{name:`contextWindow`,"model-value":I.contextWindow,options:X.value.map(e=>({value:e.contextWindow,label:e.label})),onChange:de},null,8,[`model-value`,`options`])])):(w(),u(`label`,en,[T(e(K(a)(`上下文容量`)),1),C(v(`input`,{"onUpdate:modelValue":o[5]||=e=>I.contextWindow=e,name:`contextWindow`,type:`number`},null,512),[[i,I.contextWindow,void 0,{number:!0}]])])),v(`label`,null,[T(e(K(a)(`最大输入 Token`)),1),C(v(`input`,{"onUpdate:modelValue":o[6]||=e=>I.maxInputTokens=e,name:`maxInputTokens`,type:`number`},null,512),[[i,I.maxInputTokens,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`最大输出 Token`)),1),C(v(`input`,{"onUpdate:modelValue":o[7]||=e=>I.maxOutputTokens=e,name:`maxOutputTokens`,type:`number`},null,512),[[i,I.maxOutputTokens,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`思考强度`))+` `,1),H(Y,{modelValue:I.reasoningEffort,"onUpdate:modelValue":o[8]||=e=>I.reasoningEffort=e,name:`reasoningEffort`,"aria-label":K(a)(`思考强度`),options:ie.value.map(e=>({value:e,label:me(e)}))},null,8,[`modelValue`,`aria-label`,`options`])])])]),v(`details`,tn,[v(`summary`,null,e(K(a)(`高级参数与模型能力`)),1),v(`div`,nn,[v(`label`,null,[T(e(K(a)(`随机程度 Temperature`)),1),C(v(`input`,{"onUpdate:modelValue":o[9]||=e=>I.temperature=e,name:`temperature`,type:`number`,step:`0.05`},null,512),[[i,I.temperature,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`采样范围 Top P`)),1),C(v(`input`,{"onUpdate:modelValue":o[10]||=e=>I.topP=e,name:`topP`,type:`number`,step:`0.05`},null,512),[[i,I.topP,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`超时(毫秒)`)),1),C(v(`input`,{"onUpdate:modelValue":o[11]||=e=>I.timeoutMs=e,name:`timeoutMs`,type:`number`},null,512),[[i,I.timeoutMs,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`知识检索模型`)),1),C(v(`input`,{"onUpdate:modelValue":o[12]||=e=>I.embeddingModel=e,name:`embeddingModel`,placeholder:K(a)(`留空跟随对话模型`)},null,8,rn),[[i,I.embeddingModel]])])]),v(`p`,an,e(K(a)(`打开图片理解后,聊天里的图片会先在本机读取,再连同画面交给这个模型。主模型不能看图时,到会话设置另选一个打开了图片理解的视觉兼容模型。`)),1),v(`div`,on,[(w(!0),u(r,null,D({vision:K(a)(`图片理解`),system:`System Prompt`,json:K(a)(`JSON 输出`),tools:K(a)(`工具调用`),embedding:K(a)(`知识向量`)},(t,n)=>(w(),u(`label`,{key:n,class:`check`},[C(v(`input`,{"onUpdate:modelValue":e=>I[n]=e,name:n,type:`checkbox`},null,8,sn),[[J,I[n]]]),T(e(t),1)]))),128))])]),A.value?(w(),u(`div`,cn,e(A.value),1)):y(``,!0),v(`div`,ln,[v(`button`,{class:`primary`,disabled:S.value},e(S.value?K(a)(`正在保存…`):K(a)(`保存模型`)),9,un),v(`small`,dn,e(K(B).dirty?K(a)(`有未保存的修改`):K(a)(`已保存的模型才会用来测试和回复`)),1),I.isDefault?y(``,!0):(w(),u(`label`,fn,[v(`input`,{type:`checkbox`,checked:I.enabled!==!1,onChange:o[13]||=e=>{I.enabled=e.target.checked,K(B).dirty=!0}},null,40,pn),T(e(K(a)(`启用这个备用模型`)),1)])),I.isDefault?y(``,!0):(w(),u(`button`,{key:1,id:`setDefaultModel`,type:`button`,onClick:xe},e(K(a)(`设为默认模型`)),1)),oe.value?(w(),u(`button`,{key:2,id:`testModel`,type:`button`,disabled:S.value||E.value||K(B).dirty,onClick:we},e(E.value?K(a)(`正在测试…`):K(B).dirty?K(a)(`保存后测试此模型`):K(a)(`测试此模型连接`)),9,mn)):y(``,!0),v(`button`,{id:`deleteModel`,type:`button`,class:`danger push`,onClick:Ce},e(K(a)(`删除模型`)),1)])],32)])):(w(),u(`section`,hn,[H(ee,{title:K(a)(`还没有模型`),text:K(a)(`常见厂商会预填模型参数;OpenRouter 可选 GPT-6 预设,也可用自选模型手动填写模型 ID 和参数。`)},{default:q(()=>[v(`button`,{class:`primary`,onClick:ve},e(K(a)(`+ 新增模型`)),1)]),_:1},8,[`title`,`text`])]))]),H(dt),H(At),v(`section`,gn,[v(`div`,_n,[v(`div`,null,[v(`span`,vn,e(K(a)(`TOKEN LEDGER · 累计用量`)),1),v(`h2`,yn,e(K(a)(`一路聊到现在`)),1),v(`p`,null,e(K(a)(`统计本机账本记录的模型调用;缓存 Token 已包含在输入量里。`)),1)]),v(`div`,bn,[v(`strong`,null,e($(j.value?.total)),1),v(`span`,null,e(K(a)(`累计 Token`)),1)])]),v(`div`,xn,[v(`div`,Sn,[v(`span`,null,e(K(a)(`输入`)),1),v(`b`,null,e($(j.value?.input)),1)]),v(`div`,Cn,[v(`span`,null,e(K(a)(`输出`)),1),v(`b`,null,e($(j.value?.output)),1)]),v(`div`,wn,[v(`span`,null,[T(e(K(a)(`缓存命中`))+` `,1),v(`small`,null,e(K(a)(`(输入子项)`)),1)]),v(`b`,null,e($(j.value?.cached)),1)]),v(`div`,Tn,[v(`span`,null,e(K(a)(`调用次数`)),1),v(`b`,null,e($(j.value?.calls)),1)])]),v(`div`,En,[j.value?.since?(w(),u(`small`,Dn,[T(e(K(a)(`从 {v} 开始记录 · {v2} 为模型返回用量`,{v:new Date(j.value.since).toLocaleDateString(K(s)()),v2:$(j.value.reportedTokens)}))+` `,1),j.value.estimatedCalls?(w(),u(r,{key:0},[T(e(K(a)(`· {v} 次调用按文本估算`,{v:$(j.value.estimatedCalls)})),1)],64)):y(``,!0)])):F.value?(w(),u(`small`,On,e(F.value),1)):(w(),u(`small`,kn,e(K(a)(`还没有模型调用记录。`)),1)),v(`button`,{type:`button`,class:`usage-refresh`,disabled:M.value,onClick:he},e(M.value?K(a)(`更新中…`):K(a)(`刷新统计 ↻`)),9,An)])]),H(ae,{open:O.value,title:K(a)(`选择模型`),eyebrow:`MODELS`,width:`880px`,onClose:o[17]||=e=>O.value=!1},{default:q(()=>[v(`div`,jn,[v(`p`,Mn,e(K(a)(`先选供应商,再挑具体模型;支持搜索。火山方舟 Coding Plan 已预填套餐专用接口与型号参数,请勿换成普通推理 API 地址。`)),1),v(`label`,Nn,[v(`span`,null,e(K(a)(`搜索模型或供应商`)),1),C(v(`input`,{"onUpdate:modelValue":o[15]||=e=>k.value=e,type:`search`,placeholder:K(a)(`例如:火山方舟、Kimi K3、DeepSeek`)},null,8,Pn),[[i,k.value]])]),(w(!0),u(r,null,D(z.value,t=>(w(),u(`details`,{key:t.vendor,class:`vendor`,"data-vendor":t.vendor},[v(`summary`,In,[v(`span`,Ln,[v(`b`,null,e(t.vendor),1),v(`small`,null,e(K(a)(`{length} 个预设`,{length:t.models.length})),1)]),o[19]||=v(`span`,{class:`vendor-chevron`,"aria-hidden":`true`},`⌄`,-1)]),v(`div`,Rn,[(w(!0),u(r,null,D(t.models,t=>(w(),u(`button`,{key:t.id,type:`button`,class:`preset-card`,"data-preset":t.id,onClick:e=>ye(t)},[v(`b`,null,e(t.label),1),v(`small`,null,e(t.model||K(a)(`填写你在 OpenRouter 选择的模型 ID`)),1),v(`small`,null,e(pe(t)),1),v(`small`,null,e(t.summary),1)],8,zn))),128))])],8,Fn))),128)),z.value.length?y(``,!0):(w(),u(`p`,Bn,e(K(a)(`没有找到匹配的模型预设。`)),1)),U.value?(w(),u(`button`,{key:1,type:`button`,class:`preset-card custom`,"data-preset":`custom`,onClick:o[16]||=e=>ye(U.value)},[v(`b`,null,e(U.value.label),1),v(`small`,null,e(U.value.summary),1)])):y(``,!0)])]),_:1},8,[`open`,`title`])]))}}),[[`__scopeId`,`data-v-8a9bd858`]]),Hn={class:`switch`},Un=[`name`,`disabled`],Wn=z({__name:`Toggle`,props:j({name:{},disabled:{type:Boolean}},{modelValue:{type:Boolean,default:!1},modelModifiers:{}}),emits:[`update:modelValue`],setup(e){let t=O(e,`modelValue`);return(n,r)=>(w(),u(`label`,Hn,[C(v(`input`,{"onUpdate:modelValue":r[0]||=e=>t.value=e,type:`checkbox`,name:e.name,disabled:e.disabled},null,8,Un),[[J,t.value]]),v(`span`,null,[R(n.$slots,`default`)])]))}}),Gn={class:`runtime-grid`},Kn={class:`card-head`},qn={class:`eyebrow`},Jn={class:`switches`},Yn={class:`save-bar`},Xn={class:`primary`,type:`submit`},Zn={class:`faint`},Qn={class:`card numbers`},$n=[`title`],er=F(z({__name:`Runtime`,setup(t){let n=f(!!B.health.settings.enabled),r=f(!!B.health.settings.demo),i=o(()=>(B.core.sessions||[]).filter(e=>e.enabled&&!e.archived).length),s=o(()=>{let e=B.health.backup;if(!e)return null;if(!e.enabled)return{value:a(`已关闭`),caption:a(`自动备份`),tone:`warn`,title:``};if(e.lastError)return{value:a(`失败`),caption:a(`自动备份出错,稍后重试`),tone:`danger`,title:e.lastError.message};if(!e.latest)return{value:a(`还没有`),caption:a(`自动备份,运行一阵后会做第一份`),tone:``,title:``};let t=Math.max(1,Math.round(e.latest.bytes/1048576));return{value:X(e.latest.at),caption:a(`上次自动备份 · {mb} MB · 已留 {count}/{keep} 份`,{mb:t,count:e.count,keep:e.keep}),tone:``,title:e.latest.name}});async function c(){try{await L({enabled:n.value,demo:r.value}),B.dirty=!1,B.health=await E(),W(a(`已保存并应用`))}catch(e){W(e.message,!0)}}return(t,o)=>(w(),u(`div`,Gn,[v(`form`,{id:`runtime`,class:`card`,onSubmit:g(c,[`prevent`]),onChange:o[2]||=e=>K(B).dirty=!0},[v(`div`,Kn,[v(`div`,null,[v(`span`,qn,e(K(a)(`运行开关`)),1),v(`h2`,null,e(K(a)(`TA 现在可以说话吗`)),1)])]),v(`div`,Jn,[H(Wn,{modelValue:n.value,"onUpdate:modelValue":o[0]||=e=>n.value=e,name:`enabled`},{default:q(()=>[v(`b`,null,e(K(a)(`允许参与聊天`)),1),v(`small`,null,e(K(a)(`总开关。关掉后 TA 不看也不回任何会话,心智照常保存。`)),1)]),_:1},8,[`modelValue`]),H(Wn,{modelValue:r.value,"onUpdate:modelValue":o[1]||=e=>r.value=e,name:`demo`},{default:q(()=>[v(`b`,null,e(K(a)(`仅模拟运行,不向 QQ 发送`)),1),v(`small`,null,e(K(a)(`模拟模式下,「对话」里可以发模拟消息走完整流程;它们写进模拟会话,不进入真实记忆。`)),1)]),_:1},8,[`modelValue`])]),v(`div`,Yn,[v(`button`,Xn,e(K(a)(`保存运行状态`)),1),v(`small`,Zn,e(K(B).dirty?K(a)(`有未保存的修改`):K(a)(`已保存,立刻生效`)),1)])],32),v(`section`,Qn,[v(`button`,{onClick:o[3]||=e=>K(A)(`chats`)},[v(`b`,null,e(i.value),1),v(`span`,null,e(K(a)(`参与中的会话`)),1)]),v(`button`,{onClick:o[4]||=e=>K(A)(`system`,`models`)},[v(`b`,null,e(K(B).core.models.length),1),v(`span`,null,e(K(a)(`可用模型`)),1)]),v(`button`,{onClick:o[5]||=e=>K(A)(`system`,`connect`)},[v(`b`,null,e(K(B).health.connection?.online?K(a)(`在线`):K(a)(`离线`)),1),v(`span`,null,e(K(a)(`QQ 连接`)),1)]),s.value?(w(),u(`button`,{key:0,class:m([`stat`,s.value.tone]),title:s.value.title,"data-testid":`backup-status`,type:`button`,onClick:o[6]||=e=>K(A)(`system`,`storage`)},[v(`b`,null,e(s.value.value),1),v(`span`,null,e(s.value.caption),1)],10,$n)):y(``,!0)])]))}}),[[`__scopeId`,`data-v-1f197523`]]),tr={class:`card search-profile`},nr={class:`eyebrow`},rr={class:`muted`},ir={key:0,class:`faint`},ar={class:`check`},or=[`disabled`],sr={class:`search-fields`},cr=[`disabled`],lr=[`disabled`,`placeholder`],ur=[`disabled`],dr=[`disabled`],fr=[`disabled`],pr={class:`faint`},mr={class:`search-usage`,role:`status`},hr={class:`chip`},gr={class:`faint`},_r={class:`faint`},vr={class:`row`},yr=[`disabled`],br=[`disabled`],xr={key:0,class:`faint`},Sr=[`role`],Cr=F(z({__name:`SearchProfile`,setup(t){let n=[`provider`,`enabled`,`baseUrl`,`timeoutMs`,`maxResults`,`dailyLimit`],r=te({provider:`tavily`,enabled:!0,baseUrl:``,apiKey:``,timeoutMs:2e4,maxResults:5,dailyLimit:12}),s=f(null),c=f(!1),l=f(!1),d=f(``),p=f(!1),h=new Map,_=`tavily`,x=o(()=>l.value&&(!!r.apiKey.trim()||n.some(e=>r[e]!==s.value?.[e]))),S=e=>e===`brave`?`Brave`:`Tavily`,E=o(()=>s.value?.dailyLimit===0?a(`不限`):s.value?.dailyLimit??12);b(x,e=>{B.dirty=e}),b(()=>[B.tick,B.pulse],()=>{l.value&&!c.value&&B.page===`system`&&B.sub===`search`&&D().catch(()=>{})});async function D(){s.value=await P(`/mind/time/search`)}async function O(){try{await D(),Object.assign(r,s.value,{apiKey:``}),_=r.provider,l.value=!0}catch(e){W(e.message,!0)}}async function k(){if(c.value)return;c.value=!0;let e=r.provider;h.set(_,{...r,provider:_});try{Object.assign(r,h.get(e)||{...await P(`/mind/time/search?provider=`+e),apiKey:``}),_=e,d.value=``}catch(e){r.provider=_,W(e.message,!0)}finally{c.value=!1}}function A(){return Object.fromEntries([...n,`apiKey`].map(e=>[e,r[e]]))}async function j(){if(!c.value){c.value=!0;try{let e=await P(`/mind/time/search`,`PATCH`,A());s.value=e,Object.assign(r,e,{apiKey:``}),h.set(r.provider,{...r}),_=r.provider,W(a(`搜索配置已保存并生效`))}catch(e){W(e.message,!0)}finally{c.value=!1}}}async function M(){if(!c.value){c.value=!0,d.value=``,p.value=!1;try{let e=await P(`/mind/time/search/test`,`POST`,A()),t={source:e.profile.mode===`web`?a(`{provider} 联网检索`,{provider:S(e.profile.provider)}):e.profile.materialLabel,count:e.results.length};d.value=x.value?a(`{source}测试通过,返回 {count} 条资料。测试不占用每日查询额度;当前填写的配置尚未保存。`,t):a(`{source}测试通过,返回 {count} 条资料。测试不占用每日查询额度。`,t)}catch(e){p.value=!0,d.value=a(`{error}。本次测试不占用每日查询额度。`,{error:e.message})}finally{try{await D()}catch{}c.value=!1}}}return N(O),U(()=>{B.dirty=!1}),(t,n)=>(w(),u(`section`,tr,[v(`span`,nr,e(K(a)(`SEARCH · 独立搜索`)),1),v(`h2`,null,e(K(a)(`接触世界的资料`)),1),v(`p`,rr,e(K(a)(`配置后优先联网检索。未配置密钥或关闭独立搜索时,使用当前模型整理已有知识。`)),1),l.value?(w(),u(`p`,ir,e(K(a)(`当前生效:{v}。表单修改保存后生效。`,{v:s.value.mode===`web`?K(a)(`{provider} · 联网检索资料`,{provider:S(s.value.provider)}):s.value.materialLabel})),1)):y(``,!0),l.value?(w(),u(`form`,{key:1,onSubmit:g(j,[`prevent`])},[v(`label`,ar,[C(v(`input`,{"onUpdate:modelValue":n[0]||=e=>r.enabled=e,type:`checkbox`,disabled:c.value},null,8,or),[[J,r.enabled]]),T(e(K(a)(`启用独立搜索`)),1)]),v(`div`,sr,[v(`label`,null,[T(e(K(a)(`提供方`)),1),H(Y,{modelValue:r.provider,"onUpdate:modelValue":n[1]||=e=>r.provider=e,"aria-label":K(a)(`搜索提供方`),disabled:c.value,options:[{value:`tavily`,label:`Tavily`},{value:`brave`,label:`Brave`}],onChange:k},null,8,[`modelValue`,`aria-label`,`disabled`])]),v(`label`,null,[T(e(K(a)(`搜索地址`)),1),C(v(`input`,{"onUpdate:modelValue":n[2]||=e=>r.baseUrl=e,type:`url`,required:``,name:`searchUrl`,disabled:c.value},null,8,cr),[[i,r.baseUrl]])]),v(`label`,null,[T(e(K(a)(`独立密钥`)),1),C(v(`input`,{"onUpdate:modelValue":n[3]||=e=>r.apiKey=e,type:`password`,autocomplete:`new-password`,name:`searchKey`,disabled:c.value,placeholder:r.hasApiKey?K(a)(`已保存,留空保留`):K(a)(`填写该提供方的搜索密钥`)},null,8,lr),[[i,r.apiKey]])]),v(`label`,null,[T(e(K(a)(`超时(毫秒)`)),1),C(v(`input`,{"onUpdate:modelValue":n[4]||=e=>r.timeoutMs=e,type:`number`,min:`1000`,max:`120000`,disabled:c.value},null,8,ur),[[i,r.timeoutMs,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`每次结果数`)),1),C(v(`input`,{"onUpdate:modelValue":n[5]||=e=>r.maxResults=e,type:`number`,min:`1`,max:`20`,disabled:c.value},null,8,dr),[[i,r.maxResults,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`每日查询上限`)),1),C(v(`input`,{"onUpdate:modelValue":n[6]||=e=>r.dailyLimit=e,name:`searchDailyLimit`,type:`number`,min:`0`,max:`100000`,disabled:c.value},null,8,fr),[[i,r.dailyLimit,void 0,{number:!0}]]),v(`small`,pr,e(K(a)(`可手动调整;0 表示不限。保存后立即生效。`)),1)])]),v(`div`,mr,[v(`span`,hr,e(K(a)(`今日有效查询 {v} / {limitLabel}`,{v:s.value.used||0,limitLabel:E.value})),1),v(`small`,gr,e(K(a)(`{v} 次进行中 · {v2} 次失败 · {v3} 次测试`,{v:s.value.usage?.running||0,v2:s.value.usage?.failed||0,v3:s.value.usage?.diagnostics||0})),1)]),v(`p`,_r,e(K(a)(`测试当前填写的配置,不会自动保存。失败与连接测试不占本地每日额度;提供方的账户额度由提供方管理。`)),1),v(`div`,vr,[v(`button`,{class:`primary`,disabled:c.value},e(K(a)(`保存搜索`)),9,yr),v(`button`,{type:`button`,disabled:c.value,onClick:M},e(c.value?K(a)(`处理中…`):K(a)(`测试连接`)),9,br),x.value?(w(),u(`span`,xr,e(K(a)(`有尚未保存的修改`)),1)):y(``,!0)]),d.value?(w(),u(`p`,{key:0,role:p.value?`alert`:`status`,class:m([`search-result`,{failed:p.value}])},e(d.value),11,Sr)):y(``,!0)],32)):y(``,!0)]))}}),[[`__scopeId`,`data-v-e874d8b6`]]),wr={key:0,class:`card data-transfer`,"aria-labelledby":`data-transfer-title`},Tr={class:`eyebrow`},Er={id:`data-transfer-title`},Dr={class:`transfer-note`},Or={class:`transfer-note`},kr={class:`transfer-actions`},Ar=[`disabled`],jr=[`disabled`],Mr=[`aria-label`],Nr={class:`transfer-note`},Pr={key:0,class:`transfer-progress`,role:`status`},Fr={key:1,class:`transfer-error`,role:`alert`},Ir={key:2,class:`transfer-note`},Lr={key:3,class:`transfer-preview`},Rr={class:`eyebrow`},zr={class:`transfer-note`},Br={class:`transfer-counts`},Vr={class:`transfer-actions`},Hr=[`disabled`],Ur=[`disabled`],Wr=F(z({__name:`DataTransfer`,setup(n){let i=f(null),s=f(null),l=f(),m=f(``),h=f(``),g=!0,_=null,b=o(()=>!!m.value),x=o(()=>m.value===`restarting`?a(`正在保留快照并重启加载,请等待…`):m.value===`uploading`?a(`正在上传数据文件…`):m.value===`exporting`?a(`正在生成完整数据包…`):a(`正在校验数据文件…`)),S=o(()=>{let e=s.value?.summary?.tables||{};return[[a(`聊天记录`),e.core_events||e.messages||0],[a(`记忆`),e.core_memories||e.memories||0],[a(`待办`),e.mind_time_tasks||0],[a(`作品`),e.mind_time_works||0],[a(`日记`),e.mind_diary||0]]}),C=()=>new Promise(e=>setTimeout(e,800));async function T(e,t=!1){for(let n=0;n<4500&&g;n++){try{let n=await P(`/storage/transfer/jobs/`+e);if(n.status===`error`)throw Error(n.error||a(`数据处理失败`));if(n.status===(t?`done`:`ready`))return n;if(n.status===`expired`)throw Error(a(`数据文件已过期,请重新选择`))}catch(e){if(!t||!(e instanceof TypeError)&&e.message!==a(`请求失败`))throw e}await C()}throw Error(a(`等待数据处理超时,请检查实例运行状态`))}async function E(){if(!b.value){m.value=`exporting`,h.value=``;try{let e=await P(`/storage/transfer/export`,`POST`,{});if(await T(e.id),!g)return;let t=document.createElement(`a`);t.href=`/api/storage/transfer/download/`+e.id,t.download=``,document.body.appendChild(t),t.click(),t.remove(),W(a(`数据包已生成,浏览器将开始下载`))}catch(e){g&&(h.value=e.message)}finally{g&&(m.value=``)}}}async function O(e){let t=e.target,n=t.files?.[0];if(t.value=``,n&&!b.value){if(h.value=``,s.value=null,n.size>(i.value?.maxBytes||0)){h.value=a(`数据文件超过导入大小限制`);return}m.value=`uploading`,_=new AbortController;try{await p();let e=await fetch(`/api/storage/transfer/upload`,{method:`POST`,credentials:`same-origin`,headers:{"Content-Type":`application/octet-stream`,"X-LuckyTri-Filename":encodeURIComponent(n.name),"X-LuckyTri-Locale":c.value},body:n,signal:_.signal});if(e.status===401)throw d(),Error(a(`请先登录管理台`));let t=await e.json().catch(()=>({}));if(!e.ok)throw Error(t.error||a(`数据上传失败`));m.value=`checking`;let r=await T(t.id);g&&(s.value=r)}catch(e){g&&(h.value=e.message)}finally{_=null,g&&(m.value=``)}}}async function A(){if(s.value&&!b.value)try{await P(`/storage/transfer/jobs/`+s.value.id,`DELETE`),s.value=null}catch(e){h.value=e.message}}async function j(){if(!s.value||b.value||!await t(a(`用这份数据替换当前数据,并保留导入前快照。实例将重启,导入后自动回复关闭。本机管理密码与 QQ 连接配置保持不变。`),{title:a(`确认导入数据`),confirmText:a(`导入并重启`),danger:!0}))return;m.value=`restarting`,h.value=``;let e=s.value.id;try{if(await P(`/storage/transfer/import`,`POST`,{id:e}),await T(e,!0),!g)return;k(),location.reload()}catch(e){g&&(h.value=e.message)}finally{g&&(m.value=``)}}return N(async()=>{try{i.value=await P(`/storage/transfer`)}catch(e){g&&(h.value=e.message)}}),V(()=>{g=!1,_?.abort()}),(t,n)=>i.value?.available?(w(),u(`section`,wr,[v(`span`,Tr,e(K(a)(`DATA · 导入与导出`)),1),v(`h2`,Er,e(K(a)(`带上记忆,继续生活。`)),1),v(`p`,Dr,e(K(a)(`导出数据库内的聊天、记忆、待办、作品、知识与设置。插件文件、知识库原始文件和本机 .env 不在数据包中。`)),1),v(`p`,Or,e(K(a)(`数据包包含私聊内容和模型设置中的密钥,请存放在你信任的位置。导入前会校验,确认后才替换当前数据。`)),1),v(`div`,kr,[v(`button`,{class:`primary`,type:`button`,disabled:b.value,onClick:E},e(K(a)(`导出数据包`)),9,Ar),v(`button`,{type:`button`,disabled:b.value,onClick:n[0]||=e=>l.value?.click()},e(K(a)(`选择导入文件`)),9,jr),v(`input`,{ref_key:`input`,ref:l,class:`transfer-file`,type:`file`,accept:`.luckytri,.db,.sqlite,.sqlite3`,"aria-label":K(a)(`导入数据文件`),onChange:O},null,40,Mr)]),v(`p`,Nr,e(K(a)(`支持 .luckytri 数据包和已有 SQLite 备份,单个文件最多 {size} GiB。`,{size:(i.value.maxBytes/1073741824).toFixed(0)})),1),b.value?(w(),u(`p`,Pr,e(x.value),1)):y(``,!0),h.value?(w(),u(`p`,Fr,e(h.value),1)):y(``,!0),i.value.lastImport?.status===`done`?(w(),u(`p`,Ir,e(K(a)(`上次数据导入已完成,自动回复在导入时关闭。请检查连接、模型和待办后再开启;插件需重新安装或确认权限。`)),1)):y(``,!0),s.value?(w(),u(`div`,Lr,[v(`span`,Rr,e(K(a)(`校验通过 · 尚未导入`)),1),v(`h3`,null,e(s.value.summary?.name),1),v(`p`,zr,e(s.value.name)+` · `+e(K(a)(`数据库版本 {from} → {to}`,{from:s.value.originalVersion,to:s.value.summary?.schemaVersion})),1),v(`div`,Br,[(w(!0),u(r,null,D(S.value,([t,n])=>(w(),u(`div`,{key:t},[v(`b`,null,e(n),1),v(`span`,null,e(t),1)]))),128))]),v(`div`,Vr,[v(`button`,{class:`primary`,type:`button`,disabled:b.value,onClick:j},e(K(a)(`导入并重启`)),9,Hr),v(`button`,{type:`button`,disabled:b.value,onClick:A},e(K(a)(`取消导入`)),9,Ur)])])):y(``,!0)])):y(``,!0)}}),[[`__scopeId`,`data-v-ea16c0c1`]]),Gr={class:`storage-page`},Kr={class:`card storage-overview`},qr={class:`eyebrow`},Jr={key:0,class:`storage-metrics`},Yr={key:0,class:`storage-error`,role:`alert`},Xr={key:1,class:`storage-grid`},Zr={class:`card-head`},Qr={class:`eyebrow`},$r={class:`storage-check`},ei={class:`storage-fields`},ti=[`aria-label`],ni=[`aria-label`],ri=[`aria-label`],ii={class:`storage-note`},ai={key:0,class:`storage-note`},oi={key:1,class:`storage-error`},si=[`disabled`],ci={class:`card storage-list`},li={class:`card-head`},ui={class:`eyebrow`},di={class:`storage-note`},fi={class:`storage-actions`},pi=[`disabled`],mi=[`disabled`],hi=[`disabled`],gi={class:`storage-scroll`},_i=[`checked`,`disabled`,`aria-label`,`onChange`],vi={class:`storage-item`},yi={key:0,class:`storage-error`,role:`alert`},bi={class:`storage-footer`},xi=[`disabled`],Si=F(z({__name:`BackupManager`,setup(n){let c=f(null),l=f({enabled:!0,time:`04:30`,retainDays:14,keepFull:2}),d=f([]),p=f(!1),h=f(``),_=f([]),b=!0,x=e=>`${e.scope}:${e.name}`,S=o(()=>c.value?.entries.filter(e=>d.value.includes(x(e)))||[]),E=o(()=>S.value.reduce((e,t)=>e+t.bytes,0)),O=e=>e===0?`0 B`:e>=1073741824?`${(e/1073741824).toFixed(2)} GiB`:`${Math.max(.01,e/1048576).toFixed(2)} MiB`,k=e=>new Date(e).toLocaleString(s()),A=e=>({auto:a(`自动备份`),full:a(`完整备份`),migration:a(`迁移快照`),legacy:a(`旧版本备份`),snapshot:a(`升级前快照`),import:a(`导入前快照`)})[e];async function j(e=!1){try{h.value=``;let t=await P(`/storage/cleanup`);if(!b)return;if(c.value=t,e)l.value={...c.value.policy},d.value=[],B.dirty=!1;else{let e=new Set(c.value.entries.filter(e=>!e.protected).map(x));d.value=d.value.filter(t=>e.has(t))}}catch(e){b&&(h.value=e.message)}}function M(){B.dirty=!0}function F(e){let t=x(e);d.value=d.value.includes(t)?d.value.filter(e=>e!==t):[...d.value,t]}function I(){d.value=(c.value?.plan.items||[]).map(x)}function L(){d.value=(c.value?.entries||[]).filter(e=>e.kind===`full`&&!e.protected).map(x)}async function R(){if(!p.value){p.value=!0;try{let e=await P(`/storage/cleanup`,`PATCH`,{enabled:l.value.enabled,time:l.value.time,retainDays:Number(l.value.retainDays),keepFull:Number(l.value.keepFull)});c.value=e,l.value={...e.policy},B.dirty=!1,W(a(`备份整理规则已保存`))}catch(e){W(e.message,!0)}finally{p.value=!1}}}async function z(){if(!S.value.length||p.value)return;let e=S.value.map(({scope:e,name:t,bytes:n,modified:r})=>({scope:e,name:t,bytes:n,modified:r}));if(await t(a(`将清理选中的 {count} 份备份,释放约 {size}。这些历史恢复点清理后无法从本机找回。`,{count:e.length,size:O(E.value)}),{title:a(`清理所选备份`),confirmText:a(`清理所选`),danger:!0})){p.value=!0;try{let t=await P(`/storage/cleanup/manual`,`POST`,{items:e});_.value=t.failures||[];let n=new Set((t.failures||[]).map(e=>`${e.scope}:${e.name}`));d.value=d.value.filter(e=>n.has(e)),await j(),W(a(`已清理 {count} 份备份,释放 {size}`,{count:t.removed.length,size:O(t.bytes)})+(_.value.length?a(`;部分未清理,详情见列表`):``),_.value.length>0)}catch(e){W(e.message,!0),await j()}finally{p.value=!1}}}return N(()=>j(!0)),V(()=>{b=!1}),(t,n)=>(w(),u(`div`,Gr,[v(`section`,Kr,[v(`span`,qr,e(K(a)(`DATA · 数据与备份`)),1),v(`h2`,null,e(K(a)(`留住重要的,整理重复的。`)),1),v(`p`,null,e(K(a)(`这里管理历史备份。聊天、记忆和作品仍在正在运行的数据库里,不会被列入清理。`)),1),c.value?(w(),u(`div`,Jr,[v(`div`,null,[v(`b`,null,e(O(c.value.totalBytes)),1),v(`span`,null,e(K(a)(`可管理的历史备份`)),1)]),v(`div`,null,[v(`b`,null,e(c.value.entries.length),1),v(`span`,null,e(K(a)(`份数据库副本`)),1)]),v(`div`,null,[v(`b`,null,e(O(c.value.plan.bytes)),1),v(`span`,null,e(K(a)(`按当前规则可定时整理`)),1)])])):y(``,!0)]),h.value?(w(),u(`p`,Yr,e(h.value),1)):y(``,!0),H(Wr),c.value?(w(),u(`div`,Xr,[v(`form`,{class:`card storage-policy`,onSubmit:g(R,[`prevent`])},[v(`div`,Zr,[v(`div`,null,[v(`span`,Qr,e(K(a)(`定时整理`)),1),v(`h2`,null,e(K(a)(`每天给备份留一点空间`)),1)])]),v(`label`,$r,[C(v(`input`,{"onUpdate:modelValue":n[0]||=e=>l.value.enabled=e,type:`checkbox`,onChange:M},null,544),[[J,l.value.enabled]]),T(e(K(a)(`启用定时整理`)),1)]),v(`div`,ei,[v(`label`,null,[T(e(K(a)(`每天执行时间`)),1),C(v(`input`,{"onUpdate:modelValue":n[1]||=e=>l.value.time=e,type:`text`,inputmode:`numeric`,maxlength:`5`,placeholder:`04:30`,"aria-label":K(a)(`每天执行时间`),onInput:M},null,40,ti),[[i,l.value.time]])]),v(`label`,null,[T(e(K(a)(`完整备份保留天数`)),1),C(v(`input`,{"onUpdate:modelValue":n[2]||=e=>l.value.retainDays=e,type:`number`,min:`1`,max:`3650`,"aria-label":K(a)(`完整备份保留天数`),onInput:M},null,40,ni),[[i,l.value.retainDays,void 0,{number:!0}]])]),v(`label`,null,[T(e(K(a)(`完整备份最多保留份数`)),1),C(v(`input`,{"onUpdate:modelValue":n[3]||=e=>l.value.keepFull=e,type:`number`,min:`0`,max:`100`,"aria-label":K(a)(`完整备份最多保留份数`),onInput:M},null,40,ri),[[i,l.value.keepFull,void 0,{number:!0}]])])]),v(`p`,ii,e(K(a)(`时间按服务器本地时区 {zone}。完整备份超过保留天数或数量上限便会定时整理;数量填 0 表示不保留完整备份。手动清理可选择完整备份和迁移快照,执行前会校验同一实例的近期自动恢复点。`,{zone:c.value.serverTimeZone})),1),c.value.last?(w(),u(`p`,ai,e(c.value.last.error&&c.value.last.removed===0?K(a)(`上次整理未执行:{error}`,{error:c.value.last.error}):K(a)(`上次整理:{time} · {count} 份 · {size}`,{time:k(c.value.last.at),count:c.value.last.removed,size:O(c.value.last.bytes)})),1)):y(``,!0),c.value.last?.error&&c.value.last.removed>0?(w(),u(`p`,oi,e(c.value.last.error),1)):y(``,!0),v(`button`,{class:`primary`,type:`submit`,disabled:p.value},e(p.value?K(a)(`处理中…`):K(a)(`保存整理规则`)),9,si)],32),v(`section`,ci,[v(`div`,li,[v(`div`,null,[v(`span`,ui,e(K(a)(`手动整理`)),1),v(`h2`,null,e(K(a)(`挑选历史恢复点`)),1)])]),v(`p`,di,e(K(a)(`自动备份已有自己的轮换规则。迁移、旧版本和升级前快照只由你手动挑选;清理前会再次核对文件和恢复点。`)),1),v(`div`,fi,[v(`button`,{type:`button`,disabled:p.value||!c.value.plan.items.length,onClick:I},e(K(a)(`选中规则建议`)),9,pi),v(`button`,{type:`button`,disabled:p.value,onClick:L},e(K(a)(`选中完整备份`)),9,mi),v(`button`,{type:`button`,disabled:p.value||!d.value.length,onClick:n[4]||=e=>d.value=[]},e(K(a)(`取消选择`)),9,hi)]),v(`div`,gi,[(w(!0),u(r,null,D(c.value.entries,t=>(w(),u(`label`,{key:x(t),class:m([`storage-row`,{protected:t.protected}])},[v(`input`,{type:`checkbox`,checked:d.value.includes(x(t)),disabled:p.value||t.protected||c.value.running,"aria-label":t.name,onChange:e=>F(t)},null,40,_i),v(`span`,vi,[v(`strong`,null,e(t.name),1),v(`small`,null,e(A(t.kind))+` · `+e(k(t.at))+` · `+e(t.manifest?K(a)(`有校验清单`):K(a)(`旧备份无清单`))+e(t.protected?` · `+(t.protectionReason||K(a)(`保留恢复点`)):``),1)]),v(`b`,null,e(O(t.bytes)),1)],2))),128))]),_.value.length?(w(),u(`div`,yi,[v(`p`,null,e(K(a)(`部分备份未清理,请刷新列表后重试`)),1),(w(!0),u(r,null,D(_.value,t=>(w(),u(`p`,{key:t.name},e(t.name)+` · `+e(t.error),1))),128))])):y(``,!0),v(`div`,bi,[v(`span`,null,e(K(a)(`已选 {count} 份 · 约 {size}`,{count:S.value.length,size:O(E.value)})),1),v(`button`,{class:`primary`,type:`button`,disabled:p.value||c.value.running||!S.value.length,onClick:z},e(K(a)(`清理所选`)),9,xi)])])])):y(``,!0)]))}}),[[`__scopeId`,`data-v-4593780e`]]),Ci={class:`card password-settings`},wi={class:`row`},Ti=[`disabled`],Ei=F(z({__name:`PasswordSettings`,setup(t){let n=f(``),r=f(``),o=f(``),s=f(!1);async function c(){if(!s.value){if(r.value!==o.value){W(a(`两次输入的密码不一致`),!0);return}s.value=!0;try{await S(`password`,{currentPassword:n.value,password:r.value}),n.value=r.value=o.value=``,W(a(`管理密码已更新`))}catch(e){W(e.message,!0)}finally{s.value=!1}}}return(t,l)=>(w(),u(`section`,Ci,[v(`h2`,null,e(K(a)(`管理密码`)),1),v(`p`,null,e(K(a)(`一个密码管理这个小世界。修改后,其他浏览器需要重新登录。`)),1),v(`form`,{onSubmit:g(c,[`prevent`])},[v(`label`,null,[T(e(K(a)(`当前密码`)),1),C(v(`input`,{"onUpdate:modelValue":l[0]||=e=>n.value=e,name:`currentPassword`,type:`password`,autocomplete:`current-password`,required:``},null,512),[[i,n.value]])]),v(`label`,null,[T(e(K(a)(`新密码`)),1),C(v(`input`,{"onUpdate:modelValue":l[1]||=e=>r.value=e,name:`newPassword`,type:`password`,autocomplete:`new-password`,minlength:`8`,maxlength:`256`,required:``},null,512),[[i,r.value]])]),v(`label`,null,[T(e(K(a)(`确认密码`)),1),C(v(`input`,{"onUpdate:modelValue":l[2]||=e=>o.value=e,name:`confirmNewPassword`,type:`password`,autocomplete:`new-password`,minlength:`8`,maxlength:`256`,required:``},null,512),[[i,o.value]])]),v(`div`,wi,[v(`button`,{class:`primary`,disabled:s.value},e(K(a)(`修改密码`)),9,Ti),v(`button`,{type:`button`,onClick:l[3]||=(...e)=>K(G)&&K(G)(...e)},e(K(a)(`退出登录`)),1)])],32)]))}}),[[`__scopeId`,`data-v-36cd9f70`]]),Di={class:`card update-settings`,"aria-labelledby":`update-title`},Oi={id:`update-title`},ki=[`disabled`],Ai={class:`kv`},ji={key:0,class:`muted`,role:`alert`},Mi={class:`muted small-text`},Ni={key:1,class:`update-how stack tight`},Pi=[`disabled`],Fi={key:1,role:`status`},Ii={key:2,class:`error-text`,role:`alert`},Li={key:0,class:`error-text`},Ri={key:1,class:`error-text`},zi={key:2,class:`error-text`},Bi={key:4,class:`muted`},Vi={class:`update-links`},Hi=[`href`],Ui=[`href`],Wi=F(z({__name:`UpdateSettings`,setup(n){let i=f(null),o=f(!1),s=f(!1),c,d=!1,p=l({queued:M(`更新已开始`),downloading:M(`正在下载新版本…`),checking:M(`正在检查新程序…`),stopping:M(`正在保存当下并停止实例…`),backup:M(`正在保留更新前的校验备份…`),migrating:M(`正在整理并校验记忆与数据…`),restarting:M(`正在切换版本并重启…`),verifying:M(`正在确认新实例就绪…`),restoring:M(`正在恢复原版本和数据…`),done:M(`更新与重启已完成`),error:M(`更新未完成`)}),h=l({queued:M(`准备更新`),downloading:M(`下载新版本`),checking:M(`检查新程序`),stopping:M(`停止旧实例`),backup:M(`保存校验备份`),migrating:M(`迁移记忆与数据`),restarting:M(`切换并重启`),verifying:M(`检查新实例`),restoring:M(`恢复原版本`)});function g(e){return e&&![`done`,`error`].includes(e.status)}async function _(){if(!d){try{let e=await P(`/system/update`);if(i.value=e,e.operation?.status===`done`){s.value=!1,location.reload();return}s.value=!!g(e.operation)}catch{}s.value&&!d&&(c=setTimeout(_,1800))}}U(()=>{d=!0,clearTimeout(c)});let b=l({unchecked:M(`尚未检查更新`),available:M(`有新版本可用`),current:M(`已是最新发布版本`),ahead:M(`当前版本领先于 npm 发布版本`),unavailable:M(`暂时无法检查更新`)});N(async()=>{try{i.value=await P(`/system/update`),s.value=!!g(i.value.operation),s.value&&(c=setTimeout(_,1800))}catch(e){W(e.message,!0)}});async function x(){if(!o.value){o.value=!0;try{i.value=await P(`/system/update/check`,`POST`,{})}catch(e){W(e.message,!0)}finally{o.value=!1}}}async function S(){if(!(s.value||o.value||i.value?.status!==`available`)&&await t(a(`更新到 {version} 并重启当前实例?先下载校验,再保留数据恢复点;启动失败时尝试恢复原版本。`,{version:i.value.latest}),{title:a(`更新并重启`),confirmText:a(`开始更新`)})){s.value=!0;try{i.value.operation=await P(`/system/update/install`,`POST`,{version:i.value.latest}),c=setTimeout(_,800)}catch(e){s.value=!1,W(e.message,!0)}}}return(t,n)=>(w(),u(`section`,Di,[v(`header`,null,[v(`div`,null,[n[0]||=v(`span`,{class:`eyebrow`},`LUCKYTRI / VERSION`,-1),v(`h2`,Oi,e(K(a)(`版本与更新`)),1)]),v(`button`,{disabled:o.value||s.value||!i.value,onClick:x},e(o.value?K(a)(`正在检查…`):K(a)(`检查更新`)),9,ki)]),i.value?(w(),u(r,{key:0},[v(`p`,{class:m([`version-state`,{available:i.value.status===`available`}]),role:`status`},e(K(b)[i.value.status]||K(b).unchecked),3),v(`dl`,Ai,[v(`dt`,null,e(K(a)(`当前版本`)),1),v(`dd`,null,e(i.value.current),1),v(`dt`,null,e(K(a)(`npm 最新版本`)),1),v(`dd`,null,e(i.value.latest||`—`),1),v(`dt`,null,e(K(a)(`上次成功检查`)),1),v(`dd`,null,e(i.value.checkedAt?K(ne)(i.value.checkedAt):`—`),1)]),i.value.error?(w(),u(`p`,ji,e(K(a)(`暂时无法连接 npm 或读取版本信息,请稍后重试。`)),1)):y(``,!0),v(`p`,Mi,e(K(a)(`点击时才检查,五分钟内复用结果。检查更新不会自动安装或重启。`)),1),i.value.status===`available`||i.value.operation?(w(),u(`div`,Ni,[v(`p`,null,e(K(a)(`下载期间继续运行,切换前保留数据恢复点。更新完成后此页面会自动重新连接。`)),1),i.value.status===`available`?(w(),u(`button`,{key:0,class:`primary`,disabled:s.value||o.value,onClick:S},e(s.value?K(a)(`正在更新…`):K(a)(`更新并重启`)),9,Pi)):y(``,!0),i.value.operation?(w(),u(`p`,Fi,e(K(p)[i.value.operation.status])+` · `+e(i.value.operation.version),1)):y(``,!0),i.value.operation?.error?(w(),u(`p`,Ii,e(i.value.operation.error),1)):y(``,!0),i.value.operation?.status===`error`?(w(),u(r,{key:3},[K(h)[i.value.operation.failedStage]?(w(),u(`p`,Li,e(K(a)(`失败阶段:{stage}`,{stage:K(h)[i.value.operation.failedStage]})),1)):y(``,!0),i.value.operation.detail?(w(),u(`p`,Ri,e(i.value.operation.detail),1)):y(``,!0),i.value.operation.recoveryDetail?(w(),u(`p`,zi,e(i.value.operation.recoveryDetail),1)):y(``,!0)],64)):y(``,!0),i.value.operation?.restored?(w(),u(`p`,Bi,e(K(a)(`已恢复原版本和更新前的数据。`)),1)):y(``,!0)])):y(``,!0),v(`nav`,Vi,[v(`a`,{href:i.value.npmUrl,target:`_blank`,rel:`noopener noreferrer`},`npm`,8,Hi),v(`a`,{href:i.value.releaseUrl,target:`_blank`,rel:`noopener noreferrer`},e(K(a)(`发布说明`))+` ↗`,9,Ui)])],64)):y(``,!0)]))}}),[[`__scopeId`,`data-v-afcb3dd7`]]),Gi={class:`page system`},Ki={class:`system-intro`},qi={class:`eyebrow`},Ji={class:`system-status`},Yi=F(z({__name:`SystemPage`,setup(n){let i=[`connect`,`models`,`search`,`runtime`,`storage`],o=f(i.includes(B.sub)?B.sub:`connect`);async function s(e){e!==o.value&&(!B.dirty||await t(a(`当前设置还没保存,离开这个分区吗?`),{title:a(`未保存的修改`),confirmText:a(`放弃修改`),cancelText:a(`继续编辑`)}))&&(B.dirty=!1,o.value=e)}return b(o,e=>I(e)),b(()=>B.sub,e=>{i.includes(e)&&(o.value=e)}),(t,n)=>(w(),u(`div`,Gi,[v(`header`,Ki,[v(`div`,null,[v(`span`,qi,e(K(a)(`THE WORLD AROUND HER · 系统`)),1),v(`h1`,null,[T(e(K(a)(`让她与世界,`)),1),v(`em`,null,e(K(a)(`温柔相连。`)),1)]),v(`p`,null,e(K(a)(`连接、模型与运行方式都在这里。每一处改变,都可以看见结果。`)),1)]),v(`span`,Ji,[v(`i`,{class:m({off:!K(B).health.connection?.online})},null,2),T(` `+e(K(B).health.connection?.online?K(a)(`正在与 QQ 相连`):K(a)(`等待 QQ 连接`)),1)])]),H(ie,{"model-value":o.value,"onUpdate:modelValue":s,label:K(a)(`系统的分区`),items:[{key:`connect`,label:K(a)(`连接 QQ`)},{key:`models`,label:K(a)(`模型库`)},{key:`search`,label:K(a)(`独立搜索`)},{key:`runtime`,label:K(a)(`运行开关`)},{key:`storage`,label:K(a)(`数据与备份`)}]},null,8,[`model-value`,`label`,`items`]),o.value===`connect`?(w(),_(We,{key:0,onOpen:s})):o.value===`models`?(w(),_(Vn,{key:1})):o.value===`search`?(w(),_(Cr,{key:2})):o.value===`runtime`?(w(),u(r,{key:3},[H(er),H(Wi),H(Ei)],64)):(w(),_(Si,{key:4}))]))}}),[[`__scopeId`,`data-v-a12a372e`]]);export{Yi as default};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{Ct as e,D as t,Dt as n,Et as r,G as i,H as a,I as o,J as s,M as c,P as l,Q as u,St as d,Tt as f,W as p,X as m,Y as h,Z as g,_,_t as v,bt as y,dt as b,et as x,ft as S,i as C,j as w,lt as ee,m as T,n as E,o as te,rt as D,s as O,t as ne,tt as k,ut as re,v as A,wt as j,yt as ie}from"./Empty-CAGOJsfD.js";import{v as M,y as N}from"./mind-CBTkFje2.js";import{a as ae,b as oe,c as se,n as ce,o as le}from"./index-L0bHax8C.js";var P=[`aria-label`],F={class:`agenda-heading`},I={class:`eyebrow`},L=[`aria-label`],R=[`aria-pressed`],z=[`aria-pressed`],B={class:`muted`},V={class:`agenda-legend`},ue={class:`legend-actual`},de={class:`legend-plan`},H={class:`legend-free`},U={class:`legend-point`},W={class:`agenda-chart`},G={class:`agenda-axis`},fe={class:`agenda-lane`},pe={class:`lane-label`},me={class:`lane-track`},he=[`title`,`aria-label`,`onClick`],ge=[`title`],K={class:`agenda-lane`},q={class:`lane-label`},J={class:`lane-track`},_e=[`title`,`aria-label`,`onClick`],Y=[`title`],X={key:0,class:`agenda-history`},Z={class:`agenda-itinerary`},ve=[`onClick`],Q={key:1,class:`faint`},$={key:2,class:`faint`},ye={class:`agenda-itinerary`},be=[`data-kind`],xe=[`onClick`],Se={key:0,class:`muted`},Ce={key:2,class:`faint`},we={key:3,class:`faint`},Te={key:4,class:`agenda-waiting`,open:``},Ee=[`onClick`],De={class:`muted`},Oe={key:5,class:`agenda-waiting`,open:``},ke=[`onClick`],Ae={class:`muted`},je={key:6,class:`agenda-waiting`,open:``},Me=[`onClick`],Ne={class:`muted`},Pe=E(D({__name:`DayAgenda`,props:{agenda:{}},emits:[`task`],setup(e,{emit:t}){let a=e,l=t,p=d(!0),m=s(()=>{let e=a.agenda;if(!p.value)return[e.start,e.end];let t=Math.max(e.start,Math.min(e.end-216e5,Math.floor((e.now-e.start)/36e5)*36e5+e.start-36e5));return[t,Math.min(e.end,t+216e5)]}),_=e=>e===a.agenda.end?`24:00`:N(c(),{timeZone:a.agenda.zone,hour:`2-digit`,minute:`2-digit`,hourCycle:`h23`}).format(new Date(e)),v=e=>(e-m.value[0])/(m.value[1]-m.value[0])*100,y=e=>(e.chartEnd??e.end)>e.start&&(e.chartEnd??e.end)>m.value[0]&&e.start<m.value[1],C=e=>({left:Math.max(0,v(e.start))+`%`,width:Math.max(.3,Math.min(100,v(e.chartEnd??e.end))-Math.max(0,v(e.start)))+`%`}),w=s(()=>Array.from({length:7},(e,t)=>m.value[0]+(m.value[1]-m.value[0])*t/6)),ee=s(()=>a.agenda.planned.filter(e=>e.kind!==`sleep`).slice(0,18)),T=e=>`${_(e.start)} — ${_(e.end)} · ${e.title} · ${e.label||{rest:o(`休息建议`),free:o(`自由安排`),sleep:o(`作息安排`)}[e.kind]||o(`已发生`)}`,E=e=>e.engagedMs===null?o(`此前时长未单独记录`):o(`实际投入 {v} 分钟`,{v:Math.floor(e.engagedMs/6e4)});return(t,a)=>(b(),u(`section`,{class:`card day-agenda`,"aria-label":j(o)(`今日时间表`)},[h(`div`,F,[h(`div`,null,[h(`span`,I,n(e.agenda.date),1),h(`h2`,null,n(j(o)(`今日时间表`)),1)]),h(`div`,{class:`agenda-range`,role:`group`,"aria-label":j(o)(`时间表显示范围`)},[h(`button`,{"aria-pressed":p.value,onClick:a[0]||=e=>p.value=!0},n(j(o)(`此刻附近`)),9,R),h(`button`,{"aria-pressed":!p.value,onClick:a[1]||=e=>p.value=!1},n(j(o)(`全天`)),9,z)],8,L)]),h(`p`,B,n(e.agenda.note),1),h(`div`,V,[h(`span`,ue,n(j(o)(`实际时段`)),1),h(`span`,de,n(j(o)(`选定的安排`)),1),h(`span`,H,n(j(o)(`作息 / 空白`)),1),h(`span`,U,n(j(o)(`● 伴随交流`)),1)]),h(`div`,W,[h(`div`,G,[(b(!0),u(i,null,S(w.value,(e,t)=>(b(),u(`time`,{key:e,style:r({left:t*100/6+`%`})},n(_(e)),5))),128))]),h(`div`,fe,[h(`span`,pe,n(j(o)(`已发生`)),1),h(`div`,me,[(b(!0),u(i,null,S(w.value.slice(0,-1),(e,t)=>(b(),u(`i`,{key:e,class:`gridline`,style:r({left:t*100/6+`%`})},null,4))),128)),(b(!0),u(i,null,S(e.agenda.actual.filter(y),e=>(b(),u(`button`,{key:e.id,class:f([`agenda-block actual`,{ongoing:e.ongoing}]),style:r(C(e)),title:T(e)+` · `+E(e),"aria-label":T(e),onClick:t=>l(`task`,e.taskId)},null,14,he))),128)),(b(!0),u(i,null,S(e.agenda.interactions.filter(e=>e.at>=m.value[0]&&e.at<m.value[1]),e=>(b(),u(`span`,{key:e.id,class:`agenda-interaction`,style:r({left:v(e.at)+`%`}),title:_(e.at)+j(o)(` · 伴随交流`)},null,12,ge))),128)),v(e.agenda.now)>=0&&v(e.agenda.now)<=100?(b(),u(`span`,{key:0,class:`agenda-now`,style:r({left:v(e.agenda.now)+`%`})},[h(`small`,null,n(j(o)(`现在`)),1)],4)):g(``,!0)])]),h(`div`,K,[h(`span`,q,n(j(o)(`接下来`)),1),h(`div`,J,[(b(!0),u(i,null,S(w.value.slice(0,-1),(e,t)=>(b(),u(`i`,{key:e,class:`gridline`,style:r({left:t*100/6+`%`})},null,4))),128)),(b(!0),u(i,null,S(e.agenda.planned.filter(y),e=>(b(),u(i,{key:e.id},[e.taskId?(b(),u(`button`,{key:0,class:`agenda-block plan`,style:r(C(e)),title:T(e),"aria-label":T(e),onClick:t=>l(`task`,e.taskId)},null,12,_e)):(b(),u(`span`,{key:1,class:f([`agenda-block`,e.kind]),style:r(C(e)),title:T(e)},null,14,Y))],64))),128))])])]),e.agenda.actual.length?(b(),u(`details`,X,[h(`summary`,null,n(j(o)(`已经走过的时段 · {length} 段`,{length:e.agenda.actual.length})),1),h(`ol`,Z,[(b(!0),u(i,null,S(e.agenda.actual,e=>(b(),u(`li`,{key:e.id},[h(`time`,null,[x(n(_(e.start)),1),a[2]||=h(`br`,null,null,-1),x(n(_(e.end)),1)]),h(`div`,null,[h(`button`,{class:`text-button`,onClick:t=>l(`task`,e.taskId)},n(e.title),9,ve),h(`small`,null,n(e.label)+` · `+n(E(e)),1)])]))),128))])])):(b(),u(`p`,Q,n(j(o)(`今天还没有活动记录,实际开始后会显示在上方。`)),1)),h(`h3`,null,n(j(o)(`她定下的安排`)),1),ee.value.length?g(``,!0):(b(),u(`p`,$,n(j(o)(`还没有选定活动时间,留白由她再决定,不按待办队列填满。`)),1)),h(`ol`,ye,[(b(!0),u(i,null,S(ee.value,e=>(b(),u(`li`,{key:e.id,"data-kind":e.kind},[h(`time`,null,[x(n(_(e.start)),1),a[3]||=h(`br`,null,null,-1),x(n(_(e.end)),1)]),h(`div`,null,[e.taskId?(b(),u(i,{key:0},[h(`button`,{class:`text-button`,onClick:t=>l(`task`,e.taskId)},n(e.title),9,xe),h(`small`,null,n(j(o)(`{label} · {v} · {durationMinutes} 分钟 · {scope}`,{label:e.label,v:e.kindOfTask===`plan`?j(o)(`自己的安排`):e.kindOfTask===`promise`?j(o)(`答应的事`):j(o)(`外部建议`),durationMinutes:e.durationMinutes,scope:e.scope})),1),e.why?(b(),u(`p`,Se,n(e.why),1)):g(``,!0)],64)):(b(),u(i,{key:1},[h(`b`,null,n(e.title),1),h(`small`,null,n(e.kind===`free`?j(o)(`可以想自己的事,也可以歇着;不算已做过`):j(o)(`预计,做完眼前这段再调整`)),1)],64)),e.interruptedAt?(b(),u(`p`,Ce,n(_(e.interruptedAt))+` `+n(e.interruption===`sleep`?j(o)(`进入睡眠安排,醒来后再选择续接时间。`):j(o)(`有更高优先级安排,届时先让位,之后再选续接时间。`)),1)):g(``,!0)])],8,be))),128))]),e.agenda.planned.some(e=>e.kind===`sleep`)?(b(),u(`p`,we,n(j(o)(`睡眠安排:{v}`,{v:e.agenda.planned.filter(e=>e.kind===`sleep`).map(e=>_(e.start)+` — `+_(e.end)).join(`、`)})),1)):g(``,!0),e.agenda.unarranged?.length?(b(),u(`details`,Te,[h(`summary`,null,n(j(o)(`已记下,还没选时间 · {length} 件`,{length:e.agenda.unarranged.length})),1),h(`ul`,null,[(b(!0),u(i,null,S(e.agenda.unarranged,e=>(b(),u(`li`,{key:e.id},[h(`button`,{class:`text-button`,onClick:t=>l(`task`,e.id)},n(e.title),9,Ee),h(`p`,De,n(e.reason),1)]))),128))])])):g(``,!0),e.agenda.paused?.length?(b(),u(`details`,Oe,[h(`summary`,null,n(j(o)(`暂时停下来,进度保留 · {length} 件`,{length:e.agenda.paused.length})),1),h(`ul`,null,[(b(!0),u(i,null,S(e.agenda.paused,e=>(b(),u(`li`,{key:e.id},[h(`button`,{class:`text-button`,onClick:t=>l(`task`,e.id)},n(e.title),9,ke),h(`p`,Ae,n(e.reason),1)]))),128))])])):g(``,!0),e.agenda.waiting.length?(b(),u(`details`,je,[h(`summary`,null,n(j(o)(`需要条件或调整约定 · {length} 件`,{length:e.agenda.waiting.length})),1),h(`ul`,null,[(b(!0),u(i,null,S(e.agenda.waiting,e=>(b(),u(`li`,{key:e.id},[h(`button`,{class:`text-button`,onClick:t=>l(`task`,e.id)},n(e.title),9,Me),h(`p`,Ne,n(e.reason),1)]))),128))])])):g(``,!0)],8,P))}}),[[`__scopeId`,`data-v-10b48f6c`]]),Fe=[`aria-label`],Ie={class:`experience-intro`},Le={class:`eyebrow`},Re={class:`experience-date`},ze={class:`experience-timeline`},Be=[`data-experience`],Ve=[`datetime`],He={class:`card experience-card`},Ue={class:`experience-meta`},We={class:`experience-kind`},Ge={key:0,class:`faint`},Ke={key:0,class:`experience-summary`},qe={key:1,class:`faint experience-missing`},Je={key:2,class:`experience-project faint`},Ye={key:3,class:`experience-actions`},Xe=[`onClick`],Ze=[`onClick`],Qe={key:4,class:`experience-materials`},$e=[`onClick`],et={class:`experience-capability`},tt={class:`faint`},nt={class:`muted`},rt=E(D({__name:`ExperienceLog`,props:{rows:{},zone:{},loading:{type:Boolean}},emits:[`work`,`project`,`source`],setup(e,{emit:t}){let r=e,a=t,l=s(()=>{let e=N(c(),{timeZone:r.zone,year:`numeric`,month:`long`,day:`numeric`,weekday:`short`}),t=[];for(let n of r.rows){let r=e.format(n.created);t.at(-1)?.date!==r&&t.push({date:r,rows:[]}),t.at(-1).rows.push(n)}return t});function d(e){return N(c(),{timeZone:r.zone,hour:`2-digit`,minute:`2-digit`,hourCycle:`h23`}).format(e)}return(t,r)=>(b(),u(`section`,{class:`experience-log`,"aria-label":j(o)(`体验记录`)},[h(`header`,Ie,[h(`div`,null,[h(`span`,Le,n(j(o)(`EXPERIENCES · 留下的经历`)),1),h(`h1`,null,n(j(o)(`最近做过的事`)),1)]),h(`p`,null,n(j(o)(`故事写到哪里,玩过什么,又留下了哪些想法。`)),1)]),(b(!0),u(i,null,S(l.value,e=>(b(),u(`section`,{key:e.date,class:`experience-day`},[h(`h2`,Re,n(e.date),1),h(`div`,ze,[(b(!0),u(i,null,S(e.rows,e=>(b(),u(`article`,{key:e.id,class:`experience-entry`,"data-experience":e.id},[h(`time`,{class:`experience-clock`,datetime:new Date(e.created).toISOString()},n(d(e.created)),9,Ve),h(`div`,He,[h(`div`,Ue,[h(`span`,We,n(j(o)(`{label}记录`,{label:e.label})),1),e.work?(b(),u(`span`,Ge,n(j(o)(`{v} · {characters} 字 · 版本 {version}`,{v:e.work.state===`complete`?j(o)(`已保存成果`):j(o)(`已保存草稿`),characters:e.work.characters,version:e.work.version})),1)):g(``,!0)]),h(`h3`,null,n(e.title),1),e.summary?(b(),u(`p`,Ke,n(e.summary),1)):(b(),u(`p`,qe,n(j(o)(`这条旧记录没有保存摘要。`)),1)),e.project?.title&&e.project.title!==e.title?(b(),u(`p`,Je,n(j(o)(`来自 {title}`,{title:e.project.title})),1)):g(``,!0),e.work||e.project?(b(),u(`div`,Ye,[e.work?(b(),u(`button`,{key:0,onClick:t=>a(`work`,e.work.id,e.work.version)},[x(n(e.activity===`write`?j(o)(`阅读这一稿`):j(o)(`阅读完整记录`)),1),r[0]||=h(`span`,{"aria-hidden":`true`},` →`,-1)],8,Xe)):g(``,!0),e.project?(b(),u(`button`,{key:1,class:`text-button`,onClick:t=>a(`project`,e.project.id)},n(j(o)(`查看项目`)),9,Ze)):g(``,!0)])):g(``,!0),e.materials?.length?(b(),u(`details`,Qe,[h(`summary`,null,n(j(o)(`接触的内容 · {length} 份`,{length:e.materials.length})),1),h(`ul`,null,[(b(!0),u(i,null,S(e.materials,e=>(b(),u(`li`,{key:e.id},[h(`button`,{class:`text-button`,onClick:t=>a(`source`,e.id)},n(e.title||j(o)(`未命名资料`)),9,$e)]))),128))])])):g(``,!0)])],8,Be))),128))])]))),128)),!e.loading&&!e.rows.length?(b(),m(ne,{key:0,title:j(o)(`这里还没有经历记录`),text:j(o)(`做过的事与保存的成果,会逐渐出现在这里。`)},null,8,[`title`,`text`])):g(``,!0),h(`details`,et,[h(`summary`,null,[x(n(j(o)(`游戏客户端连接`))+` `,1),h(`span`,tt,n(j(o)(`开发中`)),1)]),h(`p`,nt,n(j(o)(`客户端控制尚未接入。已有的游玩记录可以在上方阅读。`)),1)])],8,Fe))}}),[[`__scopeId`,`data-v-400cba84`]]),it={class:`page time-page`},at={class:`time-intro`},ot={class:`eyebrow`},st={class:`time-clock`,"aria-hidden":`true`},ct={key:0,class:`card`,role:`alert`},lt={key:1,class:`muted`,role:`status`},ut={class:`time-today`},dt={class:`card main-activity`},ft={class:`eyebrow`},pt={class:`chip`},mt={key:0,class:`faint`},ht={key:1,class:`faint`},gt={class:`muted`},_t={class:`muted`},vt={key:0,class:`faint`},yt={class:`card day-balance`},bt={class:`eyebrow`},xt={class:`muted`},St={key:1,class:`card own-care`},Ct={class:`eyebrow`},wt={key:0,class:`muted`},Tt={key:1,class:`faint`},Et=[`disabled`],Dt={class:`card time-settings`},Ot=[`disabled`],kt={key:1},At={class:`sr-only`},jt=[`placeholder`],Mt={key:2},Nt={key:0,class:`time-cards`},Pt=[`data-task`],Ft={class:`row task-meta`},It=[`data-tone`],Lt={class:`faint`},Rt={class:`task-priority`},zt={key:0,class:`muted`},Bt={class:`faint`},Vt={key:1,class:`muted`},Ht={key:2,class:`share-status`},Ut={key:3,class:`muted`},Wt={class:`task-sources`},Gt={key:0,class:`faint`},Kt={class:`faint`},qt={key:1,class:`muted`},Jt={class:`row`},Yt=[`onClick`],Xt=[`onClick`],Zt=[`onClick`],Qt=[`onClick`],$t=[`onClick`],en=[`onClick`],tn={key:1,class:`time-cards work-grid`},nn=[`data-work`,`onClick`],rn={class:`eyebrow`},an={class:`faint`},on={key:2,class:`time-cards work-grid`},sn={class:`eyebrow`},cn={class:`muted`},ln=[`onClick`],un={class:`row time-pagination`},dn=[`disabled`],fn=[`disabled`],pn={class:`row`},mn={class:`chip`},hn={class:`work-body`},gn={class:`muted`},_n={key:0},vn={class:`row`},yn={class:`list`},bn=[`onClick`],xn={key:1},Sn={class:`list`},Cn=[`onClick`],wn=[`href`],Tn={key:1,class:`muted`},En={class:`faint`},Dn={class:`work-body`},On=E(D({__name:`TimePage`,setup(r){let c=[`today`,`tasks`,`works`,`projects`,`experiences`],f=d(c.includes(O.sub.split(`/`)[0])?O.sub.split(`/`)[0]:`today`),E=e(_(`/mind/time`)),D=e([]),N=d(!1),P=d(``),F=d(0),I=d(``),L=d(``),R=d(O.sub.split(`/`)[0]===`tasks`&&O.sub.split(`/`)[1]||``),z=e(null),B=e(null),V=e(null),ue=d(!1),de=d(!1),H=d(!1),U=d(!1),W=d({focusMinutes:25,breakMinutes:5,stepMinutes:5,paceSpeed:1.25,ownPlanMinutes:45,commitmentReviewMinutes:30}),G=s(()=>oe.data?.clock?.timeZone||`Asia/Shanghai`),fe=l({todo:w(`ToDo · 待办`),scheduled:w(`Scheduled · 已安排`),doing:w(`Doing · 正在做`),paused:w(`Paused · 暂停`),waiting:w(`Waiting · 等待`),done:w(`Done · 已完成`),abandoned:w(`Abandoned · 已放下`)}),pe=l({none:``,waiting:w(`完成,尚未交付`),deferred:w(`暂缓交付`),declined:w(`暂不分享`),pending:w(`待继续交付`),sent:w(`已完整交付`),reported:w(`已整理并汇报`),uncertain:w(`送达不确定,等待核对`),sending:w(`正在交付`)}),me=l({0:w(`低`),1:w(`普通`),2:w(`高`),3:w(`最高`)});function he(e){return e.state===`waiting`?e.waitKind===`adjust`?o(`需要调整约定`):e.waitKind===`specify`?o(`待想具体`):o(`Waiting · 等条件`):e.state===`todo`&&!e.schedule?.chosenAt?o(`ToDo · 待选时间`):e.state===`scheduled`?o(`Scheduled · 已选时间`):e.state===`paused`?o(`Paused · 进度保留`):fe[e.state]}async function ge(e,t){try{await T(`/mind/time/tasks/`+e.id+`/control`,`POST`,{action:`priority`,priority:t}),await Y()}catch(e){A(e.message,!0)}}let K=e=>o(`{v} 分钟`,{v:Math.floor((e||0)/6e4)}),q=e=>o(`{v} 分钟`,{v:Math.ceil((e||0)/6e4)}),J=0;function _e(){let e=new URLSearchParams({limit:`24`,offset:String(F.value)});return I.value&&e.set(`q`,I.value),f.value===`tasks`&&L.value&&e.set(`state`,L.value),f.value===`tasks`&&R.value&&e.set(`id`,R.value),`/mind/time/`+f.value+`?`+e}async function Y(){let e=++J,t=f.value===`today`?`/mind/time`:_e(),n=_(t);n&&(f.value===`today`?E.value=n:D.value=n),N.value=!n,P.value=``;try{let n=await T(t);if(e!==J)return;f.value===`today`?(E.value=n,H.value||(W.value={...n.settings})):(D.value=n,de.value=n.length===24)}catch(t){e===J&&(P.value=t.message)}finally{e===J&&(N.value=!1)}}async function X(e,t){ue.value=!0;try{z.value=await T(`/mind/time/works/`+encodeURIComponent(e)+(t?`?version=`+t:``)),B.value=null,V.value=null}catch(e){A(e.message,!0)}finally{ue.value=!1}}async function Z(e){try{let t=await T(`/mind/time/projects/`+e),[n,r]=await Promise.all([T(`/mind/time/works?project=`+e),T(`/mind/time/projects/`+e+`/sources`)]);B.value={...t,works:n,sources:r},z.value=null,V.value=null}catch(e){A(e.message,!0)}}async function ve(e){try{V.value=await T(`/mind/time/sources/`+e)}catch(e){A(e.message,!0)}}async function Q(e,n){let r,i;if(n===`schedule`){let n=await t(o(`最早开始时间(YYYY-MM-DD HH:mm)。截止时间保留原安排。`),{title:o(`安排时间`),confirmText:o(`继续`),placeholder:`2026-10-02 14:30`});if(n===null)return;r=n;let a=await t(o(`这次安排投入多少分钟(5 至 240)?`),{title:o(`投入时间`),confirmText:o(`继续`),placeholder:String(e.schedule?.durationMinutes||25)});if(a===null)return;i=Number(a)}let a=await t(o(n===`abandon`?`留下放下这件事的原因。`:`留下这次调整的原因。`),{title:o(`调整安排`),confirmText:o(`保存`),placeholder:o(`管理台调整`)});if(a!==null)try{await T(`/mind/time/tasks/`+e.id+`/control`,`POST`,{action:n,...r?{readyAt:r}:{},...i===void 0?{}:{durationMinutes:i},reason:a||o(`管理台调整`)}),await Y()}catch(e){A(e.message,!0)}}async function $(e){if(!B.value)return;let n=await t(o(`提出选题、续写方向或修改想法。她会自行决定是否采纳。`),{title:o(`给她一个建议`),confirmText:o(`留下建议`)});if(n!==null)try{let t=await T(`/mind/time/projects/`+B.value.id+`/suggest`,`POST`,{action:e,idea:n});A(t.duplicate?o(`这个项目已有待处理事项`):o(`建议已保存,等待她的选择`)),await Y()}catch(e){A(e.message,!0)}}async function ye(){if(!z.value)return;let e=z.value,t=new Blob([e.title+`
|
|
1
|
+
import{Ct as e,D as t,Dt as n,Et as r,G as i,H as a,I as o,J as s,M as c,P as l,Q as u,St as d,Tt as f,W as p,X as m,Y as h,Z as g,_,_t as v,bt as y,dt as b,et as x,ft as S,i as C,j as w,lt as ee,m as T,n as E,o as te,rt as D,s as O,t as ne,tt as k,ut as re,v as A,wt as j,yt as ie}from"./Empty-BSmsWoGM.js";import{v as M,y as N}from"./mind-CQkvddhx.js";import{a as ae,b as oe,c as se,n as ce,o as le}from"./index-BaXEYeFH.js";var P=[`aria-label`],F={class:`agenda-heading`},I={class:`eyebrow`},L=[`aria-label`],R=[`aria-pressed`],z=[`aria-pressed`],B={class:`muted`},V={class:`agenda-legend`},ue={class:`legend-actual`},de={class:`legend-plan`},H={class:`legend-free`},U={class:`legend-point`},W={class:`agenda-chart`},G={class:`agenda-axis`},fe={class:`agenda-lane`},pe={class:`lane-label`},me={class:`lane-track`},he=[`title`,`aria-label`,`onClick`],ge=[`title`],K={class:`agenda-lane`},q={class:`lane-label`},J={class:`lane-track`},_e=[`title`,`aria-label`,`onClick`],Y=[`title`],X={key:0,class:`agenda-history`},Z={class:`agenda-itinerary`},ve=[`onClick`],Q={key:1,class:`faint`},$={key:2,class:`faint`},ye={class:`agenda-itinerary`},be=[`data-kind`],xe=[`onClick`],Se={key:0,class:`muted`},Ce={key:2,class:`faint`},we={key:3,class:`faint`},Te={key:4,class:`agenda-waiting`,open:``},Ee=[`onClick`],De={class:`muted`},Oe={key:5,class:`agenda-waiting`,open:``},ke=[`onClick`],Ae={class:`muted`},je={key:6,class:`agenda-waiting`,open:``},Me=[`onClick`],Ne={class:`muted`},Pe=E(D({__name:`DayAgenda`,props:{agenda:{}},emits:[`task`],setup(e,{emit:t}){let a=e,l=t,p=d(!0),m=s(()=>{let e=a.agenda;if(!p.value)return[e.start,e.end];let t=Math.max(e.start,Math.min(e.end-216e5,Math.floor((e.now-e.start)/36e5)*36e5+e.start-36e5));return[t,Math.min(e.end,t+216e5)]}),_=e=>e===a.agenda.end?`24:00`:N(c(),{timeZone:a.agenda.zone,hour:`2-digit`,minute:`2-digit`,hourCycle:`h23`}).format(new Date(e)),v=e=>(e-m.value[0])/(m.value[1]-m.value[0])*100,y=e=>(e.chartEnd??e.end)>e.start&&(e.chartEnd??e.end)>m.value[0]&&e.start<m.value[1],C=e=>({left:Math.max(0,v(e.start))+`%`,width:Math.max(.3,Math.min(100,v(e.chartEnd??e.end))-Math.max(0,v(e.start)))+`%`}),w=s(()=>Array.from({length:7},(e,t)=>m.value[0]+(m.value[1]-m.value[0])*t/6)),ee=s(()=>a.agenda.planned.filter(e=>e.kind!==`sleep`).slice(0,18)),T=e=>`${_(e.start)} — ${_(e.end)} · ${e.title} · ${e.label||{rest:o(`休息建议`),free:o(`自由安排`),sleep:o(`作息安排`)}[e.kind]||o(`已发生`)}`,E=e=>e.engagedMs===null?o(`此前时长未单独记录`):o(`实际投入 {v} 分钟`,{v:Math.floor(e.engagedMs/6e4)});return(t,a)=>(b(),u(`section`,{class:`card day-agenda`,"aria-label":j(o)(`今日时间表`)},[h(`div`,F,[h(`div`,null,[h(`span`,I,n(e.agenda.date),1),h(`h2`,null,n(j(o)(`今日时间表`)),1)]),h(`div`,{class:`agenda-range`,role:`group`,"aria-label":j(o)(`时间表显示范围`)},[h(`button`,{"aria-pressed":p.value,onClick:a[0]||=e=>p.value=!0},n(j(o)(`此刻附近`)),9,R),h(`button`,{"aria-pressed":!p.value,onClick:a[1]||=e=>p.value=!1},n(j(o)(`全天`)),9,z)],8,L)]),h(`p`,B,n(e.agenda.note),1),h(`div`,V,[h(`span`,ue,n(j(o)(`实际时段`)),1),h(`span`,de,n(j(o)(`选定的安排`)),1),h(`span`,H,n(j(o)(`作息 / 空白`)),1),h(`span`,U,n(j(o)(`● 伴随交流`)),1)]),h(`div`,W,[h(`div`,G,[(b(!0),u(i,null,S(w.value,(e,t)=>(b(),u(`time`,{key:e,style:r({left:t*100/6+`%`})},n(_(e)),5))),128))]),h(`div`,fe,[h(`span`,pe,n(j(o)(`已发生`)),1),h(`div`,me,[(b(!0),u(i,null,S(w.value.slice(0,-1),(e,t)=>(b(),u(`i`,{key:e,class:`gridline`,style:r({left:t*100/6+`%`})},null,4))),128)),(b(!0),u(i,null,S(e.agenda.actual.filter(y),e=>(b(),u(`button`,{key:e.id,class:f([`agenda-block actual`,{ongoing:e.ongoing}]),style:r(C(e)),title:T(e)+` · `+E(e),"aria-label":T(e),onClick:t=>l(`task`,e.taskId)},null,14,he))),128)),(b(!0),u(i,null,S(e.agenda.interactions.filter(e=>e.at>=m.value[0]&&e.at<m.value[1]),e=>(b(),u(`span`,{key:e.id,class:`agenda-interaction`,style:r({left:v(e.at)+`%`}),title:_(e.at)+j(o)(` · 伴随交流`)},null,12,ge))),128)),v(e.agenda.now)>=0&&v(e.agenda.now)<=100?(b(),u(`span`,{key:0,class:`agenda-now`,style:r({left:v(e.agenda.now)+`%`})},[h(`small`,null,n(j(o)(`现在`)),1)],4)):g(``,!0)])]),h(`div`,K,[h(`span`,q,n(j(o)(`接下来`)),1),h(`div`,J,[(b(!0),u(i,null,S(w.value.slice(0,-1),(e,t)=>(b(),u(`i`,{key:e,class:`gridline`,style:r({left:t*100/6+`%`})},null,4))),128)),(b(!0),u(i,null,S(e.agenda.planned.filter(y),e=>(b(),u(i,{key:e.id},[e.taskId?(b(),u(`button`,{key:0,class:`agenda-block plan`,style:r(C(e)),title:T(e),"aria-label":T(e),onClick:t=>l(`task`,e.taskId)},null,12,_e)):(b(),u(`span`,{key:1,class:f([`agenda-block`,e.kind]),style:r(C(e)),title:T(e)},null,14,Y))],64))),128))])])]),e.agenda.actual.length?(b(),u(`details`,X,[h(`summary`,null,n(j(o)(`已经走过的时段 · {length} 段`,{length:e.agenda.actual.length})),1),h(`ol`,Z,[(b(!0),u(i,null,S(e.agenda.actual,e=>(b(),u(`li`,{key:e.id},[h(`time`,null,[x(n(_(e.start)),1),a[2]||=h(`br`,null,null,-1),x(n(_(e.end)),1)]),h(`div`,null,[h(`button`,{class:`text-button`,onClick:t=>l(`task`,e.taskId)},n(e.title),9,ve),h(`small`,null,n(e.label)+` · `+n(E(e)),1)])]))),128))])])):(b(),u(`p`,Q,n(j(o)(`今天还没有活动记录,实际开始后会显示在上方。`)),1)),h(`h3`,null,n(j(o)(`她定下的安排`)),1),ee.value.length?g(``,!0):(b(),u(`p`,$,n(j(o)(`还没有选定活动时间,留白由她再决定,不按待办队列填满。`)),1)),h(`ol`,ye,[(b(!0),u(i,null,S(ee.value,e=>(b(),u(`li`,{key:e.id,"data-kind":e.kind},[h(`time`,null,[x(n(_(e.start)),1),a[3]||=h(`br`,null,null,-1),x(n(_(e.end)),1)]),h(`div`,null,[e.taskId?(b(),u(i,{key:0},[h(`button`,{class:`text-button`,onClick:t=>l(`task`,e.taskId)},n(e.title),9,xe),h(`small`,null,n(j(o)(`{label} · {v} · {durationMinutes} 分钟 · {scope}`,{label:e.label,v:e.kindOfTask===`plan`?j(o)(`自己的安排`):e.kindOfTask===`promise`?j(o)(`答应的事`):j(o)(`外部建议`),durationMinutes:e.durationMinutes,scope:e.scope})),1),e.why?(b(),u(`p`,Se,n(e.why),1)):g(``,!0)],64)):(b(),u(i,{key:1},[h(`b`,null,n(e.title),1),h(`small`,null,n(e.kind===`free`?j(o)(`可以想自己的事,也可以歇着;不算已做过`):j(o)(`预计,做完眼前这段再调整`)),1)],64)),e.interruptedAt?(b(),u(`p`,Ce,n(_(e.interruptedAt))+` `+n(e.interruption===`sleep`?j(o)(`进入睡眠安排,醒来后再选择续接时间。`):j(o)(`有更高优先级安排,届时先让位,之后再选续接时间。`)),1)):g(``,!0)])],8,be))),128))]),e.agenda.planned.some(e=>e.kind===`sleep`)?(b(),u(`p`,we,n(j(o)(`睡眠安排:{v}`,{v:e.agenda.planned.filter(e=>e.kind===`sleep`).map(e=>_(e.start)+` — `+_(e.end)).join(`、`)})),1)):g(``,!0),e.agenda.unarranged?.length?(b(),u(`details`,Te,[h(`summary`,null,n(j(o)(`已记下,还没选时间 · {length} 件`,{length:e.agenda.unarranged.length})),1),h(`ul`,null,[(b(!0),u(i,null,S(e.agenda.unarranged,e=>(b(),u(`li`,{key:e.id},[h(`button`,{class:`text-button`,onClick:t=>l(`task`,e.id)},n(e.title),9,Ee),h(`p`,De,n(e.reason),1)]))),128))])])):g(``,!0),e.agenda.paused?.length?(b(),u(`details`,Oe,[h(`summary`,null,n(j(o)(`暂时停下来,进度保留 · {length} 件`,{length:e.agenda.paused.length})),1),h(`ul`,null,[(b(!0),u(i,null,S(e.agenda.paused,e=>(b(),u(`li`,{key:e.id},[h(`button`,{class:`text-button`,onClick:t=>l(`task`,e.id)},n(e.title),9,ke),h(`p`,Ae,n(e.reason),1)]))),128))])])):g(``,!0),e.agenda.waiting.length?(b(),u(`details`,je,[h(`summary`,null,n(j(o)(`需要条件或调整约定 · {length} 件`,{length:e.agenda.waiting.length})),1),h(`ul`,null,[(b(!0),u(i,null,S(e.agenda.waiting,e=>(b(),u(`li`,{key:e.id},[h(`button`,{class:`text-button`,onClick:t=>l(`task`,e.id)},n(e.title),9,Me),h(`p`,Ne,n(e.reason),1)]))),128))])])):g(``,!0)],8,P))}}),[[`__scopeId`,`data-v-10b48f6c`]]),Fe=[`aria-label`],Ie={class:`experience-intro`},Le={class:`eyebrow`},Re={class:`experience-date`},ze={class:`experience-timeline`},Be=[`data-experience`],Ve=[`datetime`],He={class:`card experience-card`},Ue={class:`experience-meta`},We={class:`experience-kind`},Ge={key:0,class:`faint`},Ke={key:0,class:`experience-summary`},qe={key:1,class:`faint experience-missing`},Je={key:2,class:`experience-project faint`},Ye={key:3,class:`experience-actions`},Xe=[`onClick`],Ze=[`onClick`],Qe={key:4,class:`experience-materials`},$e=[`onClick`],et={class:`experience-capability`},tt={class:`faint`},nt={class:`muted`},rt=E(D({__name:`ExperienceLog`,props:{rows:{},zone:{},loading:{type:Boolean}},emits:[`work`,`project`,`source`],setup(e,{emit:t}){let r=e,a=t,l=s(()=>{let e=N(c(),{timeZone:r.zone,year:`numeric`,month:`long`,day:`numeric`,weekday:`short`}),t=[];for(let n of r.rows){let r=e.format(n.created);t.at(-1)?.date!==r&&t.push({date:r,rows:[]}),t.at(-1).rows.push(n)}return t});function d(e){return N(c(),{timeZone:r.zone,hour:`2-digit`,minute:`2-digit`,hourCycle:`h23`}).format(e)}return(t,r)=>(b(),u(`section`,{class:`experience-log`,"aria-label":j(o)(`体验记录`)},[h(`header`,Ie,[h(`div`,null,[h(`span`,Le,n(j(o)(`EXPERIENCES · 留下的经历`)),1),h(`h1`,null,n(j(o)(`最近做过的事`)),1)]),h(`p`,null,n(j(o)(`故事写到哪里,玩过什么,又留下了哪些想法。`)),1)]),(b(!0),u(i,null,S(l.value,e=>(b(),u(`section`,{key:e.date,class:`experience-day`},[h(`h2`,Re,n(e.date),1),h(`div`,ze,[(b(!0),u(i,null,S(e.rows,e=>(b(),u(`article`,{key:e.id,class:`experience-entry`,"data-experience":e.id},[h(`time`,{class:`experience-clock`,datetime:new Date(e.created).toISOString()},n(d(e.created)),9,Ve),h(`div`,He,[h(`div`,Ue,[h(`span`,We,n(j(o)(`{label}记录`,{label:e.label})),1),e.work?(b(),u(`span`,Ge,n(j(o)(`{v} · {characters} 字 · 版本 {version}`,{v:e.work.state===`complete`?j(o)(`已保存成果`):j(o)(`已保存草稿`),characters:e.work.characters,version:e.work.version})),1)):g(``,!0)]),h(`h3`,null,n(e.title),1),e.summary?(b(),u(`p`,Ke,n(e.summary),1)):(b(),u(`p`,qe,n(j(o)(`这条旧记录没有保存摘要。`)),1)),e.project?.title&&e.project.title!==e.title?(b(),u(`p`,Je,n(j(o)(`来自 {title}`,{title:e.project.title})),1)):g(``,!0),e.work||e.project?(b(),u(`div`,Ye,[e.work?(b(),u(`button`,{key:0,onClick:t=>a(`work`,e.work.id,e.work.version)},[x(n(e.activity===`write`?j(o)(`阅读这一稿`):j(o)(`阅读完整记录`)),1),r[0]||=h(`span`,{"aria-hidden":`true`},` →`,-1)],8,Xe)):g(``,!0),e.project?(b(),u(`button`,{key:1,class:`text-button`,onClick:t=>a(`project`,e.project.id)},n(j(o)(`查看项目`)),9,Ze)):g(``,!0)])):g(``,!0),e.materials?.length?(b(),u(`details`,Qe,[h(`summary`,null,n(j(o)(`接触的内容 · {length} 份`,{length:e.materials.length})),1),h(`ul`,null,[(b(!0),u(i,null,S(e.materials,e=>(b(),u(`li`,{key:e.id},[h(`button`,{class:`text-button`,onClick:t=>a(`source`,e.id)},n(e.title||j(o)(`未命名资料`)),9,$e)]))),128))])])):g(``,!0)])],8,Be))),128))])]))),128)),!e.loading&&!e.rows.length?(b(),m(ne,{key:0,title:j(o)(`这里还没有经历记录`),text:j(o)(`做过的事与保存的成果,会逐渐出现在这里。`)},null,8,[`title`,`text`])):g(``,!0),h(`details`,et,[h(`summary`,null,[x(n(j(o)(`游戏客户端连接`))+` `,1),h(`span`,tt,n(j(o)(`开发中`)),1)]),h(`p`,nt,n(j(o)(`客户端控制尚未接入。已有的游玩记录可以在上方阅读。`)),1)])],8,Fe))}}),[[`__scopeId`,`data-v-400cba84`]]),it={class:`page time-page`},at={class:`time-intro`},ot={class:`eyebrow`},st={class:`time-clock`,"aria-hidden":`true`},ct={key:0,class:`card`,role:`alert`},lt={key:1,class:`muted`,role:`status`},ut={class:`time-today`},dt={class:`card main-activity`},ft={class:`eyebrow`},pt={class:`chip`},mt={key:0,class:`faint`},ht={key:1,class:`faint`},gt={class:`muted`},_t={class:`muted`},vt={key:0,class:`faint`},yt={class:`card day-balance`},bt={class:`eyebrow`},xt={class:`muted`},St={key:1,class:`card own-care`},Ct={class:`eyebrow`},wt={key:0,class:`muted`},Tt={key:1,class:`faint`},Et=[`disabled`],Dt={class:`card time-settings`},Ot=[`disabled`],kt={key:1},At={class:`sr-only`},jt=[`placeholder`],Mt={key:2},Nt={key:0,class:`time-cards`},Pt=[`data-task`],Ft={class:`row task-meta`},It=[`data-tone`],Lt={class:`faint`},Rt={class:`task-priority`},zt={key:0,class:`muted`},Bt={class:`faint`},Vt={key:1,class:`muted`},Ht={key:2,class:`share-status`},Ut={key:3,class:`muted`},Wt={class:`task-sources`},Gt={key:0,class:`faint`},Kt={class:`faint`},qt={key:1,class:`muted`},Jt={class:`row`},Yt=[`onClick`],Xt=[`onClick`],Zt=[`onClick`],Qt=[`onClick`],$t=[`onClick`],en=[`onClick`],tn={key:1,class:`time-cards work-grid`},nn=[`data-work`,`onClick`],rn={class:`eyebrow`},an={class:`faint`},on={key:2,class:`time-cards work-grid`},sn={class:`eyebrow`},cn={class:`muted`},ln=[`onClick`],un={class:`row time-pagination`},dn=[`disabled`],fn=[`disabled`],pn={class:`row`},mn={class:`chip`},hn={class:`work-body`},gn={class:`muted`},_n={key:0},vn={class:`row`},yn={class:`list`},bn=[`onClick`],xn={key:1},Sn={class:`list`},Cn=[`onClick`],wn=[`href`],Tn={key:1,class:`muted`},En={class:`faint`},Dn={class:`work-body`},On=E(D({__name:`TimePage`,setup(r){let c=[`today`,`tasks`,`works`,`projects`,`experiences`],f=d(c.includes(O.sub.split(`/`)[0])?O.sub.split(`/`)[0]:`today`),E=e(_(`/mind/time`)),D=e([]),N=d(!1),P=d(``),F=d(0),I=d(``),L=d(``),R=d(O.sub.split(`/`)[0]===`tasks`&&O.sub.split(`/`)[1]||``),z=e(null),B=e(null),V=e(null),ue=d(!1),de=d(!1),H=d(!1),U=d(!1),W=d({focusMinutes:25,breakMinutes:5,stepMinutes:5,paceSpeed:1.25,ownPlanMinutes:45,commitmentReviewMinutes:30}),G=s(()=>oe.data?.clock?.timeZone||`Asia/Shanghai`),fe=l({todo:w(`ToDo · 待办`),scheduled:w(`Scheduled · 已安排`),doing:w(`Doing · 正在做`),paused:w(`Paused · 暂停`),waiting:w(`Waiting · 等待`),done:w(`Done · 已完成`),abandoned:w(`Abandoned · 已放下`)}),pe=l({none:``,waiting:w(`完成,尚未交付`),deferred:w(`暂缓交付`),declined:w(`暂不分享`),pending:w(`待继续交付`),sent:w(`已完整交付`),reported:w(`已整理并汇报`),uncertain:w(`送达不确定,等待核对`),sending:w(`正在交付`)}),me=l({0:w(`低`),1:w(`普通`),2:w(`高`),3:w(`最高`)});function he(e){return e.state===`waiting`?e.waitKind===`adjust`?o(`需要调整约定`):e.waitKind===`specify`?o(`待想具体`):o(`Waiting · 等条件`):e.state===`todo`&&!e.schedule?.chosenAt?o(`ToDo · 待选时间`):e.state===`scheduled`?o(`Scheduled · 已选时间`):e.state===`paused`?o(`Paused · 进度保留`):fe[e.state]}async function ge(e,t){try{await T(`/mind/time/tasks/`+e.id+`/control`,`POST`,{action:`priority`,priority:t}),await Y()}catch(e){A(e.message,!0)}}let K=e=>o(`{v} 分钟`,{v:Math.floor((e||0)/6e4)}),q=e=>o(`{v} 分钟`,{v:Math.ceil((e||0)/6e4)}),J=0;function _e(){let e=new URLSearchParams({limit:`24`,offset:String(F.value)});return I.value&&e.set(`q`,I.value),f.value===`tasks`&&L.value&&e.set(`state`,L.value),f.value===`tasks`&&R.value&&e.set(`id`,R.value),`/mind/time/`+f.value+`?`+e}async function Y(){let e=++J,t=f.value===`today`?`/mind/time`:_e(),n=_(t);n&&(f.value===`today`?E.value=n:D.value=n),N.value=!n,P.value=``;try{let n=await T(t);if(e!==J)return;f.value===`today`?(E.value=n,H.value||(W.value={...n.settings})):(D.value=n,de.value=n.length===24)}catch(t){e===J&&(P.value=t.message)}finally{e===J&&(N.value=!1)}}async function X(e,t){ue.value=!0;try{z.value=await T(`/mind/time/works/`+encodeURIComponent(e)+(t?`?version=`+t:``)),B.value=null,V.value=null}catch(e){A(e.message,!0)}finally{ue.value=!1}}async function Z(e){try{let t=await T(`/mind/time/projects/`+e),[n,r]=await Promise.all([T(`/mind/time/works?project=`+e),T(`/mind/time/projects/`+e+`/sources`)]);B.value={...t,works:n,sources:r},z.value=null,V.value=null}catch(e){A(e.message,!0)}}async function ve(e){try{V.value=await T(`/mind/time/sources/`+e)}catch(e){A(e.message,!0)}}async function Q(e,n){let r,i;if(n===`schedule`){let n=await t(o(`最早开始时间(YYYY-MM-DD HH:mm)。截止时间保留原安排。`),{title:o(`安排时间`),confirmText:o(`继续`),placeholder:`2026-10-02 14:30`});if(n===null)return;r=n;let a=await t(o(`这次安排投入多少分钟(5 至 240)?`),{title:o(`投入时间`),confirmText:o(`继续`),placeholder:String(e.schedule?.durationMinutes||25)});if(a===null)return;i=Number(a)}let a=await t(o(n===`abandon`?`留下放下这件事的原因。`:`留下这次调整的原因。`),{title:o(`调整安排`),confirmText:o(`保存`),placeholder:o(`管理台调整`)});if(a!==null)try{await T(`/mind/time/tasks/`+e.id+`/control`,`POST`,{action:n,...r?{readyAt:r}:{},...i===void 0?{}:{durationMinutes:i},reason:a||o(`管理台调整`)}),await Y()}catch(e){A(e.message,!0)}}async function $(e){if(!B.value)return;let n=await t(o(`提出选题、续写方向或修改想法。她会自行决定是否采纳。`),{title:o(`给她一个建议`),confirmText:o(`留下建议`)});if(n!==null)try{let t=await T(`/mind/time/projects/`+B.value.id+`/suggest`,`POST`,{action:e,idea:n});A(t.duplicate?o(`这个项目已有待处理事项`):o(`建议已保存,等待她的选择`)),await Y()}catch(e){A(e.message,!0)}}async function ye(){if(!z.value)return;let e=z.value,t=new Blob([e.title+`
|
|
2
2
|
|
|
3
3
|
`+e.content],{type:`text/plain;charset=utf-8`}),n=URL.createObjectURL(t),r=document.createElement(`a`);r.href=n,r.download=e.title.replace(/[\\/:*?"<>|]/g,`_`)+`-v`+e.version+`.txt`,r.click(),URL.revokeObjectURL(n)}async function be(){if(!U.value){U.value=!0,J++;try{let e=await T(`/mind/time/settings`,`PUT`,{...W.value});J++,W.value=e,H.value=!1,A(o(`专注安排已保存`)),await Y()}catch(e){A(e.message,!0)}finally{U.value=!1}}}function xe(e){R.value=e,f.value===`tasks`?Y():f.value=`tasks`,te(`tasks/`+e)}async function Se(){try{await T(`/mind/time/care`,`POST`,{}),A(o(`已记下,空下来时回看说过的话`)),await Y()}catch(e){A(e.message,!0)}}async function Ce(){try{await T(`/mind/time/plan`,`POST`,{}),A(o(`已记下,让她重新想具体时间与投入时长`)),await Y()}catch(e){A(e.message,!0)}}function we(){F.value=0,Y()}v(f,e=>{O.page===`time`&&(F.value=0,D.value=[],I.value=``,L.value=``,e!==`tasks`&&(R.value=``),te(e===`today`?``:e===`tasks`&&R.value?`tasks/`+R.value:e===`works`&&O.sub.startsWith(`works/`)?O.sub:e),Y())}),v(()=>[O.page,O.sub],([e,t])=>{if(e!==`time`)return;let n=t.split(`/`)[0]||`today`;if(n===`tasks`){let e=t.split(`/`)[1]||``;R.value!==e&&(R.value=e,f.value===`tasks`&&Y())}c.includes(n)&&(f.value=n),n===`works`&&t.split(`/`)[1]&&z.value?.id!==t.split(`/`)[1]&&X(t.split(`/`)[1])});let Te=ae(`time`,Y),Ee=0;return ee(()=>{Ee=window.setInterval(()=>{Te.value&&f.value===`today`&&!document.hidden&&Y()},5e3);let e=O.sub.split(`/`)[1];e&&f.value===`works`&&X(e)}),re(()=>{clearInterval(Ee),J++}),(e,t)=>(b(),u(`div`,it,[h(`header`,at,[h(`div`,null,[h(`span`,ot,n(j(o)(`TIME · 时间`)),1),h(`h1`,null,[x(n(j(o)(`日子在走,`)),1),h(`em`,null,n(j(o)(`我也有自己的事。`)),1)]),h(`p`,null,n(j(o)(`想做的事,正在留下的作品,与世界相遇的每一段。`)),1)]),h(`div`,st,[t[24]||=h(`span`,null,`25`,-1),h(`small`,null,n(j(o)(`留一点时间给自己`)),1)])]),k(ce,{modelValue:f.value,"onUpdate:modelValue":t[0]||=e=>f.value=e,label:j(o)(`时间的分区`),items:[{key:`today`,label:j(o)(`今日`)},{key:`tasks`,label:j(o)(`待办`)},{key:`works`,label:j(o)(`作品库`)},{key:`projects`,label:j(o)(`持续项目`)},{key:`experiences`,label:j(o)(`体验记录`)}]},null,8,[`modelValue`,`label`,`items`]),P.value?(b(),u(`p`,ct,[x(n(P.value)+` `,1),h(`button`,{onClick:Y},n(j(o)(`重试`)),1)])):g(``,!0),N.value?(b(),u(`p`,lt,n(j(o)(`正在取回这段生活…`)),1)):g(``,!0),f.value===`today`&&E.value?(b(),u(i,{key:2},[h(`section`,ut,[h(`article`,dt,[h(`span`,ft,n(j(o)(`此刻的主活动`)),1),E.value.current?(b(),u(i,{key:0},[h(`h2`,null,n(E.value.current.title||E.value.current.label),1),h(`span`,pt,n(E.value.current.label)+` · `+n(E.value.current.timing?.phase===`preparing`?j(o)(`正在准备`):(E.value.current.sessionElapsedMs??E.value.current.elapsedMs)<6e4?j(o)(`刚开始这一段`):j(o)(`本次已投入 `)+K(E.value.current.sessionElapsedMs??E.value.current.elapsedMs)),1),E.value.current.schedule?.chosenAt?(b(),u(`p`,mt,n(j(o)(`她安排 {v} 开始,这次想投入 {durationMinutes} 分钟。`,{v:j(M)(E.value.current.schedule.proposedAt,G.value),durationMinutes:E.value.current.schedule.durationMinutes})),1)):g(``,!0),E.value.current.timing?.plannedMs?(b(),u(`p`,ht,n(j(o)(`本段预计 {v} · 还需约 {v2}`,{v:q(E.value.current.timing.plannedMs),v2:q(E.value.current.timing.remainingMs)})),1)):g(``,!0),h(`p`,null,n(E.value.current.why||j(o)(`从自己的打算接着做。`)),1),h(`p`,gt,n(E.value.current.checkpoint?.next||j(o)(`正在推进当前步骤。`)),1),h(`button`,{class:`text-button`,onClick:t[1]||=e=>f.value=`tasks`},n(j(o)(`查看安排 →`)),1)],64)):(b(),u(i,{key:1},[h(`h2`,null,n(E.value.agenda?.idle?.title||j(o)(`这会儿没有主活动`)),1),h(`p`,_t,n(E.value.agenda?.idle?.reason||j(o)(`自己选择接下来做什么,也可以歇着。`)),1),E.value.agenda?.idle?.next?(b(),u(`p`,vt,n(j(o)(`下一项:{title} · {v} 开始 · {durationMinutes} 分钟`,{title:E.value.agenda.idle.next.title,v:j(M)(E.value.agenda.idle.next.chosenStart,G.value),durationMinutes:E.value.agenda.idle.next.durationMinutes})),1)):g(``,!0),h(`button`,{class:`text-button`,onClick:Ce},n(j(o)(`让她重新想想安排`)),1)],64))]),h(`article`,yt,[h(`span`,bt,n(j(o)(`今天`)),1),h(`h2`,null,n(K(E.value.today?.activeMs)),1),h(`p`,null,n(j(o)(`实际活动投入 · {energyLabel} · {mood}`,{energyLabel:E.value.affect?.energyLabel,mood:E.value.affect?.mood})),1),h(`p`,xt,n(j(o)(`普通交流可以伴随进行,短消息不会自动暂停。`)),1),h(`button`,{class:`text-button`,onClick:t[2]||=e=>j(C)(`life`)},n(j(o)(`翻开日记 →`)),1)])]),E.value.agenda?(b(),m(Pe,{key:0,agenda:E.value.agenda,onTask:xe},null,8,[`agenda`])):g(``,!0),E.value.care?(b(),u(`section`,St,[h(`span`,Ct,n(j(o)(`独处时理一理`)),1),h(`h2`,null,n(j(o)(`自己的打算,说过的约定`)),1),h(`p`,null,n(j(o)(`空下来时,她会想一件自己愿意做的小事,也会回看有没有漏下答应别人的事。可以选择歇着。`)),1),E.value.care.last?(b(),u(`p`,wt,[x(n(j(o)(`最近:{reason}`,{reason:E.value.care.last.reason})),1),E.value.care.last.finished?(b(),u(i,{key:0},[x(` · `+n(j(M)(E.value.care.last.finished,G.value)),1)],64)):g(``,!0)])):g(``,!0),E.value.care.pendingReplies?(b(),u(`p`,Tt,n(j(o)(`还有 {pendingReplies} 条已说过的话等着分批回看。`,{pendingReplies:E.value.care.pendingReplies})),1)):g(``,!0),h(`button`,{disabled:E.value.care.queued||!!E.value.care.working,onClick:Se},n(E.value.care.working?j(o)(`正在整理自己的生活`):E.value.care.queued?j(o)(`已记下,空下来时整理`):j(o)(`空下来整理一下约定`)),9,Et)])):g(``,!0),h(`details`,Dt,[h(`summary`,null,n(j(o)(`专注与休息安排`)),1),h(`form`,{onSubmit:p(be,[`prevent`]),onInput:t[9]||=e=>H.value=!0,onChange:t[10]||=e=>H.value=!0},[h(`label`,null,[x(n(j(o)(`默认专注段(分钟)`)),1),y(h(`input`,{"onUpdate:modelValue":t[3]||=e=>W.value.focusMinutes=e,type:`number`,min:`1`,max:`120`},null,512),[[a,W.value.focusMinutes,void 0,{number:!0}]]),h(`small`,null,n(j(o)(`没有另行选择时使用;她自己的安排优先。`)),1)]),h(`label`,null,[x(n(j(o)(`休息建议(分钟)`)),1),y(h(`input`,{"onUpdate:modelValue":t[4]||=e=>W.value.breakMinutes=e,type:`number`,min:`1`,max:`120`},null,512),[[a,W.value.breakMinutes,void 0,{number:!0}]])]),h(`label`,null,[x(n(j(o)(`保存步骤间隔(分钟)`)),1),y(h(`input`,{"onUpdate:modelValue":t[5]||=e=>W.value.stepMinutes=e,type:`number`,min:`1`,max:`120`},null,512),[[a,W.value.stepMinutes,void 0,{number:!0}]])]),h(`label`,null,[x(n(j(o)(`活动节奏`)),1),y(h(`input`,{"onUpdate:modelValue":t[6]||=e=>W.value.paceSpeed=e,type:`number`,min:`1`,max:`2`,step:`0.05`},null,512),[[a,W.value.paceSpeed,void 0,{number:!0}]]),h(`small`,null,n(j(o)(`默认 1.25 倍,所有活动按现实时间逐段推进。`)),1)]),h(`label`,null,[x(n(j(o)(`想自己的安排(间隔分钟)`)),1),y(h(`input`,{"onUpdate:modelValue":t[7]||=e=>W.value.ownPlanMinutes=e,type:`number`,min:`1`,max:`120`},null,512),[[a,W.value.ownPlanMinutes,void 0,{number:!0}]]),h(`small`,null,n(j(o)(`有空才考虑,可以决定休息。`)),1)]),h(`label`,null,[x(n(j(o)(`回看说过的话(间隔分钟)`)),1),y(h(`input`,{"onUpdate:modelValue":t[8]||=e=>W.value.commitmentReviewMinutes=e,type:`number`,min:`1`,max:`120`},null,512),[[a,W.value.commitmentReviewMinutes,void 0,{number:!0}]]),h(`small`,null,n(j(o)(`分批整理约定,保留去重与原来的选择。`)),1)]),h(`button`,{class:`primary`,disabled:U.value},n(U.value?j(o)(`正在保存`):j(o)(`保存安排`)),9,Ot)],32)])],64)):f.value===`today`?g(``,!0):(b(),u(i,{key:3},[h(`form`,{class:`time-filter`,onSubmit:p(we,[`prevent`])},[f.value===`tasks`&&R.value?(b(),u(`button`,{key:0,type:`button`,onClick:t[11]||=e=>{R.value=``,j(te)(`tasks`),Y()}},n(j(o)(`查看全部待办`)),1)):g(``,!0),[`works`,`projects`,`experiences`].includes(f.value)?(b(),u(`label`,kt,[h(`span`,At,n(j(o)(`搜索标题`)),1),y(h(`input`,{"onUpdate:modelValue":t[12]||=e=>I.value=e,placeholder:j(o)(`搜索标题或项目`)},null,8,jt),[[a,I.value]]),h(`button`,null,n(j(o)(`搜索`)),1)])):g(``,!0),f.value===`tasks`?(b(),u(`label`,Mt,[x(n(j(o)(`任务状态`)),1),k(se,{modelValue:L.value,"onUpdate:modelValue":t[13]||=e=>L.value=e,"aria-label":j(o)(`任务状态`),options:[{value:``,label:j(o)(`全部`)},...Object.entries(j(fe)).map(([e,t])=>({value:e,label:t}))],onChange:we},null,8,[`modelValue`,`aria-label`,`options`])])):g(``,!0)],32),f.value===`tasks`?(b(),u(`div`,Nt,[(b(!0),u(i,null,S(D.value,e=>(b(),u(`article`,{key:e.id,class:`card time-task`,"data-task":e.id},[h(`div`,Ft,[h(`span`,{class:`chip`,"data-tone":e.state===`done`?`ok`:`quiet`},n(he(e)),9,It),h(`span`,Lt,n(e.kind===`promise`?j(o)(`答应的事`):e.kind===`suggestion`?j(o)(`外部建议`):j(o)(`自己的计划`))+n(e.person?` · `+e.person:``),1),h(`label`,Rt,[h(`span`,null,n(j(o)(`优先级`)),1),k(se,{"model-value":e.priority,"aria-label":j(o)(`优先级:`)+e.title,options:Object.entries(j(me)).map(([e,t])=>({value:e,label:t})),disabled:!!e.checkpoint?.mergedInto,"onUpdate:modelValue":t=>ge(e,Number(t))},null,8,[`model-value`,`aria-label`,`options`,`disabled`,`onUpdate:modelValue`])])]),h(`h2`,null,n(e.title),1),h(`p`,null,n(e.why),1),e.wait_reason?(b(),u(`p`,zt,n(e.wait_reason),1)):g(``,!0),h(`p`,Bt,[e.schedule?.chosenAt&&!e.checkpoint?.reschedule?(b(),u(i,{key:0},[x(n(j(o)(`{v} {v2} — {v3} · 这次 {durationMinutes} 分钟`,{v:e.schedule.chosenBy===`admin`?j(o)(`管理台安排`):j(o)(`她选定`),v2:j(M)(e.schedule.proposedAt,G.value),v3:j(M)(e.schedule.proposedEnd,G.value),durationMinutes:e.schedule.durationMinutes})),1)],64)):e.schedule?.startedAt?(b(),u(i,{key:1},[x(n(j(o)(`本段开始 {v}`,{v:j(M)(e.schedule.startedAt,G.value)})),1)],64)):e.schedule?.proposedAt?(b(),u(i,{key:2},[x(n(e.schedule.conditional?j(o)(`条件满足后建议`):j(o)(`已安排`))+` `+n(j(M)(e.schedule.proposedAt,G.value))+` — `+n(j(M)(e.schedule.proposedEnd,G.value)),1)],64)):(b(),u(i,{key:3},[x(n(e.state===`waiting`?j(o)(`需要解决上面的条件,再选择时间`):e.state===`paused`?j(o)(`进度已保存,之后再安排续接时间`):j(o)(`已记下,等她选择具体时间`)),1)],64)),e.timing?.plannedMs?(b(),u(i,{key:4},[x(n(j(o)(`· 本段预计 {v} · 本段已投入 {v2}`,{v:q(e.timing.plannedMs),v2:K(e.timing.stepMs)})),1),e.timing.phase===`engaged`?(b(),u(i,{key:0},[x(n(j(o)(`· 还需约 {v}`,{v:q(e.timing.remainingMs)})),1)],64)):g(``,!0)],64)):e.timing?.phase===`legacy`?(b(),u(i,{key:5},[x(n(j(o)(`· 此前时长未单独记录`)),1)],64)):(b(),u(i,{key:6},[x(` · `+n(e.state===`doing`?j(o)(`正在准备这一段`):j(o)(`尚未开始本段投入`)),1)],64))]),e.schedule?.outcome?(b(),u(`p`,Vt,n(j(o)(`本段目标:{outcome}`,{outcome:e.schedule.outcome})),1)):g(``,!0),j(pe)[e.share_state]?(b(),u(`p`,Ht,n(j(pe)[e.share_state])+` `+n(e.share_reason),1)):g(``,!0),e.checkpoint?.next?(b(),u(`p`,Ut,n(j(o)(`下一步:{next}`,{next:e.checkpoint.next})),1)):g(``,!0),h(`details`,Wt,[h(`summary`,null,n(j(o)(`来源与原安排 · {length} 条`,{length:e.sources.length})),1),e.due_at?(b(),u(`p`,Gt,n(j(o)(`原话日期参考 {v},不作为逾期判断。`,{v:j(M)(e.due_at,G.value)})),1)):g(``,!0),h(`small`,Kt,n(e.sources.join(` · `)),1),e.checkpoint?.mergedInto?(b(),u(`p`,qt,n(j(o)(`已合并到唯一事项,保留这条原记录。`)),1)):g(``,!0)]),h(`div`,Jt,[e.work_id?(b(),u(`button`,{key:0,onClick:t=>X(e.work_id)},n(j(o)(`阅读已有正文`)),9,Yt)):g(``,!0),e.project_id?(b(),u(`button`,{key:1,onClick:t=>Z(e.project_id)},n(j(o)(`持续项目`)),9,Xt)):g(``,!0),[`done`,`abandoned`].includes(e.state)?g(``,!0):(b(),u(i,{key:2},[e.state===`doing`?(b(),u(`button`,{key:0,onClick:t=>Q(e,`pause`)},n(j(o)(`暂停`)),9,Zt)):(b(),u(`button`,{key:1,onClick:t=>Q(e,`resume`)},n(j(o)(`重新安排`)),9,Qt)),h(`button`,{onClick:t=>Q(e,`schedule`)},n(j(o)(`安排时间`)),9,$t),h(`button`,{class:`text-button`,onClick:t=>Q(e,`abandon`)},n(j(o)(`放下`)),9,en)],64))])],8,Pt))),128))])):f.value===`works`?(b(),u(`div`,tn,[(b(!0),u(i,null,S(D.value,e=>(b(),u(`button`,{key:e.id,class:`card work-card`,"data-work":e.id,onClick:t=>X(e.id)},[h(`span`,rn,n(j(o)(`{v} · 第 {ordinal} 篇`,{v:e.state===`complete`?j(o)(`完成稿`):j(o)(`草稿`),ordinal:e.ordinal})),1),h(`h2`,null,n(e.title),1),h(`p`,null,n(e.summary),1),h(`small`,null,n(j(o)(`{characters} 字 · 版本 {version}`,{characters:e.characters,version:e.version})),1),h(`span`,an,n(e.project_title||j(o)(`独处留下的东西`)),1)],8,nn))),128))])):f.value===`projects`?(b(),u(`div`,on,[(b(!0),u(i,null,S(D.value,e=>(b(),u(`article`,{key:e.id,class:`card`},[h(`span`,sn,n(e.kind===`game`?j(o)(`游戏`):e.serial?j(o)(`连载`):j(o)(`持续项目`))+` · `+n(e.state===`active`?j(o)(`在继续`):e.state===`complete`?j(o)(`已完结`):j(o)(`暂时放下`)),1),h(`h2`,null,n(e.title),1),h(`p`,null,n(e.why),1),h(`p`,cn,n(e.summary),1),h(`button`,{onClick:t=>Z(e.id)},n(j(o)(`打开项目`)),9,ln)]))),128))])):(b(),m(rt,{key:3,rows:D.value,zone:G.value,loading:N.value,onWork:X,onProject:Z,onSource:ve},null,8,[`rows`,`zone`,`loading`])),f.value!==`experiences`&&!N.value&&!D.value.length?(b(),m(ne,{key:4,title:f.value===`works`?j(o)(`作品还在等待第一笔`):j(o)(`这里还没有记录`),text:j(o)(`实际发生并保存之后,这里才会出现内容。`)},null,8,[`title`,`text`])):g(``,!0),h(`div`,un,[h(`button`,{disabled:F.value===0,onClick:t[14]||=e=>{F.value=Math.max(0,F.value-24),Y()}},n(j(o)(`上一页`)),9,dn),h(`span`,null,n(F.value/24+1),1),h(`button`,{disabled:!de.value,onClick:t[15]||=e=>{F.value+=24,Y()}},n(j(o)(`下一页`)),9,fn)])],64)),k(le,{open:!!z.value,title:z.value?.title||j(o)(`作品`),eyebrow:j(o)(`她留下的正文`),width:`780px`,onClose:t[18]||=e=>z.value=null},{default:ie(()=>[z.value?(b(),u(i,{key:0},[h(`div`,pn,[h(`span`,mn,n(j(o)(`{v} · {length} 字`,{v:z.value.state===`complete`?j(o)(`完成稿`):j(o)(`草稿`),length:z.value.content.length})),1),h(`label`,null,[x(n(j(o)(`版本`)),1),k(se,{"model-value":z.value.version,"aria-label":j(o)(`作品版本`),options:z.value.versions.map(e=>({value:e.version,label:e.version+` · `+j(M)(e.created,G.value)})),"onUpdate:modelValue":t[16]||=e=>X(z.value.id,Number(e))},null,8,[`model-value`,`aria-label`,`options`])]),h(`button`,{onClick:ye},n(j(o)(`导出正文`)),1)]),h(`p`,hn,n(z.value.content),1),z.value.project_id?(b(),u(`button`,{key:0,onClick:t[17]||=e=>Z(z.value.project_id)},n(j(o)(`查看项目与设定`)),1)):g(``,!0)],64)):g(``,!0)]),_:1},8,[`open`,`title`,`eyebrow`]),k(le,{open:!!B.value,title:B.value?.title||j(o)(`持续项目`),eyebrow:j(o)(`她自己的方向`),width:`740px`,onClose:t[22]||=e=>B.value=null},{default:ie(()=>[B.value?(b(),u(i,{key:0},[h(`p`,null,n(B.value.why),1),h(`p`,gn,n(B.value.summary),1),Object.keys(B.value.bible||{}).length?(b(),u(`details`,_n,[h(`summary`,null,n(j(o)(`设定与未解决线索`)),1),h(`dl`,null,[(b(!0),u(i,null,S(B.value.bible,(e,t)=>(b(),u(i,{key:t},[h(`dt`,null,n({characters:j(o)(`人物`),world:j(o)(`世界`),threads:j(o)(`未解决线索`),topic:j(o)(`资料主题`),mode:j(o)(`模式`)}[t]||t),1),h(`dd`,null,n(e),1)],64))),128))])])):g(``,!0),h(`div`,vn,[h(`button`,{onClick:t[19]||=e=>$(`continue`)},n(j(o)(`建议续写`)),1),h(`button`,{onClick:t[20]||=e=>$(`revise`)},n(j(o)(`建议修改`)),1),h(`button`,{onClick:t[21]||=e=>$(`direction`)},n(j(o)(`建议方向`)),1)]),h(`h3`,null,n(j(o)(`已经留下的篇章`)),1),h(`ul`,yn,[(b(!0),u(i,null,S(B.value.works,e=>(b(),u(`li`,{key:e.id},[h(`button`,{class:`text-button`,onClick:t=>X(e.id)},n(j(o)(`第 {ordinal} 篇 · {title}`,{ordinal:e.ordinal,title:e.title})),9,bn),h(`small`,null,n(e.state===`draft`?j(o)(`草稿`):j(o)(`完成稿`)),1)]))),128))]),B.value.sources.length?(b(),u(`h3`,xn,n(j(o)(`接触的资料`)),1)):g(``,!0),h(`ul`,Sn,[(b(!0),u(i,null,S(B.value.sources,e=>(b(),u(`li`,{key:e.id},[h(`button`,{class:`text-button`,onClick:t=>ve(e.id)},n(e.title),9,Cn)]))),128))])],64)):g(``,!0)]),_:1},8,[`open`,`title`,`eyebrow`]),k(le,{open:!!V.value,title:V.value?.title||j(o)(`资料`),eyebrow:V.value?.kind===`model`?j(o)(`模型知识整理 · 未经联网核验`):j(o)(`实际返回的摘录`),width:`740px`,onClose:t[23]||=e=>V.value=null},{default:ie(()=>[V.value?(b(),u(i,{key:0},[V.value.url?(b(),u(`a`,{key:0,href:V.value.url,target:`_blank`,rel:`noopener noreferrer`},n(j(o)(`打开来源`)),9,wn)):g(``,!0),V.value.kind===`model`?(b(),u(`p`,Tn,n(V.value.uncertainty||j(o)(`基于模型已有知识,具体剧情与章节仍需核验。`)),1)):g(``,!0),h(`p`,En,n(j(M)(V.value.created,G.value)),1),h(`p`,Dn,n(V.value.content),1)],64)):g(``,!0)]),_:1},8,[`open`,`title`,`eyebrow`])]))}}),[[`__scopeId`,`data-v-6804b51c`]]);export{On as default};
|