dsh-mishu 0.7.2 → 0.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -33,7 +33,7 @@ __export(index_exports, {
33
33
  module.exports = __toCommonJS(index_exports);
34
34
 
35
35
  // src/client/Board.tsx
36
- var import_react6 = require("react");
36
+ var import_react7 = require("react");
37
37
 
38
38
  // src/client/api.ts
39
39
  async function post(path, body) {
@@ -80,7 +80,15 @@ var settingsApi = {
80
80
  saveMail: (lang, account, password) => post("/mail/save", { lang, account, password }),
81
81
  testMail: (lang, account, password) => post("/mail/test", { lang, account, password }),
82
82
  deleteMail: (lang, id) => post("/mail/delete", { lang, id }),
83
- syncMail: (lang, id) => post("/mail/sync", { lang, id })
83
+ syncMail: (lang, id) => post("/mail/sync", { lang, id }),
84
+ saveWatch: (lang, watch) => post("/watch/save", { lang, watch }),
85
+ testWatch: (lang, watch) => post("/watch/test", { lang, watch }),
86
+ deleteWatch: (lang, id) => post("/watch/delete", { lang, id }),
87
+ syncWatch: (lang, id) => post("/watch/sync", { lang, id }),
88
+ armBrief: (lang) => post("/schedule/brief/arm", { lang }),
89
+ disarmBrief: (lang) => post("/schedule/brief/disarm", { lang }),
90
+ runTask: (lang, id) => post("/schedule/run", { lang, id }),
91
+ deleteTask: (lang, id) => post("/schedule/delete", { lang, id })
84
92
  };
85
93
 
86
94
  // src/client/AskAI.tsx
@@ -156,6 +164,7 @@ var zh = {
156
164
  sourceGithub: "GitHub",
157
165
  sourceMail: "\u90AE\u4EF6",
158
166
  sourceManual: "\u4EA4\u4EE3",
167
+ sourceWatch: "\u5173\u6CE8",
159
168
  sGeneral: "\u901A\u7528",
160
169
  sLanguage: "\u8BED\u8A00",
161
170
  sLanguageAuto: "\u8DDF\u968F\u7CFB\u7EDF",
@@ -208,6 +217,34 @@ var zh = {
208
217
  sPasswordTestOnly: "\u6CA1\u6709\u94A5\u5319\u4E32\uFF1A\u8FD9\u91CC\u586B\u7684\u53EA\u7528\u6765\u6D4B\u8BD5\u8FDE\u63A5\uFF0C\u4E0D\u4F1A\u4FDD\u5B58",
209
218
  secretKinds: { macos: "macOS \u94A5\u5319\u4E32", windows: "Windows \u51ED\u636E\u7BA1\u7406\u5668", linux: "Linux \u5BC6\u94A5\u73AF\uFF08Secret Service\uFF09", memory: "\u5185\u5B58\uFF08\u6D4B\u8BD5\u7528\uFF09" },
210
219
  sNoAccounts: "\u8FD8\u6CA1\u6709\u6DFB\u52A0\u90AE\u7BB1\u3002",
220
+ sWatch: "\u81EA\u5DF1\u5173\u6CE8\u7684",
221
+ sWatchHint: "\u9664\u4E86 GitHub \u548C\u90AE\u7BB1\uFF0C\u4F60\u4E5F\u53EF\u4EE5\u8BA9\u5C0F\u79D8\u4E66\u76EF\u7740\u4EFB\u610F\u4E00\u4E2A\u7F51\u5740\uFF1A\u516C\u544A\u9875\u3001\u4EF7\u683C\u3001\u62DB\u8058\u9875\u3001\u8BA2\u9605\u6E90\u90FD\u884C\u3002\u5B83\u4F1A\u9694\u4E00\u4F1A\u513F\u770B\u4E00\u6B21\uFF0C\u6709\u53D8\u5316\u5C31\u653E\u5230\u770B\u677F\u4E0A\u3002",
222
+ sNoWatches: "\u8FD8\u6CA1\u6709\u5173\u6CE8\u4EFB\u4F55\u7F51\u5740\u3002",
223
+ sAddWatch: "+ \u5173\u6CE8\u4E00\u4E2A\u7F51\u5740",
224
+ wTitleAdd: "\u5173\u6CE8\u4E00\u4E2A\u7F51\u5740",
225
+ wTitleEdit: "\u4FEE\u6539\u5173\u6CE8",
226
+ wUrl: "\u7F51\u5740",
227
+ wUrlHint: "RSS \u8BA2\u9605\u3001JSON \u63A5\u53E3\u3001\u666E\u901A\u7F51\u9875\u90FD\u53EF\u4EE5\u3002\u8981\u767B\u5F55\u624D\u80FD\u770B\u7684\u9875\u9762\u8BFB\u4E0D\u5230\u3002",
228
+ wLabel: "\u540D\u79F0",
229
+ wKeywords: "\u5173\u6CE8\u54EA\u4E9B\u5B57\uFF08\u53EF\u9009\uFF0C\u7528\u9017\u53F7\u5206\u5F00\uFF09",
230
+ wKeywordsHint: "\u586B\u4E86\u5C31\u53EA\u5728\u51FA\u73B0\u8FD9\u4E9B\u5B57\u65F6\u63D0\u9192\u4F60\uFF1B\u4E0D\u586B\u5C31\u662F\u6709\u53D8\u5316\u5C31\u63D0\u9192\u3002",
231
+ wEvery: "\u591A\u4E45\u770B\u4E00\u6B21",
232
+ wEveryUnit: (n) => `${n} \u5206\u949F`,
233
+ wTest: "\u5148\u8BD5\u8BFB\u4E00\u4E0B",
234
+ wTesting: "\u6B63\u5728\u8BFB\u2026",
235
+ wTestOk: (n, title) => `\u8BFB\u5230\u4E86 ${n} \u6761\u5185\u5BB9\uFF0C\u7B2C\u4E00\u6761\u662F\u300C${title}\u300D\u3002`,
236
+ wTestNoHit: (word) => `\u8BFB\u5230\u4E86\uFF0C\u4F46\u7B2C\u4E00\u6761\u91CC\u6CA1\u6709\u300C${word}\u300D\u3002\u4FDD\u5B58\u540E\u8FD8\u4F1A\u7EE7\u7EED\u76EF\u7740\u3002`,
237
+ wTestHit: (word) => `\u8BFB\u5230\u4E86\uFF0C\u7B2C\u4E00\u6761\u91CC\u5C31\u6709\u300C${word}\u300D\u3002`,
238
+ wSave: "\u4FDD\u5B58",
239
+ wSaveAndCheck: "\u4FDD\u5B58\u5E76\u770B\u4E00\u6B21",
240
+ wCheckNow: "\u73B0\u5728\u770B\u4E00\u6B21",
241
+ wDeleteConfirm: "\u5220\u6389\u8FD9\u4E2A\u5173\u6CE8\uFF1F\u5B83\u8FD8\u6CA1\u5904\u7406\u7684\u4E8B\u9879\u4F1A\u88AB\u5173\u6389\u3002",
242
+ wNeverChecked: "\u8FD8\u6CA1\u770B\u8FC7",
243
+ wKeywordsNone: "\u6709\u4EFB\u4F55\u53D8\u5316\u5C31\u544A\u8BC9\u6211",
244
+ wKeywordsList: (words) => `\u63D0\u5230 ${words} \u65F6\u544A\u8BC9\u6211`,
245
+ wChecked: (at, n) => `${at} \u770B\u8FC7\uFF0C${n} \u6761\u5185\u5BB9`,
246
+ wDisabled: "\u5DF2\u505C\u7528",
247
+ wAskSetup: "\u4E0D\u77E5\u9053\u8BE5\u586B\u4EC0\u4E48\u7F51\u5740\uFF1F",
211
248
  sAddAccount: "+ \u6DFB\u52A0\u90AE\u7BB1",
212
249
  sEdit: "\u7F16\u8F91",
213
250
  sDelete: "\u5220\u9664",
@@ -248,6 +285,24 @@ var zh = {
248
285
  nQuiet: "\u514D\u6253\u6270\uFF0C\u4ECE",
249
286
  nTo: "\u5230",
250
287
  nZone: (zone) => `\u6309 ${zone} \u7684\u65F6\u95F4\u3002\u514D\u6253\u6270\u671F\u95F4\u4E0D\u53D1\uFF0C\u671F\u95F4\u51FA\u73B0\u7684\u6025\u4E8B\u7B49\u7ED3\u675F\u540E\u4E00\u8D77\u53D1\u3002`,
288
+ nSchedule: "\u4EA4\u7ED9 DSH \u7684\u81EA\u52A8\u5316\u4EFB\u52A1",
289
+ nScheduleHint: "\u9664\u4E86\u7535\u8111\u901A\u77E5\uFF0C\u7B80\u62A5\u4E5F\u53EF\u4EE5\u505A\u6210 DSH \u7684\u5B9A\u65F6\u4EFB\u52A1\uFF1A\u5230\u70B9\u5728\u5BF9\u8BDD\u91CC\u51FA\u73B0\u4E00\u6761\uFF0C\u4F60\u6253\u5F00 DSH \u5C31\u80FD\u770B\u89C1\u3002",
290
+ nScheduleArm: "\u628A\u7B80\u62A5\u505A\u6210\u5B9A\u65F6\u4EFB\u52A1",
291
+ nScheduleArmed: "\u7B80\u62A5\u5DF2\u7ECF\u662F\u5B9A\u65F6\u4EFB\u52A1\u4E86\uFF0C\u6539\u65F6\u95F4\u4F1A\u81EA\u52A8\u8DDF\u7740\u6539\u3002",
292
+ nScheduleDisarm: "\u53D6\u6D88\u8FD9\u4E2A\u5B9A\u65F6\u4EFB\u52A1",
293
+ nScheduleDisarmConfirm: "\u53D6\u6D88\u7B80\u62A5\u7684\u5B9A\u65F6\u4EFB\u52A1\uFF1F\u7535\u8111\u901A\u77E5\u4E0D\u53D7\u5F71\u54CD\u3002",
294
+ nScheduleNoService: "\u8FD9\u4E2A DSH \u6CA1\u6709\u81EA\u52A8\u5316\u4EFB\u52A1\u670D\u52A1\uFF08\u63D2\u4EF6\u6CA1\u88C5\uFF0C\u6216\u8005\u7248\u672C\u592A\u8001\uFF09\u3002\u7B80\u62A5\u53EA\u80FD\u7528\u7535\u8111\u901A\u77E5\u53D1\u3002",
295
+ nScheduleTasks: "DSH \u91CC\u7684\u5B9A\u65F6\u4EFB\u52A1",
296
+ nScheduleNone: "DSH \u91CC\u8FD8\u6CA1\u6709\u5B9A\u65F6\u4EFB\u52A1\u3002",
297
+ nScheduleMine: "\u5C0F\u79D8\u4E66\u5EFA\u7684",
298
+ nScheduleRunNow: "\u73B0\u5728\u8DD1\u4E00\u6B21",
299
+ nScheduleRunning: "\u6B63\u5728\u8DD1",
300
+ nScheduleDeleteConfirm: "\u5220\u6389\u8FD9\u4E2A\u5B9A\u65F6\u4EFB\u52A1\uFF1F\u5220\u4E86\u5C31\u4E0D\u518D\u6309\u65F6\u95F4\u8DD1\u4E86\u3002",
301
+ nScheduleNext: (when) => `\u4E0B\u4E00\u6B21 ${when}`,
302
+ nScheduleEnded: "\u5DF2\u7ECF\u8DD1\u5B8C\u4E86",
303
+ nSchedulePaused: "\u5DF2\u6682\u505C",
304
+ nScheduleLast: (when) => `\u4E0A\u6B21 ${when}`,
305
+ nSchedulePrompt: "\u5230\u70B9\u5B83\u4F1A\u8BF4",
251
306
  nChannels: "\u53D1\u5230\u54EA\u91CC",
252
307
  nDesktop: "\u7535\u8111\u901A\u77E5",
253
308
  nDesktopOn: "\u5728\u8FD9\u53F0\u7535\u8111\u53F3\u4E0A\u89D2\u5F39\u51FA\u901A\u77E5\u3002",
@@ -343,6 +398,7 @@ var en = {
343
398
  sourceGithub: "GitHub",
344
399
  sourceMail: "Mail",
345
400
  sourceManual: "Noted",
401
+ sourceWatch: "Watching",
346
402
  sGeneral: "General",
347
403
  sLanguage: "Language",
348
404
  sLanguageAuto: "Follow the system",
@@ -395,6 +451,34 @@ var en = {
395
451
  sPasswordTestOnly: "No keychain: used only to test the connection, not saved",
396
452
  secretKinds: { macos: "the macOS Keychain", windows: "Windows Credential Manager", linux: "the Linux keyring (Secret Service)", memory: "memory (tests)" },
397
453
  sNoAccounts: "No mail account yet.",
454
+ sWatch: "Things you watch",
455
+ sWatchHint: "Beyond GitHub and mail, the secretary can keep an eye on any address you give it: an announcements page, a price, a job posting, a feed. It looks now and then and puts a card on the board when something changes.",
456
+ sNoWatches: "Not watching anything yet.",
457
+ sAddWatch: "+ Watch an address",
458
+ wTitleAdd: "Watch an address",
459
+ wTitleEdit: "Edit watch",
460
+ wUrl: "Address",
461
+ wUrlHint: "An RSS feed, a JSON endpoint or a plain page all work. Pages behind a login cannot be read.",
462
+ wLabel: "Name",
463
+ wKeywords: "Words to watch for (optional, comma separated)",
464
+ wKeywordsHint: "With words, it only tells you when they show up; without, any change is worth a card.",
465
+ wEvery: "Check every",
466
+ wEveryUnit: (n) => `${n} minutes`,
467
+ wTest: "Read it once",
468
+ wTesting: "Reading\u2026",
469
+ wTestOk: (n, title) => `Read ${n} entries; the first is "${title}".`,
470
+ wTestNoHit: (word) => `It loaded, but the first entry does not mention "${word}". It keeps watching after you save.`,
471
+ wTestHit: (word) => `It loaded, and the first entry mentions "${word}".`,
472
+ wSave: "Save",
473
+ wSaveAndCheck: "Save and look once",
474
+ wCheckNow: "Look now",
475
+ wDeleteConfirm: "Delete this watch? Anything it still has open is closed.",
476
+ wNeverChecked: "Not checked yet",
477
+ wKeywordsNone: "tell me about any change",
478
+ wKeywordsList: (words) => `tell me when it mentions ${words}`,
479
+ wChecked: (at, n) => `checked ${at}, ${n} entries`,
480
+ wDisabled: "disabled",
481
+ wAskSetup: "Not sure what address to use?",
398
482
  sAddAccount: "+ Add a mail account",
399
483
  sEdit: "Edit",
400
484
  sDelete: "Delete",
@@ -435,6 +519,24 @@ var en = {
435
519
  nQuiet: "Quiet hours from",
436
520
  nTo: "to",
437
521
  nZone: (zone) => `In ${zone} time. Nothing is sent during quiet hours; urgent items from then come when they end.`,
522
+ nSchedule: "Hand the brief to DSH's scheduled tasks",
523
+ nScheduleHint: "Besides a desktop notification, the brief can be a DSH scheduled task: at that hour a turn appears in a conversation, there whenever you open DSH.",
524
+ nScheduleArm: "Make the brief a scheduled task",
525
+ nScheduleArmed: "The brief is a scheduled task; changing its time moves it too.",
526
+ nScheduleDisarm: "Remove that scheduled task",
527
+ nScheduleDisarmConfirm: "Remove the brief's scheduled task? The desktop notification is unaffected.",
528
+ nScheduleNoService: "This DSH has no scheduled-tasks service (the plugin is missing or too old). The brief stays a desktop notification.",
529
+ nScheduleTasks: "Scheduled tasks on this DSH",
530
+ nScheduleNone: "No scheduled tasks yet.",
531
+ nScheduleMine: "made by the secretary",
532
+ nScheduleRunNow: "Run now",
533
+ nScheduleRunning: "Running",
534
+ nScheduleDeleteConfirm: "Delete this scheduled task? It will stop running.",
535
+ nScheduleNext: (when) => `next ${when}`,
536
+ nScheduleEnded: "already finished",
537
+ nSchedulePaused: "paused",
538
+ nScheduleLast: (when) => `last ${when}`,
539
+ nSchedulePrompt: "What it will say",
438
540
  nChannels: "Where to send",
439
541
  nDesktop: "This computer",
440
542
  nDesktopOn: "A notification in the corner of this screen.",
@@ -516,7 +618,7 @@ function AskAI({ topic, lang, locale, openChat: openChat2, compact = false }) {
516
618
  }
517
619
 
518
620
  // src/client/Settings.tsx
519
- var import_react5 = require("react");
621
+ var import_react6 = require("react");
520
622
 
521
623
  // src/client/Fold.tsx
522
624
  var import_react2 = require("react");
@@ -730,19 +832,115 @@ function FeishuDialog({ lang, locale, onDone }) {
730
832
  ] });
731
833
  }
732
834
 
733
- // src/client/Settings.tsx
835
+ // src/client/Schedule.tsx
836
+ var import_react5 = require("react");
734
837
  var import_jsx_runtime5 = require("react/jsx-runtime");
838
+ function ScheduleSection({ view, lang, locale, take }) {
839
+ const t = TEXT[lang];
840
+ const [busy, setBusy] = (0, import_react5.useState)();
841
+ const [error, setError] = (0, import_react5.useState)();
842
+ const schedule = view.schedule;
843
+ if (schedule === null) {
844
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
845
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: t.nSchedule }),
846
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-hint", children: t.nScheduleNoService })
847
+ ] });
848
+ }
849
+ const act = async (key, call, saved) => {
850
+ setBusy(key);
851
+ const result = await call();
852
+ setBusy(void 0);
853
+ setError(result.ok ? void 0 : result.message);
854
+ take(result, saved);
855
+ };
856
+ const afterTask = (result) => {
857
+ if (!result.ok) {
858
+ setError(result.message);
859
+ return;
860
+ }
861
+ setError(void 0);
862
+ take({ ok: true, view: { ...view, schedule: result.schedule } });
863
+ };
864
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
865
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: t.nSchedule }),
866
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-hint", children: t.nScheduleHint }),
867
+ schedule.brief.armed ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
868
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-ok", children: t.nScheduleArmed }),
869
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-actions", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", disabled: busy !== void 0, onClick: () => {
870
+ if (window.confirm(t.nScheduleDisarmConfirm)) void act("disarm", () => settingsApi.disarmBrief(locale()));
871
+ }, children: t.nScheduleDisarm }) })
872
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-actions", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", disabled: busy !== void 0, onClick: () => {
873
+ void act("arm", () => settingsApi.armBrief(locale()), t.sSaved);
874
+ }, children: busy === "arm" ? t.loading : t.nScheduleArm }) }),
875
+ schedule.brief.error === null ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-error", children: schedule.brief.error }),
876
+ error === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-error", children: error }),
877
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: t.nScheduleTasks }),
878
+ schedule.tasks.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-empty", children: t.nScheduleNone }) : schedule.tasks.map((task) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
879
+ TaskRow,
880
+ {
881
+ task,
882
+ lang,
883
+ locale,
884
+ busy: busy === task.id,
885
+ onRun: () => {
886
+ setBusy(task.id);
887
+ void settingsApi.runTask(locale(), task.id).then((r) => {
888
+ setBusy(void 0);
889
+ afterTask(r);
890
+ });
891
+ },
892
+ onDelete: () => {
893
+ setBusy(task.id);
894
+ void settingsApi.deleteTask(locale(), task.id).then((r) => {
895
+ setBusy(void 0);
896
+ afterTask(r);
897
+ });
898
+ }
899
+ },
900
+ task.id
901
+ ))
902
+ ] });
903
+ }
904
+ function TaskRow({ task, lang, locale, busy, onRun, onDelete }) {
905
+ const t = TEXT[lang];
906
+ const state = task.status === "ended" ? t.nScheduleEnded : task.status === "paused" ? t.nSchedulePaused : task.next === null ? "" : t.nScheduleNext(task.next);
907
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Fold, { id: `task-${task.id}`, title: `${task.title}${task.mine ? ` \xB7 ${t.nScheduleMine}` : ""}`, children: [
908
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-card-meta", children: [
909
+ task.when,
910
+ state === "" ? "" : ` \xB7 ${state}`
911
+ ] }),
912
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-card-meta", children: [
913
+ task.running ? t.nScheduleRunning : "",
914
+ task.lastDelivery === null ? "" : `${task.running ? " \xB7 " : ""}${t.nScheduleLast(task.lastDelivery)}`
915
+ ] }),
916
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-card-note", children: [
917
+ t.nSchedulePrompt,
918
+ "\uFF1A",
919
+ task.prompt
920
+ ] }),
921
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-actions", children: [
922
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", disabled: busy || task.status === "ended", onClick: onRun, children: busy ? t.loading : t.nScheduleRunNow }),
923
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn mishu-btn-quiet", disabled: busy, onClick: () => {
924
+ if (window.confirm(t.nScheduleDeleteConfirm)) onDelete();
925
+ }, children: t.sDelete })
926
+ ] })
927
+ ] });
928
+ }
929
+
930
+ // src/client/Settings.tsx
931
+ var import_jsx_runtime6 = require("react/jsx-runtime");
735
932
  var CATEGORIES = ["document", "bill", "birthday", "renewal", "other"];
736
933
  function MishuSettings({ lang, locale, openChat: openChat2 }) {
737
934
  const t = TEXT[lang];
738
- const [view, setView] = (0, import_react5.useState)();
739
- const [error, setError] = (0, import_react5.useState)();
740
- const [note, setNote] = (0, import_react5.useState)();
741
- const [lead, setLead] = (0, import_react5.useState)({});
742
- const [githubTest, setGithubTest] = (0, import_react5.useState)();
743
- const [confirmOn, setConfirmOn] = (0, import_react5.useState)(false);
744
- const [pasting, setPasting] = (0, import_react5.useState)(false);
745
- const [editing, setEditing] = (0, import_react5.useState)();
935
+ const [view, setView] = (0, import_react6.useState)();
936
+ const [error, setError] = (0, import_react6.useState)();
937
+ const [note, setNote] = (0, import_react6.useState)();
938
+ const [lead, setLead] = (0, import_react6.useState)({});
939
+ const [githubTest, setGithubTest] = (0, import_react6.useState)();
940
+ const [confirmOn, setConfirmOn] = (0, import_react6.useState)(false);
941
+ const [pasting, setPasting] = (0, import_react6.useState)(false);
942
+ const [editing, setEditing] = (0, import_react6.useState)();
943
+ const [watching, setWatching] = (0, import_react6.useState)();
746
944
  const take = (result, saved) => {
747
945
  if (result.ok) {
748
946
  setView(result.view);
@@ -753,11 +951,11 @@ function MishuSettings({ lang, locale, openChat: openChat2 }) {
753
951
  setError(result.message);
754
952
  }
755
953
  };
756
- (0, import_react5.useEffect)(() => {
954
+ (0, import_react6.useEffect)(() => {
757
955
  void settingsApi.load(locale()).then((r) => take(r));
758
956
  }, [locale]);
759
957
  if (view === void 0) {
760
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-settings", children: error === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-empty", children: t.loading }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-error", children: [
958
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-settings", children: error === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-empty", children: t.loading }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-error", children: [
761
959
  t.failed,
762
960
  error
763
961
  ] }) });
@@ -765,71 +963,71 @@ function MishuSettings({ lang, locale, openChat: openChat2 }) {
765
963
  const save = async (settings) => take(await settingsApi.save(locale(), settings), t.sSaved);
766
964
  const token = view.github.token;
767
965
  const secretKind = t.secretKinds[view.secrets.kind] ?? view.secrets.kind;
768
- const markRead = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
769
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-field", children: [
966
+ const markRead = /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
967
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
770
968
  t.sMarkRead,
771
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("select", { value: view.settings.markRead, onChange: (e) => {
969
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("select", { value: view.settings.markRead, onChange: (e) => {
772
970
  const value = e.target.value;
773
971
  if (value === "on") setConfirmOn(true);
774
972
  else void save({ markRead: value });
775
973
  }, children: [
776
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "off", children: t.sMarkOff }),
777
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "shadow", children: t.sMarkShadow }),
778
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "on", children: t.sMarkOn })
974
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "off", children: t.sMarkOff }),
975
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "shadow", children: t.sMarkShadow }),
976
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "on", children: t.sMarkOn })
779
977
  ] })
780
978
  ] }),
781
- confirmOn ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-banner", children: [
782
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { children: t.sMarkConfirm }),
783
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-actions", children: [
784
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn primary", onClick: () => {
979
+ confirmOn ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-banner", children: [
980
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children: t.sMarkConfirm }),
981
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-actions", children: [
982
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn primary", onClick: () => {
785
983
  setConfirmOn(false);
786
984
  void save({ markRead: "on" });
787
985
  }, children: t.sConfirm }),
788
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => setConfirmOn(false), children: t.sCancel })
986
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => setConfirmOn(false), children: t.sCancel })
789
987
  ] })
790
988
  ] }) : null
791
989
  ] });
792
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FoldGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-settings", children: [
793
- error === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-error", children: [
990
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(FoldGroup, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-settings", children: [
991
+ error === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-error", children: [
794
992
  t.failed,
795
993
  error
796
994
  ] }),
797
- note === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-ok", children: note }),
798
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Fold, { id: "sources", className: "mishu-panel", title: t.bSources, children: [
799
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-hint", children: t.bSourcesHint }),
800
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: t.sGithub }),
801
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-check", children: [
802
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "checkbox", checked: view.settings.githubEnabled, onChange: (e) => {
995
+ note === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-ok", children: note }),
996
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Fold, { id: "sources", className: "mishu-panel", title: t.bSources, children: [
997
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint", children: t.bSourcesHint }),
998
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { children: t.sGithub }),
999
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-check", children: [
1000
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "checkbox", checked: view.settings.githubEnabled, onChange: (e) => {
803
1001
  void save({ githubEnabled: e.target.checked });
804
1002
  } }),
805
1003
  t.sGithubOn
806
1004
  ] }),
807
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-row-explain", children: [
808
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "mishu-row-label", children: t.sToken }),
809
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: token.found ? "" : "mishu-danger", children: token.found ? token.from === "env" ? t.sTokenEnv(view.github.tokenEnv) : token.from === "keychain" ? t.sTokenKeychain : t.sTokenGh : token.text })
1005
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-row-explain", children: [
1006
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mishu-row-label", children: t.sToken }),
1007
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: token.found ? "" : "mishu-danger", children: token.found ? token.from === "env" ? t.sTokenEnv(view.github.tokenEnv) : token.from === "keychain" ? t.sTokenKeychain : t.sTokenGh : token.text })
810
1008
  ] }),
811
- token.found ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-actions", children: [
812
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => {
1009
+ token.found ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-actions", children: [
1010
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => {
813
1011
  setGithubTest(t.sTesting);
814
1012
  void settingsApi.testGithub(locale()).then((r) => setGithubTest(r.ok ? t.sGithubOk(r.login) : `${t.failed}${r.message}`));
815
1013
  }, children: t.sTest }),
816
- token.from === "env" || pasting ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => setPasting(true), children: t.sTokenReplace }),
817
- token.from === "keychain" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn mishu-btn-quiet", onClick: () => {
1014
+ token.from === "env" || pasting ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => setPasting(true), children: t.sTokenReplace }),
1015
+ token.from === "keychain" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn mishu-btn-quiet", onClick: () => {
818
1016
  if (window.confirm(t.sTokenRemoveConfirm)) void settingsApi.deleteToken(locale()).then((r) => {
819
1017
  setGithubTest(void 0);
820
1018
  take(r);
821
1019
  });
822
1020
  }, children: t.sTokenRemove }) : null,
823
- githubTest === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "mishu-hint", children: githubTest })
1021
+ githubTest === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mishu-hint", children: githubTest })
824
1022
  ] }) : null,
825
- !token.found || pasting ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(GithubConnect, { view, lang, locale, onSaved: (next, login) => {
1023
+ !token.found || pasting ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(GithubConnect, { view, lang, locale, onSaved: (next, login) => {
826
1024
  setPasting(false);
827
1025
  setGithubTest(t.sTokenSaved(login));
828
1026
  take({ ok: true, view: next });
829
1027
  }, onCancel: token.found ? () => setPasting(false) : void 0 }) : null,
830
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { children: t.sMail }),
831
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-hint", children: t.sMailPrivacy }),
832
- view.accounts.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-empty", children: t.sNoAccounts }) : view.accounts.map((account) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1028
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { children: t.sMail }),
1029
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint", children: t.sMailPrivacy }),
1030
+ view.accounts.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-empty", children: t.sNoAccounts }) : view.accounts.map((account) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
833
1031
  AccountRow,
834
1032
  {
835
1033
  account,
@@ -842,8 +1040,8 @@ function MishuSettings({ lang, locale, openChat: openChat2 }) {
842
1040
  },
843
1041
  account.id
844
1042
  )),
845
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn mishu-add-toggle", onClick: () => setEditing({ preset: "custom", sinceDays: 14, enabled: true }), children: t.sAddAccount }),
846
- editing === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1043
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn mishu-add-toggle", onClick: () => setEditing({ preset: "custom", sinceDays: 14, enabled: true }), children: t.sAddAccount }),
1044
+ editing === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
847
1045
  MailDialog,
848
1046
  {
849
1047
  draft: editing,
@@ -856,52 +1054,83 @@ function MishuSettings({ lang, locale, openChat: openChat2 }) {
856
1054
  if (next !== void 0) take({ ok: true, view: next }, note2 ?? t.sSaved);
857
1055
  }
858
1056
  }
1057
+ ),
1058
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { children: t.sWatch }),
1059
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint", children: t.sWatchHint }),
1060
+ view.watches.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-empty", children: t.sNoWatches }) : view.watches.map((watch) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1061
+ WatchRow,
1062
+ {
1063
+ watch,
1064
+ lang,
1065
+ locale,
1066
+ openChat: openChat2,
1067
+ onEdit: () => setWatching({ ...watch }),
1068
+ onView: (next) => take(next)
1069
+ },
1070
+ watch.id
1071
+ )),
1072
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn mishu-add-toggle", onClick: () => setWatching({ label: "", url: "", keywords: "", enabled: true, intervalMinutes: 60 }), children: t.sAddWatch }),
1073
+ watching === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1074
+ WatchDialog,
1075
+ {
1076
+ draft: watching,
1077
+ lang,
1078
+ locale,
1079
+ openChat: openChat2,
1080
+ onDone: (next, note2) => {
1081
+ setWatching(void 0);
1082
+ if (next !== void 0) take({ ok: true, view: next }, note2 ?? t.sSaved);
1083
+ }
1084
+ }
859
1085
  )
860
1086
  ] }),
861
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Fold, { id: "what", className: "mishu-panel", title: t.bWhat, children: [
862
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-hint", children: t.bUrgentRule }),
863
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-field", children: t.sLead }),
864
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-grid5", children: CATEGORIES.map((c) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-field", children: [
1087
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Fold, { id: "what", className: "mishu-panel", title: t.bWhat, children: [
1088
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint", children: t.bUrgentRule }),
1089
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-field", children: t.sLead }),
1090
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-grid5", children: CATEGORIES.map((c) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
865
1091
  t.categories[c],
866
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "number", min: 0, max: 366, value: lead[c] ?? 0, onChange: (e) => setLead({ ...lead, [c]: Number(e.target.value) }) })
1092
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "number", min: 0, max: 366, value: lead[c] ?? 0, onChange: (e) => setLead({ ...lead, [c]: Number(e.target.value) }) })
867
1093
  ] }, c)) }),
868
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn primary", onClick: () => {
1094
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn primary", onClick: () => {
869
1095
  void save({ leadDays: lead });
870
1096
  }, children: t.sSave })
871
1097
  ] }),
872
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Fold, { id: "when", className: "mishu-panel", title: t.bWhen, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(NotifySection, { view, lang, locale, take }) }),
873
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Fold, { id: "do", className: "mishu-panel", title: t.bDo, children: [
1098
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Fold, { id: "when", className: "mishu-panel", title: t.bWhen, children: [
1099
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(NotifySection, { view, lang, locale, take }),
1100
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ScheduleSection, { view, lang, locale, take })
1101
+ ] }),
1102
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Fold, { id: "do", className: "mishu-panel", title: t.bDo, children: [
874
1103
  markRead,
875
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-hint", children: t.bMailReadOnly })
1104
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint", children: t.bMailReadOnly })
876
1105
  ] }),
877
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Fold, { id: "general", className: "mishu-panel", title: t.sGeneral, children: [
878
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-field", children: [
1106
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Fold, { id: "general", className: "mishu-panel", title: t.sGeneral, children: [
1107
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
879
1108
  t.sLanguage,
880
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("select", { value: view.settings.language, onChange: (e) => {
1109
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("select", { value: view.settings.language, onChange: (e) => {
881
1110
  void save({ language: e.target.value });
882
1111
  }, children: [
883
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "auto", children: t.sLanguageAuto }),
884
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "zh", children: "\u4E2D\u6587" }),
885
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: "en", children: "English" })
1112
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "auto", children: t.sLanguageAuto }),
1113
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "zh", children: "\u4E2D\u6587" }),
1114
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: "en", children: "English" })
886
1115
  ] })
887
1116
  ] }),
888
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: view.secrets.available && view.secrets.file === void 0 ? "mishu-hint" : "mishu-hint mishu-warn", children: !view.secrets.available ? t.sSecretsNone(view.secrets.why ?? secretKind) : view.secrets.file !== void 0 ? t.sSecretsFile(view.secrets.file.path, view.secrets.file.why) : t.sSecretsAt(secretKind) })
1117
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: view.secrets.available && view.secrets.file === void 0 ? "mishu-hint" : "mishu-hint mishu-warn", children: !view.secrets.available ? t.sSecretsNone(view.secrets.why ?? secretKind) : view.secrets.file !== void 0 ? t.sSecretsFile(view.secrets.file.path, view.secrets.file.why) : t.sSecretsAt(secretKind) })
889
1118
  ] })
890
1119
  ] }) });
891
1120
  }
892
1121
  function GithubConnect({ view, lang, locale, onSaved, onCancel }) {
893
1122
  const t = TEXT[lang];
894
- const [signingIn, setSigningIn] = (0, import_react5.useState)(false);
895
- const [paste, setPaste] = (0, import_react5.useState)(!view.github.deviceLogin);
896
- if (!view.github.deviceLogin) return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TokenForm, { view, lang, locale, onSaved, onCancel });
897
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
898
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-actions", children: [
899
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn primary", onClick: () => setSigningIn(true), children: t.gLogin }),
900
- paste ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn mishu-btn-quiet", onClick: () => setPaste(true), children: t.gPasteInstead }),
901
- onCancel === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", onClick: onCancel, children: t.sCancel })
1123
+ const [signingIn, setSigningIn] = (0, import_react6.useState)(false);
1124
+ const [paste, setPaste] = (0, import_react6.useState)(!view.github.deviceLogin);
1125
+ if (!view.github.deviceLogin) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TokenForm, { view, lang, locale, onSaved, onCancel });
1126
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1127
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-actions", children: [
1128
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn primary", onClick: () => setSigningIn(true), children: t.gLogin }),
1129
+ paste ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn mishu-btn-quiet", onClick: () => setPaste(true), children: t.gPasteInstead }),
1130
+ onCancel === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: onCancel, children: t.sCancel })
902
1131
  ] }),
903
- paste ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TokenForm, { view, lang, locale, onSaved, onCancel: void 0 }) : null,
904
- signingIn ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(GithubLoginDialog, { lang, locale, onClose: () => setSigningIn(false), onSaved: (next, login) => {
1132
+ paste ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TokenForm, { view, lang, locale, onSaved, onCancel: void 0 }) : null,
1133
+ signingIn ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(GithubLoginDialog, { lang, locale, onClose: () => setSigningIn(false), onSaved: (next, login) => {
905
1134
  setSigningIn(false);
906
1135
  onSaved(next, login);
907
1136
  } }) : null
@@ -909,12 +1138,12 @@ function GithubConnect({ view, lang, locale, onSaved, onCancel }) {
909
1138
  }
910
1139
  function GithubLoginDialog({ lang, locale, onClose, onSaved }) {
911
1140
  const t = TEXT[lang];
912
- const [login, setLogin] = (0, import_react5.useState)();
913
- const [error, setError] = (0, import_react5.useState)();
914
- const [copied, setCopied] = (0, import_react5.useState)(false);
915
- const [attempt, setAttempt] = (0, import_react5.useState)(0);
916
- const saved = (0, import_react5.useRef)(void 0);
917
- (0, import_react5.useEffect)(() => {
1141
+ const [login, setLogin] = (0, import_react6.useState)();
1142
+ const [error, setError] = (0, import_react6.useState)();
1143
+ const [copied, setCopied] = (0, import_react6.useState)(false);
1144
+ const [attempt, setAttempt] = (0, import_react6.useState)(0);
1145
+ const saved = (0, import_react6.useRef)(void 0);
1146
+ (0, import_react6.useEffect)(() => {
918
1147
  let alive = true;
919
1148
  let timer;
920
1149
  setLogin(void 0);
@@ -958,42 +1187,42 @@ function GithubLoginDialog({ lang, locale, onClose, onSaved }) {
958
1187
  const copy2 = (code) => {
959
1188
  void navigator.clipboard?.writeText(code).then(() => setCopied(true), () => setCopied(false));
960
1189
  };
961
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Modal, { title: t.gLogin, onClose: close, children: error !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
962
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-preview mishu-danger", children: error }),
963
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-actions", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", onClick: close, children: t.gClose }) })
964
- ] }) : login === void 0 || login.state === "idle" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-hint", children: t.gStarting }) : login.state === "waiting" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
965
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-field", children: t.gStep1 }),
966
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-code-row", children: [
967
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("code", { className: "mishu-code", children: login.userCode }),
968
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => copy2(login.userCode), children: copied ? t.gCopied : t.gCopy })
1190
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Modal, { title: t.gLogin, onClose: close, children: error !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1191
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-preview mishu-danger", children: error }),
1192
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-actions", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: close, children: t.gClose }) })
1193
+ ] }) : login === void 0 || login.state === "idle" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint", children: t.gStarting }) : login.state === "waiting" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1194
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-field", children: t.gStep1 }),
1195
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-code-row", children: [
1196
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { className: "mishu-code", children: login.userCode }),
1197
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => copy2(login.userCode), children: copied ? t.gCopied : t.gCopy })
969
1198
  ] }),
970
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-field", children: t.gStep2 }),
971
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-actions", children: [
972
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn primary", onClick: () => window.open(login.verificationUri, "_blank", "noopener"), children: t.gOpen }),
973
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "mishu-hint", children: t.gWaiting })
1199
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-field", children: t.gStep2 }),
1200
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-actions", children: [
1201
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn primary", onClick: () => window.open(login.verificationUri, "_blank", "noopener"), children: t.gOpen }),
1202
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mishu-hint", children: t.gWaiting })
974
1203
  ] }),
975
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-hint", children: t.gScopes })
976
- ] }) : login.state === "done" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
977
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-ok", children: t.gDone(login.login) }),
978
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-actions", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn primary", onClick: close, children: t.gClose }) })
979
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
980
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-preview mishu-danger", children: login.message }),
981
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-actions", children: [
982
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn primary", onClick: () => {
1204
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint", children: t.gScopes })
1205
+ ] }) : login.state === "done" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1206
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-ok", children: t.gDone(login.login) }),
1207
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-actions", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn primary", onClick: close, children: t.gClose }) })
1208
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1209
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-preview mishu-danger", children: login.message }),
1210
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-actions", children: [
1211
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn primary", onClick: () => {
983
1212
  setCopied(false);
984
1213
  setAttempt(attempt + 1);
985
1214
  }, children: t.gRetry }),
986
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", onClick: close, children: t.gClose })
1215
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: close, children: t.gClose })
987
1216
  ] })
988
1217
  ] }) });
989
1218
  }
990
1219
  function TokenForm({ view, lang, locale, onSaved, onCancel }) {
991
1220
  const t = TEXT[lang];
992
- const [token, setToken] = (0, import_react5.useState)("");
993
- const [busy, setBusy] = (0, import_react5.useState)(false);
994
- const [message, setMessage] = (0, import_react5.useState)();
1221
+ const [token, setToken] = (0, import_react6.useState)("");
1222
+ const [busy, setBusy] = (0, import_react6.useState)(false);
1223
+ const [message, setMessage] = (0, import_react6.useState)();
995
1224
  if (!view.secrets.available) {
996
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-hint mishu-warn", children: t.sTokenNoKeychain(view.github.tokenEnv, view.secrets.why ?? "") });
1225
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint mishu-warn", children: t.sTokenNoKeychain(view.github.tokenEnv, view.secrets.why ?? "") });
997
1226
  }
998
1227
  const save = async () => {
999
1228
  setBusy(true);
@@ -1007,54 +1236,54 @@ function TokenForm({ view, lang, locale, onSaved, onCancel }) {
1007
1236
  setMessage(r.message);
1008
1237
  }
1009
1238
  };
1010
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-add", children: [
1011
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-field", children: [
1239
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-add", children: [
1240
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
1012
1241
  t.sTokenPaste,
1013
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "password", value: token, autoComplete: "off", spellCheck: false, placeholder: "ghp_\u2026", onChange: (e) => {
1242
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "password", value: token, autoComplete: "off", spellCheck: false, placeholder: "ghp_\u2026", onChange: (e) => {
1014
1243
  setToken(e.target.value);
1015
1244
  setMessage(void 0);
1016
1245
  } })
1017
1246
  ] }),
1018
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-hint", children: t.sTokenHow }),
1019
- message === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-preview mishu-danger", children: message }),
1020
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-actions", children: [
1021
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => window.open(view.github.newTokenUrl, "_blank", "noopener"), children: t.sTokenNew }),
1022
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn primary", disabled: busy || token.trim() === "", onClick: () => {
1247
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint", children: t.sTokenHow }),
1248
+ message === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-preview mishu-danger", children: message }),
1249
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-actions", children: [
1250
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => window.open(view.github.newTokenUrl, "_blank", "noopener"), children: t.sTokenNew }),
1251
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn primary", disabled: busy || token.trim() === "", onClick: () => {
1023
1252
  void save();
1024
1253
  }, children: busy ? t.sTesting : t.sTokenSave }),
1025
- onCancel === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", onClick: onCancel, children: t.sCancel })
1254
+ onCancel === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: onCancel, children: t.sCancel })
1026
1255
  ] })
1027
1256
  ] });
1028
1257
  }
1029
1258
  function AccountRow({ account, secretsOk, lang, locale, openChat: openChat2, onEdit, onView }) {
1030
1259
  const t = TEXT[lang];
1031
- const [busy, setBusy] = (0, import_react5.useState)(false);
1260
+ const [busy, setBusy] = (0, import_react6.useState)(false);
1032
1261
  const report = account.report;
1033
1262
  const status = !account.hasPassword ? secretsOk ? t.sNoPassword : t.sEnvHint(account.envName) : report === null ? t.sNeverChecked : report.error !== void 0 ? report.error[lang] : lang === "zh" ? `${new Date(report.at).toLocaleString()} \u6536\u4FE1\uFF0C${report.messages} \u5C01\u672A\u8BFB` : `checked ${new Date(report.at).toLocaleString()}, ${report.messages} unread`;
1034
1263
  const failed = !account.hasPassword || report?.error !== void 0;
1035
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Fold, { id: `account-${account.id}`, title: `${account.label}${account.enabled ? "" : ` (${lang === "zh" ? "\u5DF2\u505C\u7528" : "disabled"})`}`, children: [
1036
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-card-meta", children: [
1264
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Fold, { id: `account-${account.id}`, title: `${account.label}${account.enabled ? "" : ` (${lang === "zh" ? "\u5DF2\u505C\u7528" : "disabled"})`}`, children: [
1265
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-card-meta", children: [
1037
1266
  account.address,
1038
1267
  " \xB7 ",
1039
1268
  account.host,
1040
1269
  ":",
1041
1270
  account.port
1042
1271
  ] }),
1043
- account.mismatch === null ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "mishu-card-note mishu-warn", children: account.mismatch }),
1044
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `mishu-card-note ${failed ? "mishu-danger" : ""}`, children: [
1272
+ account.mismatch === null ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-card-note mishu-warn", children: account.mismatch }),
1273
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `mishu-card-note ${failed ? "mishu-danger" : ""}`, children: [
1045
1274
  status,
1046
- account.hasPassword && report?.error !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AskAI, { topic: { kind: "mail-error", accountId: account.id }, lang, locale, openChat: openChat2, compact: true }) : null
1275
+ account.hasPassword && report?.error !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AskAI, { topic: { kind: "mail-error", accountId: account.id }, lang, locale, openChat: openChat2, compact: true }) : null
1047
1276
  ] }),
1048
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-actions", children: [
1049
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", disabled: busy || !account.hasPassword, onClick: () => {
1277
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-actions", children: [
1278
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", disabled: busy || !account.hasPassword, onClick: () => {
1050
1279
  setBusy(true);
1051
1280
  void settingsApi.syncMail(locale(), account.id).then((r) => {
1052
1281
  setBusy(false);
1053
1282
  onView(r);
1054
1283
  });
1055
1284
  }, children: busy ? t.sTesting : t.sCheckNow }),
1056
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: account.hasPassword && account.mismatch === null ? "mishu-btn" : "mishu-btn primary", onClick: onEdit, children: t.sEdit }),
1057
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn mishu-btn-quiet", onClick: () => {
1285
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: account.hasPassword && account.mismatch === null ? "mishu-btn" : "mishu-btn primary", onClick: onEdit, children: t.sEdit }),
1286
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn mishu-btn-quiet", onClick: () => {
1058
1287
  if (window.confirm(t.sDeleteConfirm)) void settingsApi.deleteMail(locale(), account.id).then(onView);
1059
1288
  }, children: t.sDelete })
1060
1289
  ] })
@@ -1063,12 +1292,12 @@ function AccountRow({ account, secretsOk, lang, locale, openChat: openChat2, onE
1063
1292
  function MailDialog({ draft, view, lang, locale, openChat: openChat2, onDone }) {
1064
1293
  const t = TEXT[lang];
1065
1294
  const existing = draft.id !== void 0;
1066
- const [account, setAccount] = (0, import_react5.useState)(draft);
1067
- const [picked, setPicked] = (0, import_react5.useState)(existing);
1068
- const [password, setPassword] = (0, import_react5.useState)("");
1069
- const [message, setMessage] = (0, import_react5.useState)();
1070
- const [failedTest, setFailedTest] = (0, import_react5.useState)(false);
1071
- const [busy, setBusy] = (0, import_react5.useState)(false);
1295
+ const [account, setAccount] = (0, import_react6.useState)(draft);
1296
+ const [picked, setPicked] = (0, import_react6.useState)(existing);
1297
+ const [password, setPassword] = (0, import_react6.useState)("");
1298
+ const [message, setMessage] = (0, import_react6.useState)();
1299
+ const [failedTest, setFailedTest] = (0, import_react6.useState)(false);
1300
+ const [busy, setBusy] = (0, import_react6.useState)(false);
1072
1301
  const preset = view.presets.find((p) => p.id === account.preset) ?? view.presets[view.presets.length - 1];
1073
1302
  const custom = preset.id === "custom";
1074
1303
  const set = (patch) => {
@@ -1101,93 +1330,220 @@ function MailDialog({ draft, view, lang, locale, openChat: openChat2, onDone })
1101
1330
  setMessage({ ok: false, text: r.message });
1102
1331
  }
1103
1332
  };
1104
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Modal, { title: existing ? t.mTitleEdit : t.mTitleAdd, onClose: () => onDone(), children: [
1105
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-field", children: [
1333
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Modal, { title: existing ? t.mTitleEdit : t.mTitleAdd, onClose: () => onDone(), children: [
1334
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
1106
1335
  t.sAddress,
1107
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "email", value: account.address ?? "", autoComplete: "off", autoFocus: !existing, onChange: (e) => setAddress(e.target.value) })
1336
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "email", value: account.address ?? "", autoComplete: "off", autoFocus: !existing, onChange: (e) => setAddress(e.target.value) })
1108
1337
  ] }),
1109
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-field", children: [
1338
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
1110
1339
  t.sProvider,
1111
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("select", { value: account.preset, onChange: (e) => {
1340
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("select", { value: account.preset, onChange: (e) => {
1112
1341
  setPicked(true);
1113
1342
  set({ preset: e.target.value });
1114
- }, children: view.presets.map((p) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: p.id, children: p.label }, p.id)) })
1343
+ }, children: view.presets.map((p) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value: p.id, children: p.label }, p.id)) })
1115
1344
  ] }),
1116
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `mishu-steps${preset.supported ? "" : " mishu-danger"}${failedTest ? " attention" : ""}`, children: [
1117
- preset.steps.length === 0 ? preset.howTo : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ol", { children: preset.steps.map((step, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("li", { children: [
1345
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `mishu-steps${preset.supported ? "" : " mishu-danger"}${failedTest ? " attention" : ""}`, children: [
1346
+ preset.steps.length === 0 ? preset.howTo : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ol", { children: preset.steps.map((step, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { children: [
1118
1347
  step.text,
1119
- step.link === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1348
+ step.link === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1120
1349
  " ",
1121
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => window.open(step.link.url, "_blank", "noopener"), children: step.link.label })
1350
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => window.open(step.link.url, "_blank", "noopener"), children: step.link.label })
1122
1351
  ] })
1123
1352
  ] }, i)) }),
1124
- preset.supported ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-steps-help", children: [
1353
+ preset.supported ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-steps-help", children: [
1125
1354
  t.mStepsHelp,
1126
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AskAI, { topic: { kind: "mail-setup", preset: preset.id }, lang, locale, openChat: openChat2, compact: true })
1355
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AskAI, { topic: { kind: "mail-setup", preset: preset.id }, lang, locale, openChat: openChat2, compact: true })
1127
1356
  ] }) : null
1128
1357
  ] }),
1129
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-field", children: [
1358
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
1130
1359
  t.sPassword,
1131
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "password", value: password, autoComplete: "new-password", placeholder: existing && view.secrets.available ? t.sPasswordKeep : "", onChange: (e) => {
1360
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "password", value: password, autoComplete: "new-password", placeholder: existing && view.secrets.available ? t.sPasswordKeep : "", onChange: (e) => {
1132
1361
  setPassword(e.target.value);
1133
1362
  setMessage(void 0);
1134
1363
  setFailedTest(false);
1135
1364
  } })
1136
1365
  ] }),
1137
- lengthOff ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-hint mishu-warn", children: t.mLength(preset.label, preset.passwordLength, typed.length) }) : null,
1138
- view.secrets.available ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "mishu-hint mishu-warn", children: t.sPasswordTestOnly }),
1139
- custom ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-row", children: [
1140
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-field", children: [
1366
+ lengthOff ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint mishu-warn", children: t.mLength(preset.label, preset.passwordLength, typed.length) }) : null,
1367
+ view.secrets.available ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint mishu-warn", children: t.sPasswordTestOnly }),
1368
+ custom ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-row", children: [
1369
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
1141
1370
  t.sHost,
1142
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { value: account.host ?? "", placeholder: "imap.example.com", onChange: (e) => set({ host: e.target.value }) })
1371
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { value: account.host ?? "", placeholder: "imap.example.com", onChange: (e) => set({ host: e.target.value }) })
1143
1372
  ] }),
1144
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-field", children: [
1373
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
1145
1374
  t.sPort,
1146
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "number", value: account.port ?? 993, onChange: (e) => set({ port: Number(e.target.value) }) })
1375
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "number", value: account.port ?? 993, onChange: (e) => set({ port: Number(e.target.value) }) })
1147
1376
  ] })
1148
1377
  ] }) : null,
1149
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("details", { className: "mishu-more", children: [
1150
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("summary", { children: t.mMore }),
1151
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-row", children: [
1152
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-field", children: [
1378
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("details", { className: "mishu-more", children: [
1379
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("summary", { children: t.mMore }),
1380
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-row", children: [
1381
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
1153
1382
  t.sLabel,
1154
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { value: account.label ?? "", placeholder: account.address ?? "", onChange: (e) => set({ label: e.target.value }) })
1383
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { value: account.label ?? "", placeholder: account.address ?? "", onChange: (e) => set({ label: e.target.value }) })
1155
1384
  ] }),
1156
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-field", children: [
1385
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
1157
1386
  t.sUser,
1158
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { value: account.user ?? "", placeholder: account.address ?? "", autoComplete: "off", onChange: (e) => set({ user: e.target.value }) })
1387
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { value: account.user ?? "", placeholder: account.address ?? "", autoComplete: "off", onChange: (e) => set({ user: e.target.value }) })
1159
1388
  ] })
1160
1389
  ] }),
1161
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-row", children: [
1162
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-field", children: [
1390
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-row", children: [
1391
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
1163
1392
  t.sSince,
1164
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "number", min: 1, max: 90, value: account.sinceDays ?? 14, onChange: (e) => set({ sinceDays: Number(e.target.value) }) })
1393
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "number", min: 1, max: 90, value: account.sinceDays ?? 14, onChange: (e) => set({ sinceDays: Number(e.target.value) }) })
1165
1394
  ] }),
1166
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "mishu-check", children: [
1167
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("input", { type: "checkbox", checked: account.enabled !== false, onChange: (e) => set({ enabled: e.target.checked }) }),
1395
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-check", children: [
1396
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "checkbox", checked: account.enabled !== false, onChange: (e) => set({ enabled: e.target.checked }) }),
1168
1397
  t.sEnabled
1169
1398
  ] })
1170
1399
  ] })
1171
1400
  ] }),
1172
- message === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `mishu-preview ${message.ok ? "" : "mishu-danger"}`, children: [
1401
+ message === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `mishu-preview ${message.ok ? "" : "mishu-danger"}`, children: [
1173
1402
  message.text,
1174
- message.ok || !preset.supported ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AskAI, { topic: { kind: "mail-setup", preset: preset.id, error: message.text }, lang, locale, openChat: openChat2, compact: true })
1403
+ message.ok || !preset.supported ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AskAI, { topic: { kind: "mail-setup", preset: preset.id, error: message.text }, lang, locale, openChat: openChat2, compact: true })
1175
1404
  ] }),
1176
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "mishu-actions", children: [
1177
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn primary", disabled: busy || !preset.supported || (account.address ?? "") === "", onClick: () => {
1405
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-actions", children: [
1406
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn primary", disabled: busy || !preset.supported || (account.address ?? "") === "", onClick: () => {
1178
1407
  void testAndSave();
1179
1408
  }, children: busy ? t.sTesting : t.mTestSave }),
1180
- failedTest ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn mishu-btn-quiet", disabled: busy, onClick: () => {
1409
+ failedTest ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn mishu-btn-quiet", disabled: busy, onClick: () => {
1181
1410
  setBusy(true);
1182
1411
  void save();
1183
1412
  }, children: t.mSaveAnyway }) : null,
1184
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => onDone(), children: t.sCancel })
1413
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => onDone(), children: t.sCancel })
1185
1414
  ] })
1186
1415
  ] });
1187
1416
  }
1417
+ function WatchRow({ watch, lang, locale, openChat: openChat2, onEdit, onView }) {
1418
+ const t = TEXT[lang];
1419
+ const [busy, setBusy] = (0, import_react6.useState)(false);
1420
+ const failed = watch.report?.error !== void 0;
1421
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Fold, { id: `watch-${watch.id}`, title: `${watch.label}${watch.enabled ? "" : ` (${t.wDisabled})`}`, children: [
1422
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-card-meta", children: [
1423
+ watch.url,
1424
+ " \xB7 ",
1425
+ t.wEveryUnit(watch.intervalMinutes)
1426
+ ] }),
1427
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-card-meta", children: watch.summary }),
1428
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `mishu-card-note ${failed ? "mishu-danger" : ""}`, children: [
1429
+ watch.status,
1430
+ failed ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AskAI, { topic: { kind: "watch-error", watchId: watch.id }, lang, locale, openChat: openChat2, compact: true }) : null
1431
+ ] }),
1432
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-actions", children: [
1433
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", disabled: busy, onClick: () => {
1434
+ setBusy(true);
1435
+ void settingsApi.syncWatch(locale(), watch.id).then((r) => {
1436
+ setBusy(false);
1437
+ onView(r);
1438
+ });
1439
+ }, children: busy ? t.wTesting : t.wCheckNow }),
1440
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: onEdit, children: t.sEdit }),
1441
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn mishu-btn-quiet", onClick: () => {
1442
+ if (window.confirm(t.wDeleteConfirm)) void settingsApi.deleteWatch(locale(), watch.id).then(onView);
1443
+ }, children: t.sDelete })
1444
+ ] })
1445
+ ] });
1446
+ }
1447
+ function WatchDialog({ draft, lang, locale, openChat: openChat2, onDone }) {
1448
+ const t = TEXT[lang];
1449
+ const existing = draft.id !== void 0;
1450
+ const [watch, setWatch] = (0, import_react6.useState)(draft);
1451
+ const [message, setMessage] = (0, import_react6.useState)();
1452
+ const [tested, setTested] = (0, import_react6.useState)();
1453
+ const [busy, setBusy] = (0, import_react6.useState)(false);
1454
+ const set = (patch) => {
1455
+ setWatch({ ...watch, ...patch });
1456
+ setMessage(void 0);
1457
+ setTested(void 0);
1458
+ };
1459
+ const save = async (thenCheck = false) => {
1460
+ setBusy(true);
1461
+ const r = await settingsApi.saveWatch(locale(), watch);
1462
+ if (!r.ok) {
1463
+ setBusy(false);
1464
+ setMessage({ ok: false, text: r.message });
1465
+ return;
1466
+ }
1467
+ let view = r.view;
1468
+ if (thenCheck) {
1469
+ const checked = await settingsApi.syncWatch(locale(), r.id);
1470
+ if (checked.ok) view = checked.view;
1471
+ }
1472
+ setBusy(false);
1473
+ onDone(view, t.sSaved);
1474
+ };
1475
+ const test = async () => {
1476
+ setBusy(true);
1477
+ setMessage({ ok: true, text: t.wTesting });
1478
+ const r = await settingsApi.testWatch(locale(), watch);
1479
+ setBusy(false);
1480
+ if (!r.ok) {
1481
+ setMessage({ ok: false, text: r.message });
1482
+ return;
1483
+ }
1484
+ setTested(r);
1485
+ const hit = r.keywordHit === void 0 ? void 0 : r.keyword;
1486
+ setMessage({
1487
+ ok: true,
1488
+ text: r.keywordHit === false && hit !== void 0 ? `${t.wTestOk(r.items, r.title)} ${t.wTestNoHit(hit)}` : r.keywordHit === true && hit !== void 0 ? `${t.wTestOk(r.items, r.title)} ${t.wTestHit(hit)}` : t.wTestOk(r.items, r.title)
1489
+ });
1490
+ };
1491
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(Modal, { title: existing ? t.wTitleEdit : t.wTitleAdd, onClose: () => onDone(), children: [
1492
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
1493
+ t.wUrl,
1494
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { value: watch.url, autoComplete: "off", autoFocus: !existing, placeholder: "https://example.com/news.xml", onChange: (e) => set({ url: e.target.value }) })
1495
+ ] }),
1496
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint", children: t.wUrlHint }),
1497
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
1498
+ t.wLabel,
1499
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { value: watch.label, placeholder: hostOf(watch.url), onChange: (e) => set({ label: e.target.value }) })
1500
+ ] }),
1501
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
1502
+ t.wKeywords,
1503
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { value: watch.keywords, placeholder: lang === "zh" ? "\u4E0A\u65B0, \u8865\u4E01, \u9762\u8BD5" : "release, patch, interview", onChange: (e) => set({ keywords: e.target.value }) })
1504
+ ] }),
1505
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint", children: t.wKeywordsHint }),
1506
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-row", children: [
1507
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
1508
+ t.wEvery,
1509
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "number", min: 15, max: 1440, step: 15, value: watch.intervalMinutes, onChange: (e) => set({ intervalMinutes: Number(e.target.value) }) })
1510
+ ] }),
1511
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-check", children: [
1512
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "checkbox", checked: watch.enabled, onChange: (e) => set({ enabled: e.target.checked }) }),
1513
+ t.sEnabled
1514
+ ] })
1515
+ ] }),
1516
+ tested === void 0 ? null : tested.excerpt === "" ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-preview", children: tested.excerpt }),
1517
+ message === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `mishu-preview ${message.ok ? "" : "mishu-danger"}`, children: [
1518
+ message.text,
1519
+ message.ok ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AskAI, { topic: { kind: "watch-setup" }, lang, locale, openChat: openChat2, compact: true })
1520
+ ] }),
1521
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-actions", children: [
1522
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", disabled: busy || watch.url.trim() === "", onClick: () => {
1523
+ void test();
1524
+ }, children: t.wTest }),
1525
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn primary", disabled: busy || watch.url.trim() === "", onClick: () => {
1526
+ void save(true);
1527
+ }, children: busy ? t.wTesting : t.wSaveAndCheck }),
1528
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => onDone(), children: t.sCancel })
1529
+ ] }),
1530
+ existing ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "mishu-hint", children: [
1531
+ t.wAskSetup,
1532
+ " ",
1533
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AskAI, { topic: { kind: "watch-setup" }, lang, locale, openChat: openChat2, compact: true })
1534
+ ] })
1535
+ ] });
1536
+ }
1537
+ function hostOf(url) {
1538
+ try {
1539
+ return new URL(url).hostname;
1540
+ } catch {
1541
+ return "";
1542
+ }
1543
+ }
1188
1544
 
1189
1545
  // src/client/Board.tsx
1190
- var import_jsx_runtime6 = require("react/jsx-runtime");
1546
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1191
1547
  var SOURCE_KEY = "dsh-mishu.source";
1192
1548
  function loadSource() {
1193
1549
  try {
@@ -1223,15 +1579,15 @@ function saveWidths(widths) {
1223
1579
  }
1224
1580
  }
1225
1581
  function MishuBoard({ locale, openChat: openChat2 }) {
1226
- const [board, setBoard] = (0, import_react6.useState)();
1227
- const [error, setError] = (0, import_react6.useState)();
1228
- const [busy, setBusy] = (0, import_react6.useState)(false);
1229
- const [syncing, setSyncing] = (0, import_react6.useState)(false);
1230
- const [dropOn, setDropOn] = (0, import_react6.useState)();
1231
- const [widths, setWidths] = (0, import_react6.useState)(loadWidths);
1232
- const [tab, setTab] = (0, import_react6.useState)("board");
1233
- const [openCard, setOpenCard] = (0, import_react6.useState)();
1234
- const [source, setSourceState] = (0, import_react6.useState)(loadSource);
1582
+ const [board, setBoard] = (0, import_react7.useState)();
1583
+ const [error, setError] = (0, import_react7.useState)();
1584
+ const [busy, setBusy] = (0, import_react7.useState)(false);
1585
+ const [syncing, setSyncing] = (0, import_react7.useState)(false);
1586
+ const [dropOn, setDropOn] = (0, import_react7.useState)();
1587
+ const [widths, setWidths] = (0, import_react7.useState)(loadWidths);
1588
+ const [tab, setTab] = (0, import_react7.useState)("board");
1589
+ const [openCard, setOpenCard] = (0, import_react7.useState)();
1590
+ const [source, setSourceState] = (0, import_react7.useState)(loadSource);
1235
1591
  const setSource = (next) => {
1236
1592
  setSourceState(next);
1237
1593
  try {
@@ -1239,11 +1595,11 @@ function MishuBoard({ locale, openChat: openChat2 }) {
1239
1595
  } catch {
1240
1596
  }
1241
1597
  };
1242
- const dragged = (0, import_react6.useRef)(void 0);
1243
- const columnsRef = (0, import_react6.useRef)(null);
1598
+ const dragged = (0, import_react7.useRef)(void 0);
1599
+ const columnsRef = (0, import_react7.useRef)(null);
1244
1600
  const lang = board?.lang ?? uiLang(locale());
1245
1601
  const t = TEXT[lang];
1246
- const take = (0, import_react6.useCallback)((result) => {
1602
+ const take = (0, import_react7.useCallback)((result) => {
1247
1603
  if (result.ok) {
1248
1604
  setBoard(result.board);
1249
1605
  setError(void 0);
@@ -1251,8 +1607,8 @@ function MishuBoard({ locale, openChat: openChat2 }) {
1251
1607
  setError(result.message);
1252
1608
  }
1253
1609
  }, []);
1254
- const load = (0, import_react6.useCallback)(() => mishuApi.board(locale()).then(take), [locale, take]);
1255
- (0, import_react6.useEffect)(() => {
1610
+ const load = (0, import_react7.useCallback)(() => mishuApi.board(locale()).then(take), [locale, take]);
1611
+ (0, import_react7.useEffect)(() => {
1256
1612
  void load();
1257
1613
  const timer = setInterval(() => {
1258
1614
  void load();
@@ -1347,7 +1703,7 @@ function MishuBoard({ locale, openChat: openChat2 }) {
1347
1703
  const key = cardKey(item);
1348
1704
  setOpenCard((current) => current === key ? void 0 : key);
1349
1705
  };
1350
- const card = (item, column) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1706
+ const card = (item, column) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1351
1707
  Card,
1352
1708
  {
1353
1709
  item,
@@ -1373,12 +1729,12 @@ function MishuBoard({ locale, openChat: openChat2 }) {
1373
1729
  cardKey(item)
1374
1730
  );
1375
1731
  if (board === void 0) {
1376
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-page", children: [
1377
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-head", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-title", children: [
1378
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h1", { children: t.title }),
1379
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RestartButton, { lang, locale })
1732
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-page", children: [
1733
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-head", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-title", children: [
1734
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h1", { children: t.title }),
1735
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RestartButton, { lang, locale })
1380
1736
  ] }) }),
1381
- error === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-empty", children: t.loading }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-error", children: [
1737
+ error === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "mishu-empty", children: t.loading }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-error", children: [
1382
1738
  t.failed,
1383
1739
  error
1384
1740
  ] })
@@ -1400,10 +1756,11 @@ function MishuBoard({ locale, openChat: openChat2 }) {
1400
1756
  { id: "all", label: t.all },
1401
1757
  { id: "github", label: t.sourceGithub },
1402
1758
  { id: "mail", label: t.sourceMail },
1759
+ { id: "watch", label: t.sourceWatch },
1403
1760
  { id: "manual", label: t.sourceManual }
1404
1761
  ];
1405
1762
  const template = `minmax(0, ${widths[0]}fr) 10px minmax(0, ${widths[1]}fr) 10px minmax(0, ${widths[2]}fr)`;
1406
- const divider = (index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1763
+ const divider = (index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1407
1764
  "div",
1408
1765
  {
1409
1766
  className: "mishu-divider",
@@ -1414,107 +1771,112 @@ function MishuBoard({ locale, openChat: openChat2 }) {
1414
1771
  onDoubleClick: resetWidths
1415
1772
  }
1416
1773
  );
1417
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-page", "data-mishu-board": "", children: [
1418
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-head", children: [
1419
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-title", children: [
1420
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h1", { children: t.title }),
1421
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-tabs", role: "tablist", children: [
1422
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", role: "tab", "aria-selected": tab === "board", className: tab === "board" ? "active" : "", onClick: () => setTab("board"), children: t.tabBoard }),
1423
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", role: "tab", "aria-selected": tab === "settings", className: tab === "settings" ? "active" : "", onClick: () => setTab("settings"), children: t.tabSettings })
1774
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-page", "data-mishu-board": "", children: [
1775
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-head", children: [
1776
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-title", children: [
1777
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h1", { children: t.title }),
1778
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-tabs", role: "tablist", children: [
1779
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", role: "tab", "aria-selected": tab === "board", className: tab === "board" ? "active" : "", onClick: () => setTab("board"), children: t.tabBoard }),
1780
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", role: "tab", "aria-selected": tab === "settings", className: tab === "settings" ? "active" : "", onClick: () => setTab("settings"), children: t.tabSettings })
1424
1781
  ] }),
1425
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(RestartButton, { lang, locale })
1782
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RestartButton, { lang, locale })
1426
1783
  ] }),
1427
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-sources", children: [
1428
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
1429
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("i", { className: `mishu-dot ${board.sources.github.state}` }),
1784
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-sources", children: [
1785
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
1786
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("i", { className: `mishu-dot ${board.sources.github.state}` }),
1430
1787
  board.sources.github.text,
1431
- board.sources.github.state === "error" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AskAI, { topic: { kind: "github-error" }, lang, locale, openChat: openChat2, compact: true }) : null
1788
+ board.sources.github.state === "error" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AskAI, { topic: { kind: "github-error" }, lang, locale, openChat: openChat2, compact: true }) : null
1432
1789
  ] }),
1433
- board.sources.mail.map((m) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
1434
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("i", { className: `mishu-dot ${m.state}` }),
1790
+ board.sources.mail.map((m) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
1791
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("i", { className: `mishu-dot ${m.state}` }),
1435
1792
  m.text,
1436
- m.state === "error" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AskAI, { topic: { kind: "mail-error", accountId: m.id }, lang, locale, openChat: openChat2, compact: true }) : null
1793
+ m.state === "error" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AskAI, { topic: { kind: "mail-error", accountId: m.id }, lang, locale, openChat: openChat2, compact: true }) : null
1437
1794
  ] }, m.id)),
1438
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", disabled: syncing, onClick: () => {
1795
+ board.sources.watch.map((w) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
1796
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("i", { className: `mishu-dot ${w.state}` }),
1797
+ w.text,
1798
+ w.state === "error" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AskAI, { topic: { kind: "watch-error", watchId: w.id }, lang, locale, openChat: openChat2, compact: true }) : null
1799
+ ] }, `watch-${w.id}`)),
1800
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "mishu-btn", disabled: syncing, onClick: () => {
1439
1801
  void sync();
1440
1802
  }, children: syncing ? t.syncing : t.sync })
1441
1803
  ] })
1442
1804
  ] }),
1443
- tab === "settings" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MishuSettings, { lang, locale, openChat: openChat2 }) : null,
1444
- tab === "settings" ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1445
- error === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-error", children: [
1805
+ tab === "settings" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MishuSettings, { lang, locale, openChat: openChat2 }) : null,
1806
+ tab === "settings" ? null : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1807
+ error === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-error", children: [
1446
1808
  t.failed,
1447
1809
  error
1448
1810
  ] }),
1449
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "mishu-summary", children: [
1811
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "mishu-summary", children: [
1450
1812
  board.summary,
1451
1813
  " ",
1452
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AskAI, { topic: { kind: "summary" }, lang, locale, openChat: openChat2, compact: true })
1814
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AskAI, { topic: { kind: "summary" }, lang, locale, openChat: openChat2, compact: true })
1453
1815
  ] }),
1454
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-metrics", children: [
1455
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-metric", children: [
1456
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-metric-label", children: t.metricHandle }),
1457
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-metric-value", children: [
1816
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-metrics", children: [
1817
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-metric", children: [
1818
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-metric-label", children: t.metricHandle }),
1819
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-metric-value", children: [
1458
1820
  metrics.handle,
1459
- metrics.overdue > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("small", { className: "mishu-danger", children: [
1821
+ metrics.overdue > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("small", { className: "mishu-danger", children: [
1460
1822
  metrics.overdue,
1461
1823
  " ",
1462
1824
  t.metricOverdue
1463
1825
  ] }) : null
1464
1826
  ] })
1465
1827
  ] }),
1466
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-metric", children: [
1467
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-metric-label", children: t.metricSoon }),
1468
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-metric-value", children: metrics.dueSoon })
1828
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-metric", children: [
1829
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-metric-label", children: t.metricSoon }),
1830
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-metric-value", children: metrics.dueSoon })
1469
1831
  ] }),
1470
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-metric", children: [
1471
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-metric-label", children: t.metricClosed }),
1472
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-metric-value", children: metrics.closedToday })
1832
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-metric", children: [
1833
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-metric-label", children: t.metricClosed }),
1834
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-metric-value", children: metrics.closedToday })
1473
1835
  ] }),
1474
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-metric", children: [
1475
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-metric-label", children: t.metricShadow }),
1476
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-metric-value", children: [
1836
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-metric", children: [
1837
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-metric-label", children: t.metricShadow }),
1838
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-metric-value", children: [
1477
1839
  metrics.shadow,
1478
- board.markRead === "shadow" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("small", { className: "mishu-warn", children: t.shadowTag }) : null
1840
+ board.markRead === "shadow" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("small", { className: "mishu-warn", children: t.shadowTag }) : null
1479
1841
  ] })
1480
1842
  ] })
1481
1843
  ] }),
1482
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-filters", role: "group", children: sources.map((s) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", "aria-pressed": source === s.id, className: `mishu-chip ${source === s.id ? "active" : ""}`, onClick: () => setSource(s.id), children: [
1844
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-filters", role: "group", children: sources.map((s) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", "aria-pressed": source === s.id, className: `mishu-chip ${source === s.id ? "active" : ""}`, onClick: () => setSource(s.id), children: [
1483
1845
  s.label,
1484
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: count(s.id) })
1846
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: count(s.id) })
1485
1847
  ] }, s.id)) }),
1486
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-columns", ref: columnsRef, style: { ["--mishu-cols"]: template }, children: [
1487
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: `mishu-col ${dropOn === "handle" ? "drop" : ""}`, ...dropProps("handle"), "aria-label": t.handle, children: [
1488
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-col-head", children: [
1848
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-columns", ref: columnsRef, style: { ["--mishu-cols"]: template }, children: [
1849
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: `mishu-col ${dropOn === "handle" ? "drop" : ""}`, ...dropProps("handle"), "aria-label": t.handle, children: [
1850
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-col-head", children: [
1489
1851
  t.handle,
1490
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: columns.handle.length })
1852
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: columns.handle.length })
1491
1853
  ] }),
1492
- columns.handle.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-empty", children: t.emptyHandle }) : columns.handle.map((item) => card(item, "handle"))
1854
+ columns.handle.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-empty", children: t.emptyHandle }) : columns.handle.map((item) => card(item, "handle"))
1493
1855
  ] }),
1494
1856
  divider(0),
1495
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: `mishu-col ${dropOn === "remember" ? "drop" : ""}`, ...dropProps("remember"), "aria-label": t.remember, title: t.dropRemember, children: [
1496
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-col-head", children: [
1857
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: `mishu-col ${dropOn === "remember" ? "drop" : ""}`, ...dropProps("remember"), "aria-label": t.remember, title: t.dropRemember, children: [
1858
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-col-head", children: [
1497
1859
  t.remember,
1498
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: columns.remember.length })
1860
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: columns.remember.length })
1499
1861
  ] }),
1500
- columns.remember.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-empty", children: t.emptyRemember }) : columns.remember.map((item) => card(item, "remember")),
1501
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AddForm, { lang, locale, onAdded: (next) => setBoard(next) })
1862
+ columns.remember.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-empty", children: t.emptyRemember }) : columns.remember.map((item) => card(item, "remember")),
1863
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AddForm, { lang, locale, onAdded: (next) => setBoard(next) })
1502
1864
  ] }),
1503
1865
  divider(1),
1504
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { className: `mishu-col ${dropOn === "done" ? "drop" : ""}`, ...dropProps("done"), "aria-label": t.done, title: t.dropDone, children: [
1505
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-col-head", children: [
1866
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { className: `mishu-col ${dropOn === "done" ? "drop" : ""}`, ...dropProps("done"), "aria-label": t.done, title: t.dropDone, children: [
1867
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-col-head", children: [
1506
1868
  t.done,
1507
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: columns.done.total })
1869
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: columns.done.total })
1508
1870
  ] }),
1509
- columns.done.groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-empty", children: t.emptyDone }) : columns.done.groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("details", { className: "mishu-group", children: [
1510
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("summary", { children: [
1871
+ columns.done.groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-empty", children: t.emptyDone }) : columns.done.groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("details", { className: "mishu-group", children: [
1872
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("summary", { children: [
1511
1873
  group.label,
1512
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: group.items.length })
1874
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: group.items.length })
1513
1875
  ] }),
1514
1876
  group.items.map((item) => card(item, "done"))
1515
1877
  ] }, group.reason)),
1516
- columns.done.total > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint", children: t.doneHint }) : null,
1517
- metrics.shadow > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-banner", children: t.shadow(metrics.shadow) }) : null
1878
+ columns.done.total > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "mishu-hint", children: t.doneHint }) : null,
1879
+ metrics.shadow > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-banner", children: t.shadow(metrics.shadow) }) : null
1518
1880
  ] })
1519
1881
  ] })
1520
1882
  ] })
@@ -1522,10 +1884,10 @@ function MishuBoard({ locale, openChat: openChat2 }) {
1522
1884
  }
1523
1885
  function Card({ item, column, lang, locale, busy, label, openChat: openChat2, open, onToggle, onAct, onDragStart, onDragEnd }) {
1524
1886
  const t = TEXT[lang];
1525
- const [detail, setDetail] = (0, import_react6.useState)();
1887
+ const [detail, setDetail] = (0, import_react7.useState)();
1526
1888
  const explain = item.explain;
1527
1889
  const compact = column === "done";
1528
- (0, import_react6.useEffect)(() => {
1890
+ (0, import_react7.useEffect)(() => {
1529
1891
  if (!open || item.target !== "matter" || detail !== void 0) return;
1530
1892
  let alive = true;
1531
1893
  void mishuApi.detail(locale(), item.id).then((r) => {
@@ -1535,11 +1897,11 @@ function Card({ item, column, lang, locale, busy, label, openChat: openChat2, op
1535
1897
  alive = false;
1536
1898
  };
1537
1899
  }, [open, item.target, item.id, detail, locale]);
1538
- const row = (name, text, className = "") => text === null || text === void 0 || text === "" ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `mishu-row-explain ${className}`, children: [
1539
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mishu-row-label", children: name }),
1540
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: text })
1900
+ const row = (name, text, className = "") => text === null || text === void 0 || text === "" ? null : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `mishu-row-explain ${className}`, children: [
1901
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "mishu-row-label", children: name }),
1902
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: text })
1541
1903
  ] });
1542
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1904
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1543
1905
  "div",
1544
1906
  {
1545
1907
  className: `mishu-card ${open ? "open" : ""} ${item.tone === "normal" ? "" : item.tone}`,
@@ -1550,7 +1912,7 @@ function Card({ item, column, lang, locale, busy, label, openChat: openChat2, op
1550
1912
  },
1551
1913
  onDragEnd,
1552
1914
  children: [
1553
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1915
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1554
1916
  "div",
1555
1917
  {
1556
1918
  className: "mishu-card-head",
@@ -1565,40 +1927,40 @@ function Card({ item, column, lang, locale, busy, label, openChat: openChat2, op
1565
1927
  onToggle();
1566
1928
  },
1567
1929
  children: [
1568
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mishu-caret", "aria-hidden": "true" }),
1569
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mishu-card-title", children: item.title })
1930
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "mishu-caret", "aria-hidden": "true" }),
1931
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "mishu-card-title", children: item.title })
1570
1932
  ]
1571
1933
  }
1572
1934
  ),
1573
- open ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-card-body", children: [
1574
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-card-meta", children: item.meta }),
1575
- !compact && explain !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-explain", children: [
1935
+ open ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-card-body", children: [
1936
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-card-meta", children: item.meta }),
1937
+ !compact && explain !== null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-explain", children: [
1576
1938
  row(t.what, explain.what),
1577
1939
  row(column === "remember" ? t.whyKeep : t.why, explain.why),
1578
1940
  row(t.fix, explain.fix, "mishu-fix")
1579
1941
  ] }) : null,
1580
- !compact && explain === null && item.note !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-card-note", children: item.note }) : null,
1581
- item.target === "matter" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-detail", children: detail === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-empty", children: t.loading }) : "error" in detail ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-danger", children: detail.error }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1582
- compact && detail.explain !== null ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1942
+ !compact && explain === null && item.note !== null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-card-note", children: item.note }) : null,
1943
+ item.target === "matter" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-detail", children: detail === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-empty", children: t.loading }) : "error" in detail ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-danger", children: detail.error }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1944
+ compact && detail.explain !== null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1583
1945
  row(t.what, detail.explain.what),
1584
1946
  row(t.whyDone, detail.explain.why)
1585
1947
  ] }) : null,
1586
- detail.did.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-row-explain", children: [
1587
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "mishu-row-label", children: t.did }),
1588
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: detail.did.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children: line }, i)) })
1948
+ detail.did.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-row-explain", children: [
1949
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "mishu-row-label", children: t.did }),
1950
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: detail.did.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: line }, i)) })
1589
1951
  ] }) : null,
1590
- detail.messages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-messages", children: [
1591
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "mishu-row-label", children: t.messages(detail.messages.length) }),
1592
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { children: detail.messages.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { children: [
1593
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: m.at }),
1952
+ detail.messages.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-messages", children: [
1953
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "mishu-row-label", children: t.messages(detail.messages.length) }),
1954
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { children: detail.messages.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("li", { children: [
1955
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: m.at }),
1594
1956
  " ",
1595
1957
  m.title
1596
1958
  ] }, i)) })
1597
1959
  ] }) : null
1598
1960
  ] }) }) : null,
1599
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-actions", children: [
1600
- column === "handle" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AskAI, { topic: item.target === "series" ? { kind: "series", id: item.id } : { kind: "matter", id: item.id }, lang, locale, openChat: openChat2 }) : null,
1601
- item.actions.map((action, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1961
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-actions", children: [
1962
+ column === "handle" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AskAI, { topic: item.target === "series" ? { kind: "series", id: item.id } : { kind: "matter", id: item.id }, lang, locale, openChat: openChat2 }) : null,
1963
+ item.actions.map((action, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1602
1964
  "button",
1603
1965
  {
1604
1966
  type: "button",
@@ -1609,7 +1971,7 @@ function Card({ item, column, lang, locale, busy, label, openChat: openChat2, op
1609
1971
  },
1610
1972
  action
1611
1973
  )),
1612
- column === "handle" ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AskAI, { topic: item.target === "series" ? { kind: "series", id: item.id } : { kind: "matter", id: item.id }, lang, locale, openChat: openChat2, compact: true })
1974
+ column === "handle" ? null : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AskAI, { topic: item.target === "series" ? { kind: "series", id: item.id } : { kind: "matter", id: item.id }, lang, locale, openChat: openChat2, compact: true })
1613
1975
  ] })
1614
1976
  ] }) : null
1615
1977
  ]
@@ -1619,11 +1981,11 @@ function Card({ item, column, lang, locale, busy, label, openChat: openChat2, op
1619
1981
  var EMPTY = { title: "", due: "", repeat: "none", category: "other", note: "" };
1620
1982
  function AddForm({ lang, locale, onAdded }) {
1621
1983
  const t = TEXT[lang];
1622
- const [open, setOpen] = (0, import_react6.useState)(false);
1623
- const [item, setItem] = (0, import_react6.useState)(EMPTY);
1624
- const [preview, setPreview] = (0, import_react6.useState)();
1625
- const [saving, setSaving] = (0, import_react6.useState)(false);
1626
- (0, import_react6.useEffect)(() => {
1984
+ const [open, setOpen] = (0, import_react7.useState)(false);
1985
+ const [item, setItem] = (0, import_react7.useState)(EMPTY);
1986
+ const [preview, setPreview] = (0, import_react7.useState)();
1987
+ const [saving, setSaving] = (0, import_react7.useState)(false);
1988
+ (0, import_react7.useEffect)(() => {
1627
1989
  if (!open || item.title.trim() === "" || item.due === "") {
1628
1990
  setPreview(void 0);
1629
1991
  return;
@@ -1634,7 +1996,7 @@ function AddForm({ lang, locale, onAdded }) {
1634
1996
  return () => clearTimeout(timer);
1635
1997
  }, [open, item, locale]);
1636
1998
  if (!open) {
1637
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("button", { type: "button", className: "mishu-btn mishu-add-toggle", onClick: () => setOpen(true), children: [
1999
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("button", { type: "button", className: "mishu-btn mishu-add-toggle", onClick: () => setOpen(true), children: [
1638
2000
  "+ ",
1639
2001
  t.add
1640
2002
  ] });
@@ -1652,49 +2014,49 @@ function AddForm({ lang, locale, onAdded }) {
1652
2014
  setPreview({ ok: false, text: result.message });
1653
2015
  }
1654
2016
  };
1655
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-add", children: [
1656
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
2017
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-add", children: [
2018
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "mishu-field", children: [
1657
2019
  t.addTitle,
1658
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { value: item.title, placeholder: t.addTitlePlaceholder, onChange: set("title") })
2020
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { value: item.title, placeholder: t.addTitlePlaceholder, onChange: set("title") })
1659
2021
  ] }),
1660
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-row", children: [
1661
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
2022
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-row", children: [
2023
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "mishu-field", children: [
1662
2024
  t.addDue,
1663
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { type: "date", value: item.due, onChange: set("due") })
2025
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { type: "date", value: item.due, onChange: set("due") })
1664
2026
  ] }),
1665
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
2027
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "mishu-field", children: [
1666
2028
  t.addRepeat,
1667
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("select", { value: item.repeat, onChange: set("repeat"), children: Object.entries(t.repeats).map(([value, text]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value, children: text }, value)) })
2029
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("select", { value: item.repeat, onChange: set("repeat"), children: Object.entries(t.repeats).map(([value, text]) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value, children: text }, value)) })
1668
2030
  ] })
1669
2031
  ] }),
1670
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-row", children: [
1671
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
2032
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-row", children: [
2033
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "mishu-field", children: [
1672
2034
  t.addCategory,
1673
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("select", { value: item.category, onChange: set("category"), children: Object.entries(t.categories).map(([value, text]) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("option", { value, children: text }, value)) })
2035
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("select", { value: item.category, onChange: set("category"), children: Object.entries(t.categories).map(([value, text]) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value, children: text }, value)) })
1674
2036
  ] }),
1675
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "mishu-field", children: [
2037
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "mishu-field", children: [
1676
2038
  t.addNote,
1677
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("input", { value: item.note, onChange: set("note") })
2039
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { value: item.note, onChange: set("note") })
1678
2040
  ] })
1679
2041
  ] }),
1680
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: `mishu-preview ${preview?.ok === false ? "mishu-danger" : ""}`, children: preview?.text ?? t.previewHint }),
1681
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "mishu-actions", children: [
1682
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn primary", disabled: saving || preview?.ok !== true, onClick: () => {
2042
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: `mishu-preview ${preview?.ok === false ? "mishu-danger" : ""}`, children: preview?.text ?? t.previewHint }),
2043
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mishu-actions", children: [
2044
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "mishu-btn primary", disabled: saving || preview?.ok !== true, onClick: () => {
1683
2045
  void save();
1684
2046
  }, children: t.save }),
1685
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => {
2047
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "mishu-btn", onClick: () => {
1686
2048
  setOpen(false);
1687
2049
  setItem(EMPTY);
1688
2050
  }, children: t.cancel })
1689
2051
  ] }),
1690
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "mishu-hint", children: t.chatHint })
2052
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "mishu-hint", children: t.chatHint })
1691
2053
  ] });
1692
2054
  }
1693
2055
  function RestartButton({ lang, locale }) {
1694
2056
  const t = TEXT[lang];
1695
- const [why, setWhy] = (0, import_react6.useState)();
1696
- const [status, setStatus] = (0, import_react6.useState)();
1697
- (0, import_react6.useEffect)(() => {
2057
+ const [why, setWhy] = (0, import_react7.useState)();
2058
+ const [status, setStatus] = (0, import_react7.useState)();
2059
+ (0, import_react7.useEffect)(() => {
1698
2060
  void restartApi.info(locale()).then((r) => {
1699
2061
  if (r.ok && !r.supported) setWhy(r.why);
1700
2062
  });
@@ -1714,12 +2076,12 @@ function RestartButton({ lang, locale }) {
1714
2076
  setStatus({ ok: true, text: await reconnect(locale) ? t.restartReloading : t.restartSlow });
1715
2077
  }
1716
2078
  };
1717
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1718
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", className: "mishu-btn", title: why === void 0 ? t.restartTip : `${t.restartTip}
2079
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
2080
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "mishu-btn", title: why === void 0 ? t.restartTip : `${t.restartTip}
1719
2081
  ${why}`, disabled: status?.ok === true, onClick: () => {
1720
2082
  void restart();
1721
2083
  }, children: t.restart }),
1722
- status === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: status.ok ? "mishu-hint" : "mishu-hint mishu-warn", children: status.text })
2084
+ status === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: status.ok ? "mishu-hint" : "mishu-hint mishu-warn", children: status.text })
1723
2085
  ] });
1724
2086
  }
1725
2087
  async function reconnect(locale) {
@@ -1873,18 +2235,18 @@ var STYLES = `
1873
2235
  `;
1874
2236
 
1875
2237
  // src/client/index.tsx
1876
- var import_jsx_runtime7 = require("react/jsx-runtime");
2238
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1877
2239
  var PACKAGE_NAME = "dsh-mishu";
1878
2240
  var inject = ["slots", "locale"];
1879
2241
  var PANEL_ID = "dsh-mishu";
1880
2242
  var NS = "dsh-mishu";
1881
2243
  var openChat;
1882
2244
  function MishuIcon({ size }) {
1883
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.8, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
1884
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("rect", { x: "5", y: "4", width: "14", height: "17", rx: "2" }),
1885
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M9 4h6v3H9z" }),
1886
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M9 12l2 2 4-4" }),
1887
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("path", { d: "M9 17h6" })
2245
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.8, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
2246
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("rect", { x: "5", y: "4", width: "14", height: "17", rx: "2" }),
2247
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M9 4h6v3H9z" }),
2248
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M9 12l2 2 4-4" }),
2249
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M9 17h6" })
1888
2250
  ] });
1889
2251
  }
1890
2252
  function apply(ctx) {