@dmmulroy/overseer 0.4.0 → 0.5.1

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/bin/os CHANGED
@@ -82,8 +82,13 @@ if (command === "mcp") {
82
82
  console.error("Failed to start MCP server:", err.message);
83
83
  process.exit(1);
84
84
  });
85
- } else {
86
- // All other commands - passthrough to native binary
85
+ }
86
+ // Handle `os ui` - start Task Viewer webapp
87
+ else if (command === "ui") {
88
+ startUiServer(args.slice(1));
89
+ }
90
+ // All other commands - passthrough to native binary
91
+ else {
87
92
  const child = spawn(getBinaryPath(), args, {
88
93
  stdio: "inherit",
89
94
  });
@@ -101,3 +106,89 @@ if (command === "mcp") {
101
106
  }
102
107
  });
103
108
  }
109
+
110
+ /**
111
+ * Start the UI server
112
+ * Usage: os ui [port] [--port PORT] [--open]
113
+ */
114
+ function startUiServer(uiArgs) {
115
+ // Parse args: positional port, --port flag, --open flag
116
+ let port = null;
117
+ let openBrowser = false;
118
+
119
+ for (let i = 0; i < uiArgs.length; i++) {
120
+ const arg = uiArgs[i];
121
+ if (arg === "--port" && i + 1 < uiArgs.length) {
122
+ port = parseInt(uiArgs[++i], 10);
123
+ } else if (arg === "--open") {
124
+ openBrowser = true;
125
+ } else if (arg === "--help" || arg === "-h") {
126
+ console.log(`Usage: os ui [port] [--port PORT] [--open]
127
+
128
+ Options:
129
+ port Port number (positional, default: 6969)
130
+ --port PORT Port number (explicit flag)
131
+ --open Open browser after starting
132
+
133
+ Examples:
134
+ os ui # Start on port 6969
135
+ os ui 8080 # Start on port 8080
136
+ os ui --port 3000 # Start on port 3000
137
+ os ui --open # Start and open browser`);
138
+ process.exit(0);
139
+ } else if (/^\d+$/.test(arg) && port === null) {
140
+ // Positional port number
141
+ port = parseInt(arg, 10);
142
+ }
143
+ }
144
+
145
+ // Port precedence: --port > positional > PORT env > 6969
146
+ if (port === null && process.env.PORT) {
147
+ port = parseInt(process.env.PORT, 10);
148
+ }
149
+ if (port === null || isNaN(port)) {
150
+ port = 6969;
151
+ }
152
+
153
+ // Set up environment for the UI server
154
+ const binaryPath = getBinaryPath();
155
+ process.env.OVERSEER_CLI_PATH = binaryPath;
156
+ process.env.PORT = String(port);
157
+ process.env.NODE_ENV = "production";
158
+
159
+ // Static files are in dist/ui/static/ relative to package root
160
+ const uiDir = join(__dirname, "..", "dist", "ui");
161
+ process.env.OVERSEER_UI_STATIC_ROOT = join(uiDir, "static");
162
+
163
+ // Change cwd to ui dir (serveStatic needs relative path from cwd)
164
+ process.chdir(uiDir);
165
+
166
+ const serverPath = join(uiDir, "server.js");
167
+
168
+ if (!existsSync(serverPath)) {
169
+ console.error("UI server not found. The package may not have been built correctly.");
170
+ console.error(`Expected: ${serverPath}`);
171
+ process.exit(1);
172
+ }
173
+
174
+ // Open browser after server starts (if requested)
175
+ if (openBrowser) {
176
+ // Delay to let server start
177
+ setTimeout(() => {
178
+ const url = `http://localhost:${port}`;
179
+ const openCmd =
180
+ platform === "darwin" ? "open" :
181
+ platform === "win32" ? "start" : "xdg-open";
182
+ try {
183
+ execSync(`${openCmd} ${url}`, { stdio: "ignore" });
184
+ } catch {
185
+ // Ignore errors (e.g., no display)
186
+ }
187
+ }, 500);
188
+ }
189
+
190
+ import(serverPath).catch((err) => {
191
+ console.error("Failed to start UI server:", err.message);
192
+ process.exit(1);
193
+ });
194
+ }
@@ -1,8 +1,24 @@
1
- import type { Task, TaskWithContext } from "../types.js";
1
+ import type { Depth, Task, TaskWithContext, TaskTree, TaskProgress } from "../types.js";
2
+ /**
3
+ * Task type aliases for depth (ergonomic sugar)
4
+ */
5
+ export type TaskType = "milestone" | "task" | "subtask";
2
6
  export interface TaskFilter {
3
7
  parentId?: string;
4
8
  ready?: boolean;
5
9
  completed?: boolean;
10
+ /**
11
+ * Filter by depth: 0=milestones, 1=tasks, 2=subtasks.
12
+ * Maps to CLI: --milestones | --tasks | --subtasks
13
+ * Mutually exclusive with parentId and type.
14
+ */
15
+ depth?: Depth;
16
+ /**
17
+ * Filter by type: "milestone" | "task" | "subtask".
18
+ * Alias for depth (milestone=0, task=1, subtask=2).
19
+ * Mutually exclusive with parentId and depth.
20
+ */
21
+ type?: TaskType;
6
22
  }
7
23
  export interface CreateTaskInput {
8
24
  description: string;
@@ -43,7 +59,7 @@ export declare const tasks: {
43
59
  /**
44
60
  * Mark task as started.
45
61
  * Follows blockers to find startable work, cascades to deepest leaf.
46
- * Creates VCS bookmark for started task.
62
+ * Creates VCS bookmark for started task and records start commit.
47
63
  * Returns the task that was actually started.
48
64
  *
49
65
  * **Requires VCS**: Must be in a jj or git repository.
@@ -83,5 +99,23 @@ export declare const tasks: {
83
99
  * Returns task with full context chain and inherited learnings, or null if no ready tasks.
84
100
  */
85
101
  nextReady(milestoneId?: string): Promise<TaskWithContext | null>;
102
+ /**
103
+ * Get task tree structure.
104
+ * If rootId provided, returns single tree rooted at that task.
105
+ * If no rootId, returns array of all milestone trees.
106
+ *
107
+ * **Warning:** Large trees may hit 50k output limit. Prefer scoping to specific milestone.
108
+ */
109
+ tree(rootId?: string): Promise<TaskTree | TaskTree[]>;
110
+ /**
111
+ * Search tasks by description.
112
+ * Returns tasks matching the query (case-insensitive substring match).
113
+ */
114
+ search(query: string): Promise<Task[]>;
115
+ /**
116
+ * Get progress summary for a milestone or all tasks.
117
+ * Returns aggregate counts: { total, completed, ready, blocked }
118
+ */
119
+ progress(rootId?: string): Promise<TaskProgress>;
86
120
  };
87
121
  //# sourceMappingURL=tasks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/api/tasks.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,KAAK;IAChB;;;OAGG;kBACiB,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAQhD;;OAEG;YACW,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAI/C;;;OAGG;kBACiB,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAWnD;;;OAGG;eACc,MAAM,SAAS,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAS/D;;;;;;;OAOG;cACa,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC;;;;;;;OAOG;iBAEG,MAAM,YACA;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAClD,OAAO,CAAC,IAAI,CAAC;IAWhB;;OAEG;eACc,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC;;OAEG;eACc,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC;;;OAGG;kBACiB,MAAM,aAAa,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7D;;OAEG;oBACmB,MAAM,aAAa,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D;;;OAGG;4BAC2B,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;CAKvE,CAAC"}
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/api/tasks.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAExF;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG,MAAM,GAAG,SAAS,CAAC;AAQxD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IACd;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,KAAK;IAChB;;;OAGG;kBACiB,UAAU,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAgChD;;OAEG;YACW,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAI/C;;;OAGG;kBACiB,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAWnD;;;OAGG;eACc,MAAM,SAAS,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAS/D;;;;;;;OAOG;cACa,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC;;;;;;;OAOG;iBAEG,MAAM,YACA;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAClD,OAAO,CAAC,IAAI,CAAC;IAWhB;;OAEG;eACc,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC;;OAEG;eACc,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC;;;OAGG;kBACiB,MAAM,aAAa,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7D;;OAEG;oBACmB,MAAM,aAAa,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D;;;OAGG;4BAC2B,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAMtE;;;;;;OAMG;kBACiB,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,QAAQ,EAAE,CAAC;IAS3D;;;OAGG;kBACiB,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAI5C;;;OAGG;sBACqB,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAKvD,CAAC"}
package/dist/api/tasks.js CHANGED
@@ -2,6 +2,12 @@
2
2
  * Tasks API - typed wrapper around os task commands
3
3
  */
4
4
  import { callCli } from "../cli.js";
5
+ import { decodeTask, decodeTasks, decodeTaskWithContext, decodeTaskWithContextOrNull, decodeTaskTree, decodeTaskTrees, decodeTaskProgress, } from "../decoder.js";
6
+ const TYPE_TO_DEPTH = {
7
+ milestone: 0,
8
+ task: 1,
9
+ subtask: 2,
10
+ };
5
11
  /**
6
12
  * Tasks API exposed to VM sandbox
7
13
  */
@@ -11,6 +17,16 @@ export const tasks = {
11
17
  * Returns tasks without context chain or inherited learnings.
12
18
  */
13
19
  async list(filter) {
20
+ // Resolve type to depth if provided
21
+ const effectiveDepth = filter?.type !== undefined
22
+ ? TYPE_TO_DEPTH[filter.type]
23
+ : filter?.depth;
24
+ if (filter?.parentId !== undefined && effectiveDepth !== undefined) {
25
+ throw new Error("parentId and depth/type are mutually exclusive - use parentId alone; depth is implied by parent type");
26
+ }
27
+ if (filter?.depth !== undefined && filter?.type !== undefined) {
28
+ throw new Error("depth and type are mutually exclusive - use one or the other");
29
+ }
14
30
  const args = ["task", "list"];
15
31
  if (filter?.parentId)
16
32
  args.push("--parent", filter.parentId);
@@ -18,13 +34,21 @@ export const tasks = {
18
34
  args.push("--ready");
19
35
  if (filter?.completed)
20
36
  args.push("--completed");
21
- return (await callCli(args));
37
+ if (effectiveDepth !== undefined) {
38
+ const depthFlags = {
39
+ 0: "--milestones",
40
+ 1: "--tasks",
41
+ 2: "--subtasks",
42
+ };
43
+ args.push(depthFlags[effectiveDepth]);
44
+ }
45
+ return decodeTasks(await callCli(args)).unwrap("tasks.list");
22
46
  },
23
47
  /**
24
48
  * Get single task with full context chain and inherited learnings.
25
49
  */
26
50
  async get(id) {
27
- return (await callCli(["task", "get", id]));
51
+ return decodeTaskWithContext(await callCli(["task", "get", id])).unwrap("tasks.get");
28
52
  },
29
53
  /**
30
54
  * Create new task.
@@ -41,7 +65,7 @@ export const tasks = {
41
65
  if (input.blockedBy && input.blockedBy.length > 0) {
42
66
  args.push("--blocked-by", input.blockedBy.join(","));
43
67
  }
44
- return (await callCli(args));
68
+ return decodeTask(await callCli(args)).unwrap("tasks.create");
45
69
  },
46
70
  /**
47
71
  * Update existing task.
@@ -57,18 +81,18 @@ export const tasks = {
57
81
  args.push("--priority", String(input.priority));
58
82
  if (input.parentId)
59
83
  args.push("--parent", input.parentId);
60
- return (await callCli(args));
84
+ return decodeTask(await callCli(args)).unwrap("tasks.update");
61
85
  },
62
86
  /**
63
87
  * Mark task as started.
64
88
  * Follows blockers to find startable work, cascades to deepest leaf.
65
- * Creates VCS bookmark for started task.
89
+ * Creates VCS bookmark for started task and records start commit.
66
90
  * Returns the task that was actually started.
67
91
  *
68
92
  * **Requires VCS**: Must be in a jj or git repository.
69
93
  */
70
94
  async start(id) {
71
- return (await callCli(["task", "start", id]));
95
+ return decodeTask(await callCli(["task", "start", id])).unwrap("tasks.start");
72
96
  },
73
97
  /**
74
98
  * Complete task with optional result and learnings.
@@ -87,13 +111,13 @@ export const tasks = {
87
111
  args.push("--learning", learning);
88
112
  }
89
113
  }
90
- return (await callCli(args));
114
+ return decodeTask(await callCli(args)).unwrap("tasks.complete");
91
115
  },
92
116
  /**
93
117
  * Reopen completed task.
94
118
  */
95
119
  async reopen(id) {
96
- return (await callCli(["task", "reopen", id]));
120
+ return decodeTask(await callCli(["task", "reopen", id])).unwrap("tasks.reopen");
97
121
  },
98
122
  /**
99
123
  * Delete task (cascades to children and learnings).
@@ -122,7 +146,39 @@ export const tasks = {
122
146
  const args = ["task", "next-ready"];
123
147
  if (milestoneId)
124
148
  args.push("--milestone", milestoneId);
125
- return (await callCli(args));
149
+ return decodeTaskWithContextOrNull(await callCli(args)).unwrap("tasks.nextReady");
150
+ },
151
+ /**
152
+ * Get task tree structure.
153
+ * If rootId provided, returns single tree rooted at that task.
154
+ * If no rootId, returns array of all milestone trees.
155
+ *
156
+ * **Warning:** Large trees may hit 50k output limit. Prefer scoping to specific milestone.
157
+ */
158
+ async tree(rootId) {
159
+ const args = ["task", "tree"];
160
+ if (rootId) {
161
+ args.push(rootId);
162
+ return decodeTaskTree(await callCli(args)).unwrap("tasks.tree");
163
+ }
164
+ return decodeTaskTrees(await callCli(args)).unwrap("tasks.tree");
165
+ },
166
+ /**
167
+ * Search tasks by description.
168
+ * Returns tasks matching the query (case-insensitive substring match).
169
+ */
170
+ async search(query) {
171
+ return decodeTasks(await callCli(["task", "search", query])).unwrap("tasks.search");
172
+ },
173
+ /**
174
+ * Get progress summary for a milestone or all tasks.
175
+ * Returns aggregate counts: { total, completed, ready, blocked }
176
+ */
177
+ async progress(rootId) {
178
+ const args = ["task", "progress"];
179
+ if (rootId)
180
+ args.push(rootId);
181
+ return decodeTaskProgress(await callCli(args)).unwrap("tasks.progress");
126
182
  },
127
183
  };
128
184
  //# sourceMappingURL=tasks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/api/tasks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/api/tasks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Runtime decoders for CLI JSON output.
3
+ * Validates structure matches expected types at runtime.
4
+ */
5
+ import { Result } from "better-result";
6
+ import { type Task, type TaskWithContext, type Learning, type TaskTree, type TaskProgress } from "./types.js";
7
+ declare const DecodeError_base: import("better-result").TaggedErrorClass<"DecodeError", {
8
+ message: string;
9
+ path?: string;
10
+ }>;
11
+ /**
12
+ * Decode error with path context
13
+ */
14
+ export declare class DecodeError extends DecodeError_base {
15
+ }
16
+ /**
17
+ * Decode a Learning from unknown JSON
18
+ */
19
+ export declare function decodeLearning(v: unknown): Result<Learning, DecodeError>;
20
+ /**
21
+ * Decode a Learning array
22
+ */
23
+ export declare function decodeLearnings(v: unknown): Result<Learning[], DecodeError>;
24
+ /**
25
+ * Decode a Task from unknown JSON
26
+ */
27
+ export declare function decodeTask(v: unknown): Result<Task, DecodeError>;
28
+ /**
29
+ * Decode a Task array
30
+ */
31
+ export declare function decodeTasks(v: unknown): Result<Task[], DecodeError>;
32
+ /**
33
+ * Decode TaskWithContext from unknown JSON
34
+ */
35
+ export declare function decodeTaskWithContext(v: unknown): Result<TaskWithContext, DecodeError>;
36
+ /**
37
+ * Decode nullable TaskWithContext (for nextReady)
38
+ */
39
+ export declare function decodeTaskWithContextOrNull(v: unknown): Result<TaskWithContext | null, DecodeError>;
40
+ /**
41
+ * Decode TaskTree from unknown JSON (recursive)
42
+ */
43
+ export declare function decodeTaskTree(v: unknown): Result<TaskTree, DecodeError>;
44
+ /**
45
+ * Decode TaskTree array (for tree without root ID)
46
+ */
47
+ export declare function decodeTaskTrees(v: unknown): Result<TaskTree[], DecodeError>;
48
+ /**
49
+ * Decode TaskProgress from unknown JSON
50
+ */
51
+ export declare function decodeTaskProgress(v: unknown): Result<TaskProgress, DecodeError>;
52
+ export {};
53
+ //# sourceMappingURL=decoder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decoder.d.ts","sourceRoot":"","sources":["../src/decoder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAe,MAAM,eAAe,CAAC;AACpD,OAAO,EAGL,KAAK,IAAI,EACT,KAAK,eAAe,EACpB,KAAK,QAAQ,EAOb,KAAK,QAAQ,EACb,KAAK,YAAY,EAClB,MAAM,YAAY,CAAC;;aAMT,MAAM;WACR,MAAM;;AALf;;GAEG;AACH,qBAAa,WAAY,SAAQ,gBAG7B;CAAG;AAgCP;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,CA8BxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,EAAE,WAAW,CAAC,CAiB3E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CA6HhE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,WAAW,CAAC,CAiBnE;AA6DD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,eAAe,EAAE,WAAW,CAAC,CA2BtF;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,CAAC,EAAE,OAAO,GACT,MAAM,CAAC,eAAe,GAAG,IAAI,EAAE,WAAW,CAAC,CAG7C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,CAgCxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,EAAE,WAAW,CAAC,CAiB3E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,CAqBhF"}