@psiclawops/hypermem 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.
Files changed (94) hide show
  1. package/ARCHITECTURE.md +296 -0
  2. package/LICENSE +190 -0
  3. package/README.md +243 -0
  4. package/dist/background-indexer.d.ts +117 -0
  5. package/dist/background-indexer.d.ts.map +1 -0
  6. package/dist/background-indexer.js +732 -0
  7. package/dist/compaction-fence.d.ts +89 -0
  8. package/dist/compaction-fence.d.ts.map +1 -0
  9. package/dist/compaction-fence.js +153 -0
  10. package/dist/compositor.d.ts +139 -0
  11. package/dist/compositor.d.ts.map +1 -0
  12. package/dist/compositor.js +1109 -0
  13. package/dist/cross-agent.d.ts +57 -0
  14. package/dist/cross-agent.d.ts.map +1 -0
  15. package/dist/cross-agent.js +254 -0
  16. package/dist/db.d.ts +131 -0
  17. package/dist/db.d.ts.map +1 -0
  18. package/dist/db.js +398 -0
  19. package/dist/desired-state-store.d.ts +100 -0
  20. package/dist/desired-state-store.d.ts.map +1 -0
  21. package/dist/desired-state-store.js +212 -0
  22. package/dist/doc-chunk-store.d.ts +115 -0
  23. package/dist/doc-chunk-store.d.ts.map +1 -0
  24. package/dist/doc-chunk-store.js +278 -0
  25. package/dist/doc-chunker.d.ts +99 -0
  26. package/dist/doc-chunker.d.ts.map +1 -0
  27. package/dist/doc-chunker.js +324 -0
  28. package/dist/episode-store.d.ts +48 -0
  29. package/dist/episode-store.d.ts.map +1 -0
  30. package/dist/episode-store.js +135 -0
  31. package/dist/fact-store.d.ts +57 -0
  32. package/dist/fact-store.d.ts.map +1 -0
  33. package/dist/fact-store.js +175 -0
  34. package/dist/fleet-store.d.ts +144 -0
  35. package/dist/fleet-store.d.ts.map +1 -0
  36. package/dist/fleet-store.js +276 -0
  37. package/dist/hybrid-retrieval.d.ts +60 -0
  38. package/dist/hybrid-retrieval.d.ts.map +1 -0
  39. package/dist/hybrid-retrieval.js +340 -0
  40. package/dist/index.d.ts +611 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +1042 -0
  43. package/dist/knowledge-graph.d.ts +110 -0
  44. package/dist/knowledge-graph.d.ts.map +1 -0
  45. package/dist/knowledge-graph.js +305 -0
  46. package/dist/knowledge-store.d.ts +72 -0
  47. package/dist/knowledge-store.d.ts.map +1 -0
  48. package/dist/knowledge-store.js +241 -0
  49. package/dist/library-schema.d.ts +22 -0
  50. package/dist/library-schema.d.ts.map +1 -0
  51. package/dist/library-schema.js +717 -0
  52. package/dist/message-store.d.ts +76 -0
  53. package/dist/message-store.d.ts.map +1 -0
  54. package/dist/message-store.js +273 -0
  55. package/dist/preference-store.d.ts +54 -0
  56. package/dist/preference-store.d.ts.map +1 -0
  57. package/dist/preference-store.js +109 -0
  58. package/dist/preservation-gate.d.ts +82 -0
  59. package/dist/preservation-gate.d.ts.map +1 -0
  60. package/dist/preservation-gate.js +150 -0
  61. package/dist/provider-translator.d.ts +40 -0
  62. package/dist/provider-translator.d.ts.map +1 -0
  63. package/dist/provider-translator.js +349 -0
  64. package/dist/rate-limiter.d.ts +76 -0
  65. package/dist/rate-limiter.d.ts.map +1 -0
  66. package/dist/rate-limiter.js +179 -0
  67. package/dist/redis.d.ts +188 -0
  68. package/dist/redis.d.ts.map +1 -0
  69. package/dist/redis.js +534 -0
  70. package/dist/schema.d.ts +15 -0
  71. package/dist/schema.d.ts.map +1 -0
  72. package/dist/schema.js +203 -0
  73. package/dist/secret-scanner.d.ts +51 -0
  74. package/dist/secret-scanner.d.ts.map +1 -0
  75. package/dist/secret-scanner.js +248 -0
  76. package/dist/seed.d.ts +108 -0
  77. package/dist/seed.d.ts.map +1 -0
  78. package/dist/seed.js +177 -0
  79. package/dist/system-store.d.ts +73 -0
  80. package/dist/system-store.d.ts.map +1 -0
  81. package/dist/system-store.js +182 -0
  82. package/dist/topic-store.d.ts +45 -0
  83. package/dist/topic-store.d.ts.map +1 -0
  84. package/dist/topic-store.js +136 -0
  85. package/dist/types.d.ts +329 -0
  86. package/dist/types.d.ts.map +1 -0
  87. package/dist/types.js +9 -0
  88. package/dist/vector-store.d.ts +132 -0
  89. package/dist/vector-store.d.ts.map +1 -0
  90. package/dist/vector-store.js +498 -0
  91. package/dist/work-store.d.ts +112 -0
  92. package/dist/work-store.d.ts.map +1 -0
  93. package/dist/work-store.js +273 -0
  94. package/package.json +57 -0
package/README.md ADDED
@@ -0,0 +1,243 @@
1
+ # HyperMem
2
+
3
+ Agent-centric memory system for OpenClaw. Four-layer architecture: Redis hot cache → per-agent message DB → per-agent vector DB → shared fleet library.
4
+
5
+ **Status:** Core complete + context engine plugin shipped. 29 modules, ~12,300 lines, 419 tests across 11 suites. All passing.
6
+
7
+ ## What It Does
8
+
9
+ HyperMem replaces the default OpenClaw context assembly pipeline. Instead of the runtime managing conversation history and compaction, HyperMem owns the full prompt composition lifecycle:
10
+
11
+ 1. **Records** every message to SQLite (L2) and Redis (L1) as it arrives
12
+ 2. **Indexes** conversations and workspace files for semantic retrieval (L3)
13
+ 3. **Composes** each LLM prompt fresh from storage — facts, knowledge, history, recall — within a strict token budget
14
+ 4. **Owns compaction** — the runtime's legacy compaction is bypassed entirely; HyperMem handles its own context management
15
+
16
+ This means agents get structured, budget-aware context every turn instead of a growing transcript that eventually gets summarized.
17
+
18
+ ## Architecture
19
+
20
+ See [ARCHITECTURE.md](./ARCHITECTURE.md) for the full design.
21
+
22
+ ```
23
+ L1 Redis Hot session cache (sub-ms reads, identity kernel, fleet cache)
24
+ L2 Messages DB Per-agent conversation history (SQLite, rotatable)
25
+ L3 Vectors DB Per-agent semantic search (sqlite-vec, 768d embeddings)
26
+ L4 Library DB Fleet-wide structured knowledge (10 collections + knowledge graph)
27
+ ```
28
+
29
+ ### Key Components
30
+
31
+ - **Compositor** — Assembles LLM prompts from all 4 layers with token budgeting. Each slot gets a proportional cap of remaining budget (facts 30%, knowledge 20%, preferences 10%, cross-session 20%). Post-assembly safety valve catches estimation drift and trims history to fit. Multi-provider output (Anthropic + OpenAI).
32
+ - **Context Engine Plugin** — OpenClaw plugin (`plugin/src/index.ts`) that registers HyperMem as a context engine. Owns compaction, translates between OpenClaw's runtime events and HyperMem's storage/composition pipeline. Drop-in replacement for the default context assembly.
33
+ - **Hybrid Retrieval** — Combined FTS5 full-text search + KNN vector similarity with Reciprocal Rank Fusion for recall quality.
34
+ - **Doc Chunker** — Section-aware markdown/file parser that splits workspace documents into semantically meaningful chunks for indexing.
35
+ - **Workspace Seeder** — Indexes workspace files (AGENTS.md, SOUL.md, POLICY.md, daily memory, etc.) into L4 collections with idempotent re-indexing and source-hash deduplication.
36
+ - **Fleet Cache** — Redis hot layer for agent profiles + fleet summary. Cache-aside reads, write-through invalidation, bulk hydration on gateway startup.
37
+ - **Knowledge Graph** — DAG traversal over entity relationships. BFS with depth/direction/type filters, shortest path, degree analytics.
38
+ - **Rate Limiter** — Token-bucket for embedding API calls. Priority queue (high > normal > low) with reserved tokens for user-facing recall.
39
+ - **Secret Scanner** — Scans content for API keys, tokens, and credentials before storage. Prevents accidental persistence of secrets.
40
+ - **Provider Translator** — Converts between neutral internal format and Anthropic/OpenAI at the output boundary. Handles tool call ID round-tripping.
41
+ - **Message Rotation** — Automatic rotation of message DBs at 100MB / 90 days. WAL checkpoint before rotate.
42
+ - **Background Indexer** — LLM-powered fact/knowledge extraction from conversations (framework complete).
43
+
44
+ ### Library Collections (L4)
45
+
46
+ | Collection | Purpose |
47
+ |---|---|
48
+ | Facts | Verifiable claims with confidence, domain, expiry, supersedes chains |
49
+ | Knowledge | Domain/key/value structured data with FTS |
50
+ | Episodes | Significant events with impact and participants |
51
+ | Topics | Cross-session thread tracking |
52
+ | Preferences | Operator/user behavioral patterns |
53
+ | Fleet Registry | Agent registry with tier, org, capabilities |
54
+ | System Registry | Service state and lifecycle tracking |
55
+ | Work Items | Work queue with status transitions and FTS5 |
56
+ | Session Registry | Session lifecycle tracking |
57
+ | Desired State | Per-agent config with automatic drift detection |
58
+
59
+ ## Context Engine Plugin
60
+
61
+ The plugin (`plugin/`) is how HyperMem integrates with OpenClaw. It implements the `ContextEngine` interface:
62
+
63
+ ```typescript
64
+ // plugin registers as a context engine with:
65
+ {
66
+ id: 'hypermem',
67
+ name: 'HyperMem Context Engine',
68
+ version: '0.1.0',
69
+ ownsCompaction: true, // runtime skips legacy compaction
70
+ }
71
+ ```
72
+
73
+ **Lifecycle hooks handled:**
74
+ | Event | Action |
75
+ |---|---|
76
+ | `gateway:startup` | Init HyperMem, auto-rotate DBs, hydrate fleet cache |
77
+ | `agent:bootstrap` | Warm session (history, facts, profile → Redis) |
78
+ | `message:received` | Record user message to SQLite + Redis |
79
+ | `message:sent` | Record assistant message to SQLite + Redis |
80
+ | `context:compose` | Full four-layer prompt assembly within token budget |
81
+
82
+ **Install:** Deployed as an OpenClaw managed hook at `~/.openclaw/hooks/hypermem-core/handler.js`. The plugin build step copies compiled output to this path.
83
+
84
+ ## Requirements
85
+
86
+ - **Node.js 22+** (uses built-in `node:sqlite`)
87
+ - **Redis 7+** (optional — all operations degrade gracefully to SQLite-only)
88
+ - **Ollama** (optional — for embedding generation, model: `nomic-embed-text`, 768d)
89
+ - **sqlite-vec** (optional — for vector search)
90
+
91
+ ## Quick Start
92
+
93
+ ```bash
94
+ npm install
95
+ npm run build # TypeScript compilation + hook deployment
96
+
97
+ # Run all tests (requires Redis on localhost:6379 for full suite)
98
+ npm test
99
+
100
+ # Quick smoke test (SQLite-only, no external deps)
101
+ npm run test:quick
102
+ ```
103
+
104
+ ### Test Suites
105
+
106
+ ```bash
107
+ npm test # All 11 suites (419 tests)
108
+ npm run test:quick # smoke + library + compositor
109
+ ```
110
+
111
+ ## Data Directory
112
+
113
+ ```
114
+ ~/.openclaw/hypermem/
115
+ ├── library.db # Fleet-wide shared knowledge (L4)
116
+ └── agents/
117
+ └── {agentId}/
118
+ ├── messages.db # Current conversation DB (L2)
119
+ ├── messages_2026Q1.db # Rotated archive (read-only)
120
+ └── vectors.db # Semantic search index (L3)
121
+ ```
122
+
123
+ ## API
124
+
125
+ ```typescript
126
+ import { HyperMem } from '@psiclawops/hypermem';
127
+
128
+ const hm = await HyperMem.create({
129
+ agentId: 'forge',
130
+ dataDir: '~/.openclaw/hypermem',
131
+ redis: { host: 'localhost', port: 6379 },
132
+ ollama: { host: 'http://localhost:11434', model: 'nomic-embed-text' }
133
+ });
134
+
135
+ // Record messages
136
+ await hm.recordUserMessage(conversationId, 'How does drift detection work?');
137
+ await hm.recordAssistantMessage(conversationId, 'Drift detection compares...');
138
+
139
+ // Compose prompt (all 4 layers, budget-aware)
140
+ const composed = await hm.compose({
141
+ agentId: 'forge',
142
+ sessionKey: 'agent:forge:webchat:main',
143
+ tokenBudget: 4000,
144
+ provider: 'anthropic'
145
+ });
146
+
147
+ // Hybrid retrieval (FTS + vector)
148
+ const results = await hm.hybridSearch('drift detection', {
149
+ limit: 10,
150
+ ftsWeight: 0.4,
151
+ vectorWeight: 0.6
152
+ });
153
+
154
+ // Fleet operations
155
+ await hm.upsertFleetAgent({ id: 'forge', displayName: 'Forge', tier: 'council' });
156
+ await hm.setDesiredState('forge', 'model', 'anthropic/claude-opus-4-6', 'ragesaq');
157
+ const drifted = await hm.getDriftedState();
158
+
159
+ // Semantic search
160
+ const similar = await hm.searchSimilar('drift detection', { limit: 5, threshold: 0.8 });
161
+
162
+ // Knowledge graph
163
+ await hm.addKnowledgeLink('fact', factId, 'knowledge', knowledgeId, 'supports');
164
+ const related = await hm.traverseKnowledge('fact', factId, { maxDepth: 3 });
165
+
166
+ // Workspace indexing
167
+ await hm.seedWorkspace('/path/to/workspace');
168
+
169
+ // Cleanup
170
+ await hm.close();
171
+ ```
172
+
173
+ ## Test Coverage
174
+
175
+ | Suite | Tests | What's Covered |
176
+ |---|---|---|
177
+ | smoke | 10 | End-to-end create/write/read/close, provider translation |
178
+ | redis-integration | 24 | Redis slots, history, pub/sub |
179
+ | cross-agent | 20 | Cross-agent queries, fleet search, visibility tiers |
180
+ | vector-search | 33 | Embedding, KNN, batch indexing |
181
+ | library | 71 | All L4 collections (facts → desired state) |
182
+ | compositor | 50 | Four-layer composition, budgets, providers, safety valve |
183
+ | fleet-cache | 32 | Redis fleet cache, hydration, cache-aside |
184
+ | rotation | 29 | DB rotation, auto-rotate, collision handling |
185
+ | knowledge-graph | 33 | DAG traversal, shortest path, analytics |
186
+ | rate-limiter | 22 | Token bucket, priority, timeout, embedder |
187
+ | doc-chunker | 105 | Markdown/file chunking, section-aware parsing, seeder |
188
+ | **Total** | **419** | |
189
+
190
+ ## Module Map
191
+
192
+ 29 source files, ~12,300 lines:
193
+
194
+ | Module | Lines | Layer | Purpose |
195
+ |---|---|---|---|
196
+ | `index.ts` | ~1,340 | All | Facade — all public API |
197
+ | `compositor.ts` | ~1,030 | L1-L4 | Prompt assembly + token budgeting + safety valve |
198
+ | `library-schema.ts` | ~780 | L4 | Library schema v5 + migrations |
199
+ | `background-indexer.ts` | ~680 | L2-L4 | LLM-powered extraction framework |
200
+ | `vector-store.ts` | ~600 | L3 | Semantic search + embedding |
201
+ | `hybrid-retrieval.ts` | ~450 | L3-L4 | FTS5 + KNN with Reciprocal Rank Fusion |
202
+ | `fleet-store.ts` | ~440 | L4 | Fleet registry + capabilities |
203
+ | `db.ts` | ~440 | - | Database manager + rotation |
204
+ | `knowledge-graph.ts` | ~420 | L4 | DAG traversal + shortest path |
205
+ | `redis.ts` | ~400 | L1 | Redis operations + fleet cache |
206
+ | `doc-chunker.ts` | ~400 | - | Section-aware markdown/file parser |
207
+ | `work-store.ts` | ~400 | L4 | Work queue + FTS5 |
208
+ | `provider-translator.ts` | ~390 | - | Neutral ↔ provider format conversion |
209
+ | `doc-chunk-store.ts` | ~375 | L4 | Chunk storage + deduplication |
210
+ | `message-store.ts` | ~370 | L2 | Conversation recording + querying |
211
+ | `types.ts` | ~330 | - | Shared type definitions |
212
+ | `cross-agent.ts` | ~330 | L2-L4 | Cross-agent knowledge queries + visibility |
213
+ | `desired-state-store.ts` | ~310 | L4 | Config drift detection |
214
+ | `knowledge-store.ts` | ~300 | L4 | Domain/key/value structured data |
215
+ | `secret-scanner.ts` | ~285 | - | Credential/secret detection |
216
+ | `system-store.ts` | ~250 | L4 | Service state tracking |
217
+ | `seed.ts` | ~250 | L4 | Workspace seeder + collection inference |
218
+ | `fact-store.ts` | ~230 | L4 | Facts with confidence + expiry |
219
+ | `rate-limiter.ts` | ~230 | L3 | Token-bucket for embedding API |
220
+ | `schema.ts` | ~200 | L2 | Messages schema + migrations |
221
+ | `episode-store.ts` | ~180 | L4 | Significant event tracking |
222
+ | `preference-store.ts` | ~170 | L4 | Operator behavioral patterns |
223
+ | `topic-store.ts` | ~160 | L4 | Cross-session thread tracking |
224
+ | `plugin/src/index.ts` | ~550 | - | OpenClaw context engine plugin |
225
+
226
+ ## Roadmap
227
+
228
+ - [x] ~~Document chunk ingestion pipeline (section-aware markdown parsing)~~
229
+ - [x] ~~Workspace seeder with idempotent re-indexing~~
230
+ - [x] ~~Hybrid retrieval (FTS5 + KNN with RRF)~~
231
+ - [x] ~~Context engine plugin (OpenClaw integration)~~
232
+ - [x] ~~Compositor safety valve for budget overrun~~
233
+ - [x] ~~Own compaction (`ownsCompaction: true`)~~
234
+ - [ ] Background indexer activation (LLM extraction from live conversations)
235
+ - [ ] Versioned atomic re-indexing (source hash + transactional swap)
236
+ - [ ] Bootstrap seed command (`hypermem seed --workspace`)
237
+ - [ ] npm publish to registry
238
+ - [ ] Live org registry (replace hardcoded `defaultOrgRegistry()` with library.db lookup)
239
+ - [ ] Embedding model hot-swap (currently pinned to nomic-embed-text)
240
+
241
+ ## License
242
+
243
+ Private — PsiClawOps
@@ -0,0 +1,117 @@
1
+ /**
2
+ * HyperMem Background Indexer
3
+ *
4
+ * Processes message history to extract structured knowledge:
5
+ * - Facts: atomic pieces of learned information
6
+ * - Episodes: significant events worth remembering
7
+ * - Topics: conversation threads and their lifecycle
8
+ * - Knowledge: durable structured entries (domain + key)
9
+ *
10
+ * Runs as a periodic background task, processing unindexed messages
11
+ * in batches. Each batch is scored, classified, and stored in L4 (library.db).
12
+ *
13
+ * Design principles:
14
+ * - No LLM dependency: extraction uses pattern matching + heuristics
15
+ * - Idempotent: tracks watermarks per agent to avoid reprocessing
16
+ * - Bounded: processes N messages per tick to avoid blocking
17
+ * - Observable: logs extraction stats for monitoring
18
+ */
19
+ import type { DatabaseSync } from 'node:sqlite';
20
+ import type { IndexerConfig, SessionCursor } from './types.js';
21
+ import type { VectorStore } from './vector-store.js';
22
+ export interface IndexerStats {
23
+ agentId: string;
24
+ messagesProcessed: number;
25
+ factsExtracted: number;
26
+ episodesRecorded: number;
27
+ topicsUpdated: number;
28
+ knowledgeUpserted: number;
29
+ elapsedMs: number;
30
+ /** Number of messages that were post-cursor (unseen by model, high-signal priority). */
31
+ postCursorMessages: number;
32
+ }
33
+ /**
34
+ * Optional callback to fetch the session cursor for an agent+session.
35
+ * When provided, the indexer uses the cursor to prioritize unseen messages.
36
+ * The cursor boundary separates "model has seen this" from "new since last compose".
37
+ */
38
+ export type CursorFetcher = (agentId: string, sessionKey: string) => Promise<SessionCursor | null>;
39
+ export interface WatermarkState {
40
+ agentId: string;
41
+ lastMessageId: number;
42
+ lastRunAt: string;
43
+ }
44
+ export declare class BackgroundIndexer {
45
+ private getMessageDb?;
46
+ private getLibraryDb?;
47
+ private listAgents?;
48
+ private getCursor?;
49
+ private readonly config;
50
+ private intervalHandle;
51
+ private running;
52
+ private vectorStore;
53
+ constructor(config?: Partial<IndexerConfig>, getMessageDb?: ((agentId: string) => DatabaseSync) | undefined, getLibraryDb?: (() => DatabaseSync) | undefined, listAgents?: (() => string[]) | undefined, getCursor?: CursorFetcher | undefined);
54
+ /**
55
+ * Set the vector store for embedding new facts/episodes at index time.
56
+ * Optional — if not set, indexer runs without embedding (FTS5-only mode).
57
+ */
58
+ setVectorStore(vs: VectorStore): void;
59
+ /**
60
+ * Start periodic indexing.
61
+ */
62
+ start(): void;
63
+ /**
64
+ * Stop periodic indexing.
65
+ */
66
+ stop(): void;
67
+ /**
68
+ * Run one indexing pass across all agents.
69
+ */
70
+ tick(): Promise<IndexerStats[]>;
71
+ /**
72
+ * Process a single agent's unindexed messages.
73
+ *
74
+ * When a cursor fetcher is available, messages are split into two tiers:
75
+ * - Post-cursor (id > cursor.lastSentId): "unseen" by the model, high-signal priority
76
+ * - Pre-cursor (id <= cursor.lastSentId): already in the model's context window, lower priority
77
+ * Post-cursor messages are processed first. This ensures the indexer prioritizes
78
+ * content the model hasn't seen yet — decisions, incidents, and discoveries that
79
+ * happened between context windows.
80
+ */
81
+ private processAgent;
82
+ /**
83
+ * Fetch unindexed messages for an agent.
84
+ */
85
+ private getUnindexedMessages;
86
+ /**
87
+ * Get the session key for a conversation ID.
88
+ */
89
+ private getSessionKeyForMessage;
90
+ /**
91
+ * Get the indexing watermark for an agent.
92
+ */
93
+ private getWatermark;
94
+ /**
95
+ * Set the indexing watermark for an agent.
96
+ */
97
+ private setWatermark;
98
+ /**
99
+ * Apply time-based decay to facts.
100
+ * Increases decay_score for older facts, making them less relevant.
101
+ */
102
+ private applyDecay;
103
+ /**
104
+ * Parse a duration string like "24h", "7d" into seconds.
105
+ */
106
+ private parseDuration;
107
+ /**
108
+ * Get current watermarks for all agents.
109
+ */
110
+ getWatermarks(libraryDb: DatabaseSync): WatermarkState[];
111
+ }
112
+ /**
113
+ * Create and start a background indexer connected to HyperMem databases.
114
+ * Used by the hook or a standalone daemon.
115
+ */
116
+ export declare function createIndexer(getMessageDb: (agentId: string) => DatabaseSync, getLibraryDb: () => DatabaseSync, listAgents: () => string[], config?: Partial<IndexerConfig>, getCursor?: CursorFetcher, vectorStore?: VectorStore): BackgroundIndexer;
117
+ //# sourceMappingURL=background-indexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"background-indexer.d.ts","sourceRoot":"","sources":["../src/background-indexer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAiB,aAAa,EAAe,aAAa,EAAE,MAAM,YAAY,CAAC;AAO3F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,wFAAwF;IACxF,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;AAEnG,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAgVD,qBAAa,iBAAiB;IAQ1B,OAAO,CAAC,YAAY,CAAC;IACrB,OAAO,CAAC,YAAY,CAAC;IACrB,OAAO,CAAC,UAAU,CAAC;IACnB,OAAO,CAAC,SAAS,CAAC;IAVpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,WAAW,CAA4B;gBAG7C,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,EACvB,YAAY,CAAC,GAAE,CAAC,OAAO,EAAE,MAAM,KAAK,YAAY,aAAA,EAChD,YAAY,CAAC,GAAE,MAAM,YAAY,aAAA,EACjC,UAAU,CAAC,GAAE,MAAM,MAAM,EAAE,aAAA,EAC3B,SAAS,CAAC,EAAE,aAAa,YAAA;IAanC;;;OAGG;IACH,cAAc,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI;IAIrC;;OAEG;IACH,KAAK,IAAI,IAAI;IAmBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAiDrC;;;;;;;;;OASG;YACW,YAAY;IAkK1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IA+B5B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAK/B;;OAEG;IACH,OAAO,CAAC,YAAY;IAsBpB;;OAEG;IACH,OAAO,CAAC,YAAY;IAWpB;;;OAGG;IACH,OAAO,CAAC,UAAU;IA2ClB;;OAEG;IACH,OAAO,CAAC,aAAa;IAarB;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,YAAY,GAAG,cAAc,EAAE;CAezD;AAID;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,YAAY,EAC/C,YAAY,EAAE,MAAM,YAAY,EAChC,UAAU,EAAE,MAAM,MAAM,EAAE,EAC1B,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,EAC/B,SAAS,CAAC,EAAE,aAAa,EACzB,WAAW,CAAC,EAAE,WAAW,GACxB,iBAAiB,CAInB"}