@geoly-ai/social-hub-cli 0.2.22 → 0.2.24

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 (55) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/client.d.ts +21 -0
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +64 -1
  5. package/dist/client.js.map +1 -1
  6. package/dist/client.test.d.ts +2 -0
  7. package/dist/client.test.d.ts.map +1 -0
  8. package/dist/client.test.js +123 -0
  9. package/dist/client.test.js.map +1 -0
  10. package/dist/cmd-manifest.json +14 -2
  11. package/dist/cmd-manifest.test.js +4 -0
  12. package/dist/cmd-manifest.test.js.map +1 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +4 -2
  15. package/dist/index.js.map +1 -1
  16. package/dist/permission-runner.d.ts +21 -4
  17. package/dist/permission-runner.d.ts.map +1 -1
  18. package/dist/permission-runner.js +36 -9
  19. package/dist/permission-runner.js.map +1 -1
  20. package/dist/permission-runner.test.js +76 -0
  21. package/dist/permission-runner.test.js.map +1 -1
  22. package/dist/permissions-gates-subreddit-style.d.ts +10 -0
  23. package/dist/permissions-gates-subreddit-style.d.ts.map +1 -0
  24. package/dist/permissions-gates-subreddit-style.js +66 -0
  25. package/dist/permissions-gates-subreddit-style.js.map +1 -0
  26. package/dist/permissions-gates-subreddit-style.test.d.ts +2 -0
  27. package/dist/permissions-gates-subreddit-style.test.d.ts.map +1 -0
  28. package/dist/permissions-gates-subreddit-style.test.js +44 -0
  29. package/dist/permissions-gates-subreddit-style.test.js.map +1 -0
  30. package/dist/permissions.d.ts +10 -0
  31. package/dist/permissions.d.ts.map +1 -1
  32. package/dist/permissions.js +9 -2
  33. package/dist/permissions.js.map +1 -1
  34. package/dist/register-extensions.d.ts.map +1 -1
  35. package/dist/register-extensions.js +1 -0
  36. package/dist/register-extensions.js.map +1 -1
  37. package/dist/register-subreddit-style-actions.test.d.ts +2 -0
  38. package/dist/register-subreddit-style-actions.test.d.ts.map +1 -0
  39. package/dist/register-subreddit-style-actions.test.js +295 -0
  40. package/dist/register-subreddit-style-actions.test.js.map +1 -0
  41. package/dist/register-subreddit-style.d.ts +57 -0
  42. package/dist/register-subreddit-style.d.ts.map +1 -0
  43. package/dist/register-subreddit-style.js +418 -0
  44. package/dist/register-subreddit-style.js.map +1 -0
  45. package/dist/register-subreddit-style.test.d.ts +2 -0
  46. package/dist/register-subreddit-style.test.d.ts.map +1 -0
  47. package/dist/register-subreddit-style.test.js +183 -0
  48. package/dist/register-subreddit-style.test.js.map +1 -0
  49. package/package.json +1 -1
  50. package/skills/README.md +1 -0
  51. package/skills/manifest.json +6 -1
  52. package/skills/social-hub-cli/SKILL.md +1 -0
  53. package/skills/social-hub-content-review/SKILL.md +23 -5
  54. package/skills/social-hub-post-review/SKILL.md +23 -4
  55. package/skills/social-hub-style-profiles/SKILL.md +126 -0
@@ -0,0 +1,295 @@
1
+ import { Command } from "commander";
2
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
3
+ /**
4
+ * Commander action 集成测试(Codex diff 轮 P2):mock 传输层(hubRequest)与权限
5
+ * 预检(withPermissionGates 放行但记录入参),锁定十个 leaf command 的 HTTP
6
+ * method/path/query/If-Match/body、rowVersion 自动 GET、dry-run 行为、
7
+ * PROFILE_STALE 不重试、gate 入参与负向校验。
8
+ */
9
+ const hubRequestMock = vi.fn();
10
+ /** 记录 withPermissionGates 入参(锁 gate 映射回归;Codex 复评 P2)。 */
11
+ const gateCalls = vi.hoisted(() => []);
12
+ class MockHubHttpError extends Error {
13
+ status;
14
+ code;
15
+ constructor(status, code, message) {
16
+ super(message);
17
+ this.name = "HubHttpError";
18
+ this.status = status;
19
+ this.code = code;
20
+ }
21
+ }
22
+ vi.mock("./client.js", () => ({
23
+ hubRequest: (...args) => hubRequestMock(...args),
24
+ HubHttpError: MockHubHttpError,
25
+ resolveTeamId: (id) => id ?? "team-ctx",
26
+ requireClient: () => ({}),
27
+ getBaseUrl: () => "https://api.example.com",
28
+ }));
29
+ vi.mock("./permission-runner.js", () => ({
30
+ withPermissionGates: async (input, run) => {
31
+ gateCalls.push(input);
32
+ await run({ role: "manager", teamId: input.teamId });
33
+ },
34
+ withPermissionGate: async (input, run) => {
35
+ gateCalls.push(input);
36
+ await run({ role: "manager", teamId: input.teamId });
37
+ },
38
+ }));
39
+ const { registerSubredditStyleCommands } = await import("./register-subreddit-style.js");
40
+ const PROFILE_ID = "123e4567-e89b-42d3-a456-426614174000";
41
+ const PROFILE_HEAD = {
42
+ id: PROFILE_ID,
43
+ scope: "global",
44
+ subreddit: "bouldering",
45
+ brandId: null,
46
+ version: 3,
47
+ status: "proposed",
48
+ summary: "画像摘要",
49
+ proposedByUserId: "user-1",
50
+ rowVersion: `ssp:${PROFILE_ID}:proposed:2026-07-26T00:00:00.000Z`,
51
+ };
52
+ function newProgram() {
53
+ const program = new Command();
54
+ program.exitOverride();
55
+ registerSubredditStyleCommands(program);
56
+ return program;
57
+ }
58
+ async function run(...args) {
59
+ await newProgram().parseAsync(["node", "social-hub", ...args]);
60
+ }
61
+ beforeEach(() => {
62
+ hubRequestMock.mockReset();
63
+ gateCalls.length = 0;
64
+ vi.spyOn(process, "exit").mockImplementation((() => {
65
+ throw new Error("process.exit");
66
+ }));
67
+ vi.spyOn(console, "log").mockImplementation(() => { });
68
+ vi.spyOn(console, "error").mockImplementation(() => { });
69
+ });
70
+ afterEach(() => {
71
+ vi.restoreAllMocks();
72
+ });
73
+ describe("style-profiles 读面", () => {
74
+ it("list:GET 带过滤 query", async () => {
75
+ hubRequestMock.mockResolvedValue({ items: [], total: 0 });
76
+ await run("style-profiles", "list", "--subreddit", "bouldering", "--status", "proposed,approved", "-n", "20");
77
+ expect(hubRequestMock).toHaveBeenCalledTimes(1);
78
+ const [path] = hubRequestMock.mock.calls[0];
79
+ expect(path).toContain("/v1/system/subreddit-style-profiles?");
80
+ expect(path).toContain("subreddit=bouldering");
81
+ expect(path).toContain("status=proposed%2Capproved");
82
+ expect(path).toContain("limit=20");
83
+ });
84
+ it("get:GET :id", async () => {
85
+ hubRequestMock.mockResolvedValue({ profile: PROFILE_HEAD });
86
+ await run("style-profiles", "get", "--id", PROFILE_ID);
87
+ expect(hubRequestMock).toHaveBeenCalledWith(`/v1/system/subreddit-style-profiles/${PROFILE_ID}`);
88
+ });
89
+ it("active:GET /active 带 subreddit(+brandId)", async () => {
90
+ hubRequestMock.mockResolvedValue({ profile: null, versionToken: null });
91
+ await run("style-profiles", "active", "--subreddit", "bouldering", "--brand", "123e4567-e89b-42d3-a456-426614174001");
92
+ const [path] = hubRequestMock.mock.calls[0];
93
+ expect(path).toContain("/v1/system/subreddit-style-profiles/active?");
94
+ expect(path).toContain("subreddit=bouldering");
95
+ expect(path).toContain("brandId=123e4567-e89b-42d3-a456-426614174001");
96
+ });
97
+ });
98
+ describe("style-profiles propose", () => {
99
+ it("--apply:POST body 透传", async () => {
100
+ hubRequestMock.mockResolvedValue({ profile: PROFILE_HEAD });
101
+ await run("style-profiles", "propose", "-j", '{"scope":"global","subreddit":"bouldering","profile":{"tone":"t"}}', "--apply");
102
+ expect(hubRequestMock).toHaveBeenCalledWith("/v1/system/subreddit-style-profiles", {
103
+ method: "POST",
104
+ body: {
105
+ scope: "global",
106
+ subreddit: "bouldering",
107
+ profile: { tone: "t" },
108
+ },
109
+ });
110
+ });
111
+ it("--dry-run:不 POST", async () => {
112
+ await run("style-profiles", "propose", "-j", '{"scope":"global","subreddit":"bouldering","profile":{"tone":"t"}}', "--dry-run");
113
+ expect(hubRequestMock).not.toHaveBeenCalled();
114
+ expect(console.log).toHaveBeenCalled();
115
+ });
116
+ it("propose 注册 userOnly(本地拒 api_key;Codex 验收 P2)", async () => {
117
+ hubRequestMock.mockResolvedValue({ profile: PROFILE_HEAD });
118
+ await run("style-profiles", "propose", "-j", '{"scope":"global","subreddit":"bouldering","profile":{"tone":"t"}}', "--apply");
119
+ expect(gateCalls[0]).toMatchObject({
120
+ command: "style-profiles propose",
121
+ gates: [{ resource: "subredditStyleProfile", action: "create" }],
122
+ userOnly: true,
123
+ });
124
+ });
125
+ });
126
+ describe("style-profiles 流转(approve/reject/cancel/retire)", () => {
127
+ it("approve:缺省自动 GET 取 rowVersion,POST 带 If-Match、无 body", async () => {
128
+ hubRequestMock
129
+ .mockResolvedValueOnce({ profile: PROFILE_HEAD })
130
+ .mockResolvedValueOnce({
131
+ profile: { ...PROFILE_HEAD, status: "approved" },
132
+ });
133
+ await run("style-profiles", "approve", "--id", PROFILE_ID, "--apply");
134
+ expect(hubRequestMock).toHaveBeenCalledTimes(2);
135
+ expect(hubRequestMock.mock.calls[0]?.[0]).toBe(`/v1/system/subreddit-style-profiles/${PROFILE_ID}`);
136
+ expect(hubRequestMock.mock.calls[1]).toEqual([
137
+ `/v1/system/subreddit-style-profiles/${PROFILE_ID}/approve`,
138
+ {
139
+ method: "POST",
140
+ headers: { "If-Match": PROFILE_HEAD.rowVersion },
141
+ body: undefined,
142
+ },
143
+ ]);
144
+ });
145
+ it("approve:显式 --row-version 不 GET", async () => {
146
+ hubRequestMock.mockResolvedValue({ profile: PROFILE_HEAD });
147
+ await run("style-profiles", "approve", "--id", PROFILE_ID, "--row-version", `ssp:${PROFILE_ID}:proposed:x`, "--apply");
148
+ expect(hubRequestMock).toHaveBeenCalledTimes(1);
149
+ expect(hubRequestMock.mock.calls[0]?.[1]).toMatchObject({
150
+ method: "POST",
151
+ headers: { "If-Match": `ssp:${PROFILE_ID}:proposed:x` },
152
+ });
153
+ });
154
+ it.each(["reject", "cancel", "retire"])("%s:POST 带 If-Match 与 {reason} body", async (name) => {
155
+ hubRequestMock
156
+ .mockResolvedValueOnce({ profile: PROFILE_HEAD })
157
+ .mockResolvedValueOnce({ profile: PROFILE_HEAD });
158
+ await run("style-profiles", name, "--id", PROFILE_ID, "--reason", "原因说明", "--apply");
159
+ expect(hubRequestMock).toHaveBeenCalledTimes(2);
160
+ expect(hubRequestMock.mock.calls[1]).toEqual([
161
+ `/v1/system/subreddit-style-profiles/${PROFILE_ID}/${name}`,
162
+ {
163
+ method: "POST",
164
+ headers: { "If-Match": PROFILE_HEAD.rowVersion },
165
+ body: { reason: "原因说明" },
166
+ },
167
+ ]);
168
+ });
169
+ it("approve --dry-run:GET 一次、不 POST,摘要含 rowVersion/status", async () => {
170
+ hubRequestMock.mockResolvedValueOnce({ profile: PROFILE_HEAD });
171
+ await run("style-profiles", "approve", "--id", PROFILE_ID, "--dry-run");
172
+ expect(hubRequestMock).toHaveBeenCalledTimes(1);
173
+ const printed = vi.mocked(console.log).mock.calls.flat().join("\n");
174
+ expect(printed).toContain(PROFILE_HEAD.rowVersion);
175
+ expect(printed).toContain("proposed");
176
+ });
177
+ it("PROFILE_STALE:不重试,输出重取提示,退出非 0", async () => {
178
+ hubRequestMock
179
+ .mockResolvedValueOnce({ profile: PROFILE_HEAD })
180
+ .mockRejectedValueOnce(new MockHubHttpError(409, "PROFILE_STALE", "HTTP 409: stale"));
181
+ await expect(run("style-profiles", "approve", "--id", PROFILE_ID, "--apply")).rejects.toThrow();
182
+ expect(hubRequestMock).toHaveBeenCalledTimes(2);
183
+ const stderr = vi.mocked(console.error).mock.calls.flat().join("\n");
184
+ expect(stderr).toContain("不会自动重试");
185
+ });
186
+ });
187
+ describe("subreddit-annotations", () => {
188
+ const PERMALINK = "https://www.reddit.com/r/bouldering/comments/abc123/t/";
189
+ it("list:GET team 路径带 query(annotationType 映射自 --type)", async () => {
190
+ hubRequestMock.mockResolvedValue({ items: [], total: 0 });
191
+ await run("subreddit-annotations", "list", "-t", "team-a", "--type", "style_fit", "--source", "human");
192
+ const [path] = hubRequestMock.mock.calls[0];
193
+ expect(path).toContain("/v1/teams/team-a/subreddit-post-annotations?");
194
+ expect(path).toContain("annotationType=style_fit");
195
+ expect(path).toContain("source=human");
196
+ });
197
+ it("upsert --apply:POST upsert 端点,body 形状正确", async () => {
198
+ hubRequestMock.mockResolvedValue({ annotation: { id: "a1" } });
199
+ await run("subreddit-annotations", "upsert", "-t", "team-a", "--subreddit", "bouldering", "--permalink", PERMALINK, "--type", "style_fit", "--score", "4", "--label", "tone-match", "--apply");
200
+ expect(hubRequestMock).toHaveBeenCalledWith("/v1/teams/team-a/subreddit-post-annotations/upsert", {
201
+ method: "POST",
202
+ body: {
203
+ subreddit: "bouldering",
204
+ permalink: PERMALINK,
205
+ annotationType: "style_fit",
206
+ score: 4,
207
+ label: "tone-match",
208
+ scope: "team",
209
+ },
210
+ });
211
+ });
212
+ it("upsert --dry-run:不 POST;缺省 team 走 context(team-ctx)", async () => {
213
+ await run("subreddit-annotations", "upsert", "--subreddit", "bouldering", "--permalink", PERMALINK, "--type", "style_fit", "--score", "4", "--dry-run");
214
+ expect(hubRequestMock).not.toHaveBeenCalled();
215
+ const printed = vi.mocked(console.log).mock.calls.flat().join("\n");
216
+ expect(printed).toContain("team-ctx");
217
+ expect(printed).toContain("last-write-wins");
218
+ });
219
+ it("upsert 非法输入(非 Reddit permalink)在请求前拒", async () => {
220
+ await expect(run("subreddit-annotations", "upsert", "-t", "team-a", "--subreddit", "bouldering", "--permalink", "https://example.com/x", "--type", "style_fit", "--score", "4", "--apply")).rejects.toThrow("process.exit");
221
+ expect(hubRequestMock).not.toHaveBeenCalled();
222
+ });
223
+ });
224
+ describe("gate 入参与负向校验(Codex 复评 P2)", () => {
225
+ const PERMALINK = "https://www.reddit.com/r/bouldering/comments/abc123/t/";
226
+ const BRAND_UUID = "123e4567-e89b-42d3-a456-426614174001";
227
+ it("list 命令预检 action=read(与服务端断言一致)", async () => {
228
+ hubRequestMock.mockResolvedValue({ items: [], total: 0 });
229
+ await run("style-profiles", "list");
230
+ await run("subreddit-annotations", "list", "-t", "team-a");
231
+ expect(gateCalls).toHaveLength(2);
232
+ expect(gateCalls[0]).toMatchObject({
233
+ command: "style-profiles list",
234
+ gates: [{ resource: "subredditStyleProfile", action: "read" }],
235
+ });
236
+ expect(gateCalls[1]).toMatchObject({
237
+ command: "subreddit-annotations list",
238
+ gates: [{ resource: "subredditPostAnnotation", action: "read" }],
239
+ teamId: "team-a",
240
+ });
241
+ });
242
+ it("写命令 userOnly;upsert team=create+update,global 追加画像治理 gate", async () => {
243
+ hubRequestMock.mockResolvedValue({ profile: PROFILE_HEAD });
244
+ await run("style-profiles", "approve", "--id", PROFILE_ID, "--row-version", `ssp:${PROFILE_ID}:proposed:x`, "--apply");
245
+ expect(gateCalls[0]).toMatchObject({
246
+ command: "style-profiles approve",
247
+ userOnly: true,
248
+ });
249
+ gateCalls.length = 0;
250
+ hubRequestMock.mockResolvedValue({ annotation: { id: "a1" } });
251
+ await run("subreddit-annotations", "upsert", "-t", "team-a", "--subreddit", "bouldering", "--permalink", PERMALINK, "--type", "style_fit", "--score", "4", "--apply");
252
+ expect(gateCalls[0]).toMatchObject({
253
+ command: "subreddit-annotations upsert",
254
+ gates: [
255
+ { resource: "subredditPostAnnotation", action: "create" },
256
+ { resource: "subredditPostAnnotation", action: "update" },
257
+ ],
258
+ teamId: "team-a",
259
+ userOnly: true,
260
+ });
261
+ gateCalls.length = 0;
262
+ await run("subreddit-annotations", "upsert", "-t", "team-a", "--subreddit", "bouldering", "--permalink", PERMALINK, "--type", "brand_friendliness", "--brand", BRAND_UUID, "--score", "2", "--scope", "global", "--apply");
263
+ expect(gateCalls[0]).toMatchObject({
264
+ gates: [
265
+ { resource: "subredditPostAnnotation", action: "create" },
266
+ { resource: "subredditPostAnnotation", action: "update" },
267
+ { resource: "subredditStyleProfile", action: "update" },
268
+ ],
269
+ });
270
+ });
271
+ it("显式空 --row-version('\"\"')fail-closed,不发任何请求", async () => {
272
+ await expect(run("style-profiles", "approve", "--id", PROFILE_ID, "--row-version", '""', "--apply")).rejects.toThrow("process.exit");
273
+ expect(hubRequestMock).not.toHaveBeenCalled();
274
+ const stderr = vi.mocked(console.error).mock.calls.flat().join("\n");
275
+ expect(stderr).toContain("--row-version 无效");
276
+ });
277
+ it.each([
278
+ {
279
+ name: "非法 brandId",
280
+ args: ["--type", "brand_friendliness", "--brand", "b1"],
281
+ },
282
+ {
283
+ name: "空 label",
284
+ args: ["--type", "style_fit", "--label", " "],
285
+ },
286
+ {
287
+ name: "超长 note",
288
+ args: ["--type", "style_fit", "--note", "x".repeat(2001)],
289
+ },
290
+ ])("upsert $name 在请求前拒", async ({ args }) => {
291
+ await expect(run("subreddit-annotations", "upsert", "-t", "team-a", "--subreddit", "bouldering", "--permalink", PERMALINK, "--score", "4", ...args, "--apply")).rejects.toThrow("process.exit");
292
+ expect(hubRequestMock).not.toHaveBeenCalled();
293
+ });
294
+ });
295
+ //# sourceMappingURL=register-subreddit-style-actions.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-subreddit-style-actions.test.js","sourceRoot":"","sources":["../src/register-subreddit-style-actions.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import type { Command } from "commander";
2
+ type StyleProfileView = {
3
+ id: string;
4
+ scope: "global" | "brand";
5
+ subreddit: string;
6
+ brandId: string | null;
7
+ version: number;
8
+ status: "proposed" | "approved" | "retired";
9
+ summary: string | null;
10
+ proposedByUserId: string | null;
11
+ rowVersion: string;
12
+ [key: string]: unknown;
13
+ };
14
+ /**
15
+ * If-Match token 归一:接受成对引号(GET 的 ETag 形状)或裸 token。
16
+ * fail-closed(Codex 验收 P2):W/ 弱 ETag、* 通配、多值(含逗号)、引号不成对
17
+ * 一律判无效——CLI 只接受单个 strong token,非法形状本地即拒,不留给服务端。
18
+ */
19
+ export declare function normalizeRowVersionToken(raw: string | undefined): string | undefined;
20
+ /** 显式 token 与目标画像明显不符的软检查(前缀 ssp:<id>:);权威校验仍在服务端。 */
21
+ export declare function rowVersionMatchesId(id: string, token: string): boolean;
22
+ /**
23
+ * rowVersion 解析:**传过 --row-version 就必须用显式值**——归一后为空(如 '""')
24
+ * fail-closed 退出,绝不回退自动 GET(否则用户想用指定版本保护的写会意外作用于
25
+ * 最新版本;Codex diff 轮 P1)。未传才自动 GET 当前值(便利读取)。
26
+ * fetcher 可注入(测试)。
27
+ */
28
+ export declare function resolveRowVersion(input: {
29
+ id: string;
30
+ rowVersion?: string;
31
+ }, fetcher?: (id: string) => Promise<StyleProfileView>): Promise<{
32
+ rowVersion: string;
33
+ head: StyleProfileView | null;
34
+ }>;
35
+ export type AnnotationUpsertInput = {
36
+ subreddit: string;
37
+ permalink: string;
38
+ type: string;
39
+ score: string;
40
+ brand?: string;
41
+ label?: string;
42
+ note?: string;
43
+ scope: string;
44
+ };
45
+ export declare function buildAnnotationUpsertBody(input: AnnotationUpsertInput): {
46
+ subreddit: string;
47
+ permalink: string;
48
+ annotationType: "style_fit" | "brand_friendliness";
49
+ brandId?: string;
50
+ score: number;
51
+ label?: string;
52
+ note?: string;
53
+ scope: "team" | "global";
54
+ };
55
+ export declare function registerSubredditStyleCommands(program: Command): void;
56
+ export {};
57
+ //# sourceMappingURL=register-subreddit-style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-subreddit-style.d.ts","sourceRoot":"","sources":["../src/register-subreddit-style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuBzC,KAAK,gBAAgB,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;IAC5C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,GAAG,SAAS,GACtB,MAAM,GAAG,SAAS,CAapB;AAED,sDAAsD;AACtD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAEtE;AASD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,EAC1C,OAAO,GAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAqB,GACrE,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAA;CAAE,CAAC,CA2BhE;AA8GD,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,qBAAqB,GAAG;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,WAAW,GAAG,oBAAoB,CAAC;IACnD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;CAC1B,CAiDA;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwRrE"}