dsh-group-status 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.en.md +36 -18
  3. package/README.md +39 -19
  4. package/lib/client.js +659 -300
  5. package/lib/client.js.map +1 -1
  6. package/lib/index.js +22 -9
  7. package/lib/types/client/BadgeSettingsCard.d.ts +24 -0
  8. package/lib/types/client/BadgeSettingsCard.d.ts.map +1 -0
  9. package/lib/types/client/BadgeSettingsCard.js +73 -0
  10. package/lib/types/client/BadgeSettingsCard.js.map +1 -0
  11. package/lib/types/client/badge-field.d.ts +44 -0
  12. package/lib/types/client/badge-field.d.ts.map +1 -0
  13. package/lib/types/client/badge-field.js +77 -0
  14. package/lib/types/client/badge-field.js.map +1 -0
  15. package/lib/types/client/badge-labels.d.ts +92 -0
  16. package/lib/types/client/badge-labels.d.ts.map +1 -0
  17. package/lib/types/client/badge-labels.js +150 -0
  18. package/lib/types/client/badge-labels.js.map +1 -0
  19. package/lib/types/client/badge-settings.d.ts +31 -3
  20. package/lib/types/client/badge-settings.d.ts.map +1 -1
  21. package/lib/types/client/badge-settings.js +50 -6
  22. package/lib/types/client/badge-settings.js.map +1 -1
  23. package/lib/types/client/facet-store.d.ts +46 -0
  24. package/lib/types/client/facet-store.d.ts.map +1 -0
  25. package/lib/types/client/facet-store.js +123 -0
  26. package/lib/types/client/facet-store.js.map +1 -0
  27. package/lib/types/client/facet-visibility.d.ts +17 -0
  28. package/lib/types/client/facet-visibility.d.ts.map +1 -0
  29. package/lib/types/client/facet-visibility.js +18 -0
  30. package/lib/types/client/facet-visibility.js.map +1 -0
  31. package/lib/types/client/facets.d.ts +265 -0
  32. package/lib/types/client/facets.d.ts.map +1 -0
  33. package/lib/types/client/facets.js +209 -0
  34. package/lib/types/client/facets.js.map +1 -0
  35. package/lib/types/client/group-status.d.ts +97 -45
  36. package/lib/types/client/group-status.d.ts.map +1 -1
  37. package/lib/types/client/group-status.js +148 -85
  38. package/lib/types/client/group-status.js.map +1 -1
  39. package/lib/types/client/index.d.ts +25 -0
  40. package/lib/types/client/index.d.ts.map +1 -1
  41. package/lib/types/client/index.js +59 -1
  42. package/lib/types/client/index.js.map +1 -1
  43. package/lib/types/client/legacy/bridge.d.ts +30 -0
  44. package/lib/types/client/legacy/bridge.d.ts.map +1 -0
  45. package/lib/types/client/legacy/bridge.js +58 -0
  46. package/lib/types/client/legacy/bridge.js.map +1 -0
  47. package/lib/types/client/legacy/register-legacy-facets.d.ts +14 -0
  48. package/lib/types/client/legacy/register-legacy-facets.d.ts.map +1 -0
  49. package/lib/types/client/legacy/register-legacy-facets.js +77 -0
  50. package/lib/types/client/legacy/register-legacy-facets.js.map +1 -0
  51. package/lib/types/client/legacy/schedule.d.ts +49 -0
  52. package/lib/types/client/legacy/schedule.d.ts.map +1 -0
  53. package/lib/types/client/legacy/schedule.js +73 -0
  54. package/lib/types/client/legacy/schedule.js.map +1 -0
  55. package/lib/types/client/legacy/store-source.d.ts +78 -0
  56. package/lib/types/client/legacy/store-source.d.ts.map +1 -0
  57. package/lib/types/client/legacy/store-source.js +82 -0
  58. package/lib/types/client/legacy/store-source.js.map +1 -0
  59. package/lib/types/client/legacy/waiting-review.d.ts +85 -0
  60. package/lib/types/client/legacy/waiting-review.d.ts.map +1 -0
  61. package/lib/types/client/legacy/waiting-review.js +179 -0
  62. package/lib/types/client/legacy/waiting-review.js.map +1 -0
  63. package/lib/types/client/locales.d.ts +46 -4
  64. package/lib/types/client/locales.d.ts.map +1 -1
  65. package/lib/types/client/locales.js +46 -4
  66. package/lib/types/client/locales.js.map +1 -1
  67. package/lib/types/client/rows/GroupBadge.d.ts +19 -25
  68. package/lib/types/client/rows/GroupBadge.d.ts.map +1 -1
  69. package/lib/types/client/rows/GroupBadge.js +45 -106
  70. package/lib/types/client/rows/GroupBadge.js.map +1 -1
  71. package/lib/types/client/rows/Rows.d.ts +7 -3
  72. package/lib/types/client/rows/Rows.d.ts.map +1 -1
  73. package/lib/types/client/rows/Rows.js +6 -6
  74. package/lib/types/client/rows/Rows.js.map +1 -1
  75. package/lib/types/client/rows/WorkspaceBrowser.d.ts.map +1 -1
  76. package/lib/types/client/rows/WorkspaceBrowser.js +21 -21
  77. package/lib/types/client/rows/WorkspaceBrowser.js.map +1 -1
  78. package/lib/types/client/tree.d.ts +2 -5
  79. package/lib/types/client/tree.d.ts.map +1 -1
  80. package/lib/types/client/tree.js +0 -5
  81. package/lib/types/client/tree.js.map +1 -1
  82. package/lib/types/index.d.ts +31 -1
  83. package/lib/types/index.d.ts.map +1 -1
  84. package/lib/types/index.js +13 -1
  85. package/lib/types/index.js.map +1 -1
  86. package/package.json +1 -5
@@ -0,0 +1,14 @@
1
+ import { type FacetRegistry, type Unregister } from '../facets.ts';
2
+ import type { LegacyFacetSources } from './store-source.ts';
3
+ /**
4
+ * 登记本插件目前**代管**的状态源。
5
+ *
6
+ * 两个 facet 都显式声明 `origin: 'legacy'`,所以状态所有者一旦自己注册同名 facet,
7
+ * 适配器就让位({@link FACET_ORIGIN_RANK}),不会重复计数。
8
+ *
9
+ * @returns 一次性注销函数(挂到 `ctx.effect` 的清理上)。
10
+ */
11
+ export declare function registerLegacyFacets(sources: LegacyFacetSources, target?: FacetRegistry): Unregister;
12
+ /** 本插件目前代管了哪些状态源(诊断与测试用)。 */
13
+ export declare const LEGACY_FACET_IDS: readonly string[];
14
+ //# sourceMappingURL=register-legacy-facets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-legacy-facets.d.ts","sourceRoot":"","sources":["../../../../src/client/legacy/register-legacy-facets.tsx"],"names":[],"mappings":"AAYA,OAAO,EAA2C,KAAK,aAAa,EAAyB,KAAK,UAAU,EAAE,MAAM,cAAc,CAAA;AAGlI,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAkB3D;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,EAAE,MAAM,GAAE,aAA+B,GAAG,UAAU,CAwCrH;AAUD,6BAA6B;AAC7B,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAAiD,CAAA"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * 过渡期:把内置适配器登记进 facet 注册面,并交出它们各自的图标。
3
+ *
4
+ * ⚠️ 本文件与整个 `legacy/` 目录都是**临时代管**:状态所有者(dsh-later、
5
+ * dsh-gitea-dispatch)按 `../facets.ts` 的协议自己注册之后,这里连同两个适配器一起
6
+ * 删除。图标之所以留在这一层而不是放回 `rows/GroupBadge.tsx`:「这个状态长什么样」
7
+ * 是状态所有者的知识,本插件只管把它放进徽标的排格里。
8
+ *
9
+ * @module dsh-group-status/client/legacy/register-legacy-facets
10
+ */
11
+ import { createElement } from 'react';
12
+ import { IconClockOutlineRegular, IconListPenOutlineRegular } from '@deepseek-ai/dsh-client-ui-primitives';
13
+ import { registerGroupStatusFacet } from "../facets.js";
14
+ import { registry as defaultRegistry } from "../facets.js";
15
+ import { createScheduleFacet, SCHEDULE_FACET_ID } from "./schedule.js";
16
+ import { createWaitingReviewFacet, WAITING_REVIEW_FACET_ID, } from "./waiting-review.js";
17
+ /** 语义色档 → 宿主色令牌(与改造前的取色逐档一致)。 */
18
+ const TONE_COLOR = {
19
+ info: '#8b5cf6',
20
+ warn: 'var(--dsw-alias-state-warn-secondary)',
21
+ error: 'var(--dsw-alias-state-error-primary)',
22
+ };
23
+ /** 带色的一小段 inline-flex,尺寸与其余徽标图标一致。 */
24
+ function glyph(color, icon) {
25
+ return createElement('span', { style: { color, display: 'inline-flex', alignItems: 'center' } }, icon);
26
+ }
27
+ /**
28
+ * 登记本插件目前**代管**的状态源。
29
+ *
30
+ * 两个 facet 都显式声明 `origin: 'legacy'`,所以状态所有者一旦自己注册同名 facet,
31
+ * 适配器就让位({@link FACET_ORIGIN_RANK}),不会重复计数。
32
+ *
33
+ * @returns 一次性注销函数(挂到 `ctx.effect` 的清理上)。
34
+ */
35
+ export function registerLegacyFacets(sources, target = defaultRegistry) {
36
+ const disposers = [];
37
+ if (sources.schedule !== undefined) {
38
+ const facet = {
39
+ ...createScheduleFacet(sources.schedule),
40
+ // 紫色与 dsh-later 自己的定时徽标同源(浅深底对比均 >=3:1);
41
+ // urgent / overdue 走宿主 warn / error 语义令牌。
42
+ renderIcon: (fold) => glyph(fold.tone === 'error' ? TONE_COLOR.error : fold.tone === 'warn' ? TONE_COLOR.warn : TONE_COLOR.info, createElement(IconClockOutlineRegular, { size: 14 })),
43
+ };
44
+ disposers.push(target === defaultRegistry
45
+ ? registerGroupStatusFacet(facet)
46
+ : registerInto(target, facet));
47
+ }
48
+ if (sources.waiting !== undefined) {
49
+ const facet = {
50
+ ...createWaitingReviewFacet(sources.waiting),
51
+ // #23:这枚「列表笔」是**过时刻意保留的兜底形状,不是当前形状**。dsh-gitea-dispatch
52
+ // 自其 #56/#60 起交出自绘的沙漏(跟随 waitingIconStyle 四档),本文件按
53
+ // FACET_ORIGIN_RANK 让位给它(provider 恒胜 legacy)。只有 provider 缺席
54
+ //(未安装 / 版本早于 #47)或登记失败时才会现形——那些路径下形状与行内不一致是
55
+ // **有意接受的**,好过「等待评审彻底不进徽标」。别把它当成 bug 改回沙漏。
56
+ // 与定时任务仍用不同图标:两者同属"在等"的语义,只靠颜色区分对色盲用户不可用。
57
+ renderIcon: (fold) => glyph(fold.tone === 'error' ? TONE_COLOR.error : TONE_COLOR.warn, createElement(IconListPenOutlineRegular, { size: 14 })),
58
+ };
59
+ disposers.push(target === defaultRegistry
60
+ ? registerGroupStatusFacet(facet)
61
+ : registerInto(target, facet));
62
+ }
63
+ return () => {
64
+ for (const dispose of disposers)
65
+ dispose();
66
+ };
67
+ }
68
+ /** 对给定登记面注册一个 facet(与单例路径同一套校验/拒绝语义)。 */
69
+ function registerInto(target, facet) {
70
+ const result = target.register(facet);
71
+ return result.ok ? () => {
72
+ target.remove(result.id, facet);
73
+ } : () => undefined;
74
+ }
75
+ /** 本插件目前代管了哪些状态源(诊断与测试用)。 */
76
+ export const LEGACY_FACET_IDS = [SCHEDULE_FACET_ID, WAITING_REVIEW_FACET_ID];
77
+ //# sourceMappingURL=register-legacy-facets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-legacy-facets.js","sourceRoot":"","sources":["../../../../src/client/legacy/register-legacy-facets.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * 过渡期适配器:dsh-later 的「定时任务」→ facet。
3
+ *
4
+ * ⚠️ 与 `waiting-review.ts` 同属临时层,dsh-later 自己注册之后连同图标映射一并删除。
5
+ * 见其 issue #17(摘要 API)与本次的升级请求。
6
+ *
7
+ * @module dsh-group-status/client/legacy/schedule
8
+ */
9
+ import type { FacetFold, FacetRenderContext, GroupStatusFacet } from '../facets.ts';
10
+ /** facet id:与 dsh-later 自己注册时应当使用的 id 保持一致。 */
11
+ export declare const SCHEDULE_FACET_ID = "dsh-later.schedule";
12
+ /** 一条定时任务事实,来自 dsh-later 的 `useScheduleSummary()`。 */
13
+ export interface ScheduleSummaryEntry {
14
+ readonly count: number;
15
+ readonly pausedCount: number;
16
+ readonly nextAt?: number;
17
+ readonly state: 'scheduled' | 'urgent' | 'overdue';
18
+ }
19
+ /** 会话 id → 该会话的定时任务事实。 */
20
+ export type ScheduleSummaryMap = ReadonlyMap<string, ScheduleSummaryEntry>;
21
+ /** 定时折果携带的数据:只有本 facet 读。 */
22
+ export interface ScheduleData {
23
+ /** 组内定时任务总条数(含已暂停)。 */
24
+ readonly tasks: number;
25
+ /** 组内最高优先级状态:overdue > urgent > scheduled。 */
26
+ readonly state: 'scheduled' | 'urgent' | 'overdue' | undefined;
27
+ }
28
+ /**
29
+ * 把一组的会话 id 折成定时任务事实。
30
+ *
31
+ * `count` 用**有条目的会话数**(与徽标"还需要看几件事"的口径一致),任务总数留在
32
+ * `data.tasks` 里供文案/明细使用。
33
+ */
34
+ export declare function foldSchedule(snapshot: ScheduleSummaryMap | undefined, sessionIds: readonly string[]): FacetFold<ScheduleData>;
35
+ /** 跨层合并:会话数与任务数相加,状态取更紧急的一档。 */
36
+ export declare function mergeScheduleFold(a: FacetFold<ScheduleData>, b: FacetFold<ScheduleData>): FacetFold<ScheduleData>;
37
+ /** 「N 定时任务」:措辞沿用本插件的行级文案键。 */
38
+ export declare function scheduleLabel(fold: FacetFold<ScheduleData>, context: FacetRenderContext): string;
39
+ /**
40
+ * 构造内置的定时任务 facet。
41
+ *
42
+ * @param input.getSnapshot - 读 dsh-later 的摘要 Map。
43
+ * @param input.subscribe - 订阅其变化。
44
+ */
45
+ export declare function createScheduleFacet(input: {
46
+ subscribe: (listener: () => void) => () => void;
47
+ getSnapshot: () => ScheduleSummaryMap | undefined;
48
+ }): GroupStatusFacet<ScheduleSummaryMap | undefined, ScheduleData>;
49
+ //# sourceMappingURL=schedule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../../../src/client/legacy/schedule.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAGnF,+CAA+C;AAC/C,eAAO,MAAM,iBAAiB,uBAAuB,CAAA;AAErD,sDAAsD;AACtD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAA;CACnD;AAED,0BAA0B;AAC1B,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;AAE1E,6BAA6B;AAC7B,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAA;CAC/D;AAOD;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,kBAAkB,GAAG,SAAS,EACxC,UAAU,EAAE,SAAS,MAAM,EAAE,GAC5B,SAAS,CAAC,YAAY,CAAC,CAoBzB;AAED,gCAAgC;AAChC,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC,YAAY,CAAC,CAUjH;AAED,8BAA8B;AAC9B,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAEhG;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE;IACzC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;IAC/C,WAAW,EAAE,MAAM,kBAAkB,GAAG,SAAS,CAAA;CAClD,GAAG,gBAAgB,CAAC,kBAAkB,GAAG,SAAS,EAAE,YAAY,CAAC,CAajE"}
@@ -0,0 +1,73 @@
1
+ import { GROUP_STATUS_FACET_PROTOCOL_VERSION } from "../facets.js";
2
+ /** facet id:与 dsh-later 自己注册时应当使用的 id 保持一致。 */
3
+ export const SCHEDULE_FACET_ID = 'dsh-later.schedule';
4
+ /** 状态优先级(越大越紧急),与 dsh-later 的行内口径一致。 */
5
+ const SCHEDULE_RANK = {
6
+ scheduled: 1, urgent: 2, overdue: 3,
7
+ };
8
+ /**
9
+ * 把一组的会话 id 折成定时任务事实。
10
+ *
11
+ * `count` 用**有条目的会话数**(与徽标"还需要看几件事"的口径一致),任务总数留在
12
+ * `data.tasks` 里供文案/明细使用。
13
+ */
14
+ export function foldSchedule(snapshot, sessionIds) {
15
+ let sessions = 0;
16
+ let tasks = 0;
17
+ let state;
18
+ if (snapshot !== undefined) {
19
+ for (const id of sessionIds) {
20
+ const entry = snapshot.get(id);
21
+ if (entry === undefined)
22
+ continue;
23
+ sessions += 1;
24
+ tasks += entry.count;
25
+ if (state === undefined || SCHEDULE_RANK[entry.state] > SCHEDULE_RANK[state])
26
+ state = entry.state;
27
+ }
28
+ }
29
+ return {
30
+ count: sessions,
31
+ tone: state === 'overdue' ? 'error' : state === 'urgent' ? 'warn' : 'info',
32
+ // 提醒已过点 / 五分钟内到点 = 真的在催用户,这是脉冲的唯一合法用途。
33
+ pulse: state === 'overdue' || state === 'urgent',
34
+ data: { tasks, state },
35
+ };
36
+ }
37
+ /** 跨层合并:会话数与任务数相加,状态取更紧急的一档。 */
38
+ export function mergeScheduleFold(a, b) {
39
+ const rankA = a.data?.state === undefined ? 0 : SCHEDULE_RANK[a.data.state];
40
+ const rankB = b.data?.state === undefined ? 0 : SCHEDULE_RANK[b.data.state];
41
+ const state = rankB > rankA ? b.data?.state : a.data?.state;
42
+ return {
43
+ count: a.count + b.count,
44
+ tone: state === 'overdue' ? 'error' : state === 'urgent' ? 'warn' : 'info',
45
+ pulse: a.pulse || b.pulse,
46
+ data: { tasks: (a.data?.tasks ?? 0) + (b.data?.tasks ?? 0), state },
47
+ };
48
+ }
49
+ /** 「N 定时任务」:措辞沿用本插件的行级文案键。 */
50
+ export function scheduleLabel(fold, context) {
51
+ return `${fold.count} ${context.t('status.scheduled')}`;
52
+ }
53
+ /**
54
+ * 构造内置的定时任务 facet。
55
+ *
56
+ * @param input.getSnapshot - 读 dsh-later 的摘要 Map。
57
+ * @param input.subscribe - 订阅其变化。
58
+ */
59
+ export function createScheduleFacet(input) {
60
+ return {
61
+ protocol: GROUP_STATUS_FACET_PROTOCOL_VERSION,
62
+ id: SCHEDULE_FACET_ID,
63
+ origin: 'legacy',
64
+ settingKey: 'showScheduledInBadge',
65
+ order: 10,
66
+ subscribe: input.subscribe,
67
+ getSnapshot: input.getSnapshot,
68
+ fold: (snapshot, sessionIds) => foldSchedule(snapshot, sessionIds),
69
+ merge: mergeScheduleFold,
70
+ label: scheduleLabel,
71
+ };
72
+ }
73
+ //# sourceMappingURL=schedule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../../../src/client/legacy/schedule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * 过渡期桥接层里**与图标无关**的那一半。
3
+ *
4
+ * 单独成文只为一件事:可测。`register-legacy-facets.tsx` 引宿主图标集,它的 `require`
5
+ * 图在本仓库里解析不了(`vitest.config.ts` 排除理由 (b))。"store 迟到怎么办"和"设置
6
+ * 关掉哪个来源"都是真会咬人的逻辑,跟图标写在一起就永远进不了测试。
7
+ *
8
+ * @module dsh-group-status/client/legacy/store-source
9
+ */
10
+ import { type ResolvedBadgeSettings } from '../badge-settings.ts';
11
+ import type { RegisteredFacet } from '../facets.ts';
12
+ import type { ScheduleSummaryMap } from './schedule.ts';
13
+ import type { WaitingReviewSummarizer, WaitingReviewSummaryMap } from './waiting-review.ts';
14
+ /**
15
+ * 把「store 可能迟到」的两层订阅合成一个稳定订阅面。
16
+ *
17
+ * @param getStore - 读当前生效的 store(未登记时 undefined)。
18
+ * @param subscribeRegistry - 订阅 store 登记变化(提供方 apply 晚于本插件渲染时用它自愈)。
19
+ */
20
+ export declare function bridgeLateStoreSource<Snapshot>(getStore: (() => {
21
+ getSnapshot: () => Snapshot | undefined;
22
+ subscribe: (listener: () => void) => () => void;
23
+ } | undefined) | undefined, subscribeRegistry: ((listener: () => void) => () => void) | undefined): {
24
+ subscribe: (listener: () => void) => () => void;
25
+ getSnapshot: () => Snapshot | undefined;
26
+ } | undefined;
27
+ /**
28
+ * 安装两个过渡适配器。
29
+ *
30
+ * @returns 一次性注销函数(挂到 `ctx.effect` 的清理上)。
31
+
32
+ /**
33
+ * 按设置筛掉被关掉的来源。
34
+ *
35
+ * 过滤放在**折叠之前**而不是渲染阶段:数字、图标、`aria-label`、悬停明细与"要不要画
36
+ * 徽标"因此天然同源,不会出现在 label 里有、计数里没有的情况。
37
+ */
38
+ export declare function visibleFacets(entries: readonly RegisteredFacet[], settings: ResolvedBadgeSettings): RegisteredFacet[];
39
+ /** 提供方 store 的最小面(两家同形:宿主 `useSyncExternalStore` 的外部存储)。 */
40
+ export interface ProviderStore<Snapshot> {
41
+ getSnapshot: () => Snapshot | undefined;
42
+ subscribe: (listener: () => void) => () => void;
43
+ }
44
+ /** 两家 provider 的 client 导出面里,桥接层真正用到的部分。 */
45
+ export interface LegacyProviderClients {
46
+ /** 缺席(未安装 / 未启用)就整个省略这个键。 */
47
+ later?: {
48
+ getScheduleSummaryStore?: () => ProviderStore<ScheduleSummaryMap> | undefined;
49
+ subscribeScheduleSummaryStore?: (listener: () => void) => () => void;
50
+ };
51
+ /** 同上。 */
52
+ dispatch?: {
53
+ getWaitingSummaryStore?: () => ProviderStore<WaitingReviewSummaryMap> | undefined;
54
+ subscribeWaitingSummaryStore?: (listener: () => void) => () => void;
55
+ summarizeWaitingGroup?: WaitingReviewSummarizer;
56
+ };
57
+ }
58
+ /** 交给图标层的装配入参(见 `register-legacy-facets.tsx`)。 */
59
+ export interface LegacyFacetSources {
60
+ schedule: {
61
+ subscribe: (listener: () => void) => () => void;
62
+ getSnapshot: () => ScheduleSummaryMap | undefined;
63
+ } | undefined;
64
+ waiting: {
65
+ subscribe: (listener: () => void) => () => void;
66
+ getSnapshot: () => WaitingReviewSummaryMap | undefined;
67
+ summarize?: WaitingReviewSummarizer;
68
+ } | undefined;
69
+ }
70
+ /**
71
+ * 从两家 provider 的 client 面拼出登记入参。
72
+ *
73
+ * 这一层刻意不碰图标、不 `require`:它是桥接里唯一"会拼错"的部分(store 迟到、
74
+ * 谁缺席、委托哪个聚合函数),能被测试覆盖才有意义。`require` 与图标各自留在只有一行
75
+ * 调用的 `bridge.ts` 与 `register-legacy-facets.tsx` 里。
76
+ */
77
+ export declare function assembleLegacySources(clients: LegacyProviderClients): LegacyFacetSources;
78
+ //# sourceMappingURL=store-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-source.d.ts","sourceRoot":"","sources":["../../../../src/client/legacy/store-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAA0B,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AACzF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAA;AAE3F;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAC5C,QAAQ,EAAE,CAAC,MAAM;IAAE,WAAW,EAAE,MAAM,QAAQ,GAAG,SAAS,CAAC;IAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;CAAE,GAAG,SAAS,CAAC,GAAG,SAAS,EACtI,iBAAiB,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC,GAAG,SAAS,GACpE;IAAE,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,QAAQ,GAAG,SAAS,CAAA;CAAE,GAAG,SAAS,CA4B1G;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,QAAQ,EAAE,qBAAqB,GAC9B,eAAe,EAAE,CAEnB;AAED,4DAA4D;AAC5D,MAAM,WAAW,aAAa,CAAC,QAAQ;IACrC,WAAW,EAAE,MAAM,QAAQ,GAAG,SAAS,CAAA;IACvC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;CAChD;AAED,4CAA4C;AAC5C,MAAM,WAAW,qBAAqB;IACpC,6BAA6B;IAC7B,KAAK,CAAC,EAAE;QACN,uBAAuB,CAAC,EAAE,MAAM,aAAa,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAAA;QAC7E,6BAA6B,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;KACrE,CAAA;IACD,UAAU;IACV,QAAQ,CAAC,EAAE;QACT,sBAAsB,CAAC,EAAE,MAAM,aAAa,CAAC,uBAAuB,CAAC,GAAG,SAAS,CAAA;QACjF,4BAA4B,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;QACnE,qBAAqB,CAAC,EAAE,uBAAuB,CAAA;KAChD,CAAA;CACF;AAED,kDAAkD;AAClD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE;QACR,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;QAC/C,WAAW,EAAE,MAAM,kBAAkB,GAAG,SAAS,CAAA;KAClD,GAAG,SAAS,CAAA;IACb,OAAO,EAAE;QACP,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;QAC/C,WAAW,EAAE,MAAM,uBAAuB,GAAG,SAAS,CAAA;QACtD,SAAS,CAAC,EAAE,uBAAuB,CAAA;KACpC,GAAG,SAAS,CAAA;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,GAAG,kBAAkB,CAgBxF"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * 过渡期桥接层里**与图标无关**的那一半。
3
+ *
4
+ * 单独成文只为一件事:可测。`register-legacy-facets.tsx` 引宿主图标集,它的 `require`
5
+ * 图在本仓库里解析不了(`vitest.config.ts` 排除理由 (b))。"store 迟到怎么办"和"设置
6
+ * 关掉哪个来源"都是真会咬人的逻辑,跟图标写在一起就永远进不了测试。
7
+ *
8
+ * @module dsh-group-status/client/legacy/store-source
9
+ */
10
+ import { facetVisibleBySettings } from "../badge-settings.js";
11
+ /**
12
+ * 把「store 可能迟到」的两层订阅合成一个稳定订阅面。
13
+ *
14
+ * @param getStore - 读当前生效的 store(未登记时 undefined)。
15
+ * @param subscribeRegistry - 订阅 store 登记变化(提供方 apply 晚于本插件渲染时用它自愈)。
16
+ */
17
+ export function bridgeLateStoreSource(getStore, subscribeRegistry) {
18
+ if (getStore === undefined)
19
+ return undefined;
20
+ return {
21
+ getSnapshot: () => getStore()?.getSnapshot(),
22
+ subscribe: (listener) => {
23
+ // store 每迟到/替换一次就要重挂它的订阅;登记表变化本身也算一次变化。
24
+ let storeUnsubscribe;
25
+ let current;
26
+ const rewire = () => {
27
+ const next = getStore();
28
+ if (next === current)
29
+ return;
30
+ storeUnsubscribe?.();
31
+ current = next;
32
+ storeUnsubscribe = next?.subscribe(listener);
33
+ };
34
+ rewire();
35
+ const unsubscribeRegistry = subscribeRegistry?.(() => {
36
+ rewire();
37
+ listener();
38
+ });
39
+ return () => {
40
+ unsubscribeRegistry?.();
41
+ storeUnsubscribe?.();
42
+ storeUnsubscribe = undefined;
43
+ current = undefined;
44
+ };
45
+ },
46
+ };
47
+ }
48
+ /**
49
+ * 安装两个过渡适配器。
50
+ *
51
+ * @returns 一次性注销函数(挂到 `ctx.effect` 的清理上)。
52
+
53
+ /**
54
+ * 按设置筛掉被关掉的来源。
55
+ *
56
+ * 过滤放在**折叠之前**而不是渲染阶段:数字、图标、`aria-label`、悬停明细与"要不要画
57
+ * 徽标"因此天然同源,不会出现在 label 里有、计数里没有的情况。
58
+ */
59
+ export function visibleFacets(entries, settings) {
60
+ return entries.filter(entry => facetVisibleBySettings(settings, entry.facet.settingKey));
61
+ }
62
+ /**
63
+ * 从两家 provider 的 client 面拼出登记入参。
64
+ *
65
+ * 这一层刻意不碰图标、不 `require`:它是桥接里唯一"会拼错"的部分(store 迟到、
66
+ * 谁缺席、委托哪个聚合函数),能被测试覆盖才有意义。`require` 与图标各自留在只有一行
67
+ * 调用的 `bridge.ts` 与 `register-legacy-facets.tsx` 里。
68
+ */
69
+ export function assembleLegacySources(clients) {
70
+ const schedule = bridgeLateStoreSource(clients.later?.getScheduleSummaryStore, clients.later?.subscribeScheduleSummaryStore);
71
+ const waiting = bridgeLateStoreSource(clients.dispatch?.getWaitingSummaryStore, clients.dispatch?.subscribeWaitingSummaryStore);
72
+ const summarize = clients.dispatch?.summarizeWaitingGroup;
73
+ return {
74
+ schedule: schedule === undefined ? undefined : { subscribe: schedule.subscribe, getSnapshot: schedule.getSnapshot },
75
+ waiting: waiting === undefined ? undefined : {
76
+ subscribe: waiting.subscribe,
77
+ getSnapshot: waiting.getSnapshot,
78
+ ...(summarize === undefined ? {} : { summarize }),
79
+ },
80
+ };
81
+ }
82
+ //# sourceMappingURL=store-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-source.js","sourceRoot":"","sources":["../../../../src/client/legacy/store-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,sBAAsB,EAA8B,MAAM,sBAAsB,CAAA;AAKzF;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAsI,EACtI,iBAAqE;IAErE,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC5C,OAAO;QACL,WAAW,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE;QAC5C,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE;YACtB,wCAAwC;YACxC,IAAI,gBAA0C,CAAA;YAC9C,IAAI,OAAoC,CAAA;YACxC,MAAM,MAAM,GAAG,GAAS,EAAE;gBACxB,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAA;gBACvB,IAAI,IAAI,KAAK,OAAO;oBAAE,OAAM;gBAC5B,gBAAgB,EAAE,EAAE,CAAA;gBACpB,OAAO,GAAG,IAAI,CAAA;gBACd,gBAAgB,GAAG,IAAI,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAA;YAC9C,CAAC,CAAA;YACD,MAAM,EAAE,CAAA;YACR,MAAM,mBAAmB,GAAG,iBAAiB,EAAE,CAAC,GAAG,EAAE;gBACnD,MAAM,EAAE,CAAA;gBACR,QAAQ,EAAE,CAAA;YACZ,CAAC,CAAC,CAAA;YACF,OAAO,GAAG,EAAE;gBACV,mBAAmB,EAAE,EAAE,CAAA;gBACvB,gBAAgB,EAAE,EAAE,CAAA;gBACpB,gBAAgB,GAAG,SAAS,CAAA;gBAC5B,OAAO,GAAG,SAAS,CAAA;YACrB,CAAC,CAAA;QACH,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAmC,EACnC,QAA+B;IAE/B,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAA;AAC1F,CAAC;AAoCD;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAA8B;IAClE,MAAM,QAAQ,GAAG,qBAAqB,CACpC,OAAO,CAAC,KAAK,EAAE,uBAAuB,EAAE,OAAO,CAAC,KAAK,EAAE,6BAA6B,CACrF,CAAA;IACD,MAAM,OAAO,GAAG,qBAAqB,CACnC,OAAO,CAAC,QAAQ,EAAE,sBAAsB,EAAE,OAAO,CAAC,QAAQ,EAAE,4BAA4B,CACzF,CAAA;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,qBAAqB,CAAA;IACzD,OAAO;QACL,QAAQ,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE;QACnH,OAAO,EAAE,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;YAC3C,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;SAClD;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,85 @@
1
+ import type { FacetFold, FacetRenderContext, GroupStatusFacet } from '../facets.ts';
2
+ /** facet id:与 dsh-gitea-dispatch 自己注册时应当使用的 id 保持一致。 */
3
+ export declare const WAITING_REVIEW_FACET_ID = "dsh-gitea-dispatch.waiting-review";
4
+ /**
5
+ * 一条等待评审事实,来自 dsh-gitea-dispatch 的 `useWaitingSummary()`
6
+ * (issue: dsh-gitea-dispatch#16)。
7
+ *
8
+ * 可选字段是提供方契约的一部分:正是它们让徽标能说「在等哪个 PR」「还剩多久」。
9
+ * 本类型此前只声明 `{ prNumber, state }`,于是提供方已经取回的信息被静默丢掉。
10
+ */
11
+ export interface WaitingReviewSummaryEntry {
12
+ readonly prNumber: number;
13
+ readonly state: 'waiting' | 'overdue';
14
+ /** 等待起点(宿主 state 里是 epoch ms,过 wire 可能是 ISO 字符串)。 */
15
+ readonly startedAt?: number | string;
16
+ /** CI 声明的等待上限(秒);缺省 = 时长未知。 */
17
+ readonly waitMaxSec?: number;
18
+ /** CI 声明的绝对截止(epoch ms);优先于 `startedAt + waitMaxSec`。 */
19
+ readonly deadline?: number;
20
+ }
21
+ /** 会话 id → 该会话的等待事实(没有条目 = 没在等)。 */
22
+ export type WaitingReviewSummaryMap = ReadonlyMap<string, WaitingReviewSummaryEntry>;
23
+ /** 提供方 `summarizeWaitingGroup()` 的折果形状。 */
24
+ export interface WaitingReviewFold {
25
+ /** 组内**在等**的会话数。 */
26
+ sessions: number;
27
+ /** 组内在等的 PR 号(按传入会话顺序)。 */
28
+ prNumbers: readonly number[];
29
+ /** 组内最高优先级状态:overdue > waiting。 */
30
+ state: 'waiting' | 'overdue' | undefined;
31
+ /** 组内**尚未到点**的最早截止(epoch ms);无则缺省。 */
32
+ nextDeadline?: number;
33
+ }
34
+ /** 提供方的分组聚合函数面。 */
35
+ export type WaitingReviewSummarizer = (summary: WaitingReviewSummaryMap, sessionIds: readonly string[], now: number) => WaitingReviewFold;
36
+ /** 等待折果携带的数据:徽标从不解释它,只有本 facet 读。 */
37
+ export interface WaitingReviewData {
38
+ readonly prNumbers: readonly number[];
39
+ readonly state: 'waiting' | 'overdue' | undefined;
40
+ readonly nextDeadline?: number;
41
+ }
42
+ /**
43
+ * 一条等待的绝对截止(epoch ms);`undefined` = 时长未知。
44
+ *
45
+ * 刻意与提供方的 `deadlineOf` 同口径(绝对 deadline 优先,才退 `startedAt + waitMaxSec`):
46
+ * CI 的等待从"进入循环"起算,而广播在此之前已发出,只按时长算会让徽标的倒计时晚于
47
+ * 真实截止(其 Issues #2577)。`startedAt` 的两种形态同理都要认。
48
+ */
49
+ export declare function waitingDeadlineOf(entry: WaitingReviewSummaryEntry): number | undefined;
50
+ /**
51
+ * 提供方聚合面缺席时的等价折叠。
52
+ *
53
+ * 与提供方的 `summarizeWaitingGroup()` 同一套判据:四形态 id 兜底(复用
54
+ * `cross-plugin-summary.ts` 的 `entryFor`,规则与它的 `waitingEntryFor` 相同)、
55
+ * `overdue > waiting` 排序、只把**未到期**的截止算作 `nextDeadline`。
56
+ */
57
+ export declare function summarizeWaitingGroupLocally(summary: WaitingReviewSummaryMap, sessionIds: readonly string[], now: number): WaitingReviewFold;
58
+ /**
59
+ * 同 facet 跨层合并:PR 号取并集去重升序、色档取更紧急的一档、
60
+ * 倒计时取两侧更早的那个未到期截止。
61
+ */
62
+ export declare function mergeWaitingReviewFold(a: FacetFold<WaitingReviewData>, b: FacetFold<WaitingReviewData>): FacetFold<WaitingReviewData>;
63
+ /** `#15, #2783(+2)`:去重升序、封顶三个。 */
64
+ export declare function prNumberList(prNumbers: readonly number[] | undefined): string;
65
+ /**
66
+ * 等待评审那一句文案:状态 + 剩余时长(分钟粒度)+ PR 号。
67
+ *
68
+ * 措辞与提供方自己的行内呈现同档(`等待评审 3:28` / `评审等待已超时` / `等待评审结果`),
69
+ * 但只到分钟:徽标只在提供方 store 通知时重渲染,秒级读数会停在旧值上撒谎。
70
+ */
71
+ export declare function waitingReviewLabel(fold: FacetFold<WaitingReviewData>, context: FacetRenderContext): string;
72
+ /**
73
+ * 构造本插件内置的等待评审 facet。
74
+ *
75
+ * @param input - 提供方的摘要读取面;`summarize` 缺席时退回本地等价折叠。
76
+ * @param input.subscribe - 订阅快照变化(提供方 store 的订阅面)。
77
+ * @param input.getSnapshot - 读当前摘要 Map。
78
+ * @param input.summarize - 提供方的分组聚合(有则委托)。
79
+ */
80
+ export declare function createWaitingReviewFacet(input: {
81
+ subscribe: (listener: () => void) => () => void;
82
+ getSnapshot: () => WaitingReviewSummaryMap | undefined;
83
+ summarize?: WaitingReviewSummarizer;
84
+ }): GroupStatusFacet<WaitingReviewSummaryMap | undefined, WaitingReviewData>;
85
+ //# sourceMappingURL=waiting-review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"waiting-review.d.ts","sourceRoot":"","sources":["../../../../src/client/legacy/waiting-review.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAa,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAG9F,wDAAwD;AACxD,eAAO,MAAM,uBAAuB,sCAAsC,CAAA;AAI1E;;;;;;GAMG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAAA;IACrC,qDAAqD;IACrD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACpC,+BAA+B;IAC/B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,oCAAoC;AACpC,MAAM,MAAM,uBAAuB,GAAG,WAAW,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAA;AAEpF,2CAA2C;AAC3C,MAAM,WAAW,iBAAiB;IAChC,oBAAoB;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,2BAA2B;IAC3B,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IAC5B,mCAAmC;IACnC,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAA;IACxC,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,mBAAmB;AACnB,MAAM,MAAM,uBAAuB,GAAG,CACpC,OAAO,EAAE,uBAAuB,EAChC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,GAAG,EAAE,MAAM,KACR,iBAAiB,CAAA;AAEtB,qCAAqC;AACrC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IACrC,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,CAAA;IACjD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,yBAAyB,GAAG,MAAM,GAAG,SAAS,CAgBtF;AAED;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,uBAAuB,EAChC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,GAAG,EAAE,MAAM,GACV,iBAAiB,CAoBnB;AAqBD;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,SAAS,CAAC,iBAAiB,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,iBAAiB,CAAC,GAAG,SAAS,CAAC,iBAAiB,CAAC,CAkBrI;AAED,kCAAkC;AAClC,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,CAM7E;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,SAAS,CAAC,iBAAiB,CAAC,EAAE,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAc1G;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC9C,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;IAC/C,WAAW,EAAE,MAAM,uBAAuB,GAAG,SAAS,CAAA;IACtD,SAAS,CAAC,EAAE,uBAAuB,CAAA;CACpC,GAAG,gBAAgB,CAAC,uBAAuB,GAAG,SAAS,EAAE,iBAAiB,CAAC,CAkB3E"}