@pcircle/footprint 1.0.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 (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +80 -0
  3. package/SKILL.md +355 -0
  4. package/dist/index.d.ts +19 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +690 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/lib/crypto/decrypt.d.ts +11 -0
  9. package/dist/lib/crypto/decrypt.d.ts.map +1 -0
  10. package/dist/lib/crypto/decrypt.js +30 -0
  11. package/dist/lib/crypto/decrypt.js.map +1 -0
  12. package/dist/lib/crypto/encrypt.d.ts +13 -0
  13. package/dist/lib/crypto/encrypt.d.ts.map +1 -0
  14. package/dist/lib/crypto/encrypt.js +24 -0
  15. package/dist/lib/crypto/encrypt.js.map +1 -0
  16. package/dist/lib/crypto/index.d.ts +6 -0
  17. package/dist/lib/crypto/index.d.ts.map +1 -0
  18. package/dist/lib/crypto/index.js +5 -0
  19. package/dist/lib/crypto/index.js.map +1 -0
  20. package/dist/lib/crypto/key-derivation.d.ts +30 -0
  21. package/dist/lib/crypto/key-derivation.d.ts.map +1 -0
  22. package/dist/lib/crypto/key-derivation.js +63 -0
  23. package/dist/lib/crypto/key-derivation.js.map +1 -0
  24. package/dist/lib/crypto/types.d.ts +22 -0
  25. package/dist/lib/crypto/types.d.ts.map +1 -0
  26. package/dist/lib/crypto/types.js +10 -0
  27. package/dist/lib/crypto/types.js.map +1 -0
  28. package/dist/lib/storage/database.d.ts +116 -0
  29. package/dist/lib/storage/database.d.ts.map +1 -0
  30. package/dist/lib/storage/database.js +390 -0
  31. package/dist/lib/storage/database.js.map +1 -0
  32. package/dist/lib/storage/export.d.ts +26 -0
  33. package/dist/lib/storage/export.d.ts.map +1 -0
  34. package/dist/lib/storage/export.js +113 -0
  35. package/dist/lib/storage/export.js.map +1 -0
  36. package/dist/lib/storage/git.d.ts +16 -0
  37. package/dist/lib/storage/git.d.ts.map +1 -0
  38. package/dist/lib/storage/git.js +55 -0
  39. package/dist/lib/storage/git.js.map +1 -0
  40. package/dist/lib/storage/index.d.ts +6 -0
  41. package/dist/lib/storage/index.d.ts.map +1 -0
  42. package/dist/lib/storage/index.js +5 -0
  43. package/dist/lib/storage/index.js.map +1 -0
  44. package/dist/lib/storage/schema.d.ts +17 -0
  45. package/dist/lib/storage/schema.d.ts.map +1 -0
  46. package/dist/lib/storage/schema.js +103 -0
  47. package/dist/lib/storage/schema.js.map +1 -0
  48. package/dist/lib/storage/types.d.ts +26 -0
  49. package/dist/lib/storage/types.d.ts.map +1 -0
  50. package/dist/lib/storage/types.js +2 -0
  51. package/dist/lib/storage/types.js.map +1 -0
  52. package/dist/test-helpers.d.ts +33 -0
  53. package/dist/test-helpers.d.ts.map +1 -0
  54. package/dist/test-helpers.js +108 -0
  55. package/dist/test-helpers.js.map +1 -0
  56. package/dist/types.d.ts +29 -0
  57. package/dist/types.d.ts.map +1 -0
  58. package/dist/types.js +2 -0
  59. package/dist/types.js.map +1 -0
  60. package/dist/ui/dashboard.html +965 -0
  61. package/dist/ui/detail.html +348 -0
  62. package/dist/ui/export.html +409 -0
  63. package/dist/ui/register.d.ts +7 -0
  64. package/dist/ui/register.d.ts.map +1 -0
  65. package/dist/ui/register.js +154 -0
  66. package/dist/ui/register.js.map +1 -0
  67. package/dist/ui-tmp/ui/export.html +409 -0
  68. package/package.json +78 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PCIRCLE, LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # @pcircle/footprint
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@pcircle/footprint)](https://www.npmjs.com/package/@pcircle/footprint)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
5
+
6
+ Model Context Protocol (MCP) server that automatically captures and encrypts LLM conversations as legal evidence.
7
+
8
+ ## Why EvidenceMCP?
9
+
10
+ - **Prove IP Ownership** - Timestamped evidence of LLM-assisted work
11
+ - **Zero Effort** - Automatic capture via MCP protocol
12
+ - **Privacy First** - End-to-end encrypted, locally stored
13
+ - **Legally Valid** - Git timestamps + SHA-256 checksums
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install -g @pcircle/footprint
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ 1. **Set environment variables:**
24
+ ```bash
25
+ export EVIDENCEMCP_DB_PATH="./evidence.db"
26
+ export EVIDENCEMCP_PASSWORD="your-secure-password"
27
+ ```
28
+
29
+ 2. **Configure Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
30
+ ```json
31
+ {
32
+ "mcpServers": {
33
+ "footprint": {
34
+ "command": "npx",
35
+ "args": ["footprint"],
36
+ "env": {
37
+ "EVIDENCEMCP_DB_PATH": "/path/to/evidence.db",
38
+ "EVIDENCEMCP_PASSWORD": "your-password"
39
+ }
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ 3. **Restart Claude Desktop** - Evidence collection starts automatically
46
+
47
+ ## Features
48
+
49
+ - 🔐 XChaCha20-Poly1305 encryption
50
+ - 🕒 Git commit timestamps
51
+ - đŸ“Ļ Tamper-proof ZIP exports
52
+ - 🔍 Search and retrieve evidence
53
+
54
+ ## MCP Tools
55
+
56
+ ### capture-evidence
57
+ Captures and encrypts an LLM conversation.
58
+
59
+ ### list-evidences
60
+ Lists all captured evidence with pagination.
61
+
62
+ ### get-evidence
63
+ Retrieves and decrypts specific evidence by ID.
64
+
65
+ ### export-evidences
66
+ Exports evidence to encrypted ZIP archive.
67
+
68
+ ## Security
69
+
70
+ - **Encryption**: XChaCha20-Poly1305 (256-bit)
71
+ - **Key Derivation**: Argon2id (OWASP recommended)
72
+ - **Storage**: Local SQLite with encrypted BLOBs
73
+
74
+ âš ī¸ **Store your password securely** - Loss means permanent data loss.
75
+
76
+ ## Support
77
+
78
+ - [Documentation](https://github.com/PCIRCLE-AI/footprint#readme)
79
+ - [Issues](https://github.com/PCIRCLE-AI/footprint/issues)
80
+ - [License](https://github.com/PCIRCLE-AI/footprint/blob/main/LICENSE)
package/SKILL.md ADDED
@@ -0,0 +1,355 @@
1
+ # Footprint Agent Skill
2
+
3
+ Capture and encrypt LLM conversations as tamper-proof legal evidence with Git timestamps.
4
+
5
+ ## Decision Tree: Should I Capture This?
6
+
7
+ ```
8
+ Should I capture this conversation?
9
+ ├─ User explicitly asked → YES
10
+ │ ├─ "save this conversation"
11
+ │ ├─ "record this for evidence"
12
+ │ ├─ "capture this as evidence"
13
+ │ └─ "I need this for legal/audit purposes"
14
+ ├─ High-value content mentioned → SUGGEST to user
15
+ │ ├─ IP/Patents: "patent", "intellectual property", "IP", "invention"
16
+ │ ├─ Legal: "contract", "agreement", "legal", "copyright", "license"
17
+ │ ├─ Business: "decision", "milestone", "deliverable", "approval"
18
+ │ ├─ Research: "algorithm", "research hypothesis", "findings", "proof"
19
+ │ └─ Compliance: "audit", "compliance", "evidence", "documentation"
20
+ ├─ Casual chat/small talk → NO
21
+ │ ├─ Weather, personal life, jokes
22
+ │ ├─ Basic troubleshooting
23
+ │ └─ Draft/brainstorming sessions (unless finalized)
24
+ └─ Uncertain content → ASK user
25
+ └─ "Would you like me to save this conversation as evidence?"
26
+ ```
27
+
28
+ ## Specific Trigger Patterns
29
+
30
+ **Immediate capture (don't ask, just do it):**
31
+ - "save this conversation"
32
+ - "record this for evidence"
33
+ - "capture this as evidence"
34
+ - "I need this documented"
35
+ - "save this for legal purposes"
36
+
37
+ **Suggest capture (ask user first):**
38
+ - After discussing: patents, contracts, algorithms, research hypotheses, business decisions
39
+ - When mentioned: "IP", "copyright", "legal", "audit", "proof", "compliance"
40
+ - Milestone completions: "finished", "completed", "approved", "signed off"
41
+ - Key decisions: "we decided", "the plan is", "going with option"
42
+
43
+ **Never capture without explicit request:**
44
+ - Casual conversations, personal chat, jokes
45
+ - Debugging sessions, draft work, brainstorming
46
+ - Test conversations, API experiments
47
+ - Private/sensitive personal information
48
+
49
+ ## Available Tools
50
+
51
+ ### 1. `capture-evidence`
52
+ Save a conversation as encrypted evidence.
53
+
54
+ **Input Parameters:**
55
+ ```json
56
+ {
57
+ "conversationId": "api-auth-decision-2026-01-28",
58
+ "llmProvider": "Claude Sonnet 4.5",
59
+ "content": "Human: We need to decide on the OAuth implementation...\nAssistant: I recommend using PKCE flow...\nHuman: Approved, let's go with that approach.",
60
+ "messageCount": 15,
61
+ "tags": "api,oauth,security,decision,approved"
62
+ }
63
+ ```
64
+
65
+ **Expected Output (text):**
66
+ ```
67
+ ✅ Evidence captured successfully
68
+ - Evidence ID: `550e8400-e29b-41d4-a716-446655440000`
69
+ - Conversation ID: `api-auth-decision-2026-01-28`
70
+ - Messages: 15
71
+ - Tags: api,oauth,security,decision,approved
72
+ - Git hash: `a1b2c3d4e5f6789...`
73
+ - Created: 2026-01-28T14:30:45Z
74
+
75
+ Keep this Evidence ID safe for future reference.
76
+ ```
77
+
78
+ **Expected Output (structuredContent):**
79
+ ```json
80
+ {
81
+ "type": "evidence_created",
82
+ "evidenceId": "550e8400-e29b-41d4-a716-446655440000",
83
+ "conversationId": "api-auth-decision-2026-01-28",
84
+ "messageCount": 15,
85
+ "tags": ["api", "oauth", "security", "decision", "approved"],
86
+ "gitHash": "a1b2c3d4e5f6789...",
87
+ "timestamp": "2026-01-28T14:30:45Z",
88
+ "verified": true
89
+ }
90
+ ```
91
+
92
+ ### 2. `list-evidences`
93
+ List all captured evidence (metadata only).
94
+
95
+ **Input Parameters:**
96
+ ```json
97
+ {
98
+ "limit": 10,
99
+ "offset": 0
100
+ }
101
+ ```
102
+
103
+ **Expected Output (text):**
104
+ ```
105
+ 📋 Evidence Archive (10 most recent)
106
+ 1. api-auth-decision-2026-01-28 | 15 msgs | api,oauth,security
107
+ 2. patent-algorithm-2026-01-27 | 32 msgs | ip,patent,algorithm
108
+ 3. contract-review-2026-01-26 | 8 msgs | legal,contract
109
+ ...
110
+ ```
111
+
112
+ **Expected Output (structuredContent):**
113
+ ```json
114
+ {
115
+ "type": "evidence_list",
116
+ "total": 25,
117
+ "evidences": [
118
+ {
119
+ "id": "550e8400-e29b-41d4-a716-446655440000",
120
+ "conversationId": "api-auth-decision-2026-01-28",
121
+ "messageCount": 15,
122
+ "tags": ["api", "oauth", "security"],
123
+ "created": "2026-01-28T14:30:45Z"
124
+ }
125
+ ]
126
+ }
127
+ ```
128
+
129
+ ### 3. `get-evidence`
130
+ Retrieve and decrypt specific evidence.
131
+
132
+ **Input Parameters:**
133
+ ```json
134
+ {
135
+ "id": "550e8400-e29b-41d4-a716-446655440000"
136
+ }
137
+ ```
138
+
139
+ **Expected Output (text):**
140
+ ```
141
+ 📄 Evidence Retrieved
142
+ - ID: 550e8400-e29b-41d4-a716-446655440000
143
+ - Created: 2026-01-28T14:30:45Z
144
+ - Provider: Claude Sonnet 4.5
145
+ - Verified: ✅ Checksum valid, Git timestamp confirmed
146
+
147
+ [Decrypted conversation content follows...]
148
+ Human: We need to decide on the OAuth implementation...
149
+ Assistant: I recommend using PKCE flow...
150
+ ```
151
+
152
+ ### 4. `search-evidence`
153
+ Find evidence by content or tags.
154
+
155
+ **Input Parameters:**
156
+ ```json
157
+ {
158
+ "query": "OAuth OR PKCE OR authentication",
159
+ "tags": ["api", "security"],
160
+ "limit": 5
161
+ }
162
+ ```
163
+
164
+ ### 5. `export-evidence`
165
+ Export evidence as encrypted archive.
166
+
167
+ **Input Parameters:**
168
+ ```json
169
+ {
170
+ "id": "550e8400-e29b-41d4-a716-446655440000",
171
+ "format": "zip"
172
+ }
173
+ ```
174
+
175
+ **Expected Output (structuredContent):**
176
+ ```json
177
+ {
178
+ "type": "evidence_export",
179
+ "filename": "evidence-550e8400-export.zip",
180
+ "base64Data": "UEsDBBQAAAAIAL...",
181
+ "size": 2048,
182
+ "checksum": "sha256:a1b2c3d4..."
183
+ }
184
+ ```
185
+
186
+ ## Best Practices
187
+
188
+ ### Naming conversationId
189
+ **Format:** `{topic-type}-{descriptive-name}-{YYYY-MM-DD}`
190
+
191
+ **Good examples:**
192
+ - `api-auth-decision-2026-01-28`
193
+ - `patent-ml-algorithm-2026-01-27`
194
+ - `contract-vendor-negotiation-2026-01-26`
195
+ - `milestone-mvp-completion-2026-01-25`
196
+
197
+ **Avoid:**
198
+ - `conversation-1` (not descriptive)
199
+ - `important-chat` (too vague)
200
+ - `chat-2026-01-28` (missing context)
201
+
202
+ ### Choosing Tags
203
+ **Common patterns:**
204
+ - **Type**: `decision`, `milestone`, `research`, `review`, `approval`
205
+ - **Domain**: `api`, `ui`, `database`, `security`, `legal`, `business`
206
+ - **Status**: `draft`, `finalized`, `approved`, `rejected`
207
+ - **IP**: `patent`, `copyright`, `trade-secret`, `invention`
208
+ - **Legal**: `contract`, `agreement`, `compliance`, `audit`
209
+
210
+ **Tag Guidelines:**
211
+ - Use 3-6 tags maximum
212
+ - Prefer specific over general (`oauth` not just `auth`)
213
+ - Include project/product names if relevant
214
+ - Always include content type (`decision`, `research`, etc.)
215
+
216
+ ### When to Use Each Tool
217
+ - **capture-evidence**: Primary tool for saving conversations
218
+ - **list-evidences**: Browse/overview existing evidence
219
+ - **search-evidence**: Find specific content across evidence
220
+ - **get-evidence**: Retrieve full content of specific evidence
221
+ - **export-evidence**: Legal/audit export needs
222
+
223
+ ## Token-Efficient Agent Responses
224
+
225
+ **After capturing evidence (keep it brief):**
226
+ ```
227
+ ✅ Evidence saved as `{conversationId}`
228
+ ID: `{first-8-chars-of-id}`...
229
+ Tags: {tags}
230
+ ```
231
+
232
+ **When suggesting capture:**
233
+ ```
234
+ 💡 This looks like valuable evidence (contains {trigger}). Save it?
235
+ ```
236
+
237
+ **When declining to capture:**
238
+ ```
239
+ â„šī¸ Skipping evidence capture (casual conversation)
240
+ ```
241
+
242
+ **For retrieval:**
243
+ ```
244
+ 📄 Found: {conversationId} ({messageCount} messages)
245
+ [Show relevant excerpt or summary]
246
+ ```
247
+
248
+ ## Error Handling with Recovery Actions
249
+
250
+ | Error | Likely Cause | Recovery Action |
251
+ |-------|--------------|-----------------|
252
+ | "Password required" | EVIDENCEMCP_PASSWORD not set | 1. Check env config<br>2. Restart MCP server<br>3. Verify password in env |
253
+ | "Evidence not found" | Invalid/wrong ID | 1. Use `list-evidences` to find correct ID<br>2. Search by conversationId<br>3. Check if user meant different evidence |
254
+ | "Decryption failed" | Password changed/wrong | 1. Verify current password matches<br>2. Check if evidence pre-dates password change<br>3. Try with backup password if available |
255
+ | "Database error" | DB path/permissions issues | 1. Check EVIDENCEMCP_DB_PATH exists<br>2. Verify file permissions<br>3. Create directory if missing |
256
+ | "Git repository error" | Git not initialized | 1. Initialize git in evidence directory<br>2. Set git user.name/user.email<br>3. Make initial commit |
257
+ | "Capture timeout" | Large conversation size | 1. Split into smaller chunks<br>2. Reduce messageCount<br>3. Compress content before capture |
258
+
259
+ **Agent Recovery Protocol:**
260
+ 1. **Detect error** from tool response
261
+ 2. **Identify cause** from error message
262
+ 3. **Apply recovery action** from table above
263
+ 4. **Retry operation** if recovery successful
264
+ 5. **Escalate to user** only if recovery fails
265
+
266
+ ## Workflow Examples
267
+
268
+ ### 1. User Explicit Request
269
+ ```
270
+ User: "Save this conversation about the API design"
271
+
272
+ Agent:
273
+ 1. ✅ Capture immediately (explicit request)
274
+ 2. Use conversationId: "api-design-discussion-2026-01-28"
275
+ 3. Tags: "api,design,architecture"
276
+ 4. Report success with Evidence ID
277
+ ```
278
+
279
+ ### 2. High-Value Content Detection
280
+ ```
281
+ User: "We've decided to patent this algorithm approach."
282
+
283
+ Agent:
284
+ 1. 🔍 Detect trigger: "patent" + "decided"
285
+ 2. 💡 Suggest: "This looks like valuable evidence (contains patent decision). Save it?"
286
+ 3. ✅ If user agrees, capture with tags: "patent,algorithm,decision,ip"
287
+ ```
288
+
289
+ ### 3. Evidence Retrieval
290
+ ```
291
+ User: "Find the conversation about OAuth implementation"
292
+
293
+ Agent:
294
+ 1. 🔍 Search: list-evidences or search-evidence with "OAuth"
295
+ 2. 📄 Present matches with conversationId and brief summary
296
+ 3. đŸŽ¯ If user selects one, get-evidence to show full content
297
+ ```
298
+
299
+ ### 4. Legal Export
300
+ ```
301
+ User: "Export the patent evidence for filing"
302
+
303
+ Agent:
304
+ 1. 🔍 Help identify relevant evidence (search by "patent" tag)
305
+ 2. đŸ“Ļ Export each evidence as encrypted ZIP
306
+ 3. ✅ Provide files with verification instructions
307
+ 4. 📋 Remind about Git hash verification for legal proof
308
+ ```
309
+
310
+ ## Security & Verification
311
+
312
+ - **Password**: Set via `EVIDENCEMCP_PASSWORD` env var (never ask user in chat)
313
+ - **Encryption**: AES-256-GCM with Argon2id key derivation
314
+ - **Git Timestamps**: Cryptographic proof of creation time
315
+ - **SHA-256 Checksums**: Detect any content tampering
316
+ - **Evidence Chain**: Each capture creates immutable Git commit
317
+
318
+ **For legal proceedings:**
319
+ 1. Export evidence with `export-evidence`
320
+ 2. Verify Git hash against repository
321
+ 3. Check SHA-256 checksum matches
322
+ 4. Git log shows creation timestamp
323
+ 5. Encrypted archive proves content integrity
324
+
325
+ ## Installation (Reference Only)
326
+
327
+ This section is for humans setting up the agent environment:
328
+
329
+ ```bash
330
+ # Install MCP server
331
+ npm install -g @pcircle/footprint-server
332
+
333
+ # Claude Desktop config (~/.config/claude/claude_desktop_config.json)
334
+ {
335
+ "mcpServers": {
336
+ "footprint": {
337
+ "command": "footprint",
338
+ "env": {
339
+ "EVIDENCEMCP_DB_PATH": "~/evidence/evidence.db",
340
+ "EVIDENCEMCP_PASSWORD": "your-secure-password-here"
341
+ }
342
+ }
343
+ }
344
+ }
345
+ ```
346
+
347
+ ## Performance Notes
348
+
349
+ - **Capture time**: ~1-3 seconds per conversation
350
+ - **Database size**: ~1KB per message on average
351
+ - **Git overhead**: ~100 bytes per evidence commit
352
+ - **Search speed**: Sub-second for <1000 evidence records
353
+ - **Export time**: ~5-15 seconds depending on content size
354
+
355
+ Large conversations (>100 messages) may take longer to encrypt and commit.
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import type { ServerConfig } from './types.js';
3
+ /**
4
+ * EvidenceMCP Server - Captures LLM conversations as encrypted evidence
5
+ * with Git timestamps and export capabilities.
6
+ */
7
+ export declare class EvidenceMCPServer {
8
+ private server;
9
+ private config;
10
+ private db;
11
+ private derivedKey;
12
+ constructor(config: ServerConfig);
13
+ private getDerivedKey;
14
+ private registerTools;
15
+ private registerResources;
16
+ start(): Promise<void>;
17
+ }
18
+ export { EvidenceMCPTestHelpers } from './test-helpers.js';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AASA,OAAO,KAAK,EAAE,YAAY,EAAyB,MAAM,YAAY,CAAC;AAMtE;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,EAAE,CAAmB;IAC7B,OAAO,CAAC,UAAU,CAA2B;gBAEjC,MAAM,EAAE,YAAY;YAqBlB,aAAa;IAQ3B,OAAO,CAAC,aAAa;IAqrBrB,OAAO,CAAC,iBAAiB;IA6BnB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B;AAwBD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC"}