dsh-group-status 0.2.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +65 -0
- package/README.en.md +42 -24
- package/README.md +45 -25
- package/lib/client.js +1781 -483
- package/lib/client.js.map +1 -1
- package/lib/index.js +22 -9
- package/lib/types/client/BadgeSettingsCard.d.ts +24 -0
- package/lib/types/client/BadgeSettingsCard.d.ts.map +1 -0
- package/lib/types/client/BadgeSettingsCard.js +73 -0
- package/lib/types/client/BadgeSettingsCard.js.map +1 -0
- package/lib/types/client/badge-field.d.ts +44 -0
- package/lib/types/client/badge-field.d.ts.map +1 -0
- package/lib/types/client/badge-field.js +77 -0
- package/lib/types/client/badge-field.js.map +1 -0
- package/lib/types/client/badge-labels.d.ts +92 -0
- package/lib/types/client/badge-labels.d.ts.map +1 -0
- package/lib/types/client/badge-labels.js +150 -0
- package/lib/types/client/badge-labels.js.map +1 -0
- package/lib/types/client/badge-settings.d.ts +31 -3
- package/lib/types/client/badge-settings.d.ts.map +1 -1
- package/lib/types/client/badge-settings.js +50 -6
- package/lib/types/client/badge-settings.js.map +1 -1
- package/lib/types/client/contract/slots.d.ts +39 -21
- package/lib/types/client/contract/slots.d.ts.map +1 -1
- package/lib/types/client/contract/slots.js.map +1 -1
- package/lib/types/client/contract/toast.d.ts +67 -0
- package/lib/types/client/contract/toast.d.ts.map +1 -0
- package/lib/types/client/contract/toast.js +2 -0
- package/lib/types/client/contract/toast.js.map +1 -0
- package/lib/types/client/facet-store.d.ts +46 -0
- package/lib/types/client/facet-store.d.ts.map +1 -0
- package/lib/types/client/facet-store.js +123 -0
- package/lib/types/client/facet-store.js.map +1 -0
- package/lib/types/client/facet-visibility.d.ts +17 -0
- package/lib/types/client/facet-visibility.d.ts.map +1 -0
- package/lib/types/client/facet-visibility.js +18 -0
- package/lib/types/client/facet-visibility.js.map +1 -0
- package/lib/types/client/facets.d.ts +265 -0
- package/lib/types/client/facets.d.ts.map +1 -0
- package/lib/types/client/facets.js +209 -0
- package/lib/types/client/facets.js.map +1 -0
- package/lib/types/client/group-status.d.ts +97 -45
- package/lib/types/client/group-status.d.ts.map +1 -1
- package/lib/types/client/group-status.js +148 -85
- package/lib/types/client/group-status.js.map +1 -1
- package/lib/types/client/index.d.ts +31 -3
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +107 -14
- package/lib/types/client/index.js.map +1 -1
- package/lib/types/client/locales.d.ts +60 -4
- package/lib/types/client/locales.d.ts.map +1 -1
- package/lib/types/client/locales.js +60 -4
- package/lib/types/client/locales.js.map +1 -1
- package/lib/types/client/navigation.d.ts +45 -12
- package/lib/types/client/navigation.d.ts.map +1 -1
- package/lib/types/client/navigation.js +102 -26
- package/lib/types/client/navigation.js.map +1 -1
- package/lib/types/client/rows/GroupBadge.d.ts +19 -25
- package/lib/types/client/rows/GroupBadge.d.ts.map +1 -1
- package/lib/types/client/rows/GroupBadge.js +45 -106
- package/lib/types/client/rows/GroupBadge.js.map +1 -1
- package/lib/types/client/rows/Rows.d.ts +7 -3
- package/lib/types/client/rows/Rows.d.ts.map +1 -1
- package/lib/types/client/rows/Rows.js +9 -9
- package/lib/types/client/rows/Rows.js.map +1 -1
- package/lib/types/client/rows/WorkspaceBrowser.d.ts +1 -1
- package/lib/types/client/rows/WorkspaceBrowser.d.ts.map +1 -1
- package/lib/types/client/rows/WorkspaceBrowser.js +75 -71
- package/lib/types/client/rows/WorkspaceBrowser.js.map +1 -1
- package/lib/types/client/session-actions/ArchiveSession.js +1 -1
- package/lib/types/client/session-actions/ArchiveSession.js.map +1 -1
- package/lib/types/client/session-actions/ForkSession.d.ts +5 -4
- package/lib/types/client/session-actions/ForkSession.d.ts.map +1 -1
- package/lib/types/client/session-actions/ForkSession.js +7 -4
- package/lib/types/client/session-actions/ForkSession.js.map +1 -1
- package/lib/types/client/session-actions/PinSession.js +1 -1
- package/lib/types/client/session-actions/PinSession.js.map +1 -1
- package/lib/types/client/session-actions/RowActionToast.d.ts +5 -8
- package/lib/types/client/session-actions/RowActionToast.d.ts.map +1 -1
- package/lib/types/client/session-actions/RowActionToast.js +10 -49
- package/lib/types/client/session-actions/RowActionToast.js.map +1 -1
- package/lib/types/client/session-actions/SessionId.d.ts +8 -0
- package/lib/types/client/session-actions/SessionId.d.ts.map +1 -0
- package/lib/types/client/session-actions/SessionId.js +16 -0
- package/lib/types/client/session-actions/SessionId.js.map +1 -0
- package/lib/types/client/session-watermarks.d.ts +30 -0
- package/lib/types/client/session-watermarks.d.ts.map +1 -0
- package/lib/types/client/session-watermarks.js +54 -0
- package/lib/types/client/session-watermarks.js.map +1 -0
- package/lib/types/client/shortcuts.d.ts +2 -7
- package/lib/types/client/shortcuts.d.ts.map +1 -1
- package/lib/types/client/shortcuts.js +7 -11
- package/lib/types/client/shortcuts.js.map +1 -1
- package/lib/types/client/toast/Toast.d.ts +41 -0
- package/lib/types/client/toast/Toast.d.ts.map +1 -0
- package/lib/types/client/toast/Toast.js +44 -0
- package/lib/types/client/toast/Toast.js.map +1 -0
- package/lib/types/client/toast/register.d.ts +11 -0
- package/lib/types/client/toast/register.d.ts.map +1 -0
- package/lib/types/client/toast/register.js +162 -0
- package/lib/types/client/toast/register.js.map +1 -0
- package/lib/types/client/tree.d.ts +2 -5
- package/lib/types/client/tree.d.ts.map +1 -1
- package/lib/types/client/tree.js +0 -5
- package/lib/types/client/tree.js.map +1 -1
- package/lib/types/index.d.ts +31 -1
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +13 -1
- package/lib/types/index.js.map +1 -1
- package/package.json +33 -34
|
@@ -5,30 +5,19 @@
|
|
|
5
5
|
* vendored file only needs one import line and one field assignment to wire
|
|
6
6
|
* the badge aggregation in. Everything fork-specific lives here.
|
|
7
7
|
*
|
|
8
|
+
* ## 本模块不认识任何具体状态源
|
|
9
|
+
*
|
|
10
|
+
* 它只统计宿主自己的行级事实(进行中 / 待审批 / 计划待审 / 等待回答 / 已完成 /
|
|
11
|
+
* 子智能体);外部状态一律经 `./facets.ts` 的协议折成 {@link FacetFold}。
|
|
12
|
+
*
|
|
13
|
+
* 这不是洁癖:此前这里为定时任务与等待评审各写了一组具名字段和一套查表,于是提供方
|
|
14
|
+
* 新增字段时本插件的本地类型一无所知,信息**静默丢失**(不报错、测试也不红,见
|
|
15
|
+
* CHANGELOG 0.2.3 第一条)。把语义留在拥有它的那一侧,这类漂移才结构上不可能发生。
|
|
16
|
+
*
|
|
8
17
|
* @module
|
|
9
18
|
*/
|
|
10
|
-
import type {
|
|
11
|
-
|
|
12
|
-
* One session's waiting-review fact, as published by dsh-gitea-dispatch's
|
|
13
|
-
* `useWaitingSummary()` (issue: dsh-gitea-dispatch#16).
|
|
14
|
-
*/
|
|
15
|
-
export interface WaitingReviewSummaryEntry {
|
|
16
|
-
readonly prNumber: number;
|
|
17
|
-
readonly state: 'waiting' | 'overdue';
|
|
18
|
-
}
|
|
19
|
-
/** Session id → that session's waiting-review fact (no entry = not waiting). */
|
|
20
|
-
export type WaitingReviewSummaryMap = ReadonlyMap<string, WaitingReviewSummaryEntry>;
|
|
21
|
-
/**
|
|
22
|
-
* One session's schedule fact, as published by dsh-later's `useScheduleSummary()`.
|
|
23
|
-
*/
|
|
24
|
-
export interface ScheduleSummaryEntry {
|
|
25
|
-
readonly count: number;
|
|
26
|
-
readonly pausedCount: number;
|
|
27
|
-
readonly nextAt?: number;
|
|
28
|
-
readonly state: 'scheduled' | 'urgent' | 'overdue';
|
|
29
|
-
}
|
|
30
|
-
/** Session id → that session's schedule fact (no entry = no scheduled tasks). */
|
|
31
|
-
export type ScheduleSummaryMap = ReadonlyMap<string, ScheduleSummaryEntry>;
|
|
19
|
+
import type { AnyFacet, AnyFacetFold, RegisteredFacet } from './facets.ts';
|
|
20
|
+
import type { GroupNode, SessionNode } from './tree.ts';
|
|
32
21
|
/**
|
|
33
22
|
* Aggregated live-session counts for one group, computed over all members so a
|
|
34
23
|
* folded folder row can hint at hidden activity.
|
|
@@ -46,33 +35,38 @@ export interface GroupLiveStatus {
|
|
|
46
35
|
done: number;
|
|
47
36
|
/** Running direct children across members. */
|
|
48
37
|
subagents: number;
|
|
49
|
-
/**
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
38
|
+
/**
|
|
39
|
+
* 外部状态源的折果,按 facet id 索引,只含**有贡献**的来源(`count > 0`)。
|
|
40
|
+
*
|
|
41
|
+
* 这里刻意没有 `scheduled*` / `waitingReview*` 这类具名字段:徽标一旦为某个来源开
|
|
42
|
+
* 一个字段,就等于把别人家的语义焊进自己的类型,新增来源就得改本插件。
|
|
43
|
+
* `FacetFold.data` 的形状只有该来源自己读。
|
|
44
|
+
*/
|
|
45
|
+
facets: ReadonlyMap<string, FacetEntry>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 一个来源在**这一组**上的折果,连同它自己的 facet。
|
|
49
|
+
*
|
|
50
|
+
* 带上 facet 是为了让渲染(文案、图标、脉冲)与多层合并(`facet.merge`)都不必再回
|
|
51
|
+
* 登记面查表——也就不需要任何模块级状态。
|
|
52
|
+
*/
|
|
53
|
+
export interface FacetEntry {
|
|
54
|
+
facet: AnyFacet;
|
|
55
|
+
fold: AnyFacetFold;
|
|
59
56
|
}
|
|
60
57
|
/**
|
|
61
58
|
* Zero-valued sentinel for {@link GroupLiveStatus}.
|
|
62
59
|
*
|
|
63
|
-
* Used when a group
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* React selectors never trigger spurious re-renders on it.
|
|
60
|
+
* Used when a group has nothing to report. Kept as a frozen constant so the
|
|
61
|
+
* reference is stable across renders — `Object.is` comparisons in React selectors
|
|
62
|
+
* never trigger spurious re-renders on it.
|
|
67
63
|
*/
|
|
68
64
|
export declare const EMPTY_LIVE_STATUS: GroupLiveStatus;
|
|
69
65
|
/**
|
|
70
|
-
*
|
|
71
|
-
* highest-priority state (overdue > urgent > scheduled for schedule; overdue > waiting
|
|
72
|
-
* for waiting-review).
|
|
66
|
+
* 合并两份分组折果:本插件自己的计数相加,外部状态来源**按 facet 各自合并**。
|
|
73
67
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
68
|
+
* 用于多层聚合:折叠的父文件夹要覆盖整棵子树,而子树里每一层都已各自折过一遍。
|
|
69
|
+
* `FacetFold.data` 怎么合归该 facet 自己决定,本模块从不解释。
|
|
76
70
|
*/
|
|
77
71
|
export declare function mergeLiveStatus(a: GroupLiveStatus, b: GroupLiveStatus): GroupLiveStatus;
|
|
78
72
|
/**
|
|
@@ -80,10 +74,68 @@ export declare function mergeLiveStatus(a: GroupLiveStatus, b: GroupLiveStatus):
|
|
|
80
74
|
* hidden live sessions. Mirrors the session-row status priority (pending
|
|
81
75
|
* outranks running outranks completed) at the counting level; labels resolve with
|
|
82
76
|
* locale at render time.
|
|
77
|
+
*
|
|
83
78
|
* @param nodes - member rows of the group.
|
|
84
|
-
* @param sessionIds - the same members' Session ids (
|
|
85
|
-
* @param
|
|
86
|
-
* @param
|
|
79
|
+
* @param sessionIds - the same members' Session ids (facets address their own data by id).
|
|
80
|
+
* @param facets - the registered status sources to fold over this group.
|
|
81
|
+
* @param now - one clock reading for the whole pass, so sibling facets cannot disagree
|
|
82
|
+
* about which deadlines are still ahead.
|
|
83
|
+
*/
|
|
84
|
+
export declare function summarizeGroupStatus(nodes: readonly SessionNode[], sessionIds: readonly string[], facets?: readonly RegisteredFacet[], now?: number): GroupLiveStatus;
|
|
85
|
+
/**
|
|
86
|
+
* Measure each group's own members, as the input to {@link aggregateGroupStatuses}.
|
|
87
|
+
*
|
|
88
|
+
* Every group is measured, expanded ones included. A folder row shows no badge while
|
|
89
|
+
* it is expanded, but its sessions still need attention and a collapsed ancestor must
|
|
90
|
+
* keep counting them — so expansion is a rendering fact, never an input to the
|
|
91
|
+
* aggregation. Short-circuiting expanded groups to `EMPTY_LIVE_STATUS` (the shape this
|
|
92
|
+
* had before the tree-wide aggregator existed, harmless while nothing aggregated) makes
|
|
93
|
+
* every collapsed parent undercount by the size of its expanded descendants.
|
|
94
|
+
*
|
|
95
|
+
* @param groups - derived groups, each with its member rows already populated.
|
|
96
|
+
* @param facets - registered sources, already filtered by the visibility settings.
|
|
97
|
+
* @param now - one clock reading shared by every group in the pass.
|
|
98
|
+
*/
|
|
99
|
+
export declare function directStatusesForGroups(groups: readonly {
|
|
100
|
+
key: string;
|
|
101
|
+
sessions: readonly SessionNode[];
|
|
102
|
+
}[], facets?: readonly RegisteredFacet[], now?: number): Map<string, GroupLiveStatus>;
|
|
103
|
+
/**
|
|
104
|
+
* Fold every group's DIRECT status up the workspace tree, so a collapsed folder
|
|
105
|
+
* counts every descendant session. A group's own row shows no badge while it is
|
|
106
|
+
* expanded, but its sessions still need attention and its collapsed ancestor must
|
|
107
|
+
* keep counting them — so the walk never depends on a group's expanded state.
|
|
108
|
+
*
|
|
109
|
+
* @param direct - each group's own-member status, keyed by group key.
|
|
110
|
+
* @param childrenByParent - the rendered tree: parent key (`undefined` = roots) → children.
|
|
111
|
+
* @returns aggregated status per group key: own members plus the whole subtree.
|
|
112
|
+
*/
|
|
113
|
+
export declare function aggregateGroupStatuses(direct: ReadonlyMap<string, GroupLiveStatus>, childrenByParent: ReadonlyMap<string | undefined, readonly {
|
|
114
|
+
key: string;
|
|
115
|
+
}[]>): Map<string, GroupLiveStatus>;
|
|
116
|
+
/**
|
|
117
|
+
* A group row whose badge input is resolved: its own members plus its whole subtree.
|
|
118
|
+
*
|
|
119
|
+
* `GroupNode.liveStatus` is optional only because upstream never fills it — this
|
|
120
|
+
* package's aggregator is the sole producer. Typing a rendered row as
|
|
121
|
+
* `StatusedGroupNode` is what turns "a row that skipped the aggregator" into a compile
|
|
122
|
+
* error instead of a folder that silently lost its badge, which is how the PR #10
|
|
123
|
+
* regression reached main.
|
|
124
|
+
*/
|
|
125
|
+
export interface StatusedGroupNode extends GroupNode {
|
|
126
|
+
liveStatus: GroupLiveStatus;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Attach each group's subtree-wide status, in derivation order. This is the producer
|
|
130
|
+
* the sidebar renders from.
|
|
131
|
+
*
|
|
132
|
+
* Expanded groups carry their status too: their own row draws no badge (a decision
|
|
133
|
+
* inside `groupLiveBadge`), but a collapsed ancestor still has to count them, so
|
|
134
|
+
* expansion never suppresses the measurement.
|
|
135
|
+
*
|
|
136
|
+
* @param groups - derived rows, in the order they render.
|
|
137
|
+
* @param direct - each group's own-member status, from {@link directStatusesForGroups}.
|
|
138
|
+
* @param childrenByParent - the rendered tree: parent key (`undefined` = roots) → children.
|
|
87
139
|
*/
|
|
88
|
-
export declare function
|
|
140
|
+
export declare function withAggregatedStatus(groups: readonly GroupNode[], direct: ReadonlyMap<string, GroupLiveStatus>, childrenByParent: ReadonlyMap<string | undefined, readonly GroupNode[]>): StatusedGroupNode[];
|
|
89
141
|
//# sourceMappingURL=group-status.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group-status.d.ts","sourceRoot":"","sources":["../../../src/client/group-status.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"group-status.d.ts","sourceRoot":"","sources":["../../../src/client/group-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE1E,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAIvD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAA;IAChB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAA;IAClB,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAA;IAChB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAA;IACZ,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;;OAMG;IACH,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CACxC;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,QAAQ,CAAA;IACf,IAAI,EAAE,YAAY,CAAA;CACnB;AAKD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,eAGX,CAAA;AAErB;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,eAAe,GAAG,eAAe,CAUvF;AAuBD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,MAAM,GAAE,SAAS,eAAe,EAAO,EACvC,GAAG,GAAE,MAAmB,GACvB,eAAe,CA6CjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,SAAS,WAAW,EAAE,CAAA;CAAE,EAAE,EACpE,MAAM,GAAE,SAAS,eAAe,EAAO,EACvC,GAAG,GAAE,MAAmB,GACvB,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAQ9B;AAED;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,EAC5C,gBAAgB,EAAE,WAAW,CAAC,MAAM,GAAG,SAAS,EAAE,SAAS;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,GAC5E,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAwB9B;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAkB,SAAQ,SAAS;IAClD,UAAU,EAAE,eAAe,CAAA;CAC5B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,EAC5C,gBAAgB,EAAE,WAAW,CAAC,MAAM,GAAG,SAAS,EAAE,SAAS,SAAS,EAAE,CAAC,GACtE,iBAAiB,EAAE,CAKrB"}
|
|
@@ -1,34 +1,24 @@
|
|
|
1
|
+
import { defaultMergeFold } from "./facets.js";
|
|
2
|
+
/** 空折果表:让哨兵的引用跨渲染稳定。 */
|
|
3
|
+
const EMPTY_FACETS = new Map();
|
|
1
4
|
/**
|
|
2
5
|
* Zero-valued sentinel for {@link GroupLiveStatus}.
|
|
3
6
|
*
|
|
4
|
-
* Used when a group
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* React selectors never trigger spurious re-renders on it.
|
|
7
|
+
* Used when a group has nothing to report. Kept as a frozen constant so the
|
|
8
|
+
* reference is stable across renders — `Object.is` comparisons in React selectors
|
|
9
|
+
* never trigger spurious re-renders on it.
|
|
8
10
|
*/
|
|
9
11
|
export const EMPTY_LIVE_STATUS = Object.freeze({
|
|
10
12
|
running: 0, approval: 0, planReview: 0, question: 0, done: 0, subagents: 0,
|
|
11
|
-
|
|
12
|
-
waitingReviewCount: 0, waitingReviewState: undefined,
|
|
13
|
+
facets: EMPTY_FACETS,
|
|
13
14
|
});
|
|
14
15
|
/**
|
|
15
|
-
*
|
|
16
|
-
* highest-priority state (overdue > urgent > scheduled for schedule; overdue > waiting
|
|
17
|
-
* for waiting-review).
|
|
16
|
+
* 合并两份分组折果:本插件自己的计数相加,外部状态来源**按 facet 各自合并**。
|
|
18
17
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* 用于多层聚合:折叠的父文件夹要覆盖整棵子树,而子树里每一层都已各自折过一遍。
|
|
19
|
+
* `FacetFold.data` 怎么合归该 facet 自己决定,本模块从不解释。
|
|
21
20
|
*/
|
|
22
21
|
export function mergeLiveStatus(a, b) {
|
|
23
|
-
// Schedule state: overdue (3) > urgent (2) > scheduled (1) > undefined (0)
|
|
24
|
-
const priorityOf = (s) => s === 'overdue' ? 3 : s === 'urgent' ? 2 : s === 'scheduled' ? 1 : 0;
|
|
25
|
-
const schedulePriorityA = priorityOf(a.scheduleState);
|
|
26
|
-
const schedulePriorityB = priorityOf(b.scheduleState);
|
|
27
|
-
const scheduleState = schedulePriorityA >= schedulePriorityB ? a.scheduleState : b.scheduleState;
|
|
28
|
-
// Waiting-review state: overdue > waiting > undefined
|
|
29
|
-
const waitingPriorityA = a.waitingReviewState === 'overdue' ? 2 : a.waitingReviewState === 'waiting' ? 1 : 0;
|
|
30
|
-
const waitingPriorityB = b.waitingReviewState === 'overdue' ? 2 : b.waitingReviewState === 'waiting' ? 1 : 0;
|
|
31
|
-
const waitingReviewState = waitingPriorityA >= waitingPriorityB ? a.waitingReviewState : b.waitingReviewState;
|
|
32
22
|
return {
|
|
33
23
|
running: a.running + b.running,
|
|
34
24
|
approval: a.approval + b.approval,
|
|
@@ -36,24 +26,25 @@ export function mergeLiveStatus(a, b) {
|
|
|
36
26
|
question: a.question + b.question,
|
|
37
27
|
done: a.done + b.done,
|
|
38
28
|
subagents: a.subagents + b.subagents,
|
|
39
|
-
|
|
40
|
-
scheduledCount: a.scheduledCount + b.scheduledCount,
|
|
41
|
-
scheduleState,
|
|
42
|
-
waitingReviewCount: a.waitingReviewCount + b.waitingReviewCount,
|
|
43
|
-
waitingReviewState,
|
|
29
|
+
facets: mergeFacets(a.facets, b.facets),
|
|
44
30
|
};
|
|
45
31
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
32
|
+
/** 按 facet id 合并两侧折果;只有一侧有的来源原样带过。 */
|
|
33
|
+
function mergeFacets(a, b) {
|
|
34
|
+
if (a.size === 0)
|
|
35
|
+
return b;
|
|
36
|
+
if (b.size === 0)
|
|
37
|
+
return a;
|
|
38
|
+
const merged = new Map(a);
|
|
39
|
+
for (const [id, entry] of b) {
|
|
40
|
+
const own = merged.get(id);
|
|
41
|
+
// 合并规则由该来源自己声明;缺省只加数量、取更紧急的色档、脉冲取或。
|
|
42
|
+
// 合并后仍沿用先登记那一份的 facet 引用:两侧本就是同一个来源。
|
|
43
|
+
merged.set(id, own === undefined
|
|
44
|
+
? entry
|
|
45
|
+
: { facet: own.facet, fold: own.facet.merge?.(own.fold, entry.fold) ?? defaultMergeFold(own.fold, entry.fold) });
|
|
46
|
+
}
|
|
47
|
+
return merged;
|
|
57
48
|
}
|
|
58
49
|
// ── Main computation ──
|
|
59
50
|
/**
|
|
@@ -61,84 +52,156 @@ function stripSessionPrefix(id) {
|
|
|
61
52
|
* hidden live sessions. Mirrors the session-row status priority (pending
|
|
62
53
|
* outranks running outranks completed) at the counting level; labels resolve with
|
|
63
54
|
* locale at render time.
|
|
55
|
+
*
|
|
64
56
|
* @param nodes - member rows of the group.
|
|
65
|
-
* @param sessionIds - the same members' Session ids (
|
|
66
|
-
* @param
|
|
67
|
-
* @param
|
|
57
|
+
* @param sessionIds - the same members' Session ids (facets address their own data by id).
|
|
58
|
+
* @param facets - the registered status sources to fold over this group.
|
|
59
|
+
* @param now - one clock reading for the whole pass, so sibling facets cannot disagree
|
|
60
|
+
* about which deadlines are still ahead.
|
|
68
61
|
*/
|
|
69
|
-
export function summarizeGroupStatus(nodes, sessionIds,
|
|
62
|
+
export function summarizeGroupStatus(nodes, sessionIds, facets = [], now = Date.now()) {
|
|
70
63
|
let running = 0;
|
|
71
64
|
let approval = 0;
|
|
72
65
|
let planReview = 0;
|
|
73
66
|
let question = 0;
|
|
74
67
|
let done = 0;
|
|
75
68
|
let subagents = 0;
|
|
69
|
+
// #25②:这一段曾与 `rows/Rows.tsx` 的 `sessionStatuses()` 各写一份优先级,两处结果不同
|
|
70
|
+
// (pending 会话漏算子智能体;未运行但已完成 + 有运行中子智能体时两处判断相反)。计数
|
|
71
|
+
// 判据仍在本模块(徽标只需要五个数字),但**语义以行内为准**:行内 pending 会同时给出
|
|
72
|
+
// subagents,未运行且有 subagents 时不承认 completed。下面的分支刻意照抄那两条规则,
|
|
73
|
+
// 不是另立一套「徽标自己的优先级」。
|
|
76
74
|
for (const n of nodes) {
|
|
77
75
|
if (n.blank || n.archived)
|
|
78
76
|
continue;
|
|
77
|
+
const hasSubagents = n.runningSubagentCount > 0;
|
|
78
|
+
// 行内:pending 与 subagents 可并存(Rows.tsx `[pending, subagents]`),故不 `continue`。
|
|
79
79
|
if (n.pendingInteraction === 'approval') {
|
|
80
80
|
approval += 1;
|
|
81
|
+
subagents += n.runningSubagentCount;
|
|
81
82
|
continue;
|
|
82
83
|
}
|
|
83
84
|
if (n.pendingInteraction === 'plan-review') {
|
|
84
85
|
planReview += 1;
|
|
86
|
+
subagents += n.runningSubagentCount;
|
|
85
87
|
continue;
|
|
86
88
|
}
|
|
87
89
|
if (n.pendingInteraction === 'question') {
|
|
88
90
|
question += 1;
|
|
91
|
+
subagents += n.runningSubagentCount;
|
|
89
92
|
continue;
|
|
90
93
|
}
|
|
91
|
-
if (n.running)
|
|
94
|
+
if (n.running) {
|
|
92
95
|
running += 1;
|
|
93
|
-
|
|
96
|
+
subagents += n.runningSubagentCount;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
// 行内:subagents 优先于 completed(`if (subagents !== undefined) return [subagents]`)。
|
|
100
|
+
if (hasSubagents) {
|
|
101
|
+
subagents += n.runningSubagentCount;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (n.completed)
|
|
94
105
|
done += 1;
|
|
95
|
-
subagents += n.runningSubagentCount;
|
|
96
106
|
}
|
|
97
|
-
//
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
let highestPriority = 0; // 0=none, 1=scheduled, 2=urgent, 3=overdue
|
|
105
|
-
for (const id of sessionIds) {
|
|
106
|
-
const entry = scheduleSummary.get(id);
|
|
107
|
-
if (entry) {
|
|
108
|
-
totalSessions += 1;
|
|
109
|
-
totalCount += entry.count;
|
|
110
|
-
const priority = entry.state === 'overdue' ? 3 : entry.state === 'urgent' ? 2 : 1;
|
|
111
|
-
if (priority > highestPriority)
|
|
112
|
-
highestPriority = priority;
|
|
113
|
-
}
|
|
107
|
+
// 外部来源逐个折。一个来源坏了不该带塌整只徽标:快照读失败按「此刻没有数据」处理,
|
|
108
|
+
// 折叠抛错则跳过该来源——两者都不往渲染管线里扩散。
|
|
109
|
+
const folded = new Map();
|
|
110
|
+
for (const { facet } of facets) {
|
|
111
|
+
let snapshot;
|
|
112
|
+
try {
|
|
113
|
+
snapshot = facet.getSnapshot();
|
|
114
114
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (waitingReviewSummary && sessionIds.length > 0) {
|
|
127
|
-
for (const id of sessionIds) {
|
|
128
|
-
const entry = waitingReviewSummary.get(id) ?? waitingReviewSummary.get(stripSessionPrefix(id));
|
|
129
|
-
if (entry === undefined)
|
|
130
|
-
continue;
|
|
131
|
-
waitingReviewCount += 1;
|
|
132
|
-
if (entry.state === 'overdue')
|
|
133
|
-
waitingReviewState = 'overdue';
|
|
134
|
-
else if (waitingReviewState === undefined)
|
|
135
|
-
waitingReviewState = 'waiting';
|
|
115
|
+
catch {
|
|
116
|
+
snapshot = undefined;
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
const result = facet.fold(snapshot, sessionIds, now);
|
|
120
|
+
// `count <= 0` 的来源不进表:数字、图标、文案、显隐判定都当它不存在。
|
|
121
|
+
if (result !== undefined && result.count > 0)
|
|
122
|
+
folded.set(facet.id, { facet, fold: result });
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
/* 同上:这个来源此刻不参与徽标 */
|
|
136
126
|
}
|
|
137
127
|
}
|
|
138
|
-
return {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
128
|
+
return { running, approval, planReview, question, done, subagents, facets: folded };
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Measure each group's own members, as the input to {@link aggregateGroupStatuses}.
|
|
132
|
+
*
|
|
133
|
+
* Every group is measured, expanded ones included. A folder row shows no badge while
|
|
134
|
+
* it is expanded, but its sessions still need attention and a collapsed ancestor must
|
|
135
|
+
* keep counting them — so expansion is a rendering fact, never an input to the
|
|
136
|
+
* aggregation. Short-circuiting expanded groups to `EMPTY_LIVE_STATUS` (the shape this
|
|
137
|
+
* had before the tree-wide aggregator existed, harmless while nothing aggregated) makes
|
|
138
|
+
* every collapsed parent undercount by the size of its expanded descendants.
|
|
139
|
+
*
|
|
140
|
+
* @param groups - derived groups, each with its member rows already populated.
|
|
141
|
+
* @param facets - registered sources, already filtered by the visibility settings.
|
|
142
|
+
* @param now - one clock reading shared by every group in the pass.
|
|
143
|
+
*/
|
|
144
|
+
export function directStatusesForGroups(groups, facets = [], now = Date.now()) {
|
|
145
|
+
const map = new Map();
|
|
146
|
+
for (const group of groups) {
|
|
147
|
+
map.set(group.key, summarizeGroupStatus(group.sessions, group.sessions.map(s => s.id), facets, now));
|
|
148
|
+
}
|
|
149
|
+
return map;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Fold every group's DIRECT status up the workspace tree, so a collapsed folder
|
|
153
|
+
* counts every descendant session. A group's own row shows no badge while it is
|
|
154
|
+
* expanded, but its sessions still need attention and its collapsed ancestor must
|
|
155
|
+
* keep counting them — so the walk never depends on a group's expanded state.
|
|
156
|
+
*
|
|
157
|
+
* @param direct - each group's own-member status, keyed by group key.
|
|
158
|
+
* @param childrenByParent - the rendered tree: parent key (`undefined` = roots) → children.
|
|
159
|
+
* @returns aggregated status per group key: own members plus the whole subtree.
|
|
160
|
+
*/
|
|
161
|
+
export function aggregateGroupStatuses(direct, childrenByParent) {
|
|
162
|
+
const aggregated = new Map();
|
|
163
|
+
// Parentage comes from path-prefix matching, so a self- or mutual-parent edge is
|
|
164
|
+
// representable; without this guard the fold would recurse forever and hang the sidebar.
|
|
165
|
+
const visiting = new Set();
|
|
166
|
+
const fold = (key) => {
|
|
167
|
+
const cached = aggregated.get(key);
|
|
168
|
+
if (cached !== undefined)
|
|
169
|
+
return cached;
|
|
170
|
+
if (visiting.has(key))
|
|
171
|
+
return direct.get(key) ?? EMPTY_LIVE_STATUS;
|
|
172
|
+
visiting.add(key);
|
|
173
|
+
let total = direct.get(key) ?? EMPTY_LIVE_STATUS;
|
|
174
|
+
for (const child of childrenByParent.get(key) ?? []) {
|
|
175
|
+
total = mergeLiveStatus(total, fold(child.key));
|
|
176
|
+
}
|
|
177
|
+
visiting.delete(key);
|
|
178
|
+
aggregated.set(key, total);
|
|
179
|
+
return total;
|
|
142
180
|
};
|
|
181
|
+
// Every listed child is folded, not just the roots: an unreachable group would
|
|
182
|
+
// otherwise be missing from the map and lose its badge.
|
|
183
|
+
for (const children of childrenByParent.values()) {
|
|
184
|
+
for (const child of children)
|
|
185
|
+
fold(child.key);
|
|
186
|
+
}
|
|
187
|
+
return aggregated;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Attach each group's subtree-wide status, in derivation order. This is the producer
|
|
191
|
+
* the sidebar renders from.
|
|
192
|
+
*
|
|
193
|
+
* Expanded groups carry their status too: their own row draws no badge (a decision
|
|
194
|
+
* inside `groupLiveBadge`), but a collapsed ancestor still has to count them, so
|
|
195
|
+
* expansion never suppresses the measurement.
|
|
196
|
+
*
|
|
197
|
+
* @param groups - derived rows, in the order they render.
|
|
198
|
+
* @param direct - each group's own-member status, from {@link directStatusesForGroups}.
|
|
199
|
+
* @param childrenByParent - the rendered tree: parent key (`undefined` = roots) → children.
|
|
200
|
+
*/
|
|
201
|
+
export function withAggregatedStatus(groups, direct, childrenByParent) {
|
|
202
|
+
const aggregated = aggregateGroupStatuses(direct, childrenByParent);
|
|
203
|
+
// A group missing from the fold has neither measured members nor listed children,
|
|
204
|
+
// so it is idle rather than unknown.
|
|
205
|
+
return groups.map(group => ({ ...group, liveStatus: aggregated.get(group.key) ?? EMPTY_LIVE_STATUS }));
|
|
143
206
|
}
|
|
144
207
|
//# sourceMappingURL=group-status.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group-status.js","sourceRoot":"","sources":["../../../src/client/group-status.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"group-status.js","sourceRoot":"","sources":["../../../src/client/group-status.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import type { Context } from '@deepseek-ai/cordis';
|
|
2
|
-
import type {
|
|
2
|
+
import type { RemoteEndpoint } from '@deepseek-ai/dsh-api-remote-access/client';
|
|
3
|
+
import type { WorkspaceId, WorkspaceSnapshot } from '@deepseek-ai/dsh-api-workspace-controller/client';
|
|
3
4
|
import type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots';
|
|
4
5
|
import { type ResolvedBadgeSettings } from './badge-settings.ts';
|
|
5
6
|
import { type WorkspaceKey } from './locales.ts';
|
|
6
|
-
export type { UiWorkspace } from './navigation.ts';
|
|
7
|
-
export type { DirectoryFlowOwnerProps, DirectoryFlowSlotName, DirectoryPickingHooks, DirectoryPickingInjected, MenuOpenState, RowToast, SessionRenameTarget, SessionRowOwnerProps, UseMenuOpenState, WorkspaceBrowserInjected, SessionRowScheduleOwnerProps, WorkspaceBrowserProps, WorkspacePickerInjected, WorkspacePickerProps, } from './contract/slots.ts';
|
|
7
|
+
export type { StartSessionOptions, UiWorkspace } from './navigation.ts';
|
|
8
|
+
export type { DirectoryFlowOwnerProps, DirectoryFlowSlotName, DirectoryPickingHooks, DirectoryPickingInjected, MenuOpenState, RowToast, RowToastActions, SessionIdInjected, SessionRenameTarget, SessionRowOwnerProps, UseMenuOpenState, WorkspaceBrowserInjected, SessionRowScheduleOwnerProps, WorkspaceBrowserProps, WorkspacePickerInjected, WorkspacePickerProps, } from './contract/slots.ts';
|
|
8
9
|
export type { WorkspaceKey } from './locales.ts';
|
|
9
10
|
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
10
11
|
interface GlobalStandardProps {
|
|
11
12
|
/** Selector hook over the pure Workspace Controller snapshot. */
|
|
12
13
|
useWorkspaces: SnapshotSelectorHook<WorkspaceSnapshot>;
|
|
14
|
+
/** Whether the current Peer may call `action` on one Workspace resource. */
|
|
15
|
+
useWorkspaceAccess: (workspaceId: WorkspaceId, action: RemoteEndpoint) => boolean;
|
|
13
16
|
/** Selector hook over this plugin's own settings face (badge preferences). */
|
|
14
17
|
useBadgeSettings: SnapshotSelectorHook<ResolvedBadgeSettings>;
|
|
15
18
|
}
|
|
@@ -31,6 +34,31 @@ declare module '@deepseek-ai/dsh-api-session-controller/client' {
|
|
|
31
34
|
* provides a waitable service. apply therefore depends on each slot
|
|
32
35
|
* declaration through `slots.inject()` instead of assuming order.
|
|
33
36
|
*/
|
|
37
|
+
/**
|
|
38
|
+
* ── 跨插件公共 API:分组状态 facet 协议 ─────────────────────────────
|
|
39
|
+
*
|
|
40
|
+
* 任何插件想让自己的状态进**折叠分组**的徽标,就 `require('dsh-group-status/client')`
|
|
41
|
+
* 拿这三个符号注册一个 facet;本插件不认识它,也不为它改代码:
|
|
42
|
+
*
|
|
43
|
+
* ```ts
|
|
44
|
+
* const gs = require('dsh-group-status/client')
|
|
45
|
+
* const unregister = gs?.registerGroupStatusFacet?.({
|
|
46
|
+
* protocol: gs.GROUP_STATUS_FACET_PROTOCOL_VERSION,
|
|
47
|
+
* id: 'my-plugin.review', // '<包名>.<状态名>',全局唯一
|
|
48
|
+
* subscribe: store.subscribe, // 外部存储面,不要求 React hook
|
|
49
|
+
* getSnapshot: store.getSnapshot,
|
|
50
|
+
* fold: (snapshot, sessionIds, now) => ({ count, tone, pulse, data }),
|
|
51
|
+
* merge: (a, b) => ({ ... }), // 多层文件夹怎么合并你的折果
|
|
52
|
+
* label: (fold, { now }) => '等待评审(剩 3分钟) · #15',
|
|
53
|
+
* renderIcon: (fold) => h('svg', …), // 图标归你,本插件只负责摆放
|
|
54
|
+
* })
|
|
55
|
+
* ctx.effect(() => () => unregister?.(), 'my-plugin: group-status facet')
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* 完整契约、版本规则与为什么是这个方向见 `docs/facet-protocol.md`。
|
|
59
|
+
*/
|
|
60
|
+
export { GROUP_STATUS_FACET_PROTOCOL_VERSION, FACET_TONE_RANK, registerGroupStatusFacet, registry as groupStatusFacetRegistry, } from './facets.ts';
|
|
61
|
+
export type { AnyFacet, AnyFacetFold, FacetFold, FacetOrigin, FacetRenderContext, FacetRegistration, FacetRejection, FacetTone, GroupStatusFacet, Unregister, } from './facets.ts';
|
|
34
62
|
export declare const inject: string[];
|
|
35
63
|
/**
|
|
36
64
|
* Register the browser and picker once their slot declarations are on the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAA;AAE/E,OAAO,KAAK,EAC2C,WAAW,EAAE,iBAAiB,EACpF,MAAM,kDAAkD,CAAA;AAGzD,OAAO,KAAK,EAAkB,oBAAoB,EAAE,MAAM,kCAAkC,CAAA;AAsB5F,OAAO,EAAuC,KAAK,qBAAqB,EAAE,MAAM,qBAAqB,CAAA;AAerG,OAAO,EAAU,KAAK,YAAY,EAAE,MAAM,cAAc,CAAA;AAExD,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AACvE,YAAY,EACV,uBAAuB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,wBAAwB,EAC/F,aAAa,EAAE,QAAQ,EAAE,eAAe,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,oBAAoB,EACtG,gBAAgB,EAAE,wBAAwB,EAC1C,4BAA4B,EAC5B,qBAAqB,EACrB,uBAAuB,EAAE,oBAAoB,GAC9C,MAAM,qBAAqB,CAAA;AAC5B,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAEhD,OAAO,QAAQ,kCAAkC,CAAC;IAChD,UAAU,mBAAmB;QAC3B,iEAAiE;QACjE,aAAa,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,CAAA;QACtD,4EAA4E;QAC5E,kBAAkB,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,KAAK,OAAO,CAAA;QACjF,8EAA8E;QAC9E,gBAAgB,EAAE,oBAAoB,CAAC,qBAAqB,CAAC,CAAA;KAC9D;IAED,UAAU,kBAAkB;QAC1B,+DAA+D;QAC/D,SAAS,EAAE,YAAY,CAAA;KACxB;CACF;AAED,OAAO,QAAQ,gDAAgD,CAAC;IAC9D,UAAU,yBAAyB;QACjC,kBAAkB,EAAE,OAAO,CAAA;KAC5B;CACF;AAkCD;;;;;;;GAOG;AACH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EACL,mCAAmC,EAAE,eAAe,EAAE,wBAAwB,EAC9E,QAAQ,IAAI,wBAAwB,GACrC,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,WAAW,EAAE,kBAAkB,EAClE,iBAAiB,EAAE,cAAc,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,GAC3E,MAAM,aAAa,CAAA;AAEpB,eAAO,MAAM,MAAM,UAElB,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAiTxC"}
|