@whispering233/ai-editor-db 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whispering233/ai-editor-db",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "数据库层:better-sqlite3 连接 / 建表 / 查询",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -25,12 +25,16 @@
25
25
  "postpack": "node ../../scripts/restore-package-json.mjs"
26
26
  },
27
27
  "dependencies": {
28
- "@whispering233/ai-editor-shared": "0.0.2",
28
+ "@whispering233/ai-editor-shared": "0.0.4",
29
29
  "better-sqlite3": "^13.0.0",
30
30
  "nanoid": "^5.1.0"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/better-sqlite3": "^7.6.13",
34
34
  "typescript": "^5.8.0"
35
+ },
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "https://github.com/whispering233/ai-editor"
35
39
  }
36
40
  }
@@ -1,15 +0,0 @@
1
- /**
2
- * 原子写 JSON 文件(决策 11):
3
- * 1. 写同目录临时文件 `{filePath}.tmp`(writeSync 到已打开的 fd)
4
- * 2. fsync 数据落盘(保证 rename 后文件内容完整,崩溃不产生半写文件)
5
- * 3. rename 覆盖目标文件(同文件系统内原子操作)
6
- *
7
- * 任一步抛错:原文件保持完好;临时文件可能残留(由调用方/启动清理兜底)。
8
- */
9
- export declare function writeJsonAtomic(filePath: string, data: unknown): void;
10
- /**
11
- * 读取 JSON 文件:文件不存在返回 null,存在则 JSON.parse 并返回(parse 失败抛错,不静默吞)。
12
- * 用于 loadOutlineFile / loadProjectFile 的统一入口。
13
- */
14
- export declare function readJsonFile<T>(filePath: string): T | null;
15
- //# sourceMappingURL=atomic.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"atomic.d.ts","sourceRoot":"","sources":["../../src/queries/atomic.ts"],"names":[],"mappings":"AAOA;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAWrE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAW1D"}
@@ -1,44 +0,0 @@
1
- // @ai-editor/db JSON 文件原子读写辅助(T2.2)
2
- // 决策 11:outline.json / project.json 保存必须「写临时文件 → fsync → rename 覆盖」,
3
- // 保证崩溃/断电时磁盘上要么是旧文件要么是新文件;禁止直接覆盖写。
4
- // 时间约定(schema.md 第 16 行):时间字段由应用层写入 ISO 8601,本模块只负责文件 I/O。
5
- import { closeSync, fsyncSync, openSync, readFileSync, renameSync, writeSync } from "node:fs";
6
- /**
7
- * 原子写 JSON 文件(决策 11):
8
- * 1. 写同目录临时文件 `{filePath}.tmp`(writeSync 到已打开的 fd)
9
- * 2. fsync 数据落盘(保证 rename 后文件内容完整,崩溃不产生半写文件)
10
- * 3. rename 覆盖目标文件(同文件系统内原子操作)
11
- *
12
- * 任一步抛错:原文件保持完好;临时文件可能残留(由调用方/启动清理兜底)。
13
- */
14
- export function writeJsonAtomic(filePath, data) {
15
- const tmpPath = `${filePath}.tmp`;
16
- const content = `${JSON.stringify(data, null, 2)}\n`;
17
- const fd = openSync(tmpPath, "w");
18
- try {
19
- writeSync(fd, content);
20
- fsyncSync(fd);
21
- }
22
- finally {
23
- closeSync(fd);
24
- }
25
- renameSync(tmpPath, filePath);
26
- }
27
- /**
28
- * 读取 JSON 文件:文件不存在返回 null,存在则 JSON.parse 并返回(parse 失败抛错,不静默吞)。
29
- * 用于 loadOutlineFile / loadProjectFile 的统一入口。
30
- */
31
- export function readJsonFile(filePath) {
32
- let raw;
33
- try {
34
- raw = readFileSync(filePath, "utf8");
35
- }
36
- catch (err) {
37
- if (err.code === "ENOENT") {
38
- return null;
39
- }
40
- throw err;
41
- }
42
- return JSON.parse(raw);
43
- }
44
- //# sourceMappingURL=atomic.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"atomic.js","sourceRoot":"","sources":["../../src/queries/atomic.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,qEAAqE;AACrE,mCAAmC;AACnC,2DAA2D;AAE3D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAE9F;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,IAAa;IAC7D,MAAM,OAAO,GAAG,GAAG,QAAQ,MAAM,CAAC;IAClC,MAAM,OAAO,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;IACrD,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC;QACH,SAAS,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QACvB,SAAS,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;YAAS,CAAC;QACT,SAAS,CAAC,EAAE,CAAC,CAAC;IAChB,CAAC;IACD,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAI,QAAgB;IAC9C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAM,CAAC;AAC9B,CAAC"}
@@ -1,48 +0,0 @@
1
- import type { OutlineFileNode, OutlineFileTree, OutlineFileVolume } from "@ai-editor/shared";
2
- /** outline.json 文件名(与 project.json / data.db 并列的项目数据文件,schema.md 第 3-14 行) */
3
- export declare const OUTLINE_FILE_NAME = "outline.json";
4
- /** 大纲节点或树根的公共形态(findOutlineNode 的 parent 引用用) */
5
- export type OutlineParent = OutlineFileTree | OutlineFileNode;
6
- /**
7
- * 轻量结构校验:是否为合法 OutlineFileTree(根 id/type、schema_version、children 数组)。
8
- * shared 未提供 file 形态的校验函数(T1.3 只做字段映射),此处守卫 root 级形状即可,
9
- * 节点级字段由写入方(服务端)保证。
10
- */
11
- export declare function isOutlineFileTree(value: unknown): value is OutlineFileTree;
12
- /**
13
- * 读取 outline.json:文件不存在返回 null(由调用方决定初始化,如 initOutlineFile);
14
- * 文件存在但结构非法则抛错(不静默吞坏数据)。
15
- */
16
- export declare function loadOutlineFile(dir: string): OutlineFileTree | null;
17
- /**
18
- * 原子写 outline.json(决策 11:临时文件 + fsync + rename)。
19
- * 禁止直接覆盖原文件。
20
- */
21
- export declare function saveOutlineFile(dir: string, tree: OutlineFileTree): void;
22
- /**
23
- * 首次初始化:创建空根树(决策 19:严格三层 root → volume → chapter → scene,无游离节点)
24
- * 并原子写入;顶层 schema_version 与 project.json / data.db 的 user_version 同步(决策 13)。
25
- */
26
- export declare function initOutlineFile(dir: string): OutlineFileTree;
27
- /**
28
- * 递归查找节点:返回 { node, parent }(parent 为直接父引用,root 的子节点 parent 为树根)。
29
- * 未找到返回 null。供 updateOutlineNode 与后续大纲操作(T2.7 移动/删除)复用。
30
- */
31
- export declare function findOutlineNode(tree: OutlineFileTree, id: string): {
32
- node: OutlineFileNode;
33
- parent: OutlineParent | null;
34
- } | null;
35
- /**
36
- * 根到节点的路径 id 数组(含树根 "root" 与节点自身),如 ["root", "vol-1", "ch-1", "sc-1"]。
37
- * 未找到返回 null。T2.7 大纲操作(移动/删除的祖先链校验)复用。
38
- */
39
- export declare function getNodePathIds(tree: OutlineFileTree, id: string): string[] | null;
40
- /**
41
- * 更新大纲节点:读树 → 定位节点 → 应用 updater 修改 → 统一更新该节点 updated_at(决策 19:
42
- * 节点任何字段变更——title/summary/children 重排——都在原子写流程中刷新版本戳)→ 原子写回。
43
- * 返回更新后的整树。outline.json 不存在或节点未找到则抛错。
44
- */
45
- export declare function updateOutlineNode(dir: string, nodeId: string, updater: (node: OutlineFileNode) => void): OutlineFileTree;
46
- /** 便捷类型导出:卷节点(T2.7 移动操作等会用到) */
47
- export type { OutlineFileVolume };
48
- //# sourceMappingURL=outline.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"outline.d.ts","sourceRoot":"","sources":["../../src/queries/outline.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAI7F,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD,iDAAiD;AACjD,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,eAAe,CAAC;AAE9D;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAM1E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAUnE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAExE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAS5D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,eAAe,EACrB,EAAE,EAAE,MAAM,GACT;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAQhE;AAuBD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAMjF;AAiBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,GACvC,eAAe,CAajB;AAED,gCAAgC;AAChC,YAAY,EAAE,iBAAiB,EAAE,CAAC"}
@@ -1,134 +0,0 @@
1
- // @ai-editor/db 大纲 JSON 存储(outline.json,T2.2)
2
- //
3
- // 契约来源:doc/database/schema.md(outline.json 第 123-155 行)、决策 11(原子写)、决策 19(节点版本戳)。
4
- // 存储形态为 OutlineFileTree(snake_case,shared 定义);API 形态转换(mapOutlineFileToTree 等)在
5
- // shared/utils/mapping.ts,由上层(server)在返回前调用,本模块只做文件形态的读写与节点操作。
6
- //
7
- // 时间约定:节点 updated_at 由本模块在原子写流程中统一更新(决策 19),应用层写入 ISO 8601。
8
- import { join } from "node:path";
9
- import { SCHEMA_VERSION } from "../schema";
10
- import { readJsonFile, writeJsonAtomic } from "./atomic";
11
- /** outline.json 文件名(与 project.json / data.db 并列的项目数据文件,schema.md 第 3-14 行) */
12
- export const OUTLINE_FILE_NAME = "outline.json";
13
- /**
14
- * 轻量结构校验:是否为合法 OutlineFileTree(根 id/type、schema_version、children 数组)。
15
- * shared 未提供 file 形态的校验函数(T1.3 只做字段映射),此处守卫 root 级形状即可,
16
- * 节点级字段由写入方(服务端)保证。
17
- */
18
- export function isOutlineFileTree(value) {
19
- if (typeof value !== "object" || value === null) {
20
- return false;
21
- }
22
- const v = value;
23
- return v.id === "root" && v.type === "root" && typeof v.schema_version === "number" && Array.isArray(v.children);
24
- }
25
- /**
26
- * 读取 outline.json:文件不存在返回 null(由调用方决定初始化,如 initOutlineFile);
27
- * 文件存在但结构非法则抛错(不静默吞坏数据)。
28
- */
29
- export function loadOutlineFile(dir) {
30
- const filePath = join(dir, OUTLINE_FILE_NAME);
31
- const raw = readJsonFile(filePath);
32
- if (raw === null) {
33
- return null;
34
- }
35
- if (!isOutlineFileTree(raw)) {
36
- throw new Error(`loadOutlineFile: ${filePath} 结构非法(非 OutlineFileTree)`);
37
- }
38
- return raw;
39
- }
40
- /**
41
- * 原子写 outline.json(决策 11:临时文件 + fsync + rename)。
42
- * 禁止直接覆盖原文件。
43
- */
44
- export function saveOutlineFile(dir, tree) {
45
- writeJsonAtomic(join(dir, OUTLINE_FILE_NAME), tree);
46
- }
47
- /**
48
- * 首次初始化:创建空根树(决策 19:严格三层 root → volume → chapter → scene,无游离节点)
49
- * 并原子写入;顶层 schema_version 与 project.json / data.db 的 user_version 同步(决策 13)。
50
- */
51
- export function initOutlineFile(dir) {
52
- const tree = {
53
- id: "root",
54
- type: "root",
55
- schema_version: SCHEMA_VERSION,
56
- children: [],
57
- };
58
- saveOutlineFile(dir, tree);
59
- return tree;
60
- }
61
- /**
62
- * 递归查找节点:返回 { node, parent }(parent 为直接父引用,root 的子节点 parent 为树根)。
63
- * 未找到返回 null。供 updateOutlineNode 与后续大纲操作(T2.7 移动/删除)复用。
64
- */
65
- export function findOutlineNode(tree, id) {
66
- for (const child of tree.children) {
67
- const found = findNodeRecursive(child, id, tree);
68
- if (found) {
69
- return found;
70
- }
71
- }
72
- return null;
73
- }
74
- /** findOutlineNode 的递归实现(scene 为叶子,无 children 分支) */
75
- function findNodeRecursive(node, id, parent) {
76
- if (node.id === id) {
77
- return { node, parent };
78
- }
79
- if (node.type === "scene") {
80
- return null;
81
- }
82
- for (const child of node.children ?? []) {
83
- const found = findNodeRecursive(child, id, node);
84
- if (found) {
85
- return found;
86
- }
87
- }
88
- return null;
89
- }
90
- /**
91
- * 根到节点的路径 id 数组(含树根 "root" 与节点自身),如 ["root", "vol-1", "ch-1", "sc-1"]。
92
- * 未找到返回 null。T2.7 大纲操作(移动/删除的祖先链校验)复用。
93
- */
94
- export function getNodePathIds(tree, id) {
95
- const path = [];
96
- if (collectPath(tree, id, path)) {
97
- return path;
98
- }
99
- return null;
100
- }
101
- /** getNodePathIds 的递归实现:回溯式收集路径(先压栈,失败弹栈) */
102
- function collectPath(node, id, path) {
103
- if (node.type === "scene") {
104
- return false;
105
- }
106
- for (const child of node.children ?? []) {
107
- path.push(child.id);
108
- if (child.id === id || (child.type !== "scene" && collectPath(child, id, path))) {
109
- return true;
110
- }
111
- path.pop();
112
- }
113
- return false;
114
- }
115
- /**
116
- * 更新大纲节点:读树 → 定位节点 → 应用 updater 修改 → 统一更新该节点 updated_at(决策 19:
117
- * 节点任何字段变更——title/summary/children 重排——都在原子写流程中刷新版本戳)→ 原子写回。
118
- * 返回更新后的整树。outline.json 不存在或节点未找到则抛错。
119
- */
120
- export function updateOutlineNode(dir, nodeId, updater) {
121
- const tree = loadOutlineFile(dir);
122
- if (!tree) {
123
- throw new Error(`updateOutlineNode: ${join(dir, OUTLINE_FILE_NAME)} 不存在`);
124
- }
125
- const found = findOutlineNode(tree, nodeId);
126
- if (!found) {
127
- throw new Error(`updateOutlineNode: 未找到节点 ${nodeId}`);
128
- }
129
- updater(found.node);
130
- found.node.updated_at = new Date().toISOString();
131
- saveOutlineFile(dir, tree);
132
- return tree;
133
- }
134
- //# sourceMappingURL=outline.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"outline.js","sourceRoot":"","sources":["../../src/queries/outline.ts"],"names":[],"mappings":"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"}
@@ -1,21 +0,0 @@
1
- import { type ProjectFileConfig, type ProjectLanguage } from "@ai-editor/shared";
2
- /** project.json 文件名 */
3
- export declare const PROJECT_FILE_NAME = "project.json";
4
- /** 读取 project.json:文件不存在返回 null(由调用方决定初始化) */
5
- export declare function loadProjectFile(dir: string): ProjectFileConfig | null;
6
- /** 原子写 project.json(决策 11:临时文件 + fsync + rename,与 outline.json 同款) */
7
- export declare function saveProjectFile(dir: string, config: ProjectFileConfig): void;
8
- /**
9
- * 首次初始化 project.json(决策 8:自动创建,此后跨启动稳定):
10
- * - id:proj- 前缀 + nanoid(shared generateProjectId,跨启动稳定,画布布局 localStorage 隔离 key)
11
- * - created_at / updated_at:ISO 8601 应用层写入(schema.md 第 16 行),初始两者相同
12
- * - schema_version:与 outline.json 顶层 / data.db user_version 同步(决策 13)
13
- * - current_position:null(未设置)
14
- * 写入后返回配置对象(调用方持有即可,无需再读)。
15
- */
16
- export declare function initProjectFile(dir: string, init: {
17
- name: string;
18
- language: ProjectLanguage;
19
- prompt: string;
20
- }): ProjectFileConfig;
21
- //# sourceMappingURL=project.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/queries/project.ts"],"names":[],"mappings":"AAOA,OAAO,EAAqB,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIpG,uBAAuB;AACvB,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD,8CAA8C;AAC9C,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAErE;AAED,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAE5E;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAChE,iBAAiB,CAcnB"}
@@ -1,43 +0,0 @@
1
- // @ai-editor/db 项目配置 JSON 存储(project.json,T2.2)
2
- //
3
- // 契约来源:doc/database/schema.md(project.json 第 157-186 行)、决策 8(首次初始化自动创建)、
4
- // 决策 11(同款原子写)、决策 13(schema_version 与 outline.json / data.db user_version 同步)。
5
- // 硬约束(决策 17):DeepSeek API key 绝不写入本文件。
6
- import { join } from "node:path";
7
- import { generateProjectId } from "@ai-editor/shared";
8
- import { SCHEMA_VERSION } from "../schema";
9
- import { readJsonFile, writeJsonAtomic } from "./atomic";
10
- /** project.json 文件名 */
11
- export const PROJECT_FILE_NAME = "project.json";
12
- /** 读取 project.json:文件不存在返回 null(由调用方决定初始化) */
13
- export function loadProjectFile(dir) {
14
- return readJsonFile(join(dir, PROJECT_FILE_NAME));
15
- }
16
- /** 原子写 project.json(决策 11:临时文件 + fsync + rename,与 outline.json 同款) */
17
- export function saveProjectFile(dir, config) {
18
- writeJsonAtomic(join(dir, PROJECT_FILE_NAME), config);
19
- }
20
- /**
21
- * 首次初始化 project.json(决策 8:自动创建,此后跨启动稳定):
22
- * - id:proj- 前缀 + nanoid(shared generateProjectId,跨启动稳定,画布布局 localStorage 隔离 key)
23
- * - created_at / updated_at:ISO 8601 应用层写入(schema.md 第 16 行),初始两者相同
24
- * - schema_version:与 outline.json 顶层 / data.db user_version 同步(决策 13)
25
- * - current_position:null(未设置)
26
- * 写入后返回配置对象(调用方持有即可,无需再读)。
27
- */
28
- export function initProjectFile(dir, init) {
29
- const now = new Date().toISOString();
30
- const config = {
31
- id: generateProjectId(),
32
- name: init.name,
33
- language: init.language,
34
- prompt: init.prompt,
35
- schema_version: SCHEMA_VERSION,
36
- current_position: null,
37
- created_at: now,
38
- updated_at: now,
39
- };
40
- saveProjectFile(dir, config);
41
- return config;
42
- }
43
- //# sourceMappingURL=project.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/queries/project.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,EAAE;AACF,yEAAyE;AACzE,+EAA+E;AAC/E,uCAAuC;AAEvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,iBAAiB,EAAgD,MAAM,mBAAmB,CAAC;AACpG,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEzD,uBAAuB;AACvB,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAEhD,8CAA8C;AAC9C,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,OAAO,YAAY,CAAoB,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,MAAyB;IACpE,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAW,EACX,IAAiE;IAEjE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,MAAM,GAAsB;QAChC,EAAE,EAAE,iBAAiB,EAAE;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,cAAc,EAAE,cAAc;QAC9B,gBAAgB,EAAE,IAAI;QACtB,UAAU,EAAE,GAAG;QACf,UAAU,EAAE,GAAG;KAChB,CAAC;IACF,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC;AAChB,CAAC"}