@mka-rainmaker/ama 0.1.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/LICENSE +21 -0
- package/README.md +149 -0
- package/dist/analyzers/baseline/analyzer.d.ts +47 -0
- package/dist/analyzers/baseline/analyzer.d.ts.map +1 -0
- package/dist/analyzers/baseline/analyzer.js +84 -0
- package/dist/analyzers/baseline/analyzer.js.map +1 -0
- package/dist/analyzers/baseline/c.d.ts +12 -0
- package/dist/analyzers/baseline/c.d.ts.map +1 -0
- package/dist/analyzers/baseline/c.js +56 -0
- package/dist/analyzers/baseline/c.js.map +1 -0
- package/dist/analyzers/baseline/config.d.ts +21 -0
- package/dist/analyzers/baseline/config.d.ts.map +1 -0
- package/dist/analyzers/baseline/config.js +32 -0
- package/dist/analyzers/baseline/config.js.map +1 -0
- package/dist/analyzers/baseline/csharp.d.ts +9 -0
- package/dist/analyzers/baseline/csharp.d.ts.map +1 -0
- package/dist/analyzers/baseline/csharp.js +107 -0
- package/dist/analyzers/baseline/csharp.js.map +1 -0
- package/dist/analyzers/baseline/go.d.ts +11 -0
- package/dist/analyzers/baseline/go.d.ts.map +1 -0
- package/dist/analyzers/baseline/go.js +66 -0
- package/dist/analyzers/baseline/go.js.map +1 -0
- package/dist/analyzers/baseline/java.d.ts +9 -0
- package/dist/analyzers/baseline/java.d.ts.map +1 -0
- package/dist/analyzers/baseline/java.js +50 -0
- package/dist/analyzers/baseline/java.js.map +1 -0
- package/dist/analyzers/baseline/javascript.d.ts +10 -0
- package/dist/analyzers/baseline/javascript.d.ts.map +1 -0
- package/dist/analyzers/baseline/javascript.js +55 -0
- package/dist/analyzers/baseline/javascript.js.map +1 -0
- package/dist/analyzers/baseline/kotlin.d.ts +11 -0
- package/dist/analyzers/baseline/kotlin.d.ts.map +1 -0
- package/dist/analyzers/baseline/kotlin.js +67 -0
- package/dist/analyzers/baseline/kotlin.js.map +1 -0
- package/dist/analyzers/baseline/paths.d.ts +6 -0
- package/dist/analyzers/baseline/paths.d.ts.map +1 -0
- package/dist/analyzers/baseline/paths.js +17 -0
- package/dist/analyzers/baseline/paths.js.map +1 -0
- package/dist/analyzers/baseline/php.d.ts +11 -0
- package/dist/analyzers/baseline/php.d.ts.map +1 -0
- package/dist/analyzers/baseline/php.js +76 -0
- package/dist/analyzers/baseline/php.js.map +1 -0
- package/dist/analyzers/baseline/python.d.ts +10 -0
- package/dist/analyzers/baseline/python.d.ts.map +1 -0
- package/dist/analyzers/baseline/python.js +63 -0
- package/dist/analyzers/baseline/python.js.map +1 -0
- package/dist/analyzers/baseline/rust.d.ts +10 -0
- package/dist/analyzers/baseline/rust.d.ts.map +1 -0
- package/dist/analyzers/baseline/rust.js +45 -0
- package/dist/analyzers/baseline/rust.js.map +1 -0
- package/dist/analyzers/baseline/swift.d.ts +11 -0
- package/dist/analyzers/baseline/swift.d.ts.map +1 -0
- package/dist/analyzers/baseline/swift.js +19 -0
- package/dist/analyzers/baseline/swift.js.map +1 -0
- package/dist/analyzers/baseline/treesitter.d.ts +11 -0
- package/dist/analyzers/baseline/treesitter.d.ts.map +1 -0
- package/dist/analyzers/baseline/treesitter.js +87 -0
- package/dist/analyzers/baseline/treesitter.js.map +1 -0
- package/dist/analyzers/baseline/walk.d.ts +26 -0
- package/dist/analyzers/baseline/walk.d.ts.map +1 -0
- package/dist/analyzers/baseline/walk.js +76 -0
- package/dist/analyzers/baseline/walk.js.map +1 -0
- package/dist/analyzers/registry.d.ts +19 -0
- package/dist/analyzers/registry.d.ts.map +1 -0
- package/dist/analyzers/registry.js +43 -0
- package/dist/analyzers/registry.js.map +1 -0
- package/dist/analyzers/sfc/analyzer.d.ts +17 -0
- package/dist/analyzers/sfc/analyzer.d.ts.map +1 -0
- package/dist/analyzers/sfc/analyzer.js +141 -0
- package/dist/analyzers/sfc/analyzer.js.map +1 -0
- package/dist/analyzers/sidecar/analyzer.d.ts +29 -0
- package/dist/analyzers/sidecar/analyzer.d.ts.map +1 -0
- package/dist/analyzers/sidecar/analyzer.js +114 -0
- package/dist/analyzers/sidecar/analyzer.js.map +1 -0
- package/dist/analyzers/sidecar/protocol.d.ts +508 -0
- package/dist/analyzers/sidecar/protocol.d.ts.map +1 -0
- package/dist/analyzers/sidecar/protocol.js +102 -0
- package/dist/analyzers/sidecar/protocol.js.map +1 -0
- package/dist/analyzers/types.d.ts +46 -0
- package/dist/analyzers/types.d.ts.map +1 -0
- package/dist/analyzers/types.js +2 -0
- package/dist/analyzers/types.js.map +1 -0
- package/dist/analyzers/typescript/analyzer.d.ts +126 -0
- package/dist/analyzers/typescript/analyzer.d.ts.map +1 -0
- package/dist/analyzers/typescript/analyzer.js +1600 -0
- package/dist/analyzers/typescript/analyzer.js.map +1 -0
- package/dist/cli/commands/cycles.d.ts +6 -0
- package/dist/cli/commands/cycles.d.ts.map +1 -0
- package/dist/cli/commands/cycles.js +27 -0
- package/dist/cli/commands/cycles.js.map +1 -0
- package/dist/cli/commands/files.d.ts +6 -0
- package/dist/cli/commands/files.d.ts.map +1 -0
- package/dist/cli/commands/files.js +33 -0
- package/dist/cli/commands/files.js.map +1 -0
- package/dist/cli/commands/impact.d.ts +18 -0
- package/dist/cli/commands/impact.d.ts.map +1 -0
- package/dist/cli/commands/impact.js +113 -0
- package/dist/cli/commands/impact.js.map +1 -0
- package/dist/cli/commands/lifecycle.d.ts +5 -0
- package/dist/cli/commands/lifecycle.d.ts.map +1 -0
- package/dist/cli/commands/lifecycle.js +83 -0
- package/dist/cli/commands/lifecycle.js.map +1 -0
- package/dist/cli/commands/query.d.ts +31 -0
- package/dist/cli/commands/query.d.ts.map +1 -0
- package/dist/cli/commands/query.js +187 -0
- package/dist/cli/commands/query.js.map +1 -0
- package/dist/cli/commands/search.d.ts +21 -0
- package/dist/cli/commands/search.d.ts.map +1 -0
- package/dist/cli/commands/search.js +160 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/commands/status.d.ts +6 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +63 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/sync.d.ts +6 -0
- package/dist/cli/commands/sync.d.ts.map +1 -0
- package/dist/cli/commands/sync.js +57 -0
- package/dist/cli/commands/sync.js.map +1 -0
- package/dist/cli/emit.d.ts +9 -0
- package/dist/cli/emit.d.ts.map +1 -0
- package/dist/cli/emit.js +10 -0
- package/dist/cli/emit.js.map +1 -0
- package/dist/cli/index.d.ts +37 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +128 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/paths.d.ts +7 -0
- package/dist/cli/paths.d.ts.map +1 -0
- package/dist/cli/paths.js +10 -0
- package/dist/cli/paths.js.map +1 -0
- package/dist/cli/query-runner.d.ts +13 -0
- package/dist/cli/query-runner.d.ts.map +1 -0
- package/dist/cli/query-runner.js +33 -0
- package/dist/cli/query-runner.js.map +1 -0
- package/dist/graph/dispatch.d.ts +17 -0
- package/dist/graph/dispatch.d.ts.map +1 -0
- package/dist/graph/dispatch.js +82 -0
- package/dist/graph/dispatch.js.map +1 -0
- package/dist/graph/id.d.ts +19 -0
- package/dist/graph/id.d.ts.map +1 -0
- package/dist/graph/id.js +17 -0
- package/dist/graph/id.js.map +1 -0
- package/dist/graph/index.d.ts +6 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +4 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/types.d.ts +71 -0
- package/dist/graph/types.d.ts.map +1 -0
- package/dist/graph/types.js +52 -0
- package/dist/graph/types.js.map +1 -0
- package/dist/indexer/debouncer.d.ts +32 -0
- package/dist/indexer/debouncer.d.ts.map +1 -0
- package/dist/indexer/debouncer.js +81 -0
- package/dist/indexer/debouncer.js.map +1 -0
- package/dist/indexer/ignore.d.ts +55 -0
- package/dist/indexer/ignore.d.ts.map +1 -0
- package/dist/indexer/ignore.js +170 -0
- package/dist/indexer/ignore.js.map +1 -0
- package/dist/indexer/indexer.d.ts +112 -0
- package/dist/indexer/indexer.d.ts.map +1 -0
- package/dist/indexer/indexer.js +392 -0
- package/dist/indexer/indexer.js.map +1 -0
- package/dist/indexer/watcher.d.ts +50 -0
- package/dist/indexer/watcher.d.ts.map +1 -0
- package/dist/indexer/watcher.js +86 -0
- package/dist/indexer/watcher.js.map +1 -0
- package/dist/mcp/build-info.d.ts +16 -0
- package/dist/mcp/build-info.d.ts.map +1 -0
- package/dist/mcp/build-info.js +54 -0
- package/dist/mcp/build-info.js.map +1 -0
- package/dist/mcp/http.d.ts +18 -0
- package/dist/mcp/http.d.ts.map +1 -0
- package/dist/mcp/http.js +145 -0
- package/dist/mcp/http.js.map +1 -0
- package/dist/mcp/server.d.ts +22 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +401 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/session.d.ts +155 -0
- package/dist/mcp/session.d.ts.map +1 -0
- package/dist/mcp/session.js +319 -0
- package/dist/mcp/session.js.map +1 -0
- package/dist/query/service.d.ts +329 -0
- package/dist/query/service.d.ts.map +1 -0
- package/dist/query/service.js +959 -0
- package/dist/query/service.js.map +1 -0
- package/dist/runtime/entrypoint.d.ts +11 -0
- package/dist/runtime/entrypoint.d.ts.map +1 -0
- package/dist/runtime/entrypoint.js +22 -0
- package/dist/runtime/entrypoint.js.map +1 -0
- package/dist/runtime/quiet-sqlite-warning.d.ts +14 -0
- package/dist/runtime/quiet-sqlite-warning.d.ts.map +1 -0
- package/dist/runtime/quiet-sqlite-warning.js +26 -0
- package/dist/runtime/quiet-sqlite-warning.js.map +1 -0
- package/dist/runtime/wasm-tier.d.ts +2 -0
- package/dist/runtime/wasm-tier.d.ts.map +1 -0
- package/dist/runtime/wasm-tier.js +54 -0
- package/dist/runtime/wasm-tier.js.map +1 -0
- package/dist/store/memory.d.ts +54 -0
- package/dist/store/memory.d.ts.map +1 -0
- package/dist/store/memory.js +210 -0
- package/dist/store/memory.js.map +1 -0
- package/dist/store/sqlite.d.ts +38 -0
- package/dist/store/sqlite.d.ts.map +1 -0
- package/dist/store/sqlite.js +298 -0
- package/dist/store/sqlite.js.map +1 -0
- package/dist/store/types.d.ts +76 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +2 -0
- package/dist/store/types.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collapses bursts of file-change events into batched syncs. Each `notify(rel)`
|
|
3
|
+
* adds the path to a pending set and (re)arms a trailing timer; when the window
|
|
4
|
+
* elapses quietly, every pending path is synced once. A single flush runs at a
|
|
5
|
+
* time — paths that arrive while one is in progress are batched into the next —
|
|
6
|
+
* and a failing sync is isolated so the rest of the batch still runs.
|
|
7
|
+
*
|
|
8
|
+
* The debounce window collapses the several `fs.watch` events a single save can
|
|
9
|
+
* emit into one re-index. Drives ama-gd5.3's auto-sync; reusable anywhere a
|
|
10
|
+
* stream of keyed events should settle before acting.
|
|
11
|
+
*/
|
|
12
|
+
export class Debouncer {
|
|
13
|
+
sync;
|
|
14
|
+
windowMs;
|
|
15
|
+
pending = new Set();
|
|
16
|
+
timer;
|
|
17
|
+
flushing = false;
|
|
18
|
+
constructor(sync, windowMs) {
|
|
19
|
+
this.sync = sync;
|
|
20
|
+
this.windowMs = windowMs;
|
|
21
|
+
}
|
|
22
|
+
/** Record a changed path and (re)start the trailing window. */
|
|
23
|
+
notify(rel) {
|
|
24
|
+
this.pending.add(rel);
|
|
25
|
+
this.arm();
|
|
26
|
+
}
|
|
27
|
+
/** Pending paths not yet synced — for surfacing sync status (ama-gd5.6). */
|
|
28
|
+
get pendingCount() {
|
|
29
|
+
return this.pending.size;
|
|
30
|
+
}
|
|
31
|
+
/** The actual queued paths — for naming stale files in a banner (ama-gd5.5). */
|
|
32
|
+
pendingPaths() {
|
|
33
|
+
return [...this.pending];
|
|
34
|
+
}
|
|
35
|
+
/** Cancel the pending window. Does not flush — stopping accepts staleness. */
|
|
36
|
+
stop() {
|
|
37
|
+
if (this.timer !== undefined) {
|
|
38
|
+
clearTimeout(this.timer);
|
|
39
|
+
this.timer = undefined;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
arm() {
|
|
43
|
+
if (this.timer !== undefined)
|
|
44
|
+
clearTimeout(this.timer);
|
|
45
|
+
this.timer = setTimeout(() => {
|
|
46
|
+
this.timer = undefined;
|
|
47
|
+
void this.flush();
|
|
48
|
+
}, this.windowMs);
|
|
49
|
+
}
|
|
50
|
+
async flush() {
|
|
51
|
+
// A flush is already running; let it pick up what arrived, or re-arm so the
|
|
52
|
+
// next window drains anything it could not.
|
|
53
|
+
if (this.flushing) {
|
|
54
|
+
if (this.pending.size > 0)
|
|
55
|
+
this.arm();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (this.pending.size === 0)
|
|
59
|
+
return;
|
|
60
|
+
this.flushing = true;
|
|
61
|
+
const batch = [...this.pending];
|
|
62
|
+
this.pending.clear();
|
|
63
|
+
try {
|
|
64
|
+
for (const rel of batch) {
|
|
65
|
+
try {
|
|
66
|
+
await this.sync(rel);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
console.error(`[ama] auto-sync failed for ${rel}:`, err);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
this.flushing = false;
|
|
75
|
+
// Edits that landed during the flush get their own window.
|
|
76
|
+
if (this.pending.size > 0)
|
|
77
|
+
this.arm();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=debouncer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debouncer.js","sourceRoot":"","sources":["../../src/indexer/debouncer.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,SAAS;IAMD;IACA;IANF,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,KAAK,CAAiC;IACtC,QAAQ,GAAG,KAAK,CAAC;IAEzB,YACmB,IAAY,EACZ,QAAgB;QADhB,SAAI,GAAJ,IAAI,CAAQ;QACZ,aAAQ,GAAR,QAAQ,CAAQ;IAChC,CAAC;IAEJ,+DAA+D;IAC/D,MAAM,CAAC,GAAW;QAChB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,GAAG,EAAE,CAAC;IACb,CAAC;IAED,4EAA4E;IAC5E,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED,gFAAgF;IAChF,YAAY;QACV,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,8EAA8E;IAC9E,IAAI;QACF,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACzB,CAAC;IACH,CAAC;IAEO,GAAG;QACT,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvD,IAAI,CAAC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC3B,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;YACvB,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpB,CAAC;IAEO,KAAK,CAAC,KAAK;QACjB,4EAA4E;QAC5E,4CAA4C;QAC5C,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC;gBAAE,IAAI,CAAC,GAAG,EAAE,CAAC;YACtC,OAAO;QACT,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO;QACpC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC;YACH,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;gBACxB,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACvB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,8BAA8B,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC;gBAC3D,CAAC;YACH,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;YACtB,2DAA2D;YAC3D,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC;gBAAE,IAAI,CAAC,GAAG,EAAE,CAAC;QACxC,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Directories never worth indexing or watching. Dot-entries (`.git`, `.beads`,
|
|
3
|
+
* `.vscode`, …) are skipped separately. Shared by the indexer's file discovery
|
|
4
|
+
* and the file watcher so the set of files we *watch* matches what we *index*.
|
|
5
|
+
*/
|
|
6
|
+
export declare const IGNORED_DIRS: Set<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Files larger than this are skipped by both discovery and the watcher — a
|
|
9
|
+
* minified bundle or data blob isn't worth parsing and risks a memory blowup.
|
|
10
|
+
* Shared so the initial index and the watcher agree on what's too big; without
|
|
11
|
+
* it a huge file would be indexed on first build but skipped on re-index.
|
|
12
|
+
*/
|
|
13
|
+
export declare const MAX_FILE_SIZE_BYTES: number;
|
|
14
|
+
/** Resolved ignore patterns for one root: exact segment names and name globs. */
|
|
15
|
+
export interface IgnoreRules {
|
|
16
|
+
/** Dir/file names ignored at any depth (IGNORED_DIRS + .gitignore bare names). */
|
|
17
|
+
names: Set<string>;
|
|
18
|
+
/** Name globs from .gitignore (e.g. `*.gen.ts`), each anchored to a full segment. */
|
|
19
|
+
globs: RegExp[];
|
|
20
|
+
/** Root-anchored patterns (a leading or embedded slash, e.g. `/build`,
|
|
21
|
+
* `pkg/internal`), matched against the full repo-relative path. (ama-yhu) */
|
|
22
|
+
anchored: RegExp[];
|
|
23
|
+
/** `!` negation patterns (full-path regexes): a path matched by an ignore rule
|
|
24
|
+
* is re-included if it also matches one of these. A negation always wins (so a
|
|
25
|
+
* rare re-ignore-after-negation over-includes rather than over-excludes —
|
|
26
|
+
* fail-toward-inclusion); nested .gitignore is a follow-up. (ama-d28) */
|
|
27
|
+
negations: RegExp[];
|
|
28
|
+
}
|
|
29
|
+
/** The built-in ignores, used when no `.gitignore` has been loaded. */
|
|
30
|
+
export declare const BASE_IGNORE_RULES: IgnoreRules;
|
|
31
|
+
/**
|
|
32
|
+
* Read `<root>/.gitignore` and fold a *safe subset* of its patterns into the
|
|
33
|
+
* built-in ignores. Blank lines and `#` comments are skipped; nested `.gitignore`
|
|
34
|
+
* files are a follow-up (ama-d28). A bare `name`/`name/` ignores that segment at
|
|
35
|
+
* any depth; a glob like `*.ext` matches a segment; a pattern with a slash or `**`
|
|
36
|
+
* is anchored to the root and matched against the full path; a `!` line re-includes
|
|
37
|
+
* a path an earlier ignore excluded. (ama-2eu, ama-yhu, ama-dd9, ama-d28)
|
|
38
|
+
*/
|
|
39
|
+
export declare function loadIgnoreRules(root: string): IgnoreRules;
|
|
40
|
+
/**
|
|
41
|
+
* Augment ignore rules with a subdirectory's own `.gitignore`, rebased so its
|
|
42
|
+
* patterns match the subtree relative to that directory — git applies a nested
|
|
43
|
+
* `.gitignore` to its own subtree, dir-relative (so `/build` means `<dir>/build`,
|
|
44
|
+
* not the repo root). Returns the parent rules unchanged when the directory has
|
|
45
|
+
* none. The root `.gitignore` is folded in by {@link loadIgnoreRules}; this is for
|
|
46
|
+
* the nested directories the discovery walk descends into. (ama-pyk)
|
|
47
|
+
*/
|
|
48
|
+
export declare function withNestedIgnore(dir: string, dirRel: string, parent: IgnoreRules): IgnoreRules;
|
|
49
|
+
/** Whether a single path segment (a file or directory name) is ignored. */
|
|
50
|
+
export declare function isIgnoredSegment(name: string, rules?: IgnoreRules): boolean;
|
|
51
|
+
/** Whether a repo-relative path is ignored: any segment matches an any-depth
|
|
52
|
+
* name/glob, or the full path matches a root-anchored pattern — unless a `!`
|
|
53
|
+
* negation re-includes it. (ama-yhu, ama-d28) */
|
|
54
|
+
export declare function isIgnoredPath(rel: string, rules?: IgnoreRules): boolean;
|
|
55
|
+
//# sourceMappingURL=ignore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ignore.d.ts","sourceRoot":"","sources":["../../src/indexer/ignore.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,eAAO,MAAM,YAAY,aAAyD,CAAC;AAEnF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,QAAc,CAAC;AAE/C,iFAAiF;AACjF,MAAM,WAAW,WAAW;IAC1B,kFAAkF;IAClF,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnB,qFAAqF;IACrF,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB;kFAC8E;IAC9E,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;8EAG0E;IAC1E,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,uEAAuE;AACvE,eAAO,MAAM,iBAAiB,EAAE,WAK/B,CAAC;AA0CF;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAkCzD;AAYD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,WAAW,CAsB9F;AAED,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,WAA+B,GAAG,OAAO,CAE9F;AAED;;kDAEkD;AAClD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,GAAE,WAA+B,GAAG,OAAO,CAO1F"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Directories never worth indexing or watching. Dot-entries (`.git`, `.beads`,
|
|
5
|
+
* `.vscode`, …) are skipped separately. Shared by the indexer's file discovery
|
|
6
|
+
* and the file watcher so the set of files we *watch* matches what we *index*.
|
|
7
|
+
*/
|
|
8
|
+
export const IGNORED_DIRS = new Set(["node_modules", "dist", "build", "coverage"]);
|
|
9
|
+
/**
|
|
10
|
+
* Files larger than this are skipped by both discovery and the watcher — a
|
|
11
|
+
* minified bundle or data blob isn't worth parsing and risks a memory blowup.
|
|
12
|
+
* Shared so the initial index and the watcher agree on what's too big; without
|
|
13
|
+
* it a huge file would be indexed on first build but skipped on re-index.
|
|
14
|
+
*/
|
|
15
|
+
export const MAX_FILE_SIZE_BYTES = 1024 * 1024; // 1 MB
|
|
16
|
+
/** The built-in ignores, used when no `.gitignore` has been loaded. */
|
|
17
|
+
export const BASE_IGNORE_RULES = {
|
|
18
|
+
names: IGNORED_DIRS,
|
|
19
|
+
globs: [],
|
|
20
|
+
anchored: [],
|
|
21
|
+
negations: [],
|
|
22
|
+
};
|
|
23
|
+
/** A gitignore name glob (`*.ext`, `build-*`) as a whole-segment regex. (ama-2eu) */
|
|
24
|
+
function globToSegmentRegExp(glob) {
|
|
25
|
+
const body = glob
|
|
26
|
+
.replace(/[.+^${}()|[\]\\]/g, "\\$&")
|
|
27
|
+
.replace(/\*/g, "[^/]*")
|
|
28
|
+
.replace(/\?/g, "[^/]");
|
|
29
|
+
return new RegExp(`^${body}$`);
|
|
30
|
+
}
|
|
31
|
+
/** A root-anchored gitignore pattern (`build`, `pkg/internal`, `src/*.gen.ts`,
|
|
32
|
+
* `**/*.log`, `a/**/b` — with any leading/trailing slash already stripped) as a
|
|
33
|
+
* regex over the full repo-relative (posix) path, matching the entry and
|
|
34
|
+
* everything under it. `*`/`?` stay within a path segment; `**` spans segments —
|
|
35
|
+
* a leading or mid `**/` matches zero or more directories, a trailing `/**`
|
|
36
|
+
* matches everything under the prefix. (ama-yhu, ama-dd9) */
|
|
37
|
+
function anchoredToRegExp(pattern) {
|
|
38
|
+
// A trailing `/**` matches everything under the prefix — the `(?:/|$)` suffix
|
|
39
|
+
// already does, so drop it.
|
|
40
|
+
const trimmed = pattern.replace(/\/\*\*$/, "");
|
|
41
|
+
// Expand glob tokens and escape regex specials in one pass — the alternation
|
|
42
|
+
// tries `**/` and `**` before a single `*`, so a deep glob isn't mis-expanded,
|
|
43
|
+
// and the expansions' own regex syntax is never re-escaped.
|
|
44
|
+
const body = trimmed.replace(/\*\*\/|\*\*|\*|\?|[.+^${}()|[\]\\]/g, (m) => {
|
|
45
|
+
if (m === "**/")
|
|
46
|
+
return "(?:.*/)?"; // zero or more directories
|
|
47
|
+
if (m === "**")
|
|
48
|
+
return ".*"; // any run, across path segments
|
|
49
|
+
if (m === "*")
|
|
50
|
+
return "[^/]*"; // within one segment
|
|
51
|
+
if (m === "?")
|
|
52
|
+
return "[^/]";
|
|
53
|
+
return `\\${m}`; // a regex special — escape it
|
|
54
|
+
});
|
|
55
|
+
return new RegExp(`^${body}(?:/|$)`);
|
|
56
|
+
}
|
|
57
|
+
/** A `!` negation pattern (the `!` already stripped) as a full-path regex: a bare
|
|
58
|
+
* name / segment glob matches that segment at any depth (like `**/name`); a
|
|
59
|
+
* pattern with a slash or `**` is root-anchored. (ama-d28) */
|
|
60
|
+
function negationToRegExp(pattern) {
|
|
61
|
+
const anchored = pattern.includes("/") || pattern.includes("**");
|
|
62
|
+
return anchoredToRegExp(anchored ? pattern.replace(/^\/+/, "") : `**/${pattern}`);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Read `<root>/.gitignore` and fold a *safe subset* of its patterns into the
|
|
66
|
+
* built-in ignores. Blank lines and `#` comments are skipped; nested `.gitignore`
|
|
67
|
+
* files are a follow-up (ama-d28). A bare `name`/`name/` ignores that segment at
|
|
68
|
+
* any depth; a glob like `*.ext` matches a segment; a pattern with a slash or `**`
|
|
69
|
+
* is anchored to the root and matched against the full path; a `!` line re-includes
|
|
70
|
+
* a path an earlier ignore excluded. (ama-2eu, ama-yhu, ama-dd9, ama-d28)
|
|
71
|
+
*/
|
|
72
|
+
export function loadIgnoreRules(root) {
|
|
73
|
+
const names = new Set(IGNORED_DIRS);
|
|
74
|
+
const globs = [];
|
|
75
|
+
const anchored = [];
|
|
76
|
+
const negations = [];
|
|
77
|
+
let text;
|
|
78
|
+
try {
|
|
79
|
+
text = fs.readFileSync(path.join(root, ".gitignore"), "utf8");
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return { names, globs, anchored, negations };
|
|
83
|
+
}
|
|
84
|
+
for (const raw of text.split("\n")) {
|
|
85
|
+
const line = raw.trim();
|
|
86
|
+
if (!line || line.startsWith("#"))
|
|
87
|
+
continue;
|
|
88
|
+
if (line.startsWith("!")) {
|
|
89
|
+
// A negation re-includes a path an earlier rule excluded. (ama-d28)
|
|
90
|
+
const neg = line.slice(1).replace(/\/+$/, "");
|
|
91
|
+
if (neg)
|
|
92
|
+
negations.push(negationToRegExp(neg));
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const body = line.replace(/\/+$/, ""); // a trailing slash only marks dir-only
|
|
96
|
+
if (!body)
|
|
97
|
+
continue;
|
|
98
|
+
if (body.includes("/") || body.includes("**")) {
|
|
99
|
+
// A leading/embedded slash or a `**` deep glob anchors the pattern to this
|
|
100
|
+
// .gitignore's directory (the root) — match it root-relatively, against the
|
|
101
|
+
// full path, not at any depth. (ama-yhu, ama-dd9)
|
|
102
|
+
anchored.push(anchoredToRegExp(body.replace(/^\/+/, "")));
|
|
103
|
+
}
|
|
104
|
+
else if (/[*?]/.test(body)) {
|
|
105
|
+
globs.push(globToSegmentRegExp(body));
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
names.add(body);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return { names, globs, anchored, negations };
|
|
112
|
+
}
|
|
113
|
+
/** A nested-`.gitignore` line as a full-path regex relative to its own directory
|
|
114
|
+
* (`baseRel`): a bare name/glob matches at any depth under it (`baseRel/**/name`);
|
|
115
|
+
* a slash/`**` pattern is anchored to it (`baseRel/pattern`). Reuses the root
|
|
116
|
+
* matcher's compiler, just rooted one directory deeper. (ama-pyk) */
|
|
117
|
+
function scopedToRegExp(pattern, baseRel) {
|
|
118
|
+
const rel = pattern.includes("/") || pattern.includes("**") ? pattern.replace(/^\/+/, "") : `**/${pattern}`;
|
|
119
|
+
return anchoredToRegExp(`${baseRel}/${rel}`);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Augment ignore rules with a subdirectory's own `.gitignore`, rebased so its
|
|
123
|
+
* patterns match the subtree relative to that directory — git applies a nested
|
|
124
|
+
* `.gitignore` to its own subtree, dir-relative (so `/build` means `<dir>/build`,
|
|
125
|
+
* not the repo root). Returns the parent rules unchanged when the directory has
|
|
126
|
+
* none. The root `.gitignore` is folded in by {@link loadIgnoreRules}; this is for
|
|
127
|
+
* the nested directories the discovery walk descends into. (ama-pyk)
|
|
128
|
+
*/
|
|
129
|
+
export function withNestedIgnore(dir, dirRel, parent) {
|
|
130
|
+
let text;
|
|
131
|
+
try {
|
|
132
|
+
text = fs.readFileSync(path.join(dir, ".gitignore"), "utf8");
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
return parent;
|
|
136
|
+
}
|
|
137
|
+
const base = dirRel.split(path.sep).join("/"); // repo-relative, posix
|
|
138
|
+
const anchored = [...parent.anchored];
|
|
139
|
+
const negations = [...parent.negations];
|
|
140
|
+
for (const raw of text.split("\n")) {
|
|
141
|
+
const line = raw.trim();
|
|
142
|
+
if (!line || line.startsWith("#"))
|
|
143
|
+
continue;
|
|
144
|
+
if (line.startsWith("!")) {
|
|
145
|
+
const neg = line.slice(1).replace(/\/+$/, "");
|
|
146
|
+
if (neg)
|
|
147
|
+
negations.push(scopedToRegExp(neg, base));
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
const body = line.replace(/\/+$/, "");
|
|
151
|
+
if (body)
|
|
152
|
+
anchored.push(scopedToRegExp(body, base));
|
|
153
|
+
}
|
|
154
|
+
return { ...parent, anchored, negations };
|
|
155
|
+
}
|
|
156
|
+
/** Whether a single path segment (a file or directory name) is ignored. */
|
|
157
|
+
export function isIgnoredSegment(name, rules = BASE_IGNORE_RULES) {
|
|
158
|
+
return name.startsWith(".") || rules.names.has(name) || rules.globs.some((re) => re.test(name));
|
|
159
|
+
}
|
|
160
|
+
/** Whether a repo-relative path is ignored: any segment matches an any-depth
|
|
161
|
+
* name/glob, or the full path matches a root-anchored pattern — unless a `!`
|
|
162
|
+
* negation re-includes it. (ama-yhu, ama-d28) */
|
|
163
|
+
export function isIgnoredPath(rel, rules = BASE_IGNORE_RULES) {
|
|
164
|
+
const segments = rel.split(path.sep);
|
|
165
|
+
const posix = segments.join("/");
|
|
166
|
+
const ignored = segments.some((seg) => isIgnoredSegment(seg, rules)) ||
|
|
167
|
+
rules.anchored.some((re) => re.test(posix));
|
|
168
|
+
return ignored && !rules.negations.some((re) => re.test(posix));
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=ignore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ignore.js","sourceRoot":"","sources":["../../src/indexer/ignore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { AnalyzerRegistry } from "../analyzers/registry.js";
|
|
2
|
+
import type { ResolutionStats } from "../analyzers/types.js";
|
|
3
|
+
import type { Tier } from "../graph/index.js";
|
|
4
|
+
import type { FileMeta, Store } from "../store/types.js";
|
|
5
|
+
export interface LanguageCoverage {
|
|
6
|
+
language: string;
|
|
7
|
+
tier: Tier;
|
|
8
|
+
files: number;
|
|
9
|
+
}
|
|
10
|
+
export interface IndexStats {
|
|
11
|
+
/** Absolute root that was indexed. */
|
|
12
|
+
root: string;
|
|
13
|
+
nodeCount: number;
|
|
14
|
+
edgeCount: number;
|
|
15
|
+
/** Number of source files actually analyzed. */
|
|
16
|
+
fileCount: number;
|
|
17
|
+
/** Per-language coverage, each carrying the analyzer's tier. */
|
|
18
|
+
languages: LanguageCoverage[];
|
|
19
|
+
/** Aggregate call-resolution coverage across deep analyzers, when measured. */
|
|
20
|
+
resolution?: ResolutionStats;
|
|
21
|
+
}
|
|
22
|
+
/** What a catch-up {@link Indexer.sync} reconciled. */
|
|
23
|
+
export interface SyncResult {
|
|
24
|
+
/** Repo-relative paths re-indexed because they were new or modified. */
|
|
25
|
+
changed: string[];
|
|
26
|
+
/** Repo-relative paths dropped because they no longer exist (or analyze). */
|
|
27
|
+
removed: string[];
|
|
28
|
+
}
|
|
29
|
+
/** Throw if `root` resolves to the filesystem root, the user's home directory,
|
|
30
|
+
* or a well-known system directory — a guardrail so a stray `index_repository`
|
|
31
|
+
* call (an agent, a typo) can't walk the whole machine. (ama-m8k.10) */
|
|
32
|
+
export declare function assertSafeRoot(root: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Turns a directory into a graph: discover source files, hand each to the
|
|
35
|
+
* analyzer that claims its extension, and collect the resulting nodes/edges
|
|
36
|
+
* into a store. All files for one analyzer are analyzed together so it can
|
|
37
|
+
* resolve cross-file references (e.g. an import's call target).
|
|
38
|
+
*/
|
|
39
|
+
export declare class Indexer {
|
|
40
|
+
private readonly registry;
|
|
41
|
+
/** How to create the backing store for a (resolved) project root — swap this to
|
|
42
|
+
* persist to SQLite. The root is passed so a multi-project session can give each
|
|
43
|
+
* project an independent store; a factory that ignores it and returns one shared
|
|
44
|
+
* store would alias every project onto the last index. (ama-mnj) */
|
|
45
|
+
private readonly createStore;
|
|
46
|
+
constructor(registry: AnalyzerRegistry,
|
|
47
|
+
/** How to create the backing store for a (resolved) project root — swap this to
|
|
48
|
+
* persist to SQLite. The root is passed so a multi-project session can give each
|
|
49
|
+
* project an independent store; a factory that ignores it and returns one shared
|
|
50
|
+
* store would alias every project onto the last index. (ama-mnj) */
|
|
51
|
+
createStore?: (root: string) => Store);
|
|
52
|
+
/** The (language, tier) that owns a file, or undefined if no analyzer claims it.
|
|
53
|
+
* Lets a caller recompute per-language coverage live from the current file set,
|
|
54
|
+
* so index_status's census stays correct after incremental syncs — not only
|
|
55
|
+
* after a full index, which is the only thing that writes the cached coverage
|
|
56
|
+
* metadata. (ama-okg) */
|
|
57
|
+
languageOf(rel: string): {
|
|
58
|
+
language: string;
|
|
59
|
+
tier: Tier;
|
|
60
|
+
} | undefined;
|
|
61
|
+
index(root: string): Promise<{
|
|
62
|
+
store: Store;
|
|
63
|
+
stats: IndexStats;
|
|
64
|
+
}>;
|
|
65
|
+
/**
|
|
66
|
+
* Reopen a previously-persisted index without re-analyzing: open the store and,
|
|
67
|
+
* if it holds a usable index for `root` (matching schema version and root, with
|
|
68
|
+
* nodes present), reconstruct its {@link IndexStats} from the persisted
|
|
69
|
+
* coverage metadata. Returns undefined — and closes the freshly-opened store —
|
|
70
|
+
* when there is nothing usable (an empty in-memory store, a different root, or
|
|
71
|
+
* an incompatible schema), so the caller falls back to a full {@link index}.
|
|
72
|
+
*/
|
|
73
|
+
open(root: string): Promise<{
|
|
74
|
+
store: Store;
|
|
75
|
+
stats: IndexStats;
|
|
76
|
+
} | undefined>;
|
|
77
|
+
/**
|
|
78
|
+
* Re-index a single changed file into an existing store, in place. Re-analyzes
|
|
79
|
+
* just `rel` and reconciles its delta (so an edit churns only what changed);
|
|
80
|
+
* if `rel` was deleted or is no longer analyzable, its data is dropped instead.
|
|
81
|
+
* Edges from `rel` into files this pass never walks still resolve, because the
|
|
82
|
+
* analyzer falls back to location-derived ids for nodes already in the store.
|
|
83
|
+
*/
|
|
84
|
+
reindexFile(store: Store, root: string, rel: string): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Catch-up reconcile: compare the tree on disk against the stored fingerprints
|
|
87
|
+
* and re-index everything that drifted — files added or modified since the
|
|
88
|
+
* last index, and files that have since vanished. Detection is cheap
|
|
89
|
+
* (size + mtime, with a content hash only as the tiebreaker), and unchanged
|
|
90
|
+
* files are skipped entirely. The manual counterpart to the live watcher.
|
|
91
|
+
*/
|
|
92
|
+
sync(store: Store, root: string): Promise<SyncResult>;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* An indexer wired with the analyzers Ama ships today. Pass a `createStore`
|
|
96
|
+
* factory to persist into SQLite instead of the default in-memory store.
|
|
97
|
+
*/
|
|
98
|
+
export declare function createDefaultIndexer(createStore?: (root: string) => Store): Indexer;
|
|
99
|
+
/** Fingerprint a file for staleness tracking: size, mtime, and content hash.
|
|
100
|
+
* Returns null when the file has vanished (gone between discovery and now — an
|
|
101
|
+
* editor's atomic save or temp file) so the caller can drop it instead of
|
|
102
|
+
* crashing the index. (ama-7r5) */
|
|
103
|
+
export declare function fingerprint(root: string, rel: string): FileMeta | null;
|
|
104
|
+
/**
|
|
105
|
+
* Whether a file differs from its recorded fingerprint. Size and mtime are the
|
|
106
|
+
* cheap first check; the content hash is consulted only when they are
|
|
107
|
+
* inconclusive (mtime can change without the bytes changing), so an unchanged
|
|
108
|
+
* file is never re-hashed. A file that has vanished counts as stale, so the
|
|
109
|
+
* caller reindexes it and its `existsSync` check reconciles the removal. (ama-7r5)
|
|
110
|
+
*/
|
|
111
|
+
export declare function isStale(root: string, rel: string, meta: FileMeta): boolean;
|
|
112
|
+
//# sourceMappingURL=indexer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../../src/indexer/indexer.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,OAAO,KAAK,EAA4B,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGvF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AASzD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,+EAA+E;IAC/E,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AASD,uDAAuD;AACvD,MAAM,WAAW,UAAU;IACzB,wEAAwE;IACxE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAqBD;;yEAEyE;AACzE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAOjD;AAED;;;;;GAKG;AACH,qBAAa,OAAO;IAEhB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB;;;yEAGqE;IACrE,OAAO,CAAC,QAAQ,CAAC,WAAW;gBALX,QAAQ,EAAE,gBAAgB;IAC3C;;;yEAGqE;IACpD,WAAW,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAiC;IAGnF;;;;8BAI0B;IAC1B,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,CAAA;KAAE,GAAG,SAAS;IAK/D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,CAAC;IA+FvE;;;;;;;OAOG;IACG,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,GAAG,SAAS,CAAC;IAwClF;;;;;;OAMG;IACG,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBzE;;;;;;OAMG;IACG,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;CAqB5D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK,GAAG,OAAO,CAiBnF;AAeD;;;oCAGoC;AACpC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAStE;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAe1E"}
|