@mcp-monorepo/notion-query 1.1.0 → 1.3.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/dist/index.js +56 -7
- package/dist/index.js.map +1 -1
- package/dist/lib/client.d.ts +9 -0
- package/dist/lib/client.d.ts.map +1 -0
- package/dist/lib/client.js +19 -0
- package/dist/lib/client.js.map +1 -0
- package/dist/lib/config.d.ts +44 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +49 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/id-utils.d.ts +8 -0
- package/dist/lib/id-utils.d.ts.map +1 -0
- package/dist/lib/id-utils.js +20 -0
- package/dist/lib/id-utils.js.map +1 -0
- package/dist/lib/markdown-converter.d.ts +8 -0
- package/dist/lib/markdown-converter.d.ts.map +1 -0
- package/dist/lib/markdown-converter.js +95 -0
- package/dist/lib/markdown-converter.js.map +1 -0
- package/dist/lib/notion-syncer.d.ts +27 -0
- package/dist/lib/notion-syncer.d.ts.map +1 -0
- package/dist/lib/notion-syncer.js +212 -0
- package/dist/lib/notion-syncer.js.map +1 -0
- package/dist/lib/parser.d.ts +13 -0
- package/dist/lib/parser.d.ts.map +1 -0
- package/dist/lib/parser.js +88 -0
- package/dist/lib/parser.js.map +1 -0
- package/dist/lib/property-parser.d.ts +23 -0
- package/dist/lib/property-parser.d.ts.map +1 -0
- package/dist/lib/property-parser.js +200 -0
- package/dist/lib/property-parser.js.map +1 -0
- package/dist/lib/response-formatter.d.ts +16 -0
- package/dist/lib/response-formatter.d.ts.map +1 -0
- package/dist/lib/response-formatter.js +173 -0
- package/dist/lib/response-formatter.js.map +1 -0
- package/dist/lib/sync-state-manager.d.ts +29 -0
- package/dist/lib/sync-state-manager.d.ts.map +1 -0
- package/dist/lib/sync-state-manager.js +45 -0
- package/dist/lib/sync-state-manager.js.map +1 -0
- package/dist/local-rag/DEMO.d.ts +22 -0
- package/dist/local-rag/DEMO.d.ts.map +1 -0
- package/dist/local-rag/DEMO.js +142 -0
- package/dist/local-rag/DEMO.js.map +1 -0
- package/dist/local-rag/chunker.d.ts +24 -0
- package/dist/local-rag/chunker.d.ts.map +1 -0
- package/dist/local-rag/chunker.js +58 -0
- package/dist/local-rag/chunker.js.map +1 -0
- package/dist/local-rag/embedder.d.ts +43 -0
- package/dist/local-rag/embedder.d.ts.map +1 -0
- package/dist/local-rag/embedder.js +74 -0
- package/dist/local-rag/embedder.js.map +1 -0
- package/dist/local-rag/embedder.service.d.ts +15 -0
- package/dist/local-rag/embedder.service.d.ts.map +1 -0
- package/dist/local-rag/embedder.service.js +84 -0
- package/dist/local-rag/embedder.service.js.map +1 -0
- package/dist/local-rag/embedder.worker.d.ts +2 -0
- package/dist/local-rag/embedder.worker.d.ts.map +1 -0
- package/dist/local-rag/embedder.worker.js +34 -0
- package/dist/local-rag/embedder.worker.js.map +1 -0
- package/dist/local-rag/errors.d.ts +31 -0
- package/dist/local-rag/errors.d.ts.map +1 -0
- package/dist/local-rag/errors.js +47 -0
- package/dist/local-rag/errors.js.map +1 -0
- package/dist/local-rag/html-parser.d.ts +2 -0
- package/dist/local-rag/html-parser.d.ts.map +1 -0
- package/dist/local-rag/html-parser.js +32 -0
- package/dist/local-rag/html-parser.js.map +1 -0
- package/dist/local-rag/index.d.ts +67 -0
- package/dist/local-rag/index.d.ts.map +1 -0
- package/dist/local-rag/index.js +410 -0
- package/dist/local-rag/index.js.map +1 -0
- package/dist/local-rag/parser.d.ts +59 -0
- package/dist/local-rag/parser.d.ts.map +1 -0
- package/dist/local-rag/parser.js +206 -0
- package/dist/local-rag/parser.js.map +1 -0
- package/dist/local-rag/types.d.ts +209 -0
- package/dist/local-rag/types.d.ts.map +1 -0
- package/dist/local-rag/types.js +5 -0
- package/dist/local-rag/types.js.map +1 -0
- package/dist/local-rag/utils/pool.d.ts +60 -0
- package/dist/local-rag/utils/pool.d.ts.map +1 -0
- package/dist/local-rag/utils/pool.js +140 -0
- package/dist/local-rag/utils/pool.js.map +1 -0
- package/dist/local-rag/utils/typed-emitter.d.ts +28 -0
- package/dist/local-rag/utils/typed-emitter.d.ts.map +1 -0
- package/dist/local-rag/utils/typed-emitter.js +44 -0
- package/dist/local-rag/utils/typed-emitter.js.map +1 -0
- package/dist/local-rag/vectordb/index.d.ts +91 -0
- package/dist/local-rag/vectordb/index.d.ts.map +1 -0
- package/dist/local-rag/vectordb/index.js +278 -0
- package/dist/local-rag/vectordb/index.js.map +1 -0
- package/dist/local-rag/vectordb/manager.d.ts +28 -0
- package/dist/local-rag/vectordb/manager.d.ts.map +1 -0
- package/dist/local-rag/vectordb/manager.js +91 -0
- package/dist/local-rag/vectordb/manager.js.map +1 -0
- package/dist/local-rag/vectordb/migration.d.ts +27 -0
- package/dist/local-rag/vectordb/migration.d.ts.map +1 -0
- package/dist/local-rag/vectordb/migration.js +121 -0
- package/dist/local-rag/vectordb/migration.js.map +1 -0
- package/dist/local-rag/vectordb/retriever.d.ts +51 -0
- package/dist/local-rag/vectordb/retriever.d.ts.map +1 -0
- package/dist/local-rag/vectordb/retriever.js +157 -0
- package/dist/local-rag/vectordb/retriever.js.map +1 -0
- package/dist/local-rag/vectordb/schema.d.ts +33 -0
- package/dist/local-rag/vectordb/schema.d.ts.map +1 -0
- package/dist/local-rag/vectordb/schema.js +102 -0
- package/dist/local-rag/vectordb/schema.js.map +1 -0
- package/dist/local-rag/watcher.d.ts +48 -0
- package/dist/local-rag/watcher.d.ts.map +1 -0
- package/dist/local-rag/watcher.js +102 -0
- package/dist/local-rag/watcher.js.map +1 -0
- package/dist/tools/create-pages.d.ts +4 -0
- package/dist/tools/create-pages.d.ts.map +1 -0
- package/dist/tools/create-pages.js +184 -0
- package/dist/tools/create-pages.js.map +1 -0
- package/dist/tools/fetch.d.ts +4 -0
- package/dist/tools/fetch.d.ts.map +1 -0
- package/dist/tools/fetch.js +90 -0
- package/dist/tools/fetch.js.map +1 -0
- package/dist/tools/query-datasource.d.ts +4 -0
- package/dist/tools/query-datasource.d.ts.map +1 -0
- package/dist/tools/{notion-query.js → query-datasource.js} +31 -38
- package/dist/tools/query-datasource.js.map +1 -0
- package/dist/tools/search.d.ts +12 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +75 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/update-page.d.ts +4 -0
- package/dist/tools/update-page.d.ts.map +1 -0
- package/dist/tools/update-page.js +135 -0
- package/dist/tools/update-page.js.map +1 -0
- package/package.json +23 -8
- package/dist/tools/notion-query.d.ts +0 -3
- package/dist/tools/notion-query.d.ts.map +0 -1
- package/dist/tools/notion-query.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-parser.d.ts","sourceRoot":"","sources":["../../src/local-rag/html-parser.ts"],"names":[],"mappings":"AAIA,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBxF"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { logger } from '@mcp-monorepo/shared';
|
|
2
|
+
import { Readability, isProbablyReaderable } from '@mozilla/readability';
|
|
3
|
+
import { JSDOM } from 'jsdom';
|
|
4
|
+
export async function parseHtmlContent(url, htmlContent) {
|
|
5
|
+
const doc = new JSDOM(htmlContent, { url });
|
|
6
|
+
// First, check if the page is likely to be readable
|
|
7
|
+
if (!isProbablyReaderable(doc.window.document)) {
|
|
8
|
+
logger.warn(`Page at ${url} is not considered readerable. Falling back to basic parsing.`);
|
|
9
|
+
// Fallback to the naive implementation if not readerable
|
|
10
|
+
return defaultParseHtmlContent(htmlContent);
|
|
11
|
+
}
|
|
12
|
+
const reader = new Readability(doc.window.document);
|
|
13
|
+
const article = reader.parse();
|
|
14
|
+
const textContent = article?.textContent?.trim();
|
|
15
|
+
if (textContent) {
|
|
16
|
+
// Successfully parsed, return the clean text content
|
|
17
|
+
// For Markdown, you would convert article.content here with another library
|
|
18
|
+
return textContent;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
// Readability failed to parse an article, use the fallback
|
|
22
|
+
logger.warn(`Readability.js could not parse an article from ${url}. Falling back to basic parsing.`);
|
|
23
|
+
return defaultParseHtmlContent(htmlContent);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function defaultParseHtmlContent(htmlContent) {
|
|
27
|
+
return htmlContent
|
|
28
|
+
.replace(/<[^>]*>/g, ' ')
|
|
29
|
+
.replace(/\s+/g, ' ')
|
|
30
|
+
.trim();
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=html-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-parser.js","sourceRoot":"","sources":["../../src/local-rag/html-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AACxE,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAE7B,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAW,EAAE,WAAmB;IACrE,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,CAAA;IAE3C,oDAAoD;IACpD,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,WAAW,GAAG,+DAA+D,CAAC,CAAA;QAC1F,yDAAyD;QACzD,OAAO,uBAAuB,CAAC,WAAW,CAAC,CAAA;IAC7C,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IACnD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,EAAE,CAAA;IAE9B,MAAM,WAAW,GAAG,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAA;IAChD,IAAI,WAAW,EAAE,CAAC;QAChB,qDAAqD;QACrD,4EAA4E;QAC5E,OAAO,WAAW,CAAA;IACpB,CAAC;SAAM,CAAC;QACN,2DAA2D;QAC3D,MAAM,CAAC,IAAI,CAAC,kDAAkD,GAAG,kCAAkC,CAAC,CAAA;QACpG,OAAO,uBAAuB,CAAC,WAAW,CAAC,CAAA;IAC7C,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAAC,WAAmB;IAClD,OAAO,WAAW;SACf,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAA;AACX,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { IngestFileInput, IngestFolderInput, IngestTextInupt, IngestUrlInput, ListItem, ListOptions, LocalRAGConfig, QueryInput, QueryResult, StatusReport, UpdateMemoryInput, WatchOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A powerful, private, and configurable local RAG library.
|
|
4
|
+
*/
|
|
5
|
+
export declare class LocalRAG {
|
|
6
|
+
private readonly config;
|
|
7
|
+
private readonly parser;
|
|
8
|
+
private readonly chunker;
|
|
9
|
+
private readonly embedder;
|
|
10
|
+
private readonly vectorStore;
|
|
11
|
+
private readonly watcher;
|
|
12
|
+
private readonly writeExecutor;
|
|
13
|
+
private cleanupIntervalId?;
|
|
14
|
+
private optimizeIntervalId?;
|
|
15
|
+
private constructor();
|
|
16
|
+
static create(config: LocalRAGConfig): Promise<LocalRAG>;
|
|
17
|
+
/**
|
|
18
|
+
* Initializes the database connection and starts background jobs. Must be called before any other methods.
|
|
19
|
+
*/
|
|
20
|
+
private initialize;
|
|
21
|
+
/**
|
|
22
|
+
* Gracefully shuts down all background processes like the watcher, embedder pool, and periodic jobs.
|
|
23
|
+
*/
|
|
24
|
+
shutdown(): Promise<void>;
|
|
25
|
+
ingestFile(input: IngestFileInput): Promise<void>;
|
|
26
|
+
ingestFolder(input: IngestFolderInput): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Ingests a raw text snippet into the vector store.
|
|
29
|
+
*/
|
|
30
|
+
ingestText(input: IngestTextInupt): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Ingests content from a URL.
|
|
33
|
+
*/
|
|
34
|
+
ingestUrl(input: IngestUrlInput): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Searches the vector store with a natural language query.
|
|
37
|
+
*/
|
|
38
|
+
query(input: QueryInput): Promise<QueryResult[]>;
|
|
39
|
+
/**
|
|
40
|
+
* Updates an existing text snippet (memory).
|
|
41
|
+
*/
|
|
42
|
+
updateMemory(input: UpdateMemoryInput): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Deletes a file or snippet from the vector store.
|
|
45
|
+
*/
|
|
46
|
+
delete(path: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Lists all items in the vector store, with optional filtering and pagination.
|
|
49
|
+
*/
|
|
50
|
+
list(options?: ListOptions): Promise<ListItem[]>;
|
|
51
|
+
/**
|
|
52
|
+
* Retrieves the current status of the RAG system.
|
|
53
|
+
*/
|
|
54
|
+
getStatus(): Promise<StatusReport>;
|
|
55
|
+
/**
|
|
56
|
+
* Manually triggers a cleanup of all expired text snippets from the database.
|
|
57
|
+
*/
|
|
58
|
+
cleanupExpired(): Promise<number>;
|
|
59
|
+
watch(path: string, options?: WatchOptions): Promise<void>;
|
|
60
|
+
unwatch(path: string): Promise<void>;
|
|
61
|
+
private startPeriodicJobs;
|
|
62
|
+
private findSupportedFiles;
|
|
63
|
+
private setupWatcherListeners;
|
|
64
|
+
private calculateExpiresAt;
|
|
65
|
+
private _createVectorChunks;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/local-rag/index.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAEV,eAAe,EACf,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,QAAQ,EACR,WAAW,EACX,cAAc,EACd,UAAU,EACV,WAAW,EACX,YAAY,EACZ,iBAAiB,EAEjB,YAAY,EACb,MAAM,YAAY,CAAA;AAEnB;;GAEG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0B;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmB;IAEjD,OAAO,CAAC,iBAAiB,CAAC,CAAgB;IAC1C,OAAO,CAAC,kBAAkB,CAAC,CAAgB;IAE3C,OAAO;WAqBM,MAAM,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,QAAQ,CAAC;IAgC9D;;OAEG;YACW,UAAU;IAWxB;;OAEG;IACU,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAW/B,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAgD3C,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBlE;;OAEG;IACI,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BxD;;OAEG;IACI,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA6BtD;;OAEG;IACU,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAM7D;;OAEG;IACI,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqC5D;;OAEG;IACI,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO1C;;OAEG;IACU,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAI7D;;OAEG;IACU,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC;IAI/C;;OAEG;IACI,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC;IAIjC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAe9D,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa3C,OAAO,CAAC,iBAAiB;YA4BX,kBAAkB;IAgBhC,OAAO,CAAC,qBAAqB;IAqB7B,OAAO,CAAC,kBAAkB;YAeZ,mBAAmB;CA4BlC"}
|
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
// noinspection JSUnusedGlobalSymbols
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { readdir, stat } from 'node:fs/promises';
|
|
4
|
+
import { basename, extname, join, resolve } from 'node:path';
|
|
5
|
+
import { ThrottledExecutor, logger } from '@mcp-monorepo/shared';
|
|
6
|
+
import { DocumentChunker } from './chunker.js';
|
|
7
|
+
import { Embedder } from './embedder.js';
|
|
8
|
+
import { ValidationError } from './errors.js';
|
|
9
|
+
import { parseHtmlContent } from './html-parser.js';
|
|
10
|
+
import { DocumentParser } from './parser.js';
|
|
11
|
+
import { VectorStore } from './vectordb/index.js';
|
|
12
|
+
import { DirectoryWatcher } from './watcher.js';
|
|
13
|
+
/**
|
|
14
|
+
* A powerful, private, and configurable local RAG library.
|
|
15
|
+
*/
|
|
16
|
+
export class LocalRAG {
|
|
17
|
+
config;
|
|
18
|
+
parser;
|
|
19
|
+
chunker;
|
|
20
|
+
embedder;
|
|
21
|
+
vectorStore;
|
|
22
|
+
watcher;
|
|
23
|
+
writeExecutor;
|
|
24
|
+
cleanupIntervalId;
|
|
25
|
+
optimizeIntervalId;
|
|
26
|
+
constructor(config, embedder, vectorStore) {
|
|
27
|
+
this.config = config;
|
|
28
|
+
this.writeExecutor = new ThrottledExecutor(0);
|
|
29
|
+
// Initialize components
|
|
30
|
+
this.parser = new DocumentParser({
|
|
31
|
+
baseDir: this.config.baseDir,
|
|
32
|
+
maxFileSize: this.config.maxFileSize,
|
|
33
|
+
});
|
|
34
|
+
this.chunker = new DocumentChunker({
|
|
35
|
+
chunkSize: this.config.chunkSize,
|
|
36
|
+
chunkOverlap: this.config.chunkOverlap,
|
|
37
|
+
});
|
|
38
|
+
this.embedder = embedder;
|
|
39
|
+
this.vectorStore = vectorStore;
|
|
40
|
+
// Initialize the watcher
|
|
41
|
+
this.watcher = new DirectoryWatcher(this.config.debounceMs, this.parser.getSupportedExtensions());
|
|
42
|
+
this.setupWatcherListeners();
|
|
43
|
+
}
|
|
44
|
+
static async create(config) {
|
|
45
|
+
const baseDir = resolve(config.baseDir ?? process.cwd());
|
|
46
|
+
const requiredConfig = {
|
|
47
|
+
baseDir,
|
|
48
|
+
dbPath: config.dbPath,
|
|
49
|
+
cacheDir: config.cacheDir ?? resolve(baseDir, '.cache', 'models'),
|
|
50
|
+
modelName: config.modelName ?? 'Xenova/all-MiniLM-L6-v2',
|
|
51
|
+
maxFileSize: config.maxFileSize ?? 100 * 1024 * 1024, // 100MB
|
|
52
|
+
chunkSize: config.chunkSize ?? 512,
|
|
53
|
+
chunkOverlap: config.chunkOverlap ?? 100,
|
|
54
|
+
debounceMs: config.debounceMs ?? 5000,
|
|
55
|
+
cleanupIntervalMs: config.cleanupIntervalMs ?? 0, // Default to disabled
|
|
56
|
+
optimizeIntervalMs: config.optimizeIntervalMs ?? 0, // Default to disabled
|
|
57
|
+
retrievalOptions: config.retrievalOptions ?? {},
|
|
58
|
+
poolConfig: config.poolConfig ?? {},
|
|
59
|
+
};
|
|
60
|
+
const embedder = await Embedder.create({
|
|
61
|
+
modelPath: requiredConfig.modelName,
|
|
62
|
+
batchSize: 32,
|
|
63
|
+
cacheDir: requiredConfig.cacheDir,
|
|
64
|
+
poolConfig: requiredConfig.poolConfig,
|
|
65
|
+
});
|
|
66
|
+
const vectorStore = await VectorStore.create({
|
|
67
|
+
dbPath: requiredConfig.dbPath,
|
|
68
|
+
...requiredConfig.retrievalOptions,
|
|
69
|
+
});
|
|
70
|
+
const rag = new LocalRAG(requiredConfig, embedder, vectorStore);
|
|
71
|
+
await rag.initialize();
|
|
72
|
+
return rag;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Initializes the database connection and starts background jobs. Must be called before any other methods.
|
|
76
|
+
*/
|
|
77
|
+
async initialize() {
|
|
78
|
+
// Hydrate the watcher with persisted paths
|
|
79
|
+
const watchedPaths = await this.vectorStore.getWatchedPaths();
|
|
80
|
+
for (const item of watchedPaths) {
|
|
81
|
+
this.watcher.watch(item.path);
|
|
82
|
+
}
|
|
83
|
+
logger.info(`Watcher initialized and now monitoring ${watchedPaths.length} persisted paths.`);
|
|
84
|
+
this.startPeriodicJobs();
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Gracefully shuts down all background processes like the watcher, embedder pool, and periodic jobs.
|
|
88
|
+
*/
|
|
89
|
+
async shutdown() {
|
|
90
|
+
if (this.cleanupIntervalId)
|
|
91
|
+
clearInterval(this.cleanupIntervalId);
|
|
92
|
+
if (this.optimizeIntervalId)
|
|
93
|
+
clearInterval(this.optimizeIntervalId);
|
|
94
|
+
await this.watcher.close();
|
|
95
|
+
await this.embedder.destroy();
|
|
96
|
+
await this.writeExecutor.onIdle();
|
|
97
|
+
this.vectorStore.close();
|
|
98
|
+
logger.info('LocalRAG shutdown complete.');
|
|
99
|
+
}
|
|
100
|
+
ingestFile(input) {
|
|
101
|
+
return this.writeExecutor.execute(async () => {
|
|
102
|
+
// Callers are responsible for handling errors, including those from unsupported file types.
|
|
103
|
+
// The watcher listener has special handling to ignore unsupported files.
|
|
104
|
+
const { filePath, tags, project, watch } = input;
|
|
105
|
+
const absolutePath = resolve(filePath);
|
|
106
|
+
const stats = await this.parser.validateAndGetFileStats(absolutePath);
|
|
107
|
+
const currentMtime = stats.fileModifiedAt;
|
|
108
|
+
const existingMetadata = await this.vectorStore.getLatestMetadata(absolutePath);
|
|
109
|
+
if (existingMetadata?.fileModifiedAt === currentMtime) {
|
|
110
|
+
logger.info(`Skipping ingestion for unchanged file: ${absolutePath}`);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
logger.info(`Ingesting changed or new file: ${absolutePath}`);
|
|
114
|
+
const { text, language, fileSize, metadata: fileMetadata } = await this.parser.parseFile(absolutePath);
|
|
115
|
+
const metadata = {
|
|
116
|
+
...fileMetadata,
|
|
117
|
+
fileName: basename(absolutePath),
|
|
118
|
+
fileSize,
|
|
119
|
+
fileType: extname(absolutePath).slice(1),
|
|
120
|
+
language,
|
|
121
|
+
tags: tags ?? [],
|
|
122
|
+
project,
|
|
123
|
+
memoryType: 'file',
|
|
124
|
+
};
|
|
125
|
+
const vectorChunks = await this._createVectorChunks(text, metadata, absolutePath);
|
|
126
|
+
if (vectorChunks.length === 0) {
|
|
127
|
+
logger.warn(`Skipping ingestion for ${absolutePath} as it produced no valid chunks (file might be empty or too short).`);
|
|
128
|
+
await this.vectorStore.deleteChunks(absolutePath);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
await this.vectorStore.deleteChunks(absolutePath);
|
|
132
|
+
await this.vectorStore.insertChunks(vectorChunks);
|
|
133
|
+
}
|
|
134
|
+
if (watch && !this.watcher.isWatching(absolutePath)) {
|
|
135
|
+
await this.watch(absolutePath);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
async ingestFolder(input) {
|
|
140
|
+
const { folderPath, watch, recursive = false, project, tags } = input;
|
|
141
|
+
const absolutePath = resolve(folderPath);
|
|
142
|
+
if (watch) {
|
|
143
|
+
// If watching, we just attach the watcher. Chokidar with `ignoreInitial: false`
|
|
144
|
+
// will emit 'add' events for all existing files, which our listeners will handle.
|
|
145
|
+
logger.info(`Attaching watcher to ${absolutePath}. It will process existing and new files (recursive: ${recursive}).`);
|
|
146
|
+
await this.watch(absolutePath, { recursive });
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
// If not watching, perform a one-time manual scan and ingestion.
|
|
150
|
+
logger.info(`Performing one-time ingestion for ${absolutePath} (recursive: ${recursive}).`);
|
|
151
|
+
const filesToIndex = await this.findSupportedFiles(absolutePath, recursive);
|
|
152
|
+
logger.info(`Found ${filesToIndex.length} supported files to ingest.`);
|
|
153
|
+
await Promise.all(filesToIndex.map((filePath) => this.ingestFile({ filePath, project, tags, watch: false })));
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Ingests a raw text snippet into the vector store.
|
|
158
|
+
*/
|
|
159
|
+
ingestText(input) {
|
|
160
|
+
return this.writeExecutor.execute(async () => {
|
|
161
|
+
const { text, label, language, tags, project, ttl } = input;
|
|
162
|
+
if (!label.match(/^[\w.-]+$/)) {
|
|
163
|
+
throw new ValidationError('Label must contain only alphanumeric characters, hyphens, underscores, and dots.');
|
|
164
|
+
}
|
|
165
|
+
const syntheticPath = `memory://${label}`;
|
|
166
|
+
const metadata = {
|
|
167
|
+
fileName: label,
|
|
168
|
+
fileSize: text.length,
|
|
169
|
+
fileType: 'text-snippet',
|
|
170
|
+
language,
|
|
171
|
+
tags: tags ?? [],
|
|
172
|
+
project,
|
|
173
|
+
memoryType: 'text',
|
|
174
|
+
expiresAt: ttl ? this.calculateExpiresAt(ttl) : undefined,
|
|
175
|
+
};
|
|
176
|
+
const vectorChunks = await this._createVectorChunks(text, metadata, syntheticPath);
|
|
177
|
+
await this.vectorStore.deleteChunks(syntheticPath);
|
|
178
|
+
await this.vectorStore.insertChunks(vectorChunks);
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Ingests content from a URL.
|
|
183
|
+
*/
|
|
184
|
+
ingestUrl(input) {
|
|
185
|
+
return this.writeExecutor.execute(async () => {
|
|
186
|
+
const { url, tags, project, ttl } = input;
|
|
187
|
+
const label = basename(new URL(url).pathname) || `web-${Date.now()}`;
|
|
188
|
+
const response = await fetch(url);
|
|
189
|
+
if (!response.ok)
|
|
190
|
+
throw new Error(`Failed to fetch URL: ${response.statusText}`);
|
|
191
|
+
const htmlContent = await response.text();
|
|
192
|
+
const text = await parseHtmlContent(url, htmlContent);
|
|
193
|
+
const syntheticPath = `url://${label}`;
|
|
194
|
+
const metadata = {
|
|
195
|
+
fileName: label,
|
|
196
|
+
fileSize: text.length,
|
|
197
|
+
fileType: 'web-page',
|
|
198
|
+
tags: tags ?? [],
|
|
199
|
+
project,
|
|
200
|
+
memoryType: 'url',
|
|
201
|
+
expiresAt: ttl ? this.calculateExpiresAt(ttl) : undefined,
|
|
202
|
+
sourceUrl: url,
|
|
203
|
+
};
|
|
204
|
+
const vectorChunks = await this._createVectorChunks(text, metadata, syntheticPath);
|
|
205
|
+
await this.vectorStore.deleteChunks(syntheticPath);
|
|
206
|
+
await this.vectorStore.insertChunks(vectorChunks);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Searches the vector store with a natural language query.
|
|
211
|
+
*/
|
|
212
|
+
async query(input) {
|
|
213
|
+
const { query, limit, filters } = input;
|
|
214
|
+
const queryVector = await this.embedder.embed(query);
|
|
215
|
+
return this.vectorStore.search(queryVector, query, limit, filters);
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Updates an existing text snippet (memory).
|
|
219
|
+
*/
|
|
220
|
+
updateMemory(input) {
|
|
221
|
+
return this.writeExecutor.execute(async () => {
|
|
222
|
+
const { label, mode = 'replace', text: newText, tags, addTags, removeTags } = input;
|
|
223
|
+
const syntheticPath = `memory://${label}`;
|
|
224
|
+
const existingChunks = await this.vectorStore.getChunksByPath(syntheticPath);
|
|
225
|
+
if (existingChunks.length === 0)
|
|
226
|
+
throw new Error(`Memory with label "${label}" not found.`);
|
|
227
|
+
const oldMetadata = existingChunks[0].metadata;
|
|
228
|
+
let fullText = existingChunks
|
|
229
|
+
.sort((a, b) => a.chunkIndex - b.chunkIndex)
|
|
230
|
+
.map((c) => c.text)
|
|
231
|
+
.join('');
|
|
232
|
+
if (newText) {
|
|
233
|
+
if (mode === 'append')
|
|
234
|
+
fullText += newText;
|
|
235
|
+
else if (mode === 'prepend')
|
|
236
|
+
fullText = newText + fullText;
|
|
237
|
+
else
|
|
238
|
+
fullText = newText;
|
|
239
|
+
}
|
|
240
|
+
let newTags = oldMetadata?.tags ?? [];
|
|
241
|
+
if (tags)
|
|
242
|
+
newTags = tags; // Replace
|
|
243
|
+
if (addTags)
|
|
244
|
+
newTags = [...new Set([...newTags, ...addTags])];
|
|
245
|
+
if (removeTags)
|
|
246
|
+
newTags = newTags.filter((t) => !removeTags.includes(t));
|
|
247
|
+
const updatedMetadata = {
|
|
248
|
+
...oldMetadata,
|
|
249
|
+
tags: newTags,
|
|
250
|
+
fileSize: fullText.length,
|
|
251
|
+
};
|
|
252
|
+
const vectorChunks = await this._createVectorChunks(fullText, updatedMetadata, syntheticPath);
|
|
253
|
+
await this.vectorStore.deleteChunks(syntheticPath);
|
|
254
|
+
await this.vectorStore.insertChunks(vectorChunks);
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Deletes a file or snippet from the vector store.
|
|
259
|
+
*/
|
|
260
|
+
delete(path) {
|
|
261
|
+
return this.writeExecutor.execute(async () => {
|
|
262
|
+
// Path can be an absolute file path or a synthetic path like `memory://label`
|
|
263
|
+
await this.vectorStore.deleteChunks(path);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Lists all items in the vector store, with optional filtering and pagination.
|
|
268
|
+
*/
|
|
269
|
+
async list(options) {
|
|
270
|
+
return this.vectorStore.listFiles(options);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Retrieves the current status of the RAG system.
|
|
274
|
+
*/
|
|
275
|
+
async getStatus() {
|
|
276
|
+
return this.vectorStore.getStatus();
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Manually triggers a cleanup of all expired text snippets from the database.
|
|
280
|
+
*/
|
|
281
|
+
cleanupExpired() {
|
|
282
|
+
return this.writeExecutor.execute(() => this.vectorStore.cleanupExpired());
|
|
283
|
+
}
|
|
284
|
+
watch(path, options = {}) {
|
|
285
|
+
return this.writeExecutor.execute(async () => {
|
|
286
|
+
const absolutePath = resolve(path);
|
|
287
|
+
if (this.watcher.isWatching(absolutePath))
|
|
288
|
+
return;
|
|
289
|
+
const stats = await stat(absolutePath);
|
|
290
|
+
const type = stats.isDirectory() ? 'folder' : 'file';
|
|
291
|
+
const recursive = type === 'folder' ? (options.recursive ?? false) : false;
|
|
292
|
+
await this.vectorStore.addWatchedPath(absolutePath, type, recursive);
|
|
293
|
+
this.watcher.watch(absolutePath);
|
|
294
|
+
logger.info(`Now watching path: ${absolutePath}`);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
unwatch(path) {
|
|
298
|
+
return this.writeExecutor.execute(async () => {
|
|
299
|
+
const absolutePath = resolve(path);
|
|
300
|
+
await this.vectorStore.removeWatchedPath(absolutePath);
|
|
301
|
+
this.watcher.unwatch(absolutePath);
|
|
302
|
+
logger.info(`Stopped watching path: ${absolutePath}`);
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
// ============================================
|
|
306
|
+
// Private Helper Methods
|
|
307
|
+
// ============================================
|
|
308
|
+
startPeriodicJobs() {
|
|
309
|
+
if (this.config.cleanupIntervalMs && this.config.cleanupIntervalMs > 0) {
|
|
310
|
+
logger.info(`Starting periodic cleanup job every ${this.config.cleanupIntervalMs}ms.`);
|
|
311
|
+
this.cleanupIntervalId = setInterval(async () => {
|
|
312
|
+
try {
|
|
313
|
+
logger.info('Running periodic cleanup job...');
|
|
314
|
+
const deletedCount = await this.cleanupExpired();
|
|
315
|
+
if (deletedCount > 0) {
|
|
316
|
+
logger.info(`Periodic cleanup job finished. Removed ${deletedCount} expired items.`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
logger.error('Periodic cleanup job failed.', error);
|
|
321
|
+
}
|
|
322
|
+
}, this.config.cleanupIntervalMs);
|
|
323
|
+
}
|
|
324
|
+
if (this.config.optimizeIntervalMs && this.config.optimizeIntervalMs > 0) {
|
|
325
|
+
logger.info(`Starting periodic DB optimization every ${this.config.optimizeIntervalMs}ms.`);
|
|
326
|
+
this.optimizeIntervalId = setInterval(async () => {
|
|
327
|
+
try {
|
|
328
|
+
await this.vectorStore.optimize();
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
logger.error('Periodic database optimization failed.', error);
|
|
332
|
+
}
|
|
333
|
+
}, this.config.optimizeIntervalMs);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
async findSupportedFiles(folderPath, recursive) {
|
|
337
|
+
const supportedExtensions = new Set(this.parser.getSupportedExtensions());
|
|
338
|
+
const files = [];
|
|
339
|
+
const entries = await readdir(folderPath, { withFileTypes: true });
|
|
340
|
+
for (const entry of entries) {
|
|
341
|
+
const fullPath = join(folderPath, entry.name);
|
|
342
|
+
if (entry.isDirectory() && recursive) {
|
|
343
|
+
files.push(...(await this.findSupportedFiles(fullPath, true)));
|
|
344
|
+
}
|
|
345
|
+
else if (entry.isFile() && supportedExtensions.has(extname(entry.name).toLowerCase())) {
|
|
346
|
+
files.push(fullPath);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
return files;
|
|
350
|
+
}
|
|
351
|
+
setupWatcherListeners() {
|
|
352
|
+
const handleIngest = async (filePath) => {
|
|
353
|
+
try {
|
|
354
|
+
await this.ingestFile({ filePath });
|
|
355
|
+
}
|
|
356
|
+
catch (error) {
|
|
357
|
+
if (error instanceof ValidationError && error.message.includes('Unsupported file format')) {
|
|
358
|
+
// This is expected when the watcher picks up an unsupported file. Ignore it.
|
|
359
|
+
logger.debug(`Watcher ignored unsupported file: ${filePath}`);
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
// Log any other unexpected errors during ingestion.
|
|
363
|
+
logger.error(`Watcher failed to process file ${filePath}.`, error);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
this.watcher.on('file-added', handleIngest);
|
|
368
|
+
this.watcher.on('file-changed', handleIngest);
|
|
369
|
+
this.watcher.on('file-deleted', (filePath) => this.delete(filePath).catch((e) => logger.error(e, `Watcher failed to delete file: ${filePath}`)));
|
|
370
|
+
}
|
|
371
|
+
calculateExpiresAt(ttl) {
|
|
372
|
+
const match = ttl.match(/^(\d+)([dhy])$/);
|
|
373
|
+
if (!match)
|
|
374
|
+
throw new ValidationError(`Invalid TTL format: ${ttl}. Use '1d', '7h', '1y' etc.`);
|
|
375
|
+
const value = parseInt(match[1], 10);
|
|
376
|
+
const unit = match[2];
|
|
377
|
+
const date = new Date();
|
|
378
|
+
if (unit === 'd')
|
|
379
|
+
date.setDate(date.getDate() + value);
|
|
380
|
+
else if (unit === 'h')
|
|
381
|
+
date.setHours(date.getHours() + value);
|
|
382
|
+
else if (unit === 'y')
|
|
383
|
+
date.setFullYear(date.getFullYear() + value);
|
|
384
|
+
return date.toISOString();
|
|
385
|
+
}
|
|
386
|
+
async _createVectorChunks(text, baseMetadata, path) {
|
|
387
|
+
const chunks = await this.chunker.chunkText(text);
|
|
388
|
+
if (chunks.length === 0)
|
|
389
|
+
return [];
|
|
390
|
+
const embeddings = await this.embedder.embedBatch(chunks.map((c) => c.text));
|
|
391
|
+
const now = new Date().toISOString();
|
|
392
|
+
return chunks.map((chunk, i) => ({
|
|
393
|
+
id: randomUUID(),
|
|
394
|
+
filePath: path,
|
|
395
|
+
chunkIndex: chunk.index,
|
|
396
|
+
text: chunk.text,
|
|
397
|
+
vector: embeddings[i],
|
|
398
|
+
metadata: {
|
|
399
|
+
fileName: '', // Default values, will be overwritten
|
|
400
|
+
fileSize: 0,
|
|
401
|
+
fileType: '',
|
|
402
|
+
createdAt: now,
|
|
403
|
+
updatedAt: now,
|
|
404
|
+
...baseMetadata,
|
|
405
|
+
},
|
|
406
|
+
timestamp: now,
|
|
407
|
+
}));
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/local-rag/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { DocumentMetadata } from './types.js';
|
|
2
|
+
export interface ParserConfig {
|
|
3
|
+
baseDir: string;
|
|
4
|
+
maxFileSize: number;
|
|
5
|
+
}
|
|
6
|
+
export interface ParsedFile {
|
|
7
|
+
text: string;
|
|
8
|
+
language?: string;
|
|
9
|
+
fileSize: number;
|
|
10
|
+
metadata: Partial<DocumentMetadata>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Parses text content from various file formats.
|
|
14
|
+
* Extracts basic metadata and transforms structured content for better RAG performance.
|
|
15
|
+
*/
|
|
16
|
+
export declare class DocumentParser {
|
|
17
|
+
private readonly config;
|
|
18
|
+
constructor(config: ParserConfig);
|
|
19
|
+
/**
|
|
20
|
+
* Parses a file, automatically detecting its format.
|
|
21
|
+
* @param filePath - The path to the file to parse.
|
|
22
|
+
* @returns The extracted text, detected language (for code files), and file size.
|
|
23
|
+
*/
|
|
24
|
+
parseFile(filePath: string): Promise<ParsedFile>;
|
|
25
|
+
/**
|
|
26
|
+
* Returns a list of all supported file extensions.
|
|
27
|
+
* @returns An array of file extensions (e.g., ['.pdf', '.ts', '.md']).
|
|
28
|
+
*/
|
|
29
|
+
getSupportedExtensions(): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Validates that a file path is absolute and within the configured `baseDir`.
|
|
32
|
+
* @param filePath - The absolute path to validate.
|
|
33
|
+
* @throws {ValidationError} If the path is invalid or outside the security boundary.
|
|
34
|
+
*/
|
|
35
|
+
validateFilePath(filePath: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Validates that a file's size is within the configured limit.
|
|
38
|
+
* @param filePath - The path to the file to check.
|
|
39
|
+
* @returns The file size in bytes.
|
|
40
|
+
* @throws {ValidationError} If the file is too large.
|
|
41
|
+
* @throws {FileOperationError} If the file stats cannot be read.
|
|
42
|
+
*/
|
|
43
|
+
validateAndGetFileStats(filePath: string): Promise<{
|
|
44
|
+
fileSize: number;
|
|
45
|
+
fileCreatedAt: string;
|
|
46
|
+
fileModifiedAt: string;
|
|
47
|
+
}>;
|
|
48
|
+
private detectLanguage;
|
|
49
|
+
private parsePdf;
|
|
50
|
+
private parseDocx;
|
|
51
|
+
private parseJson;
|
|
52
|
+
/**
|
|
53
|
+
* Parses CSV into a text format where each row preserves the header context.
|
|
54
|
+
* This is crucial for the semantic meaning of chunks.
|
|
55
|
+
*/
|
|
56
|
+
private parseStructuredCsv;
|
|
57
|
+
private parseAsPlainText;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/local-rag/parser.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AA6BlD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;CACpC;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,MAAM,EAAE,YAAY;IAIhC;;;;OAIG;IACU,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IA4C7D;;;OAGG;IACI,sBAAsB,IAAI,MAAM,EAAE;IAMzC;;;;OAIG;IACI,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAa/C;;;;;;OAMG;IACU,uBAAuB,CAClC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IAiB/E,OAAO,CAAC,cAAc;YAIR,QAAQ;YAaR,SAAS;YAWT,SAAS;IAWvB;;;OAGG;YACW,kBAAkB;YAuBlB,gBAAgB;CAO/B"}
|