dsh-knowledge-library 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.js CHANGED
@@ -27,7 +27,7 @@ __export(client_exports, {
27
27
  module.exports = __toCommonJS(client_exports);
28
28
 
29
29
  // src/ui/App.tsx
30
- var import_react4 = require("react");
30
+ var import_react5 = require("react");
31
31
 
32
32
  // src/ui/icons.tsx
33
33
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -452,6 +452,10 @@ function StartKnowledgeDialog({ root, sourceIds, model, initialMode, onClose, on
452
452
  /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { name: "arrow", size: 12 })
453
453
  ] })
454
454
  ] }),
455
+ model.available && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("details", { className: "kl-knowledge-model", children: [
456
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("summary", { children: "\u8F93\u51FA\u914D\u7F6E\u4E0E\u601D\u8003" }),
457
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children: "\u8F93\u51FA\u989D\u5EA6\u6CBF\u7528\u5F53\u524D\u6A21\u578B\u914D\u7F6E\uFF0C\u63D2\u4EF6\u4E0D\u53E6\u8BBE token \u4E0A\u9650\u3002Harness \u4F7F\u7528\u6A21\u578B\u9002\u914D\u5668\u7684\u9ED8\u8BA4\u8F93\u51FA\u914D\u7F6E\uFF0C\u72EC\u7ACB\u9884\u89C8\u4F7F\u7528\u6A21\u578B\u670D\u52A1\u9ED8\u8BA4\u914D\u7F6E\u3002\u4FDD\u7559\u5F53\u524D\u601D\u8003\u5F3A\u5EA6\uFF0C\u90E8\u5206\u6A21\u578B\u5C06\u601D\u8003\u4E0E\u6B63\u6587\u4E00\u8D77\u8BA1\u5165\u989D\u5EA6\uFF0C\u8D39\u7528\u6309\u6A21\u578B\u670D\u52A1\u89C4\u5219\u8BA1\u7B97\u3002\u63D0\u70BC/\u5206\u6790\u6BCF\u6B21\u6700\u591A\u7B49\u5F85 5 \u5206\u949F\uFF0C\u5206\u7EC4/\u7EFC\u5408/\u5BF9\u6BD4\u6700\u591A 10 \u5206\u949F\uFF0C\u53EF\u968F\u65F6\u53D6\u6D88\uFF1B\u622A\u65AD\u4E0D\u4F1A\u81EA\u52A8\u91CD\u8BD5\u3002" })
458
+ ] }),
455
459
  characters > 1e5 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { role: "alert", className: "kl-form-error", children: "\u6B63\u6587\u8D85\u8FC7 10 \u4E07\u5B57\uFF0C\u8BF7\u51CF\u5C11\u9009\u62E9\u540E\u5206\u6279\u6574\u7406\u3002" }),
456
460
  invalidSource && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { role: "alert", className: "kl-form-error", children: "\u90E8\u5206\u8D44\u6599\u5DF2\u5220\u9664\u3001\u4EC5\u5F52\u6863\u6216\u5C5E\u4E8E\u77E5\u8BC6\u7B14\u8BB0\uFF0C\u8BF7\u91CD\u65B0\u9009\u62E9\u3002" }),
457
461
  error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { role: "alert", className: "kl-form-error", children: error }),
@@ -696,8 +700,191 @@ function DraftEditor({ root, job, onRefresh, onOpenSource, onSaved, onNotify })
696
700
  ] });
697
701
  }
698
702
 
699
- // src/ui/App.tsx
703
+ // src/ui/ImageCapture.tsx
704
+ var import_react4 = require("react");
700
705
  var import_jsx_runtime5 = require("react/jsx-runtime");
706
+ function ImageSettings({ root }) {
707
+ const [status, setStatus] = (0, import_react4.useState)();
708
+ const [enabled, setEnabled] = (0, import_react4.useState)(false);
709
+ const [limit, setLimit] = (0, import_react4.useState)(6);
710
+ const [confirmed, setConfirmed] = (0, import_react4.useState)(false);
711
+ const [busy, setBusy] = (0, import_react4.useState)(false);
712
+ const [error, setError] = (0, import_react4.useState)("");
713
+ const [saved, setSaved] = (0, import_react4.useState)(false);
714
+ (0, import_react4.useEffect)(() => {
715
+ const abort = new AbortController();
716
+ void api("/settings/images", { signal: abort.signal }).then((value) => {
717
+ setStatus(value);
718
+ setEnabled(value.enabled);
719
+ setLimit(value.maxImages);
720
+ }).catch((e) => {
721
+ if (!abort.signal.aborted) setError(e.message);
722
+ });
723
+ return () => abort.abort();
724
+ }, [root]);
725
+ async function save() {
726
+ if (!status || busy) return;
727
+ setBusy(true);
728
+ setError("");
729
+ setSaved(false);
730
+ try {
731
+ const value = await post("/settings/images", { settings: { enabled, maxImages: limit }, version: status.version, expectedRoot: root, expectedModel: status.currentModel, confirmed });
732
+ setStatus(value);
733
+ setEnabled(value.enabled);
734
+ setLimit(value.maxImages);
735
+ setConfirmed(false);
736
+ setSaved(true);
737
+ } catch (e) {
738
+ setError(e.message);
739
+ } finally {
740
+ setBusy(false);
741
+ }
742
+ }
743
+ const mismatch = status?.enabled && status.model !== status.currentModel;
744
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "kl-image-settings", "aria-label": "\u7F51\u9875\u56FE\u7247\u8BC6\u522B\u8BBE\u7F6E", children: [
745
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: "\u6B63\u6587\u56FE\u7247\u8BC6\u522B" }),
746
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "kl-proxy-option", children: [
747
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "checkbox", checked: enabled, disabled: !status?.supported || busy, onChange: (e) => {
748
+ setEnabled(e.target.checked);
749
+ setConfirmed(false);
750
+ setSaved(false);
751
+ } }),
752
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u91C7\u96C6\u7F51\u9875\u65F6\u81EA\u52A8\u8BC6\u522B\u6B63\u6587\u56FE\u7247" })
753
+ ] }),
754
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "\u5F00\u542F\u540E\uFF0C\u540E\u7EED\u7F51\u9875\u7684\u6B63\u6587\u56FE\u7247\u4F1A\u81EA\u52A8\u53D1\u9001\u7ED9\u5F53\u524D\u89C6\u89C9\u6A21\u578B\uFF0C\u53EF\u80FD\u4EA7\u751F\u6A21\u578B\u8D39\u7528\u3002\u539F\u56FE\u4E0E\u8BC6\u522B\u6587\u5B57\u4FDD\u5B58\u5728\u672C\u5730\uFF0C\u53EF\u641C\u7D22\u3001\u5F15\u7528\u548C\u6574\u7406\u4E3A\u77E5\u8BC6\u7B14\u8BB0\u3002" }),
755
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "kl-image-model", children: [
756
+ "\u5F53\u524D\u6A21\u578B\uFF1A",
757
+ status?.currentModel || "\u672A\u914D\u7F6E",
758
+ status?.model && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
759
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("br", {}),
760
+ "\u5DF2\u7ED1\u5B9A\u6A21\u578B\uFF1A",
761
+ status.model
762
+ ] })
763
+ ] }),
764
+ status?.reason && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-muted", children: status.reason }),
765
+ mismatch && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { role: "alert", children: "\u6A21\u578B\u5DF2\u6539\u53D8\uFF0C\u539F\u56FE\u7247\u4EFB\u52A1\u4E0D\u4F1A\u81EA\u52A8\u5207\u6362\u6A21\u578B\u3002\u8BF7\u5207\u56DE\u539F\u6A21\u578B\uFF0C\u6216\u786E\u8BA4\u65B0\u8BBE\u7F6E\u7528\u4E8E\u540E\u7EED\u7F51\u9875\u3002" }),
766
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "kl-image-limit", children: [
767
+ "\u6BCF\u9875\u6700\u591A\u8BC6\u522B\u56FE\u7247\u6570",
768
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { "aria-label": "\u6BCF\u9875\u6700\u591A\u8BC6\u522B\u56FE\u7247\u6570", type: "number", min: "1", max: "10", value: limit, disabled: busy || !status?.supported, onChange: (e) => {
769
+ setLimit(Number(e.target.value));
770
+ setConfirmed(false);
771
+ setSaved(false);
772
+ } })
773
+ ] }),
774
+ enabled && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "kl-proxy-option", children: [
775
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "checkbox", checked: confirmed, disabled: busy || !status?.available, onChange: (e) => setConfirmed(e.target.checked) }),
776
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
777
+ "\u786E\u8BA4\u4F7F\u7528 ",
778
+ status?.currentModel || "\u5F53\u524D\u6A21\u578B",
779
+ "\uFF0C\u6BCF\u9875\u6700\u591A ",
780
+ limit,
781
+ " \u5F20\uFF0C\u5141\u8BB8\u540E\u7EED\u91C7\u96C6\u81EA\u52A8\u53D1\u9001\u56FE\u7247\u5E76\u4EA7\u751F\u6A21\u578B\u8D39\u7528"
782
+ ] })
783
+ ] }),
784
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", disabled: busy || !status?.supported || !Number.isInteger(limit) || limit < 1 || limit > 10 || enabled && (!status?.available || !confirmed), onClick: () => void save(), children: busy ? "\u6B63\u5728\u4FDD\u5B58\u2026" : "\u4FDD\u5B58\u56FE\u7247\u8BC6\u522B\u8BBE\u7F6E" }),
785
+ saved && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { role: "status", children: "\u5DF2\u4FDD\u5B58\uFF0C\u5BF9\u540E\u7EED\u7F51\u9875\u91C7\u96C6\u751F\u6548\uFF1B\u5DF2\u6709\u8D44\u6599\u53EF\u4FDD\u7559\u539F\u6837\u3002" }),
786
+ error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-form-error", role: "alert", children: error })
787
+ ] });
788
+ }
789
+ function ImageCapturePolicy() {
790
+ const [status, setStatus] = (0, import_react4.useState)();
791
+ (0, import_react4.useEffect)(() => {
792
+ const abort = new AbortController();
793
+ void api("/settings/images", { signal: abort.signal }).then(setStatus).catch(() => {
794
+ });
795
+ return () => abort.abort();
796
+ }, []);
797
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kl-image-policy", children: !status ? "\u6B63\u5728\u8BFB\u53D6\u56FE\u7247\u91C7\u96C6\u8BBE\u7F6E\u2026" : status.enabled ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
798
+ "\u56FE\u7247\u8BC6\u522B\u5DF2\u5F00\u542F\uFF1A",
799
+ status.model,
800
+ "\uFF0C\u6BCF\u9875\u6700\u591A ",
801
+ status.maxImages,
802
+ " \u5F20\u3002\u6B63\u6587\u56FE\u7247\u5C06\u53D1\u9001\u7ED9\u6A21\u578B\uFF0C\u53EF\u80FD\u4EA7\u751F\u8D39\u7528\u3002",
803
+ (!status.available || status.model !== status.currentModel) && " \u5F53\u524D\u6A21\u578B\u4E0D\u53EF\u7528\u6216\u4E0E\u7ED1\u5B9A\u6A21\u578B\u4E0D\u540C\uFF0C\u56FE\u7247\u5C06\u4FDD\u7559\u4E3A\u5931\u8D25\u4EFB\u52A1\u4F9B\u6838\u5BF9\u3002"
804
+ ] }) : "\u56FE\u7247\u8BC6\u522B\u672A\u5F00\u542F\u3002\u53EF\u5728\u8D44\u6599\u5E93\u8BBE\u7F6E\u4E2D\u542F\u7528\uFF0C\u81EA\u52A8\u4FDD\u5B58\u539F\u56FE\u5E76\u63D0\u53D6\u56FE\u4E2D\u6587\u5B57\u4E0E\u56FE\u793A\u542B\u4E49\u3002" });
805
+ }
806
+ var imageStates = { pending: "\u7B49\u5F85\u5904\u7406", downloading: "\u4E0B\u8F7D\u4E2D", recognizing: "\u8BC6\u522B\u4E2D", completed: "\u5DF2\u8BC6\u522B", failed: "\u672A\u5B8C\u6210", skipped: "\u5DF2\u8DF3\u8FC7" };
807
+ var imagesPending = (detail) => detail.images?.some((image) => ["pending", "downloading", "recognizing"].includes(image.status));
808
+ function PageImages({ detail, onRetry, onJump }) {
809
+ if (!detail.images?.length) return null;
810
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "kl-page-images", "aria-label": "\u6B63\u6587\u56FE\u7247", children: [
811
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-image-heading", children: [
812
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("h3", { children: [
813
+ "\u6B63\u6587\u56FE\u7247 \xB7 ",
814
+ detail.images.length
815
+ ] }),
816
+ !detail.deletedAt && !imagesPending(detail) && detail.images.some((image) => image.status === "failed" && image.attempts < 3) && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", onClick: onRetry, children: "\u91CD\u8BD5\u5931\u8D25\u56FE\u7247" })
817
+ ] }),
818
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-muted", children: "\u56FE\u7247\u6587\u5B57\u548C\u56FE\u793A\u89E3\u8BFB\u5DF2\u6807\u6CE8\u4E3A\u6A21\u578B\u8F93\u51FA\uFF0C\u8BF7\u7ED3\u5408\u539F\u56FE\u6838\u5BF9\u3002" }),
819
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kl-image-grid", children: detail.images.map((image, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-image-record", children: [
820
+ image.originalAvailable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { href: `${API}/materials/${detail.id}/images/${image.id}`, target: "_blank", rel: "noreferrer", "aria-label": `\u67E5\u770B\u539F\u56FE ${index + 1}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { loading: "lazy", src: `${API}/materials/${detail.id}/images/${image.id}`, alt: image.alt || `\u6B63\u6587\u56FE\u7247 ${index + 1}` }) }),
821
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("strong", { children: [
822
+ "\u56FE\u7247 ",
823
+ index + 1,
824
+ " \xB7 ",
825
+ imageStates[image.status]
826
+ ] }),
827
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("small", { children: image.model }),
828
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { href: image.url, target: "_blank", rel: "noreferrer", children: "\u6765\u6E90\u56FE\u7247" }),
829
+ image.error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: image.error }),
830
+ image.uncertainty && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { children: [
831
+ "\u5F85\u6838\u5B9E\uFF1A",
832
+ image.uncertainty
833
+ ] }),
834
+ image.segmentId && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", onClick: () => onJump(image.segmentId), children: "\u67E5\u770B\u8BC6\u522B\u6587\u5B57" })
835
+ ] }, image.id)) })
836
+ ] });
837
+ }
838
+ function ImageRetryDialog({ id, root, onClose, onStarted }) {
839
+ const [detail, setDetail] = (0, import_react4.useState)();
840
+ const [busy, setBusy] = (0, import_react4.useState)(false);
841
+ const [error, setError] = (0, import_react4.useState)("");
842
+ (0, import_react4.useEffect)(() => {
843
+ const abort = new AbortController();
844
+ void api(`/materials/${id}`, { signal: abort.signal }).then(setDetail).catch((e) => {
845
+ if (!abort.signal.aborted) setError(e.message);
846
+ });
847
+ return () => abort.abort();
848
+ }, [id]);
849
+ const eligible = detail?.images?.filter((image) => image.status === "failed" && image.attempts < 3) || [];
850
+ async function retry() {
851
+ if (!eligible.length || busy) return;
852
+ setBusy(true);
853
+ setError("");
854
+ try {
855
+ await post(`/materials/${id}/images/retry`, { expectedRoot: root, expectedModel: eligible[0].model, imageIds: eligible.map((image) => image.id), confirmed: true });
856
+ onStarted();
857
+ } catch (e) {
858
+ setError(e.message);
859
+ } finally {
860
+ setBusy(false);
861
+ }
862
+ }
863
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Dialog, { title: "\u91CD\u8BD5\u5931\u8D25\u56FE\u7247", description: "\u5C06\u518D\u6B21\u53D1\u9001\u4E0B\u5217\u5931\u8D25\u56FE\u7247\u5230\u539F\u4EFB\u52A1\u6A21\u578B\uFF0C\u53EF\u80FD\u4EA7\u751F\u8D39\u7528\u3002\u5DF2\u6210\u529F\u56FE\u7247\u4E0D\u4F1A\u91CD\u590D\u8BC6\u522B\u3002", onClose: () => {
864
+ if (!busy) onClose();
865
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-delete-dialog", children: [
866
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: detail ? `${detail.title} \xB7 ${eligible.length} \u5F20\u53EF\u91CD\u8BD5\u56FE\u7247` : "\u6B63\u5728\u6838\u5BF9\u56FE\u7247\u2026" }),
867
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { children: [
868
+ "\u6A21\u578B\uFF1A",
869
+ eligible[0]?.model || "\u2014",
870
+ "\u3002\u6BCF\u5F20\u56FE\u7247\u6700\u591A\u53D1\u8D77 3 \u6B21\u6A21\u578B\u8BF7\u6C42\u3002"
871
+ ] }),
872
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { children: eligible.map((image) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("li", { children: [
873
+ image.alt || image.url,
874
+ "\uFF08\u5DF2\u8BF7\u6C42 ",
875
+ image.attempts,
876
+ " \u6B21\uFF09"
877
+ ] }, image.id)) }),
878
+ error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { role: "alert", className: "kl-form-error", children: error }),
879
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("footer", { children: [
880
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", disabled: busy, onClick: onClose, children: "\u53D6\u6D88" }),
881
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-primary", disabled: busy || !eligible.length || !!detail && (!!detail.deletedAt || !!imagesPending(detail)), onClick: () => void retry(), children: busy ? "\u6B63\u5728\u63D0\u4EA4\u2026" : `\u786E\u8BA4\u91CD\u8BD5 ${eligible.length} \u5F20\u56FE\u7247` })
882
+ ] })
883
+ ] }) });
884
+ }
885
+
886
+ // src/ui/App.tsx
887
+ var import_jsx_runtime6 = require("react/jsx-runtime");
701
888
  var kinds = {
702
889
  web: { label: "\u7F51\u9875", icon: "web" },
703
890
  text: { label: "\u6587\u672C", icon: "file" },
@@ -712,37 +899,38 @@ function splitTags2(value) {
712
899
  return value.split(/[,,]/).map((v) => v.trim()).filter(Boolean);
713
900
  }
714
901
  function App() {
715
- const [stats, setStats] = (0, import_react4.useState)();
716
- const [items, setItems] = (0, import_react4.useState)([]);
717
- const [total, setTotal] = (0, import_react4.useState)(0);
718
- const [query, setQuery] = (0, import_react4.useState)("");
719
- const [filter, setFilter] = (0, import_react4.useState)({});
720
- const [selected, setSelected] = (0, import_react4.useState)();
721
- const [detail, setDetail] = (0, import_react4.useState)();
722
- const [anchor, setAnchor] = (0, import_react4.useState)();
723
- const [editor, setEditor] = (0, import_react4.useState)();
724
- const [deletion, setDeletion] = (0, import_react4.useState)();
725
- const [restoring, setRestoring] = (0, import_react4.useState)();
726
- const [emptyRoot, setEmptyRoot] = (0, import_react4.useState)();
727
- const [jobs, setJobs] = (0, import_react4.useState)([]);
728
- const [knowledge, setKnowledge] = (0, import_react4.useState)();
729
- const [batchMode, setBatchMode] = (0, import_react4.useState)(false);
730
- const [checkedIds, setCheckedIds] = (0, import_react4.useState)([]);
731
- const [generation, setGeneration] = (0, import_react4.useState)();
732
- const [knowledgeOpen, setKnowledgeOpen] = (0, import_react4.useState)();
733
- const [showJobs, setShowJobs] = (0, import_react4.useState)(false);
734
- const [showInfo, setShowInfo] = (0, import_react4.useState)(false);
735
- const [settingsFromJobs, setSettingsFromJobs] = (0, import_react4.useState)(false);
736
- const [showNavigation, setShowNavigation] = (0, import_react4.useState)(false);
737
- const [error, setError] = (0, import_react4.useState)("");
738
- const [toast, setToast] = (0, import_react4.useState)("");
739
- const [loading, setLoading] = (0, import_react4.useState)(true);
740
- const [detailLoading, setDetailLoading] = (0, import_react4.useState)(false);
741
- const [revision, setRevision] = (0, import_react4.useState)(0);
742
- const [limit, setLimit] = (0, import_react4.useState)(40);
743
- const searchRef = (0, import_react4.useRef)(null);
744
- const detailRef = (0, import_react4.useRef)(null);
745
- const refresh = (0, import_react4.useCallback)(() => setRevision((v) => v + 1), []);
902
+ const [stats, setStats] = (0, import_react5.useState)();
903
+ const [items, setItems] = (0, import_react5.useState)([]);
904
+ const [total, setTotal] = (0, import_react5.useState)(0);
905
+ const [query, setQuery] = (0, import_react5.useState)("");
906
+ const [filter, setFilter] = (0, import_react5.useState)({});
907
+ const [selected, setSelected] = (0, import_react5.useState)();
908
+ const [detail, setDetail] = (0, import_react5.useState)();
909
+ const [anchor, setAnchor] = (0, import_react5.useState)();
910
+ const [editor, setEditor] = (0, import_react5.useState)();
911
+ const [deletion, setDeletion] = (0, import_react5.useState)();
912
+ const [restoring, setRestoring] = (0, import_react5.useState)();
913
+ const [emptyRoot, setEmptyRoot] = (0, import_react5.useState)();
914
+ const [jobs, setJobs] = (0, import_react5.useState)([]);
915
+ const [knowledge, setKnowledge] = (0, import_react5.useState)();
916
+ const [batchMode, setBatchMode] = (0, import_react5.useState)(false);
917
+ const [checkedIds, setCheckedIds] = (0, import_react5.useState)([]);
918
+ const [generation, setGeneration] = (0, import_react5.useState)();
919
+ const [knowledgeOpen, setKnowledgeOpen] = (0, import_react5.useState)();
920
+ const [showJobs, setShowJobs] = (0, import_react5.useState)(false);
921
+ const [imageRetry, setImageRetry] = (0, import_react5.useState)();
922
+ const [showInfo, setShowInfo] = (0, import_react5.useState)(false);
923
+ const [settingsFromJobs, setSettingsFromJobs] = (0, import_react5.useState)(false);
924
+ const [showNavigation, setShowNavigation] = (0, import_react5.useState)(false);
925
+ const [error, setError] = (0, import_react5.useState)("");
926
+ const [toast, setToast] = (0, import_react5.useState)("");
927
+ const [loading, setLoading] = (0, import_react5.useState)(true);
928
+ const [detailLoading, setDetailLoading] = (0, import_react5.useState)(false);
929
+ const [revision, setRevision] = (0, import_react5.useState)(0);
930
+ const [limit, setLimit] = (0, import_react5.useState)(40);
931
+ const searchRef = (0, import_react5.useRef)(null);
932
+ const detailRef = (0, import_react5.useRef)(null);
933
+ const refresh = (0, import_react5.useCallback)(() => setRevision((v) => v + 1), []);
746
934
  const notify = (message) => setToast(message);
747
935
  const chooseFilter = (next) => {
748
936
  setFilter(next);
@@ -754,7 +942,7 @@ function App() {
754
942
  setBatchMode(false);
755
943
  setCheckedIds([]);
756
944
  };
757
- const refreshMeta = (0, import_react4.useCallback)(async () => {
945
+ const refreshMeta = (0, import_react5.useCallback)(async () => {
758
946
  const [s, j, k] = await Promise.all([api("/stats"), api("/jobs"), api("/knowledge").catch((e) => {
759
947
  if (e instanceof ApiError && e.status === 404) return { supported: false, available: false, reason: "\u8BF7\u91CD\u542F\u8D44\u6599\u5E93\u670D\u52A1\u4EE5\u542F\u7528\u77E5\u8BC6\u6574\u7406\u3002", jobs: [], states: {} };
760
948
  throw e;
@@ -763,13 +951,13 @@ function App() {
763
951
  setJobs(j);
764
952
  setKnowledge(k);
765
953
  }, []);
766
- (0, import_react4.useEffect)(() => {
954
+ (0, import_react5.useEffect)(() => {
767
955
  setCheckedIds([]);
768
956
  }, [query]);
769
- (0, import_react4.useEffect)(() => {
957
+ (0, import_react5.useEffect)(() => {
770
958
  void refreshMeta().catch((e) => setError(e.message));
771
959
  }, [revision, refreshMeta]);
772
- (0, import_react4.useEffect)(() => {
960
+ (0, import_react5.useEffect)(() => {
773
961
  const controller = new AbortController();
774
962
  const timer = setTimeout(() => {
775
963
  setLoading(true);
@@ -789,7 +977,7 @@ function App() {
789
977
  controller.abort();
790
978
  };
791
979
  }, [query, filter, revision, limit]);
792
- (0, import_react4.useEffect)(() => {
980
+ (0, import_react5.useEffect)(() => {
793
981
  if (!selected) {
794
982
  setDetail(void 0);
795
983
  return;
@@ -804,7 +992,7 @@ function App() {
804
992
  });
805
993
  return () => controller.abort();
806
994
  }, [selected, revision]);
807
- (0, import_react4.useEffect)(() => {
995
+ (0, import_react5.useEffect)(() => {
808
996
  if (!detail || !anchor) return;
809
997
  const element = Array.from(detailRef.current?.querySelectorAll("[data-segment-id]") || []).find((el) => el.dataset.segmentId === anchor);
810
998
  element?.scrollIntoView({ block: "center" });
@@ -812,17 +1000,17 @@ function App() {
812
1000
  const pending = jobs.filter((j) => ["queued", "running"].includes(j.status)).length;
813
1001
  const knowledgePending = knowledge?.jobs.filter((j) => ["queued", "running"].includes(j.status)).length || 0;
814
1002
  const draftCount = knowledge?.jobs.filter((j) => ["draft", "grouping"].includes(j.status)).length || 0;
815
- (0, import_react4.useEffect)(() => {
1003
+ (0, import_react5.useEffect)(() => {
816
1004
  if (!pending && !knowledgePending) return;
817
1005
  const interval = setInterval(refresh, 2500);
818
1006
  return () => clearInterval(interval);
819
1007
  }, [pending, knowledgePending, refresh]);
820
- (0, import_react4.useEffect)(() => {
1008
+ (0, import_react5.useEffect)(() => {
821
1009
  if (!toast) return;
822
1010
  const timer = setTimeout(() => setToast(""), 3500);
823
1011
  return () => clearTimeout(timer);
824
1012
  }, [toast]);
825
- (0, import_react4.useEffect)(() => {
1013
+ (0, import_react5.useEffect)(() => {
826
1014
  const listener = (event) => {
827
1015
  if ((event.ctrlKey || event.metaKey) && event.key === "k") {
828
1016
  event.preventDefault();
@@ -877,293 +1065,295 @@ function App() {
877
1065
  if (stats) setGeneration({ root: stats.root, sourceIds: ids, mode });
878
1066
  }
879
1067
  const currentTitle = filter.trashed ? "\u56DE\u6536\u7AD9" : filter.category || filter.collection || (filter.tag ? `\u6807\u7B7E \xB7 ${filter.tag}` : filter.kind === "note" ? "\u77E5\u8BC6\u7B14\u8BB0" : "\u5168\u90E8\u8D44\u6599");
880
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-app", children: [
881
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("main", { className: "kl-workspace", children: [
882
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("header", { className: "kl-header", children: [
883
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h1", { children: currentTitle }),
884
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-header-actions", children: [
885
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: "kl-secondary", onClick: () => setEditor({ mode: "note" }), children: [
886
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "note", size: 16 }),
1068
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-app", children: [
1069
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("main", { className: "kl-workspace", children: [
1070
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("header", { className: "kl-header", children: [
1071
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h1", { children: currentTitle }),
1072
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-header-actions", children: [
1073
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "kl-secondary", onClick: () => setEditor({ mode: "note" }), children: [
1074
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "note", size: 16 }),
887
1075
  "\u5199\u7B14\u8BB0"
888
1076
  ] }),
889
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: "kl-primary", onClick: () => setEditor({ mode: "capture" }), children: [
890
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "plus", size: 16 }),
1077
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "kl-primary", onClick: () => setEditor({ mode: "capture" }), children: [
1078
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "plus", size: 16 }),
891
1079
  "\u6536\u96C6\u8D44\u6599"
892
1080
  ] })
893
1081
  ] })
894
1082
  ] }),
895
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-navigation", children: [
896
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("nav", { "aria-label": "\u8D44\u6599\u5BFC\u822A", children: [
897
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { "aria-pressed": !Object.values(filter).some(Boolean), onClick: () => chooseFilter({}), children: "\u5168\u90E8\u8D44\u6599" }),
898
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { "aria-pressed": filter.category === "\u6536\u4EF6\u7BB1", onClick: () => chooseFilter({ category: "\u6536\u4EF6\u7BB1" }), children: "\u6536\u4EF6\u7BB1" }),
899
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { "aria-pressed": filter.kind === "note", onClick: () => chooseFilter({ kind: "note" }), children: "\u77E5\u8BC6\u7B14\u8BB0" }),
900
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { "aria-pressed": filter.trashed === "1", onClick: () => chooseFilter({ trashed: "1" }), children: "\u56DE\u6536\u7AD9" })
1083
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-navigation", children: [
1084
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("nav", { "aria-label": "\u8D44\u6599\u5BFC\u822A", children: [
1085
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { "aria-pressed": !Object.values(filter).some(Boolean), onClick: () => chooseFilter({}), children: "\u5168\u90E8\u8D44\u6599" }),
1086
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { "aria-pressed": filter.category === "\u6536\u4EF6\u7BB1", onClick: () => chooseFilter({ category: "\u6536\u4EF6\u7BB1" }), children: "\u6536\u4EF6\u7BB1" }),
1087
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { "aria-pressed": filter.kind === "note", onClick: () => chooseFilter({ kind: "note" }), children: "\u77E5\u8BC6\u7B14\u8BB0" }),
1088
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { "aria-pressed": filter.trashed === "1", onClick: () => chooseFilter({ trashed: "1" }), children: "\u56DE\u6536\u7AD9" })
901
1089
  ] }),
902
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: "kl-directory-toggle", "aria-expanded": showNavigation, "aria-controls": "kl-directory", onClick: () => setShowNavigation((v) => !v), children: [
903
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "folder", size: 16 }),
1090
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "kl-directory-toggle", "aria-expanded": showNavigation, "aria-controls": "kl-directory", onClick: () => setShowNavigation((v) => !v), children: [
1091
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "folder", size: 16 }),
904
1092
  "\u5206\u7C7B\u4E0E\u4E13\u9898"
905
1093
  ] })
906
1094
  ] }),
907
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-toolbar", children: [
908
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "kl-search", children: [
909
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "search", size: 19 }),
910
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { ref: searchRef, "aria-label": "\u641C\u7D22\u8D44\u6599", placeholder: "\u641C\u7D22\u6B63\u6587\u3001\u6807\u9898\u3001\u6807\u7B7E\u2026", value: query, onChange: (e) => {
1095
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-toolbar", children: [
1096
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "kl-search", children: [
1097
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "search", size: 19 }),
1098
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { ref: searchRef, "aria-label": "\u641C\u7D22\u8D44\u6599", placeholder: "\u641C\u7D22\u6B63\u6587\u3001\u6807\u9898\u3001\u6807\u7B7E\u2026", value: query, onChange: (e) => {
911
1099
  setQuery(e.target.value);
912
1100
  setLimit(40);
913
1101
  } }),
914
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("kbd", { children: "Ctrl K" })
1102
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("kbd", { children: "Ctrl K" })
915
1103
  ] }),
916
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { "aria-label": pending ? `\u91C7\u96C6\u4EFB\u52A1\uFF0C${pending} \u9879\u5904\u7406\u4E2D` : "\u91C7\u96C6\u4EFB\u52A1", className: `kl-job-button ${pending ? "has-jobs" : ""}`, onClick: () => setShowJobs(true), children: [
917
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "clock", size: 17 }),
918
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: pending ? `${pending} \u9879\u5904\u7406\u4E2D` : "\u91C7\u96C6\u4EFB\u52A1" }),
919
- jobs.some((j) => j.status === "failed") && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("i", {})
1104
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { "aria-label": pending ? `\u91C7\u96C6\u4EFB\u52A1\uFF0C${pending} \u9879\u5904\u7406\u4E2D` : "\u91C7\u96C6\u4EFB\u52A1", className: `kl-job-button ${pending ? "has-jobs" : ""}`, onClick: () => setShowJobs(true), children: [
1105
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "clock", size: 17 }),
1106
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: pending ? `${pending} \u9879\u5904\u7406\u4E2D` : "\u91C7\u96C6\u4EFB\u52A1" }),
1107
+ jobs.some((j) => j.status === "failed") && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("i", {})
920
1108
  ] }),
921
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { "aria-label": "\u77E5\u8BC6\u6574\u7406", title: "\u77E5\u8BC6\u6574\u7406", className: `kl-job-button ${knowledgePending || draftCount ? "has-jobs" : ""}`, onClick: () => {
1109
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { "aria-label": "\u77E5\u8BC6\u6574\u7406", title: "\u77E5\u8BC6\u6574\u7406", className: `kl-job-button ${knowledgePending || draftCount ? "has-jobs" : ""}`, onClick: () => {
922
1110
  refresh();
923
1111
  if (stats) setKnowledgeOpen({ root: stats.root });
924
1112
  }, children: [
925
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "note", size: 17 }),
926
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: draftCount ? `${draftCount} \u4EFD\u5F85\u786E\u8BA4` : "\u77E5\u8BC6\u6574\u7406" }),
927
- !!knowledgePending && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "kl-spinner" })
1113
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "note", size: 17 }),
1114
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: draftCount ? `${draftCount} \u4EFD\u5F85\u786E\u8BA4` : "\u77E5\u8BC6\u6574\u7406" }),
1115
+ !!knowledgePending && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "kl-spinner" })
928
1116
  ] }),
929
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-icon-button", "aria-label": "\u8D44\u6599\u5E93\u8BBE\u7F6E", title: "\u8D44\u6599\u5E93\u8BBE\u7F6E", onClick: () => {
1117
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-icon-button", "aria-label": "\u8D44\u6599\u5E93\u8BBE\u7F6E", title: "\u8D44\u6599\u5E93\u8BBE\u7F6E", onClick: () => {
930
1118
  setSettingsFromJobs(false);
931
1119
  setShowInfo(true);
932
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "settings", size: 18 }) })
1120
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "settings", size: 18 }) })
933
1121
  ] }),
934
- !!error && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-error", role: "alert", children: [
935
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: error }),
936
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { "aria-label": "\u5173\u95ED\u9519\u8BEF", onClick: () => setError(""), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "close", size: 16 }) })
1122
+ !!error && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-error", role: "alert", children: [
1123
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: error }),
1124
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { "aria-label": "\u5173\u95ED\u9519\u8BEF", onClick: () => setError(""), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "close", size: 16 }) })
937
1125
  ] }),
938
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-filterbar", children: [
939
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
940
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("b", { children: total }),
1126
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-filterbar", children: [
1127
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
1128
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("b", { children: total }),
941
1129
  " \u4EFD\u8D44\u6599",
942
1130
  query && ` \xB7 \u201C${query}\u201D`
943
1131
  ] }),
944
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
945
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("select", { "aria-label": "\u6309\u7C7B\u578B\u7B5B\u9009", value: filter.kind || "", onChange: (e) => {
1132
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1133
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("select", { "aria-label": "\u6309\u7C7B\u578B\u7B5B\u9009", value: filter.kind || "", onChange: (e) => {
946
1134
  setFilter({ ...filter, kind: e.target.value || void 0 });
947
1135
  setLimit(40);
948
1136
  }, children: [
949
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "", children: "\u6240\u6709\u7C7B\u578B" }),
950
- Object.entries(kinds).map(([value, kind]) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value, children: kind.label }, value))
1137
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "", children: "\u6240\u6709\u7C7B\u578B" }),
1138
+ Object.entries(kinds).map(([value, kind]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value, children: kind.label }, value))
951
1139
  ] }),
952
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "kl-sort-label", children: "\u6700\u8FD1\u66F4\u65B0 \u2193" })
1140
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "kl-sort-label", children: "\u6700\u8FD1\u66F4\u65B0 \u2193" })
953
1141
  ] })
954
1142
  ] }),
955
- filter.trashed && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-trash-toolbar", children: [
956
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: stats?.canEmptyTrash ? stats.purgePending ? `${stats.purgePending} \u4EFD\u8D44\u6599\u7684\u6587\u4EF6\u6E05\u7406\u672A\u5B8C\u6210\uFF0C\u53EF\u518D\u6B21\u6E05\u7A7A\u4EE5\u91CD\u8BD5\u3002` : "\u6E05\u7A7A\u5C06\u6C38\u4E45\u5220\u9664\u6574\u4E2A\u56DE\u6536\u7AD9\uFF0C\u4E0D\u53D7\u5F53\u524D\u641C\u7D22\u548C\u7C7B\u578B\u7B5B\u9009\u9650\u5236\u3002" : "\u8BF7\u91CD\u542F\u8D44\u6599\u5E93\u670D\u52A1\u4EE5\u542F\u7528\u6E05\u7A7A\u56DE\u6536\u7AD9\u3002" }),
957
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: "kl-secondary kl-danger", disabled: !stats?.canEmptyTrash || !(stats.trashed || stats.purgePending) || !!restoring, onClick: () => stats && setEmptyRoot(stats.root), children: [
958
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "trash", size: 15 }),
1143
+ filter.trashed && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-trash-toolbar", children: [
1144
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: stats?.canEmptyTrash ? stats.purgePending ? `${stats.purgePending} \u4EFD\u8D44\u6599\u7684\u6587\u4EF6\u6E05\u7406\u672A\u5B8C\u6210\uFF0C\u53EF\u518D\u6B21\u6E05\u7A7A\u4EE5\u91CD\u8BD5\u3002` : "\u6E05\u7A7A\u5C06\u6C38\u4E45\u5220\u9664\u6574\u4E2A\u56DE\u6536\u7AD9\uFF0C\u4E0D\u53D7\u5F53\u524D\u641C\u7D22\u548C\u7C7B\u578B\u7B5B\u9009\u9650\u5236\u3002" : "\u8BF7\u91CD\u542F\u8D44\u6599\u5E93\u670D\u52A1\u4EE5\u542F\u7528\u6E05\u7A7A\u56DE\u6536\u7AD9\u3002" }),
1145
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "kl-secondary kl-danger", disabled: !stats?.canEmptyTrash || !(stats.trashed || stats.purgePending) || !!restoring, onClick: () => stats && setEmptyRoot(stats.root), children: [
1146
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "trash", size: 15 }),
959
1147
  "\u6E05\u7A7A\u56DE\u6536\u7AD9"
960
1148
  ] })
961
1149
  ] }),
962
- !filter.trashed && filter.kind !== "note" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-knowledge-toolbar", children: [
963
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: batchMode ? `\u5DF2\u9009\u62E9 ${checkedIds.length} / 10 \u4EFD\u8D44\u6599\uFF1B\u5207\u6362\u641C\u7D22\u6216\u5206\u7C7B\u4F1A\u6E05\u9664\u9009\u62E9\u3002` : knowledge?.smartSupported ? "\u96F6\u6563\u8D44\u6599\u5148\u667A\u80FD\u5206\u7EC4\uFF0C\u518D\u6309\u7EC4\u5F62\u6210\u77E5\u8BC6\u7B14\u8BB0\u3002" : "\u8BF7\u91CD\u542F\u8D44\u6599\u5E93\u670D\u52A1\u4EE5\u542F\u7528\u667A\u80FD\u5206\u7EC4\u3002" }),
964
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
965
- batchMode && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-primary", disabled: !checkedIds.length || !knowledge?.smartSupported, onClick: () => generateFor(checkedIds, "smart"), children: "\u667A\u80FD\u5206\u6790\u5206\u7EC4" }),
966
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", disabled: !knowledge?.smartSupported, onClick: () => {
1150
+ !filter.trashed && filter.kind !== "note" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-knowledge-toolbar", children: [
1151
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: batchMode ? `\u5DF2\u9009\u62E9 ${checkedIds.length} / 10 \u4EFD\u8D44\u6599\uFF1B\u5207\u6362\u641C\u7D22\u6216\u5206\u7C7B\u4F1A\u6E05\u9664\u9009\u62E9\u3002` : knowledge?.smartSupported ? "\u96F6\u6563\u8D44\u6599\u5148\u667A\u80FD\u5206\u7EC4\uFF0C\u518D\u6309\u7EC4\u5F62\u6210\u77E5\u8BC6\u7B14\u8BB0\u3002" : "\u8BF7\u91CD\u542F\u8D44\u6599\u5E93\u670D\u52A1\u4EE5\u542F\u7528\u667A\u80FD\u5206\u7EC4\u3002" }),
1152
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1153
+ batchMode && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-primary", disabled: !checkedIds.length || !knowledge?.smartSupported, onClick: () => generateFor(checkedIds, "smart"), children: "\u667A\u80FD\u5206\u6790\u5206\u7EC4" }),
1154
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary", disabled: !knowledge?.smartSupported, onClick: () => {
967
1155
  setBatchMode(!batchMode);
968
1156
  setCheckedIds([]);
969
1157
  }, children: batchMode ? "\u53D6\u6D88\u9009\u62E9" : "\u667A\u80FD\u6574\u7406" })
970
1158
  ] })
971
1159
  ] }),
972
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `kl-body ${detail || detailLoading ? "with-detail" : ""}`, children: [
973
- showNavigation && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("aside", { className: "kl-nav", id: "kl-directory", "aria-label": "\u5206\u7C7B\u4E0E\u4E13\u9898", children: [
974
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-directory-title", children: [
975
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u5206\u7C7B\u4E0E\u4E13\u9898" }),
976
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-icon-button", "aria-label": "\u5173\u95ED\u5206\u7C7B\u5BFC\u822A", onClick: () => setShowNavigation(false), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "close", size: 16 }) })
1160
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `kl-body ${detail || detailLoading ? "with-detail" : ""}`, children: [
1161
+ showNavigation && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("aside", { className: "kl-nav", id: "kl-directory", "aria-label": "\u5206\u7C7B\u4E0E\u4E13\u9898", children: [
1162
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-directory-title", children: [
1163
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u5206\u7C7B\u4E0E\u4E13\u9898" }),
1164
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-icon-button", "aria-label": "\u5173\u95ED\u5206\u7C7B\u5BFC\u822A", onClick: () => setShowNavigation(false), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "close", size: 16 }) })
977
1165
  ] }),
978
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-nav-section", children: [
979
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kl-nav-label", children: "\u5206\u7C7B" }),
980
- stats?.categories.filter((c) => c.name !== "\u6536\u4EF6\u7BB1").map((c) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { "aria-pressed": filter.category === c.name, className: "kl-nav-row", onClick: () => chooseFilter({ category: c.name }), children: [
981
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "folder", size: 16 }),
982
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { title: c.name, children: c.name }),
983
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("small", { children: c.count })
1166
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-nav-section", children: [
1167
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "kl-nav-label", children: "\u5206\u7C7B" }),
1168
+ stats?.categories.filter((c) => c.name !== "\u6536\u4EF6\u7BB1").map((c) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { "aria-pressed": filter.category === c.name, className: "kl-nav-row", onClick: () => chooseFilter({ category: c.name }), children: [
1169
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "folder", size: 16 }),
1170
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { title: c.name, children: c.name }),
1171
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("small", { children: c.count })
984
1172
  ] }, c.name)),
985
- !stats?.categories.some((c) => c.name !== "\u6536\u4EF6\u7BB1") && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-nav-hint", children: "\u6536\u96C6\u8D44\u6599\u65F6\u6DFB\u52A0\u5206\u7C7B" })
1173
+ !stats?.categories.some((c) => c.name !== "\u6536\u4EF6\u7BB1") && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-nav-hint", children: "\u6536\u96C6\u8D44\u6599\u65F6\u6DFB\u52A0\u5206\u7C7B" })
986
1174
  ] }),
987
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-nav-section", children: [
988
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kl-nav-label", children: "\u4E13\u9898" }),
989
- stats?.collections.map((c) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { "aria-pressed": filter.collection === c.name, className: "kl-nav-row", onClick: () => chooseFilter({ collection: c.name }), children: [
990
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "kl-collection-dot" }),
991
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { title: c.name, children: c.name }),
992
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("small", { children: c.count })
1175
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-nav-section", children: [
1176
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "kl-nav-label", children: "\u4E13\u9898" }),
1177
+ stats?.collections.map((c) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { "aria-pressed": filter.collection === c.name, className: "kl-nav-row", onClick: () => chooseFilter({ collection: c.name }), children: [
1178
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "kl-collection-dot" }),
1179
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { title: c.name, children: c.name }),
1180
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("small", { children: c.count })
993
1181
  ] }, c.name)),
994
- !stats?.collections.length && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-nav-hint", children: "\u6536\u96C6\u8D44\u6599\u65F6\u6DFB\u52A0\u4E13\u9898" })
1182
+ !stats?.collections.length && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-nav-hint", children: "\u6536\u96C6\u8D44\u6599\u65F6\u6DFB\u52A0\u4E13\u9898" })
995
1183
  ] }),
996
- !!stats?.tags.length && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-nav-section", children: [
997
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kl-nav-label", children: "\u6807\u7B7E" }),
998
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kl-tag-cloud", children: stats.tags.slice(0, 15).map((tag) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { "aria-pressed": filter.tag === tag.name, onClick: () => chooseFilter({ tag: tag.name }), children: [
1184
+ !!stats?.tags.length && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-nav-section", children: [
1185
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "kl-nav-label", children: "\u6807\u7B7E" }),
1186
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "kl-tag-cloud", children: stats.tags.slice(0, 15).map((tag) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { "aria-pressed": filter.tag === tag.name, onClick: () => chooseFilter({ tag: tag.name }), children: [
999
1187
  "#",
1000
1188
  tag.name
1001
1189
  ] }, tag.name)) })
1002
1190
  ] }),
1003
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-nav-bottom", children: [
1004
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "kl-live-dot" }),
1191
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-nav-bottom", children: [
1192
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "kl-live-dot" }),
1005
1193
  "\u4FDD\u5B58\u5728\u8FD9\u53F0\u7535\u8111"
1006
1194
  ] })
1007
1195
  ] }),
1008
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "kl-list", "aria-label": "\u8D44\u6599\u5217\u8868", "aria-busy": loading, children: [
1009
- loading && !items.length ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-empty", children: [
1010
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "kl-spinner" }),
1196
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: "kl-list", "aria-label": "\u8D44\u6599\u5217\u8868", "aria-busy": loading, children: [
1197
+ loading && !items.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-empty", children: [
1198
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "kl-spinner" }),
1011
1199
  "\u6B63\u5728\u8BFB\u53D6\u8D44\u6599\u5E93\u2026"
1012
- ] }) : !items.length ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-empty", children: [
1013
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: filter.trashed ? "trash" : "inbox", size: 28 }),
1014
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { children: filter.trashed ? "\u56DE\u6536\u7AD9\u4E2D\u6CA1\u6709\u5339\u914D\u7684\u8D44\u6599" : query || Object.values(filter).some(Boolean) ? "\u6CA1\u6709\u627E\u5230\u5339\u914D\u7684\u8D44\u6599" : "\u8FD8\u6CA1\u6709\u8D44\u6599\uFF0C\u6536\u96C6\u7684\u5185\u5BB9\u4F1A\u663E\u793A\u5728\u8FD9\u91CC" }),
1015
- query && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "\u8BD5\u8BD5\u5176\u4ED6\u5173\u952E\u8BCD\uFF0C\u6216\u5207\u6362\u5206\u7C7B\u3002" }),
1016
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", onClick: () => query || Object.values(filter).some(Boolean) ? (setQuery(""), chooseFilter({})) : setEditor({ mode: "capture" }), children: query || Object.values(filter).some(Boolean) ? "\u67E5\u770B\u5168\u90E8\u8D44\u6599" : "\u6536\u96C6\u7B2C\u4E00\u4EFD\u8D44\u6599" })
1017
- ] }) : items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `kl-item-row ${batchMode ? "kl-selectable" : ""}`, children: [
1018
- batchMode && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "checkbox", className: "kl-material-checkbox", "aria-label": `\u9009\u62E9 ${item.title}`, checked: checkedIds.includes(item.id), disabled: item.kind === "note" || item.status !== "ready" || !!checkedIds.length && checkedIds.length >= 10 && !checkedIds.includes(item.id), onChange: (e) => setCheckedIds((ids) => e.target.checked ? [...ids, item.id] : ids.filter((id) => id !== item.id)) }),
1019
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: `kl-item ${selected === item.id ? "selected" : ""}`, onClick: () => {
1200
+ ] }) : !items.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-empty", children: [
1201
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: filter.trashed ? "trash" : "inbox", size: 28 }),
1202
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { children: filter.trashed ? "\u56DE\u6536\u7AD9\u4E2D\u6CA1\u6709\u5339\u914D\u7684\u8D44\u6599" : query || Object.values(filter).some(Boolean) ? "\u6CA1\u6709\u627E\u5230\u5339\u914D\u7684\u8D44\u6599" : "\u8FD8\u6CA1\u6709\u8D44\u6599\uFF0C\u6536\u96C6\u7684\u5185\u5BB9\u4F1A\u663E\u793A\u5728\u8FD9\u91CC" }),
1203
+ query && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: "\u8BD5\u8BD5\u5176\u4ED6\u5173\u952E\u8BCD\uFF0C\u6216\u5207\u6362\u5206\u7C7B\u3002" }),
1204
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary", onClick: () => query || Object.values(filter).some(Boolean) ? (setQuery(""), chooseFilter({})) : setEditor({ mode: "capture" }), children: query || Object.values(filter).some(Boolean) ? "\u67E5\u770B\u5168\u90E8\u8D44\u6599" : "\u6536\u96C6\u7B2C\u4E00\u4EFD\u8D44\u6599" })
1205
+ ] }) : items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `kl-item-row ${batchMode ? "kl-selectable" : ""}`, children: [
1206
+ batchMode && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "checkbox", className: "kl-material-checkbox", "aria-label": `\u9009\u62E9 ${item.title}`, checked: checkedIds.includes(item.id), disabled: item.kind === "note" || item.status !== "ready" || !!checkedIds.length && checkedIds.length >= 10 && !checkedIds.includes(item.id), onChange: (e) => setCheckedIds((ids) => e.target.checked ? [...ids, item.id] : ids.filter((id) => id !== item.id)) }),
1207
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: `kl-item ${selected === item.id ? "selected" : ""}`, onClick: () => {
1020
1208
  setAnchor(void 0);
1021
1209
  setSelected(item.id);
1022
1210
  }, children: [
1023
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-item-top", children: [
1024
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: `kl-type kl-type-${item.kind}`, children: [
1025
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: kinds[item.kind].icon, size: 15 }),
1211
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-item-top", children: [
1212
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: `kl-type kl-type-${item.kind}`, children: [
1213
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: kinds[item.kind].icon, size: 15 }),
1026
1214
  kinds[item.kind].label
1027
1215
  ] }),
1028
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("time", { children: date(item.createdAt) })
1216
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("time", { children: date(item.createdAt) })
1029
1217
  ] }),
1030
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { children: item.title }),
1031
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: item.excerpt || item.extraction }),
1032
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-item-bottom", children: [
1033
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "kl-category", children: [
1034
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "folder", size: 13 }),
1218
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { children: item.title }),
1219
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: item.excerpt || item.extraction }),
1220
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-item-bottom", children: [
1221
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "kl-category", children: [
1222
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "folder", size: 13 }),
1035
1223
  item.category
1036
1224
  ] }),
1037
- item.tags.slice(0, 2).map((tag) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "kl-chip", children: tag }, tag)),
1038
- item.status === "stored" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "kl-stored", children: "\u4EC5\u5F52\u6863" }),
1039
- !item.deletedAt && item.kind !== "note" && item.status === "ready" && knowledge?.supported && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(KnowledgeBadge, { state: knowledge.states[item.id] }),
1040
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "arrow", size: 15 })
1225
+ item.tags.slice(0, 2).map((tag) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "kl-chip", children: tag }, tag)),
1226
+ item.status === "stored" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "kl-stored", children: "\u4EC5\u5F52\u6863" }),
1227
+ !item.deletedAt && item.kind !== "note" && item.status === "ready" && knowledge?.supported && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(KnowledgeBadge, { state: knowledge.states[item.id] }),
1228
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "arrow", size: 15 })
1041
1229
  ] })
1042
1230
  ] }),
1043
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: `kl-icon-button kl-row-action ${item.deletedAt ? "" : "kl-danger"}`, title: item.deletedAt ? "\u6062\u590D\u8D44\u6599" : "\u5220\u9664\u8D44\u6599", "aria-label": `${item.deletedAt ? "\u6062\u590D" : "\u5220\u9664"} ${item.title}`, disabled: !stats || !!restoring, onClick: () => item.deletedAt ? void restoreItem(item.id) : askDelete(item), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: item.deletedAt ? "restore" : "trash", size: 16 }) })
1231
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: `kl-icon-button kl-row-action ${item.deletedAt ? "" : "kl-danger"}`, title: item.deletedAt ? "\u6062\u590D\u8D44\u6599" : "\u5220\u9664\u8D44\u6599", "aria-label": `${item.deletedAt ? "\u6062\u590D" : "\u5220\u9664"} ${item.title}`, disabled: !stats || !!restoring, onClick: () => item.deletedAt ? void restoreItem(item.id) : askDelete(item), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: item.deletedAt ? "restore" : "trash", size: 16 }) })
1044
1232
  ] }, item.id)),
1045
- items.length < total && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-load-more", onClick: () => setLimit((v) => Math.min(100, v + 40)), disabled: limit >= 100, children: limit >= 100 ? "\u8BF7\u7F29\u5C0F\u641C\u7D22\u8303\u56F4\uFF08\u6700\u591A\u663E\u793A 100 \u6761\uFF09" : "\u52A0\u8F7D\u66F4\u591A" })
1233
+ items.length < total && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-load-more", onClick: () => setLimit((v) => Math.min(100, v + 40)), disabled: limit >= 100, children: limit >= 100 ? "\u8BF7\u7F29\u5C0F\u641C\u7D22\u8303\u56F4\uFF08\u6700\u591A\u663E\u793A 100 \u6761\uFF09" : "\u52A0\u8F7D\u66F4\u591A" })
1046
1234
  ] }),
1047
- selected && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "kl-detail", "aria-label": "\u8D44\u6599\u8BE6\u60C5", ref: detailRef, children: [
1048
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-detail-toolbar", children: [
1049
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: "kl-back", onClick: () => {
1235
+ selected && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: "kl-detail", "aria-label": "\u8D44\u6599\u8BE6\u60C5", ref: detailRef, children: [
1236
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-detail-toolbar", children: [
1237
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "kl-back", onClick: () => {
1050
1238
  setSelected(void 0);
1051
1239
  setDetail(void 0);
1052
1240
  }, children: [
1053
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "close", size: 18 }),
1054
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u5173\u95ED\u9605\u8BFB" })
1241
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "close", size: 18 }),
1242
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u5173\u95ED\u9605\u8BFB" })
1055
1243
  ] }),
1056
- detail && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1057
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { title: "\u590D\u5236\u8D44\u6599\u5F15\u7528", "aria-label": "\u590D\u5236\u8D44\u6599\u5F15\u7528", onClick: () => void copy(`library://${detail.id}`), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "copy", size: 17 }) }),
1058
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("a", { title: "\u5BFC\u51FA Markdown", "aria-label": "\u5BFC\u51FA Markdown", href: `${API}/materials/${detail.id}/export`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "download", size: 17 }) }),
1059
- detail.deletedAt ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { disabled: !stats || !!restoring, onClick: () => void restoreItem(detail.id), children: [
1060
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "restore", size: 16 }),
1244
+ detail && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1245
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { title: "\u590D\u5236\u8D44\u6599\u5F15\u7528", "aria-label": "\u590D\u5236\u8D44\u6599\u5F15\u7528", onClick: () => void copy(`library://${detail.id}`), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "copy", size: 17 }) }),
1246
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("a", { title: "\u5BFC\u51FA Markdown", "aria-label": "\u5BFC\u51FA Markdown", href: `${API}/materials/${detail.id}/export`, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "download", size: 17 }) }),
1247
+ detail.deletedAt ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { disabled: !stats || !!restoring, onClick: () => void restoreItem(detail.id), children: [
1248
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "restore", size: 16 }),
1061
1249
  "\u6062\u590D\u8D44\u6599"
1062
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1063
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { onClick: () => setEditor({ mode: "edit", source: detail }), children: "\u7F16\u8F91\u4FE1\u606F" }),
1064
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-danger", title: "\u5220\u9664\u8D44\u6599", "aria-label": "\u5220\u9664\u8D44\u6599", disabled: !stats || !!restoring, onClick: () => askDelete(detail), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "trash", size: 17 }) })
1250
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1251
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: () => setEditor({ mode: "edit", source: detail }), children: "\u7F16\u8F91\u4FE1\u606F" }),
1252
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-danger", title: "\u5220\u9664\u8D44\u6599", "aria-label": "\u5220\u9664\u8D44\u6599", disabled: !stats || !!restoring, onClick: () => askDelete(detail), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "trash", size: 17 }) })
1065
1253
  ] })
1066
1254
  ] })
1067
1255
  ] }),
1068
- detailLoading ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-empty", children: [
1069
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "kl-spinner" }),
1256
+ detailLoading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-empty", children: [
1257
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "kl-spinner" }),
1070
1258
  "\u8BFB\u53D6\u4E2D\u2026"
1071
- ] }) : detail && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("article", { children: [
1072
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-detail-kicker", children: [
1073
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: kinds[detail.kind].label }),
1074
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: detail.category })
1259
+ ] }) : detail && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("article", { children: [
1260
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-detail-kicker", children: [
1261
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: kinds[detail.kind].label }),
1262
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: detail.category })
1075
1263
  ] }),
1076
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { children: detail.title }),
1077
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-source", children: [
1078
- detail.sourceUrl ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("a", { href: detail.sourceUrl, target: "_blank", rel: "noreferrer", children: [
1264
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h2", { children: detail.title }),
1265
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-source", children: [
1266
+ detail.sourceUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("a", { href: detail.sourceUrl, target: "_blank", rel: "noreferrer", children: [
1079
1267
  new URL(detail.sourceUrl).hostname,
1080
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "arrow", size: 12 })
1081
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: detail.originalName || "\u672C\u5730\u6536\u96C6" }),
1082
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: new Date(detail.createdAt).toLocaleDateString("zh-CN") }),
1083
- detail.author && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: detail.author })
1268
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "arrow", size: 12 })
1269
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: detail.originalName || "\u672C\u5730\u6536\u96C6" }),
1270
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: new Date(detail.createdAt).toLocaleDateString("zh-CN") }),
1271
+ detail.author && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: detail.author })
1084
1272
  ] }),
1085
- !!detail.tags.length && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kl-detail-tags", children: detail.tags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "kl-chip", children: [
1273
+ !!detail.tags.length && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "kl-detail-tags", children: detail.tags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "kl-chip", children: [
1086
1274
  "#",
1087
1275
  t
1088
1276
  ] }, t)) }),
1089
- detail.sourceNote && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("aside", { className: "kl-source-note", children: detail.sourceNote }),
1090
- detail.deletedAt && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-notice", children: [
1091
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "trash" }),
1092
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1093
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "\u8FD9\u4EFD\u8D44\u6599\u5728\u56DE\u6536\u7AD9" }),
1094
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "\u539F\u6587\u4E0E\u6765\u6E90\u5F15\u7528\u4ECD\u53EF\u67E5\u770B\uFF0C\u6062\u590D\u540E\u56DE\u5230\u539F\u5206\u7C7B\u3002" })
1277
+ detail.sourceNote && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("aside", { className: "kl-source-note", children: detail.sourceNote }),
1278
+ detail.deletedAt && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-notice", children: [
1279
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "trash" }),
1280
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1281
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "\u8FD9\u4EFD\u8D44\u6599\u5728\u56DE\u6536\u7AD9" }),
1282
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: "\u539F\u6587\u4E0E\u6765\u6E90\u5F15\u7528\u4ECD\u53EF\u67E5\u770B\uFF0C\u6062\u590D\u540E\u56DE\u5230\u539F\u5206\u7C7B\u3002" })
1095
1283
  ] })
1096
1284
  ] }),
1097
- detail.status === "stored" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-notice", children: [
1098
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "file" }),
1099
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1100
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "\u539F\u6587\u4EF6\u5DF2\u5B89\u5168\u5F52\u6863" }),
1101
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: detail.extraction })
1285
+ detail.status === "stored" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-notice", children: [
1286
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "file" }),
1287
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1288
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "\u539F\u6587\u4EF6\u5DF2\u5B89\u5168\u5F52\u6863" }),
1289
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: detail.extraction })
1102
1290
  ] })
1103
1291
  ] }),
1104
- !detail.deletedAt && detail.kind !== "note" && detail.status === "ready" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-knowledge-source", children: [
1105
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1106
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(KnowledgeBadge, { state: knowledge?.states[detail.id] }),
1107
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u4ECE\u8FD9\u4EFD\u8D44\u6599\u5F62\u6210\u7406\u89E3\u3001\u65B9\u6CD5\u4E0E\u5F85\u9A8C\u8BC1\u7684\u95EE\u9898\u3002" })
1292
+ !detail.deletedAt && detail.kind !== "note" && detail.status === "ready" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-knowledge-source", children: [
1293
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1294
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(KnowledgeBadge, { state: knowledge?.states[detail.id] }),
1295
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u4ECE\u8FD9\u4EFD\u8D44\u6599\u5F62\u6210\u7406\u89E3\u3001\u65B9\u6CD5\u4E0E\u5F85\u9A8C\u8BC1\u7684\u95EE\u9898\u3002" })
1108
1296
  ] }),
1109
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-knowledge-actions", children: [
1110
- ["running", "draft", "grouping"].includes(knowledge?.states[detail.id]?.status || "") ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", onClick: () => stats && setKnowledgeOpen({ root: stats.root, jobId: knowledge?.states[detail.id]?.jobId }), children: knowledge?.states[detail.id]?.status === "grouping" ? "\u67E5\u770B\u5206\u7EC4\u65B9\u6848" : "\u67E5\u770B\u6574\u7406\u4EFB\u52A1" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", disabled: !knowledge?.supported, onClick: () => generateFor([detail.id]), children: "\u751F\u6210\u77E5\u8BC6\u7B14\u8BB0" }),
1111
- knowledge?.states[detail.id]?.noteIds.map((id) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: "kl-secondary", onClick: () => openKnowledgeSource(id), children: [
1297
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-knowledge-actions", children: [
1298
+ ["running", "draft", "grouping"].includes(knowledge?.states[detail.id]?.status || "") ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary", onClick: () => stats && setKnowledgeOpen({ root: stats.root, jobId: knowledge?.states[detail.id]?.jobId }), children: knowledge?.states[detail.id]?.status === "grouping" ? "\u67E5\u770B\u5206\u7EC4\u65B9\u6848" : "\u67E5\u770B\u6574\u7406\u4EFB\u52A1" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary", disabled: !knowledge?.supported || imagesPending(detail), onClick: () => generateFor([detail.id]), children: "\u751F\u6210\u77E5\u8BC6\u7B14\u8BB0" }),
1299
+ knowledge?.states[detail.id]?.noteIds.map((id) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "kl-secondary", onClick: () => openKnowledgeSource(id), children: [
1112
1300
  "\u67E5\u770B\u77E5\u8BC6\u7B14\u8BB0",
1113
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "arrow", size: 14 })
1301
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "arrow", size: 14 })
1114
1302
  ] }, id))
1115
1303
  ] }),
1116
- !knowledge?.supported && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-muted", children: "\u8BF7\u91CD\u542F\u8D44\u6599\u5E93\u670D\u52A1\u4EE5\u542F\u7528\u77E5\u8BC6\u6574\u7406\u3002" })
1304
+ !knowledge?.supported && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-muted", children: "\u8BF7\u91CD\u542F\u8D44\u6599\u5E93\u670D\u52A1\u4EE5\u542F\u7528\u77E5\u8BC6\u6574\u7406\u3002" })
1117
1305
  ] }),
1118
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kl-content", children: detail.segments.map((segment) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `kl-segment ${anchor === segment.id ? "kl-cited" : ""}`, id: segment.id, "data-segment-id": segment.id, children: [
1119
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-segment-line", children: [
1120
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: segment.startSeconds !== void 0 ? time(segment.startSeconds) : segment.id }),
1121
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { title: "\u6458\u5F55\u4E3A\u7B14\u8BB0", "aria-label": `\u6458\u5F55 ${segment.id} \u4E3A\u7B14\u8BB0`, onClick: () => setEditor({ mode: "note", source: detail, segment }), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "note", size: 14 }) }),
1122
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { title: "\u590D\u5236\u6BB5\u843D\u5F15\u7528", "aria-label": `\u590D\u5236 ${segment.id} \u5F15\u7528`, onClick: () => void copy(`library://${detail.id}/${segment.id}`), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "copy", size: 14 }) })
1306
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PageImages, { detail, onRetry: () => stats && setImageRetry({ id: detail.id, root: stats.root }), onJump: setAnchor }),
1307
+ imagesPending(detail) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-image-policy", children: "\u6B63\u6587\u5DF2\u4FDD\u5B58\uFF0C\u56FE\u7247\u4ECD\u5728\u5904\u7406\u4E2D\u3002\u56FE\u7247\u5904\u7406\u7ED3\u675F\u6216\u505C\u6B62\u540E\u53EF\u751F\u6210\u77E5\u8BC6\u7B14\u8BB0\u3002" }),
1308
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "kl-content", children: detail.segments.map((segment) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `kl-segment ${anchor === segment.id ? "kl-cited" : ""}`, id: segment.id, "data-segment-id": segment.id, children: [
1309
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-segment-line", children: [
1310
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: segment.startSeconds !== void 0 ? time(segment.startSeconds) : segment.id }),
1311
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { title: "\u6458\u5F55\u4E3A\u7B14\u8BB0", "aria-label": `\u6458\u5F55 ${segment.id} \u4E3A\u7B14\u8BB0`, onClick: () => setEditor({ mode: "note", source: detail, segment }), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "note", size: 14 }) }),
1312
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { title: "\u590D\u5236\u6BB5\u843D\u5F15\u7528", "aria-label": `\u590D\u5236 ${segment.id} \u5F15\u7528`, onClick: () => void copy(`library://${detail.id}/${segment.id}`), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "copy", size: 14 }) })
1123
1313
  ] }),
1124
- /^#{1,6}\s/.test(segment.text) ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: segment.text.replace(/^#{1,6}\s+/, "") }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: segment.text })
1314
+ /^#{1,6}\s/.test(segment.text) ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { children: segment.text.replace(/^#{1,6}\s+/, "") }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: segment.text })
1125
1315
  ] }, segment.id)) }),
1126
- !!detail.citations.length && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-references", children: [
1127
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: "\u6765\u6E90\u5F15\u7528" }),
1128
- detail.citations.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { disabled: detail.missingSources?.includes(c.materialId), "aria-label": `\u67E5\u770B\u5F15\u7528 ${i + 1}`, onClick: () => {
1316
+ !!detail.citations.length && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-references", children: [
1317
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { children: "\u6765\u6E90\u5F15\u7528" }),
1318
+ detail.citations.map((c, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { disabled: detail.missingSources?.includes(c.materialId), "aria-label": `\u67E5\u770B\u5F15\u7528 ${i + 1}`, onClick: () => {
1129
1319
  setAnchor(c.segmentId);
1130
1320
  setSelected(c.materialId);
1131
1321
  }, children: [
1132
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "file", size: 15 }),
1133
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: detail.missingSources?.includes(c.materialId) ? "\u6765\u6E90\u5DF2\u6C38\u4E45\u5220\u9664" : `${c.materialId.slice(0, 15)}\u2026${c.segmentId ? ` / ${c.segmentId}` : ""}` }),
1134
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "arrow", size: 14 })
1322
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "file", size: 15 }),
1323
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: detail.missingSources?.includes(c.materialId) ? "\u6765\u6E90\u5DF2\u6C38\u4E45\u5220\u9664" : `${c.materialId.slice(0, 15)}\u2026${c.segmentId ? ` / ${c.segmentId}` : ""}` }),
1324
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "arrow", size: 14 })
1135
1325
  ] }, i))
1136
1326
  ] }),
1137
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("footer", { className: "kl-detail-footer", children: [
1138
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1139
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "kl-live-dot" }),
1327
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("footer", { className: "kl-detail-footer", children: [
1328
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1329
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "kl-live-dot" }),
1140
1330
  detail.extraction
1141
1331
  ] }),
1142
- detail.originalFile && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("a", { href: `${API}/materials/${detail.id}/original`, children: [
1332
+ detail.originalFile && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("a", { href: `${API}/materials/${detail.id}/original`, children: [
1143
1333
  "\u4E0B\u8F7D\u539F\u59CB\u6587\u4EF6",
1144
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "download", size: 14 })
1334
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "download", size: 14 })
1145
1335
  ] }),
1146
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { children: detail.id })
1336
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: detail.id })
1147
1337
  ] })
1148
1338
  ] })
1149
1339
  ] })
1150
1340
  ] })
1151
1341
  ] }),
1152
- generation && knowledge && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StartKnowledgeDialog, { root: generation.root, sourceIds: generation.sourceIds, model: knowledge, initialMode: generation.mode, onClose: () => setGeneration(void 0), onCreated: (job) => {
1342
+ generation && knowledge && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(StartKnowledgeDialog, { root: generation.root, sourceIds: generation.sourceIds, model: knowledge, initialMode: generation.mode, onClose: () => setGeneration(void 0), onCreated: (job) => {
1153
1343
  setGeneration(void 0);
1154
1344
  setCheckedIds([]);
1155
1345
  setBatchMode(false);
1156
1346
  setKnowledgeOpen({ root: generation.root, jobId: job.id });
1157
1347
  refresh();
1158
1348
  } }),
1159
- knowledgeOpen && knowledge && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(KnowledgeJobsDialog, { root: knowledgeOpen.root, jobId: knowledgeOpen.jobId, overview: knowledge, onClose: () => setKnowledgeOpen(void 0), onRefresh: refresh, onRegenerate: (ids, mode) => {
1349
+ knowledgeOpen && knowledge && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(KnowledgeJobsDialog, { root: knowledgeOpen.root, jobId: knowledgeOpen.jobId, overview: knowledge, onClose: () => setKnowledgeOpen(void 0), onRefresh: refresh, onRegenerate: (ids, mode) => {
1160
1350
  setKnowledgeOpen(void 0);
1161
1351
  generateFor(ids, mode);
1162
1352
  }, onOpenSource: openKnowledgeSource, onSaved: (id) => {
1163
1353
  openKnowledgeSource(id);
1164
1354
  notify("\u77E5\u8BC6\u7B14\u8BB0\u5DF2\u4FDD\u5B58\uFF0C\u539F\u59CB\u8D44\u6599\u5DF2\u4FDD\u7559");
1165
1355
  }, onNotify: notify }),
1166
- editor && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EditorDialog, { editor, categories: stats?.categories.map((c) => c.name) || [], onClose: () => setEditor(void 0), onSaved: (result) => {
1356
+ editor && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(EditorDialog, { editor, categories: stats?.categories.map((c) => c.name) || [], onClose: () => setEditor(void 0), onSaved: (result) => {
1167
1357
  setEditor(void 0);
1168
1358
  refresh();
1169
1359
  if (result.material) {
@@ -1179,11 +1369,11 @@ function App() {
1179
1369
  notify("\u7F51\u9875\u5DF2\u52A0\u5165\u91C7\u96C6\u961F\u5217");
1180
1370
  }
1181
1371
  } }),
1182
- deletion && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DeleteDialog, { item: deletion, onClose: () => setDeletion(void 0), onDeleted: () => {
1372
+ deletion && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DeleteDialog, { item: deletion, onClose: () => setDeletion(void 0), onDeleted: () => {
1183
1373
  setDeletion(void 0);
1184
1374
  afterRemoval(deletion.id, "\u8D44\u6599\u5DF2\u79FB\u5165\u56DE\u6536\u7AD9\uFF0C\u53EF\u968F\u65F6\u6062\u590D");
1185
1375
  } }),
1186
- emptyRoot && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EmptyTrashDialog, { root: emptyRoot, onClose: () => setEmptyRoot(void 0), onEmptied: (result) => {
1376
+ emptyRoot && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(EmptyTrashDialog, { root: emptyRoot, onClose: () => setEmptyRoot(void 0), onEmptied: (result) => {
1187
1377
  setEmptyRoot(void 0);
1188
1378
  setSelected(void 0);
1189
1379
  setDetail(void 0);
@@ -1194,41 +1384,63 @@ function App() {
1194
1384
  else notify(`\u56DE\u6536\u7AD9\u5DF2\u6E05\u7A7A\uFF0C\u6C38\u4E45\u5220\u9664 ${result.deleted} \u4EFD\u8D44\u6599`);
1195
1385
  searchRef.current?.focus();
1196
1386
  } }),
1197
- showJobs && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Dialog, { title: "\u91C7\u96C6\u4EFB\u52A1", description: "\u7F51\u9875\u5728\u540E\u53F0\u63D0\u53D6\u6B63\u6587\u3002\u5173\u95ED\u5E94\u7528\u540E\uFF0C\u4E0B\u6B21\u542F\u52A8\u4F1A\u6062\u590D\u672A\u5B8C\u6210\u4EFB\u52A1\u3002", onClose: () => setShowJobs(false), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kl-jobs", children: !jobs.length ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-muted", children: "\u8FD8\u6CA1\u6709\u91C7\u96C6\u4EFB\u52A1\u3002\u6DFB\u52A0\u4E00\u4E2A\u7F51\u9875\u94FE\u63A5\u5F00\u59CB\u3002" }) : jobs.map((job) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-job", children: [
1198
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1199
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: `kl-job-status ${job.status}`, children: job.status === "failed" && job.errorCode === "PAGE_REQUIRES_BROWSER" ? "\u9700\u6D4F\u89C8\u5668\u9A8C\u8BC1" : { queued: "\u6392\u961F\u4E2D", running: "\u63D0\u53D6\u4E2D", completed: "\u5DF2\u5B8C\u6210", failed: "\u5931\u8D25" }[job.status] }),
1200
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("time", { children: date(job.createdAt) })
1387
+ imageRetry && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ImageRetryDialog, { ...imageRetry, onClose: () => setImageRetry(void 0), onStarted: () => {
1388
+ setImageRetry(void 0);
1389
+ refresh();
1390
+ notify("\u5931\u8D25\u56FE\u7247\u5DF2\u52A0\u5165\u91CD\u8BD5\u961F\u5217");
1391
+ } }),
1392
+ showJobs && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog, { title: "\u91C7\u96C6\u4EFB\u52A1", description: "\u7F51\u9875\u5728\u540E\u53F0\u63D0\u53D6\u6B63\u6587\u548C\u5DF2\u542F\u7528\u7684\u56FE\u7247\u3002\u56FE\u7247\u8BC6\u522B\u4E2D\u65AD\u540E\u9700\u4E3B\u52A8\u91CD\u8BD5\uFF0C\u4E0D\u4F1A\u5728\u91CD\u542F\u65F6\u81EA\u52A8\u91CD\u590D\u6A21\u578B\u8BF7\u6C42\u3002", onClose: () => setShowJobs(false), children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "kl-jobs", children: !jobs.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-muted", children: "\u8FD8\u6CA1\u6709\u91C7\u96C6\u4EFB\u52A1\u3002\u6DFB\u52A0\u4E00\u4E2A\u7F51\u9875\u94FE\u63A5\u5F00\u59CB\u3002" }) : jobs.map((job) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-job", children: [
1393
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1394
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: `kl-job-status ${job.status}`, children: job.status === "failed" && job.errorCode === "PAGE_REQUIRES_BROWSER" ? "\u9700\u6D4F\u89C8\u5668\u9A8C\u8BC1" : { queued: "\u6392\u961F\u4E2D", running: "\u63D0\u53D6\u4E2D", completed: "\u5DF2\u5B8C\u6210", failed: "\u5931\u8D25" }[job.status] }),
1395
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("time", { children: date(job.createdAt) })
1396
+ ] }),
1397
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: job.url }),
1398
+ job.progress && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: job.progress }),
1399
+ job.imageSummary && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { children: [
1400
+ "\u56FE\u7247\uFF1A",
1401
+ job.imageSummary.completed,
1402
+ " \u5F20\u5DF2\u8BC6\u522B \xB7 ",
1403
+ job.imageSummary.failed,
1404
+ " \u5F20\u672A\u5B8C\u6210 \xB7 ",
1405
+ job.imageSummary.skipped,
1406
+ " \u5F20\u8DF3\u8FC7"
1201
1407
  ] }),
1202
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: job.url }),
1203
- job.error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { role: job.status === "failed" ? "alert" : void 0, children: job.error }),
1204
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-job-actions", children: [
1205
- job.materialId && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { onClick: () => {
1408
+ job.error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: job.status === "failed" ? "alert" : void 0, children: job.error }),
1409
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-job-actions", children: [
1410
+ job.materialId && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { onClick: () => {
1206
1411
  setSelected(job.materialId);
1207
1412
  setShowJobs(false);
1208
1413
  refresh();
1209
1414
  }, children: [
1210
1415
  "\u67E5\u770B\u8D44\u6599 ",
1211
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "arrow", size: 14 })
1416
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "arrow", size: 14 })
1212
1417
  ] }),
1213
- job.status === "failed" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1214
- /^https?:\/\//i.test(job.url) && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("a", { href: job.url, target: "_blank", rel: "noopener noreferrer", children: [
1418
+ job.materialId && job.imageCapture && ["queued", "running"].includes(job.status) && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: () => void post(`/jobs/${job.id}/images/cancel`, { expectedRoot: stats?.root }).then(refresh).catch((e) => setError(e.message)), children: "\u505C\u6B62\u56FE\u7247\u5904\u7406" }),
1419
+ job.materialId && job.status === "completed" && !!job.imageSummary?.failed && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: () => {
1420
+ if (stats) {
1421
+ setShowJobs(false);
1422
+ setImageRetry({ id: job.materialId, root: stats.root });
1423
+ }
1424
+ }, children: "\u91CD\u8BD5\u5931\u8D25\u56FE\u7247" }),
1425
+ job.status === "failed" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1426
+ /^https?:\/\//i.test(job.url) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("a", { href: job.url, target: "_blank", rel: "noopener noreferrer", children: [
1215
1427
  "\u6253\u5F00\u539F\u7F51\u9875",
1216
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "arrow", size: 14 })
1428
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "arrow", size: 14 })
1217
1429
  ] }),
1218
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { onClick: () => {
1430
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: () => {
1219
1431
  setShowJobs(false);
1220
1432
  setEditor({ mode: "capture", initialType: "text", sourceUrl: job.url });
1221
1433
  }, children: "\u7C98\u8D34\u6B63\u6587" }),
1222
- /fake-ip/i.test(job.error || "") && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { onClick: () => {
1434
+ /fake-ip/i.test(job.error || "") && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: () => {
1223
1435
  setShowJobs(false);
1224
1436
  setSettingsFromJobs(true);
1225
1437
  setShowInfo(true);
1226
1438
  }, children: "\u4EE3\u7406\u517C\u5BB9\u8BBE\u7F6E" }),
1227
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { onClick: () => void post(`/jobs/${job.id}/retry`, {}).then(refresh).catch((e) => setError(e.message)), children: "\u91CD\u65B0\u91C7\u96C6" })
1439
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { onClick: () => void post(`/jobs/${job.id}/retry`, {}).then(refresh).catch((e) => setError(e.message)), children: "\u91CD\u65B0\u91C7\u96C6" })
1228
1440
  ] })
1229
1441
  ] })
1230
1442
  ] }, job.id)) }) }),
1231
- showInfo && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SettingsDialog, { root: stats?.root || "", warnings: stats?.warnings || [], onClose: () => {
1443
+ showInfo && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SettingsDialog, { root: stats?.root || "", warnings: stats?.warnings || [], onClose: () => {
1232
1444
  setShowInfo(false);
1233
1445
  if (settingsFromJobs) setShowJobs(true);
1234
1446
  setSettingsFromJobs(false);
@@ -1253,15 +1465,15 @@ function App() {
1253
1465
  setSettingsFromJobs(false);
1254
1466
  }
1255
1467
  } }),
1256
- toast && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-toast", role: "status", children: [
1257
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "check", size: 17 }),
1468
+ toast && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-toast", role: "status", children: [
1469
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "check", size: 17 }),
1258
1470
  toast
1259
1471
  ] })
1260
1472
  ] });
1261
1473
  }
1262
1474
  function DeleteDialog({ item, onClose, onDeleted }) {
1263
- const [busy, setBusy] = (0, import_react4.useState)(false);
1264
- const [error, setError] = (0, import_react4.useState)("");
1475
+ const [busy, setBusy] = (0, import_react5.useState)(false);
1476
+ const [error, setError] = (0, import_react5.useState)("");
1265
1477
  async function remove() {
1266
1478
  setBusy(true);
1267
1479
  setError("");
@@ -1274,23 +1486,23 @@ function DeleteDialog({ item, onClose, onDeleted }) {
1274
1486
  setBusy(false);
1275
1487
  }
1276
1488
  }
1277
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Dialog, { title: "\u5220\u9664\u8D44\u6599", description: "\u8D44\u6599\u5C06\u79FB\u5165\u56DE\u6536\u7AD9\uFF0C\u539F\u6587\u4EF6\u4FDD\u7559\uFF0C\u53EF\u968F\u65F6\u6062\u590D\u3002", onClose: () => {
1489
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog, { title: "\u5220\u9664\u8D44\u6599", description: "\u8D44\u6599\u5C06\u79FB\u5165\u56DE\u6536\u7AD9\uFF0C\u539F\u6587\u4EF6\u4FDD\u7559\uFF0C\u53EF\u968F\u65F6\u6062\u590D\u3002", onClose: () => {
1278
1490
  if (!busy) onClose();
1279
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-delete-dialog", children: [
1280
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-delete-title", children: item.title }),
1281
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-muted", children: "\u5DF2\u6709\u7B14\u8BB0\u4ECD\u80FD\u67E5\u770B\u8FD9\u4EFD\u8D44\u6599\u7684\u6765\u6E90\u5F15\u7528\u3002" }),
1282
- error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-form-error", role: "alert", children: error }),
1283
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("footer", { children: [
1284
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", disabled: busy, onClick: onClose, children: "\u53D6\u6D88" }),
1285
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary kl-danger", disabled: busy, onClick: () => void remove(), children: busy ? "\u6B63\u5728\u5220\u9664\u2026" : "\u79FB\u5165\u56DE\u6536\u7AD9" })
1491
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-delete-dialog", children: [
1492
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-delete-title", children: item.title }),
1493
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-muted", children: "\u5DF2\u6709\u7B14\u8BB0\u4ECD\u80FD\u67E5\u770B\u8FD9\u4EFD\u8D44\u6599\u7684\u6765\u6E90\u5F15\u7528\u3002" }),
1494
+ error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-form-error", role: "alert", children: error }),
1495
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("footer", { children: [
1496
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary", disabled: busy, onClick: onClose, children: "\u53D6\u6D88" }),
1497
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary kl-danger", disabled: busy, onClick: () => void remove(), children: busy ? "\u6B63\u5728\u5220\u9664\u2026" : "\u79FB\u5165\u56DE\u6536\u7AD9" })
1286
1498
  ] })
1287
1499
  ] }) });
1288
1500
  }
1289
1501
  function EmptyTrashDialog({ root, onClose, onEmptied }) {
1290
- const [snapshot, setSnapshot] = (0, import_react4.useState)();
1291
- const [busy, setBusy] = (0, import_react4.useState)(false);
1292
- const [error, setError] = (0, import_react4.useState)("");
1293
- (0, import_react4.useEffect)(() => {
1502
+ const [snapshot, setSnapshot] = (0, import_react5.useState)();
1503
+ const [busy, setBusy] = (0, import_react5.useState)(false);
1504
+ const [error, setError] = (0, import_react5.useState)("");
1505
+ (0, import_react5.useEffect)(() => {
1294
1506
  const abort = new AbortController();
1295
1507
  void api("/trash", { signal: abort.signal }).then(setSnapshot).catch((e) => {
1296
1508
  if (!abort.signal.aborted) setError(e.message);
@@ -1310,35 +1522,35 @@ function EmptyTrashDialog({ root, onClose, onEmptied }) {
1310
1522
  setBusy(false);
1311
1523
  }
1312
1524
  }
1313
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Dialog, { title: "\u6E05\u7A7A\u56DE\u6536\u7AD9", description: "\u6C38\u4E45\u5220\u9664\u540E\u65E0\u6CD5\u6062\u590D\uFF0C\u8BF7\u786E\u8BA4\u6574\u4E2A\u56DE\u6536\u7AD9\u5185\u7684\u8D44\u6599\u90FD\u4E0D\u518D\u9700\u8981\u3002", onClose: () => {
1525
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog, { title: "\u6E05\u7A7A\u56DE\u6536\u7AD9", description: "\u6C38\u4E45\u5220\u9664\u540E\u65E0\u6CD5\u6062\u590D\uFF0C\u8BF7\u786E\u8BA4\u6574\u4E2A\u56DE\u6536\u7AD9\u5185\u7684\u8D44\u6599\u90FD\u4E0D\u518D\u9700\u8981\u3002", onClose: () => {
1314
1526
  if (!busy) onClose();
1315
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-delete-dialog", children: [
1316
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-delete-title", children: snapshot ? `\u5C06\u6C38\u4E45\u5220\u9664\u56DE\u6536\u7AD9\u4E2D\u7684\u5168\u90E8 ${snapshot.count} \u4EFD\u8D44\u6599\u3002` : error ? "\u8BF7\u5173\u95ED\u7A97\u53E3\u540E\u91CD\u65B0\u786E\u8BA4\u3002" : "\u6B63\u5728\u6838\u5BF9\u56DE\u6536\u7AD9\u2026" }),
1317
- !!snapshot?.pending && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { children: [
1527
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-delete-dialog", children: [
1528
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-delete-title", children: snapshot ? `\u5C06\u6C38\u4E45\u5220\u9664\u56DE\u6536\u7AD9\u4E2D\u7684\u5168\u90E8 ${snapshot.count} \u4EFD\u8D44\u6599\u3002` : error ? "\u8BF7\u5173\u95ED\u7A97\u53E3\u540E\u91CD\u65B0\u786E\u8BA4\u3002" : "\u6B63\u5728\u6838\u5BF9\u56DE\u6536\u7AD9\u2026" }),
1529
+ !!snapshot?.pending && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { children: [
1318
1530
  "\u53E6\u6709 ",
1319
1531
  snapshot.pending,
1320
1532
  " \u4EFD\u5DF2\u786E\u8BA4\u5220\u9664\u7684\u6587\u4EF6\u5C06\u7EE7\u7EED\u6E05\u7406\u3002"
1321
1533
  ] }),
1322
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-muted", children: "\u6B63\u6587\u3001\u539F\u59CB\u9644\u4EF6\u548C\u7D22\u5F15\u5C06\u88AB\u79FB\u9664\u3002\u76F8\u5173\u7B14\u8BB0\u7684\u6B63\u6587\u4F1A\u4FDD\u7559\uFF0C\u5F15\u7528\u8FD9\u4E9B\u8D44\u6599\u7684\u4F4D\u7F6E\u5C06\u6807\u8BB0\u4E3A\u201C\u6765\u6E90\u5DF2\u6C38\u4E45\u5220\u9664\u201D\u3002" }),
1323
- error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { role: "alert", className: "kl-form-error", children: error }),
1324
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("footer", { children: [
1325
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", disabled: busy, onClick: onClose, children: "\u53D6\u6D88" }),
1326
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary kl-danger", disabled: busy || !snapshot || !(snapshot.count || snapshot.pending), onClick: () => void empty(), children: busy ? "\u6B63\u5728\u6C38\u4E45\u5220\u9664\u2026" : "\u6C38\u4E45\u6E05\u7A7A" })
1534
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-muted", children: "\u6B63\u6587\u3001\u539F\u59CB\u9644\u4EF6\u548C\u7D22\u5F15\u5C06\u88AB\u79FB\u9664\u3002\u76F8\u5173\u7B14\u8BB0\u7684\u6B63\u6587\u4F1A\u4FDD\u7559\uFF0C\u5F15\u7528\u8FD9\u4E9B\u8D44\u6599\u7684\u4F4D\u7F6E\u5C06\u6807\u8BB0\u4E3A\u201C\u6765\u6E90\u5DF2\u6C38\u4E45\u5220\u9664\u201D\u3002" }),
1535
+ error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "alert", className: "kl-form-error", children: error }),
1536
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("footer", { children: [
1537
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary", disabled: busy, onClick: onClose, children: "\u53D6\u6D88" }),
1538
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary kl-danger", disabled: busy || !snapshot || !(snapshot.count || snapshot.pending), onClick: () => void empty(), children: busy ? "\u6B63\u5728\u6C38\u4E45\u5220\u9664\u2026" : "\u6C38\u4E45\u6E05\u7A7A" })
1327
1539
  ] })
1328
1540
  ] }) });
1329
1541
  }
1330
1542
  function SettingsDialog({ root, warnings, onClose, onChanged, onRebuilt, onProxySaved }) {
1331
- const [settings, setSettings] = (0, import_react4.useState)();
1332
- const [proxyMode, setProxyMode] = (0, import_react4.useState)(false);
1333
- const [target, setTarget] = (0, import_react4.useState)(root);
1334
- const [listing, setListing] = (0, import_react4.useState)();
1335
- const [browsePath, setBrowsePath] = (0, import_react4.useState)("");
1336
- const [browsing, setBrowsing] = (0, import_react4.useState)(false);
1337
- const [busy, setBusy] = (0, import_react4.useState)(false);
1338
- const [saving, setSaving] = (0, import_react4.useState)(false);
1339
- const [error, setError] = (0, import_react4.useState)("");
1340
- const request = (0, import_react4.useRef)();
1341
- (0, import_react4.useEffect)(() => {
1543
+ const [settings, setSettings] = (0, import_react5.useState)();
1544
+ const [proxyMode, setProxyMode] = (0, import_react5.useState)(false);
1545
+ const [target, setTarget] = (0, import_react5.useState)(root);
1546
+ const [listing, setListing] = (0, import_react5.useState)();
1547
+ const [browsePath, setBrowsePath] = (0, import_react5.useState)("");
1548
+ const [browsing, setBrowsing] = (0, import_react5.useState)(false);
1549
+ const [busy, setBusy] = (0, import_react5.useState)(false);
1550
+ const [saving, setSaving] = (0, import_react5.useState)(false);
1551
+ const [error, setError] = (0, import_react5.useState)("");
1552
+ const request = (0, import_react5.useRef)();
1553
+ (0, import_react5.useEffect)(() => {
1342
1554
  const abort = new AbortController();
1343
1555
  void api("/settings", { signal: abort.signal }).then((data) => {
1344
1556
  setSettings(data);
@@ -1351,7 +1563,7 @@ function SettingsDialog({ root, warnings, onClose, onChanged, onRebuilt, onProxy
1351
1563
  request.current?.abort();
1352
1564
  };
1353
1565
  }, []);
1354
- (0, import_react4.useEffect)(() => {
1566
+ (0, import_react5.useEffect)(() => {
1355
1567
  setTarget(root);
1356
1568
  }, [root]);
1357
1569
  async function browse(path) {
@@ -1421,107 +1633,108 @@ function SettingsDialog({ root, warnings, onClose, onChanged, onRebuilt, onProxy
1421
1633
  }
1422
1634
  }
1423
1635
  const changed = target.trim() && target.trim() !== root;
1424
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Dialog, { title: "\u4F60\u7684\u8D44\u6599\uFF0C\u7531\u4F60\u4FDD\u7BA1", description: "\u5185\u5BB9\u4EE5\u666E\u901A\u6587\u4EF6\u4FDD\u5B58\uFF0C\u7D22\u5F15\u53EF\u4EE5\u91CD\u5EFA\u3002", onClose: () => {
1636
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog, { title: "\u4F60\u7684\u8D44\u6599\uFF0C\u7531\u4F60\u4FDD\u7BA1", description: "\u5185\u5BB9\u4EE5\u666E\u901A\u6587\u4EF6\u4FDD\u5B58\uFF0C\u7D22\u5F15\u53EF\u4EE5\u91CD\u5EFA\u3002", onClose: () => {
1425
1637
  if (!saving) onClose();
1426
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-info", children: [
1427
- browsing ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-folder-browser", "aria-label": "\u9009\u62E9\u8D44\u6599\u5E93\u76EE\u5F55", children: [
1428
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-folder-heading", children: [
1429
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: "\u9009\u62E9\u8D44\u6599\u5E93\u76EE\u5F55" }),
1430
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", disabled: busy, onClick: () => void browse(), children: "\u4E3B\u76EE\u5F55" })
1638
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-info", children: [
1639
+ browsing ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-folder-browser", "aria-label": "\u9009\u62E9\u8D44\u6599\u5E93\u76EE\u5F55", children: [
1640
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-folder-heading", children: [
1641
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "\u9009\u62E9\u8D44\u6599\u5E93\u76EE\u5F55" }),
1642
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary", disabled: busy, onClick: () => void browse(), children: "\u4E3B\u76EE\u5F55" })
1431
1643
  ] }),
1432
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { className: "kl-folder-path", onSubmit: (e) => {
1644
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { className: "kl-folder-path", onSubmit: (e) => {
1433
1645
  e.preventDefault();
1434
1646
  void browse(browsePath);
1435
1647
  }, children: [
1436
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { "aria-label": "\u6D4F\u89C8\u76EE\u5F55\u8DEF\u5F84", value: browsePath, onChange: (e) => setBrowsePath(e.target.value) }),
1437
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", disabled: busy || !browsePath.trim(), children: "\u524D\u5F80" })
1648
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { "aria-label": "\u6D4F\u89C8\u76EE\u5F55\u8DEF\u5F84", value: browsePath, onChange: (e) => setBrowsePath(e.target.value) }),
1649
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary", disabled: busy || !browsePath.trim(), children: "\u524D\u5F80" })
1438
1650
  ] }),
1439
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("nav", { className: "kl-folder-crumbs", "aria-label": "\u76EE\u5F55\u5C42\u7EA7", children: listing?.crumbs.map((c) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { disabled: busy, onClick: () => void browse(c.path), children: [
1651
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("nav", { className: "kl-folder-crumbs", "aria-label": "\u76EE\u5F55\u5C42\u7EA7", children: listing?.crumbs.map((c) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { disabled: busy, onClick: () => void browse(c.path), children: [
1440
1652
  c.name,
1441
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "/" })
1653
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "/" })
1442
1654
  ] }, c.path)) }),
1443
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kl-folder-entries", "aria-busy": busy, children: busy ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-muted", children: "\u6B63\u5728\u8BFB\u53D6\u76EE\u5F55\u2026" }) : listing && !listing.entries.length ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-muted", children: "\u6B64\u76EE\u5F55\u6CA1\u6709\u5B50\u6587\u4EF6\u5939" }) : listing?.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { onClick: () => void browse(entry.path), children: [
1444
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "folder", size: 17 }),
1445
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: entry.name }),
1446
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "arrow", size: 15 })
1655
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "kl-folder-entries", "aria-busy": busy, children: busy ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-muted", children: "\u6B63\u5728\u8BFB\u53D6\u76EE\u5F55\u2026" }) : listing && !listing.entries.length ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-muted", children: "\u6B64\u76EE\u5F55\u6CA1\u6709\u5B50\u6587\u4EF6\u5939" }) : listing?.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { onClick: () => void browse(entry.path), children: [
1656
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "folder", size: 17 }),
1657
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: entry.name }),
1658
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "arrow", size: 15 })
1447
1659
  ] }, entry.path)) }),
1448
- listing?.truncated && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-muted", children: "\u5B50\u76EE\u5F55\u8F83\u591A\uFF0C\u4EC5\u663E\u793A\u90E8\u5206\u3002\u53EF\u586B\u5199\u5B8C\u6574\u8DEF\u5F84\u524D\u5F80\u3002" }),
1449
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-folder-actions", children: [
1450
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", onClick: () => {
1660
+ listing?.truncated && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-muted", children: "\u5B50\u76EE\u5F55\u8F83\u591A\uFF0C\u4EC5\u663E\u793A\u90E8\u5206\u3002\u53EF\u586B\u5199\u5B8C\u6574\u8DEF\u5F84\u524D\u5F80\u3002" }),
1661
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-folder-actions", children: [
1662
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary", onClick: () => {
1451
1663
  request.current?.abort();
1452
1664
  setBusy(false);
1453
1665
  setBrowsing(false);
1454
1666
  setError("");
1455
1667
  }, children: "\u53D6\u6D88\u9009\u62E9" }),
1456
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-primary", disabled: busy || !listing, onClick: () => {
1668
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-primary", disabled: busy || !listing, onClick: () => {
1457
1669
  setTarget(listing.path);
1458
1670
  setBrowsing(false);
1459
1671
  setError("");
1460
1672
  }, children: "\u9009\u62E9\u6B64\u76EE\u5F55" })
1461
1673
  ] })
1462
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1463
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("label", { htmlFor: "kl-library-root", children: "\u8D44\u6599\u5E93\u76EE\u5F55" }),
1464
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-root-field", children: [
1465
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { id: "kl-library-root", value: target, title: target, spellCheck: false, readOnly: !settings?.canChange, disabled: saving || busy, onChange: (e) => setTarget(e.target.value) }),
1466
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: "kl-secondary", disabled: !settings?.canChange || !settings.picker || busy || saving, onClick: () => void pick(), children: [
1467
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "folder", size: 16 }),
1674
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1675
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("label", { htmlFor: "kl-library-root", children: "\u8D44\u6599\u5E93\u76EE\u5F55" }),
1676
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-root-field", children: [
1677
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { id: "kl-library-root", value: target, title: target, spellCheck: false, readOnly: !settings?.canChange, disabled: saving || busy, onChange: (e) => setTarget(e.target.value) }),
1678
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "kl-secondary", disabled: !settings?.canChange || !settings.picker || busy || saving, onClick: () => void pick(), children: [
1679
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "folder", size: 16 }),
1468
1680
  busy ? "\u9009\u62E9\u4E2D\u2026" : "\u9009\u62E9\u76EE\u5F55"
1469
1681
  ] })
1470
1682
  ] }),
1471
- settings && !settings.canChange && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-muted", children: "\u8BF7\u5728 Harness \u4E2D\u9009\u62E9\u548C\u5207\u6362\u76EE\u5F55\uFF1B\u72EC\u7ACB\u9884\u89C8\u53EF\u901A\u8FC7\u542F\u52A8\u914D\u7F6E\u6307\u5B9A\u76EE\u5F55\u3002" }),
1472
- !!changed && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-root-confirm", children: [
1473
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "\u5207\u6362\u540E\u5C06\u8BFB\u53D6\u65B0\u76EE\u5F55\uFF0C\u5E76\u5C06\u540E\u7EED\u8D44\u6599\u4FDD\u5B58\u5230\u90A3\u91CC\u3002\u539F\u76EE\u5F55\u7684\u8D44\u6599\u4F1A\u4FDD\u7559\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u642C\u8FC1\u3002" }),
1474
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1475
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", disabled: saving || busy, onClick: () => {
1683
+ settings && !settings.canChange && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-muted", children: "\u8BF7\u5728 Harness \u4E2D\u9009\u62E9\u548C\u5207\u6362\u76EE\u5F55\uFF1B\u72EC\u7ACB\u9884\u89C8\u53EF\u901A\u8FC7\u542F\u52A8\u914D\u7F6E\u6307\u5B9A\u76EE\u5F55\u3002" }),
1684
+ !!changed && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-root-confirm", children: [
1685
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: "\u5207\u6362\u540E\u5C06\u8BFB\u53D6\u65B0\u76EE\u5F55\uFF0C\u5E76\u5C06\u540E\u7EED\u8D44\u6599\u4FDD\u5B58\u5230\u90A3\u91CC\u3002\u539F\u76EE\u5F55\u7684\u8D44\u6599\u4F1A\u4FDD\u7559\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u642C\u8FC1\u3002" }),
1686
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1687
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary", disabled: saving || busy, onClick: () => {
1476
1688
  setTarget(root);
1477
1689
  setError("");
1478
1690
  }, children: "\u53D6\u6D88\u4FEE\u6539" }),
1479
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-primary", disabled: saving || busy, onClick: () => void change(), children: saving ? "\u6B63\u5728\u5207\u6362\u2026" : "\u5207\u6362\u8D44\u6599\u5E93" })
1691
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-primary", disabled: saving || busy, onClick: () => void change(), children: saving ? "\u6B63\u5728\u5207\u6362\u2026" : "\u5207\u6362\u8D44\u6599\u5E93" })
1480
1692
  ] })
1481
1693
  ] }),
1482
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: "kl-network-settings", "aria-label": "\u7F51\u9875\u91C7\u96C6\u8BBE\u7F6E", children: [
1483
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: "\u7F51\u9875\u91C7\u96C6" }),
1484
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "kl-proxy-option", children: [
1485
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "checkbox", "aria-describedby": "kl-proxy-help", checked: proxyMode, disabled: !settings?.canChangeNetwork || saving || busy, onChange: (e) => {
1694
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: "kl-network-settings", "aria-label": "\u7F51\u9875\u91C7\u96C6\u8BBE\u7F6E", children: [
1695
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { children: "\u7F51\u9875\u91C7\u96C6" }),
1696
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "kl-proxy-option", children: [
1697
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "checkbox", "aria-describedby": "kl-proxy-help", checked: proxyMode, disabled: !settings?.canChangeNetwork || saving || busy, onChange: (e) => {
1486
1698
  setProxyMode(e.target.checked);
1487
1699
  setError("");
1488
1700
  } }),
1489
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Clash/Mihomo \u4EE3\u7406\u517C\u5BB9\uFF08fake-IP\uFF09" })
1701
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Clash/Mihomo \u4EE3\u7406\u517C\u5BB9\uFF08fake-IP\uFF09" })
1490
1702
  ] }),
1491
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { id: "kl-proxy-help", children: "\u672C\u673A\u4F7F\u7528 Clash/Mihomo TUN \u7684 fake-IP DNS \u65F6\u5F00\u542F\uFF0C\u5141\u8BB8\u901A\u8FC7\u4EE3\u7406\u91C7\u96C6\u89E3\u6790\u5230 198.18.* \u6216 198.19.* \u7684\u7F51\u7AD9\u3002\u672C\u673A\u53CA\u5176\u4ED6\u5185\u7F51\u5730\u5740\u4ECD\u4E0D\u5141\u8BB8\u8BBF\u95EE\u3002" }),
1492
- settings?.canChangeNetwork && !settings.canChange && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-muted", children: "\u6B64\u8BBE\u7F6E\u7528\u4E8E\u5F53\u524D\u8D44\u6599\u5E93\u7684\u72EC\u7ACB\u9884\u89C8\uFF0C\u4FDD\u5B58\u540E\u5BF9\u540E\u7EED\u91C7\u96C6\u751F\u6548\u3002" }),
1493
- settings && !settings.canChangeNetwork && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-muted", children: "\u5F53\u524D\u73AF\u5883\u65E0\u6CD5\u4FDD\u5B58\u91C7\u96C6\u8BBE\u7F6E\u3002" }),
1494
- settings?.canChangeNetwork && proxyMode !== settings.allowProxyFakeIp && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", disabled: saving || busy, onClick: () => void saveProxyMode(), children: saving ? "\u6B63\u5728\u4FDD\u5B58\u2026" : "\u4FDD\u5B58\u91C7\u96C6\u8BBE\u7F6E" })
1703
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { id: "kl-proxy-help", children: "\u672C\u673A\u4F7F\u7528 Clash/Mihomo TUN \u7684 fake-IP DNS \u65F6\u5F00\u542F\uFF0C\u5141\u8BB8\u901A\u8FC7\u4EE3\u7406\u91C7\u96C6\u89E3\u6790\u5230 198.18.* \u6216 198.19.* \u7684\u7F51\u7AD9\u3002\u672C\u673A\u53CA\u5176\u4ED6\u5185\u7F51\u5730\u5740\u4ECD\u4E0D\u5141\u8BB8\u8BBF\u95EE\u3002" }),
1704
+ settings?.canChangeNetwork && !settings.canChange && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-muted", children: "\u6B64\u8BBE\u7F6E\u7528\u4E8E\u5F53\u524D\u8D44\u6599\u5E93\u7684\u72EC\u7ACB\u9884\u89C8\uFF0C\u4FDD\u5B58\u540E\u5BF9\u540E\u7EED\u91C7\u96C6\u751F\u6548\u3002" }),
1705
+ settings && !settings.canChangeNetwork && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-muted", children: "\u5F53\u524D\u73AF\u5883\u65E0\u6CD5\u4FDD\u5B58\u91C7\u96C6\u8BBE\u7F6E\u3002" }),
1706
+ settings?.canChangeNetwork && proxyMode !== settings.allowProxyFakeIp && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary", disabled: saving || busy, onClick: () => void saveProxyMode(), children: saving ? "\u6B63\u5728\u4FDD\u5B58\u2026" : "\u4FDD\u5B58\u91C7\u96C6\u8BBE\u7F6E" })
1495
1707
  ] }),
1496
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "\u6BCF\u4EFD\u8D44\u6599\u4FDD\u7559\u539F\u59CB\u6587\u4EF6\u3001\u6B63\u6587\u3001\u5143\u6570\u636E\u548C\u5F15\u7528\u6BB5\u843D\u3002\u5206\u7C7B\u5BF9\u5E94\u672C\u5730\u6587\u4EF6\u5939\uFF0C\u63D2\u4EF6\u5378\u8F7D\u4E0D\u4F1A\u5220\u9664\u8FD9\u4E9B\u6587\u4EF6\u3002" }),
1497
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { children: "\u672C\u7248\u672C\u53EF\u63D0\u53D6\u6587\u7AE0\u6B63\u6587\u53CA\u5B57\u5E55\uFF1B\u97F3\u89C6\u9891\u3001PDF \u7B49\u683C\u5F0F\u53EF\u4EE5\u5F52\u6863\uFF0C\u81EA\u52A8\u8F6C\u5199\u548C OCR \u5C1A\u672A\u63A5\u5165\u3002" }),
1498
- warnings.map((w) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { role: "alert", children: w }, w)),
1499
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { className: "kl-secondary", disabled: busy || saving, onClick: () => {
1708
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ImageSettings, { root }, root),
1709
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: "\u6BCF\u4EFD\u8D44\u6599\u4FDD\u7559\u539F\u59CB\u6587\u4EF6\u3001\u6B63\u6587\u3001\u5143\u6570\u636E\u548C\u5F15\u7528\u6BB5\u843D\u3002\u5206\u7C7B\u5BF9\u5E94\u672C\u5730\u6587\u4EF6\u5939\uFF0C\u63D2\u4EF6\u5378\u8F7D\u4E0D\u4F1A\u5220\u9664\u8FD9\u4E9B\u6587\u4EF6\u3002" }),
1710
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: "\u652F\u6301\u7F51\u9875\u6B63\u6587\u56FE\u7247\u8BC6\u522B\uFF1B\u97F3\u89C6\u9891\u3001PDF \u7B49\u683C\u5F0F\u53EF\u4EE5\u5F52\u6863\uFF0C\u81EA\u52A8\u8F6C\u5199\u548C\u6587\u4EF6 OCR \u5C1A\u672A\u63A5\u5165\u3002" }),
1711
+ warnings.map((w) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "alert", children: w }, w)),
1712
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { className: "kl-secondary", disabled: busy || saving, onClick: () => {
1500
1713
  setSaving(true);
1501
1714
  setError("");
1502
1715
  void post("/rebuild", {}).then(onRebuilt).catch((e) => setError(e.message)).finally(() => setSaving(false));
1503
1716
  }, children: "\u4ECE\u8D44\u6599\u6587\u4EF6\u91CD\u5EFA\u7D22\u5F15" })
1504
1717
  ] }),
1505
- error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "kl-settings-error", role: "alert", children: error })
1718
+ error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "kl-settings-error", role: "alert", children: error })
1506
1719
  ] }) });
1507
1720
  }
1508
1721
  function EditorDialog({ editor, categories, onClose, onSaved }) {
1509
1722
  const editing = editor.mode === "edit";
1510
1723
  const note = editor.mode === "note";
1511
1724
  const source = editor.source;
1512
- const [type, setType] = (0, import_react4.useState)(editor.initialType || "url");
1513
- const [sourceUrl, setSourceUrl] = (0, import_react4.useState)(editor.sourceUrl || "");
1514
- const [title, setTitle] = (0, import_react4.useState)(editing ? source?.title || "" : note && source ? `${source.title} \xB7 \u6458\u5F55` : "");
1515
- const [content, setContent] = (0, import_react4.useState)(editor.segment ? `> ${editor.segment.text}
1725
+ const [type, setType] = (0, import_react5.useState)(editor.initialType || "url");
1726
+ const [sourceUrl, setSourceUrl] = (0, import_react5.useState)(editor.sourceUrl || "");
1727
+ const [title, setTitle] = (0, import_react5.useState)(editing ? source?.title || "" : note && source ? `${source.title} \xB7 \u6458\u5F55` : "");
1728
+ const [content, setContent] = (0, import_react5.useState)(editor.segment ? `> ${editor.segment.text}
1516
1729
 
1517
1730
  ` : "");
1518
- const [category, setCategory] = (0, import_react4.useState)(editing ? source?.category || "\u6536\u4EF6\u7BB1" : note ? "\u77E5\u8BC6\u7B14\u8BB0" : "\u6536\u4EF6\u7BB1");
1519
- const [tags, setTags] = (0, import_react4.useState)(editing ? source?.tags.join("\uFF0C") || "" : "");
1520
- const [collection, setCollection] = (0, import_react4.useState)(source?.collection || "");
1521
- const [sourceNote, setSourceNote] = (0, import_react4.useState)(editing ? source?.sourceNote || "" : "");
1522
- const [file, setFile] = (0, import_react4.useState)();
1523
- const [busy, setBusy] = (0, import_react4.useState)(false);
1524
- const [error, setError] = (0, import_react4.useState)("");
1731
+ const [category, setCategory] = (0, import_react5.useState)(editing ? source?.category || "\u6536\u4EF6\u7BB1" : note ? "\u77E5\u8BC6\u7B14\u8BB0" : "\u6536\u4EF6\u7BB1");
1732
+ const [tags, setTags] = (0, import_react5.useState)(editing ? source?.tags.join("\uFF0C") || "" : "");
1733
+ const [collection, setCollection] = (0, import_react5.useState)(source?.collection || "");
1734
+ const [sourceNote, setSourceNote] = (0, import_react5.useState)(editing ? source?.sourceNote || "" : "");
1735
+ const [file, setFile] = (0, import_react5.useState)();
1736
+ const [busy, setBusy] = (0, import_react5.useState)(false);
1737
+ const [error, setError] = (0, import_react5.useState)("");
1525
1738
  const citations = source && note ? [{ materialId: source.id, ...editor.segment ? { segmentId: editor.segment.id } : {} }] : [];
1526
1739
  async function submit(event) {
1527
1740
  event.preventDefault();
@@ -1556,80 +1769,81 @@ function EditorDialog({ editor, categories, onClose, onSaved }) {
1556
1769
  setContent("");
1557
1770
  setError("");
1558
1771
  };
1559
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Dialog, { title: editing ? "\u6574\u7406\u8D44\u6599" : note ? "\u5199\u4E00\u4EFD\u77E5\u8BC6\u7B14\u8BB0" : "\u6536\u96C6\u4E00\u4EFD\u8D44\u6599", description: editing ? "\u5206\u7C7B\u4F1A\u540C\u6B65\u5230\u672C\u5730\u6587\u4EF6\u5939\uFF0C\u539F\u6587\u548C\u5F15\u7528\u4FDD\u6301\u4E0D\u53D8\u3002" : note ? "\u5199\u4E0B\u7406\u89E3\uFF0C\u4E5F\u7559\u4E0B\u5B83\u7684\u6765\u6E90\u3002" : "\u5148\u6536\u96C6\uFF0C\u518D\u6162\u6162\u6574\u7406\u3002\u6240\u6709\u5185\u5BB9\u4FDD\u5B58\u5728\u4F60\u7684\u7535\u8111\u3002", onClose: () => {
1772
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog, { title: editing ? "\u6574\u7406\u8D44\u6599" : note ? "\u5199\u4E00\u4EFD\u77E5\u8BC6\u7B14\u8BB0" : "\u6536\u96C6\u4E00\u4EFD\u8D44\u6599", description: editing ? "\u5206\u7C7B\u4F1A\u540C\u6B65\u5230\u672C\u5730\u6587\u4EF6\u5939\uFF0C\u539F\u6587\u548C\u5F15\u7528\u4FDD\u6301\u4E0D\u53D8\u3002" : note ? "\u5199\u4E0B\u7406\u89E3\uFF0C\u4E5F\u7559\u4E0B\u5B83\u7684\u6765\u6E90\u3002" : "\u5148\u6536\u96C6\uFF0C\u518D\u6162\u6162\u6574\u7406\u3002\u6240\u6709\u5185\u5BB9\u4FDD\u5B58\u5728\u4F60\u7684\u7535\u8111\u3002", onClose: () => {
1560
1773
  if (!busy) onClose();
1561
- }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { onSubmit: submit, className: "kl-editor", children: [
1562
- !editing && !note && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kl-tabs", role: "tablist", "aria-label": "\u91C7\u96C6\u65B9\u5F0F", children: ["url", "text", "file"].map((value) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { type: "button", role: "tab", "aria-selected": type === value, className: type === value ? "active" : "", onClick: () => changeType(value), children: [
1563
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: value === "url" ? "web" : value === "file" ? "upload" : "file", size: 17 }),
1774
+ }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { onSubmit: submit, className: "kl-editor", children: [
1775
+ !editing && !note && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "kl-tabs", role: "tablist", "aria-label": "\u91C7\u96C6\u65B9\u5F0F", children: ["url", "text", "file"].map((value) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", role: "tab", "aria-selected": type === value, className: type === value ? "active" : "", onClick: () => changeType(value), children: [
1776
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: value === "url" ? "web" : value === "file" ? "upload" : "file", size: 17 }),
1564
1777
  value === "url" ? "\u7F51\u9875\u94FE\u63A5" : value === "file" ? "\u672C\u5730\u6587\u4EF6" : "\u6587\u672C\u6458\u5F55"
1565
1778
  ] }, value)) }),
1566
- !editing && !note && type === "url" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { children: [
1779
+ !editing && !note && type === "url" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { children: [
1567
1780
  "\u7F51\u9875\u5730\u5740",
1568
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "url", required: true, placeholder: "https://\u2026", value: content, onChange: (e) => setContent(e.target.value) }),
1569
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("small", { children: "\u652F\u6301\u53EF\u76F4\u63A5\u8BBF\u95EE\u7684\u6587\u7AE0\u7F51\u9875\u3002\u767B\u5F55\u9875\u6216\u52A8\u6001\u9875\u9762\u53EF\u590D\u5236\u6B63\u6587\u5BFC\u5165\u3002" })
1781
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "url", required: true, placeholder: "https://\u2026", value: content, onChange: (e) => setContent(e.target.value) }),
1782
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("small", { children: "\u652F\u6301\u53EF\u76F4\u63A5\u8BBF\u95EE\u7684\u6587\u7AE0\u7F51\u9875\u3002\u767B\u5F55\u9875\u6216\u52A8\u6001\u9875\u9762\u53EF\u590D\u5236\u6B63\u6587\u5BFC\u5165\u3002" })
1570
1783
  ] }),
1571
- !editing && !note && type === "file" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "kl-upload", children: [
1572
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "upload", size: 27 }),
1573
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("strong", { children: file?.name || "\u9009\u62E9\u6216\u62D6\u5165\u6587\u4EF6" }),
1574
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "\u6587\u672C\u3001HTML\u3001SRT / VTT \u5B57\u5E55\u53CA\u5176\u4ED6\u6587\u4EF6 \xB7 \u6700\u5927 64 MB" }),
1575
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { "aria-label": "\u9009\u62E9\u672C\u5730\u6587\u4EF6", type: "file", onChange: (e) => setFile(e.target.files?.[0]) }),
1576
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("small", { children: "\u89C6\u9891\u548C PDF \u53EF\u5F52\u6863\uFF0C\u5F53\u524D\u7248\u672C\u4E0D\u4F1A\u81EA\u52A8\u8F6C\u5199\u6216 OCR\u3002" })
1784
+ !editing && !note && type === "url" && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ImageCapturePolicy, {}),
1785
+ !editing && !note && type === "file" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "kl-upload", children: [
1786
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "upload", size: 27 }),
1787
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: file?.name || "\u9009\u62E9\u6216\u62D6\u5165\u6587\u4EF6" }),
1788
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "\u6587\u672C\u3001HTML\u3001SRT / VTT \u5B57\u5E55\u53CA\u5176\u4ED6\u6587\u4EF6 \xB7 \u6700\u5927 64 MB" }),
1789
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { "aria-label": "\u9009\u62E9\u672C\u5730\u6587\u4EF6", type: "file", onChange: (e) => setFile(e.target.files?.[0]) }),
1790
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("small", { children: "\u89C6\u9891\u548C PDF \u53EF\u5F52\u6863\uFF0C\u5F53\u524D\u7248\u672C\u4E0D\u4F1A\u81EA\u52A8\u8F6C\u5199\u6216 OCR\u3002" })
1577
1791
  ] }),
1578
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { children: [
1792
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { children: [
1579
1793
  "\u6807\u9898",
1580
- !editing && !note && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("em", { children: "\u53EF\u9009" }),
1581
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { required: editing || note, value: title, onChange: (e) => setTitle(e.target.value), placeholder: type === "url" && !note ? "\u81EA\u52A8\u63D0\u53D6\u7F51\u9875\u6807\u9898\uFF0C\u4E5F\u53EF\u4EE5\u81EA\u5DF1\u586B\u5199" : "\u7ED9\u8FD9\u4EFD\u5185\u5BB9\u8D77\u4E2A\u540D\u5B57", maxLength: 300 })
1794
+ !editing && !note && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("em", { children: "\u53EF\u9009" }),
1795
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { required: editing || note, value: title, onChange: (e) => setTitle(e.target.value), placeholder: type === "url" && !note ? "\u81EA\u52A8\u63D0\u53D6\u7F51\u9875\u6807\u9898\uFF0C\u4E5F\u53EF\u4EE5\u81EA\u5DF1\u586B\u5199" : "\u7ED9\u8FD9\u4EFD\u5185\u5BB9\u8D77\u4E2A\u540D\u5B57", maxLength: 300 })
1582
1796
  ] }),
1583
- !editing && (note || type === "text") && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { children: [
1797
+ !editing && (note || type === "text") && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { children: [
1584
1798
  note ? "\u7B14\u8BB0\u5185\u5BB9" : "\u6B63\u6587",
1585
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("textarea", { required: true, rows: 7, value: content, onChange: (e) => setContent(e.target.value), placeholder: note ? "\u8BB0\u5F55\u4F60\u7684\u7406\u89E3\u3001\u7ED3\u8BBA\u4E0E\u5C1A\u5F85\u9A8C\u8BC1\u7684\u95EE\u9898\u2026" : "\u7C98\u8D34\u60F3\u4FDD\u7559\u7684\u6587\u5B57\uFF0C\u652F\u6301 Markdown\u2026" })
1799
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("textarea", { required: true, rows: 7, value: content, onChange: (e) => setContent(e.target.value), placeholder: note ? "\u8BB0\u5F55\u4F60\u7684\u7406\u89E3\u3001\u7ED3\u8BBA\u4E0E\u5C1A\u5F85\u9A8C\u8BC1\u7684\u95EE\u9898\u2026" : "\u7C98\u8D34\u60F3\u4FDD\u7559\u7684\u6587\u5B57\uFF0C\u652F\u6301 Markdown\u2026" })
1586
1800
  ] }),
1587
- !editing && !note && type === "text" && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { children: [
1801
+ !editing && !note && type === "text" && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { children: [
1588
1802
  "\u6765\u6E90\u7F51\u9875",
1589
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("em", { children: "\u53EF\u9009" }),
1590
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "url", "aria-label": "\u6765\u6E90\u7F51\u9875", placeholder: "https://\u2026", value: sourceUrl, onChange: (e) => setSourceUrl(e.target.value) }),
1591
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("small", { children: "\u4FDD\u7559\u539F\u7F51\u9875\u5730\u5740\uFF0C\u65B9\u4FBF\u56DE\u6EAF\u6765\u6E90\u3002" })
1803
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("em", { children: "\u53EF\u9009" }),
1804
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "url", "aria-label": "\u6765\u6E90\u7F51\u9875", placeholder: "https://\u2026", value: sourceUrl, onChange: (e) => setSourceUrl(e.target.value) }),
1805
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("small", { children: "\u4FDD\u7559\u539F\u7F51\u9875\u5730\u5740\uFF0C\u65B9\u4FBF\u56DE\u6EAF\u6765\u6E90\u3002" })
1592
1806
  ] }),
1593
- !!citations.length && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-citation-preview", children: [
1594
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "file", size: 16 }),
1595
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
1807
+ !!citations.length && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-citation-preview", children: [
1808
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "file", size: 16 }),
1809
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
1596
1810
  "\u5F15\u7528\uFF1A",
1597
1811
  source.title,
1598
1812
  editor.segment ? ` / ${editor.segment.id}` : ""
1599
1813
  ] })
1600
1814
  ] }),
1601
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "kl-form-grid", children: [
1602
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { children: [
1815
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "kl-form-grid", children: [
1816
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { children: [
1603
1817
  "\u5206\u7C7B",
1604
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { list: "kl-categories", value: category, onChange: (e) => setCategory(e.target.value), placeholder: "\u4F8B\u5982 \u6280\u672F/AI" }),
1605
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("datalist", { id: "kl-categories", children: categories.map((c) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: c }, c)) })
1818
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { list: "kl-categories", value: category, onChange: (e) => setCategory(e.target.value), placeholder: "\u4F8B\u5982 \u6280\u672F/AI" }),
1819
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("datalist", { id: "kl-categories", children: categories.map((c) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: c }, c)) })
1606
1820
  ] }),
1607
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { children: [
1821
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { children: [
1608
1822
  "\u4E13\u9898",
1609
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("em", { children: "\u53EF\u9009" }),
1610
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { value: collection, onChange: (e) => setCollection(e.target.value), placeholder: "\u56F4\u7ED5\u4E00\u4E2A\u95EE\u9898\u7EC4\u7EC7\u8D44\u6599" })
1823
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("em", { children: "\u53EF\u9009" }),
1824
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { value: collection, onChange: (e) => setCollection(e.target.value), placeholder: "\u56F4\u7ED5\u4E00\u4E2A\u95EE\u9898\u7EC4\u7EC7\u8D44\u6599" })
1611
1825
  ] })
1612
1826
  ] }),
1613
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { children: [
1827
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { children: [
1614
1828
  "\u6807\u7B7E",
1615
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("em", { children: "\u53EF\u9009" }),
1616
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { value: tags, onChange: (e) => setTags(e.target.value), placeholder: "\u7528\u9017\u53F7\u5206\u9694\uFF0C\u4F8B\u5982\uFF1A\u5F85\u8BFB\uFF0CRAG\uFF0C\u5B9E\u8DF5" })
1829
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("em", { children: "\u53EF\u9009" }),
1830
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { value: tags, onChange: (e) => setTags(e.target.value), placeholder: "\u7528\u9017\u53F7\u5206\u9694\uFF0C\u4F8B\u5982\uFF1A\u5F85\u8BFB\uFF0CRAG\uFF0C\u5B9E\u8DF5" })
1617
1831
  ] }),
1618
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { children: [
1832
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { children: [
1619
1833
  "\u6765\u6E90\u5907\u6CE8",
1620
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("em", { children: "\u53EF\u9009" }),
1621
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { value: sourceNote, onChange: (e) => setSourceNote(e.target.value), placeholder: "\u4E3A\u4EC0\u4E48\u503C\u5F97\u4FDD\u5B58\uFF0C\u6216\u8005\u5B83\u6765\u81EA\u54EA\u91CC" })
1834
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("em", { children: "\u53EF\u9009" }),
1835
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { value: sourceNote, onChange: (e) => setSourceNote(e.target.value), placeholder: "\u4E3A\u4EC0\u4E48\u503C\u5F97\u4FDD\u5B58\uFF0C\u6216\u8005\u5B83\u6765\u81EA\u54EA\u91CC" })
1622
1836
  ] }),
1623
- error && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "kl-form-error", role: "alert", children: error }),
1624
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("footer", { children: [
1625
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { children: [
1626
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "kl-live-dot" }),
1627
- "\u4EC5\u4FDD\u5B58\u5728\u672C\u5730"
1837
+ error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "kl-form-error", role: "alert", children: error }),
1838
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("footer", { children: [
1839
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
1840
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "kl-live-dot" }),
1841
+ !editing && !note && type === "url" ? "\u91C7\u96C6\u7ED3\u679C\u4FDD\u5B58\u5728\u672C\u5730" : "\u4EC5\u4FDD\u5B58\u5728\u672C\u5730"
1628
1842
  ] }),
1629
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "kl-secondary", disabled: busy, onClick: onClose, children: "\u53D6\u6D88" }),
1630
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("button", { className: "kl-primary", type: "submit", disabled: busy, children: [
1843
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "kl-secondary", disabled: busy, onClick: onClose, children: "\u53D6\u6D88" }),
1844
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { className: "kl-primary", type: "submit", disabled: busy, children: [
1631
1845
  busy ? "\u4FDD\u5B58\u4E2D\u2026" : editing ? "\u4FDD\u5B58\u4FEE\u6539" : note ? "\u4FDD\u5B58\u7B14\u8BB0" : type === "url" ? "\u5F00\u59CB\u91C7\u96C6" : "\u4FDD\u5B58\u8D44\u6599",
1632
- !busy && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { name: "arrow", size: 16 })
1846
+ !busy && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Icon, { name: "arrow", size: 16 })
1633
1847
  ] })
1634
1848
  ] })
1635
1849
  ] }) });
@@ -1965,6 +2179,25 @@ var style_default = `/* Harness owns the palette and font. Fallbacks are for the
1965
2179
  .kl-info .kl-proxy-option { display: flex; align-items: flex-start; gap: 8px; color: var(--kl-ink); font-size: 13px; line-height: 20px; cursor: pointer; }
1966
2180
  .kl-proxy-option input { flex: none; width: 16px; height: 16px; margin: 2px 0; accent-color: var(--kl-ink); }
1967
2181
  .kl-network-settings p { font-size: 12px; margin: 8px 0 12px; }
2182
+ .kl-image-settings { margin-top: 20px; padding-top: 16px; border-top: .5px solid var(--kl-line); }
2183
+ .kl-image-settings h3, .kl-page-images h3 { font-size: 13px; font-weight: 500; margin: 0 0 12px; }
2184
+ .kl-image-settings p, .kl-image-record p { font-size: 12px; overflow-wrap: anywhere; }
2185
+ .kl-info .kl-image-limit { display: flex; align-items: center; gap: 12px; margin: 14px 0; }
2186
+ .kl-image-limit input { width: 68px; padding: 6px 8px; border: .5px solid var(--kl-line); border-radius: 8px; background: var(--kl-bg); }
2187
+ .kl-image-policy { padding: 10px 12px; border-left: 2px solid var(--kl-link); background: var(--kl-sidebar); color: var(--kl-secondary); font-size: 12px; line-height: 1.8; margin: 0 0 16px; overflow-wrap: anywhere; }
2188
+ .kl-page-images { margin: 24px 0; padding-block: 16px; border-block: .5px solid var(--kl-line); }
2189
+ .kl-image-heading { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 8px; }
2190
+ .kl-image-heading h3 { margin: 0; }
2191
+ .kl-image-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(190px, 100%), 1fr)); gap: 16px; }
2192
+ .kl-image-record { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; font-size: 12px; overflow-wrap: anywhere; }
2193
+ .kl-image-record > a:has(img) { width: 100%; }
2194
+ .kl-image-record img { display: block; width: 100%; height: 140px; object-fit: contain; border: .5px solid var(--kl-line); border-radius: 8px; background: var(--kl-sidebar); }
2195
+ .kl-image-record small { color: var(--kl-muted); }
2196
+ .kl-image-record a { color: var(--kl-link); }
2197
+ .kl-image-record p { margin: 0; color: var(--kl-secondary); }
2198
+ .kl-delete-dialog li { overflow-wrap: anywhere; }
2199
+ .kl-job > p { color: var(--kl-secondary); }
2200
+ .kl-job > p[role="alert"] { color: var(--kl-error); }
1968
2201
  .kl-error, .kl-form-error { background: var(--kl-sidebar); color: var(--kl-error); font-size: 13px; line-height: 1.7; padding: 10px 12px; border-radius: 8px; overflow-wrap: anywhere; }
1969
2202
  .kl-error { display: flex; align-items: center; gap: 12px; margin: 0 var(--kl-gutter) 14px; }
1970
2203
  .kl-error button { margin-left: auto; border: 0; background: transparent; color: inherit; display: flex; padding: 4px; }
@@ -2024,7 +2257,7 @@ var style_default = `/* Harness owns the palette and font. Fallbacks are for the
2024
2257
  `;
2025
2258
 
2026
2259
  // src/client.tsx
2027
- var import_jsx_runtime6 = require("react/jsx-runtime");
2260
+ var import_jsx_runtime7 = require("react/jsx-runtime");
2028
2261
  var inject = ["slots"];
2029
2262
  function apply(ctx) {
2030
2263
  ctx.effect(() => {
@@ -2034,13 +2267,13 @@ function apply(ctx) {
2034
2267
  document.head.append(style);
2035
2268
  return () => style.remove();
2036
2269
  });
2037
- ctx.slots.inject("main", () => ctx.slots.register({ name: "main", key: "knowledge-library" }, () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(App, {})));
2270
+ ctx.slots.inject("main", () => ctx.slots.register({ name: "main", key: "knowledge-library" }, () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(App, {})));
2038
2271
  ctx.slots.inject("sidebar.panellist", () => ctx.slots.register({
2039
2272
  name: "sidebar.panellist",
2040
2273
  id: "knowledge-library",
2041
2274
  order: 20,
2042
2275
  label: "\u8D44\u6599\u5E93"
2043
- }, () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(LibraryIcon, { size: 20 })));
2276
+ }, () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(LibraryIcon, { size: 20 })));
2044
2277
  }
2045
2278
 
2046
2279
  return module.exports;}});