@augmnt-sh/mindcache 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/dist/cli.js ADDED
@@ -0,0 +1,282 @@
1
+ #!/usr/bin/env node
2
+ import {StdioServerTransport}from'@modelcontextprotocol/sdk/server/stdio.js';import {McpServer}from'@modelcontextprotocol/sdk/server/mcp.js';import {existsSync,mkdirSync,writeFileSync,readFileSync,readdirSync,appendFileSync,unlinkSync}from'fs';import {dirname,join,relative,basename,extname,resolve}from'path';import {z as z$1}from'zod';import {fileURLToPath}from'url';import {homedir}from'os';import {createInterface}from'readline';function O(s,n){let c=s.split(`
3
+ `),t=false,e=0,o=[];for(let r of c){let i=r.match(/^(#{1,6})\s+(.+)$/);if(i){let a=i[1].length,d=i[2].trim();if(t){if(a<=e)break;o.push(r);}else d.toLowerCase()===n.toLowerCase()&&(t=true,e=a,o.push(r));}else t&&o.push(r);}return o.length>0?o.join(`
4
+ `).trim():null}function _(s,n,c){let t=s.split(`
5
+ `),e=[],o=false,r=0;for(let i of t){let a=i.match(/^(#{1,6})\s+(.+)$/);if(a){let d=a[1].length,p=a[2].trim();o&&d<=r?(o=false,e.push(i)):p.toLowerCase()===n.toLowerCase()?(o=true,r=d,e.push(i),e.push(""),e.push(c),e.push("")):e.push(i);}else o||e.push(i);}return e.join(`
6
+ `)}function S(s){let n=s.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);if(!n)return {frontmatter:{},body:s};let c={};for(let t of n[1].split(`
7
+ `)){let e=t.indexOf(":");if(e>0){let o=t.slice(0,e).trim(),r=t.slice(e+1).trim();c[o]=r;}}return {frontmatter:c,body:n[2]}}function C(s){return [...s.matchAll(/\[\[([^\]|]+)(?:\|[^\]]+)?\]\]/g)].map(c=>c[1])}function w(s){let n=s.matchAll(/(?:^|\s)#([a-zA-Z0-9_/-]+)/g);return [...new Set([...n].map(c=>c[1]))]}function G(s){let n=[],c=s.split(`
8
+ `);for(let t=0;t<c.length;t++){let e=c[t].match(/^[\s]*-\s+\[([ xX])\]\s+(.+)$/);e&&n.push({text:e[2],done:e[1]!==" ",line:t+1});}return n}function K(s){let{body:n}=S(s);return n.split(/\s+/).filter(c=>c.length>0).length}var M=class{vaultPath;fileCache=null;fileCacheTime=0;CACHE_TTL=5e3;constructor(n){this.vaultPath=n.vault;}resolve(n){let c=join(this.vaultPath,n);if(!c.startsWith(this.vaultPath))throw new Error("Path traversal not allowed");return c}ensureDir(n){let c=dirname(n);existsSync(c)||mkdirSync(c,{recursive:true});}walkDir(n){let c=[],t;try{t=readdirSync(n,{withFileTypes:!0});}catch{return c}for(let e of t){if(e.name.startsWith(".")||e.name==="node_modules")continue;let o=join(n,e.name);e.isDirectory()?c.push(...this.walkDir(o)):c.push(o);}return c}async ping(){return existsSync(this.vaultPath)}async search(n){let t=(await this.listFiles()).filter(r=>r.extension==="md"),e=n.toLowerCase(),o=[];for(let r of t)try{let i=readFileSync(this.resolve(r.path),"utf-8"),a=i.toLowerCase(),d=a.indexOf(e);if(d>=0){let p=0,u=0;for(;(u=a.indexOf(e,u))!==-1;)p++,u+=e.length;let f=Math.max(0,d-50),l=Math.min(i.length,d+n.length+50),m=i.slice(f,l).replace(/\n/g," ").trim();o.push({filename:r.path,score:p*10+(r.name.toLowerCase().includes(e)?50:0),matches:[{match:{start:d,end:d+n.length},context:m}]});}}catch{}return o.sort((r,i)=>i.score-r.score)}async readNote(n){let c=this.resolve(n);if(!existsSync(c))throw new Error(`Note not found: ${n}`);return readFileSync(c,"utf-8")}async writeNote(n,c){let t=this.resolve(n);this.ensureDir(t),writeFileSync(t,c,"utf-8"),this.fileCache=null;}async appendToNote(n,c){let t=this.resolve(n);if(!existsSync(t))throw new Error(`Note not found: ${n}`);appendFileSync(t,c,"utf-8");}async patchNote(n,c,t){let e=this.resolve(n),o=readFileSync(e,"utf-8");if(t?.targetHeading){if(!O(o,t.targetHeading))throw new Error(`Heading "${t.targetHeading}" not found`);if(t.operation==="replace"){let i=_(o,t.targetHeading,c);writeFileSync(e,i,"utf-8");}else {let i=o.split(`
9
+ `),a=t.targetHeading.toLowerCase(),d=-1;for(let p=0;p<i.length;p++){let u=i[p].match(/^#{1,6}\s+(.+)$/);if(u&&u[1].trim().toLowerCase()===a){let f=i[p].indexOf(" ");d=p+1;for(let l=p+1;l<i.length;l++){let m=i[l].match(/^(#{1,6})\s/);if(m&&m[1].length<=f)break;d=l+1;}break}}if(d>=0)i.splice(d,0,c),writeFileSync(e,i.join(`
10
+ `),"utf-8");else throw new Error(`Heading "${t.targetHeading}" not found`)}}else if(t?.targetLine!==void 0){let r=o.split(`
11
+ `);r.splice(t.targetLine,0,c),writeFileSync(e,r.join(`
12
+ `),"utf-8");}else appendFileSync(e,c,"utf-8");}async deleteNote(n){let c=this.resolve(n);if(!existsSync(c))throw new Error(`Note not found: ${n}`);unlinkSync(c),this.fileCache=null;}async listFiles(){let n=Date.now();if(this.fileCache&&n-this.fileCacheTime<this.CACHE_TTL)return this.fileCache;let c=this.walkDir(this.vaultPath);return this.fileCache=c.map(t=>{let e=relative(this.vaultPath,t),o=basename(e,extname(e)),r=extname(e).slice(1);return {path:e,name:o,extension:r}}),this.fileCacheTime=n,this.fileCache}async getActiveNote(){throw new Error("Active note detection requires Obsidian to be running. Use search or read_note instead.")}async getActiveNotePath(){throw new Error("Active note detection requires Obsidian to be running. Use search or read_note instead.")}async searchWithContext(n,c=100){let e=(await this.listFiles()).filter(i=>i.extension==="md"),o=n.toLowerCase(),r=[];for(let i of e)try{let a=readFileSync(this.resolve(i.path),"utf-8"),d=a.toLowerCase(),p=[],u=0;for(;(u=d.indexOf(o,u))!==-1;){let f=Math.max(0,u-c),l=Math.min(a.length,u+n.length+c);if(p.push({match:{start:u,end:u+n.length},context:a.slice(f,l).replace(/\n/g," ").trim()}),u+=o.length,p.length>=5)break}p.length>0&&r.push({filename:i.path,score:p.length*10+(i.name.toLowerCase().includes(o)?50:0),matches:p});}catch{}return r.sort((i,a)=>a.score-i.score)}async health(){if(!this.vaultPath)return {ok:false,error:"No vault path configured. Run: mindcache init"};if(!existsSync(this.vaultPath))return {ok:false,error:`Vault not found at: ${this.vaultPath}`};try{return {ok:!0,noteCount:(await this.listFiles()).filter(t=>t.extension==="md").length}}catch(n){return {ok:false,error:`Cannot read vault: ${n instanceof Error?n.message:String(n)}`}}}};function X(s){let n=s.getFullYear(),c=String(s.getMonth()+1).padStart(2,"0"),t=String(s.getDate()).padStart(2,"0");return `${n}-${c}-${t}`}function y(){return X(new Date)}function H(s=new Date){let n=new Date(s),c=n.getDay(),t=n.getDate()-c+(c===0?-6:1);return n.setDate(t),n.setHours(0,0,0,0),n}function Z(s=new Date){let n=H(s),c=[];for(let t=0;t<7;t++){let e=new Date(n);e.setDate(n.getDate()+t),c.push(X(e));}return c}function tt(s){let n=new Date,c=s.toLowerCase().trim();if(c==="today"){let r=new Date(n);r.setHours(0,0,0,0);let i=new Date(n);return i.setHours(23,59,59,999),{from:r,to:i}}if(c==="yesterday"){let r=new Date(n);r.setDate(r.getDate()-1),r.setHours(0,0,0,0);let i=new Date(r);return i.setHours(23,59,59,999),{from:r,to:i}}if(c==="this week")return {from:H(n),to:n};if(c==="last week"){let r=H(n),i=new Date(r);i.setDate(i.getDate()-7);let a=new Date(r);return a.setMilliseconds(-1),{from:i,to:a}}if(c==="this month")return {from:new Date(n.getFullYear(),n.getMonth(),1),to:n};if(c==="last month"){let r=new Date(n.getFullYear(),n.getMonth()-1,1),i=new Date(n.getFullYear(),n.getMonth(),0,23,59,59,999);return {from:r,to:i}}let t=c.match(/(\d{4}-\d{2}-\d{2})\s+to\s+(\d{4}-\d{2}-\d{2})/);if(t)return {from:new Date(t[1]),to:new Date(t[2])};let e=c.match(/last\s+(\d+)\s+days?/);if(e){let r=new Date(n);return r.setDate(r.getDate()-parseInt(e[1])),r.setHours(0,0,0,0),{from:r,to:n}}let o=new Date(n);return o.setDate(o.getDate()-7),o.setHours(0,0,0,0),{from:o,to:n}}function et(s,n,c){s.tool("search",'Full-text search across your Obsidian vault. Supports Obsidian search operators: "exact phrase", path:folder, tag:#tag, file:filename. Returns matching notes with context snippets.',{query:z$1.string().describe("Search query \u2014 supports Obsidian search operators")},async({query:t})=>{try{let e=await n.searchWithContext(t,200);if(e.length===0)return {content:[{type:"text",text:`No results found for "${t}"`}]};let o=e.slice(0,20).map((r,i)=>{let a=r.matches.slice(0,3).map(d=>` > ${d.context.trim()}`).join(`
13
+ `);return `${i+1}. **${r.filename}** (score: ${r.score.toFixed(1)})
14
+ ${a}`}).join(`
15
+
16
+ `);return {content:[{type:"text",text:`Found ${e.length} results for "${t}":
17
+
18
+ ${o}`}]}}catch(e){return {content:[{type:"text",text:`Search error: ${e instanceof Error?e.message:String(e)}`}],isError:true}}}),s.tool("ask","Ask a natural language question about your vault. Searches for relevant notes and returns their content so you can synthesize an answer. Use this when you need to understand what the user knows about a topic.",{question:z$1.string().describe("Natural language question to answer from vault knowledge")},async({question:t})=>{try{let e=await n.searchWithContext(t,300);if(e.length===0)return {content:[{type:"text",text:`No relevant notes found for: "${t}"`}]};let o=e.slice(0,5),r=[];for(let i of o)try{let a=await n.readNote(i.filename),{frontmatter:d}=S(a),p=w(a),u=C(a),f=a.length>2e3?a.slice(0,2e3)+`
19
+ ...(truncated)`:a;r.push(`---
20
+ **${i.filename}**`+(p.length>0?` | Tags: ${p.map(l=>`#${l}`).join(", ")}`:"")+(u.length>0?` | Links: ${u.map(l=>`[[${l}]]`).join(", ")}`:"")+(d.type?` | Type: ${d.type}`:"")+`
21
+
22
+ ${f}`);}catch{}return {content:[{type:"text",text:`Found ${e.length} relevant notes for "${t}". Here are the top ${r.length}:
23
+
24
+ ${r.join(`
25
+
26
+ `)}`}]}}catch(e){return {content:[{type:"text",text:`Ask error: ${e instanceof Error?e.message:String(e)}`}],isError:true}}}),s.tool("find_related","Find notes related to a given note via backlinks, shared tags, or shared wikilinks. Returns notes that are connected in the knowledge graph.",{path:z$1.string().describe('Path to the note (e.g., "Projects/My Project.md")')},async({path:t})=>{try{let e=await n.readNote(t),o=C(e),r=w(e),i=new Map;for(let f of o){let l=await n.search(`file:${f}`);for(let m of l.slice(0,3))m.filename!==t&&i.set(m.filename,{reason:`Linked from this note: [[${f}]]`,score:(i.get(m.filename)?.score??0)+2});}for(let f of r.slice(0,5)){let l=await n.search(`tag:#${f}`);for(let m of l.slice(0,5))if(m.filename!==t){let h=i.get(m.filename);i.set(m.filename,{reason:h?`${h.reason}; Shared tag: #${f}`:`Shared tag: #${f}`,score:(h?.score??0)+1});}}let a=t.replace(/\.md$/,"").split("/").pop()??t,d=await n.search(`"[[${a}]]"`);for(let f of d)if(f.filename!==t){let l=i.get(f.filename);i.set(f.filename,{reason:l?`${l.reason}; Links to this note`:"Links to this note",score:(l?.score??0)+3});}let p=[...i.entries()].sort((f,l)=>l[1].score-f[1].score).slice(0,15);if(p.length===0)return {content:[{type:"text",text:`No related notes found for "${t}"`}]};let u=p.map(([f,l],m)=>`${m+1}. **${f}** \u2014 ${l.reason}`).join(`
27
+ `);return {content:[{type:"text",text:`Related notes for "${t}":
28
+
29
+ ${u}`}]}}catch(e){return {content:[{type:"text",text:`Find related error: ${e instanceof Error?e.message:String(e)}`}],isError:true}}}),s.tool("find_by_tag","Find all notes with specific tags. Supports multiple tags (all must match). Use without # prefix.",{tags:z$1.array(z$1.string()).describe('Tags to search for (without # prefix, e.g., ["project", "active"])'),limit:z$1.number().optional().default(20).describe("Maximum number of results")},async({tags:t,limit:e})=>{try{let o=t.map(a=>`tag:#${a}`).join(" "),r=await n.search(o);if(r.length===0)return {content:[{type:"text",text:`No notes found with tags: ${t.map(a=>`#${a}`).join(", ")}`}]};let i=r.slice(0,e).map((a,d)=>`${d+1}. ${a.filename}`).join(`
30
+ `);return {content:[{type:"text",text:`Notes tagged ${t.map(a=>`#${a}`).join(", ")} (${r.length} total):
31
+
32
+ ${i}`}]}}catch(o){return {content:[{type:"text",text:`Tag search error: ${o instanceof Error?o.message:String(o)}`}],isError:true}}}),s.tool("find_by_date",'Find notes created or modified within a date range. Supports natural language like "today", "this week", "last month", "last 7 days", or explicit "YYYY-MM-DD to YYYY-MM-DD".',{range:z$1.string().describe('Date range \u2014 "today", "this week", "last month", "last 30 days", or "YYYY-MM-DD to YYYY-MM-DD"'),limit:z$1.number().optional().default(20).describe("Maximum results")},async({range:t,limit:e})=>{try{let{from:o,to:r}=tt(t),a=(await n.listFiles()).filter(l=>l.extension==="md"),d=o.toISOString().split("T")[0],p=r.toISOString().split("T")[0],f=(await n.search(`"${d}"`)).slice(0,e).map((l,m)=>`${m+1}. ${l.filename}`).join(`
33
+ `);return {content:[{type:"text",text:`Notes from ${d} to ${p} (searched by date reference):
34
+
35
+ `+(f||"No notes found in this range.")+`
36
+
37
+ Total markdown files in vault: ${a.length}`}]}}catch(o){return {content:[{type:"text",text:`Date search error: ${o instanceof Error?o.message:String(o)}`}],isError:true}}}),s.tool("find_recent","List notes in the vault. Returns markdown files from the vault file listing.",{limit:z$1.number().optional().default(10).describe("Number of recent notes to return")},async({limit:t})=>{try{let o=(await n.listFiles()).filter(a=>a.extension==="md"),i=o.slice(0,t).map((a,d)=>`${d+1}. ${a.path}`).join(`
38
+ `);return {content:[{type:"text",text:`Vault files (${o.length} total markdown notes):
39
+
40
+ ${i}`}]}}catch(e){return {content:[{type:"text",text:`Recent notes error: ${e instanceof Error?e.message:String(e)}`}],isError:true}}}),s.tool("find_mentions","Find all notes that mention a specific term, concept, or person. Searches for exact text matches across the vault.",{term:z$1.string().describe("Term or concept to search for"),limit:z$1.number().optional().default(20).describe("Maximum results")},async({term:t,limit:e})=>{try{let o=await n.searchWithContext(t,150);if(o.length===0)return {content:[{type:"text",text:`"${t}" is not mentioned in any notes.`}]};let r=o.slice(0,e).map((i,a)=>{let d=i.matches[0]?.context?.trim()??"";return `${a+1}. **${i.filename}**
41
+ > ${d}`}).join(`
42
+
43
+ `);return {content:[{type:"text",text:`"${t}" mentioned in ${o.length} notes:
44
+
45
+ ${r}`}]}}catch(o){return {content:[{type:"text",text:`Mentions search error: ${o instanceof Error?o.message:String(o)}`}],isError:true}}});}function nt(s,n,c){s.tool("read_note","Read the full content of a note by its path. Returns the complete markdown including frontmatter.",{path:z$1.string().describe('Path to the note (e.g., "Projects/My Project.md")')},async({path:t})=>{try{return {content:[{type:"text",text:await n.readNote(t)}]}}catch(e){return {content:[{type:"text",text:`Could not read "${t}": ${e instanceof Error?e.message:String(e)}`}],isError:true}}}),s.tool("read_section","Read a specific section from a note, identified by its heading. Returns content from the heading to the next heading of the same or higher level.",{path:z$1.string().describe("Path to the note"),heading:z$1.string().describe('Heading text to extract (e.g., "Key Points", "Action Items")')},async({path:t,heading:e})=>{try{let o=await n.readNote(t),r=O(o,e);return r?{content:[{type:"text",text:r}]}:{content:[{type:"text",text:`No section "${e}" found in "${t}"`}]}}catch(o){return {content:[{type:"text",text:`Could not read section: ${o instanceof Error?o.message:String(o)}`}],isError:true}}}),s.tool("read_summary","Get a note with its metadata: frontmatter properties, tags, wikilinks, and word count. Useful for understanding a note without reading it fully.",{path:z$1.string().describe("Path to the note")},async({path:t})=>{try{let e=await n.readNote(t),{frontmatter:o}=S(e),r=w(e),i=C(e),a=K(e);return {content:[{type:"text",text:[`**${t}**`,"",`**Words:** ${a}`,r.length>0?`**Tags:** ${r.map(p=>`#${p}`).join(", ")}`:null,i.length>0?`**Links:** ${i.map(p=>`[[${p}]]`).join(", ")}`:null,Object.keys(o).length>0?`**Properties:**
46
+ ${Object.entries(o).map(([p,u])=>` - ${p}: ${u}`).join(`
47
+ `)}`:null,"","---","",e].filter(Boolean).join(`
48
+ `)}]}}catch(e){return {content:[{type:"text",text:`Could not read summary: ${e instanceof Error?e.message:String(e)}`}],isError:true}}}),s.tool("read_properties","Read only the YAML frontmatter properties of a note. Fast way to check metadata without reading the full content.",{path:z$1.string().describe("Path to the note")},async({path:t})=>{try{let e=await n.readNote(t),{frontmatter:o}=S(e);if(Object.keys(o).length===0)return {content:[{type:"text",text:`No frontmatter found in "${t}"`}]};let r=Object.entries(o).map(([i,a])=>`${i}: ${a}`).join(`
49
+ `);return {content:[{type:"text",text:`Properties of "${t}":
50
+
51
+ ${r}`}]}}catch(e){return {content:[{type:"text",text:`Could not read properties: ${e instanceof Error?e.message:String(e)}`}],isError:true}}}),s.tool("read_today","Read today's daily note. Returns the content of today's daily note based on your configured daily notes folder and format.",{},async()=>{try{let t=`${c.dailyNotes.folder}/${y()}.md`,e=await n.readNote(t);return {content:[{type:"text",text:`**Today's Daily Note (${y()}):**
52
+
53
+ ${e}`}]}}catch{return {content:[{type:"text",text:`No daily note found for today (${y()}). Expected at: ${c.dailyNotes.folder}/${y()}.md`}]}}}),s.tool("read_this_week","Read all daily notes from the current week (Monday to Sunday). Useful for getting a weekly overview of activity.",{},async()=>{try{let t=Z(),e=[];for(let o of t){let r=`${c.dailyNotes.folder}/${o}.md`;try{let i=await n.readNote(r);e.push(`## ${o}
54
+
55
+ ${i}`);}catch{}}return e.length===0?{content:[{type:"text",text:`No daily notes found for this week (${t[0]} to ${t[6]}).`}]}:{content:[{type:"text",text:`**This Week's Daily Notes:**
56
+
57
+ ${e.join(`
58
+
59
+ ---
60
+
61
+ `)}`}]}}catch(t){return {content:[{type:"text",text:`Could not read weekly notes: ${t instanceof Error?t.message:String(t)}`}],isError:true}}}),s.tool("get_active_note","Get the currently active/open note in Obsidian. Returns both the path and content of the note the user is currently viewing.",{},async()=>{try{let t=await n.getActiveNote(),e="";try{e=await n.getActiveNotePath();}catch{}return {content:[{type:"text",text:e?`**Active Note: ${e}**
62
+
63
+ ${t}`:`**Active Note:**
64
+
65
+ ${t}`}]}}catch(t){return {content:[{type:"text",text:`Could not get active note: ${t instanceof Error?t.message:String(t)}`}],isError:true}}});}var Tt=dirname(fileURLToPath(import.meta.url)),Et=join(Tt,"..","templates"),U=new Map;function Ft(s){if(U.has(s))return U.get(s);let n=join(Et,`${s}.md`);if(!existsSync(n))throw new Error(`Template "${s}" not found at ${n}`);let c=readFileSync(n,"utf-8");return U.set(s,c),c}function Dt(s,n){let c=s,e={...{date:y(),timestamp:new Date().toISOString(),year:String(new Date().getFullYear()),month:String(new Date().getMonth()+1).padStart(2,"0"),day:String(new Date().getDate()).padStart(2,"0")},...n};for(let[o,r]of Object.entries(e))c=c.replaceAll(`{{${o}}}`,r??"");return c=c.replace(/\{\{[^}]+\}\}/g,""),c}function N(s,n={}){let c=Ft(s);return Dt(c,n)}function rt(s,n,c){s.tool("remember","Quick capture \u2014 save a thought, note, or piece of information to the vault. Auto-saves to the inbox folder. Use this for quick, unstructured captures.",{content:z$1.string().describe("The content to save"),title:z$1.string().optional().describe("Optional title for the note. If omitted, generates from content."),tags:z$1.array(z$1.string()).optional().describe("Optional tags to add (without # prefix)"),folder:z$1.string().optional().describe("Optional folder to save to (defaults to inbox)")},async({content:t,title:e,tags:o,folder:r})=>{try{let i=e??`Quick Note - ${y()} ${new Date().toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit"})}`,d=`${r??c.inbox.folder}/${i}.md`,p=o&&o.length>0?`tags:
66
+ ${o.map(f=>` - ${f}`).join(`
67
+ `)}`:`tags:
68
+ - inbox`,u=`---
69
+ date: ${y()}
70
+ ${p}
71
+ ---
72
+
73
+ ${t}
74
+ `;return await n.writeNote(d,u),{content:[{type:"text",text:`Saved to "${d}"`}]}}catch(i){return {content:[{type:"text",text:`Could not save note: ${i instanceof Error?i.message:String(i)}`}],isError:true}}}),s.tool("remember_meeting","Create a structured meeting note with attendees, agenda, notes, and action items. Uses the meeting template.",{title:z$1.string().describe("Meeting title"),attendees:z$1.string().describe("Comma-separated list of attendees"),agenda:z$1.string().optional().default("").describe("Meeting agenda"),notes:z$1.string().optional().default("").describe("Meeting notes"),action_items:z$1.string().optional().default("").describe("Action items from the meeting"),follow_up:z$1.string().optional().default("").describe("Follow-up items"),folder:z$1.string().optional().describe("Folder to save to (defaults to inbox)")},async({title:t,attendees:e,agenda:o,notes:r,action_items:i,follow_up:a,folder:d})=>{try{let p=N("meeting",{title:t,attendees:e,agenda:o,notes:r,action_items:i,follow_up:a}),f=`${d??c.inbox.folder}/${t}.md`;return await n.writeNote(f,p),{content:[{type:"text",text:`Meeting note created at "${f}"`}]}}catch(p){return {content:[{type:"text",text:`Could not create meeting note: ${p instanceof Error?p.message:String(p)}`}],isError:true}}}),s.tool("remember_decision","Log a decision using the ADR (Architecture Decision Record) format. Captures the context, decision, consequences, and alternatives considered.",{title:z$1.string().describe("Decision title"),context:z$1.string().describe("Why this decision needed to be made"),decision:z$1.string().describe("What was decided"),consequences:z$1.string().optional().default("").describe("What happens as a result"),alternatives:z$1.string().optional().default("").describe("Other options that were considered"),related:z$1.string().optional().default("").describe("Related notes or concepts"),folder:z$1.string().optional().describe("Folder to save to")},async({title:t,context:e,decision:o,consequences:r,alternatives:i,related:a,folder:d})=>{try{let p=N("decision",{title:t,context:e,decision:o,consequences:r,alternatives:i,related:a}),f=`${d??c.inbox.folder}/${t}.md`;return await n.writeNote(f,p),{content:[{type:"text",text:`Decision logged at "${f}"`}]}}catch(p){return {content:[{type:"text",text:`Could not log decision: ${p instanceof Error?p.message:String(p)}`}],isError:true}}}),s.tool("remember_idea","Capture an idea with context on why it matters and potential next steps.",{title:z$1.string().describe("Idea title"),idea:z$1.string().describe("Description of the idea"),why:z$1.string().optional().default("").describe("Why this idea matters"),next_steps:z$1.string().optional().default("").describe("Potential next steps"),related:z$1.string().optional().default("").describe("Related notes or concepts"),tags:z$1.array(z$1.string()).optional().describe("Additional tags"),folder:z$1.string().optional().describe("Folder to save to")},async({title:t,idea:e,why:o,next_steps:r,related:i,folder:a})=>{try{let d=N("idea",{title:t,idea:e,why:o,next_steps:r,related:i}),u=`${a??c.inbox.folder}/${t}.md`;return await n.writeNote(u,d),{content:[{type:"text",text:`Idea captured at "${u}"`}]}}catch(d){return {content:[{type:"text",text:`Could not capture idea: ${d instanceof Error?d.message:String(d)}`}],isError:true}}}),s.tool("remember_learning","Save something new you learned \u2014 a concept, technique, insight, or skill with examples and application notes.",{title:z$1.string().describe("What was learned"),concept:z$1.string().describe("The concept or insight"),key_points:z$1.string().optional().default("").describe("Key points to remember"),examples:z$1.string().optional().default("").describe("Examples or illustrations"),application:z$1.string().optional().default("").describe("How to apply this learning"),source:z$1.string().optional().default("").describe("Where you learned this"),related:z$1.string().optional().default("").describe("Related notes"),folder:z$1.string().optional().describe("Folder to save to")},async({title:t,concept:e,key_points:o,examples:r,application:i,source:a,related:d,folder:p})=>{try{let u=N("learning",{title:t,concept:e,key_points:o,examples:r,application:i,source:a,related:d}),l=`${p??c.inbox.folder}/${t}.md`;return await n.writeNote(l,u),{content:[{type:"text",text:`Learning saved at "${l}"`}]}}catch(u){return {content:[{type:"text",text:`Could not save learning: ${u instanceof Error?u.message:String(u)}`}],isError:true}}}),s.tool("remember_person","Create or update a note about a person \u2014 their role, organization, context, and interactions.",{name:z$1.string().describe("Person's name"),role:z$1.string().optional().default("").describe("Their role or title"),organization:z$1.string().optional().default("").describe("Their organization"),contact:z$1.string().optional().default("").describe("Contact information"),context:z$1.string().optional().default("").describe("How you know them or relevant context"),interaction:z$1.string().optional().default("").describe("Notes from recent interaction"),notes:z$1.string().optional().default("").describe("Additional notes"),folder:z$1.string().optional().describe("Folder to save to")},async({name:t,role:e,organization:o,contact:r,context:i,interaction:a,notes:d,folder:p})=>{try{let u=N("person",{name:t,role:e,organization:o,contact:r,context:i,interaction:a,notes:d}),l=`${p??c.inbox.folder}/${t}.md`;return await n.writeNote(l,u),{content:[{type:"text",text:`Person note created at "${l}"`}]}}catch(u){return {content:[{type:"text",text:`Could not create person note: ${u instanceof Error?u.message:String(u)}`}],isError:true}}}),s.tool("remember_reference","Bookmark a URL or resource with a summary, tags, and personal notes. Great for saving articles, videos, tools, or documentation.",{title:z$1.string().describe("Title of the resource"),url:z$1.string().describe("URL of the resource"),source:z$1.string().optional().default("").describe('Source (e.g., "Hacker News", "Twitter")'),summary:z$1.string().optional().default("").describe("Brief summary"),takeaways:z$1.string().optional().default("").describe("Key takeaways"),thoughts:z$1.string().optional().default("").describe("Your personal thoughts"),related:z$1.string().optional().default("").describe("Related notes"),tags:z$1.array(z$1.string()).optional().describe("Tags for categorization"),folder:z$1.string().optional().describe("Folder to save to")},async({title:t,url:e,source:o,summary:r,takeaways:i,thoughts:a,related:d,folder:p})=>{try{let u=N("article",{title:t,url:e,source:o,summary:r,takeaways:i,thoughts:a,related:d}),l=`${p??c.inbox.folder}/${t}.md`;return await n.writeNote(l,u),{content:[{type:"text",text:`Reference saved at "${l}"`}]}}catch(u){return {content:[{type:"text",text:`Could not save reference: ${u instanceof Error?u.message:String(u)}`}],isError:true}}});}function st(s,n,c){s.tool("log","Append an entry to today's daily note. Creates the daily note if it doesn't exist. Adds entries under a configurable heading with timestamps.",{entry:z$1.string().describe("The entry to add to the daily note"),heading:z$1.string().optional().default("Log").describe('Heading to add the entry under (default: "Log")')},async({entry:t,heading:e})=>{try{let o=`${c.dailyNotes.folder}/${y()}.md`,i=`
75
+ - ${new Date().toLocaleTimeString("en-US",{hour12:!1,hour:"2-digit",minute:"2-digit"})} \u2014 ${t}`;try{await n.readNote(o);try{await n.patchNote(o,i,{operation:"append",targetHeading:e});}catch{await n.appendToNote(o,`
76
+ ## ${e}
77
+ ${i}
78
+ `);}}catch{let a=`---
79
+ date: ${y()}
80
+ tags:
81
+ - daily
82
+ ---
83
+
84
+ # ${y()}
85
+
86
+ ## ${e}
87
+ ${i}
88
+ `;await n.writeNote(o,a);}return {content:[{type:"text",text:`Logged to daily note (${y()}): ${t}`}]}}catch(o){return {content:[{type:"text",text:`Could not log entry: ${o instanceof Error?o.message:String(o)}`}],isError:true}}}),s.tool("log_task","Add a task (checkbox item) to today's daily note. Creates the daily note if it doesn't exist.",{task:z$1.string().describe("The task description"),heading:z$1.string().optional().default("Tasks").describe('Heading to add the task under (default: "Tasks")')},async({task:t,heading:e})=>{try{let o=`${c.dailyNotes.folder}/${y()}.md`,r=`
89
+ - [ ] ${t}`;try{await n.readNote(o);try{await n.patchNote(o,r,{operation:"append",targetHeading:e});}catch{await n.appendToNote(o,`
90
+ ## ${e}
91
+ ${r}
92
+ `);}}catch{let i=`---
93
+ date: ${y()}
94
+ tags:
95
+ - daily
96
+ ---
97
+
98
+ # ${y()}
99
+
100
+ ## ${e}
101
+ ${r}
102
+ `;await n.writeNote(o,i);}return {content:[{type:"text",text:`Task added to daily note: ${t}`}]}}catch(o){return {content:[{type:"text",text:`Could not add task: ${o instanceof Error?o.message:String(o)}`}],isError:true}}}),s.tool("reflect","Generate reflection prompts based on recent vault activity. Reads today's and recent daily notes to suggest areas for reflection.",{},async()=>{try{let t="";try{let d=`${c.dailyNotes.folder}/${y()}.md`;t=await n.readNote(d);}catch{}let o=(await n.listFiles()).filter(d=>d.extension==="md"),i=["What was the most important thing you learned today?","What decision did you make that you want to remember?","What are you most proud of from today's work?","What would you do differently next time?","What's one thing you want to explore further?","Who helped you today, and how?","What's blocking you right now?","What's one thing you're grateful for today?"].sort(()=>Math.random()-.5).slice(0,4),a=`**Reflection Prompts for ${y()}:**
103
+
104
+ `;return a+=i.map((d,p)=>`${p+1}. ${d}`).join(`
105
+ `),t&&(a+=`
106
+
107
+ ---
108
+
109
+ **Today's note preview:**
110
+ ${t.slice(0,500)}`),a+=`
111
+
112
+ ---
113
+
114
+ Vault stats: ${o.length} notes total.`,a+="\n\nTip: Use `log` to add your reflections to today's daily note.",{content:[{type:"text",text:a}]}}catch(t){return {content:[{type:"text",text:`Reflection error: ${t instanceof Error?t.message:String(t)}`}],isError:true}}});}function it(s,n,c){s.tool("create_note","Create a new note in the vault. Supports optional templates, folder routing, and frontmatter. Will not overwrite existing notes unless explicitly requested.",{path:z$1.string().describe('Path for the new note (e.g., "Projects/My Project.md")'),content:z$1.string().describe("Markdown content for the note"),template:z$1.enum(["decision","meeting","learning","idea","person","project","book","article","weekly-review","session"]).optional().describe("Optional template to use"),variables:z$1.record(z$1.string()).optional().describe("Template variables as key-value pairs"),overwrite:z$1.boolean().optional().default(false).describe("Whether to overwrite if note already exists")},async({path:t,content:e,template:o,variables:r,overwrite:i})=>{try{if(!i)try{return await n.readNote(t),{content:[{type:"text",text:`Note already exists at "${t}". Set overwrite=true to replace it.`}]}}catch{}let a=e;return o&&(a=N(o,{...r,content:e})),await n.writeNote(t,a),{content:[{type:"text",text:`Note created at "${t}"`}]}}catch(a){return {content:[{type:"text",text:`Could not create note: ${a instanceof Error?a.message:String(a)}`}],isError:true}}}),s.tool("append_to_note","Append content to the end of an existing note. The note must already exist.",{path:z$1.string().describe("Path to the note to append to"),content:z$1.string().describe("Content to append")},async({path:t,content:e})=>{try{return await n.appendToNote(t,`
115
+ ${e}
116
+ `),{content:[{type:"text",text:`Content appended to "${t}"`}]}}catch(o){return {content:[{type:"text",text:`Could not append to note: ${o instanceof Error?o.message:String(o)}`}],isError:true}}}),s.tool("update_section","Replace the content under a specific heading in a note. Useful for updating a section without modifying the rest of the note.",{path:z$1.string().describe("Path to the note"),heading:z$1.string().describe("Heading text of the section to replace"),content:z$1.string().describe("New content for the section")},async({path:t,heading:e,content:o})=>{try{let r=await n.readNote(t),i=_(r,e,o);return await n.writeNote(t,i),{content:[{type:"text",text:`Section "${e}" updated in "${t}"`}]}}catch(r){return {content:[{type:"text",text:`Could not update section: ${r instanceof Error?r.message:String(r)}`}],isError:true}}});}function at(s,n,c){s.tool("add_link",'Add a [[wikilink]] to a note, connecting it to another note in the vault. Appends the link under a "Related" heading or at the end of the note.',{path:z$1.string().describe("Path of the note to add the link to"),target:z$1.string().describe("Name of the note to link to (without .md extension)"),context:z$1.string().optional().describe("Optional context for why these notes are related")},async({path:t,target:e,context:o})=>{try{let r=await n.readNote(t);if(C(r).includes(e))return {content:[{type:"text",text:`"${t}" already links to [[${e}]]`}]};let a=o?`
117
+ - [[${e}]] \u2014 ${o}`:`
118
+ - [[${e}]]`;try{await n.patchNote(t,a,{operation:"append",targetHeading:"Related"});}catch{await n.appendToNote(t,`
119
+ ## Related
120
+ ${a}
121
+ `);}return {content:[{type:"text",text:`Added link to [[${e}]] in "${t}"`}]}}catch(r){return {content:[{type:"text",text:`Could not add link: ${r instanceof Error?r.message:String(r)}`}],isError:true}}}),s.tool("suggest_connections","Analyze a note and suggest other notes that could be linked to it. Uses shared tags, mentions, and content similarity to find connections.",{path:z$1.string().describe("Path to the note to analyze"),limit:z$1.number().optional().default(10).describe("Maximum suggestions to return")},async({path:t,limit:e})=>{try{let o=await n.readNote(t),r=C(o),i=w(o),a=new Map;for(let f of i.slice(0,5))try{let l=await n.search(`tag:#${f}`);for(let m of l)if(m.filename!==t&&!r.includes(m.filename.replace(/\.md$/,""))){let h=a.get(m.filename)??[];h.push(`Shared tag: #${f}`),a.set(m.filename,h);}}catch{}let d=o.split(/\s+/).filter(f=>f.length>5).slice(0,10);for(let f of d.slice(0,3))try{let l=await n.search(f);for(let m of l.slice(0,5))if(m.filename!==t&&!r.includes(m.filename.replace(/\.md$/,""))){let h=a.get(m.filename)??[];h.some(x=>x.startsWith("Mentions:"))||(h.push(`Mentions: "${f}"`),a.set(m.filename,h));}}catch{}let p=[...a.entries()].sort((f,l)=>l[1].length-f[1].length).slice(0,e);if(p.length===0)return {content:[{type:"text",text:`No connection suggestions found for "${t}". The note may be well-connected already!`}]};let u=p.map(([f,l],m)=>`${m+1}. **${f}**
122
+ ${l.join(", ")}`).join(`
123
+
124
+ `);return {content:[{type:"text",text:`Suggested connections for "${t}":
125
+
126
+ ${u}
127
+
128
+ Use \`add_link\` to connect any of these notes.`}]}}catch(o){return {content:[{type:"text",text:`Could not suggest connections: ${o instanceof Error?o.message:String(o)}`}],isError:true}}}),s.tool("find_gaps","Find broken links in the vault \u2014 [[wikilinks]] that point to notes that don't exist. These represent knowledge gaps or notes waiting to be written.",{limit:z$1.number().optional().default(20).describe("Maximum gaps to return")},async({limit:t})=>{try{let e=await n.listFiles(),o=new Set(e.filter(f=>f.extension==="md").map(f=>f.name.toLowerCase())),r=new Map,i=e.filter(f=>f.extension==="md"),a=Math.min(i.length,100),d=i.sort(()=>Math.random()-.5).slice(0,a);for(let f of d)try{let l=await n.readNote(f.path),m=C(l);for(let h of m)if(!o.has(h.toLowerCase())){let x=r.get(h)??[];x.push(f.path),r.set(h,x);}}catch{}let p=[...r.entries()].sort((f,l)=>l[1].length-f[1].length).slice(0,t);return p.length===0?{content:[{type:"text",text:`No broken links found (sampled ${a} of ${i.length} notes).`}]}:{content:[{type:"text",text:`Knowledge gaps (broken links) found in vault:
129
+
130
+ ${p.map(([f,l],m)=>`${m+1}. **[[${f}]]** \u2014 referenced by ${l.length} note(s): ${l.slice(0,3).join(", ")}${l.length>3?"...":""}`).join(`
131
+ `)}
132
+
133
+ These are concepts referenced but not yet written about. Use \`create_note\` to fill them in.`}]}}catch(e){return {content:[{type:"text",text:`Could not find gaps: ${e instanceof Error?e.message:String(e)}`}],isError:true}}}),s.tool("find_orphans","Find orphan notes \u2014 notes with no incoming or outgoing links. These are disconnected from the knowledge graph and might need connecting.",{limit:z$1.number().optional().default(20).describe("Maximum orphans to return")},async({limit:t})=>{try{let o=(await n.listFiles()).filter(u=>u.extension==="md"),r=new Set,i=Math.min(o.length,100),a=o.sort(()=>Math.random()-.5).slice(0,i);for(let u of a)try{let f=await n.readNote(u.path),l=C(f);if(l.length>0){r.add(u.path);for(let m of l){let h=o.find(x=>x.name.toLowerCase()===m.toLowerCase());h&&r.add(h.path);}}}catch{}let d=a.filter(u=>!r.has(u.path)).slice(0,t);return d.length===0?{content:[{type:"text",text:`No orphan notes found (sampled ${i} notes). Your vault is well-connected!`}]}:{content:[{type:"text",text:`Orphan notes (no links in or out):
134
+
135
+ ${d.map((u,f)=>`${f+1}. ${u.path}`).join(`
136
+ `)}
137
+
138
+ Consider linking these to related notes using \`add_link\` or \`suggest_connections\`.`}]}}catch(e){return {content:[{type:"text",text:`Could not find orphans: ${e instanceof Error?e.message:String(e)}`}],isError:true}}});}function ct(s,n,c){s.tool("add_tag","Add one or more tags to a note. Tags are added to the YAML frontmatter. If the note has no frontmatter, it will be created.",{path:z$1.string().describe("Path to the note"),tags:z$1.array(z$1.string()).describe("Tags to add (without # prefix)")},async({path:t,tags:e})=>{try{let o=await n.readNote(t),{frontmatter:r,body:i}=S(o),a=[];if(r.tags){let l=r.tags;l.startsWith("[")?a.push(...l.slice(1,-1).split(",").map(m=>m.trim())):a.push(l);}let p=[...new Set([...a,...e])].map(l=>` - ${l}`).join(`
139
+ `),u=Object.entries(r).filter(([l])=>l!=="tags").map(([l,m])=>`${l}: ${m}`).join(`
140
+ `),f=`---
141
+ ${u}${u?`
142
+ `:""}tags:
143
+ ${p}
144
+ ---
145
+
146
+ ${i}`;return await n.writeNote(t,f),{content:[{type:"text",text:`Added tags ${e.map(l=>`#${l}`).join(", ")} to "${t}"`}]}}catch(o){return {content:[{type:"text",text:`Could not add tags: ${o instanceof Error?o.message:String(o)}`}],isError:true}}}),s.tool("update_properties","Update YAML frontmatter properties of a note. Can add new properties or modify existing ones.",{path:z$1.string().describe("Path to the note"),properties:z$1.record(z$1.string()).describe('Properties to set as key-value pairs (e.g., {"status": "done", "priority": "high"})')},async({path:t,properties:e})=>{try{let o=await n.readNote(t),{frontmatter:r,body:i}=S(o),a={...r,...e},p=`---
147
+ ${Object.entries(a).map(([f,l])=>`${f}: ${l}`).join(`
148
+ `)}
149
+ ---
150
+
151
+ ${i}`;await n.writeNote(t,p);let u=Object.entries(e).map(([f,l])=>`${f}: ${l}`).join(", ");return {content:[{type:"text",text:`Updated properties in "${t}": ${u}`}]}}catch(o){return {content:[{type:"text",text:`Could not update properties: ${o instanceof Error?o.message:String(o)}`}],isError:true}}}),s.tool("rename_note","Rename a note by creating a copy at the new path and deleting the original. Note: Obsidian will update backlinks if the app is running.",{old_path:z$1.string().describe("Current path of the note"),new_path:z$1.string().describe("New path for the note")},async({old_path:t,new_path:e})=>{try{let o=await n.readNote(t);try{return await n.readNote(e),{content:[{type:"text",text:`A note already exists at "${e}". Choose a different name.`}]}}catch{}return await n.writeNote(e,o),await n.deleteNote(t),{content:[{type:"text",text:`Renamed "${t}" to "${e}"`}]}}catch(o){return {content:[{type:"text",text:`Could not rename note: ${o instanceof Error?o.message:String(o)}`}],isError:true}}}),s.tool("move_note","Move a note to a different folder in the vault. Preserves the filename.",{path:z$1.string().describe("Current path of the note"),destination:z$1.string().describe('Destination folder (e.g., "Projects", "Archive")')},async({path:t,destination:e})=>{try{let o=await n.readNote(t),r=t.split("/").pop()??t,i=`${e}/${r}`;try{return await n.readNote(i),{content:[{type:"text",text:`A note already exists at "${i}". Rename the note first.`}]}}catch{}return await n.writeNote(i,o),await n.deleteNote(t),{content:[{type:"text",text:`Moved "${t}" to "${i}"`}]}}catch(o){return {content:[{type:"text",text:`Could not move note: ${o instanceof Error?o.message:String(o)}`}],isError:true}}});}function lt(s,n,c){s.tool("vault_overview","Get an overview of your Obsidian vault: total notes, folder structure, tag distribution, and general statistics.",{},async()=>{try{let t=await n.listFiles(),e=t.filter(l=>l.extension==="md"),o=t.filter(l=>l.extension!=="md"),r=new Map;for(let l of e){let m=l.path.split("/"),h=m.length>1?m.slice(0,-1).join("/"):"(root)";r.set(h,(r.get(h)??0)+1);}let i=[...r.entries()].sort((l,m)=>m[1]-l[1]).slice(0,15),a=new Map,d=Math.min(e.length,50),p=e.slice(0,d);for(let l of p)try{let m=await n.readNote(l.path),h=w(m);for(let x of h)a.set(x,(a.get(x)??0)+1);}catch{}let u=[...a.entries()].sort((l,m)=>m[1]-l[1]).slice(0,15),f=`**Vault Overview**
152
+
153
+ `;return f+=`- **Total notes:** ${e.length}
154
+ `,f+=`- **Other files:** ${o.length} (images, PDFs, etc.)
155
+ `,f+=`- **Folders:** ${r.size}
156
+
157
+ `,f+=`**Top Folders:**
158
+ `,f+=i.map(([l,m])=>` - ${l}: ${m} notes`).join(`
159
+ `),u.length>0&&(f+=`
160
+
161
+ **Top Tags** (sampled from ${d} notes):
162
+ `,f+=u.map(([l,m])=>` - #${l}: ${m}`).join(`
163
+ `)),{content:[{type:"text",text:f}]}}catch(t){return {content:[{type:"text",text:`Could not get vault overview: ${t instanceof Error?t.message:String(t)}`}],isError:true}}}),s.tool("list_tags","List all tags used in the vault with their occurrence counts. Samples notes to build the tag list.",{limit:z$1.number().optional().default(50).describe("Maximum tags to return")},async({limit:t})=>{try{let o=(await n.listFiles()).filter(u=>u.extension==="md"),r=new Map,i=Math.min(o.length,200),a=o.slice(0,i);for(let u of a)try{let f=await n.readNote(u.path),l=w(f);for(let m of l)r.set(m,(r.get(m)??0)+1);}catch{}let d=[...r.entries()].sort((u,f)=>f[1]-u[1]).slice(0,t);if(d.length===0)return {content:[{type:"text",text:"No tags found in vault."}]};let p=d.map(([u,f])=>`#${u} (${f})`).join(`
164
+ `);return {content:[{type:"text",text:`**Tags in vault** (sampled ${i} of ${o.length} notes):
165
+
166
+ ${p}`}]}}catch(e){return {content:[{type:"text",text:`Could not list tags: ${e instanceof Error?e.message:String(e)}`}],isError:true}}}),s.tool("get_vault_structure","Get the folder structure of the vault as a tree with note counts per folder. Useful for understanding vault organization.",{},async()=>{try{let e=(await n.listFiles()).filter(a=>a.extension==="md"),o=new Map;for(let a of e){let d=a.path.split("/");if(d.length>1)for(let p=1;p<d.length;p++){let u=d.slice(0,p).join("/");p===d.length-1?o.set(u,(o.get(u)??0)+1):o.has(u)||o.set(u,0);}else o.set("(root)",(o.get("(root)")??0)+1);}let i=[...o.entries()].sort((a,d)=>a[0].localeCompare(d[0])).map(([a,d])=>{let p=a.split("/").length-1,u=" ".repeat(p),f=a.split("/").pop()??a;return `${u}${f}/ (${d} notes)`}).join(`
167
+ `);return {content:[{type:"text",text:`**Vault Structure** (${e.length} total notes):
168
+
169
+ ${i}`}]}}catch(t){return {content:[{type:"text",text:`Could not get vault structure: ${t instanceof Error?t.message:String(t)}`}],isError:true}}});}function dt(s,n,c){s.tool("find_tasks","Find all checkbox tasks across the vault. Filter by status (open, done, or all). Returns tasks with their source note and line number.",{status:z$1.enum(["open","done","all"]).optional().default("open").describe("Filter by task status"),query:z$1.string().optional().describe("Optional search query to filter tasks by text"),limit:z$1.number().optional().default(30).describe("Maximum tasks to return")},async({status:t,query:e,limit:o})=>{try{let i=(await n.listFiles()).filter(l=>l.extension==="md"),a=[],d=Math.min(i.length,100),p=i.slice(0,d);for(let l of p)try{let m=await n.readNote(l.path),h=G(m);for(let x of h)e&&!x.text.toLowerCase().includes(e.toLowerCase())||t==="open"&&x.done||t==="done"&&!x.done||a.push({text:x.text,done:x.done,file:l.path,line:x.line});}catch{}if(a.length===0)return {content:[{type:"text",text:`No ${t==="all"?"":t+" "}tasks found${e?` matching "${e}"`:""}.`}]};let u=a.slice(0,o),f=u.map((l,m)=>`${m+1}. [${l.done?"x":" "}] ${l.text}
170
+ *${l.file}:${l.line}*`).join(`
171
+
172
+ `);return {content:[{type:"text",text:`**${t==="all"?"All":t==="open"?"Open":"Completed"} Tasks** (${a.length} found, showing ${u.length}):
173
+
174
+ ${f}`}]}}catch(r){return {content:[{type:"text",text:`Could not find tasks: ${r instanceof Error?r.message:String(r)}`}],isError:true}}}),s.tool("complete_task","Mark a specific task as done by replacing [ ] with [x] at the given line in a note.",{path:z$1.string().describe("Path to the note containing the task"),line:z$1.number().describe("Line number of the task (1-based)")},async({path:t,line:e})=>{try{let r=(await n.readNote(t)).split(`
175
+ `);if(e<1||e>r.length)return {content:[{type:"text",text:`Line ${e} is out of range (note has ${r.length} lines)`}],isError:!0};let i=r[e-1],a=i.match(/^(\s*-\s+)\[[ ]\](\s+.+)$/);return a?(r[e-1]=`${a[1]}[x]${a[2]}`,await n.writeNote(t,r.join(`
176
+ `)),{content:[{type:"text",text:`Completed task: "${a[2].trim()}" in "${t}"`}]}):{content:[{type:"text",text:`Line ${e} is not an open task: "${i.trim()}"`}],isError:!0}}catch(o){return {content:[{type:"text",text:`Could not complete task: ${o instanceof Error?o.message:String(o)}`}],isError:true}}});}function ft(s,n,c){s.resource("today","vault://today",{description:"Today's daily note content. Auto-updates with the current day's note.",mimeType:"text/markdown"},async t=>{try{let e=`${c.dailyNotes.folder}/${y()}.md`,o=await n.readNote(e);return {contents:[{uri:t.href,text:`# Today's Daily Note (${y()})
177
+
178
+ ${o}`,mimeType:"text/markdown"}]}}catch{return {contents:[{uri:t.href,text:`No daily note for today (${y()}).`,mimeType:"text/plain"}]}}}),s.resource("recent","vault://recent",{description:"Summary of recently modified notes in the vault.",mimeType:"text/markdown"},async t=>{try{let r=(await n.listFiles()).filter(i=>i.extension==="md").slice(0,10).map((i,a)=>`${a+1}. ${i.path}`).join(`
179
+ `);return {contents:[{uri:t.href,text:`# Recent Notes
180
+
181
+ ${r}`,mimeType:"text/markdown"}]}}catch{return {contents:[{uri:t.href,text:"Could not fetch recent notes.",mimeType:"text/plain"}]}}}),s.resource("tags","vault://tags",{description:"Tag cloud with counts from the vault.",mimeType:"text/markdown"},async t=>{try{let o=(await n.listFiles()).filter(p=>p.extension==="md"),r=new Map,i=Math.min(o.length,50);for(let p of o.slice(0,i))try{let u=await n.readNote(p.path);for(let f of w(u))r.set(f,(r.get(f)??0)+1);}catch{}let d=[...r.entries()].sort((p,u)=>u[1]-p[1]).slice(0,30).map(([p,u])=>`- #${p} (${u})`).join(`
182
+ `);return {contents:[{uri:t.href,text:`# Vault Tags
183
+
184
+ ${d||"No tags found."}`,mimeType:"text/markdown"}]}}catch{return {contents:[{uri:t.href,text:"Could not fetch tags.",mimeType:"text/plain"}]}}}),s.resource("context","vault://context",{description:"Contextual notes relevant to the current working directory or project. Auto-infers which notes may be useful.",mimeType:"text/markdown"},async t=>{try{let o=process.cwd().split("/").pop()??"",r=[];if(o)try{r=(await n.search(o)).slice(0,5).map(d=>d.filename);}catch{}if(r.length===0)return {contents:[{uri:t.href,text:`# Context
185
+
186
+ No vault notes found related to the current project "${o}".`,mimeType:"text/markdown"}]};let i=r.map((a,d)=>`${d+1}. ${a}`).join(`
187
+ `);return {contents:[{uri:t.href,text:`# Context for "${o}"
188
+
189
+ Relevant vault notes:
190
+
191
+ ${i}`,mimeType:"text/markdown"}]}}catch{return {contents:[{uri:t.href,text:"Could not determine context.",mimeType:"text/plain"}]}}});}var z="mindcache";function k(s){process.stderr.write(`[${z}] ${s}
192
+ `);}function P(s){process.stderr.write(`[${z}] ERROR: ${s}
193
+ `);}function ut(s){process.stderr.write(`[${z}] WARN: ${s}
194
+ `);}var F="0.1.0";function pt(s){let n=new McpServer({name:"mindcache",version:F},{instructions:["MindCache connects your Obsidian vault to AI.","Use the search and ask tools to find information in the user's personal knowledge base.","Use the remember tools to capture decisions, meetings, ideas, learnings, and references.","Use the log tool to add entries to the daily note.","Use the connect tools to build links between related notes.","Always check the vault before asking the user to repeat information they may have already documented.","When creating notes, use appropriate templates and add relevant tags."].join(" ")}),c=new M(s);return k("Registering tools..."),et(n,c),nt(n,c,s),rt(n,c,s),st(n,c,s),it(n,c),at(n,c),ct(n,c),lt(n,c),dt(n,c),k("Registering resources..."),ft(n,c,s),k("Server configured with 40 tools and 4 resources"),n}var Y={vault:"",dailyNotes:{folder:"Daily",format:"YYYY-MM-DD"},templates:{folder:"Templates/MindCache"},inbox:{folder:"MindCache/Inbox",requireReview:false}};function Ot(s){let n={},c="";for(let t of s.split(`
195
+ `)){let e=t.replace(/#.*$/,"").trimEnd();if(!e.trim())continue;let o=e.length-e.trimStart().length,r=e.trim(),i=r.indexOf(":");if(i<0)continue;let a=r.slice(0,i).trim(),d=r.slice(i+1).trim();o===0&&!d?(c=a,n[c]||(n[c]={})):o>0&&c?n[c][a]=d:n[a]=d;}return n}function _t(){let s=[resolve(process.cwd(),".mindcache.yml"),resolve(process.cwd(),".mindcache.yaml"),join(homedir(),".config","mindcache","config.yml"),join(homedir(),".config","mindcache","config.yaml"),join(homedir(),".mindcache.yml")];for(let n of s)if(existsSync(n))return n;return null}function j(){let s={vault:Y.vault,dailyNotes:{...Y.dailyNotes},templates:{...Y.templates},inbox:{...Y.inbox}};process.env.MINDCACHE_VAULT&&(s.vault=process.env.MINDCACHE_VAULT);let n=process.env.MINDCACHE_CONFIG||_t();if(n&&existsSync(n)){k(`Loading config from ${n}`);try{let c=readFileSync(n,"utf-8"),t=Ot(c);typeof t.vault=="string"&&(s.vault=t.vault);let e=t.daily_notes??t.dailyNotes;e&&(e.folder&&(s.dailyNotes.folder=e.folder),e.format&&(s.dailyNotes.format=e.format));let o=t.templates;o&&o.folder&&(s.templates.folder=o.folder);let r=t.inbox;r&&(r.folder&&(s.inbox.folder=r.folder),r.require_review&&(s.inbox.requireReview=r.require_review==="true"));}catch(c){ut(`Failed to parse config: ${c instanceof Error?c.message:String(c)}`);}}return s.vault.startsWith("~")&&(s.vault=s.vault.replace("~",homedir())),s}var Ht=`
196
+ MindCache v${F} \u2014 Your Obsidian vault, connected to AI.
197
+
198
+ Usage:
199
+ mindcache Start the MCP server (default)
200
+ mindcache init Interactive setup
201
+ mindcache doctor Diagnose connection issues
202
+ mindcache config Show current configuration
203
+ mindcache --help Show this help message
204
+ mindcache --version Show version
205
+
206
+ Environment variables:
207
+ MINDCACHE_VAULT Path to Obsidian vault
208
+ MINDCACHE_CONFIG Path to config file
209
+
210
+ Config file locations (checked in order):
211
+ .mindcache.yml (current directory)
212
+ ~/.config/mindcache/config.yml
213
+ ~/.mindcache.yml
214
+
215
+ Learn more: https://usemindcache.com
216
+ `;async function yt(s){let n=createInterface({input:process.stdin,output:process.stderr});return new Promise(c=>{n.question(s,t=>{n.close(),c(t.trim());});})}async function Ut(){process.stderr.write(`
217
+ MindCache Setup
218
+ `),process.stderr.write(`===============
219
+
220
+ `),process.stderr.write(`MindCache reads your Obsidian vault directly from the filesystem.
221
+ `),process.stderr.write(`No plugins required \u2014 just point it at your vault folder.
222
+
223
+ `);let s=join(homedir(),"Documents","Obsidian Vault"),n=await yt(`Obsidian vault path [${s}]: `)||s,c=await yt("Daily notes folder [Daily]: ")||"Daily",t=`# MindCache Configuration
224
+ vault: ${n}
225
+
226
+ daily_notes:
227
+ folder: ${c}
228
+ format: YYYY-MM-DD
229
+
230
+ templates:
231
+ folder: Templates/MindCache
232
+
233
+ inbox:
234
+ folder: MindCache/Inbox
235
+ require_review: false
236
+ `,e=join(homedir(),".config","mindcache");existsSync(e)||mkdirSync(e,{recursive:true});let o=join(e,"config.yml");writeFileSync(o,t),process.stderr.write(`
237
+ Config saved to: ${o}
238
+
239
+ `),process.stderr.write(`Checking vault...
240
+ `);let r=j(),a=await new M(r).health();a.ok?process.stderr.write(` Found ${a.noteCount} notes in vault
241
+
242
+ `):(process.stderr.write(` ${a.error}
243
+ `),process.stderr.write(` Check that the vault path is correct.
244
+
245
+ `)),process.stderr.write(`Add MindCache to Claude Code:
246
+ `),process.stderr.write(` claude mcp add --scope user mindcache -- npx @augmnt-sh/mindcache
247
+
248
+ `),process.exit(0);}async function zt(){process.stderr.write(`
249
+ MindCache Doctor v${F}
250
+ `),process.stderr.write(`==========================
251
+
252
+ `);let s=j();process.stderr.write(`Checking configuration...
253
+ `),s.vault?process.stderr.write(` [OK] Vault: ${s.vault}
254
+ `):process.stderr.write(` [WARN] No vault path configured. Run: mindcache init
255
+ `),process.stderr.write(` [OK] Daily notes: ${s.dailyNotes.folder}/
256
+ `),process.stderr.write(` [OK] Templates: ${s.templates.folder}/
257
+ `),process.stderr.write(` [OK] Inbox: ${s.inbox.folder}/
258
+ `),process.stderr.write(`
259
+ Checking vault access...
260
+ `);let c=await new M(s).health();c.ok?(process.stderr.write(` [OK] Vault readable
261
+ `),process.stderr.write(` [OK] Found ${c.noteCount} markdown notes
262
+ `)):(process.stderr.write(` [FAIL] ${c.error}
263
+ `),process.stderr.write(`
264
+ Troubleshooting:
265
+ `),process.stderr.write(` 1. Check that the vault path is correct
266
+ `),process.stderr.write(` 2. Check file permissions
267
+ `),process.stderr.write(` 3. Run: mindcache init
268
+ `)),process.stderr.write(`
269
+ `),process.exit(c.ok?0:1);}function Vt(){let s=j();process.stderr.write(`
270
+ MindCache Configuration
271
+ `),process.stderr.write(`=======================
272
+
273
+ `),process.stderr.write(`Vault: ${s.vault||"(not set)"}
274
+ `),process.stderr.write(`Daily folder: ${s.dailyNotes.folder}
275
+ `),process.stderr.write(`Daily format: ${s.dailyNotes.format}
276
+ `),process.stderr.write(`Templates: ${s.templates.folder}
277
+ `),process.stderr.write(`Inbox: ${s.inbox.folder}
278
+ `),process.stderr.write(`Review mode: ${s.inbox.requireReview?"on":"off"}
279
+ `),process.stderr.write(`
280
+ `),process.exit(0);}async function qt(){let s=process.version;parseInt(s.slice(1))<18&&(P(`Node.js >= 18 required, found ${s}`),process.exit(1)),k(`mindcache v${F} | Node ${s} | ${process.platform}`);let c=j();c.vault||k('WARN: No vault path configured. Run "mindcache init" for setup.');let t=pt(c),e=new StdioServerTransport,o=async()=>{k("Shutting down..."),await t.close(),process.exit(0);};process.on("SIGINT",o),process.on("SIGTERM",o),await t.connect(e);}var Gt=process.argv[2];switch(Gt){case "init":Ut().catch(s=>{P(s instanceof Error?s.message:String(s)),process.exit(1);});break;case "doctor":zt().catch(s=>{P(s instanceof Error?s.message:String(s)),process.exit(1);});break;case "config":Vt();break;case "--version":case "-v":process.stderr.write(`mindcache v${F}
281
+ `),process.exit(0);break;case "--help":case "-h":process.stderr.write(Ht),process.exit(0);break;default:qt().catch(s=>{P(`Fatal: ${s instanceof Error?s.message:String(s)}`),process.exit(1);});}//# sourceMappingURL=cli.js.map
282
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/markdown.ts","../src/obsidian.ts","../src/utils/dates.ts","../src/tools/find.ts","../src/tools/read.ts","../src/templates.ts","../src/tools/remember.ts","../src/tools/journal.ts","../src/tools/write.ts","../src/tools/connect.ts","../src/tools/organize.ts","../src/tools/understand.ts","../src/tools/tasks.ts","../src/resources/index.ts","../src/utils/logger.ts","../src/server.ts","../src/config.ts","../src/cli.ts"],"names":["extractSection","content","heading","lines","capturing","headingLevel","result","line","headingMatch","level","text","replaceSection","newContent","skipping","parseFrontmatter","match","frontmatter","colonIdx","key","value","extractWikilinks","m","extractTags","matches","extractTasks","tasks","i","wordCount","body","w","ObsidianClient","config","notePath","resolved","join","filePath","dir","dirname","existsSync","mkdirSync","results","entries","readdirSync","entry","fullPath","query","mdFiles","f","queryLower","file","readFileSync","contentLower","idx","count","pos","start","end","context","a","b","path","writeFileSync","appendFileSync","options","existing","updated","headingLower","insertIdx","j","nextMatch","unlinkSync","now","allPaths","relPath","relative","name","basename","extname","extension","contextLength","err","formatDate","date","y","d","today","startOfWeek","day","diff","weekDates","dates","parseDateRange","range","lower","thisWeekStart","lastWeekStart","lastWeekEnd","rangeMatch","daysMatch","registerFindTools","server","client","_config","z","formatted","contexts","question","topResults","notes","tags","links","truncated","t","outlinks","related","link","r","tag","noteName","backlinkResults","sorted","info","limit","from","to","fromStr","toStr","term","registerReadTools","section","words","l","k","v","dailyPath","__dirname","fileURLToPath","TEMPLATES_DIR","TEMPLATE_CACHE","loadTemplate","applyTemplate","template","variables","allVars","renderTemplate","registerRememberTools","title","folder","noteTitle","tagLine","noteContent","attendees","agenda","action_items","follow_up","decision","consequences","alternatives","idea","why","next_steps","concept","key_points","examples","application","source","role","organization","contact","interaction","url","summary","takeaways","thoughts","registerJournalTools","formattedEntry","task","formattedTask","todayContent","selected","response","p","registerWriteTools","overwrite","finalContent","registerConnectTools","target","linkLine","existingLinks","suggestions","reasons","word","files","existingNotes","gaps","sampleSize","sampled","sources","linked","orphans","registerOrganizeTools","existingTags","tagStr","tagYaml","fmEntries","properties","merged","old_path","new_path","destination","filename","newPath","registerUnderstandTools","otherFiles","folderCounts","parts","topFolders","tagCounts","topTags","folders","tree","depth","indent","registerTaskTools","status","allTasks","displayed","targetLine","registerResources","uri","projectName","PREFIX","log","message","logError","logWarn","SERVER_VERSION","createServer","McpServer","DEFAULT_CONFIG","parseSimpleYaml","currentSection","rawLine","trimmed","findConfigFile","candidates","resolve","homedir","candidate","loadConfig","configPath","raw","parsed","daily","templates","inbox","HELP","prompt","rl","createInterface","answer","runInit","defaultVault","vault","dailyFolder","configContent","configDir","health","runDoctor","showConfig","startServer","nodeVersion","transport","StdioServerTransport","shutdown","command"],"mappings":";ibAIO,SAASA,EAAeC,CAAAA,CAAiBC,CAAAA,CAAgC,CAC9E,IAAMC,CAAAA,CAAQF,EAAQ,KAAA,CAAM;AAAA,CAAI,CAAA,CAC5BG,CAAAA,CAAY,KAAA,CACZC,CAAAA,CAAe,EACbC,CAAAA,CAAmB,EAAC,CAE1B,IAAA,IAAWC,CAAAA,IAAQJ,CAAAA,CAAO,CACxB,IAAMK,EAAeD,CAAAA,CAAK,KAAA,CAAM,mBAAmB,CAAA,CAEnD,GAAIC,CAAAA,CAAc,CAChB,IAAMC,EAAQD,CAAAA,CAAa,CAAC,CAAA,CAAE,MAAA,CACxBE,EAAOF,CAAAA,CAAa,CAAC,CAAA,CAAE,IAAA,GAE7B,GAAIJ,CAAAA,CAAW,CACb,GAAIK,CAAAA,EAASJ,CAAAA,CAAc,MAC3BC,CAAAA,CAAO,KAAKC,CAAI,EAClB,CAAA,KAAWG,CAAAA,CAAK,aAAY,GAAMR,CAAAA,CAAQ,WAAA,EAAY,GACpDE,EAAY,IAAA,CACZC,CAAAA,CAAeI,CAAAA,CACfH,CAAAA,CAAO,IAAA,CAAKC,CAAI,CAAA,EAEpB,CAAA,KAAWH,GACTE,CAAAA,CAAO,IAAA,CAAKC,CAAI,EAEpB,CAEA,OAAOD,CAAAA,CAAO,MAAA,CAAS,CAAA,CAAIA,EAAO,IAAA,CAAK;AAAA,CAAI,CAAA,CAAE,IAAA,EAAK,CAAI,IACxD,CAKO,SAASK,CAAAA,CAAeV,CAAAA,CAAiBC,CAAAA,CAAiBU,CAAAA,CAA4B,CAC3F,IAAMT,CAAAA,CAAQF,EAAQ,KAAA,CAAM;AAAA,CAAI,EAC1BK,CAAAA,CAAmB,EAAC,CACtBO,CAAAA,CAAW,MACXR,CAAAA,CAAe,CAAA,CAEnB,IAAA,IAAWE,CAAAA,IAAQJ,EAAO,CACxB,IAAMK,EAAeD,CAAAA,CAAK,KAAA,CAAM,mBAAmB,CAAA,CAEnD,GAAIC,CAAAA,CAAc,CAChB,IAAMC,CAAAA,CAAQD,CAAAA,CAAa,CAAC,CAAA,CAAE,OACxBE,CAAAA,CAAOF,CAAAA,CAAa,CAAC,CAAA,CAAE,MAAK,CAE9BK,CAAAA,EAAYJ,GAASJ,CAAAA,EACvBQ,CAAAA,CAAW,MACXP,CAAAA,CAAO,IAAA,CAAKC,CAAI,CAAA,EACPG,EAAK,WAAA,EAAY,GAAMR,CAAAA,CAAQ,WAAA,IACxCW,CAAAA,CAAW,IAAA,CACXR,CAAAA,CAAeI,CAAAA,CACfH,EAAO,IAAA,CAAKC,CAAI,EAChBD,CAAAA,CAAO,IAAA,CAAK,EAAE,CAAA,CACdA,CAAAA,CAAO,IAAA,CAAKM,CAAU,EACtBN,CAAAA,CAAO,IAAA,CAAK,EAAE,CAAA,EAEdA,CAAAA,CAAO,KAAKC,CAAI,EAEpB,CAAA,KAAYM,CAAAA,EACVP,EAAO,IAAA,CAAKC,CAAI,EAEpB,CAEA,OAAOD,EAAO,IAAA,CAAK;AAAA,CAAI,CACzB,CAKO,SAASQ,CAAAA,CAAiBb,EAAwE,CACvG,IAAMc,CAAAA,CAAQd,CAAAA,CAAQ,KAAA,CAAM,oCAAoC,CAAA,CAChE,GAAI,CAACc,CAAAA,CAAO,OAAO,CAAE,WAAA,CAAa,EAAC,CAAG,IAAA,CAAMd,CAAQ,EAEpD,IAAMe,CAAAA,CAAsC,EAAC,CAC7C,IAAA,IAAWT,CAAAA,IAAQQ,CAAAA,CAAM,CAAC,EAAE,KAAA,CAAM;AAAA,CAAI,CAAA,CAAG,CACvC,IAAME,CAAAA,CAAWV,EAAK,OAAA,CAAQ,GAAG,CAAA,CACjC,GAAIU,CAAAA,CAAW,CAAA,CAAG,CAChB,IAAMC,CAAAA,CAAMX,EAAK,KAAA,CAAM,CAAA,CAAGU,CAAQ,CAAA,CAAE,IAAA,EAAK,CACnCE,CAAAA,CAAQZ,CAAAA,CAAK,KAAA,CAAMU,EAAW,CAAC,CAAA,CAAE,MAAK,CAC5CD,CAAAA,CAAYE,CAAG,CAAA,CAAIC,EACrB,CACF,CAEA,OAAO,CAAE,YAAAH,CAAAA,CAAa,IAAA,CAAMD,CAAAA,CAAM,CAAC,CAAE,CACvC,CAKO,SAASK,CAAAA,CAAiBnB,CAAAA,CAA2B,CAE1D,OAAO,CAAC,GADQA,CAAAA,CAAQ,QAAA,CAAS,iCAAiC,CAChD,CAAA,CAAE,IAAIoB,CAAAA,EAAKA,CAAAA,CAAE,CAAC,CAAC,CACnC,CAKO,SAASC,CAAAA,CAAYrB,CAAAA,CAA2B,CACrD,IAAMsB,CAAAA,CAAUtB,EAAQ,QAAA,CAAS,6BAA6B,CAAA,CAC9D,OAAO,CAAC,GAAG,IAAI,GAAA,CAAI,CAAC,GAAGsB,CAAO,CAAA,CAAE,IAAIF,CAAAA,EAAKA,CAAAA,CAAE,CAAC,CAAC,CAAC,CAAC,CACjD,CAKO,SAASG,CAAAA,CAAavB,CAAAA,CAAuE,CAClG,IAAMwB,EAA8D,EAAC,CAC/DtB,CAAAA,CAAQF,CAAAA,CAAQ,KAAA,CAAM;AAAA,CAAI,CAAA,CAEhC,IAAA,IAASyB,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAIvB,CAAAA,CAAM,MAAA,CAAQuB,CAAAA,EAAAA,CAAK,CACrC,IAAMX,CAAAA,CAAQZ,CAAAA,CAAMuB,CAAC,EAAE,KAAA,CAAM,+BAA+B,CAAA,CACxDX,CAAAA,EACFU,CAAAA,CAAM,IAAA,CAAK,CACT,IAAA,CAAMV,CAAAA,CAAM,CAAC,CAAA,CACb,IAAA,CAAMA,CAAAA,CAAM,CAAC,IAAM,GAAA,CACnB,IAAA,CAAMW,CAAAA,CAAI,CACZ,CAAC,EAEL,CAEA,OAAOD,CACT,CAKO,SAASE,CAAAA,CAAU1B,CAAAA,CAAyB,CACjD,GAAM,CAAE,IAAA,CAAA2B,CAAK,CAAA,CAAId,CAAAA,CAAiBb,CAAO,CAAA,CACzC,OAAO2B,CAAAA,CAAK,KAAA,CAAM,KAAK,CAAA,CAAE,MAAA,CAAOC,CAAAA,EAAKA,CAAAA,CAAE,OAAS,CAAC,CAAA,CAAE,MACrD,CC7GO,IAAMC,CAAAA,CAAN,KAAqB,CAClB,SAAA,CACA,SAAA,CAAgC,IAAA,CAChC,aAAA,CAAgB,CAAA,CACP,SAAA,CAAY,GAAA,CAE7B,WAAA,CAAYC,CAAAA,CAAyB,CACnC,IAAA,CAAK,SAAA,CAAYA,CAAAA,CAAO,MAC1B,CAEQ,OAAA,CAAQC,CAAAA,CAA0B,CAExC,IAAMC,CAAAA,CAAWC,IAAAA,CAAK,IAAA,CAAK,UAAWF,CAAQ,CAAA,CAC9C,GAAI,CAACC,CAAAA,CAAS,UAAA,CAAW,IAAA,CAAK,SAAS,CAAA,CACrC,MAAM,IAAI,KAAA,CAAM,4BAA4B,CAAA,CAE9C,OAAOA,CACT,CAEQ,SAAA,CAAUE,CAAAA,CAAwB,CACxC,IAAMC,CAAAA,CAAMC,OAAAA,CAAQF,CAAQ,CAAA,CACvBG,UAAAA,CAAWF,CAAG,CAAA,EACjBG,SAAAA,CAAUH,CAAAA,CAAK,CAAE,SAAA,CAAW,IAAK,CAAC,EAEtC,CAKQ,OAAA,CAAQA,CAAAA,CAAuB,CACrC,IAAMI,CAAAA,CAAoB,EAAC,CACvBC,CAAAA,CACJ,GAAI,CACFA,CAAAA,CAAUC,WAAAA,CAAYN,CAAAA,CAAK,CAAE,aAAA,CAAe,CAAA,CAAK,CAAC,EACpD,CAAA,KAAQ,CACN,OAAOI,CACT,CAEA,IAAA,IAAWG,KAASF,CAAAA,CAAS,CAG3B,GADIE,CAAAA,CAAM,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EACzBA,CAAAA,CAAM,IAAA,GAAS,cAAA,CAAgB,SAEnC,IAAMC,CAAAA,CAAWV,IAAAA,CAAKE,CAAAA,CAAKO,CAAAA,CAAM,IAAI,CAAA,CACjCA,CAAAA,CAAM,WAAA,EAAY,CACpBH,CAAAA,CAAQ,IAAA,CAAK,GAAG,IAAA,CAAK,OAAA,CAAQI,CAAQ,CAAC,CAAA,CAEtCJ,EAAQ,IAAA,CAAKI,CAAQ,EAEzB,CACA,OAAOJ,CACT,CAKA,MAAM,IAAA,EAAyB,CAC7B,OAAOF,UAAAA,CAAW,IAAA,CAAK,SAAS,CAClC,CAKA,MAAM,MAAA,CAAOO,CAAAA,CAAwC,CAEnD,IAAMC,CAAAA,CAAAA,CADQ,MAAM,IAAA,CAAK,SAAA,EAAU,EACb,MAAA,CAAOC,CAAAA,EAAKA,CAAAA,CAAE,SAAA,GAAc,IAAI,CAAA,CAChDC,CAAAA,CAAaH,CAAAA,CAAM,WAAA,EAAY,CAC/BL,CAAAA,CAA0B,EAAC,CAEjC,IAAA,IAAWS,CAAAA,IAAQH,CAAAA,CACjB,GAAI,CACF,IAAM7C,CAAAA,CAAUiD,YAAAA,CAAa,IAAA,CAAK,OAAA,CAAQD,CAAAA,CAAK,IAAI,CAAA,CAAG,OAAO,CAAA,CACvDE,CAAAA,CAAelD,CAAAA,CAAQ,WAAA,EAAY,CACnCmD,CAAAA,CAAMD,CAAAA,CAAa,OAAA,CAAQH,CAAU,CAAA,CAE3C,GAAII,CAAAA,EAAO,CAAA,CAAG,CAEZ,IAAIC,CAAAA,CAAQ,CAAA,CACRC,CAAAA,CAAM,CAAA,CACV,KAAA,CAAQA,CAAAA,CAAMH,CAAAA,CAAa,OAAA,CAAQH,EAAYM,CAAG,CAAA,IAAO,CAAA,CAAA,EACvDD,CAAAA,EAAAA,CACAC,CAAAA,EAAON,CAAAA,CAAW,MAAA,CAIpB,IAAMO,CAAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,CAAA,CAAGH,CAAAA,CAAM,EAAE,EAC5BI,CAAAA,CAAM,IAAA,CAAK,GAAA,CAAIvD,CAAAA,CAAQ,MAAA,CAAQmD,CAAAA,CAAMP,CAAAA,CAAM,MAAA,CAAS,EAAE,CAAA,CACtDY,CAAAA,CAAUxD,CAAAA,CAAQ,KAAA,CAAMsD,CAAAA,CAAOC,CAAG,CAAA,CAAE,OAAA,CAAQ,KAAA,CAAO,GAAG,CAAA,CAAE,IAAA,EAAK,CAEnEhB,CAAAA,CAAQ,IAAA,CAAK,CACX,QAAA,CAAUS,CAAAA,CAAK,IAAA,CACf,KAAA,CAAOI,CAAAA,CAAQ,IAAMJ,CAAAA,CAAK,IAAA,CAAK,WAAA,EAAY,CAAE,QAAA,CAASD,CAAU,CAAA,CAAI,EAAA,CAAK,CAAA,CAAA,CACzE,OAAA,CAAS,CAAC,CAAE,KAAA,CAAO,CAAE,KAAA,CAAOI,CAAAA,CAAK,GAAA,CAAKA,CAAAA,CAAMP,CAAAA,CAAM,MAAO,CAAA,CAAG,OAAA,CAAAY,CAAQ,CAAC,CACvE,CAAC,EACH,CACF,CAAA,KAAQ,CAER,CAGF,OAAOjB,CAAAA,CAAQ,IAAA,CAAK,CAACkB,CAAAA,CAAGC,CAAAA,GAAMA,CAAAA,CAAE,KAAA,CAAQD,CAAAA,CAAE,KAAK,CACjD,CAKA,MAAM,QAAA,CAASE,CAAAA,CAA+B,CAC5C,IAAMhB,CAAAA,CAAW,IAAA,CAAK,OAAA,CAAQgB,CAAI,CAAA,CAClC,GAAI,CAACtB,UAAAA,CAAWM,CAAQ,CAAA,CACtB,MAAM,IAAI,KAAA,CAAM,mBAAmBgB,CAAI,CAAA,CAAE,CAAA,CAE3C,OAAOV,YAAAA,CAAaN,CAAAA,CAAU,OAAO,CACvC,CAKA,MAAM,SAAA,CAAUgB,CAAAA,CAAc3D,CAAAA,CAAgC,CAC5D,IAAM2C,CAAAA,CAAW,IAAA,CAAK,OAAA,CAAQgB,CAAI,CAAA,CAClC,IAAA,CAAK,SAAA,CAAUhB,CAAQ,CAAA,CACvBiB,aAAAA,CAAcjB,CAAAA,CAAU3C,CAAAA,CAAS,OAAO,CAAA,CACxC,IAAA,CAAK,UAAY,KACnB,CAKA,MAAM,YAAA,CAAa2D,CAAAA,CAAc3D,CAAAA,CAAgC,CAC/D,IAAM2C,CAAAA,CAAW,IAAA,CAAK,OAAA,CAAQgB,CAAI,CAAA,CAClC,GAAI,CAACtB,UAAAA,CAAWM,CAAQ,CAAA,CACtB,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmBgB,CAAI,CAAA,CAAE,CAAA,CAE3CE,cAAAA,CAAelB,CAAAA,CAAU3C,CAAAA,CAAS,OAAO,EAC3C,CAKA,MAAM,SAAA,CAAU2D,CAAAA,CAAc3D,CAAAA,CAAiB8D,CAAAA,CAI7B,CAChB,IAAMnB,CAAAA,CAAW,IAAA,CAAK,OAAA,CAAQgB,CAAI,CAAA,CAC5BI,CAAAA,CAAWd,YAAAA,CAAaN,CAAAA,CAAU,OAAO,CAAA,CAE/C,GAAImB,CAAAA,EAAS,aAAA,CAAe,CAE1B,GAAI,CADY/D,CAAAA,CAAegE,CAAAA,CAAUD,CAAAA,CAAQ,aAAa,CAAA,CAE5D,MAAM,IAAI,MAAM,CAAA,SAAA,EAAYA,CAAAA,CAAQ,aAAa,CAAA,WAAA,CAAa,CAAA,CAGhE,GAAIA,CAAAA,CAAQ,SAAA,GAAc,SAAA,CAAW,CACnC,IAAME,CAAAA,CAAUtD,CAAAA,CAAeqD,CAAAA,CAAUD,CAAAA,CAAQ,aAAA,CAAe9D,CAAO,CAAA,CACvE4D,aAAAA,CAAcjB,CAAAA,CAAUqB,CAAAA,CAAS,OAAO,EAC1C,CAAA,KAAO,CAEL,IAAM9D,CAAAA,CAAQ6D,CAAAA,CAAS,KAAA,CAAM;AAAA,CAAI,EAC3BE,CAAAA,CAAeH,CAAAA,CAAQ,cAAc,WAAA,EAAY,CACnDI,EAAY,EAAA,CAEhB,IAAA,IAASzC,EAAI,CAAA,CAAGA,CAAAA,CAAIvB,EAAM,MAAA,CAAQuB,CAAAA,EAAAA,CAAK,CACrC,IAAMX,CAAAA,CAAQZ,EAAMuB,CAAC,CAAA,CAAE,MAAM,iBAAiB,CAAA,CAC9C,GAAIX,CAAAA,EAASA,CAAAA,CAAM,CAAC,CAAA,CAAE,IAAA,GAAO,WAAA,EAAY,GAAMmD,EAAc,CAE3D,IAAM7D,EAAeF,CAAAA,CAAMuB,CAAC,EAAE,OAAA,CAAQ,GAAG,EACzCyC,CAAAA,CAAYzC,CAAAA,CAAI,CAAA,CAChB,IAAA,IAAS0C,EAAI1C,CAAAA,CAAI,CAAA,CAAG0C,EAAIjE,CAAAA,CAAM,MAAA,CAAQiE,IAAK,CACzC,IAAMC,EAAYlE,CAAAA,CAAMiE,CAAC,EAAE,KAAA,CAAM,aAAa,EAC9C,GAAIC,CAAAA,EAAaA,EAAU,CAAC,CAAA,CAAE,QAAUhE,CAAAA,CAAc,MACtD8D,EAAYC,CAAAA,CAAI,EAClB,CACA,KACF,CACF,CAEA,GAAID,CAAAA,EAAa,EACfhE,CAAAA,CAAM,MAAA,CAAOgE,EAAW,CAAA,CAAGlE,CAAO,EAClC4D,aAAAA,CAAcjB,CAAAA,CAAUzC,EAAM,IAAA,CAAK;AAAA,CAAI,CAAA,CAAG,OAAO,CAAA,CAAA,KAEjD,MAAM,IAAI,KAAA,CAAM,CAAA,SAAA,EAAY4D,EAAQ,aAAa,CAAA,WAAA,CAAa,CAElE,CACF,CAAA,KAAA,GAAWA,GAAS,UAAA,GAAe,MAAA,CAAW,CAC5C,IAAM5D,CAAAA,CAAQ6D,EAAS,KAAA,CAAM;AAAA,CAAI,CAAA,CACjC7D,CAAAA,CAAM,MAAA,CAAO4D,CAAAA,CAAQ,UAAA,CAAY,CAAA,CAAG9D,CAAO,CAAA,CAC3C4D,aAAAA,CAAcjB,CAAAA,CAAUzC,CAAAA,CAAM,IAAA,CAAK;AAAA,CAAI,CAAA,CAAG,OAAO,EACnD,CAAA,KACE2D,eAAelB,CAAAA,CAAU3C,CAAAA,CAAS,OAAO,EAE7C,CAKA,MAAM,WAAW2D,CAAAA,CAA6B,CAC5C,IAAMhB,CAAAA,CAAW,IAAA,CAAK,OAAA,CAAQgB,CAAI,CAAA,CAClC,GAAI,CAACtB,UAAAA,CAAWM,CAAQ,CAAA,CACtB,MAAM,IAAI,KAAA,CAAM,mBAAmBgB,CAAI,CAAA,CAAE,EAE3CU,UAAAA,CAAW1B,CAAQ,CAAA,CACnB,IAAA,CAAK,SAAA,CAAY,KACnB,CAKA,MAAM,SAAA,EAAkC,CACtC,IAAM2B,CAAAA,CAAM,IAAA,CAAK,KAAI,CACrB,GAAI,IAAA,CAAK,SAAA,EAAaA,CAAAA,CAAM,IAAA,CAAK,cAAgB,IAAA,CAAK,SAAA,CACpD,OAAO,IAAA,CAAK,SAAA,CAGd,IAAMC,CAAAA,CAAW,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,SAAS,CAAA,CAC5C,YAAK,SAAA,CAAYA,CAAAA,CAAS,GAAA,CAAI5B,CAAAA,EAAY,CACxC,IAAM6B,EAAUC,QAAAA,CAAS,IAAA,CAAK,SAAA,CAAW9B,CAAQ,CAAA,CAC3C+B,CAAAA,CAAOC,SAASH,CAAAA,CAASI,OAAAA,CAAQJ,CAAO,CAAC,CAAA,CACzCK,EAAYD,OAAAA,CAAQJ,CAAO,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA,CAC1C,OAAO,CAAE,IAAA,CAAMA,CAAAA,CAAS,IAAA,CAAAE,CAAAA,CAAM,SAAA,CAAAG,CAAU,CAC1C,CAAC,CAAA,CACD,IAAA,CAAK,aAAA,CAAgBP,CAAAA,CACd,KAAK,SACd,CAMA,MAAM,aAAA,EAAiC,CACrC,MAAM,IAAI,KAAA,CAAM,yFAAyF,CAC3G,CAMA,MAAM,mBAAqC,CACzC,MAAM,IAAI,KAAA,CAAM,yFAAyF,CAC3G,CAKA,MAAM,iBAAA,CAAkB1B,CAAAA,CAAekC,CAAAA,CAAwB,GAAA,CAA8B,CAE3F,IAAMjC,CAAAA,CAAAA,CADQ,MAAM,KAAK,SAAA,EAAU,EACb,OAAOC,CAAAA,EAAKA,CAAAA,CAAE,SAAA,GAAc,IAAI,CAAA,CAChDC,CAAAA,CAAaH,EAAM,WAAA,EAAY,CAC/BL,CAAAA,CAA0B,EAAC,CAEjC,IAAA,IAAWS,KAAQH,CAAAA,CACjB,GAAI,CACF,IAAM7C,CAAAA,CAAUiD,YAAAA,CAAa,KAAK,OAAA,CAAQD,CAAAA,CAAK,IAAI,CAAA,CAAG,OAAO,EACvDE,CAAAA,CAAelD,CAAAA,CAAQ,WAAA,EAAY,CACnCsB,CAAAA,CAAmC,GACrC+B,CAAAA,CAAM,CAAA,CAEV,KAAA,CAAQA,CAAAA,CAAMH,CAAAA,CAAa,OAAA,CAAQH,EAAYM,CAAG,CAAA,IAAO,CAAA,CAAA,EAAI,CAC3D,IAAMC,CAAAA,CAAQ,KAAK,GAAA,CAAI,CAAA,CAAGD,CAAAA,CAAMyB,CAAa,CAAA,CACvCvB,CAAAA,CAAM,KAAK,GAAA,CAAIvD,CAAAA,CAAQ,MAAA,CAAQqD,CAAAA,CAAMT,CAAAA,CAAM,MAAA,CAASkC,CAAa,CAAA,CAMvE,GALAxD,CAAAA,CAAQ,IAAA,CAAK,CACX,KAAA,CAAO,CAAE,KAAA,CAAO+B,CAAAA,CAAK,GAAA,CAAKA,CAAAA,CAAMT,CAAAA,CAAM,MAAO,EAC7C,OAAA,CAAS5C,CAAAA,CAAQ,MAAMsD,CAAAA,CAAOC,CAAG,EAAE,OAAA,CAAQ,KAAA,CAAO,GAAG,CAAA,CAAE,IAAA,EACzD,CAAC,CAAA,CACDF,CAAAA,EAAON,CAAAA,CAAW,MAAA,CACdzB,CAAAA,CAAQ,MAAA,EAAU,EAAG,KAC3B,CAEIA,CAAAA,CAAQ,MAAA,CAAS,CAAA,EACnBiB,CAAAA,CAAQ,KAAK,CACX,QAAA,CAAUS,EAAK,IAAA,CACf,KAAA,CAAO1B,EAAQ,MAAA,CAAS,EAAA,EAAM0B,CAAAA,CAAK,IAAA,CAAK,WAAA,EAAY,CAAE,SAASD,CAAU,CAAA,CAAI,EAAA,CAAK,CAAA,CAAA,CAClF,OAAA,CAAAzB,CACF,CAAC,EAEL,CAAA,KAAQ,CAER,CAGF,OAAOiB,CAAAA,CAAQ,KAAK,CAACkB,CAAAA,CAAGC,IAAMA,CAAAA,CAAE,KAAA,CAAQD,EAAE,KAAK,CACjD,CAKA,MAAM,MAAA,EAAuE,CAC3E,GAAI,CAAC,IAAA,CAAK,SAAA,CACR,OAAO,CAAE,EAAA,CAAI,MAAO,KAAA,CAAO,+CAAgD,CAAA,CAE7E,GAAI,CAACpB,UAAAA,CAAW,KAAK,SAAS,CAAA,CAC5B,OAAO,CAAE,EAAA,CAAI,KAAA,CAAO,MAAO,CAAA,oBAAA,EAAuB,IAAA,CAAK,SAAS,CAAA,CAAG,CAAA,CAGrE,GAAI,CAGF,OAAO,CAAE,EAAA,CAAI,CAAA,CAAA,CAAM,SAAA,CAAA,CAFL,MAAM,KAAK,SAAA,EAAU,EACb,MAAA,CAAOS,CAAAA,EAAKA,CAAAA,CAAE,SAAA,GAAc,IAAI,CAAA,CAAE,MAClB,CACxC,CAAA,MAASiC,CAAAA,CAAK,CACZ,OAAO,CAAE,EAAA,CAAI,KAAA,CAAO,KAAA,CAAO,CAAA,mBAAA,EAAsBA,aAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,EAAG,CACtG,CACF,CACF,CAAA,CClUO,SAASC,EAAWC,CAAAA,CAAoB,CAC7C,IAAMC,CAAAA,CAAID,CAAAA,CAAK,WAAA,EAAY,CACrB7D,CAAAA,CAAI,MAAA,CAAO6D,EAAK,QAAA,EAAS,CAAI,CAAC,CAAA,CAAE,QAAA,CAAS,CAAA,CAAG,GAAG,CAAA,CAC/CE,CAAAA,CAAI,MAAA,CAAOF,CAAAA,CAAK,OAAA,EAAS,EAAE,QAAA,CAAS,CAAA,CAAG,GAAG,CAAA,CAChD,OAAO,GAAGC,CAAC,CAAA,CAAA,EAAI9D,CAAC,CAAA,CAAA,EAAI+D,CAAC,CAAA,CACvB,CAKO,SAASC,CAAAA,EAAgB,CAC9B,OAAOJ,CAAAA,CAAW,IAAI,IAAM,CAC9B,CAKO,SAASK,CAAAA,CAAYJ,CAAAA,CAAa,IAAI,KAAc,CACzD,IAAME,CAAAA,CAAI,IAAI,IAAA,CAAKF,CAAI,EACjBK,CAAAA,CAAMH,CAAAA,CAAE,MAAA,EAAO,CACfI,CAAAA,CAAOJ,CAAAA,CAAE,SAAQ,CAAIG,CAAAA,EAAOA,CAAAA,GAAQ,CAAA,CAAI,EAAA,CAAK,CAAA,CAAA,CACnD,OAAAH,CAAAA,CAAE,OAAA,CAAQI,CAAI,CAAA,CACdJ,CAAAA,CAAE,QAAA,CAAS,EAAG,CAAA,CAAG,CAAA,CAAG,CAAC,CAAA,CACdA,CACT,CAKO,SAASK,CAAAA,CAAUP,CAAAA,CAAa,IAAI,IAAA,CAAkB,CAC3D,IAAM3B,CAAAA,CAAQ+B,CAAAA,CAAYJ,CAAI,CAAA,CACxBQ,CAAAA,CAAkB,GACxB,IAAA,IAAShE,CAAAA,CAAI,CAAA,CAAGA,CAAAA,CAAI,CAAA,CAAGA,CAAAA,EAAAA,CAAK,CAC1B,IAAM0D,CAAAA,CAAI,IAAI,IAAA,CAAK7B,CAAK,EACxB6B,CAAAA,CAAE,OAAA,CAAQ7B,CAAAA,CAAM,OAAA,EAAQ,CAAI7B,CAAC,EAC7BgE,CAAAA,CAAM,IAAA,CAAKT,CAAAA,CAAWG,CAAC,CAAC,EAC1B,CACA,OAAOM,CACT,CAKO,SAASC,EAAAA,CAAeC,CAAAA,CAAyC,CACtE,IAAMrB,CAAAA,CAAM,IAAI,IAAA,CACVsB,CAAAA,CAAQD,EAAM,WAAA,EAAY,CAAE,IAAA,EAAK,CAEvC,GAAIC,CAAAA,GAAU,QAAS,CACrB,IAAMtC,CAAAA,CAAQ,IAAI,IAAA,CAAKgB,CAAG,EAC1BhB,CAAAA,CAAM,QAAA,CAAS,CAAA,CAAG,CAAA,CAAG,CAAA,CAAG,CAAC,EACzB,IAAMC,CAAAA,CAAM,IAAI,IAAA,CAAKe,CAAG,CAAA,CACxB,OAAAf,CAAAA,CAAI,QAAA,CAAS,EAAA,CAAI,EAAA,CAAI,EAAA,CAAI,GAAG,EACrB,CAAE,IAAA,CAAMD,CAAAA,CAAO,EAAA,CAAIC,CAAI,CAChC,CAEA,GAAIqC,CAAAA,GAAU,WAAA,CAAa,CACzB,IAAMtC,CAAAA,CAAQ,IAAI,IAAA,CAAKgB,CAAG,EAC1BhB,CAAAA,CAAM,OAAA,CAAQA,EAAM,OAAA,EAAQ,CAAI,CAAC,CAAA,CACjCA,CAAAA,CAAM,QAAA,CAAS,EAAG,CAAA,CAAG,CAAA,CAAG,CAAC,CAAA,CACzB,IAAMC,CAAAA,CAAM,IAAI,IAAA,CAAKD,CAAK,CAAA,CAC1B,OAAAC,CAAAA,CAAI,QAAA,CAAS,GAAI,EAAA,CAAI,EAAA,CAAI,GAAG,CAAA,CACrB,CAAE,KAAMD,CAAAA,CAAO,EAAA,CAAIC,CAAI,CAChC,CAEA,GAAIqC,IAAU,WAAA,CAEZ,OAAO,CAAE,IAAA,CADKP,CAAAA,CAAYf,CAAG,EACP,EAAA,CAAIA,CAAI,CAAA,CAGhC,GAAIsB,CAAAA,GAAU,WAAA,CAAa,CACzB,IAAMC,CAAAA,CAAgBR,EAAYf,CAAG,CAAA,CAC/BwB,EAAgB,IAAI,IAAA,CAAKD,CAAa,CAAA,CAC5CC,CAAAA,CAAc,OAAA,CAAQA,EAAc,OAAA,EAAQ,CAAI,CAAC,CAAA,CACjD,IAAMC,CAAAA,CAAc,IAAI,IAAA,CAAKF,CAAa,CAAA,CAC1C,OAAAE,CAAAA,CAAY,eAAA,CAAgB,EAAE,CAAA,CACvB,CAAE,IAAA,CAAMD,CAAAA,CAAe,EAAA,CAAIC,CAAY,CAChD,CAEA,GAAIH,CAAAA,GAAU,YAAA,CAEZ,OAAO,CAAE,KADK,IAAI,IAAA,CAAKtB,CAAAA,CAAI,WAAA,EAAY,CAAGA,CAAAA,CAAI,UAAS,CAAG,CAAC,CAAA,CACrC,EAAA,CAAIA,CAAI,CAAA,CAGhC,GAAIsB,CAAAA,GAAU,YAAA,CAAc,CAC1B,IAAMtC,CAAAA,CAAQ,IAAI,IAAA,CAAKgB,CAAAA,CAAI,WAAA,EAAY,CAAGA,CAAAA,CAAI,QAAA,GAAa,CAAA,CAAG,CAAC,CAAA,CACzDf,CAAAA,CAAM,IAAI,IAAA,CAAKe,EAAI,WAAA,EAAY,CAAGA,CAAAA,CAAI,QAAA,EAAS,CAAG,CAAA,CAAG,GAAI,EAAA,CAAI,EAAA,CAAI,GAAG,CAAA,CAC1E,OAAO,CAAE,IAAA,CAAMhB,CAAAA,CAAO,EAAA,CAAIC,CAAI,CAChC,CAGA,IAAMyC,CAAAA,CAAaJ,CAAAA,CAAM,KAAA,CAAM,gDAAgD,CAAA,CAC/E,GAAII,EACF,OAAO,CAAE,IAAA,CAAM,IAAI,IAAA,CAAKA,CAAAA,CAAW,CAAC,CAAC,CAAA,CAAG,GAAI,IAAI,IAAA,CAAKA,EAAW,CAAC,CAAC,CAAE,CAAA,CAItE,IAAMC,CAAAA,CAAYL,EAAM,KAAA,CAAM,sBAAsB,CAAA,CACpD,GAAIK,CAAAA,CAAW,CACb,IAAM3C,CAAAA,CAAQ,IAAI,IAAA,CAAKgB,CAAG,CAAA,CAC1B,OAAAhB,EAAM,OAAA,CAAQA,CAAAA,CAAM,OAAA,EAAQ,CAAI,QAAA,CAAS2C,CAAAA,CAAU,CAAC,CAAC,CAAC,CAAA,CACtD3C,CAAAA,CAAM,QAAA,CAAS,CAAA,CAAG,EAAG,CAAA,CAAG,CAAC,CAAA,CAClB,CAAE,IAAA,CAAMA,CAAAA,CAAO,GAAIgB,CAAI,CAChC,CAGA,IAAMhB,CAAAA,CAAQ,IAAI,KAAKgB,CAAG,CAAA,CAC1B,OAAAhB,CAAAA,CAAM,OAAA,CAAQA,EAAM,OAAA,EAAQ,CAAI,CAAC,CAAA,CACjCA,CAAAA,CAAM,QAAA,CAAS,EAAG,CAAA,CAAG,CAAA,CAAG,CAAC,CAAA,CAClB,CAAE,IAAA,CAAMA,EAAO,EAAA,CAAIgB,CAAI,CAChC,CCzGO,SAAS4B,EAAAA,CAAkBC,EAAmBC,CAAAA,CAAwBC,CAAAA,CAAgC,CAE3GF,CAAAA,CAAO,IAAA,CACL,SACA,sLAAA,CACA,CAAE,KAAA,CAAOG,GAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,wDAAmD,CAAE,CAAA,CAClF,MAAO,CAAE,KAAA,CAAA1D,CAAM,CAAA,GAAM,CACnB,GAAI,CACF,IAAML,CAAAA,CAAU,MAAM6D,CAAAA,CAAO,iBAAA,CAAkBxD,EAAO,GAAG,CAAA,CACzD,GAAIL,CAAAA,CAAQ,MAAA,GAAW,CAAA,CACrB,OAAO,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,sBAAA,EAAyBK,CAAK,GAAI,CAAC,CAAE,CAAA,CAGhF,IAAM2D,CAAAA,CAAYhE,CAAAA,CAAQ,MAAM,CAAA,CAAG,EAAE,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,CAAG,IAAM,CACnD,IAAMiE,CAAAA,CAAW,CAAA,CAAE,OAAA,CAAQ,KAAA,CAAM,EAAG,CAAC,CAAA,CAAE,GAAA,CAAIpF,CAAAA,EAAK,CAAA,IAAA,EAAOA,CAAAA,CAAE,QAAQ,IAAA,EAAM,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK;AAAA,CAAI,CAAA,CACpF,OAAO,CAAA,EAAG,CAAA,CAAI,CAAC,CAAA,IAAA,EAAO,CAAA,CAAE,QAAQ,CAAA,WAAA,EAAc,CAAA,CAAE,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAC,CAAA;AAAA,EAAMoF,CAAQ,CAAA,CAChF,CAAC,CAAA,CAAE,IAAA,CAAK;;AAAA,CAAM,CAAA,CAEd,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,MAAA,EAASjE,CAAAA,CAAQ,MAAM,iBAAiBK,CAAK,CAAA;;AAAA,EAAS2D,CAAS,CAAA,CAAG,CAAC,CACrG,CACF,CAAA,MAASxB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,cAAA,EAAiBA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CACrG,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,IAAA,CACL,KAAA,CACA,kNAAA,CACA,CAAE,QAAA,CAAUG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,0DAA0D,CAAE,CAAA,CAC5F,MAAO,CAAE,QAAA,CAAAG,CAAS,CAAA,GAAM,CACtB,GAAI,CAEF,IAAMlE,CAAAA,CAAU,MAAM6D,CAAAA,CAAO,iBAAA,CAAkBK,CAAAA,CAAU,GAAG,CAAA,CAC5D,GAAIlE,CAAAA,CAAQ,MAAA,GAAW,CAAA,CACrB,OAAO,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,8BAAA,EAAiCkE,CAAQ,CAAA,CAAA,CAAI,CAAC,CAAE,CAAA,CAI3F,IAAMC,CAAAA,CAAanE,CAAAA,CAAQ,KAAA,CAAM,CAAA,CAAG,CAAC,CAAA,CAC/BoE,CAAAA,CAAkB,EAAC,CAEzB,IAAA,IAAWtG,CAAAA,IAAUqG,CAAAA,CACnB,GAAI,CACF,IAAM1G,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAAS/F,CAAAA,CAAO,QAAQ,CAAA,CAC/C,CAAE,WAAA,CAAAU,CAAY,CAAA,CAAIF,CAAAA,CAAiBb,CAAO,CAAA,CAC1C4G,CAAAA,CAAOvF,CAAAA,CAAYrB,CAAO,CAAA,CAC1B6G,CAAAA,CAAQ1F,CAAAA,CAAiBnB,CAAO,CAAA,CAGhC8G,CAAAA,CAAY9G,CAAAA,CAAQ,MAAA,CAAS,GAAA,CAAOA,CAAAA,CAAQ,KAAA,CAAM,CAAA,CAAG,GAAI,CAAA,CAAI;AAAA,cAAA,CAAA,CAAqBA,CAAAA,CAExF2G,EAAM,IAAA,CACJ,CAAA;AAAA,EAAA,EAAUtG,EAAO,QAAQ,CAAA,EAAA,CAAA,EACxBuG,EAAK,MAAA,CAAS,CAAA,CAAI,YAAYA,CAAAA,CAAK,GAAA,CAAIG,CAAAA,EAAK,CAAA,CAAA,EAAIA,CAAC,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI,CAAC,GAAK,EAAA,CAAA,EACpEF,CAAAA,CAAM,MAAA,CAAS,CAAA,CAAI,aAAaA,CAAAA,CAAM,GAAA,CAAI,GAAK,CAAA,EAAA,EAAK,CAAC,IAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAK,KAC1E9F,CAAAA,CAAY,IAAA,CAAO,YAAYA,CAAAA,CAAY,IAAI,GAAK,EAAA,CAAA,CACrD;;AAAA,EAAO+F,CAAS,EAClB,EACF,CAAA,KAAQ,CAER,CAGF,OAAO,CACL,OAAA,CAAS,CAAC,CACR,IAAA,CAAM,MAAA,CACN,KAAM,CAAA,MAAA,EAASvE,CAAAA,CAAQ,MAAM,CAAA,qBAAA,EAAwBkE,CAAQ,CAAA,oBAAA,EAAuBE,CAAAA,CAAM,MAAM,CAAA;;AAAA,EAAQA,EAAM,IAAA,CAAK;;AAAA,CAAM,CAAC,CAAA,CAC5H,CAAC,CACH,CACF,CAAA,MAAS5B,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,WAAA,EAAcA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAClG,QAAS,IACX,CACF,CACF,CACF,EAGAoB,CAAAA,CAAO,IAAA,CACL,cAAA,CACA,8IAAA,CACA,CAAE,IAAA,CAAMG,GAAAA,CAAE,MAAA,GAAS,QAAA,CAAS,mDAAmD,CAAE,CAAA,CACjF,MAAO,CAAE,IAAA,CAAA3C,CAAK,CAAA,GAAM,CAClB,GAAI,CACF,IAAM3D,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASzC,CAAI,EACpCqD,CAAAA,CAAW7F,CAAAA,CAAiBnB,CAAO,CAAA,CACnC4G,EAAOvF,CAAAA,CAAYrB,CAAO,CAAA,CAE1BiH,CAAAA,CAAU,IAAI,GAAA,CAGpB,IAAA,IAAWC,CAAAA,IAAQF,CAAAA,CAAU,CAC3B,IAAMzE,CAAAA,CAAU,MAAM6D,EAAO,MAAA,CAAO,CAAA,KAAA,EAAQc,CAAI,CAAA,CAAE,CAAA,CAClD,IAAA,IAAWC,CAAAA,IAAK5E,CAAAA,CAAQ,MAAM,CAAA,CAAG,CAAC,CAAA,CAC5B4E,CAAAA,CAAE,QAAA,GAAaxD,CAAAA,EACjBsD,CAAAA,CAAQ,GAAA,CAAIE,EAAE,QAAA,CAAU,CACtB,MAAA,CAAQ,CAAA,yBAAA,EAA4BD,CAAI,CAAA,EAAA,CAAA,CACxC,KAAA,CAAA,CAAQD,CAAAA,CAAQ,GAAA,CAAIE,EAAE,QAAQ,CAAA,EAAG,KAAA,EAAS,CAAA,EAAK,CACjD,CAAC,EAGP,CAGA,QAAWC,CAAAA,IAAOR,CAAAA,CAAK,KAAA,CAAM,CAAA,CAAG,CAAC,CAAA,CAAG,CAClC,IAAMrE,CAAAA,CAAU,MAAM6D,CAAAA,CAAO,MAAA,CAAO,CAAA,KAAA,EAAQgB,CAAG,CAAA,CAAE,CAAA,CACjD,IAAA,IAAWD,CAAAA,IAAK5E,EAAQ,KAAA,CAAM,CAAA,CAAG,CAAC,CAAA,CAChC,GAAI4E,CAAAA,CAAE,QAAA,GAAaxD,CAAAA,CAAM,CACvB,IAAMI,CAAAA,CAAWkD,CAAAA,CAAQ,GAAA,CAAIE,CAAAA,CAAE,QAAQ,CAAA,CACvCF,CAAAA,CAAQ,GAAA,CAAIE,EAAE,QAAA,CAAU,CACtB,MAAA,CAAQpD,CAAAA,CAAW,CAAA,EAAGA,CAAAA,CAAS,MAAM,CAAA,eAAA,EAAkBqD,CAAG,CAAA,CAAA,CAAK,CAAA,aAAA,EAAgBA,CAAG,CAAA,CAAA,CAClF,KAAA,CAAA,CAAQrD,CAAAA,EAAU,KAAA,EAAS,CAAA,EAAK,CAClC,CAAC,EACH,CAEJ,CAGA,IAAMsD,CAAAA,CAAW1D,CAAAA,CAAK,OAAA,CAAQ,OAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,EAAI,EAAKA,CAAAA,CACzD2D,CAAAA,CAAkB,MAAMlB,CAAAA,CAAO,MAAA,CAAO,CAAA,GAAA,EAAMiB,CAAQ,KAAK,CAAA,CAC/D,IAAA,IAAWF,CAAAA,IAAKG,CAAAA,CACd,GAAIH,CAAAA,CAAE,QAAA,GAAaxD,CAAAA,CAAM,CACvB,IAAMI,CAAAA,CAAWkD,CAAAA,CAAQ,GAAA,CAAIE,EAAE,QAAQ,CAAA,CACvCF,CAAAA,CAAQ,GAAA,CAAIE,EAAE,QAAA,CAAU,CACtB,MAAA,CAAQpD,CAAAA,CAAW,GAAGA,CAAAA,CAAS,MAAM,CAAA,oBAAA,CAAA,CAAyB,oBAAA,CAC9D,KAAA,CAAA,CAAQA,CAAAA,EAAU,KAAA,EAAS,CAAA,EAAK,CAClC,CAAC,EACH,CAGF,IAAMwD,CAAAA,CAAS,CAAC,GAAGN,CAAAA,CAAQ,SAAS,CAAA,CACjC,IAAA,CAAK,CAACxD,CAAAA,CAAGC,CAAAA,GAAMA,CAAAA,CAAE,CAAC,EAAE,KAAA,CAAQD,CAAAA,CAAE,CAAC,CAAA,CAAE,KAAK,CAAA,CACtC,KAAA,CAAM,CAAA,CAAG,EAAE,EAEd,GAAI8D,CAAAA,CAAO,MAAA,GAAW,CAAA,CACpB,OAAO,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,4BAAA,EAA+B5D,CAAI,CAAA,CAAA,CAAI,CAAC,CAAE,CAAA,CAGrF,IAAM4C,CAAAA,CAAYgB,CAAAA,CAAO,GAAA,CAAI,CAAC,CAACvE,CAAAA,CAAMwE,CAAI,CAAA,CAAG/F,IAC1C,CAAA,EAAGA,CAAAA,CAAI,CAAC,CAAA,IAAA,EAAOuB,CAAI,CAAA,UAAA,EAAQwE,CAAAA,CAAK,MAAM,CAAA,CACxC,EAAE,IAAA,CAAK;AAAA,CAAI,CAAA,CAEX,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,mBAAA,EAAsB7D,CAAI,CAAA;;AAAA,EAAS4C,CAAS,CAAA,CAAG,CAAC,CAClF,CACF,CAAA,MAASxB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,oBAAA,EAAuBA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC3G,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,IAAA,CACL,aAAA,CACA,mGAAA,CACA,CACE,IAAA,CAAMG,GAAAA,CAAE,KAAA,CAAMA,GAAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,QAAA,CAAS,oEAAoE,CAAA,CACvG,KAAA,CAAOA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,2BAA2B,CAC/E,CAAA,CACA,MAAO,CAAE,IAAA,CAAAM,EAAM,KAAA,CAAAa,CAAM,CAAA,GAAM,CACzB,GAAI,CACF,IAAM7E,CAAAA,CAAQgE,CAAAA,CAAK,GAAA,CAAIG,CAAAA,EAAK,CAAA,KAAA,EAAQA,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,CAC3CxE,CAAAA,CAAU,MAAM6D,CAAAA,CAAO,MAAA,CAAOxD,CAAK,CAAA,CAEzC,GAAIL,EAAQ,MAAA,GAAW,CAAA,CACrB,OAAO,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAM,CAAA,0BAAA,EAA6BqE,CAAAA,CAAK,GAAA,CAAIG,CAAAA,EAAK,CAAA,CAAA,EAAIA,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAG,CAAC,CAAE,CAAA,CAG/G,IAAMR,CAAAA,CAAYhE,CAAAA,CAAQ,KAAA,CAAM,CAAA,CAAGkF,CAAK,CAAA,CAAE,GAAA,CAAI,CAACN,EAAG1F,CAAAA,GAChD,CAAA,EAAGA,CAAAA,CAAI,CAAC,CAAA,EAAA,EAAK0F,CAAAA,CAAE,QAAQ,CAAA,CACzB,EAAE,IAAA,CAAK;AAAA,CAAI,CAAA,CAEX,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,aAAA,EAAgBP,CAAAA,CAAK,IAAIG,CAAAA,EAAK,CAAA,CAAA,EAAIA,CAAC,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI,CAAC,CAAA,EAAA,EAAKxE,CAAAA,CAAQ,MAAM,CAAA;;AAAA,EAAegE,CAAS,CAAA,CAAG,CAAC,CAClI,CACF,CAAA,MAASxB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,kBAAA,EAAqBA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CACzG,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,IAAA,CACL,cAAA,CACA,+KAAA,CACA,CACE,KAAA,CAAOG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,qGAAgG,CAAA,CAC3H,MAAOA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,iBAAiB,CACrE,CAAA,CACA,MAAO,CAAE,KAAA,CAAAX,CAAAA,CAAO,MAAA8B,CAAM,CAAA,GAAM,CAC1B,GAAI,CACF,GAAM,CAAE,IAAA,CAAAC,CAAAA,CAAM,EAAA,CAAAC,CAAG,CAAA,CAAIjC,EAAAA,CAAeC,CAAK,CAAA,CAEnC9C,CAAAA,CAAAA,CADQ,MAAMuD,CAAAA,CAAO,SAAA,EAAU,EACf,MAAA,CAAOtD,CAAAA,EAAKA,CAAAA,CAAE,SAAA,GAAc,IAAI,CAAA,CAGhD8E,CAAAA,CAAUF,CAAAA,CAAK,WAAA,EAAY,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,CACzCG,CAAAA,CAAQF,CAAAA,CAAG,WAAA,EAAY,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,CAAA,CAKrCpB,CAAAA,CAAAA,CAFU,MAAMH,CAAAA,CAAO,MAAA,CAAO,CAAA,CAAA,EAAIwB,CAAO,GAAG,CAAA,EAExB,KAAA,CAAM,CAAA,CAAGH,CAAK,CAAA,CAAE,GAAA,CAAI,CAACN,CAAAA,CAAG1F,CAAAA,GAChD,CAAA,EAAGA,CAAAA,CAAI,CAAC,CAAA,EAAA,EAAK0F,CAAAA,CAAE,QAAQ,CAAA,CACzB,EAAE,IAAA,CAAK;AAAA,CAAI,CAAA,CAEX,OAAO,CACL,OAAA,CAAS,CAAC,CACR,IAAA,CAAM,MAAA,CACN,IAAA,CAAM,CAAA,WAAA,EAAcS,CAAO,CAAA,IAAA,EAAOC,CAAK,CAAA;;AAAA,CAAA,EACpCtB,GAAa,+BAAA,CAAA,CACd;;AAAA,+BAAA,EAAsC1D,EAAQ,MAAM,CAAA,CACxD,CAAC,CACH,CACF,OAASkC,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAM,CAAA,mBAAA,EAAsBA,aAAe,KAAA,CAAQA,CAAAA,CAAI,QAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,EAC1G,OAAA,CAAS,IACX,CACF,CACF,CACF,EAGAoB,CAAAA,CAAO,IAAA,CACL,cACA,8EAAA,CACA,CACE,MAAOG,GAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,EAAE,QAAA,CAAS,kCAAkC,CACtF,CAAA,CACA,MAAO,CAAE,KAAA,CAAAmB,CAAM,IAAM,CACnB,GAAI,CAEF,IAAM5E,CAAAA,CAAAA,CADQ,MAAMuD,CAAAA,CAAO,SAAA,IACL,MAAA,CAAOtD,CAAAA,EAAKA,EAAE,SAAA,GAAc,IAAI,EAMhDyD,CAAAA,CAFS1D,CAAAA,CAAQ,MAAM,CAAA,CAAG4E,CAAK,EAEZ,GAAA,CAAI,CAAC3E,EAAGrB,CAAAA,GAC/B,CAAA,EAAGA,EAAI,CAAC,CAAA,EAAA,EAAKqB,EAAE,IAAI,CAAA,CACrB,EAAE,IAAA,CAAK;AAAA,CAAI,CAAA,CAEX,OAAO,CACL,OAAA,CAAS,CAAC,CACR,IAAA,CAAM,MAAA,CACN,IAAA,CAAM,CAAA,aAAA,EAAgBD,CAAAA,CAAQ,MAAM,CAAA;;AAAA,EAA8B0D,CAAS,CAAA,CAC7E,CAAC,CACH,CACF,CAAA,MAASxB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,oBAAA,EAAuBA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC3G,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,IAAA,CACL,eAAA,CACA,oHAAA,CACA,CACE,IAAA,CAAMG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,+BAA+B,CAAA,CACzD,KAAA,CAAOA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,iBAAiB,CACrE,CAAA,CACA,MAAO,CAAE,IAAA,CAAAwB,EAAM,KAAA,CAAAL,CAAM,CAAA,GAAM,CACzB,GAAI,CACF,IAAMlF,CAAAA,CAAU,MAAM6D,CAAAA,CAAO,iBAAA,CAAkB0B,CAAAA,CAAM,GAAG,CAAA,CAExD,GAAIvF,CAAAA,CAAQ,MAAA,GAAW,CAAA,CACrB,OAAO,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,CAAA,EAAIuF,CAAI,CAAA,gCAAA,CAAmC,CAAC,CAAE,CAAA,CAGzF,IAAMvB,CAAAA,CAAYhE,CAAAA,CAAQ,KAAA,CAAM,CAAA,CAAGkF,CAAK,CAAA,CAAE,GAAA,CAAI,CAACN,CAAAA,CAAG1F,CAAAA,GAAM,CACtD,IAAM+B,CAAAA,CAAU2D,CAAAA,CAAE,OAAA,CAAQ,CAAC,CAAA,EAAG,OAAA,EAAS,IAAA,EAAK,EAAK,EAAA,CACjD,OAAO,CAAA,EAAG1F,CAAAA,CAAI,CAAC,CAAA,IAAA,EAAO0F,CAAAA,CAAE,QAAQ,CAAA;AAAA,IAAA,EAAW3D,CAAO,CAAA,CACpD,CAAC,CAAA,CAAE,IAAA,CAAK;;AAAA,CAAM,CAAA,CAEd,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,CAAA,EAAIsE,CAAI,CAAA,eAAA,EAAkBvF,EAAQ,MAAM,CAAA;;AAAA,EAAcgE,CAAS,CAAA,CAAG,CAAC,CACrG,CACF,CAAA,MAASxB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAM,CAAA,uBAAA,EAA0BA,CAAAA,YAAe,KAAA,CAAQA,EAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,EAAG,CAAC,CAAA,CAC9G,OAAA,CAAS,IACX,CACF,CACF,CACF,EACF,CC/SO,SAASgD,EAAAA,CAAkB5B,CAAAA,CAAmBC,CAAAA,CAAwBtE,CAAAA,CAA+B,CAE1GqE,CAAAA,CAAO,IAAA,CACL,WAAA,CACA,mGAAA,CACA,CAAE,IAAA,CAAMG,GAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,mDAAmD,CAAE,CAAA,CACjF,MAAO,CAAE,IAAA,CAAA3C,CAAK,CAAA,GAAM,CAClB,GAAI,CAEF,OAAO,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CADnB,MAAMyC,CAAAA,CAAO,QAAA,CAASzC,CAAI,CACO,CAAC,CAAE,CACtD,CAAA,MAASoB,EAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,mBAAmBpB,CAAI,CAAA,GAAA,EAAMoB,CAAAA,YAAe,KAAA,CAAQA,EAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,EAAG,CAAC,CAAA,CACjH,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,KACL,cAAA,CACA,mJAAA,CACA,CACE,IAAA,CAAMG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,kBAAkB,CAAA,CAC5C,OAAA,CAASA,GAAAA,CAAE,MAAA,GAAS,QAAA,CAAS,8DAA8D,CAC7F,CAAA,CACA,MAAO,CAAE,IAAA,CAAA3C,CAAAA,CAAM,OAAA,CAAA1D,CAAQ,CAAA,GAAM,CAC3B,GAAI,CACF,IAAMD,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASzC,CAAI,CAAA,CACpCqE,CAAAA,CAAUjI,CAAAA,CAAeC,CAAAA,CAASC,CAAO,CAAA,CAE/C,OAAK+H,CAAAA,CAME,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAMA,CAAQ,CAAC,CAAE,EAL3C,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,YAAA,EAAe/H,CAAO,eAAe0D,CAAI,CAAA,CAAA,CAAI,CAAC,CAChF,CAIJ,CAAA,MAASoB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAM,CAAA,wBAAA,EAA2BA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC/G,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,EAAO,IAAA,CACL,cAAA,CACA,kJAAA,CACA,CAAE,KAAMG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,kBAAkB,CAAE,CAAA,CAChD,MAAO,CAAE,KAAA3C,CAAK,CAAA,GAAM,CAClB,GAAI,CACF,IAAM3D,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASzC,CAAI,CAAA,CACpC,CAAE,YAAA5C,CAAY,CAAA,CAAIF,CAAAA,CAAiBb,CAAO,EAC1C4G,CAAAA,CAAOvF,CAAAA,CAAYrB,CAAO,CAAA,CAC1B6G,EAAQ1F,CAAAA,CAAiBnB,CAAO,CAAA,CAChCiI,CAAAA,CAAQvG,EAAU1B,CAAO,CAAA,CAiB/B,OAAO,CAAE,QAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,KAfnB,CACd,CAAA,EAAA,EAAK2D,CAAI,CAAA,EAAA,CAAA,CACT,GACA,CAAA,WAAA,EAAcsE,CAAK,CAAA,CAAA,CACnBrB,CAAAA,CAAK,OAAS,CAAA,CAAI,CAAA,UAAA,EAAaA,CAAAA,CAAK,GAAA,CAAIG,GAAK,CAAA,CAAA,EAAIA,CAAC,CAAA,CAAE,CAAA,CAAE,KAAK,IAAI,CAAC,CAAA,CAAA,CAAK,IAAA,CACrEF,EAAM,MAAA,CAAS,CAAA,CAAI,CAAA,WAAA,EAAcA,CAAAA,CAAM,IAAIqB,CAAAA,EAAK,CAAA,EAAA,EAAKA,CAAC,CAAA,EAAA,CAAI,EAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAK,KAC3E,MAAA,CAAO,IAAA,CAAKnH,CAAW,CAAA,CAAE,OAAS,CAAA,CAC9B,CAAA;AAAA,EAAoB,OAAO,OAAA,CAAQA,CAAW,CAAA,CAAE,GAAA,CAAI,CAAC,CAACoH,CAAAA,CAAGC,CAAC,CAAA,GAAM,OAAOD,CAAC,CAAA,EAAA,EAAKC,CAAC,CAAA,CAAE,EAAE,IAAA,CAAK;AAAA,CAAI,CAAC,CAAA,CAAA,CAC5F,IAAA,CACJ,EAAA,CACA,KAAA,CACA,EAAA,CACApI,CACF,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK;AAAA,CAAI,CAEsB,CAAC,CAAE,CACtD,OAAS+E,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,wBAAA,EAA2BA,CAAAA,YAAe,KAAA,CAAQA,EAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,EAC/G,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,EAAO,IAAA,CACL,iBAAA,CACA,mHAAA,CACA,CAAE,IAAA,CAAMG,GAAAA,CAAE,QAAO,CAAE,QAAA,CAAS,kBAAkB,CAAE,CAAA,CAChD,MAAO,CAAE,IAAA,CAAA3C,CAAK,CAAA,GAAM,CAClB,GAAI,CACF,IAAM3D,CAAAA,CAAU,MAAMoG,EAAO,QAAA,CAASzC,CAAI,EACpC,CAAE,WAAA,CAAA5C,CAAY,CAAA,CAAIF,CAAAA,CAAiBb,CAAO,EAEhD,GAAI,MAAA,CAAO,IAAA,CAAKe,CAAW,CAAA,CAAE,MAAA,GAAW,EACtC,OAAO,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAM,CAAA,yBAAA,EAA4B4C,CAAI,CAAA,CAAA,CAAI,CAAC,CAAE,EAGlF,IAAM4C,CAAAA,CAAY,MAAA,CAAO,OAAA,CAAQxF,CAAW,CAAA,CACzC,IAAI,CAAC,CAACoH,CAAAA,CAAGC,CAAC,CAAA,GAAM,CAAA,EAAGD,CAAC,CAAA,EAAA,EAAKC,CAAC,CAAA,CAAE,CAAA,CAC5B,IAAA,CAAK;AAAA,CAAI,CAAA,CAEZ,OAAO,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,eAAA,EAAkBzE,CAAI,CAAA;;AAAA,EAAS4C,CAAS,CAAA,CAAG,CAAC,CAAE,CACzF,CAAA,MAASxB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,2BAAA,EAA8BA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAClH,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,IAAA,CACL,YAAA,CACA,4HAAA,CACA,EAAC,CACD,SAAY,CACV,GAAI,CACF,IAAMkC,CAAAA,CAAY,CAAA,EAAGvG,CAAAA,CAAO,UAAA,CAAW,MAAM,IAAIsD,CAAAA,EAAO,CAAA,GAAA,CAAA,CAClDpF,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASiC,CAAS,EAC/C,OAAO,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,sBAAA,EAAyBjD,GAAO,CAAA;;AAAA,EAAWpF,CAAO,CAAA,CAAG,CAAC,CAAE,CACnG,CAAA,KAAQ,CACN,OAAO,CACL,QAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,KAAM,CAAA,+BAAA,EAAkCoF,CAAAA,EAAO,CAAA,gBAAA,EAAmBtD,EAAO,UAAA,CAAW,MAAM,CAAA,CAAA,EAAIsD,CAAAA,EAAO,CAAA,GAAA,CAAM,CAAC,CACxI,CACF,CACF,CACF,CAAA,CAGAe,CAAAA,CAAO,IAAA,CACL,iBACA,kHAAA,CACA,EAAC,CACD,SAAY,CACV,GAAI,CACF,IAAMV,EAAQD,CAAAA,EAAU,CAClBmB,CAAAA,CAAkB,GAExB,IAAA,IAAW1B,CAAAA,IAAQQ,CAAAA,CAAO,CACxB,IAAM9B,CAAAA,CAAO,CAAA,EAAG7B,CAAAA,CAAO,UAAA,CAAW,MAAM,CAAA,CAAA,EAAImD,CAAI,CAAA,GAAA,CAAA,CAChD,GAAI,CACF,IAAMjF,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,SAASzC,CAAI,CAAA,CAC1CgD,CAAAA,CAAM,IAAA,CAAK,MAAM1B,CAAI;;AAAA,EAAOjF,CAAO,CAAA,CAAE,EACvC,CAAA,KAAQ,CAER,CACF,CAEA,OAAI2G,CAAAA,CAAM,MAAA,GAAW,EACZ,CAAE,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,oCAAA,EAAuClB,CAAAA,CAAM,CAAC,CAAC,CAAA,IAAA,EAAOA,CAAAA,CAAM,CAAC,CAAC,CAAA,EAAA,CAAK,CAAC,CAAE,CAAA,CAG1G,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAM,CAAA;;AAAA,EAAmCkB,EAAM,IAAA,CAAK;;AAAA;;AAAA,CAAa,CAAC,CAAA,CAAG,CAAC,CAClG,CACF,CAAA,MAAS5B,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,6BAAA,EAAgCA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CACpH,QAAS,IACX,CACF,CACF,CACF,EAGAoB,CAAAA,CAAO,IAAA,CACL,iBAAA,CACA,8HAAA,CACA,EAAC,CACD,SAAY,CACV,GAAI,CACF,IAAMnG,CAAAA,CAAU,MAAMoG,EAAO,aAAA,EAAc,CACvCzC,CAAAA,CAAO,EAAA,CACX,GAAI,CACFA,CAAAA,CAAO,MAAMyC,CAAAA,CAAO,iBAAA,GACtB,CAAA,KAAQ,CAER,CAEA,OAAO,CACL,OAAA,CAAS,CAAC,CACR,IAAA,CAAM,MAAA,CACN,IAAA,CAAMzC,CAAAA,CACF,kBAAkBA,CAAI,CAAA;;AAAA,EAAS3D,CAAO,CAAA,CAAA,CACtC,CAAA;;AAAA,EAAuBA,CAAO,CAAA,CACpC,CAAC,CACH,CACF,OAAS+E,CAAAA,CAAK,CACZ,OAAO,CACL,QAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,KAAM,CAAA,2BAAA,EAA8BA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,QAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAClH,OAAA,CAAS,IACX,CACF,CACF,CACF,EACF,CCzMA,IAAMuD,GAAYlG,OAAAA,CAAQmG,aAAAA,CAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA,CAClDC,EAAAA,CAAgBvG,IAAAA,CAAKqG,EAAAA,CAAW,KAAM,WAAW,CAAA,CAcjDG,CAAAA,CAAiB,IAAI,IAKpB,SAASC,EAAAA,CAAahE,EAA4B,CACvD,GAAI+D,EAAe,GAAA,CAAI/D,CAAI,CAAA,CAAG,OAAO+D,EAAe,GAAA,CAAI/D,CAAI,CAAA,CAE5D,IAAMf,EAAO1B,IAAAA,CAAKuG,EAAAA,CAAe,CAAA,EAAG9D,CAAI,KAAK,CAAA,CAC7C,GAAI,CAACrC,UAAAA,CAAWsB,CAAI,CAAA,CAClB,MAAM,IAAI,KAAA,CAAM,aAAae,CAAI,CAAA,eAAA,EAAkBf,CAAI,CAAA,CAAE,EAG3D,IAAM3D,CAAAA,CAAUiD,YAAAA,CAAaU,CAAAA,CAAM,OAAO,CAAA,CAC1C,OAAA8E,EAAe,GAAA,CAAI/D,CAAAA,CAAM1E,CAAO,CAAA,CACzBA,CACT,CAMO,SAAS2I,GAAcC,CAAAA,CAAkBC,CAAAA,CAA2C,CACzF,IAAIxI,EAASuI,CAAAA,CAWPE,CAAAA,CAAU,CAAE,GARuB,CACvC,IAAA,CAAM1D,CAAAA,EAAM,CACZ,SAAA,CAAW,IAAI,IAAA,EAAK,CAAE,WAAA,EAAY,CAClC,KAAM,MAAA,CAAO,IAAI,IAAA,EAAK,CAAE,aAAa,CAAA,CACrC,KAAA,CAAO,MAAA,CAAO,IAAI,IAAA,EAAK,CAAE,UAAS,CAAI,CAAC,EAAE,QAAA,CAAS,CAAA,CAAG,GAAG,CAAA,CACxD,IAAK,MAAA,CAAO,IAAI,IAAA,EAAK,CAAE,SAAS,CAAA,CAAE,QAAA,CAAS,CAAA,CAAG,GAAG,CACnD,CAAA,CAE+B,GAAGyD,CAAU,EAE5C,IAAA,GAAW,CAAC5H,CAAAA,CAAKC,CAAK,IAAK,MAAA,CAAO,OAAA,CAAQ4H,CAAO,CAAA,CAC/CzI,EAASA,CAAAA,CAAO,UAAA,CAAW,CAAA,EAAA,EAAKY,CAAG,KAAMC,CAAAA,EAAS,EAAE,CAAA,CAItD,OAAAb,EAASA,CAAAA,CAAO,OAAA,CAAQ,gBAAA,CAAkB,EAAE,EAErCA,CACT,CAKO,SAAS0I,CAAAA,CAAerE,EAAoBmE,CAAAA,CAAoC,EAAC,CAAW,CACjG,IAAMD,CAAAA,CAAWF,EAAAA,CAAahE,CAAI,CAAA,CAClC,OAAOiE,EAAAA,CAAcC,CAAAA,CAAUC,CAAS,CAC1C,CCjEO,SAASG,EAAAA,CAAsB7C,CAAAA,CAAmBC,CAAAA,CAAwBtE,EAA+B,CAE9GqE,CAAAA,CAAO,IAAA,CACL,UAAA,CACA,8JACA,CACE,OAAA,CAASG,IAAE,MAAA,EAAO,CAAE,SAAS,qBAAqB,CAAA,CAClD,KAAA,CAAOA,GAAAA,CAAE,QAAO,CAAE,QAAA,EAAS,CAAE,QAAA,CAAS,kEAAkE,CAAA,CACxG,IAAA,CAAMA,GAAAA,CAAE,KAAA,CAAMA,IAAE,MAAA,EAAQ,CAAA,CAAE,QAAA,GAAW,QAAA,CAAS,yCAAyC,CAAA,CACvF,MAAA,CAAQA,IAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,SAAS,gDAAgD,CACzF,CAAA,CACA,MAAO,CAAE,OAAA,CAAAtG,CAAAA,CAAS,MAAAiJ,CAAAA,CAAO,IAAA,CAAArC,EAAM,MAAA,CAAAsC,CAAO,CAAA,GAAM,CAC1C,GAAI,CACF,IAAMC,CAAAA,CAAYF,CAAAA,EAAS,gBAAgB7D,CAAAA,EAAO,CAAA,CAAA,EAAI,IAAI,MAAK,CAAE,kBAAA,CAAmB,OAAA,CAAS,CAAE,OAAQ,CAAA,CAAA,CAAO,IAAA,CAAM,SAAA,CAAW,MAAA,CAAQ,SAAU,CAAC,CAAC,CAAA,CAAA,CAE7IzB,CAAAA,CAAO,GADQuF,CAAAA,EAAUpH,CAAAA,CAAO,KAAA,CAAM,MAChB,IAAIqH,CAAS,CAAA,GAAA,CAAA,CAEnCC,EAAUxC,CAAAA,EAAQA,CAAAA,CAAK,OAAS,CAAA,CAClC,CAAA;AAAA,EAAUA,EAAK,GAAA,CAAIG,CAAAA,EAAK,OAAOA,CAAC,CAAA,CAAE,EAAE,IAAA,CAAK;AAAA,CAAI,CAAC,CAAA,CAAA,CAC9C,CAAA;AAAA,SAAA,CAAA,CAEEsC,CAAAA,CAAc,CAAA;AAAA,MAAA,EAAcjE,GAAO;AAAA,EAAKgE,CAAO;AAAA;;AAAA,EAAYpJ,CAAO;AAAA,CAAA,CAExE,OAAA,MAAMoG,CAAAA,CAAO,SAAA,CAAUzC,CAAAA,CAAM0F,CAAW,CAAA,CAEjC,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,aAAa1F,CAAI,CAAA,CAAA,CAAI,CAAC,CACxD,CACF,CAAA,MAASoB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,qBAAA,EAAwBA,CAAAA,YAAe,MAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC5G,QAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,IAAA,CACL,kBAAA,CACA,+GACA,CACE,KAAA,CAAOG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,eAAe,CAAA,CAC1C,UAAWA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,mCAAmC,CAAA,CAClE,MAAA,CAAQA,GAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,gBAAgB,CAAA,CACnE,MAAOA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,SAAS,eAAe,CAAA,CACjE,YAAA,CAAcA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,QAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,+BAA+B,EACxF,SAAA,CAAWA,GAAAA,CAAE,MAAA,EAAO,CAAE,UAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,iBAAiB,CAAA,CACvE,MAAA,CAAQA,IAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,SAAS,uCAAuC,CAChF,CAAA,CACA,MAAO,CAAE,KAAA,CAAA2C,CAAAA,CAAO,SAAA,CAAAK,CAAAA,CAAW,MAAA,CAAAC,CAAAA,CAAQ,KAAA,CAAA5C,CAAAA,CAAO,aAAA6C,CAAAA,CAAc,SAAA,CAAAC,CAAAA,CAAW,MAAA,CAAAP,CAAO,CAAA,GAAM,CAC9E,GAAI,CACF,IAAMlJ,CAAAA,CAAU+I,CAAAA,CAAe,SAAA,CAAW,CACxC,KAAA,CAAAE,CAAAA,CAAO,SAAA,CAAAK,CAAAA,CAAW,OAAAC,CAAAA,CAAQ,KAAA,CAAA5C,CAAAA,CAAO,YAAA,CAAA6C,CAAAA,CAAc,SAAA,CAAAC,CACjD,CAAC,EAEK9F,CAAAA,CAAO,CAAA,EADQuF,CAAAA,EAAUpH,CAAAA,CAAO,KAAA,CAAM,MAChB,CAAA,CAAA,EAAImH,CAAK,MACrC,OAAA,MAAM7C,CAAAA,CAAO,SAAA,CAAUzC,CAAAA,CAAM3D,CAAO,CAAA,CAE7B,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,yBAAA,EAA4B2D,CAAI,CAAA,CAAA,CAAI,CAAC,CAAE,CAClF,CAAA,MAASoB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,+BAAA,EAAkCA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CACtH,QAAS,IACX,CACF,CACF,CACF,EAGAoB,CAAAA,CAAO,IAAA,CACL,mBAAA,CACA,gJAAA,CACA,CACE,KAAA,CAAOG,GAAAA,CAAE,MAAA,GAAS,QAAA,CAAS,gBAAgB,CAAA,CAC3C,OAAA,CAASA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,qCAAqC,CAAA,CAClE,QAAA,CAAUA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,kBAAkB,CAAA,CAChD,aAAcA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,GAAW,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,0BAA0B,CAAA,CACnF,YAAA,CAAcA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,oCAAoC,CAAA,CAC7F,QAASA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,GAAW,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,2BAA2B,CAAA,CAC/E,MAAA,CAAQA,GAAAA,CAAE,QAAO,CAAE,QAAA,EAAS,CAAE,QAAA,CAAS,mBAAmB,CAC5D,CAAA,CACA,MAAO,CAAE,MAAA2C,CAAAA,CAAO,OAAA,CAAAzF,CAAAA,CAAS,QAAA,CAAAkG,CAAAA,CAAU,YAAA,CAAAC,CAAAA,CAAc,YAAA,CAAAC,EAAc,OAAA,CAAA3C,CAAAA,CAAS,MAAA,CAAAiC,CAAO,CAAA,GAAM,CACnF,GAAI,CACF,IAAMlJ,CAAAA,CAAU+I,CAAAA,CAAe,UAAA,CAAY,CACzC,KAAA,CAAAE,CAAAA,CAAO,OAAA,CAAAzF,CAAAA,CAAS,SAAAkG,CAAAA,CAAU,YAAA,CAAAC,CAAAA,CAAc,YAAA,CAAAC,EAAc,OAAA,CAAA3C,CACxD,CAAC,CAAA,CAEKtD,EAAO,CAAA,EADQuF,CAAAA,EAAUpH,CAAAA,CAAO,KAAA,CAAM,MAChB,CAAA,CAAA,EAAImH,CAAK,CAAA,GAAA,CAAA,CACrC,aAAM7C,CAAAA,CAAO,SAAA,CAAUzC,CAAAA,CAAM3D,CAAO,CAAA,CAE7B,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,oBAAA,EAAuB2D,CAAI,CAAA,CAAA,CAAI,CAAC,CAAE,CAC7E,CAAA,MAASoB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAM,CAAA,wBAAA,EAA2BA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC/G,OAAA,CAAS,IACX,CACF,CACF,CACF,EAGAoB,CAAAA,CAAO,IAAA,CACL,eAAA,CACA,0EAAA,CACA,CACE,KAAA,CAAOG,GAAAA,CAAE,MAAA,GAAS,QAAA,CAAS,YAAY,CAAA,CACvC,IAAA,CAAMA,IAAE,MAAA,EAAO,CAAE,QAAA,CAAS,yBAAyB,EACnD,GAAA,CAAKA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,EAAE,QAAA,CAAS,uBAAuB,CAAA,CACvE,UAAA,CAAYA,IAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,QAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,sBAAsB,CAAA,CAC7E,OAAA,CAASA,GAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,EAAE,QAAA,CAAS,2BAA2B,CAAA,CAC/E,IAAA,CAAMA,IAAE,KAAA,CAAMA,GAAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,QAAA,EAAS,CAAE,QAAA,CAAS,iBAAiB,CAAA,CAC/D,MAAA,CAAQA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,QAAA,CAAS,mBAAmB,CAC5D,CAAA,CACA,MAAO,CAAE,KAAA,CAAA2C,CAAAA,CAAO,IAAA,CAAAY,CAAAA,CAAM,IAAAC,CAAAA,CAAK,UAAA,CAAAC,CAAAA,CAAY,OAAA,CAAA9C,EAAS,MAAA,CAAAiC,CAAO,CAAA,GAAM,CAC3D,GAAI,CACF,IAAMlJ,CAAAA,CAAU+I,CAAAA,CAAe,MAAA,CAAQ,CACrC,KAAA,CAAAE,CAAAA,CAAO,KAAAY,CAAAA,CAAM,GAAA,CAAAC,CAAAA,CAAK,UAAA,CAAAC,EAAY,OAAA,CAAA9C,CAChC,CAAC,CAAA,CAEKtD,EAAO,CAAA,EADQuF,CAAAA,EAAUpH,CAAAA,CAAO,KAAA,CAAM,MAChB,CAAA,CAAA,EAAImH,CAAK,CAAA,GAAA,CAAA,CACrC,aAAM7C,CAAAA,CAAO,SAAA,CAAUzC,CAAAA,CAAM3D,CAAO,EAE7B,CAAE,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,kBAAA,EAAqB2D,CAAI,CAAA,CAAA,CAAI,CAAC,CAAE,CAC3E,OAASoB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAM,CAAA,wBAAA,EAA2BA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC/G,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,EAAO,IAAA,CACL,mBAAA,CACA,oHAAA,CACA,CACE,KAAA,CAAOG,GAAAA,CAAE,MAAA,EAAO,CAAE,SAAS,kBAAkB,CAAA,CAC7C,OAAA,CAASA,GAAAA,CAAE,QAAO,CAAE,QAAA,CAAS,wBAAwB,CAAA,CACrD,WAAYA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,SAAS,wBAAwB,CAAA,CAC/E,QAAA,CAAUA,GAAAA,CAAE,QAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,2BAA2B,CAAA,CAChF,WAAA,CAAaA,GAAAA,CAAE,MAAA,EAAO,CAAE,UAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,4BAA4B,CAAA,CACpF,MAAA,CAAQA,IAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,wBAAwB,CAAA,CAC3E,OAAA,CAASA,GAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,EAAE,QAAA,CAAS,eAAe,CAAA,CACnE,MAAA,CAAQA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,GAAW,QAAA,CAAS,mBAAmB,CAC5D,CAAA,CACA,MAAO,CAAE,KAAA,CAAA2C,CAAAA,CAAO,QAAAe,CAAAA,CAAS,UAAA,CAAAC,CAAAA,CAAY,QAAA,CAAAC,CAAAA,CAAU,WAAA,CAAAC,CAAAA,CAAa,MAAA,CAAAC,EAAQ,OAAA,CAAAnD,CAAAA,CAAS,MAAA,CAAAiC,CAAO,IAAM,CACxF,GAAI,CACF,IAAMlJ,EAAU+I,CAAAA,CAAe,UAAA,CAAY,CACzC,KAAA,CAAAE,CAAAA,CAAO,OAAA,CAAAe,CAAAA,CAAS,UAAA,CAAAC,EAAY,QAAA,CAAAC,CAAAA,CAAU,WAAA,CAAAC,CAAAA,CAAa,MAAA,CAAAC,CAAAA,CAAQ,OAAA,CAAAnD,CAC7D,CAAC,CAAA,CAEKtD,CAAAA,CAAO,CAAA,EADQuF,CAAAA,EAAUpH,CAAAA,CAAO,KAAA,CAAM,MAChB,CAAA,CAAA,EAAImH,CAAK,CAAA,GAAA,CAAA,CACrC,OAAA,MAAM7C,CAAAA,CAAO,SAAA,CAAUzC,EAAM3D,CAAO,CAAA,CAE7B,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,mBAAA,EAAsB2D,CAAI,CAAA,CAAA,CAAI,CAAC,CAAE,CAC5E,CAAA,MAASoB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,yBAAA,EAA4BA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAChH,QAAS,IACX,CACF,CACF,CACF,EAGAoB,CAAAA,CAAO,IAAA,CACL,iBAAA,CACA,oGAAA,CACA,CACE,IAAA,CAAMG,GAAAA,CAAE,MAAA,GAAS,QAAA,CAAS,eAAgB,CAAA,CAC1C,IAAA,CAAMA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,GAAW,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,qBAAqB,CAAA,CACtE,YAAA,CAAcA,GAAAA,CAAE,QAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,oBAAoB,CAAA,CAC7E,QAASA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,SAAS,qBAAqB,CAAA,CACzE,OAAA,CAASA,GAAAA,CAAE,QAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,uCAAuC,CAAA,CAC3F,WAAA,CAAaA,GAAAA,CAAE,MAAA,EAAO,CAAE,UAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,SAAS,+BAA+B,CAAA,CACvF,KAAA,CAAOA,GAAAA,CAAE,QAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,kBAAkB,EACpE,MAAA,CAAQA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,QAAA,CAAS,mBAAmB,CAC5D,CAAA,CACA,MAAO,CAAE,IAAA,CAAA5B,CAAAA,CAAM,IAAA,CAAA2F,CAAAA,CAAM,YAAA,CAAAC,EAAc,OAAA,CAAAC,CAAAA,CAAS,OAAA,CAAA/G,CAAAA,CAAS,YAAAgH,CAAAA,CAAa,KAAA,CAAA7D,CAAAA,CAAO,MAAA,CAAAuC,CAAO,CAAA,GAAM,CACpF,GAAI,CACF,IAAMlJ,CAAAA,CAAU+I,CAAAA,CAAe,QAAA,CAAU,CACvC,IAAA,CAAArE,CAAAA,CAAM,IAAA,CAAA2F,CAAAA,CAAM,aAAAC,CAAAA,CAAc,OAAA,CAAAC,CAAAA,CAAS,OAAA,CAAA/G,EAAS,WAAA,CAAAgH,CAAAA,CAAa,KAAA,CAAA7D,CAC3D,CAAC,CAAA,CAEKhD,CAAAA,CAAO,CAAA,EADQuF,GAAUpH,CAAAA,CAAO,KAAA,CAAM,MAChB,CAAA,CAAA,EAAI4C,CAAI,CAAA,GAAA,CAAA,CACpC,OAAA,MAAM0B,CAAAA,CAAO,SAAA,CAAUzC,EAAM3D,CAAO,CAAA,CAE7B,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,KAAM,CAAA,wBAAA,EAA2B2D,CAAI,CAAA,CAAA,CAAI,CAAC,CAAE,CACjF,CAAA,MAASoB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,iCAAiCA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,OAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,EACrH,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,IAAA,CACL,qBACA,kIAAA,CACA,CACE,KAAA,CAAOG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,uBAAuB,EAClD,GAAA,CAAKA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,qBAAqB,CAAA,CAC9C,MAAA,CAAQA,IAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,QAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,yCAAyC,EAC5F,OAAA,CAASA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,EAAE,QAAA,CAAS,eAAe,CAAA,CACnE,SAAA,CAAWA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,GAAW,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,eAAe,CAAA,CACrE,QAAA,CAAUA,GAAAA,CAAE,QAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,wBAAwB,CAAA,CAC7E,QAASA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,SAAS,eAAe,CAAA,CACnE,IAAA,CAAMA,GAAAA,CAAE,MAAMA,GAAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,UAAS,CAAE,QAAA,CAAS,yBAAyB,CAAA,CACvE,MAAA,CAAQA,GAAAA,CAAE,MAAA,EAAO,CAAE,UAAS,CAAE,QAAA,CAAS,mBAAmB,CAC5D,EACA,MAAO,CAAE,KAAA,CAAA2C,CAAAA,CAAO,IAAAwB,CAAAA,CAAK,MAAA,CAAAL,CAAAA,CAAQ,OAAA,CAAAM,CAAAA,CAAS,SAAA,CAAAC,CAAAA,CAAW,QAAA,CAAAC,EAAU,OAAA,CAAA3D,CAAAA,CAAS,MAAA,CAAAiC,CAAO,CAAA,GAAM,CAC/E,GAAI,CACF,IAAMlJ,CAAAA,CAAU+I,CAAAA,CAAe,SAAA,CAAW,CACxC,KAAA,CAAAE,CAAAA,CAAO,GAAA,CAAAwB,CAAAA,CAAK,OAAAL,CAAAA,CAAQ,OAAA,CAAAM,CAAAA,CAAS,SAAA,CAAAC,EAAW,QAAA,CAAAC,CAAAA,CAAU,OAAA,CAAA3D,CACpD,CAAC,CAAA,CAEKtD,CAAAA,CAAO,CAAA,EADQuF,CAAAA,EAAUpH,CAAAA,CAAO,KAAA,CAAM,MAChB,CAAA,CAAA,EAAImH,CAAK,CAAA,GAAA,CAAA,CACrC,OAAA,MAAM7C,CAAAA,CAAO,SAAA,CAAUzC,EAAM3D,CAAO,CAAA,CAE7B,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,oBAAA,EAAuB2D,CAAI,CAAA,CAAA,CAAI,CAAC,CAAE,CAC7E,CAAA,MAASoB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,0BAAA,EAA6BA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CACjH,OAAA,CAAS,IACX,CACF,CACF,CACF,EACF,CCzOO,SAAS8F,EAAAA,CAAqB1E,EAAmBC,CAAAA,CAAwBtE,CAAAA,CAA+B,CAE7GqE,CAAAA,CAAO,KACL,KAAA,CACA,+IAAA,CACA,CACE,KAAA,CAAOG,IAAE,MAAA,EAAO,CAAE,QAAA,CAAS,oCAAoC,CAAA,CAC/D,OAAA,CAASA,GAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,OAAA,CAAQ,KAAK,EAAE,QAAA,CAAS,iDAAiD,CAC1G,CAAA,CACA,MAAO,CAAE,KAAA,CAAA5D,CAAAA,CAAO,OAAA,CAAAzC,CAAQ,CAAA,GAAM,CAC5B,GAAI,CACF,IAAMoI,CAAAA,CAAY,CAAA,EAAGvG,CAAAA,CAAO,WAAW,MAAM,CAAA,CAAA,EAAIsD,CAAAA,EAAO,MAMlD0F,CAAAA,CAAiB;AAAA,EAAA,EALV,IAAI,IAAA,EAAK,CAAE,mBAAmB,OAAA,CAAS,CAClD,OAAQ,CAAA,CAAA,CACR,IAAA,CAAM,UACN,MAAA,CAAQ,SACV,CAAC,CACiC,CAAA,QAAA,EAAMpI,CAAK,CAAA,CAAA,CAG7C,GAAI,CACF,MAAM0D,CAAAA,CAAO,SAASiC,CAAS,CAAA,CAE/B,GAAI,CACF,MAAMjC,EAAO,SAAA,CAAUiC,CAAAA,CAAWyC,EAAgB,CAChD,SAAA,CAAW,SACX,aAAA,CAAe7K,CACjB,CAAC,EACH,CAAA,KAAQ,CAEN,MAAMmG,CAAAA,CAAO,aAAaiC,CAAAA,CAAW;AAAA,GAAA,EAAQpI,CAAO;AAAA,EAAK6K,CAAc;AAAA,CAAI,EAC7E,CACF,CAAA,KAAQ,CAEN,IAAM9K,CAAAA,CAAU,CAAA;AAAA,MAAA,EAAcoF,GAAO;AAAA;AAAA;AAAA;;AAAA,EAAA,EAAgCA,GAAO;;AAAA,GAAA,EAAUnF,CAAO;AAAA,EAAK6K,CAAc;AAAA,CAAA,CAChH,MAAM1E,EAAO,SAAA,CAAUiC,CAAAA,CAAWrI,CAAO,EAC3C,CAEA,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAM,CAAA,sBAAA,EAAyBoF,GAAO,CAAA,GAAA,EAAM1C,CAAK,CAAA,CAAG,CAAC,CACjF,CACF,CAAA,MAASqC,CAAAA,CAAK,CACZ,OAAO,CACL,QAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,wBAAwBA,CAAAA,YAAe,KAAA,CAAQA,EAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC5G,OAAA,CAAS,IACX,CACF,CACF,CACF,EAGAoB,CAAAA,CAAO,IAAA,CACL,WACA,+FAAA,CACA,CACE,KAAMG,GAAAA,CAAE,MAAA,GAAS,QAAA,CAAS,sBAAsB,EAChD,OAAA,CAASA,GAAAA,CAAE,QAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,OAAO,CAAA,CAAE,SAAS,kDAAkD,CAC7G,EACA,MAAO,CAAE,KAAAyE,CAAAA,CAAM,OAAA,CAAA9K,CAAQ,CAAA,GAAM,CAC3B,GAAI,CACF,IAAMoI,CAAAA,CAAY,GAAGvG,CAAAA,CAAO,UAAA,CAAW,MAAM,CAAA,CAAA,EAAIsD,CAAAA,EAAO,CAAA,GAAA,CAAA,CAClD4F,CAAAA,CAAgB;AAAA,MAAA,EAAWD,CAAI,CAAA,CAAA,CAErC,GAAI,CACF,MAAM3E,CAAAA,CAAO,QAAA,CAASiC,CAAS,CAAA,CAC/B,GAAI,CACF,MAAMjC,CAAAA,CAAO,SAAA,CAAUiC,CAAAA,CAAW2C,CAAAA,CAAe,CAC/C,SAAA,CAAW,QAAA,CACX,aAAA,CAAe/K,CACjB,CAAC,EACH,CAAA,KAAQ,CACN,MAAMmG,CAAAA,CAAO,YAAA,CAAaiC,CAAAA,CAAW;AAAA,GAAA,EAAQpI,CAAO;AAAA,EAAK+K,CAAa;AAAA,CAAI,EAC5E,CACF,CAAA,KAAQ,CACN,IAAMhL,CAAAA,CAAU,CAAA;AAAA,MAAA,EAAcoF,GAAO;AAAA;AAAA;AAAA;;AAAA,EAAA,EAAgCA,GAAO;;AAAA,GAAA,EAAUnF,CAAO;AAAA,EAAK+K,CAAa;AAAA,CAAA,CAC/G,MAAM5E,CAAAA,CAAO,SAAA,CAAUiC,CAAAA,CAAWrI,CAAO,EAC3C,CAEA,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,0BAAA,EAA6B+K,CAAI,CAAA,CAAG,CAAC,CACvE,CACF,CAAA,MAAShG,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,oBAAA,EAAuBA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC3G,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,IAAA,CACL,SAAA,CACA,mIAAA,CACA,EAAC,CACD,SAAY,CACV,GAAI,CAEF,IAAI8E,EAAe,EAAA,CACnB,GAAI,CACF,IAAM5C,CAAAA,CAAY,CAAA,EAAGvG,CAAAA,CAAO,UAAA,CAAW,MAAM,CAAA,CAAA,EAAIsD,CAAAA,EAAO,CAAA,GAAA,CAAA,CACxD6F,CAAAA,CAAe,MAAM7E,CAAAA,CAAO,QAAA,CAASiC,CAAS,EAChD,CAAA,KAAQ,CAER,CAIA,IAAMxF,CAAAA,CAAAA,CADc,MAAMuD,CAAAA,CAAO,SAAA,EAAU,EACf,MAAA,CAAOtD,CAAAA,EAAKA,EAAE,SAAA,GAAc,IAAI,CAAA,CActDoI,CAAAA,CAZU,CACd,sDAAA,CACA,uDAAA,CACA,+CAAA,CACA,0CAAA,CACA,+CAAA,CACA,gCAAA,CACA,gCAAA,CACA,6CACF,CAAA,CAGyB,IAAA,CAAK,IAAM,IAAA,CAAK,MAAA,EAAO,CAAI,EAAG,CAAA,CAAE,KAAA,CAAM,CAAA,CAAG,CAAC,CAAA,CAE/DC,CAAAA,CAAW,CAAA,yBAAA,EAA4B/F,CAAAA,EAAO,CAAA;;AAAA,CAAA,CAClD,OAAA+F,CAAAA,EAAYD,CAAAA,CAAS,GAAA,CAAI,CAACE,CAAAA,CAAG3J,CAAAA,GAAM,CAAA,EAAGA,CAAAA,CAAI,CAAC,CAAA,EAAA,EAAK2J,CAAC,CAAA,CAAE,EAAE,IAAA,CAAK;AAAA,CAAI,CAAA,CAE1DH,IACFE,CAAAA,EAAY;;AAAA;;AAAA;AAAA,EAAyCF,EAAa,KAAA,CAAM,CAAA,CAAG,GAAG,CAAC,IAGjFE,CAAAA,EAAY;;AAAA;;AAAA,aAAA,EAA2BtI,CAAAA,CAAQ,MAAM,CAAA,aAAA,CAAA,CACrDsI,CAAAA,EAAY,mEAAA,CAEL,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAMA,CAAS,CAAC,CAAE,CACvD,CAAA,MAASpG,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,kBAAA,EAAqBA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CACzG,OAAA,CAAS,IACX,CACF,CACF,CACF,EACF,CC9IO,SAASsG,EAAAA,CAAmBlF,CAAAA,CAAmBC,CAAAA,CAAwBC,CAAAA,CAAgC,CAE5GF,CAAAA,CAAO,IAAA,CACL,aAAA,CACA,8JAAA,CACA,CACE,KAAMG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,wDAAwD,CAAA,CAClF,OAAA,CAASA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,+BAA+B,CAAA,CAC5D,QAAA,CAAUA,GAAAA,CAAE,IAAA,CAAK,CAAC,UAAA,CAAY,SAAA,CAAW,UAAA,CAAY,MAAA,CAAQ,QAAA,CAAU,SAAA,CAAW,MAAA,CAAQ,SAAA,CAAW,eAAA,CAAiB,SAAS,CAAC,CAAA,CAAE,QAAA,EAAS,CAAE,QAAA,CAAS,0BAA0B,CAAA,CAChL,SAAA,CAAWA,GAAAA,CAAE,MAAA,CAAOA,GAAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,QAAA,EAAS,CAAE,QAAA,CAAS,uCAAuC,CAAA,CAC3F,SAAA,CAAWA,GAAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,KAAK,CAAA,CAAE,QAAA,CAAS,6CAA6C,CACzG,CAAA,CACA,MAAO,CAAE,IAAA,CAAA3C,CAAAA,CAAM,OAAA,CAAA3D,EAAS,QAAA,CAAA4I,CAAAA,CAAU,SAAA,CAAAC,CAAAA,CAAW,SAAA,CAAAyC,CAAU,CAAA,GAAM,CAC3D,GAAI,CAEF,GAAI,CAACA,CAAAA,CACH,GAAI,CACF,OAAA,MAAMlF,CAAAA,CAAO,QAAA,CAASzC,CAAI,CAAA,CACnB,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,wBAAA,EAA2BA,CAAI,CAAA,oCAAA,CAAuC,CAAC,CACzG,CACF,CAAA,KAAQ,CAER,CAGF,IAAI4H,CAAAA,CAAevL,CAAAA,CACnB,OAAI4I,CAAAA,GACF2C,CAAAA,CAAexC,CAAAA,CAAeH,CAAAA,CAAU,CAAE,GAAGC,CAAAA,CAAW,OAAA,CAAA7I,CAAQ,CAAC,CAAA,CAAA,CAGnE,MAAMoG,CAAAA,CAAO,SAAA,CAAUzC,CAAAA,CAAM4H,CAAY,CAAA,CAElC,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,oBAAoB5H,CAAI,CAAA,CAAA,CAAI,CAAC,CAAE,CAC1E,CAAA,MAASoB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,uBAAA,EAA0BA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC9G,OAAA,CAAS,IACX,CACF,CACF,CACF,EAGAoB,CAAAA,CAAO,IAAA,CACL,gBAAA,CACA,6EAAA,CACA,CACE,IAAA,CAAMG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,+BAA+B,CAAA,CACzD,OAAA,CAASA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,mBAAmB,CAClD,CAAA,CACA,MAAO,CAAE,IAAA,CAAA3C,CAAAA,CAAM,OAAA,CAAA3D,CAAQ,CAAA,GAAM,CAC3B,GAAI,CACF,OAAA,MAAMoG,CAAAA,CAAO,aAAazC,CAAAA,CAAM;AAAA,EAAK3D,CAAO;AAAA,CAAI,CAAA,CACzC,CAAE,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,qBAAA,EAAwB2D,CAAI,CAAA,CAAA,CAAI,CAAC,CAAE,CAC9E,CAAA,MAASoB,CAAAA,CAAK,CACZ,OAAO,CACL,QAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,0BAAA,EAA6BA,aAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,EAAG,CAAC,CAAA,CACjH,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,IAAA,CACL,gBAAA,CACA,+HAAA,CACA,CACE,IAAA,CAAMG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,kBAAkB,CAAA,CAC5C,OAAA,CAASA,IAAE,MAAA,EAAO,CAAE,QAAA,CAAS,wCAAwC,CAAA,CACrE,OAAA,CAASA,IAAE,MAAA,EAAO,CAAE,QAAA,CAAS,6BAA6B,CAC5D,CAAA,CACA,MAAO,CAAE,IAAA,CAAA3C,CAAAA,CAAM,OAAA,CAAA1D,CAAAA,CAAS,OAAA,CAAAD,CAAQ,CAAA,GAAM,CACpC,GAAI,CACF,IAAMqJ,CAAAA,CAAc,MAAMjD,EAAO,QAAA,CAASzC,CAAI,CAAA,CACxCK,CAAAA,CAAUtD,CAAAA,CAAe2I,CAAAA,CAAapJ,EAASD,CAAO,CAAA,CAC5D,OAAA,MAAMoG,CAAAA,CAAO,SAAA,CAAUzC,CAAAA,CAAMK,CAAO,CAAA,CAE7B,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,SAAA,EAAY/D,CAAO,CAAA,cAAA,EAAiB0D,CAAI,CAAA,CAAA,CAAI,CAAC,CAAE,CAC1F,CAAA,MAASoB,CAAAA,CAAK,CACZ,OAAO,CACL,QAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,0BAAA,EAA6BA,aAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CACjH,OAAA,CAAS,IACX,CACF,CACF,CACF,EACF,CCzFO,SAASyG,GAAqBrF,CAAAA,CAAmBC,CAAAA,CAAwBC,CAAAA,CAAgC,CAE9GF,CAAAA,CAAO,IAAA,CACL,WACA,iJAAA,CACA,CACE,IAAA,CAAMG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,qCAAqC,CAAA,CAC/D,MAAA,CAAQA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,qDAAqD,CAAA,CACjF,OAAA,CAASA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,GAAW,QAAA,CAAS,kDAAkD,CAC5F,CAAA,CACA,MAAO,CAAE,KAAA3C,CAAAA,CAAM,MAAA,CAAA8H,CAAAA,CAAQ,OAAA,CAAAjI,CAAQ,CAAA,GAAM,CACnC,GAAI,CACF,IAAMxD,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASzC,CAAI,CAAA,CAG1C,GAFsBxC,CAAAA,CAAiBnB,CAAO,CAAA,CAE5B,QAAA,CAASyL,CAAM,CAAA,CAC/B,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,CAAA,EAAI9H,CAAI,CAAA,qBAAA,EAAwB8H,CAAM,CAAA,EAAA,CAAK,CAAC,CAC9E,CAAA,CAGF,IAAMC,CAAAA,CAAWlI,CAAAA,CACb;AAAA,IAAA,EAASiI,CAAM,CAAA,UAAA,EAAQjI,CAAO,CAAA,CAAA,CAC9B;AAAA,IAAA,EAASiI,CAAM,KAGnB,GAAI,CACF,MAAMrF,CAAAA,CAAO,SAAA,CAAUzC,EAAM+H,CAAAA,CAAU,CACrC,UAAW,QAAA,CACX,aAAA,CAAe,SACjB,CAAC,EACH,MAAQ,CAEN,MAAMtF,CAAAA,CAAO,YAAA,CAAazC,CAAAA,CAAM;AAAA;AAAA,EAAiB+H,CAAQ;AAAA,CAAI,EAC/D,CAEA,OAAO,CACL,QAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,KAAM,CAAA,gBAAA,EAAmBD,CAAM,CAAA,OAAA,EAAU9H,CAAI,GAAI,CAAC,CAC9E,CACF,CAAA,MAASoB,CAAAA,CAAK,CACZ,OAAO,CACL,QAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,KAAM,CAAA,oBAAA,EAAuBA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,QAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC3G,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,KACL,qBAAA,CACA,4IAAA,CACA,CACE,IAAA,CAAMG,IAAE,MAAA,EAAO,CAAE,QAAA,CAAS,6BAA6B,EACvD,KAAA,CAAOA,GAAAA,CAAE,MAAA,EAAO,CAAE,UAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,SAAS,+BAA+B,CACnF,CAAA,CACA,MAAO,CAAE,IAAA,CAAA3C,CAAAA,CAAM,KAAA,CAAA8D,CAAM,CAAA,GAAM,CACzB,GAAI,CACF,IAAMzH,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASzC,CAAI,CAAA,CACpCgI,CAAAA,CAAgBxK,CAAAA,CAAiBnB,CAAO,EACxC4G,CAAAA,CAAOvF,CAAAA,CAAYrB,CAAO,CAAA,CAE1B4L,CAAAA,CAAc,IAAI,GAAA,CAGxB,IAAA,IAAWxE,KAAOR,CAAAA,CAAK,KAAA,CAAM,CAAA,CAAG,CAAC,EAC/B,GAAI,CACF,IAAMrE,CAAAA,CAAU,MAAM6D,CAAAA,CAAO,MAAA,CAAO,CAAA,KAAA,EAAQgB,CAAG,CAAA,CAAE,CAAA,CACjD,IAAA,IAAWD,CAAAA,IAAK5E,EACd,GAAI4E,CAAAA,CAAE,QAAA,GAAaxD,CAAAA,EAAQ,CAACgI,CAAAA,CAAc,QAAA,CAASxE,CAAAA,CAAE,QAAA,CAAS,QAAQ,OAAA,CAAS,EAAE,CAAC,CAAA,CAAG,CACnF,IAAM0E,CAAAA,CAAUD,CAAAA,CAAY,GAAA,CAAIzE,EAAE,QAAQ,CAAA,EAAK,EAAC,CAChD0E,EAAQ,IAAA,CAAK,CAAA,aAAA,EAAgBzE,CAAG,CAAA,CAAE,EAClCwE,CAAAA,CAAY,GAAA,CAAIzE,CAAAA,CAAE,QAAA,CAAU0E,CAAO,EACrC,CAEJ,CAAA,KAAQ,CAER,CAIF,IAAM5D,CAAAA,CAAQjI,CAAAA,CAAQ,MAAM,KAAK,CAAA,CAAE,MAAA,CAAO4B,CAAAA,EAAKA,EAAE,MAAA,CAAS,CAAC,CAAA,CAAE,KAAA,CAAM,CAAA,CAAG,EAAE,CAAA,CACxE,IAAA,IAAWkK,KAAQ7D,CAAAA,CAAM,KAAA,CAAM,CAAA,CAAG,CAAC,EACjC,GAAI,CACF,IAAM1F,CAAAA,CAAU,MAAM6D,CAAAA,CAAO,MAAA,CAAO0F,CAAI,CAAA,CACxC,IAAA,IAAW3E,CAAAA,IAAK5E,CAAAA,CAAQ,KAAA,CAAM,EAAG,CAAC,CAAA,CAChC,GAAI4E,CAAAA,CAAE,WAAaxD,CAAAA,EAAQ,CAACgI,CAAAA,CAAc,QAAA,CAASxE,EAAE,QAAA,CAAS,OAAA,CAAQ,OAAA,CAAS,EAAE,CAAC,CAAA,CAAG,CACnF,IAAM0E,CAAAA,CAAUD,EAAY,GAAA,CAAIzE,CAAAA,CAAE,QAAQ,CAAA,EAAK,EAAC,CAC3C0E,CAAAA,CAAQ,IAAA,CAAK1E,CAAAA,EAAKA,EAAE,UAAA,CAAW,WAAW,CAAC,CAAA,GAC9C0E,CAAAA,CAAQ,IAAA,CAAK,CAAA,WAAA,EAAcC,CAAI,GAAG,CAAA,CAClCF,CAAAA,CAAY,GAAA,CAAIzE,CAAAA,CAAE,SAAU0E,CAAO,CAAA,EAEvC,CAEJ,CAAA,KAAQ,CAER,CAGF,IAAMtE,CAAAA,CAAS,CAAC,GAAGqE,CAAAA,CAAY,OAAA,EAAS,EACrC,IAAA,CAAK,CAACnI,CAAAA,CAAGC,CAAAA,GAAMA,EAAE,CAAC,CAAA,CAAE,MAAA,CAASD,CAAAA,CAAE,CAAC,CAAA,CAAE,MAAM,CAAA,CACxC,KAAA,CAAM,CAAA,CAAGgE,CAAK,CAAA,CAEjB,GAAIF,EAAO,MAAA,GAAW,CAAA,CACpB,OAAO,CACL,QAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,KAAM,CAAA,qCAAA,EAAwC5D,CAAI,CAAA,0CAAA,CAA6C,CAAC,CAC5H,CAAA,CAGF,IAAM4C,CAAAA,CAAYgB,CAAAA,CAAO,IAAI,CAAC,CAACvE,CAAAA,CAAM6I,CAAO,EAAGpK,CAAAA,GAC7C,CAAA,EAAGA,CAAAA,CAAI,CAAC,OAAOuB,CAAI,CAAA;AAAA,GAAA,EAAU6I,EAAQ,IAAA,CAAK,IAAI,CAAC,CAAA,CACjD,EAAE,IAAA,CAAK;;AAAA,CAAM,CAAA,CAEb,OAAO,CACL,OAAA,CAAS,CAAC,CACR,IAAA,CAAM,MAAA,CACN,IAAA,CAAM,CAAA,2BAAA,EAA8BlI,CAAI,CAAA;;AAAA,EAAS4C,CAAS;;AAAA,+CAAA,CAC5D,CAAC,CACH,CACF,CAAA,MAASxB,EAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,+BAAA,EAAkCA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,QAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CACtH,QAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,EAAO,IAAA,CACL,WAAA,CACA,0JAAA,CACA,CACE,KAAA,CAAOG,GAAAA,CAAE,QAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,SAAS,wBAAwB,CAC5E,CAAA,CACA,MAAO,CAAE,KAAA,CAAAmB,CAAM,CAAA,GAAM,CACnB,GAAI,CACF,IAAMsE,EAAQ,MAAM3F,CAAAA,CAAO,SAAA,EAAU,CAC/B4F,CAAAA,CAAgB,IAAI,IACxBD,CAAAA,CAAM,MAAA,CAAO,CAAA,EAAK,CAAA,CAAE,SAAA,GAAc,IAAI,EAAE,GAAA,CAAI,CAAA,EAAK,CAAA,CAAE,IAAA,CAAK,WAAA,EAAa,CACvE,CAAA,CAEME,CAAAA,CAAO,IAAI,GAAA,CAGXpJ,CAAAA,CAAUkJ,CAAAA,CAAM,OAAO,CAAA,EAAK,CAAA,CAAE,SAAA,GAAc,IAAI,CAAA,CAChDG,CAAAA,CAAa,KAAK,GAAA,CAAIrJ,CAAAA,CAAQ,MAAA,CAAQ,GAAG,CAAA,CACzCsJ,CAAAA,CAAUtJ,EAAQ,IAAA,CAAK,IAAM,IAAA,CAAK,MAAA,EAAO,CAAI,EAAG,EAAE,KAAA,CAAM,CAAA,CAAGqJ,CAAU,CAAA,CAE3E,IAAA,IAAWlJ,KAAQmJ,CAAAA,CACjB,GAAI,CACF,IAAMnM,CAAAA,CAAU,MAAMoG,EAAO,QAAA,CAASpD,CAAAA,CAAK,IAAI,CAAA,CACzC6D,CAAAA,CAAQ1F,CAAAA,CAAiBnB,CAAO,CAAA,CAEtC,IAAA,IAAWkH,CAAAA,IAAQL,CAAAA,CACjB,GAAI,CAACmF,EAAc,GAAA,CAAI9E,CAAAA,CAAK,aAAa,CAAA,CAAG,CAC1C,IAAMkF,CAAAA,CAAUH,CAAAA,CAAK,GAAA,CAAI/E,CAAI,CAAA,EAAK,EAAC,CACnCkF,CAAAA,CAAQ,IAAA,CAAKpJ,CAAAA,CAAK,IAAI,CAAA,CACtBiJ,EAAK,GAAA,CAAI/E,CAAAA,CAAMkF,CAAO,EACxB,CAEJ,CAAA,KAAQ,CAER,CAGF,IAAM7E,EAAS,CAAC,GAAG0E,EAAK,OAAA,EAAS,CAAA,CAC9B,IAAA,CAAK,CAACxI,CAAAA,CAAGC,IAAMA,CAAAA,CAAE,CAAC,CAAA,CAAE,MAAA,CAASD,CAAAA,CAAE,CAAC,EAAE,MAAM,CAAA,CACxC,KAAA,CAAM,CAAA,CAAGgE,CAAK,CAAA,CAEjB,OAAIF,CAAAA,CAAO,MAAA,GAAW,CAAA,CACb,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,+BAAA,EAAkC2E,CAAU,CAAA,IAAA,EAAOrJ,EAAQ,MAAM,CAAA,QAAA,CAAW,CAAC,CAC/G,CAAA,CAOK,CACL,QAAS,CAAC,CACR,IAAA,CAAM,MAAA,CACN,IAAA,CAAM,CAAA;;AAAA,EAPQ0E,CAAAA,CAAO,GAAA,CAAI,CAAC,CAACL,EAAMkF,CAAO,CAAA,CAAG3K,CAAAA,GAC7C,CAAA,EAAGA,CAAAA,CAAI,CAAC,CAAA,MAAA,EAASyF,CAAI,6BAAwBkF,CAAAA,CAAQ,MAAM,CAAA,UAAA,EAAaA,CAAAA,CAAQ,KAAA,CAAM,CAAA,CAAG,CAAC,CAAA,CAAE,KAAK,IAAI,CAAC,CAAA,EAAGA,CAAAA,CAAQ,OAAS,CAAA,CAAI,KAAA,CAAQ,EAAE,CAAA,CAC1I,EAAE,IAAA,CAAK;AAAA,CAAI,CAK4D;;AAAA,6FAAA,CACrE,CAAC,CACH,CACF,OAASrH,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAM,CAAA,qBAAA,EAAwBA,aAAe,KAAA,CAAQA,CAAAA,CAAI,QAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,EAC5G,OAAA,CAAS,IACX,CACF,CACF,CACF,EAGAoB,CAAAA,CAAO,IAAA,CACL,eACA,+IAAA,CACA,CACE,MAAOG,GAAAA,CAAE,MAAA,GAAS,QAAA,EAAS,CAAE,QAAQ,EAAE,CAAA,CAAE,SAAS,2BAA2B,CAC/E,EACA,MAAO,CAAE,MAAAmB,CAAM,CAAA,GAAM,CACnB,GAAI,CAEF,IAAM5E,CAAAA,CAAAA,CADQ,MAAMuD,EAAO,SAAA,EAAU,EACf,OAAOtD,CAAAA,EAAKA,CAAAA,CAAE,YAAc,IAAI,CAAA,CAGhDuJ,EAAS,IAAI,GAAA,CACbH,EAAa,IAAA,CAAK,GAAA,CAAIrJ,EAAQ,MAAA,CAAQ,GAAG,EACzCsJ,CAAAA,CAAUtJ,CAAAA,CAAQ,KAAK,IAAM,IAAA,CAAK,QAAO,CAAI,EAAG,EAAE,KAAA,CAAM,CAAA,CAAGqJ,CAAU,CAAA,CAE3E,IAAA,IAAWlJ,CAAAA,IAAQmJ,CAAAA,CACjB,GAAI,CACF,IAAMnM,EAAU,MAAMoG,CAAAA,CAAO,SAASpD,CAAAA,CAAK,IAAI,EACzCgE,CAAAA,CAAW7F,CAAAA,CAAiBnB,CAAO,CAAA,CAEzC,GAAIgH,EAAS,MAAA,CAAS,CAAA,CAAG,CACvBqF,CAAAA,CAAO,GAAA,CAAIrJ,EAAK,IAAI,CAAA,CACpB,QAAWkE,CAAAA,IAAQF,CAAAA,CAAU,CAE3B,IAAMyE,CAAAA,CAAS5I,EAAQ,IAAA,CAAKC,CAAAA,EAAKA,EAAE,IAAA,CAAK,WAAA,KAAkBoE,CAAAA,CAAK,WAAA,EAAa,CAAA,CACxEuE,CAAAA,EAAQY,EAAO,GAAA,CAAIZ,CAAAA,CAAO,IAAI,EACpC,CACF,CACF,CAAA,KAAQ,CAER,CAGF,IAAMa,CAAAA,CAAUH,EACb,MAAA,CAAOrJ,CAAAA,EAAK,CAACuJ,CAAAA,CAAO,GAAA,CAAIvJ,EAAE,IAAI,CAAC,EAC/B,KAAA,CAAM,CAAA,CAAG2E,CAAK,CAAA,CAEjB,OAAI6E,EAAQ,MAAA,GAAW,CAAA,CACd,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,KAAM,CAAA,+BAAA,EAAkCJ,CAAU,wCAAyC,CAAC,CACxH,EAOK,CACL,OAAA,CAAS,CAAC,CACR,IAAA,CAAM,OACN,IAAA,CAAM,CAAA;;AAAA,EAPQI,CAAAA,CAAQ,GAAA,CAAI,CAACxJ,CAAAA,CAAGrB,CAAAA,GAChC,CAAA,EAAGA,CAAAA,CAAI,CAAC,CAAA,EAAA,EAAKqB,CAAAA,CAAE,IAAI,CAAA,CACrB,EAAE,IAAA,CAAK;AAAA,CAAI,CAKiD;;AAAA,sFAAA,CAC1D,CAAC,CACH,CACF,CAAA,MAASiC,EAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,2BAA2BA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC/G,OAAA,CAAS,IACX,CACF,CACF,CACF,EACF,CClQO,SAASwH,EAAAA,CAAsBpG,CAAAA,CAAmBC,CAAAA,CAAwBC,CAAAA,CAAgC,CAE/GF,EAAO,IAAA,CACL,SAAA,CACA,6HAAA,CACA,CACE,KAAMG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,kBAAkB,CAAA,CAC5C,IAAA,CAAMA,GAAAA,CAAE,KAAA,CAAMA,GAAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,SAAS,gCAAgC,CACrE,CAAA,CACA,MAAO,CAAE,IAAA,CAAA3C,CAAAA,CAAM,IAAA,CAAAiD,CAAK,IAAM,CACxB,GAAI,CACF,IAAM5G,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASzC,CAAI,CAAA,CACpC,CAAE,WAAA,CAAA5C,CAAAA,CAAa,KAAAY,CAAK,CAAA,CAAId,CAAAA,CAAiBb,CAAO,EAGhDwM,CAAAA,CAAyB,EAAC,CAChC,GAAIzL,CAAAA,CAAY,IAAA,CAAM,CAEpB,IAAM0L,EAAS1L,CAAAA,CAAY,IAAA,CACvB0L,CAAAA,CAAO,UAAA,CAAW,GAAG,CAAA,CACvBD,CAAAA,CAAa,IAAA,CAAK,GAAGC,EAAO,KAAA,CAAM,CAAA,CAAG,CAAA,CAAE,CAAA,CAAE,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,CAAI1F,GAAKA,CAAAA,CAAE,IAAA,EAAM,CAAC,EAEtEyF,CAAAA,CAAa,IAAA,CAAKC,CAAM,EAE5B,CAGA,IAAMC,CAAAA,CADU,CAAC,GAAG,IAAI,GAAA,CAAI,CAAC,GAAGF,CAAAA,CAAc,GAAG5F,CAAI,CAAC,CAAC,CAAA,CAC/B,IAAIG,CAAAA,EAAK,CAAA,IAAA,EAAOA,CAAC,CAAA,CAAE,EAAE,IAAA,CAAK;AAAA,CAAI,CAAA,CAGhD4F,CAAAA,CAAY,MAAA,CAAO,OAAA,CAAQ5L,CAAW,CAAA,CACzC,MAAA,CAAO,CAAC,CAACoH,CAAC,CAAA,GAAMA,CAAAA,GAAM,MAAM,EAC5B,GAAA,CAAI,CAAC,CAACA,CAAAA,CAAGC,CAAC,CAAA,GAAM,CAAA,EAAGD,CAAC,CAAA,EAAA,EAAKC,CAAC,CAAA,CAAE,CAAA,CAC5B,IAAA,CAAK;AAAA,CAAI,EAENzH,CAAAA,CAAa,CAAA;AAAA,EAAQgM,CAAS,GAAGA,CAAAA,CAAY;AAAA,CAAA,CAAO,EAAE,CAAA;AAAA,EAAUD,CAAO;AAAA;;AAAA,EAAY/K,CAAI,CAAA,CAAA,CAC7F,OAAA,MAAMyE,CAAAA,CAAO,SAAA,CAAUzC,CAAAA,CAAMhD,CAAU,CAAA,CAEhC,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAM,CAAA,WAAA,EAAciG,CAAAA,CAAK,GAAA,CAAIG,CAAAA,EAAK,CAAA,CAAA,EAAIA,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,KAAA,EAAQpD,CAAI,GAAI,CAAC,CAClG,CACF,CAAA,MAASoB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,uBAAuBA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC3G,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,IAAA,CACL,mBAAA,CACA,+FAAA,CACA,CACE,IAAA,CAAMG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,kBAAkB,CAAA,CAC5C,UAAA,CAAYA,IAAE,MAAA,CAAOA,GAAAA,CAAE,MAAA,EAAQ,CAAA,CAAE,QAAA,CAAS,qFAAqF,CACjI,CAAA,CACA,MAAO,CAAE,IAAA,CAAA3C,CAAAA,CAAM,UAAA,CAAAiJ,CAAW,CAAA,GAAM,CAC9B,GAAI,CACF,IAAM5M,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASzC,CAAI,CAAA,CACpC,CAAE,WAAA,CAAA5C,CAAAA,CAAa,KAAAY,CAAK,CAAA,CAAId,CAAAA,CAAiBb,CAAO,CAAA,CAEhD6M,CAAAA,CAAS,CAAE,GAAG9L,CAAAA,CAAa,GAAG6L,CAAW,CAAA,CAKzCjM,CAAAA,CAAa,CAAA;AAAA,EAJJ,OAAO,OAAA,CAAQkM,CAAM,CAAA,CACjC,GAAA,CAAI,CAAC,CAAC1E,CAAAA,CAAGC,CAAC,CAAA,GAAM,GAAGD,CAAC,CAAA,EAAA,EAAKC,CAAC,CAAA,CAAE,EAC5B,IAAA,CAAK;AAAA,CAAI,CAEqB;AAAA;;AAAA,EAAYzG,CAAI,CAAA,CAAA,CACjD,MAAMyE,CAAAA,CAAO,SAAA,CAAUzC,CAAAA,CAAMhD,CAAU,CAAA,CAEvC,IAAMqD,CAAAA,CAAU,MAAA,CAAO,OAAA,CAAQ4I,CAAU,EACtC,GAAA,CAAI,CAAC,CAACzE,CAAAA,CAAGC,CAAC,CAAA,GAAM,CAAA,EAAGD,CAAC,CAAA,EAAA,EAAKC,CAAC,CAAA,CAAE,CAAA,CAC5B,IAAA,CAAK,IAAI,EAEZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,uBAAA,EAA0BzE,CAAI,CAAA,GAAA,EAAMK,CAAO,CAAA,CAAG,CAAC,CACjF,CACF,CAAA,MAASe,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,6BAAA,EAAgCA,CAAAA,YAAe,KAAA,CAAQA,EAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CACpH,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,IAAA,CACL,aAAA,CACA,yIAAA,CACA,CACE,QAAA,CAAUG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,0BAA0B,CAAA,CACxD,QAAA,CAAUA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,uBAAuB,CACvD,CAAA,CACA,MAAO,CAAE,QAAA,CAAAwG,CAAAA,CAAU,QAAA,CAAAC,CAAS,CAAA,GAAM,CAChC,GAAI,CACF,IAAM/M,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAAS0G,CAAQ,CAAA,CAG9C,GAAI,CACF,OAAA,MAAM1G,CAAAA,CAAO,QAAA,CAAS2G,CAAQ,CAAA,CACvB,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,0BAAA,EAA6BA,CAAQ,CAAA,2BAAA,CAA8B,CAAC,CACtG,CACF,CAAA,KAAQ,CAER,CAEA,OAAA,MAAM3G,CAAAA,CAAO,SAAA,CAAU2G,CAAAA,CAAU/M,CAAO,CAAA,CACxC,MAAMoG,CAAAA,CAAO,UAAA,CAAW0G,CAAQ,CAAA,CAEzB,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,SAAA,EAAYA,CAAQ,CAAA,MAAA,EAASC,CAAQ,CAAA,CAAA,CAAI,CAAC,CAC5E,CACF,CAAA,MAAShI,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,uBAAA,EAA0BA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC9G,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,IAAA,CACL,WAAA,CACA,yEAAA,CACA,CACE,IAAA,CAAMG,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,0BAA0B,CAAA,CACpD,WAAA,CAAaA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,kDAAkD,CACrF,CAAA,CACA,MAAO,CAAE,IAAA,CAAA3C,CAAAA,CAAM,WAAA,CAAAqJ,CAAY,CAAA,GAAM,CAC/B,GAAI,CACF,IAAMhN,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASzC,CAAI,CAAA,CACpCsJ,CAAAA,CAAWtJ,CAAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,GAAA,EAAI,EAAKA,CAAAA,CACpCuJ,CAAAA,CAAU,CAAA,EAAGF,CAAW,CAAA,CAAA,EAAIC,CAAQ,CAAA,CAAA,CAG1C,GAAI,CACF,OAAA,MAAM7G,CAAAA,CAAO,QAAA,CAAS8G,CAAO,CAAA,CACtB,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,0BAAA,EAA6BA,CAAO,CAAA,yBAAA,CAA4B,CAAC,CACnG,CACF,CAAA,KAAQ,CAER,CAEA,OAAA,MAAM9G,CAAAA,CAAO,SAAA,CAAU8G,CAAAA,CAASlN,CAAO,CAAA,CACvC,MAAMoG,CAAAA,CAAO,UAAA,CAAWzC,CAAI,CAAA,CAErB,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,OAAA,EAAUA,CAAI,CAAA,MAAA,EAASuJ,CAAO,CAAA,CAAA,CAAI,CAAC,CACrE,CACF,CAAA,MAASnI,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,qBAAA,EAAwBA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC5G,OAAA,CAAS,IACX,CACF,CACF,CACF,EACF,CClKO,SAASoI,EAAAA,CAAwBhH,CAAAA,CAAmBC,CAAAA,CAAwBC,CAAAA,CAAgC,CAEjHF,CAAAA,CAAO,IAAA,CACL,gBAAA,CACA,kHAAA,CACA,EAAC,CACD,SAAY,CACV,GAAI,CACF,IAAM4F,CAAAA,CAAQ,MAAM3F,CAAAA,CAAO,SAAA,EAAU,CAC/BvD,CAAAA,CAAUkJ,CAAAA,CAAM,MAAA,CAAOjJ,CAAAA,EAAKA,CAAAA,CAAE,SAAA,GAAc,IAAI,CAAA,CAChDsK,CAAAA,CAAarB,CAAAA,CAAM,MAAA,CAAOjJ,CAAAA,EAAKA,CAAAA,CAAE,SAAA,GAAc,IAAI,CAAA,CAGnDuK,CAAAA,CAAe,IAAI,GAAA,CACzB,IAAA,IAAWrK,CAAAA,IAAQH,CAAAA,CAAS,CAC1B,IAAMyK,CAAAA,CAAQtK,CAAAA,CAAK,IAAA,CAAK,MAAM,GAAG,CAAA,CAC3BkG,CAAAA,CAASoE,CAAAA,CAAM,MAAA,CAAS,CAAA,CAAIA,CAAAA,CAAM,KAAA,CAAM,CAAA,CAAG,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,CAAI,QAAA,CACjED,CAAAA,CAAa,GAAA,CAAInE,CAAAA,CAAAA,CAASmE,CAAAA,CAAa,GAAA,CAAInE,CAAM,CAAA,EAAK,CAAA,EAAK,CAAC,EAC9D,CAEA,IAAMqE,CAAAA,CAAa,CAAC,GAAGF,EAAa,OAAA,EAAS,CAAA,CAC1C,IAAA,CAAK,CAAC5J,CAAAA,CAAGC,CAAAA,GAAMA,CAAAA,CAAE,CAAC,CAAA,CAAID,CAAAA,CAAE,CAAC,CAAC,CAAA,CAC1B,KAAA,CAAM,CAAA,CAAG,EAAE,CAAA,CAGR+J,CAAAA,CAAY,IAAI,GAAA,CAChBtB,CAAAA,CAAa,IAAA,CAAK,GAAA,CAAIrJ,CAAAA,CAAQ,MAAA,CAAQ,EAAE,CAAA,CACxCsJ,CAAAA,CAAUtJ,CAAAA,CAAQ,MAAM,CAAA,CAAGqJ,CAAU,CAAA,CAE3C,IAAA,IAAWlJ,CAAAA,IAAQmJ,CAAAA,CACjB,GAAI,CACF,IAAMnM,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASpD,CAAAA,CAAK,IAAI,CAAA,CACzC4D,CAAAA,CAAOvF,CAAAA,CAAYrB,CAAO,CAAA,CAChC,IAAA,IAAWoH,CAAAA,IAAOR,CAAAA,CAChB4G,CAAAA,CAAU,GAAA,CAAIpG,CAAAA,CAAAA,CAAMoG,CAAAA,CAAU,GAAA,CAAIpG,CAAG,CAAA,EAAK,GAAK,CAAC,EAEpD,CAAA,KAAQ,CAER,CAGF,IAAMqG,CAAAA,CAAU,CAAC,GAAGD,CAAAA,CAAU,OAAA,EAAS,CAAA,CACpC,IAAA,CAAK,CAAC/J,CAAAA,CAAGC,CAAAA,GAAMA,CAAAA,CAAE,CAAC,CAAA,CAAID,CAAAA,CAAE,CAAC,CAAC,CAAA,CAC1B,KAAA,CAAM,CAAA,CAAG,EAAE,CAAA,CAEV0H,CAAAA,CAAW,CAAA;;AAAA,CAAA,CACf,OAAAA,CAAAA,EAAY,CAAA,mBAAA,EAAsBtI,CAAAA,CAAQ,MAAM;AAAA,CAAA,CAChDsI,CAAAA,EAAY,CAAA,mBAAA,EAAsBiC,CAAAA,CAAW,MAAM,CAAA;AAAA,CAAA,CACnDjC,CAAAA,EAAY,CAAA,eAAA,EAAkBkC,CAAAA,CAAa,IAAI;;AAAA,CAAA,CAE/ClC,CAAAA,EAAY,CAAA;AAAA,CAAA,CACZA,CAAAA,EAAYoC,CAAAA,CAAW,GAAA,CAAI,CAAC,CAACrE,CAAAA,CAAQ9F,CAAK,CAAA,GACxC,CAAA,IAAA,EAAO8F,CAAM,CAAA,EAAA,EAAK9F,CAAK,CAAA,MAAA,CACzB,EAAE,IAAA,CAAK;AAAA,CAAI,CAAA,CAEPqK,CAAAA,CAAQ,MAAA,CAAS,CAAA,GACnBtC,CAAAA,EAAY;;AAAA,2BAAA,EAAkCe,CAAU,CAAA;AAAA,CAAA,CACxDf,CAAAA,EAAYsC,CAAAA,CAAQ,GAAA,CAAI,CAAC,CAACrG,CAAAA,CAAKhE,CAAK,CAAA,GAClC,CAAA,KAAA,EAAQgE,CAAG,CAAA,EAAA,EAAKhE,CAAK,CAAA,CACvB,EAAE,IAAA,CAAK;AAAA,CAAI,GAGN,CAAE,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAM+H,CAAS,CAAC,CAAE,CACvD,OAASpG,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,iCAAiCA,CAAAA,YAAe,KAAA,CAAQA,EAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CACrH,OAAA,CAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,CAAAA,CAAO,KACL,WAAA,CACA,oGAAA,CACA,CACE,KAAA,CAAOG,IAAE,MAAA,EAAO,CAAE,UAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,wBAAwB,CAC5E,CAAA,CACA,MAAO,CAAE,KAAA,CAAAmB,CAAM,CAAA,GAAM,CACnB,GAAI,CAEF,IAAM5E,CAAAA,CAAAA,CADQ,MAAMuD,EAAO,SAAA,EAAU,EACf,OAAOtD,CAAAA,EAAKA,CAAAA,CAAE,YAAc,IAAI,CAAA,CAEhD0K,EAAY,IAAI,GAAA,CAChBtB,EAAa,IAAA,CAAK,GAAA,CAAIrJ,EAAQ,MAAA,CAAQ,GAAG,EACzCsJ,CAAAA,CAAUtJ,CAAAA,CAAQ,KAAA,CAAM,CAAA,CAAGqJ,CAAU,CAAA,CAE3C,IAAA,IAAWlJ,KAAQmJ,CAAAA,CACjB,GAAI,CACF,IAAMnM,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASpD,EAAK,IAAI,CAAA,CACzC4D,EAAOvF,CAAAA,CAAYrB,CAAO,EAChC,IAAA,IAAWoH,CAAAA,IAAOR,CAAAA,CAChB4G,CAAAA,CAAU,IAAIpG,CAAAA,CAAAA,CAAMoG,CAAAA,CAAU,IAAIpG,CAAG,CAAA,EAAK,GAAK,CAAC,EAEpD,MAAQ,CAER,CAGF,IAAMG,CAAAA,CAAS,CAAC,GAAGiG,CAAAA,CAAU,OAAA,EAAS,CAAA,CACnC,IAAA,CAAK,CAAC/J,CAAAA,CAAGC,IAAMA,CAAAA,CAAE,CAAC,EAAID,CAAAA,CAAE,CAAC,CAAC,CAAA,CAC1B,KAAA,CAAM,EAAGgE,CAAK,CAAA,CAEjB,GAAIF,CAAAA,CAAO,MAAA,GAAW,EACpB,OAAO,CAAE,QAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,yBAA0B,CAAC,CAAE,EAGxE,IAAMhB,CAAAA,CAAYgB,EAAO,GAAA,CAAI,CAAC,CAACH,CAAAA,CAAKhE,CAAK,IACvC,CAAA,CAAA,EAAIgE,CAAG,KAAKhE,CAAK,CAAA,CAAA,CACnB,EAAE,IAAA,CAAK;AAAA,CAAI,CAAA,CAEX,OAAO,CACL,OAAA,CAAS,CAAC,CACR,IAAA,CAAM,MAAA,CACN,IAAA,CAAM,CAAA,2BAAA,EAA8B8I,CAAU,CAAA,IAAA,EAAOrJ,EAAQ,MAAM,CAAA;;AAAA,EAAe0D,CAAS,CAAA,CAC7F,CAAC,CACH,CACF,CAAA,MAASxB,EAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,KAAM,CAAA,qBAAA,EAAwBA,CAAAA,YAAe,MAAQA,CAAAA,CAAI,OAAA,CAAU,OAAOA,CAAG,CAAC,EAAG,CAAC,CAAA,CAC5G,QAAS,IACX,CACF,CACF,CACF,CAAA,CAGAoB,EAAO,IAAA,CACL,qBAAA,CACA,4HACA,EAAC,CACD,SAAY,CACV,GAAI,CAEF,IAAMtD,CAAAA,CAAAA,CADQ,MAAMuD,CAAAA,CAAO,WAAU,EACf,MAAA,CAAOtD,GAAKA,CAAAA,CAAE,SAAA,GAAc,IAAI,CAAA,CAGhD4K,CAAAA,CAAU,IAAI,GAAA,CACpB,IAAA,IAAW1K,KAAQH,CAAAA,CAAS,CAC1B,IAAMyK,CAAAA,CAAQtK,CAAAA,CAAK,KAAK,KAAA,CAAM,GAAG,EACjC,GAAIsK,CAAAA,CAAM,OAAS,CAAA,CAEjB,IAAA,IAAS7L,EAAI,CAAA,CAAGA,CAAAA,CAAI6L,EAAM,MAAA,CAAQ7L,CAAAA,EAAAA,CAAK,CACrC,IAAMyH,CAAAA,CAASoE,EAAM,KAAA,CAAM,CAAA,CAAG7L,CAAC,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,CACrCA,CAAAA,GAAM6L,CAAAA,CAAM,MAAA,CAAS,EAEvBI,CAAAA,CAAQ,GAAA,CAAIxE,GAASwE,CAAAA,CAAQ,GAAA,CAAIxE,CAAM,CAAA,EAAK,CAAA,EAAK,CAAC,CAAA,CACxCwE,CAAAA,CAAQ,IAAIxE,CAAM,CAAA,EAC5BwE,EAAQ,GAAA,CAAIxE,CAAAA,CAAQ,CAAC,EAEzB,CAAA,KAEAwE,EAAQ,GAAA,CAAI,QAAA,CAAA,CAAWA,EAAQ,GAAA,CAAI,QAAQ,GAAK,CAAA,EAAK,CAAC,EAE1D,CAIA,IAAMC,EAFS,CAAC,GAAGD,EAAQ,OAAA,EAAS,EAAE,IAAA,CAAK,CAAC,EAAGhK,CAAAA,GAAM,CAAA,CAAE,CAAC,CAAA,CAAE,aAAA,CAAcA,EAAE,CAAC,CAAC,CAAC,CAAA,CAEzD,GAAA,CAAI,CAAC,CAACwF,CAAAA,CAAQ9F,CAAK,CAAA,GAAM,CAC3C,IAAMwK,CAAAA,CAAQ1E,CAAAA,CAAO,MAAM,GAAG,CAAA,CAAE,OAAS,CAAA,CACnC2E,CAAAA,CAAS,KAAK,MAAA,CAAOD,CAAK,EAC1BlJ,CAAAA,CAAOwE,CAAAA,CAAO,MAAM,GAAG,CAAA,CAAE,KAAI,EAAKA,CAAAA,CACxC,OAAO,CAAA,EAAG2E,CAAM,GAAGnJ,CAAI,CAAA,GAAA,EAAMtB,CAAK,CAAA,OAAA,CACpC,CAAC,EAAE,IAAA,CAAK;AAAA,CAAI,CAAA,CAEZ,OAAO,CACL,OAAA,CAAS,CAAC,CACR,IAAA,CAAM,MAAA,CACN,IAAA,CAAM,CAAA,qBAAA,EAAwBP,CAAAA,CAAQ,MAAM,CAAA;;AAAA,EAAqB8K,CAAI,CAAA,CACvE,CAAC,CACH,CACF,CAAA,MAAS5I,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,+BAAA,EAAkCA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CACtH,OAAA,CAAS,IACX,CACF,CACF,CACF,EACF,CCpLO,SAAS+I,EAAAA,CAAkB3H,CAAAA,CAAmBC,CAAAA,CAAwBC,CAAAA,CAAgC,CAE3GF,CAAAA,CAAO,IAAA,CACL,YAAA,CACA,wIAAA,CACA,CACE,MAAA,CAAQG,GAAAA,CAAE,IAAA,CAAK,CAAC,MAAA,CAAQ,MAAA,CAAQ,KAAK,CAAC,CAAA,CAAE,UAAS,CAAE,OAAA,CAAQ,MAAM,CAAA,CAAE,QAAA,CAAS,uBAAuB,CAAA,CACnG,KAAA,CAAOA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,QAAA,CAAS,+CAA+C,CAAA,CACrF,KAAA,CAAOA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS,CAAE,OAAA,CAAQ,EAAE,CAAA,CAAE,QAAA,CAAS,yBAAyB,CAC7E,CAAA,CACA,MAAO,CAAE,MAAA,CAAAyH,CAAAA,CAAQ,KAAA,CAAAnL,CAAAA,CAAO,KAAA,CAAA6E,CAAM,CAAA,GAAM,CAClC,GAAI,CAGF,IAAM5E,CAAAA,CAAAA,CADQ,MAAMuD,CAAAA,CAAO,SAAA,EAAU,EACf,MAAA,CAAOtD,CAAAA,EAAKA,CAAAA,CAAE,SAAA,GAAc,IAAI,CAAA,CAEhDkL,CAAAA,CAKD,EAAC,CAGA9B,CAAAA,CAAa,IAAA,CAAK,GAAA,CAAIrJ,CAAAA,CAAQ,OAAQ,GAAG,CAAA,CACzCsJ,CAAAA,CAAUtJ,CAAAA,CAAQ,KAAA,CAAM,CAAA,CAAGqJ,CAAU,CAAA,CAE3C,IAAA,IAAWlJ,CAAAA,IAAQmJ,CAAAA,CACjB,GAAI,CACF,IAAMnM,EAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASpD,CAAAA,CAAK,IAAI,CAAA,CACzCxB,CAAAA,CAAQD,CAAAA,CAAavB,CAAO,CAAA,CAElC,IAAA,IAAW+K,CAAAA,IAAQvJ,CAAAA,CACboB,CAAAA,EAAS,CAACmI,CAAAA,CAAK,IAAA,CAAK,WAAA,EAAY,CAAE,QAAA,CAASnI,CAAAA,CAAM,WAAA,EAAa,CAAA,EAC9DmL,CAAAA,GAAW,MAAA,EAAUhD,CAAAA,CAAK,IAAA,EAC1BgD,CAAAA,GAAW,MAAA,EAAU,CAAChD,CAAAA,CAAK,IAAA,EAE/BiD,CAAAA,CAAS,IAAA,CAAK,CACZ,IAAA,CAAMjD,CAAAA,CAAK,IAAA,CACX,IAAA,CAAMA,CAAAA,CAAK,IAAA,CACX,IAAA,CAAM/H,CAAAA,CAAK,IAAA,CACX,KAAM+H,CAAAA,CAAK,IACb,CAAC,EAEL,CAAA,KAAQ,CAER,CAGF,GAAIiD,CAAAA,CAAS,MAAA,GAAW,CAAA,CACtB,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,GAAA,EAAMD,CAAAA,GAAW,KAAA,CAAQ,EAAA,CAAKA,CAAAA,CAAS,GAAG,CAAA,WAAA,EAAcnL,CAAAA,CAAQ,CAAA,WAAA,EAAcA,CAAK,IAAM,EAAE,CAAA,CAAA,CAAI,CAAC,CAClI,CAAA,CAGF,IAAMqL,CAAAA,CAAYD,CAAAA,CAAS,KAAA,CAAM,CAAA,CAAGvG,CAAK,CAAA,CACnClB,CAAAA,CAAY0H,CAAAA,CAAU,GAAA,CAAI,CAAClH,CAAAA,CAAGtF,CAAAA,GAClC,CAAA,EAAGA,CAAAA,CAAI,CAAC,CAAA,GAAA,EAAMsF,CAAAA,CAAE,IAAA,CAAO,GAAA,CAAM,GAAG,CAAA,EAAA,EAAKA,CAAAA,CAAE,IAAI;AAAA,IAAA,EAASA,EAAE,IAAI,CAAA,CAAA,EAAIA,EAAE,IAAI,CAAA,CAAA,CACtE,EAAE,IAAA,CAAK;;AAAA,CAAM,CAAA,CAEb,OAAO,CACL,OAAA,CAAS,CAAC,CACR,IAAA,CAAM,MAAA,CACN,IAAA,CAAM,CAAA,EAAA,EAAKgH,CAAAA,GAAW,MAAQ,KAAA,CAAQA,CAAAA,GAAW,OAAS,MAAA,CAAS,WAAW,aAAaC,CAAAA,CAAS,MAAM,CAAA,gBAAA,EAAmBC,CAAAA,CAAU,MAAM,CAAA;;AAAA,EAAS1H,CAAS,CAAA,CACjK,CAAC,CACH,CACF,CAAA,MAASxB,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,KAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,sBAAA,EAAyBA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAC7G,QAAS,IACX,CACF,CACF,CACF,EAGAoB,CAAAA,CAAO,IAAA,CACL,eAAA,CACA,qFAAA,CACA,CACE,IAAA,CAAMG,GAAAA,CAAE,MAAA,GAAS,QAAA,CAAS,sCAAsC,CAAA,CAChE,IAAA,CAAMA,GAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,CAAS,mCAAmC,CAC/D,CAAA,CACA,MAAO,CAAE,IAAA,CAAA3C,CAAAA,CAAM,IAAA,CAAArD,CAAK,IAAM,CACxB,GAAI,CAEF,IAAMJ,GADU,MAAMkG,CAAAA,CAAO,QAAA,CAASzC,CAAI,GACpB,KAAA,CAAM;AAAA,CAAI,CAAA,CAEhC,GAAIrD,CAAAA,CAAO,CAAA,EAAKA,CAAAA,CAAOJ,CAAAA,CAAM,MAAA,CAC3B,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,OAAQ,IAAA,CAAM,CAAA,KAAA,EAAQI,CAAI,CAAA,2BAAA,EAA8BJ,CAAAA,CAAM,MAAM,CAAA,OAAA,CAAU,CAAC,CAAA,CACjG,OAAA,CAAS,CAAA,CACX,CAAA,CAGF,IAAMgO,CAAAA,CAAahO,EAAMI,CAAAA,CAAO,CAAC,CAAA,CAC3BQ,CAAAA,CAAQoN,CAAAA,CAAW,KAAA,CAAM,2BAA2B,CAAA,CAE1D,OAAKpN,CAAAA,EAOLZ,CAAAA,CAAMI,CAAAA,CAAO,CAAC,CAAA,CAAI,CAAA,EAAGQ,CAAAA,CAAM,CAAC,CAAC,CAAA,GAAA,EAAMA,CAAAA,CAAM,CAAC,CAAC,CAAA,CAAA,CAC3C,MAAMsF,CAAAA,CAAO,SAAA,CAAUzC,CAAAA,CAAMzD,CAAAA,CAAM,IAAA,CAAK;AAAA,CAAI,CAAC,CAAA,CAGtC,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,iBAAA,EAFjBY,CAAAA,CAAM,CAAC,CAAA,CAAE,MAEoC,CAAA,MAAA,EAAS6C,CAAI,CAAA,CAAA,CAAI,CAAC,CAChF,CAAA,EAZS,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,QAAQrD,CAAI,CAAA,uBAAA,EAA0B4N,CAAAA,CAAW,IAAA,EAAM,CAAA,CAAA,CAAI,CAAC,CAAA,CAC5F,OAAA,CAAS,CAAA,CACX,CAUJ,CAAA,MAASnJ,CAAAA,CAAK,CACZ,OAAO,CACL,OAAA,CAAS,CAAC,CAAE,IAAA,CAAM,MAAA,CAAQ,IAAA,CAAM,CAAA,yBAAA,EAA4BA,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CAAG,CAAC,CAAA,CAChH,OAAA,CAAS,IACX,CACF,CACF,CACF,EACF,CCxHO,SAASoJ,EAAAA,CAAkBhI,CAAAA,CAAmBC,CAAAA,CAAwBtE,EAA+B,CAE1GqE,CAAAA,CAAO,QAAA,CACL,OAAA,CACA,eAAA,CACA,CAAE,WAAA,CAAa,uEAAA,CAAyE,QAAA,CAAU,eAAgB,CAAA,CAClH,MAAOiI,CAAAA,EAAQ,CACb,GAAI,CACF,IAAM/F,CAAAA,CAAY,CAAA,EAAGvG,CAAAA,CAAO,UAAA,CAAW,MAAM,CAAA,CAAA,EAAIsD,CAAAA,EAAO,CAAA,GAAA,CAAA,CAClDpF,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASiC,CAAS,CAAA,CAC/C,OAAO,CACL,QAAA,CAAU,CAAC,CAAE,GAAA,CAAK+F,CAAAA,CAAI,IAAA,CAAM,IAAA,CAAM,CAAA,sBAAA,EAAyBhJ,CAAAA,EAAO,CAAA;;AAAA,EAAQpF,CAAO,CAAA,CAAA,CAAI,QAAA,CAAU,eAAgB,CAAC,CAClH,CACF,CAAA,KAAQ,CACN,OAAO,CACL,QAAA,CAAU,CAAC,CAAE,IAAKoO,CAAAA,CAAI,IAAA,CAAM,IAAA,CAAM,CAAA,yBAAA,EAA4BhJ,CAAAA,EAAO,CAAA,EAAA,CAAA,CAAM,QAAA,CAAU,YAAa,CAAC,CACrG,CACF,CACF,CACF,CAAA,CAGAe,CAAAA,CAAO,QAAA,CACL,QAAA,CACA,iBACA,CAAE,WAAA,CAAa,kDAAA,CAAoD,QAAA,CAAU,eAAgB,CAAA,CAC7F,MAAOiI,CAAAA,EAAQ,CACb,GAAI,CAIF,IAAMlO,CAAAA,CAAAA,CAHQ,MAAMkG,CAAAA,CAAO,SAAA,EAAU,EACf,MAAA,CAAOtD,GAAKA,CAAAA,CAAE,SAAA,GAAc,IAAI,CAAA,CAAE,MAAM,CAAA,CAAG,EAAE,CAAA,CAE7C,GAAA,CAAI,CAACA,CAAAA,CAAGrB,CAAAA,GAAM,CAAA,EAAGA,CAAAA,CAAI,CAAC,CAAA,EAAA,EAAKqB,CAAAA,CAAE,IAAI,CAAA,CAAE,EAAE,IAAA,CAAK;AAAA,CAAI,CAAA,CAEpE,OAAO,CACL,QAAA,CAAU,CAAC,CACT,GAAA,CAAKsL,CAAAA,CAAI,IAAA,CACT,IAAA,CAAM,CAAA;;AAAA,EAAqBlO,CAAK,CAAA,CAAA,CAChC,QAAA,CAAU,eACZ,CAAC,CACH,CACF,CAAA,KAAQ,CACN,OAAO,CACL,QAAA,CAAU,CAAC,CAAE,GAAA,CAAKkO,CAAAA,CAAI,IAAA,CAAM,IAAA,CAAM,+BAAA,CAAiC,QAAA,CAAU,YAAa,CAAC,CAC7F,CACF,CACF,CACF,CAAA,CAGAjI,CAAAA,CAAO,QAAA,CACL,OACA,cAAA,CACA,CAAE,WAAA,CAAa,uCAAA,CAAyC,QAAA,CAAU,eAAgB,CAAA,CAClF,MAAOiI,CAAAA,EAAQ,CACb,GAAI,CAEF,IAAMvL,CAAAA,CAAAA,CADQ,MAAMuD,CAAAA,CAAO,WAAU,EACf,MAAA,CAAOtD,CAAAA,EAAKA,CAAAA,CAAE,SAAA,GAAc,IAAI,CAAA,CAEhD0K,CAAAA,CAAY,IAAI,GAAA,CAChBtB,CAAAA,CAAa,IAAA,CAAK,GAAA,CAAIrJ,CAAAA,CAAQ,MAAA,CAAQ,EAAE,CAAA,CAE9C,QAAWG,CAAAA,IAAQH,CAAAA,CAAQ,KAAA,CAAM,CAAA,CAAGqJ,CAAU,CAAA,CAC5C,GAAI,CACF,IAAMlM,CAAAA,CAAU,MAAMoG,CAAAA,CAAO,QAAA,CAASpD,CAAAA,CAAK,IAAI,CAAA,CAC/C,QAAWoE,CAAAA,IAAO/F,CAAAA,CAAYrB,CAAO,CAAA,CACnCwN,CAAAA,CAAU,GAAA,CAAIpG,CAAAA,CAAAA,CAAMoG,CAAAA,CAAU,GAAA,CAAIpG,CAAG,CAAA,EAAK,CAAA,EAAK,CAAC,EAEpD,CAAA,KAAQ,CAER,CAOF,IAAMlH,CAAAA,CAJS,CAAC,GAAGsN,CAAAA,CAAU,OAAA,EAAS,CAAA,CACnC,IAAA,CAAK,CAAC/J,CAAAA,CAAGC,CAAAA,GAAMA,CAAAA,CAAE,CAAC,CAAA,CAAID,CAAAA,CAAE,CAAC,CAAC,CAAA,CAC1B,KAAA,CAAM,CAAA,CAAG,EAAE,CAAA,CAEO,GAAA,CAAI,CAAC,CAAC2D,CAAAA,CAAKhE,CAAK,CAAA,GAAM,CAAA,GAAA,EAAMgE,CAAG,CAAA,EAAA,EAAKhE,CAAK,CAAA,CAAA,CAAG,EAAE,IAAA,CAAK;AAAA,CAAI,CAAA,CAE5E,OAAO,CACL,QAAA,CAAU,CAAC,CACT,GAAA,CAAKgL,CAAAA,CAAI,IAAA,CACT,IAAA,CAAM,CAAA;;AAAA,EAAmBlO,GAAS,gBAAgB,CAAA,CAAA,CAClD,SAAU,eACZ,CAAC,CACH,CACF,CAAA,KAAQ,CACN,OAAO,CACL,SAAU,CAAC,CAAE,IAAKkO,CAAAA,CAAI,IAAA,CAAM,KAAM,uBAAA,CAAyB,QAAA,CAAU,YAAa,CAAC,CACrF,CACF,CACF,CACF,EAGAjI,CAAAA,CAAO,QAAA,CACL,UACA,iBAAA,CACA,CACE,YAAa,+GAAA,CACb,QAAA,CAAU,eACZ,CAAA,CACA,MAAOiI,GAAQ,CACb,GAAI,CAEF,IAAMC,CAAAA,CADM,QAAQ,GAAA,EAAI,CACA,MAAM,GAAG,CAAA,CAAE,KAAI,EAAK,EAAA,CAGxC9L,EAAoB,EAAC,CACzB,GAAI8L,CAAAA,CACF,GAAI,CAEF9L,CAAAA,CAAAA,CADsB,MAAM6D,EAAO,MAAA,CAAOiI,CAAW,GAC7B,KAAA,CAAM,CAAA,CAAG,CAAC,CAAA,CAAE,GAAA,CAAIlH,GAAKA,CAAAA,CAAE,QAAQ,EACzD,CAAA,KAAQ,CAER,CAGF,GAAI5E,CAAAA,CAAQ,SAAW,CAAA,CACrB,OAAO,CACL,QAAA,CAAU,CAAC,CACT,GAAA,CAAK6L,CAAAA,CAAI,KACT,IAAA,CAAM,CAAA;;AAAA,qDAAA,EAAqEC,CAAW,KACtF,QAAA,CAAU,eACZ,CAAC,CACH,CAAA,CAGF,IAAMnO,CAAAA,CAAQqC,CAAAA,CAAQ,IAAI,CAACO,CAAAA,CAAGrB,IAAM,CAAA,EAAGA,CAAAA,CAAI,CAAC,CAAA,EAAA,EAAKqB,CAAC,CAAA,CAAE,CAAA,CAAE,IAAA,CAAK;AAAA,CAAI,CAAA,CAC/D,OAAO,CACL,QAAA,CAAU,CAAC,CACT,GAAA,CAAKsL,CAAAA,CAAI,IAAA,CACT,IAAA,CAAM,CAAA,eAAA,EAAkBC,CAAW,CAAA;;AAAA;;AAAA,EAAiCnO,CAAK,CAAA,CAAA,CACzE,QAAA,CAAU,eACZ,CAAC,CACH,CACF,CAAA,KAAQ,CACN,OAAO,CACL,SAAU,CAAC,CAAE,IAAKkO,CAAAA,CAAI,IAAA,CAAM,KAAM,8BAAA,CAAgC,QAAA,CAAU,YAAa,CAAC,CAC5F,CACF,CACF,CACF,EACF,CCpJA,IAAME,CAAAA,CAAS,WAAA,CAER,SAASC,CAAAA,CAAIC,CAAAA,CAAuB,CACzC,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,CAAA,EAAIF,CAAM,KAAKE,CAAO;AAAA,CAAI,EACjD,CAEO,SAASC,CAAAA,CAASD,CAAAA,CAAuB,CAC9C,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,CAAA,EAAIF,CAAM,CAAA,SAAA,EAAYE,CAAO;AAAA,CAAI,EACxD,CAEO,SAASE,EAAAA,CAAQF,CAAAA,CAAuB,CAC7C,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,CAAA,EAAIF,CAAM,CAAA,QAAA,EAAWE,CAAO;AAAA,CAAI,EACvD,CCGO,IAAMG,CAAAA,CAAiB,OAAA,CAEvB,SAASC,EAAAA,CAAa9M,CAAAA,CAAoC,CAC/D,IAAMqE,EAAS,IAAI0I,SAAAA,CACjB,CACE,IAAA,CAAM,YACN,OAAA,CAASF,CACX,CAAA,CACA,CACE,aAAc,CACZ,+CAAA,CACA,yFAAA,CACA,0FAAA,CACA,qDACA,6DAAA,CACA,uGAAA,CACA,uEACF,CAAA,CAAE,KAAK,GAAG,CACZ,CACF,CAAA,CAEMvI,EAAS,IAAIvE,CAAAA,CAAeC,CAAM,CAAA,CAGxC,OAAAyM,CAAAA,CAAI,sBAAsB,CAAA,CAC1BrI,EAAAA,CAAkBC,EAAQC,CAAc,CAAA,CACxC2B,EAAAA,CAAkB5B,EAAQC,CAAAA,CAAQtE,CAAM,CAAA,CACxCkH,EAAAA,CAAsB7C,EAAQC,CAAAA,CAAQtE,CAAM,CAAA,CAC5C+I,EAAAA,CAAqB1E,EAAQC,CAAAA,CAAQtE,CAAM,CAAA,CAC3CuJ,EAAAA,CAAmBlF,EAAQC,CAAc,CAAA,CACzCoF,EAAAA,CAAqBrF,EAAQC,CAAc,CAAA,CAC3CmG,EAAAA,CAAsBpG,EAAQC,CAAc,CAAA,CAC5C+G,EAAAA,CAAwBhH,EAAQC,CAAc,CAAA,CAC9C0H,EAAAA,CAAkB3H,EAAQC,CAAc,CAAA,CAGxCmI,CAAAA,CAAI,0BAA0B,CAAA,CAC9BJ,EAAAA,CAAkBhI,CAAAA,CAAQC,CAAAA,CAAQtE,CAAM,CAAA,CAExCyM,CAAAA,CAAI,iDAAiD,CAAA,CAC9CpI,CACT,CCpCA,IAAM2I,CAAAA,CAAkC,CACtC,KAAA,CAAO,EAAA,CACP,UAAA,CAAY,CACV,OAAQ,OAAA,CACR,MAAA,CAAQ,YACV,CAAA,CACA,UAAW,CACT,MAAA,CAAQ,qBACV,CAAA,CACA,MAAO,CACL,MAAA,CAAQ,iBAAA,CACR,aAAA,CAAe,KACjB,CACF,CAAA,CAMA,SAASC,EAAAA,CAAgB/O,EAA0C,CACjE,IAAMK,CAAAA,CAAkC,GACpC2O,CAAAA,CAAiB,EAAA,CAErB,IAAA,IAAWC,CAAAA,IAAWjP,EAAQ,KAAA,CAAM;AAAA,CAAI,EAAG,CACzC,IAAMM,CAAAA,CAAO2O,CAAAA,CAAQ,QAAQ,MAAA,CAAQ,EAAE,CAAA,CAAE,OAAA,GACzC,GAAI,CAAC3O,CAAAA,CAAK,IAAA,GAAQ,SAElB,IAAMuN,CAAAA,CAASvN,CAAAA,CAAK,OAASA,CAAAA,CAAK,SAAA,EAAU,CAAE,MAAA,CACxC4O,EAAU5O,CAAAA,CAAK,IAAA,EAAK,CAEpBU,CAAAA,CAAWkO,EAAQ,OAAA,CAAQ,GAAG,CAAA,CACpC,GAAIlO,EAAW,CAAA,CAAG,SAElB,IAAMC,CAAAA,CAAMiO,EAAQ,KAAA,CAAM,CAAA,CAAGlO,CAAQ,CAAA,CAAE,MAAK,CACtCE,CAAAA,CAAQgO,CAAAA,CAAQ,KAAA,CAAMlO,EAAW,CAAC,CAAA,CAAE,IAAA,EAAK,CAE3C6M,IAAW,CAAA,EAAK,CAAC3M,CAAAA,EACnB8N,CAAAA,CAAiB/N,EACZZ,CAAAA,CAAO2O,CAAc,CAAA,GAAG3O,CAAAA,CAAO2O,CAAc,CAAA,CAAI,EAAC,CAAA,EAC9CnB,CAAAA,CAAS,GAAKmB,CAAAA,CACtB3O,CAAAA,CAAO2O,CAAc,CAAA,CAA6B/N,CAAG,CAAA,CAAIC,CAAAA,CAE1Db,CAAAA,CAAOY,CAAG,EAAIC,EAElB,CAEA,OAAOb,CACT,CAEA,SAAS8O,EAAAA,EAAgC,CACvC,IAAMC,EAAa,CACjBC,OAAAA,CAAQ,OAAA,CAAQ,GAAA,GAAO,gBAAgB,CAAA,CACvCA,OAAAA,CAAQ,OAAA,CAAQ,KAAI,CAAG,iBAAiB,CAAA,CACxCpN,IAAAA,CAAKqN,SAAQ,CAAG,SAAA,CAAW,WAAA,CAAa,YAAY,EACpDrN,IAAAA,CAAKqN,OAAAA,EAAQ,CAAG,SAAA,CAAW,YAAa,aAAa,CAAA,CACrDrN,IAAAA,CAAKqN,OAAAA,GAAW,gBAAgB,CAClC,CAAA,CAEA,IAAA,IAAWC,KAAaH,CAAAA,CACtB,GAAI/M,UAAAA,CAAWkN,CAAS,EAAG,OAAOA,CAAAA,CAEpC,OAAO,IACT,CAEO,SAASC,CAAAA,EAA8B,CAC5C,IAAM1N,EAA0B,CAC9B,KAAA,CAAOgN,CAAAA,CAAe,KAAA,CACtB,WAAY,CAAE,GAAGA,CAAAA,CAAe,UAAW,EAC3C,SAAA,CAAW,CAAE,GAAGA,CAAAA,CAAe,SAAU,CAAA,CACzC,KAAA,CAAO,CAAE,GAAGA,EAAe,KAAM,CACnC,CAAA,CAGI,OAAA,CAAQ,IAAI,eAAA,GAAiBhN,CAAAA,CAAO,KAAA,CAAQ,OAAA,CAAQ,IAAI,eAAA,CAAA,CAG5D,IAAM2N,CAAAA,CAAa,OAAA,CAAQ,IAAI,gBAAA,EAAoBN,EAAAA,EAAe,CAClE,GAAIM,GAAcpN,UAAAA,CAAWoN,CAAU,CAAA,CAAG,CACxClB,EAAI,CAAA,oBAAA,EAAuBkB,CAAU,CAAA,CAAE,CAAA,CACvC,GAAI,CACF,IAAMC,CAAAA,CAAMzM,YAAAA,CAAawM,EAAY,OAAO,CAAA,CACtCE,CAAAA,CAASZ,EAAAA,CAAgBW,CAAG,CAAA,CAE9B,OAAOC,CAAAA,CAAO,KAAA,EAAU,WAAU7N,CAAAA,CAAO,KAAA,CAAQ6N,CAAAA,CAAO,KAAA,CAAA,CAE5D,IAAMC,CAAAA,CAASD,CAAAA,CAAO,WAAA,EAAeA,CAAAA,CAAO,WACxCC,CAAAA,GACEA,CAAAA,CAAM,MAAA,GAAQ9N,CAAAA,CAAO,WAAW,MAAA,CAAS8N,CAAAA,CAAM,MAAA,CAAA,CAC/CA,CAAAA,CAAM,SAAQ9N,CAAAA,CAAO,UAAA,CAAW,MAAA,CAAS8N,CAAAA,CAAM,SAGrD,IAAMC,CAAAA,CAAYF,CAAAA,CAAO,SAAA,CACrBE,GACEA,CAAAA,CAAU,MAAA,GAAQ/N,CAAAA,CAAO,SAAA,CAAU,OAAS+N,CAAAA,CAAU,MAAA,CAAA,CAG5D,IAAMC,CAAAA,CAAQH,EAAO,KAAA,CACjBG,CAAAA,GACEA,CAAAA,CAAM,MAAA,GAAQhO,EAAO,KAAA,CAAM,MAAA,CAASgO,CAAAA,CAAM,MAAA,CAAA,CAC1CA,EAAM,cAAA,GAAgBhO,CAAAA,CAAO,KAAA,CAAM,aAAA,CAAgBgO,EAAM,cAAA,GAAmB,MAAA,CAAA,EAEpF,CAAA,MAAS/K,CAAAA,CAAK,CACZ2J,EAAAA,CAAQ,CAAA,wBAAA,EAA2B3J,CAAAA,YAAe,KAAA,CAAQA,EAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,EAAE,EACvF,CACF,CAGA,OAAIjD,EAAO,KAAA,CAAM,UAAA,CAAW,GAAG,CAAA,GAC7BA,EAAO,KAAA,CAAQA,CAAAA,CAAO,KAAA,CAAM,OAAA,CAAQ,IAAKwN,OAAAA,EAAS,CAAA,CAAA,CAG7CxN,CACT,CC1HA,IAAMiO,EAAAA,CAAO;AAAA,WAAA,EACApB,CAAc,CAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA,CAAA,CAsB3B,eAAeqB,GAAOvJ,CAAAA,CAAmC,CACvD,IAAMwJ,CAAAA,CAAKC,eAAAA,CAAgB,CAAE,KAAA,CAAO,OAAA,CAAQ,MAAO,MAAA,CAAQ,OAAA,CAAQ,MAAO,CAAC,CAAA,CAC3E,OAAO,IAAI,OAAA,CAAQb,GAAW,CAC5BY,CAAAA,CAAG,SAASxJ,CAAAA,CAAU0J,CAAAA,EAAU,CAC9BF,CAAAA,CAAG,KAAA,GACHZ,CAAAA,CAAQc,CAAAA,CAAO,MAAM,EACvB,CAAC,EACH,CAAC,CACH,CAEA,eAAeC,IAAyB,CACtC,OAAA,CAAQ,OAAO,KAAA,CAAM;AAAA;AAAA,CAAqB,CAAA,CAC1C,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA;;AAAA,CAAqB,CAAA,CAC1C,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA;AAAA,CAAqE,CAAA,CAC1F,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA;;AAAA,CAA+D,CAAA,CAEpF,IAAMC,CAAAA,CAAepO,IAAAA,CAAKqN,SAAQ,CAAG,WAAA,CAAa,gBAAgB,CAAA,CAC5DgB,CAAAA,CAAQ,MAAMN,GAAO,CAAA,qBAAA,EAAwBK,CAAY,CAAA,GAAA,CAAK,CAAA,EAAKA,CAAAA,CACnEE,CAAAA,CAAc,MAAMP,EAAAA,CAAO,8BAA8B,CAAA,EAAK,OAAA,CAE9DQ,CAAAA,CAAgB,CAAA;AAAA,OAAA,EACfF,CAAK;;AAAA;AAAA,UAAA,EAGFC,CAAW;AAAA;;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA,CAAA,CAWfE,CAAAA,CAAYxO,IAAAA,CAAKqN,OAAAA,EAAQ,CAAG,SAAA,CAAW,WAAW,CAAA,CACnDjN,UAAAA,CAAWoO,CAAS,CAAA,EACvBnO,SAAAA,CAAUmO,CAAAA,CAAW,CAAE,SAAA,CAAW,IAAK,CAAC,CAAA,CAG1C,IAAMhB,CAAAA,CAAaxN,IAAAA,CAAKwO,CAAAA,CAAW,YAAY,CAAA,CAC/C7M,aAAAA,CAAc6L,CAAAA,CAAYe,CAAa,CAAA,CAEvC,OAAA,CAAQ,OAAO,KAAA,CAAM;AAAA,iBAAA,EAAsBf,CAAU;;AAAA,CAAM,CAAA,CAG3D,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA;AAAA,CAAqB,CAAA,CAC1C,IAAM3N,CAAAA,CAAS0N,CAAAA,GAETkB,CAAAA,CAAS,MADA,IAAI7O,CAAAA,CAAeC,CAAM,EACZ,MAAA,EAAO,CAE/B4O,EAAO,EAAA,CACT,OAAA,CAAQ,OAAO,KAAA,CAAM,CAAA,QAAA,EAAWA,EAAO,SAAS,CAAA;;AAAA,CAAqB,GAErE,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,EAAA,EAAKA,EAAO,KAAK;AAAA,CAAI,CAAA,CAC1C,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA;;AAAA,CAA6C,CAAA,CAAA,CAGpE,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA;AAAA,CAAiC,CAAA,CACtD,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA;;AAAA,CAAyE,CAAA,CAE9F,OAAA,CAAQ,IAAA,CAAK,CAAC,EAChB,CAEA,eAAeC,EAAAA,EAA2B,CACxC,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM;AAAA,kBAAA,EAAuBhC,CAAc;AAAA,CAAI,CAAA,CAC9D,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA;;AAAA,CAAgC,EAErD,IAAM7M,CAAAA,CAAS0N,GAAW,CAG1B,OAAA,CAAQ,OAAO,KAAA,CAAM,CAAA;AAAA,CAA6B,CAAA,CAC7C1N,EAAO,KAAA,CAGV,OAAA,CAAQ,OAAO,KAAA,CAAM,CAAA,gBAAA,EAAmBA,EAAO,KAAK;AAAA,CAAI,CAAA,CAFxD,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA;AAAA,CAA0D,EAKjF,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,sBAAA,EAAyBA,CAAAA,CAAO,WAAW,MAAM,CAAA;AAAA,CAAK,EAC3E,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,oBAAA,EAAuBA,CAAAA,CAAO,UAAU,MAAM,CAAA;AAAA,CAAK,EACxE,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,gBAAA,EAAmBA,CAAAA,CAAO,MAAM,MAAM,CAAA;AAAA,CAAK,CAAA,CAGhE,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM;AAAA;AAAA,CAA8B,CAAA,CAEnD,IAAM4O,CAAAA,CAAS,MADA,IAAI7O,CAAAA,CAAeC,CAAM,CAAA,CACZ,MAAA,EAAO,CAE/B4O,CAAAA,CAAO,EAAA,EACT,OAAA,CAAQ,OAAO,KAAA,CAAM,CAAA;AAAA,CAA2B,EAChD,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,eAAA,EAAkBA,EAAO,SAAS,CAAA;AAAA,CAAmB,IAE1E,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA,SAAA,EAAYA,EAAO,KAAK;AAAA,CAAI,CAAA,CACjD,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM;AAAA;AAAA,CAAwB,CAAA,CAC7C,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA;AAAA,CAA+C,CAAA,CACpE,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA;AAAA,CAAiC,CAAA,CACtD,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA;AAAA,CAA8B,CAAA,CAAA,CAGrD,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM;AAAA,CAAI,EACzB,OAAA,CAAQ,IAAA,CAAKA,EAAO,EAAA,CAAK,CAAA,CAAI,CAAC,EAChC,CAEA,SAASE,EAAAA,EAAmB,CAC1B,IAAM9O,CAAAA,CAAS0N,GAAW,CAC1B,OAAA,CAAQ,OAAO,KAAA,CAAM;AAAA;AAAA,CAA6B,CAAA,CAClD,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,CAAA;;AAAA,CAA6B,EAClD,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,gBAAA,EAAmB1N,CAAAA,CAAO,OAAS,WAAW;AAAA,CAAI,EACvE,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,gBAAA,EAAmBA,CAAAA,CAAO,WAAW,MAAM;AAAA,CAAI,EACpE,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,gBAAA,EAAmBA,CAAAA,CAAO,WAAW,MAAM;AAAA,CAAI,EACpE,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,gBAAA,EAAmBA,CAAAA,CAAO,UAAU,MAAM;AAAA,CAAI,EACnE,OAAA,CAAQ,MAAA,CAAO,MAAM,CAAA,gBAAA,EAAmBA,CAAAA,CAAO,MAAM,MAAM;AAAA,CAAI,CAAA,CAC/D,QAAQ,MAAA,CAAO,KAAA,CAAM,mBAAmBA,CAAAA,CAAO,KAAA,CAAM,aAAA,CAAgB,IAAA,CAAO,KAAK;AAAA,CAAI,CAAA,CACrF,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM;AAAA,CAAI,CAAA,CACzB,OAAA,CAAQ,IAAA,CAAK,CAAC,EAChB,CAEA,eAAe+O,EAAAA,EAA6B,CAC1C,IAAMC,CAAAA,CAAc,OAAA,CAAQ,OAAA,CACV,QAAA,CAASA,EAAY,KAAA,CAAM,CAAC,CAAC,CAAA,CAC/B,KACdrC,CAAAA,CAAS,CAAA,8BAAA,EAAiCqC,CAAW,CAAA,CAAE,EACvD,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,CAAA,CAGhBvC,EAAI,CAAA,WAAA,EAAcI,CAAc,CAAA,QAAA,EAAWmC,CAAW,MAAM,OAAA,CAAQ,QAAQ,CAAA,CAAE,CAAA,CAE9E,IAAMhP,CAAAA,CAAS0N,CAAAA,EAAW,CAErB1N,CAAAA,CAAO,OACVyM,CAAAA,CAAI,iEAAiE,CAAA,CAGvE,IAAMpI,EAASyI,EAAAA,CAAa9M,CAAM,CAAA,CAC5BiP,CAAAA,CAAY,IAAIC,oBAAAA,CAEhBC,CAAAA,CAAW,SAAY,CAC3B1C,EAAI,kBAAkB,CAAA,CACtB,MAAMpI,CAAAA,CAAO,OAAM,CACnB,OAAA,CAAQ,IAAA,CAAK,CAAC,EAChB,CAAA,CAEA,OAAA,CAAQ,EAAA,CAAG,QAAA,CAAU8K,CAAQ,CAAA,CAC7B,OAAA,CAAQ,EAAA,CAAG,SAAA,CAAWA,CAAQ,CAAA,CAE9B,MAAM9K,CAAAA,CAAO,OAAA,CAAQ4K,CAAS,EAChC,CAGA,IAAMG,EAAAA,CAAU,QAAQ,IAAA,CAAK,CAAC,CAAA,CAE9B,OAAQA,IACN,KAAK,MAAA,CACHd,EAAAA,GAAU,KAAA,CAAMrL,CAAAA,EAAO,CACrB0J,CAAAA,CAAS1J,aAAe,KAAA,CAAQA,CAAAA,CAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,CAAA,CACzD,OAAA,CAAQ,IAAA,CAAK,CAAC,EAChB,CAAC,CAAA,CACD,MACF,KAAK,QAAA,CACH4L,EAAAA,EAAU,CAAE,KAAA,CAAM5L,GAAO,CACvB0J,CAAAA,CAAS1J,CAAAA,YAAe,KAAA,CAAQA,EAAI,OAAA,CAAU,MAAA,CAAOA,CAAG,CAAC,EACzD,OAAA,CAAQ,IAAA,CAAK,CAAC,EAChB,CAAC,CAAA,CACD,MACF,KAAK,QAAA,CACH6L,IAAW,CACX,MACF,KAAK,WAAA,CACL,KAAK,IAAA,CACH,OAAA,CAAQ,MAAA,CAAO,KAAA,CAAM,cAAcjC,CAAc;AAAA,CAAI,EACrD,OAAA,CAAQ,IAAA,CAAK,CAAC,CAAA,CACd,MACF,KAAK,QAAA,CACL,KAAK,KACH,OAAA,CAAQ,MAAA,CAAO,MAAMoB,EAAI,CAAA,CACzB,QAAQ,IAAA,CAAK,CAAC,EACd,MACF,QACEc,EAAAA,EAAY,CAAE,MAAM9L,CAAAA,EAAO,CACzB0J,EAAS,CAAA,OAAA,EAAU1J,CAAAA,YAAe,MAAQA,CAAAA,CAAI,OAAA,CAAU,OAAOA,CAAG,CAAC,EAAE,CAAA,CACrE,OAAA,CAAQ,KAAK,CAAC,EAChB,CAAC,EACL","file":"cli.js","sourcesContent":["/**\n * Extract a section from markdown content by heading.\n * Returns content under the heading until the next heading of same or higher level.\n */\nexport function extractSection(content: string, heading: string): string | null {\n const lines = content.split('\\n');\n let capturing = false;\n let headingLevel = 0;\n const result: string[] = [];\n\n for (const line of lines) {\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n\n if (headingMatch) {\n const level = headingMatch[1].length;\n const text = headingMatch[2].trim();\n\n if (capturing) {\n if (level <= headingLevel) break;\n result.push(line);\n } else if (text.toLowerCase() === heading.toLowerCase()) {\n capturing = true;\n headingLevel = level;\n result.push(line);\n }\n } else if (capturing) {\n result.push(line);\n }\n }\n\n return result.length > 0 ? result.join('\\n').trim() : null;\n}\n\n/**\n * Replace a section in markdown content by heading.\n */\nexport function replaceSection(content: string, heading: string, newContent: string): string {\n const lines = content.split('\\n');\n const result: string[] = [];\n let skipping = false;\n let headingLevel = 0;\n\n for (const line of lines) {\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n\n if (headingMatch) {\n const level = headingMatch[1].length;\n const text = headingMatch[2].trim();\n\n if (skipping && level <= headingLevel) {\n skipping = false;\n result.push(line);\n } else if (text.toLowerCase() === heading.toLowerCase()) {\n skipping = true;\n headingLevel = level;\n result.push(line);\n result.push('');\n result.push(newContent);\n result.push('');\n } else {\n result.push(line);\n }\n } else if (!skipping) {\n result.push(line);\n }\n }\n\n return result.join('\\n');\n}\n\n/**\n * Parse YAML frontmatter from markdown content.\n */\nexport function parseFrontmatter(content: string): { frontmatter: Record<string, string>; body: string } {\n const match = content.match(/^---\\n([\\s\\S]*?)\\n---\\n?([\\s\\S]*)$/);\n if (!match) return { frontmatter: {}, body: content };\n\n const frontmatter: Record<string, string> = {};\n for (const line of match[1].split('\\n')) {\n const colonIdx = line.indexOf(':');\n if (colonIdx > 0) {\n const key = line.slice(0, colonIdx).trim();\n const value = line.slice(colonIdx + 1).trim();\n frontmatter[key] = value;\n }\n }\n\n return { frontmatter, body: match[2] };\n}\n\n/**\n * Extract all [[wikilinks]] from markdown content.\n */\nexport function extractWikilinks(content: string): string[] {\n const matches = content.matchAll(/\\[\\[([^\\]|]+)(?:\\|[^\\]]+)?\\]\\]/g);\n return [...matches].map(m => m[1]);\n}\n\n/**\n * Extract all #tags from markdown content.\n */\nexport function extractTags(content: string): string[] {\n const matches = content.matchAll(/(?:^|\\s)#([a-zA-Z0-9_/-]+)/g);\n return [...new Set([...matches].map(m => m[1]))];\n}\n\n/**\n * Extract all tasks (checkbox items) from markdown content.\n */\nexport function extractTasks(content: string): Array<{ text: string; done: boolean; line: number }> {\n const tasks: Array<{ text: string; done: boolean; line: number }> = [];\n const lines = content.split('\\n');\n\n for (let i = 0; i < lines.length; i++) {\n const match = lines[i].match(/^[\\s]*-\\s+\\[([ xX])\\]\\s+(.+)$/);\n if (match) {\n tasks.push({\n text: match[2],\n done: match[1] !== ' ',\n line: i + 1,\n });\n }\n }\n\n return tasks;\n}\n\n/**\n * Count words in text (excluding frontmatter).\n */\nexport function wordCount(content: string): number {\n const { body } = parseFrontmatter(content);\n return body.split(/\\s+/).filter(w => w.length > 0).length;\n}\n","import { readFileSync, writeFileSync, appendFileSync, unlinkSync, existsSync, mkdirSync, readdirSync } from 'fs';\nimport { join, relative, dirname, extname, basename } from 'path';\nimport { type MindCacheConfig } from '@/config.js';\nimport { extractSection, replaceSection } from '@/utils/markdown.js';\n\nexport interface SearchResult {\n filename: string;\n score: number;\n matches: Array<{\n match: { start: number; end: number };\n context: string;\n }>;\n}\n\nexport interface VaultFile {\n path: string;\n name: string;\n extension: string;\n}\n\n/**\n * Direct filesystem client for Obsidian vaults.\n * Reads and writes markdown files directly — no plugin required.\n */\nexport class ObsidianClient {\n private vaultPath: string;\n private fileCache: VaultFile[] | null = null;\n private fileCacheTime = 0;\n private readonly CACHE_TTL = 5000; // 5 seconds\n\n constructor(config: MindCacheConfig) {\n this.vaultPath = config.vault;\n }\n\n private resolve(notePath: string): string {\n // Prevent path traversal\n const resolved = join(this.vaultPath, notePath);\n if (!resolved.startsWith(this.vaultPath)) {\n throw new Error('Path traversal not allowed');\n }\n return resolved;\n }\n\n private ensureDir(filePath: string): void {\n const dir = dirname(filePath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n }\n\n /**\n * Walk the vault directory and collect all files.\n */\n private walkDir(dir: string): string[] {\n const results: string[] = [];\n let entries;\n try {\n entries = readdirSync(dir, { withFileTypes: true });\n } catch {\n return results;\n }\n\n for (const entry of entries) {\n // Skip hidden files/dirs and .obsidian config\n if (entry.name.startsWith('.')) continue;\n if (entry.name === 'node_modules') continue;\n\n const fullPath = join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...this.walkDir(fullPath));\n } else {\n results.push(fullPath);\n }\n }\n return results;\n }\n\n /**\n * Check if the vault directory exists.\n */\n async ping(): Promise<boolean> {\n return existsSync(this.vaultPath);\n }\n\n /**\n * Search the vault using simple text matching.\n */\n async search(query: string): Promise<SearchResult[]> {\n const files = await this.listFiles();\n const mdFiles = files.filter(f => f.extension === 'md');\n const queryLower = query.toLowerCase();\n const results: SearchResult[] = [];\n\n for (const file of mdFiles) {\n try {\n const content = readFileSync(this.resolve(file.path), 'utf-8');\n const contentLower = content.toLowerCase();\n const idx = contentLower.indexOf(queryLower);\n\n if (idx >= 0) {\n // Count occurrences for scoring\n let count = 0;\n let pos = 0;\n while ((pos = contentLower.indexOf(queryLower, pos)) !== -1) {\n count++;\n pos += queryLower.length;\n }\n\n // Extract context around first match\n const start = Math.max(0, idx - 50);\n const end = Math.min(content.length, idx + query.length + 50);\n const context = content.slice(start, end).replace(/\\n/g, ' ').trim();\n\n results.push({\n filename: file.path,\n score: count * 10 + (file.name.toLowerCase().includes(queryLower) ? 50 : 0),\n matches: [{ match: { start: idx, end: idx + query.length }, context }],\n });\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n return results.sort((a, b) => b.score - a.score);\n }\n\n /**\n * Read a note's content.\n */\n async readNote(path: string): Promise<string> {\n const fullPath = this.resolve(path);\n if (!existsSync(fullPath)) {\n throw new Error(`Note not found: ${path}`);\n }\n return readFileSync(fullPath, 'utf-8');\n }\n\n /**\n * Create or overwrite a note.\n */\n async writeNote(path: string, content: string): Promise<void> {\n const fullPath = this.resolve(path);\n this.ensureDir(fullPath);\n writeFileSync(fullPath, content, 'utf-8');\n this.fileCache = null; // Invalidate cache\n }\n\n /**\n * Append content to an existing note.\n */\n async appendToNote(path: string, content: string): Promise<void> {\n const fullPath = this.resolve(path);\n if (!existsSync(fullPath)) {\n throw new Error(`Note not found: ${path}`);\n }\n appendFileSync(fullPath, content, 'utf-8');\n }\n\n /**\n * Patch content in a note (append/prepend under heading).\n */\n async patchNote(path: string, content: string, options?: {\n operation?: 'append' | 'prepend' | 'replace';\n targetHeading?: string;\n targetLine?: number;\n }): Promise<void> {\n const fullPath = this.resolve(path);\n const existing = readFileSync(fullPath, 'utf-8');\n\n if (options?.targetHeading) {\n const section = extractSection(existing, options.targetHeading);\n if (!section) {\n throw new Error(`Heading \"${options.targetHeading}\" not found`);\n }\n\n if (options.operation === 'replace') {\n const updated = replaceSection(existing, options.targetHeading, content);\n writeFileSync(fullPath, updated, 'utf-8');\n } else {\n // Append under heading — find the heading line and insert after it\n const lines = existing.split('\\n');\n const headingLower = options.targetHeading.toLowerCase();\n let insertIdx = -1;\n\n for (let i = 0; i < lines.length; i++) {\n const match = lines[i].match(/^#{1,6}\\s+(.+)$/);\n if (match && match[1].trim().toLowerCase() === headingLower) {\n // Find end of this section\n const headingLevel = lines[i].indexOf(' ');\n insertIdx = i + 1;\n for (let j = i + 1; j < lines.length; j++) {\n const nextMatch = lines[j].match(/^(#{1,6})\\s/);\n if (nextMatch && nextMatch[1].length <= headingLevel) break;\n insertIdx = j + 1;\n }\n break;\n }\n }\n\n if (insertIdx >= 0) {\n lines.splice(insertIdx, 0, content);\n writeFileSync(fullPath, lines.join('\\n'), 'utf-8');\n } else {\n throw new Error(`Heading \"${options.targetHeading}\" not found`);\n }\n }\n } else if (options?.targetLine !== undefined) {\n const lines = existing.split('\\n');\n lines.splice(options.targetLine, 0, content);\n writeFileSync(fullPath, lines.join('\\n'), 'utf-8');\n } else {\n appendFileSync(fullPath, content, 'utf-8');\n }\n }\n\n /**\n * Delete a note.\n */\n async deleteNote(path: string): Promise<void> {\n const fullPath = this.resolve(path);\n if (!existsSync(fullPath)) {\n throw new Error(`Note not found: ${path}`);\n }\n unlinkSync(fullPath);\n this.fileCache = null;\n }\n\n /**\n * List all files in the vault (cached for 5s).\n */\n async listFiles(): Promise<VaultFile[]> {\n const now = Date.now();\n if (this.fileCache && now - this.fileCacheTime < this.CACHE_TTL) {\n return this.fileCache;\n }\n\n const allPaths = this.walkDir(this.vaultPath);\n this.fileCache = allPaths.map(fullPath => {\n const relPath = relative(this.vaultPath, fullPath);\n const name = basename(relPath, extname(relPath));\n const extension = extname(relPath).slice(1);\n return { path: relPath, name, extension };\n });\n this.fileCacheTime = now;\n return this.fileCache;\n }\n\n /**\n * Get the currently active note in Obsidian.\n * Not available in filesystem mode.\n */\n async getActiveNote(): Promise<string> {\n throw new Error('Active note detection requires Obsidian to be running. Use search or read_note instead.');\n }\n\n /**\n * Get the active note's file path.\n * Not available in filesystem mode.\n */\n async getActiveNotePath(): Promise<string> {\n throw new Error('Active note detection requires Obsidian to be running. Use search or read_note instead.');\n }\n\n /**\n * Search with context around matches.\n */\n async searchWithContext(query: string, contextLength: number = 100): Promise<SearchResult[]> {\n const files = await this.listFiles();\n const mdFiles = files.filter(f => f.extension === 'md');\n const queryLower = query.toLowerCase();\n const results: SearchResult[] = [];\n\n for (const file of mdFiles) {\n try {\n const content = readFileSync(this.resolve(file.path), 'utf-8');\n const contentLower = content.toLowerCase();\n const matches: SearchResult['matches'] = [];\n let pos = 0;\n\n while ((pos = contentLower.indexOf(queryLower, pos)) !== -1) {\n const start = Math.max(0, pos - contextLength);\n const end = Math.min(content.length, pos + query.length + contextLength);\n matches.push({\n match: { start: pos, end: pos + query.length },\n context: content.slice(start, end).replace(/\\n/g, ' ').trim(),\n });\n pos += queryLower.length;\n if (matches.length >= 5) break; // Cap matches per file\n }\n\n if (matches.length > 0) {\n results.push({\n filename: file.path,\n score: matches.length * 10 + (file.name.toLowerCase().includes(queryLower) ? 50 : 0),\n matches,\n });\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n return results.sort((a, b) => b.score - a.score);\n }\n\n /**\n * Check health of the vault connection.\n */\n async health(): Promise<{ ok: boolean; error?: string; noteCount?: number }> {\n if (!this.vaultPath) {\n return { ok: false, error: 'No vault path configured. Run: mindcache init' };\n }\n if (!existsSync(this.vaultPath)) {\n return { ok: false, error: `Vault not found at: ${this.vaultPath}` };\n }\n\n try {\n const files = await this.listFiles();\n const mdCount = files.filter(f => f.extension === 'md').length;\n return { ok: true, noteCount: mdCount };\n } catch (err) {\n return { ok: false, error: `Cannot read vault: ${err instanceof Error ? err.message : String(err)}` };\n }\n }\n}\n","/**\n * Format a date as YYYY-MM-DD.\n */\nexport function formatDate(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, '0');\n const d = String(date.getDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n}\n\n/**\n * Get today's date formatted.\n */\nexport function today(): string {\n return formatDate(new Date());\n}\n\n/**\n * Get the start of the current week (Monday).\n */\nexport function startOfWeek(date: Date = new Date()): Date {\n const d = new Date(date);\n const day = d.getDay();\n const diff = d.getDate() - day + (day === 0 ? -6 : 1);\n d.setDate(diff);\n d.setHours(0, 0, 0, 0);\n return d;\n}\n\n/**\n * Get dates for the current week (Mon-Sun).\n */\nexport function weekDates(date: Date = new Date()): string[] {\n const start = startOfWeek(date);\n const dates: string[] = [];\n for (let i = 0; i < 7; i++) {\n const d = new Date(start);\n d.setDate(start.getDate() + i);\n dates.push(formatDate(d));\n }\n return dates;\n}\n\n/**\n * Parse a date range string like \"last week\", \"this month\", \"2026-01-01 to 2026-01-31\".\n */\nexport function parseDateRange(range: string): { from: Date; to: Date } {\n const now = new Date();\n const lower = range.toLowerCase().trim();\n\n if (lower === 'today') {\n const start = new Date(now);\n start.setHours(0, 0, 0, 0);\n const end = new Date(now);\n end.setHours(23, 59, 59, 999);\n return { from: start, to: end };\n }\n\n if (lower === 'yesterday') {\n const start = new Date(now);\n start.setDate(start.getDate() - 1);\n start.setHours(0, 0, 0, 0);\n const end = new Date(start);\n end.setHours(23, 59, 59, 999);\n return { from: start, to: end };\n }\n\n if (lower === 'this week') {\n const start = startOfWeek(now);\n return { from: start, to: now };\n }\n\n if (lower === 'last week') {\n const thisWeekStart = startOfWeek(now);\n const lastWeekStart = new Date(thisWeekStart);\n lastWeekStart.setDate(lastWeekStart.getDate() - 7);\n const lastWeekEnd = new Date(thisWeekStart);\n lastWeekEnd.setMilliseconds(-1);\n return { from: lastWeekStart, to: lastWeekEnd };\n }\n\n if (lower === 'this month') {\n const start = new Date(now.getFullYear(), now.getMonth(), 1);\n return { from: start, to: now };\n }\n\n if (lower === 'last month') {\n const start = new Date(now.getFullYear(), now.getMonth() - 1, 1);\n const end = new Date(now.getFullYear(), now.getMonth(), 0, 23, 59, 59, 999);\n return { from: start, to: end };\n }\n\n // Try \"YYYY-MM-DD to YYYY-MM-DD\" format\n const rangeMatch = lower.match(/(\\d{4}-\\d{2}-\\d{2})\\s+to\\s+(\\d{4}-\\d{2}-\\d{2})/);\n if (rangeMatch) {\n return { from: new Date(rangeMatch[1]), to: new Date(rangeMatch[2]) };\n }\n\n // Try \"last N days\"\n const daysMatch = lower.match(/last\\s+(\\d+)\\s+days?/);\n if (daysMatch) {\n const start = new Date(now);\n start.setDate(start.getDate() - parseInt(daysMatch[1]));\n start.setHours(0, 0, 0, 0);\n return { from: start, to: now };\n }\n\n // Default: last 7 days\n const start = new Date(now);\n start.setDate(start.getDate() - 7);\n start.setHours(0, 0, 0, 0);\n return { from: start, to: now };\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { ObsidianClient } from '@/obsidian.js';\nimport { type MindCacheConfig } from '@/config.js';\nimport { extractTags, extractWikilinks, parseFrontmatter } from '@/utils/markdown.js';\nimport { parseDateRange } from '@/utils/dates.js';\n\nexport function registerFindTools(server: McpServer, client: ObsidianClient, _config: MindCacheConfig): void {\n // ─── search ────────────────────────────────────────────────────────\n server.tool(\n 'search',\n 'Full-text search across your Obsidian vault. Supports Obsidian search operators: \"exact phrase\", path:folder, tag:#tag, file:filename. Returns matching notes with context snippets.',\n { query: z.string().describe('Search query — supports Obsidian search operators') },\n async ({ query }) => {\n try {\n const results = await client.searchWithContext(query, 200);\n if (results.length === 0) {\n return { content: [{ type: 'text', text: `No results found for \"${query}\"` }] };\n }\n\n const formatted = results.slice(0, 20).map((r, i) => {\n const contexts = r.matches.slice(0, 3).map(m => ` > ${m.context.trim()}`).join('\\n');\n return `${i + 1}. **${r.filename}** (score: ${r.score.toFixed(1)})\\n${contexts}`;\n }).join('\\n\\n');\n\n return {\n content: [{ type: 'text', text: `Found ${results.length} results for \"${query}\":\\n\\n${formatted}` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Search error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── ask ───────────────────────────────────────────────────────────\n server.tool(\n 'ask',\n 'Ask a natural language question about your vault. Searches for relevant notes and returns their content so you can synthesize an answer. Use this when you need to understand what the user knows about a topic.',\n { question: z.string().describe('Natural language question to answer from vault knowledge') },\n async ({ question }) => {\n try {\n // Extract key terms and search\n const results = await client.searchWithContext(question, 300);\n if (results.length === 0) {\n return { content: [{ type: 'text', text: `No relevant notes found for: \"${question}\"` }] };\n }\n\n // Get content from top results\n const topResults = results.slice(0, 5);\n const notes: string[] = [];\n\n for (const result of topResults) {\n try {\n const content = await client.readNote(result.filename);\n const { frontmatter } = parseFrontmatter(content);\n const tags = extractTags(content);\n const links = extractWikilinks(content);\n\n // Truncate long notes\n const truncated = content.length > 2000 ? content.slice(0, 2000) + '\\n...(truncated)' : content;\n\n notes.push(\n `---\\n**${result.filename}**` +\n (tags.length > 0 ? ` | Tags: ${tags.map(t => `#${t}`).join(', ')}` : '') +\n (links.length > 0 ? ` | Links: ${links.map(l => `[[${l}]]`).join(', ')}` : '') +\n (frontmatter.type ? ` | Type: ${frontmatter.type}` : '') +\n `\\n\\n${truncated}`\n );\n } catch {\n // Skip notes that can't be read\n }\n }\n\n return {\n content: [{\n type: 'text',\n text: `Found ${results.length} relevant notes for \"${question}\". Here are the top ${notes.length}:\\n\\n${notes.join('\\n\\n')}`,\n }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Ask error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── find_related ──────────────────────────────────────────────────\n server.tool(\n 'find_related',\n 'Find notes related to a given note via backlinks, shared tags, or shared wikilinks. Returns notes that are connected in the knowledge graph.',\n { path: z.string().describe('Path to the note (e.g., \"Projects/My Project.md\")') },\n async ({ path }) => {\n try {\n const content = await client.readNote(path);\n const outlinks = extractWikilinks(content);\n const tags = extractTags(content);\n\n const related = new Map<string, { reason: string; score: number }>();\n\n // Find notes linked from this note\n for (const link of outlinks) {\n const results = await client.search(`file:${link}`);\n for (const r of results.slice(0, 3)) {\n if (r.filename !== path) {\n related.set(r.filename, {\n reason: `Linked from this note: [[${link}]]`,\n score: (related.get(r.filename)?.score ?? 0) + 2,\n });\n }\n }\n }\n\n // Find notes with shared tags\n for (const tag of tags.slice(0, 5)) {\n const results = await client.search(`tag:#${tag}`);\n for (const r of results.slice(0, 5)) {\n if (r.filename !== path) {\n const existing = related.get(r.filename);\n related.set(r.filename, {\n reason: existing ? `${existing.reason}; Shared tag: #${tag}` : `Shared tag: #${tag}`,\n score: (existing?.score ?? 0) + 1,\n });\n }\n }\n }\n\n // Find notes that link to this note (backlinks)\n const noteName = path.replace(/\\.md$/, '').split('/').pop() ?? path;\n const backlinkResults = await client.search(`\"[[${noteName}]]\"`);\n for (const r of backlinkResults) {\n if (r.filename !== path) {\n const existing = related.get(r.filename);\n related.set(r.filename, {\n reason: existing ? `${existing.reason}; Links to this note` : 'Links to this note',\n score: (existing?.score ?? 0) + 3,\n });\n }\n }\n\n const sorted = [...related.entries()]\n .sort((a, b) => b[1].score - a[1].score)\n .slice(0, 15);\n\n if (sorted.length === 0) {\n return { content: [{ type: 'text', text: `No related notes found for \"${path}\"` }] };\n }\n\n const formatted = sorted.map(([file, info], i) =>\n `${i + 1}. **${file}** — ${info.reason}`\n ).join('\\n');\n\n return {\n content: [{ type: 'text', text: `Related notes for \"${path}\":\\n\\n${formatted}` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Find related error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── find_by_tag ───────────────────────────────────────────────────\n server.tool(\n 'find_by_tag',\n 'Find all notes with specific tags. Supports multiple tags (all must match). Use without # prefix.',\n {\n tags: z.array(z.string()).describe('Tags to search for (without # prefix, e.g., [\"project\", \"active\"])'),\n limit: z.number().optional().default(20).describe('Maximum number of results'),\n },\n async ({ tags, limit }) => {\n try {\n const query = tags.map(t => `tag:#${t}`).join(' ');\n const results = await client.search(query);\n\n if (results.length === 0) {\n return { content: [{ type: 'text', text: `No notes found with tags: ${tags.map(t => `#${t}`).join(', ')}` }] };\n }\n\n const formatted = results.slice(0, limit).map((r, i) =>\n `${i + 1}. ${r.filename}`\n ).join('\\n');\n\n return {\n content: [{ type: 'text', text: `Notes tagged ${tags.map(t => `#${t}`).join(', ')} (${results.length} total):\\n\\n${formatted}` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Tag search error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── find_by_date ──────────────────────────────────────────────────\n server.tool(\n 'find_by_date',\n 'Find notes created or modified within a date range. Supports natural language like \"today\", \"this week\", \"last month\", \"last 7 days\", or explicit \"YYYY-MM-DD to YYYY-MM-DD\".',\n {\n range: z.string().describe('Date range — \"today\", \"this week\", \"last month\", \"last 30 days\", or \"YYYY-MM-DD to YYYY-MM-DD\"'),\n limit: z.number().optional().default(20).describe('Maximum results'),\n },\n async ({ range, limit }) => {\n try {\n const { from, to } = parseDateRange(range);\n const files = await client.listFiles();\n const mdFiles = files.filter(f => f.extension === 'md');\n\n // Search for notes with dates in the range\n const fromStr = from.toISOString().split('T')[0];\n const toStr = to.toISOString().split('T')[0];\n\n // Use search to find notes mentioning dates in the range\n const results = await client.search(`\"${fromStr}\"`);\n\n const formatted = results.slice(0, limit).map((r, i) =>\n `${i + 1}. ${r.filename}`\n ).join('\\n');\n\n return {\n content: [{\n type: 'text',\n text: `Notes from ${fromStr} to ${toStr} (searched by date reference):\\n\\n` +\n (formatted || 'No notes found in this range.') +\n `\\n\\nTotal markdown files in vault: ${mdFiles.length}`,\n }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Date search error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── find_recent ───────────────────────────────────────────────────\n server.tool(\n 'find_recent',\n 'List notes in the vault. Returns markdown files from the vault file listing.',\n {\n limit: z.number().optional().default(10).describe('Number of recent notes to return'),\n },\n async ({ limit }) => {\n try {\n const files = await client.listFiles();\n const mdFiles = files.filter(f => f.extension === 'md');\n\n // The API returns files — we'll show the most recent ones\n // Note: exact modification time requires reading each file\n const recent = mdFiles.slice(0, limit);\n\n const formatted = recent.map((f, i) =>\n `${i + 1}. ${f.path}`\n ).join('\\n');\n\n return {\n content: [{\n type: 'text',\n text: `Vault files (${mdFiles.length} total markdown notes):\\n\\n${formatted}`,\n }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Recent notes error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── find_mentions ─────────────────────────────────────────────────\n server.tool(\n 'find_mentions',\n 'Find all notes that mention a specific term, concept, or person. Searches for exact text matches across the vault.',\n {\n term: z.string().describe('Term or concept to search for'),\n limit: z.number().optional().default(20).describe('Maximum results'),\n },\n async ({ term, limit }) => {\n try {\n const results = await client.searchWithContext(term, 150);\n\n if (results.length === 0) {\n return { content: [{ type: 'text', text: `\"${term}\" is not mentioned in any notes.` }] };\n }\n\n const formatted = results.slice(0, limit).map((r, i) => {\n const context = r.matches[0]?.context?.trim() ?? '';\n return `${i + 1}. **${r.filename}**\\n > ${context}`;\n }).join('\\n\\n');\n\n return {\n content: [{ type: 'text', text: `\"${term}\" mentioned in ${results.length} notes:\\n\\n${formatted}` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Mentions search error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { ObsidianClient } from '@/obsidian.js';\nimport { type MindCacheConfig } from '@/config.js';\nimport { extractSection, parseFrontmatter, extractTags, extractWikilinks, wordCount } from '@/utils/markdown.js';\nimport { today, weekDates } from '@/utils/dates.js';\n\nexport function registerReadTools(server: McpServer, client: ObsidianClient, config: MindCacheConfig): void {\n // ─── read_note ─────────────────────────────────────────────────────\n server.tool(\n 'read_note',\n 'Read the full content of a note by its path. Returns the complete markdown including frontmatter.',\n { path: z.string().describe('Path to the note (e.g., \"Projects/My Project.md\")') },\n async ({ path }) => {\n try {\n const content = await client.readNote(path);\n return { content: [{ type: 'text', text: content }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not read \"${path}\": ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── read_section ──────────────────────────────────────────────────\n server.tool(\n 'read_section',\n 'Read a specific section from a note, identified by its heading. Returns content from the heading to the next heading of the same or higher level.',\n {\n path: z.string().describe('Path to the note'),\n heading: z.string().describe('Heading text to extract (e.g., \"Key Points\", \"Action Items\")'),\n },\n async ({ path, heading }) => {\n try {\n const content = await client.readNote(path);\n const section = extractSection(content, heading);\n\n if (!section) {\n return {\n content: [{ type: 'text', text: `No section \"${heading}\" found in \"${path}\"` }],\n };\n }\n\n return { content: [{ type: 'text', text: section }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not read section: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── read_summary ─────────────────────────────────────────────────\n server.tool(\n 'read_summary',\n 'Get a note with its metadata: frontmatter properties, tags, wikilinks, and word count. Useful for understanding a note without reading it fully.',\n { path: z.string().describe('Path to the note') },\n async ({ path }) => {\n try {\n const content = await client.readNote(path);\n const { frontmatter } = parseFrontmatter(content);\n const tags = extractTags(content);\n const links = extractWikilinks(content);\n const words = wordCount(content);\n\n const summary = [\n `**${path}**`,\n '',\n `**Words:** ${words}`,\n tags.length > 0 ? `**Tags:** ${tags.map(t => `#${t}`).join(', ')}` : null,\n links.length > 0 ? `**Links:** ${links.map(l => `[[${l}]]`).join(', ')}` : null,\n Object.keys(frontmatter).length > 0\n ? `**Properties:**\\n${Object.entries(frontmatter).map(([k, v]) => ` - ${k}: ${v}`).join('\\n')}`\n : null,\n '',\n '---',\n '',\n content,\n ].filter(Boolean).join('\\n');\n\n return { content: [{ type: 'text', text: summary }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not read summary: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── read_properties ──────────────────────────────────────────────\n server.tool(\n 'read_properties',\n 'Read only the YAML frontmatter properties of a note. Fast way to check metadata without reading the full content.',\n { path: z.string().describe('Path to the note') },\n async ({ path }) => {\n try {\n const content = await client.readNote(path);\n const { frontmatter } = parseFrontmatter(content);\n\n if (Object.keys(frontmatter).length === 0) {\n return { content: [{ type: 'text', text: `No frontmatter found in \"${path}\"` }] };\n }\n\n const formatted = Object.entries(frontmatter)\n .map(([k, v]) => `${k}: ${v}`)\n .join('\\n');\n\n return { content: [{ type: 'text', text: `Properties of \"${path}\":\\n\\n${formatted}` }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not read properties: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── read_today ────────────────────────────────────────────────────\n server.tool(\n 'read_today',\n \"Read today's daily note. Returns the content of today's daily note based on your configured daily notes folder and format.\",\n {},\n async () => {\n try {\n const dailyPath = `${config.dailyNotes.folder}/${today()}.md`;\n const content = await client.readNote(dailyPath);\n return { content: [{ type: 'text', text: `**Today's Daily Note (${today()}):**\\n\\n${content}` }] };\n } catch {\n return {\n content: [{ type: 'text', text: `No daily note found for today (${today()}). Expected at: ${config.dailyNotes.folder}/${today()}.md` }],\n };\n }\n }\n );\n\n // ─── read_this_week ────────────────────────────────────────────────\n server.tool(\n 'read_this_week',\n \"Read all daily notes from the current week (Monday to Sunday). Useful for getting a weekly overview of activity.\",\n {},\n async () => {\n try {\n const dates = weekDates();\n const notes: string[] = [];\n\n for (const date of dates) {\n const path = `${config.dailyNotes.folder}/${date}.md`;\n try {\n const content = await client.readNote(path);\n notes.push(`## ${date}\\n\\n${content}`);\n } catch {\n // Skip missing daily notes\n }\n }\n\n if (notes.length === 0) {\n return { content: [{ type: 'text', text: `No daily notes found for this week (${dates[0]} to ${dates[6]}).` }] };\n }\n\n return {\n content: [{ type: 'text', text: `**This Week's Daily Notes:**\\n\\n${notes.join('\\n\\n---\\n\\n')}` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not read weekly notes: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── get_active_note ───────────────────────────────────────────────\n server.tool(\n 'get_active_note',\n 'Get the currently active/open note in Obsidian. Returns both the path and content of the note the user is currently viewing.',\n {},\n async () => {\n try {\n const content = await client.getActiveNote();\n let path = '';\n try {\n path = await client.getActiveNotePath();\n } catch {\n // Path endpoint may not be available\n }\n\n return {\n content: [{\n type: 'text',\n text: path\n ? `**Active Note: ${path}**\\n\\n${content}`\n : `**Active Note:**\\n\\n${content}`,\n }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not get active note: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n}\n","import { readFileSync, existsSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { today } from '@/utils/dates.js';\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst TEMPLATES_DIR = join(__dirname, '..', 'templates');\n\nexport type TemplateName =\n | 'decision'\n | 'meeting'\n | 'learning'\n | 'idea'\n | 'person'\n | 'project'\n | 'book'\n | 'article'\n | 'weekly-review'\n | 'session';\n\nconst TEMPLATE_CACHE = new Map<string, string>();\n\n/**\n * Load a built-in template by name.\n */\nexport function loadTemplate(name: TemplateName): string {\n if (TEMPLATE_CACHE.has(name)) return TEMPLATE_CACHE.get(name)!;\n\n const path = join(TEMPLATES_DIR, `${name}.md`);\n if (!existsSync(path)) {\n throw new Error(`Template \"${name}\" not found at ${path}`);\n }\n\n const content = readFileSync(path, 'utf-8');\n TEMPLATE_CACHE.set(name, content);\n return content;\n}\n\n/**\n * Apply variables to a template string.\n * Variables are in {{variable}} format.\n */\nexport function applyTemplate(template: string, variables: Record<string, string>): string {\n let result = template;\n\n // Built-in variables\n const builtins: Record<string, string> = {\n date: today(),\n timestamp: new Date().toISOString(),\n year: String(new Date().getFullYear()),\n month: String(new Date().getMonth() + 1).padStart(2, '0'),\n day: String(new Date().getDate()).padStart(2, '0'),\n };\n\n const allVars = { ...builtins, ...variables };\n\n for (const [key, value] of Object.entries(allVars)) {\n result = result.replaceAll(`{{${key}}}`, value ?? '');\n }\n\n // Remove any remaining unresolved variables\n result = result.replace(/\\{\\{[^}]+\\}\\}/g, '');\n\n return result;\n}\n\n/**\n * Get a template and apply variables.\n */\nexport function renderTemplate(name: TemplateName, variables: Record<string, string> = {}): string {\n const template = loadTemplate(name);\n return applyTemplate(template, variables);\n}\n\n/**\n * List all available template names.\n */\nexport function listTemplates(): TemplateName[] {\n return [\n 'decision', 'meeting', 'learning', 'idea', 'person',\n 'project', 'book', 'article', 'weekly-review', 'session',\n ];\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { ObsidianClient } from '@/obsidian.js';\nimport { type MindCacheConfig } from '@/config.js';\nimport { renderTemplate } from '@/templates.js';\nimport { today } from '@/utils/dates.js';\n\nexport function registerRememberTools(server: McpServer, client: ObsidianClient, config: MindCacheConfig): void {\n // ─── remember ──────────────────────────────────────────────────────\n server.tool(\n 'remember',\n 'Quick capture — save a thought, note, or piece of information to the vault. Auto-saves to the inbox folder. Use this for quick, unstructured captures.',\n {\n content: z.string().describe('The content to save'),\n title: z.string().optional().describe('Optional title for the note. If omitted, generates from content.'),\n tags: z.array(z.string()).optional().describe('Optional tags to add (without # prefix)'),\n folder: z.string().optional().describe('Optional folder to save to (defaults to inbox)'),\n },\n async ({ content, title, tags, folder }) => {\n try {\n const noteTitle = title ?? `Quick Note - ${today()} ${new Date().toLocaleTimeString('en-US', { hour12: false, hour: '2-digit', minute: '2-digit' })}`;\n const targetFolder = folder ?? config.inbox.folder;\n const path = `${targetFolder}/${noteTitle}.md`;\n\n const tagLine = tags && tags.length > 0\n ? `tags:\\n${tags.map(t => ` - ${t}`).join('\\n')}`\n : 'tags:\\n - inbox';\n\n const noteContent = `---\\ndate: ${today()}\\n${tagLine}\\n---\\n\\n${content}\\n`;\n\n await client.writeNote(path, noteContent);\n\n return {\n content: [{ type: 'text', text: `Saved to \"${path}\"` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not save note: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── remember_meeting ──────────────────────────────────────────────\n server.tool(\n 'remember_meeting',\n 'Create a structured meeting note with attendees, agenda, notes, and action items. Uses the meeting template.',\n {\n title: z.string().describe('Meeting title'),\n attendees: z.string().describe('Comma-separated list of attendees'),\n agenda: z.string().optional().default('').describe('Meeting agenda'),\n notes: z.string().optional().default('').describe('Meeting notes'),\n action_items: z.string().optional().default('').describe('Action items from the meeting'),\n follow_up: z.string().optional().default('').describe('Follow-up items'),\n folder: z.string().optional().describe('Folder to save to (defaults to inbox)'),\n },\n async ({ title, attendees, agenda, notes, action_items, follow_up, folder }) => {\n try {\n const content = renderTemplate('meeting', {\n title, attendees, agenda, notes, action_items, follow_up,\n });\n const targetFolder = folder ?? config.inbox.folder;\n const path = `${targetFolder}/${title}.md`;\n await client.writeNote(path, content);\n\n return { content: [{ type: 'text', text: `Meeting note created at \"${path}\"` }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not create meeting note: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── remember_decision ─────────────────────────────────────────────\n server.tool(\n 'remember_decision',\n 'Log a decision using the ADR (Architecture Decision Record) format. Captures the context, decision, consequences, and alternatives considered.',\n {\n title: z.string().describe('Decision title'),\n context: z.string().describe('Why this decision needed to be made'),\n decision: z.string().describe('What was decided'),\n consequences: z.string().optional().default('').describe('What happens as a result'),\n alternatives: z.string().optional().default('').describe('Other options that were considered'),\n related: z.string().optional().default('').describe('Related notes or concepts'),\n folder: z.string().optional().describe('Folder to save to'),\n },\n async ({ title, context, decision, consequences, alternatives, related, folder }) => {\n try {\n const content = renderTemplate('decision', {\n title, context, decision, consequences, alternatives, related,\n });\n const targetFolder = folder ?? config.inbox.folder;\n const path = `${targetFolder}/${title}.md`;\n await client.writeNote(path, content);\n\n return { content: [{ type: 'text', text: `Decision logged at \"${path}\"` }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not log decision: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── remember_idea ─────────────────────────────────────────────────\n server.tool(\n 'remember_idea',\n 'Capture an idea with context on why it matters and potential next steps.',\n {\n title: z.string().describe('Idea title'),\n idea: z.string().describe('Description of the idea'),\n why: z.string().optional().default('').describe('Why this idea matters'),\n next_steps: z.string().optional().default('').describe('Potential next steps'),\n related: z.string().optional().default('').describe('Related notes or concepts'),\n tags: z.array(z.string()).optional().describe('Additional tags'),\n folder: z.string().optional().describe('Folder to save to'),\n },\n async ({ title, idea, why, next_steps, related, folder }) => {\n try {\n const content = renderTemplate('idea', {\n title, idea, why, next_steps, related,\n });\n const targetFolder = folder ?? config.inbox.folder;\n const path = `${targetFolder}/${title}.md`;\n await client.writeNote(path, content);\n\n return { content: [{ type: 'text', text: `Idea captured at \"${path}\"` }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not capture idea: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── remember_learning ─────────────────────────────────────────────\n server.tool(\n 'remember_learning',\n 'Save something new you learned — a concept, technique, insight, or skill with examples and application notes.',\n {\n title: z.string().describe('What was learned'),\n concept: z.string().describe('The concept or insight'),\n key_points: z.string().optional().default('').describe('Key points to remember'),\n examples: z.string().optional().default('').describe('Examples or illustrations'),\n application: z.string().optional().default('').describe('How to apply this learning'),\n source: z.string().optional().default('').describe('Where you learned this'),\n related: z.string().optional().default('').describe('Related notes'),\n folder: z.string().optional().describe('Folder to save to'),\n },\n async ({ title, concept, key_points, examples, application, source, related, folder }) => {\n try {\n const content = renderTemplate('learning', {\n title, concept, key_points, examples, application, source, related,\n });\n const targetFolder = folder ?? config.inbox.folder;\n const path = `${targetFolder}/${title}.md`;\n await client.writeNote(path, content);\n\n return { content: [{ type: 'text', text: `Learning saved at \"${path}\"` }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not save learning: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── remember_person ───────────────────────────────────────────────\n server.tool(\n 'remember_person',\n 'Create or update a note about a person — their role, organization, context, and interactions.',\n {\n name: z.string().describe('Person\\'s name'),\n role: z.string().optional().default('').describe('Their role or title'),\n organization: z.string().optional().default('').describe('Their organization'),\n contact: z.string().optional().default('').describe('Contact information'),\n context: z.string().optional().default('').describe('How you know them or relevant context'),\n interaction: z.string().optional().default('').describe('Notes from recent interaction'),\n notes: z.string().optional().default('').describe('Additional notes'),\n folder: z.string().optional().describe('Folder to save to'),\n },\n async ({ name, role, organization, contact, context, interaction, notes, folder }) => {\n try {\n const content = renderTemplate('person', {\n name, role, organization, contact, context, interaction, notes,\n });\n const targetFolder = folder ?? config.inbox.folder;\n const path = `${targetFolder}/${name}.md`;\n await client.writeNote(path, content);\n\n return { content: [{ type: 'text', text: `Person note created at \"${path}\"` }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not create person note: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── remember_reference ────────────────────────────────────────────\n server.tool(\n 'remember_reference',\n 'Bookmark a URL or resource with a summary, tags, and personal notes. Great for saving articles, videos, tools, or documentation.',\n {\n title: z.string().describe('Title of the resource'),\n url: z.string().describe('URL of the resource'),\n source: z.string().optional().default('').describe('Source (e.g., \"Hacker News\", \"Twitter\")'),\n summary: z.string().optional().default('').describe('Brief summary'),\n takeaways: z.string().optional().default('').describe('Key takeaways'),\n thoughts: z.string().optional().default('').describe('Your personal thoughts'),\n related: z.string().optional().default('').describe('Related notes'),\n tags: z.array(z.string()).optional().describe('Tags for categorization'),\n folder: z.string().optional().describe('Folder to save to'),\n },\n async ({ title, url, source, summary, takeaways, thoughts, related, folder }) => {\n try {\n const content = renderTemplate('article', {\n title, url, source, summary, takeaways, thoughts, related,\n });\n const targetFolder = folder ?? config.inbox.folder;\n const path = `${targetFolder}/${title}.md`;\n await client.writeNote(path, content);\n\n return { content: [{ type: 'text', text: `Reference saved at \"${path}\"` }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not save reference: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { ObsidianClient } from '@/obsidian.js';\nimport { type MindCacheConfig } from '@/config.js';\nimport { today } from '@/utils/dates.js';\n\nexport function registerJournalTools(server: McpServer, client: ObsidianClient, config: MindCacheConfig): void {\n // ─── log ───────────────────────────────────────────────────────────\n server.tool(\n 'log',\n \"Append an entry to today's daily note. Creates the daily note if it doesn't exist. Adds entries under a configurable heading with timestamps.\",\n {\n entry: z.string().describe('The entry to add to the daily note'),\n heading: z.string().optional().default('Log').describe('Heading to add the entry under (default: \"Log\")'),\n },\n async ({ entry, heading }) => {\n try {\n const dailyPath = `${config.dailyNotes.folder}/${today()}.md`;\n const time = new Date().toLocaleTimeString('en-US', {\n hour12: false,\n hour: '2-digit',\n minute: '2-digit',\n });\n const formattedEntry = `\\n- ${time} — ${entry}`;\n\n // Try to append to existing note\n try {\n await client.readNote(dailyPath);\n // Note exists, append under the heading\n try {\n await client.patchNote(dailyPath, formattedEntry, {\n operation: 'append',\n targetHeading: heading,\n });\n } catch {\n // Heading might not exist, just append to end\n await client.appendToNote(dailyPath, `\\n## ${heading}\\n${formattedEntry}\\n`);\n }\n } catch {\n // Note doesn't exist, create it\n const content = `---\\ndate: ${today()}\\ntags:\\n - daily\\n---\\n\\n# ${today()}\\n\\n## ${heading}\\n${formattedEntry}\\n`;\n await client.writeNote(dailyPath, content);\n }\n\n return {\n content: [{ type: 'text', text: `Logged to daily note (${today()}): ${entry}` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not log entry: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── log_task ──────────────────────────────────────────────────────\n server.tool(\n 'log_task',\n \"Add a task (checkbox item) to today's daily note. Creates the daily note if it doesn't exist.\",\n {\n task: z.string().describe('The task description'),\n heading: z.string().optional().default('Tasks').describe('Heading to add the task under (default: \"Tasks\")'),\n },\n async ({ task, heading }) => {\n try {\n const dailyPath = `${config.dailyNotes.folder}/${today()}.md`;\n const formattedTask = `\\n- [ ] ${task}`;\n\n try {\n await client.readNote(dailyPath);\n try {\n await client.patchNote(dailyPath, formattedTask, {\n operation: 'append',\n targetHeading: heading,\n });\n } catch {\n await client.appendToNote(dailyPath, `\\n## ${heading}\\n${formattedTask}\\n`);\n }\n } catch {\n const content = `---\\ndate: ${today()}\\ntags:\\n - daily\\n---\\n\\n# ${today()}\\n\\n## ${heading}\\n${formattedTask}\\n`;\n await client.writeNote(dailyPath, content);\n }\n\n return {\n content: [{ type: 'text', text: `Task added to daily note: ${task}` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not add task: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── reflect ───────────────────────────────────────────────────────\n server.tool(\n 'reflect',\n \"Generate reflection prompts based on recent vault activity. Reads today's and recent daily notes to suggest areas for reflection.\",\n {},\n async () => {\n try {\n // Try to read today's daily note for context\n let todayContent = '';\n try {\n const dailyPath = `${config.dailyNotes.folder}/${today()}.md`;\n todayContent = await client.readNote(dailyPath);\n } catch {\n // No daily note today\n }\n\n // Search for recent activity\n const recentFiles = await client.listFiles();\n const mdFiles = recentFiles.filter(f => f.extension === 'md');\n\n const prompts = [\n \"What was the most important thing you learned today?\",\n \"What decision did you make that you want to remember?\",\n \"What are you most proud of from today's work?\",\n \"What would you do differently next time?\",\n \"What's one thing you want to explore further?\",\n \"Who helped you today, and how?\",\n \"What's blocking you right now?\",\n \"What's one thing you're grateful for today?\",\n ];\n\n // Pick 3-4 relevant prompts\n const selected = prompts.sort(() => Math.random() - 0.5).slice(0, 4);\n\n let response = `**Reflection Prompts for ${today()}:**\\n\\n`;\n response += selected.map((p, i) => `${i + 1}. ${p}`).join('\\n');\n\n if (todayContent) {\n response += `\\n\\n---\\n\\n**Today's note preview:**\\n${todayContent.slice(0, 500)}`;\n }\n\n response += `\\n\\n---\\n\\nVault stats: ${mdFiles.length} notes total.`;\n response += '\\n\\nTip: Use `log` to add your reflections to today\\'s daily note.';\n\n return { content: [{ type: 'text', text: response }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Reflection error: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { ObsidianClient } from '@/obsidian.js';\nimport { type MindCacheConfig } from '@/config.js';\nimport { renderTemplate } from '@/templates.js';\nimport { replaceSection } from '@/utils/markdown.js';\n\nexport function registerWriteTools(server: McpServer, client: ObsidianClient, _config: MindCacheConfig): void {\n // ─── create_note ───────────────────────────────────────────────────\n server.tool(\n 'create_note',\n 'Create a new note in the vault. Supports optional templates, folder routing, and frontmatter. Will not overwrite existing notes unless explicitly requested.',\n {\n path: z.string().describe('Path for the new note (e.g., \"Projects/My Project.md\")'),\n content: z.string().describe('Markdown content for the note'),\n template: z.enum(['decision', 'meeting', 'learning', 'idea', 'person', 'project', 'book', 'article', 'weekly-review', 'session']).optional().describe('Optional template to use'),\n variables: z.record(z.string()).optional().describe('Template variables as key-value pairs'),\n overwrite: z.boolean().optional().default(false).describe('Whether to overwrite if note already exists'),\n },\n async ({ path, content, template, variables, overwrite }) => {\n try {\n // Check if note exists\n if (!overwrite) {\n try {\n await client.readNote(path);\n return {\n content: [{ type: 'text', text: `Note already exists at \"${path}\". Set overwrite=true to replace it.` }],\n };\n } catch {\n // Note doesn't exist, proceed\n }\n }\n\n let finalContent = content;\n if (template) {\n finalContent = renderTemplate(template, { ...variables, content });\n }\n\n await client.writeNote(path, finalContent);\n\n return { content: [{ type: 'text', text: `Note created at \"${path}\"` }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not create note: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── append_to_note ────────────────────────────────────────────────\n server.tool(\n 'append_to_note',\n 'Append content to the end of an existing note. The note must already exist.',\n {\n path: z.string().describe('Path to the note to append to'),\n content: z.string().describe('Content to append'),\n },\n async ({ path, content }) => {\n try {\n await client.appendToNote(path, `\\n${content}\\n`);\n return { content: [{ type: 'text', text: `Content appended to \"${path}\"` }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not append to note: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── update_section ────────────────────────────────────────────────\n server.tool(\n 'update_section',\n 'Replace the content under a specific heading in a note. Useful for updating a section without modifying the rest of the note.',\n {\n path: z.string().describe('Path to the note'),\n heading: z.string().describe('Heading text of the section to replace'),\n content: z.string().describe('New content for the section'),\n },\n async ({ path, heading, content }) => {\n try {\n const noteContent = await client.readNote(path);\n const updated = replaceSection(noteContent, heading, content);\n await client.writeNote(path, updated);\n\n return { content: [{ type: 'text', text: `Section \"${heading}\" updated in \"${path}\"` }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not update section: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { ObsidianClient } from '@/obsidian.js';\nimport { type MindCacheConfig } from '@/config.js';\nimport { extractWikilinks, extractTags } from '@/utils/markdown.js';\n\nexport function registerConnectTools(server: McpServer, client: ObsidianClient, _config: MindCacheConfig): void {\n // ─── add_link ──────────────────────────────────────────────────────\n server.tool(\n 'add_link',\n 'Add a [[wikilink]] to a note, connecting it to another note in the vault. Appends the link under a \"Related\" heading or at the end of the note.',\n {\n path: z.string().describe('Path of the note to add the link to'),\n target: z.string().describe('Name of the note to link to (without .md extension)'),\n context: z.string().optional().describe('Optional context for why these notes are related'),\n },\n async ({ path, target, context }) => {\n try {\n const content = await client.readNote(path);\n const existingLinks = extractWikilinks(content);\n\n if (existingLinks.includes(target)) {\n return {\n content: [{ type: 'text', text: `\"${path}\" already links to [[${target}]]` }],\n };\n }\n\n const linkLine = context\n ? `\\n- [[${target}]] — ${context}`\n : `\\n- [[${target}]]`;\n\n // Try to append under \"Related\" heading\n try {\n await client.patchNote(path, linkLine, {\n operation: 'append',\n targetHeading: 'Related',\n });\n } catch {\n // No \"Related\" heading, append to end\n await client.appendToNote(path, `\\n## Related\\n${linkLine}\\n`);\n }\n\n return {\n content: [{ type: 'text', text: `Added link to [[${target}]] in \"${path}\"` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not add link: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── suggest_connections ───────────────────────────────────────────\n server.tool(\n 'suggest_connections',\n 'Analyze a note and suggest other notes that could be linked to it. Uses shared tags, mentions, and content similarity to find connections.',\n {\n path: z.string().describe('Path to the note to analyze'),\n limit: z.number().optional().default(10).describe('Maximum suggestions to return'),\n },\n async ({ path, limit }) => {\n try {\n const content = await client.readNote(path);\n const existingLinks = extractWikilinks(content);\n const tags = extractTags(content);\n\n const suggestions = new Map<string, string[]>();\n\n // Find notes with shared tags\n for (const tag of tags.slice(0, 5)) {\n try {\n const results = await client.search(`tag:#${tag}`);\n for (const r of results) {\n if (r.filename !== path && !existingLinks.includes(r.filename.replace(/\\.md$/, ''))) {\n const reasons = suggestions.get(r.filename) ?? [];\n reasons.push(`Shared tag: #${tag}`);\n suggestions.set(r.filename, reasons);\n }\n }\n } catch {\n // Skip failed searches\n }\n }\n\n // Find notes with similar content (search using key phrases)\n const words = content.split(/\\s+/).filter(w => w.length > 5).slice(0, 10);\n for (const word of words.slice(0, 3)) {\n try {\n const results = await client.search(word);\n for (const r of results.slice(0, 5)) {\n if (r.filename !== path && !existingLinks.includes(r.filename.replace(/\\.md$/, ''))) {\n const reasons = suggestions.get(r.filename) ?? [];\n if (!reasons.some(r => r.startsWith('Mentions:'))) {\n reasons.push(`Mentions: \"${word}\"`);\n suggestions.set(r.filename, reasons);\n }\n }\n }\n } catch {\n // Skip failed searches\n }\n }\n\n const sorted = [...suggestions.entries()]\n .sort((a, b) => b[1].length - a[1].length)\n .slice(0, limit);\n\n if (sorted.length === 0) {\n return {\n content: [{ type: 'text', text: `No connection suggestions found for \"${path}\". The note may be well-connected already!` }],\n };\n }\n\n const formatted = sorted.map(([file, reasons], i) =>\n `${i + 1}. **${file}**\\n ${reasons.join(', ')}`\n ).join('\\n\\n');\n\n return {\n content: [{\n type: 'text',\n text: `Suggested connections for \"${path}\":\\n\\n${formatted}\\n\\nUse \\`add_link\\` to connect any of these notes.`,\n }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not suggest connections: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── find_gaps ─────────────────────────────────────────────────────\n server.tool(\n 'find_gaps',\n 'Find broken links in the vault — [[wikilinks]] that point to notes that don\\'t exist. These represent knowledge gaps or notes waiting to be written.',\n {\n limit: z.number().optional().default(20).describe('Maximum gaps to return'),\n },\n async ({ limit }) => {\n try {\n const files = await client.listFiles();\n const existingNotes = new Set(\n files.filter(f => f.extension === 'md').map(f => f.name.toLowerCase())\n );\n\n const gaps = new Map<string, string[]>();\n\n // Sample notes to find broken links\n const mdFiles = files.filter(f => f.extension === 'md');\n const sampleSize = Math.min(mdFiles.length, 100);\n const sampled = mdFiles.sort(() => Math.random() - 0.5).slice(0, sampleSize);\n\n for (const file of sampled) {\n try {\n const content = await client.readNote(file.path);\n const links = extractWikilinks(content);\n\n for (const link of links) {\n if (!existingNotes.has(link.toLowerCase())) {\n const sources = gaps.get(link) ?? [];\n sources.push(file.path);\n gaps.set(link, sources);\n }\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n const sorted = [...gaps.entries()]\n .sort((a, b) => b[1].length - a[1].length)\n .slice(0, limit);\n\n if (sorted.length === 0) {\n return {\n content: [{ type: 'text', text: `No broken links found (sampled ${sampleSize} of ${mdFiles.length} notes).` }],\n };\n }\n\n const formatted = sorted.map(([link, sources], i) =>\n `${i + 1}. **[[${link}]]** — referenced by ${sources.length} note(s): ${sources.slice(0, 3).join(', ')}${sources.length > 3 ? '...' : ''}`\n ).join('\\n');\n\n return {\n content: [{\n type: 'text',\n text: `Knowledge gaps (broken links) found in vault:\\n\\n${formatted}\\n\\nThese are concepts referenced but not yet written about. Use \\`create_note\\` to fill them in.`,\n }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not find gaps: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── find_orphans ──────────────────────────────────────────────────\n server.tool(\n 'find_orphans',\n 'Find orphan notes — notes with no incoming or outgoing links. These are disconnected from the knowledge graph and might need connecting.',\n {\n limit: z.number().optional().default(20).describe('Maximum orphans to return'),\n },\n async ({ limit }) => {\n try {\n const files = await client.listFiles();\n const mdFiles = files.filter(f => f.extension === 'md');\n\n // Build a set of all notes that are linked to or link out\n const linked = new Set<string>();\n const sampleSize = Math.min(mdFiles.length, 100);\n const sampled = mdFiles.sort(() => Math.random() - 0.5).slice(0, sampleSize);\n\n for (const file of sampled) {\n try {\n const content = await client.readNote(file.path);\n const outlinks = extractWikilinks(content);\n\n if (outlinks.length > 0) {\n linked.add(file.path);\n for (const link of outlinks) {\n // Find the actual file path for this link\n const target = mdFiles.find(f => f.name.toLowerCase() === link.toLowerCase());\n if (target) linked.add(target.path);\n }\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n const orphans = sampled\n .filter(f => !linked.has(f.path))\n .slice(0, limit);\n\n if (orphans.length === 0) {\n return {\n content: [{ type: 'text', text: `No orphan notes found (sampled ${sampleSize} notes). Your vault is well-connected!` }],\n };\n }\n\n const formatted = orphans.map((f, i) =>\n `${i + 1}. ${f.path}`\n ).join('\\n');\n\n return {\n content: [{\n type: 'text',\n text: `Orphan notes (no links in or out):\\n\\n${formatted}\\n\\nConsider linking these to related notes using \\`add_link\\` or \\`suggest_connections\\`.`,\n }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not find orphans: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { ObsidianClient } from '@/obsidian.js';\nimport { type MindCacheConfig } from '@/config.js';\nimport { parseFrontmatter } from '@/utils/markdown.js';\n\nexport function registerOrganizeTools(server: McpServer, client: ObsidianClient, _config: MindCacheConfig): void {\n // ─── add_tag ───────────────────────────────────────────────────────\n server.tool(\n 'add_tag',\n 'Add one or more tags to a note. Tags are added to the YAML frontmatter. If the note has no frontmatter, it will be created.',\n {\n path: z.string().describe('Path to the note'),\n tags: z.array(z.string()).describe('Tags to add (without # prefix)'),\n },\n async ({ path, tags }) => {\n try {\n const content = await client.readNote(path);\n const { frontmatter, body } = parseFrontmatter(content);\n\n // Parse existing tags\n const existingTags: string[] = [];\n if (frontmatter.tags) {\n // Handle both comma-separated and array-like formats\n const tagStr = frontmatter.tags;\n if (tagStr.startsWith('[')) {\n existingTags.push(...tagStr.slice(1, -1).split(',').map(t => t.trim()));\n } else {\n existingTags.push(tagStr);\n }\n }\n\n const allTags = [...new Set([...existingTags, ...tags])];\n const tagYaml = allTags.map(t => ` - ${t}`).join('\\n');\n\n // Rebuild frontmatter\n const fmEntries = Object.entries(frontmatter)\n .filter(([k]) => k !== 'tags')\n .map(([k, v]) => `${k}: ${v}`)\n .join('\\n');\n\n const newContent = `---\\n${fmEntries}${fmEntries ? '\\n' : ''}tags:\\n${tagYaml}\\n---\\n\\n${body}`;\n await client.writeNote(path, newContent);\n\n return {\n content: [{ type: 'text', text: `Added tags ${tags.map(t => `#${t}`).join(', ')} to \"${path}\"` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not add tags: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── update_properties ─────────────────────────────────────────────\n server.tool(\n 'update_properties',\n 'Update YAML frontmatter properties of a note. Can add new properties or modify existing ones.',\n {\n path: z.string().describe('Path to the note'),\n properties: z.record(z.string()).describe('Properties to set as key-value pairs (e.g., {\"status\": \"done\", \"priority\": \"high\"})'),\n },\n async ({ path, properties }) => {\n try {\n const content = await client.readNote(path);\n const { frontmatter, body } = parseFrontmatter(content);\n\n const merged = { ...frontmatter, ...properties };\n const fmYaml = Object.entries(merged)\n .map(([k, v]) => `${k}: ${v}`)\n .join('\\n');\n\n const newContent = `---\\n${fmYaml}\\n---\\n\\n${body}`;\n await client.writeNote(path, newContent);\n\n const updated = Object.entries(properties)\n .map(([k, v]) => `${k}: ${v}`)\n .join(', ');\n\n return {\n content: [{ type: 'text', text: `Updated properties in \"${path}\": ${updated}` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not update properties: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── rename_note ───────────────────────────────────────────────────\n server.tool(\n 'rename_note',\n 'Rename a note by creating a copy at the new path and deleting the original. Note: Obsidian will update backlinks if the app is running.',\n {\n old_path: z.string().describe('Current path of the note'),\n new_path: z.string().describe('New path for the note'),\n },\n async ({ old_path, new_path }) => {\n try {\n const content = await client.readNote(old_path);\n\n // Check if target exists\n try {\n await client.readNote(new_path);\n return {\n content: [{ type: 'text', text: `A note already exists at \"${new_path}\". Choose a different name.` }],\n };\n } catch {\n // Target doesn't exist, proceed\n }\n\n await client.writeNote(new_path, content);\n await client.deleteNote(old_path);\n\n return {\n content: [{ type: 'text', text: `Renamed \"${old_path}\" to \"${new_path}\"` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not rename note: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── move_note ─────────────────────────────────────────────────────\n server.tool(\n 'move_note',\n 'Move a note to a different folder in the vault. Preserves the filename.',\n {\n path: z.string().describe('Current path of the note'),\n destination: z.string().describe('Destination folder (e.g., \"Projects\", \"Archive\")'),\n },\n async ({ path, destination }) => {\n try {\n const content = await client.readNote(path);\n const filename = path.split('/').pop() ?? path;\n const newPath = `${destination}/${filename}`;\n\n // Check if target exists\n try {\n await client.readNote(newPath);\n return {\n content: [{ type: 'text', text: `A note already exists at \"${newPath}\". Rename the note first.` }],\n };\n } catch {\n // Target doesn't exist, proceed\n }\n\n await client.writeNote(newPath, content);\n await client.deleteNote(path);\n\n return {\n content: [{ type: 'text', text: `Moved \"${path}\" to \"${newPath}\"` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not move note: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { ObsidianClient } from '@/obsidian.js';\nimport { type MindCacheConfig } from '@/config.js';\nimport { extractTags } from '@/utils/markdown.js';\n\nexport function registerUnderstandTools(server: McpServer, client: ObsidianClient, _config: MindCacheConfig): void {\n // ─── vault_overview ────────────────────────────────────────────────\n server.tool(\n 'vault_overview',\n 'Get an overview of your Obsidian vault: total notes, folder structure, tag distribution, and general statistics.',\n {},\n async () => {\n try {\n const files = await client.listFiles();\n const mdFiles = files.filter(f => f.extension === 'md');\n const otherFiles = files.filter(f => f.extension !== 'md');\n\n // Count files per folder\n const folderCounts = new Map<string, number>();\n for (const file of mdFiles) {\n const parts = file.path.split('/');\n const folder = parts.length > 1 ? parts.slice(0, -1).join('/') : '(root)';\n folderCounts.set(folder, (folderCounts.get(folder) ?? 0) + 1);\n }\n\n const topFolders = [...folderCounts.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 15);\n\n // Sample tags from recent notes\n const tagCounts = new Map<string, number>();\n const sampleSize = Math.min(mdFiles.length, 50);\n const sampled = mdFiles.slice(0, sampleSize);\n\n for (const file of sampled) {\n try {\n const content = await client.readNote(file.path);\n const tags = extractTags(content);\n for (const tag of tags) {\n tagCounts.set(tag, (tagCounts.get(tag) ?? 0) + 1);\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n const topTags = [...tagCounts.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 15);\n\n let response = `**Vault Overview**\\n\\n`;\n response += `- **Total notes:** ${mdFiles.length}\\n`;\n response += `- **Other files:** ${otherFiles.length} (images, PDFs, etc.)\\n`;\n response += `- **Folders:** ${folderCounts.size}\\n\\n`;\n\n response += `**Top Folders:**\\n`;\n response += topFolders.map(([folder, count]) =>\n ` - ${folder}: ${count} notes`\n ).join('\\n');\n\n if (topTags.length > 0) {\n response += `\\n\\n**Top Tags** (sampled from ${sampleSize} notes):\\n`;\n response += topTags.map(([tag, count]) =>\n ` - #${tag}: ${count}`\n ).join('\\n');\n }\n\n return { content: [{ type: 'text', text: response }] };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not get vault overview: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── list_tags ─────────────────────────────────────────────────────\n server.tool(\n 'list_tags',\n 'List all tags used in the vault with their occurrence counts. Samples notes to build the tag list.',\n {\n limit: z.number().optional().default(50).describe('Maximum tags to return'),\n },\n async ({ limit }) => {\n try {\n const files = await client.listFiles();\n const mdFiles = files.filter(f => f.extension === 'md');\n\n const tagCounts = new Map<string, number>();\n const sampleSize = Math.min(mdFiles.length, 200);\n const sampled = mdFiles.slice(0, sampleSize);\n\n for (const file of sampled) {\n try {\n const content = await client.readNote(file.path);\n const tags = extractTags(content);\n for (const tag of tags) {\n tagCounts.set(tag, (tagCounts.get(tag) ?? 0) + 1);\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n const sorted = [...tagCounts.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, limit);\n\n if (sorted.length === 0) {\n return { content: [{ type: 'text', text: 'No tags found in vault.' }] };\n }\n\n const formatted = sorted.map(([tag, count]) =>\n `#${tag} (${count})`\n ).join('\\n');\n\n return {\n content: [{\n type: 'text',\n text: `**Tags in vault** (sampled ${sampleSize} of ${mdFiles.length} notes):\\n\\n${formatted}`,\n }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not list tags: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── get_vault_structure ───────────────────────────────────────────\n server.tool(\n 'get_vault_structure',\n 'Get the folder structure of the vault as a tree with note counts per folder. Useful for understanding vault organization.',\n {},\n async () => {\n try {\n const files = await client.listFiles();\n const mdFiles = files.filter(f => f.extension === 'md');\n\n // Build folder tree\n const folders = new Map<string, number>();\n for (const file of mdFiles) {\n const parts = file.path.split('/');\n if (parts.length > 1) {\n // Add all parent folders\n for (let i = 1; i < parts.length; i++) {\n const folder = parts.slice(0, i).join('/');\n if (i === parts.length - 1) {\n // This is the direct parent\n folders.set(folder, (folders.get(folder) ?? 0) + 1);\n } else if (!folders.has(folder)) {\n folders.set(folder, 0);\n }\n }\n } else {\n folders.set('(root)', (folders.get('(root)') ?? 0) + 1);\n }\n }\n\n const sorted = [...folders.entries()].sort((a, b) => a[0].localeCompare(b[0]));\n\n const tree = sorted.map(([folder, count]) => {\n const depth = folder.split('/').length - 1;\n const indent = ' '.repeat(depth);\n const name = folder.split('/').pop() ?? folder;\n return `${indent}${name}/ (${count} notes)`;\n }).join('\\n');\n\n return {\n content: [{\n type: 'text',\n text: `**Vault Structure** (${mdFiles.length} total notes):\\n\\n${tree}`,\n }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not get vault structure: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod';\nimport { ObsidianClient } from '@/obsidian.js';\nimport { type MindCacheConfig } from '@/config.js';\nimport { extractTasks } from '@/utils/markdown.js';\n\nexport function registerTaskTools(server: McpServer, client: ObsidianClient, _config: MindCacheConfig): void {\n // ─── find_tasks ────────────────────────────────────────────────────\n server.tool(\n 'find_tasks',\n 'Find all checkbox tasks across the vault. Filter by status (open, done, or all). Returns tasks with their source note and line number.',\n {\n status: z.enum(['open', 'done', 'all']).optional().default('open').describe('Filter by task status'),\n query: z.string().optional().describe('Optional search query to filter tasks by text'),\n limit: z.number().optional().default(30).describe('Maximum tasks to return'),\n },\n async ({ status, query, limit }) => {\n try {\n // Search for tasks via checkbox pattern\n const files = await client.listFiles();\n const mdFiles = files.filter(f => f.extension === 'md');\n\n const allTasks: Array<{\n text: string;\n done: boolean;\n file: string;\n line: number;\n }> = [];\n\n // Sample files for tasks\n const sampleSize = Math.min(mdFiles.length, 100);\n const sampled = mdFiles.slice(0, sampleSize);\n\n for (const file of sampled) {\n try {\n const content = await client.readNote(file.path);\n const tasks = extractTasks(content);\n\n for (const task of tasks) {\n if (query && !task.text.toLowerCase().includes(query.toLowerCase())) continue;\n if (status === 'open' && task.done) continue;\n if (status === 'done' && !task.done) continue;\n\n allTasks.push({\n text: task.text,\n done: task.done,\n file: file.path,\n line: task.line,\n });\n }\n } catch {\n // Skip unreadable files\n }\n }\n\n if (allTasks.length === 0) {\n return {\n content: [{ type: 'text', text: `No ${status === 'all' ? '' : status + ' '}tasks found${query ? ` matching \"${query}\"` : ''}.` }],\n };\n }\n\n const displayed = allTasks.slice(0, limit);\n const formatted = displayed.map((t, i) =>\n `${i + 1}. [${t.done ? 'x' : ' '}] ${t.text}\\n *${t.file}:${t.line}*`\n ).join('\\n\\n');\n\n return {\n content: [{\n type: 'text',\n text: `**${status === 'all' ? 'All' : status === 'open' ? 'Open' : 'Completed'} Tasks** (${allTasks.length} found, showing ${displayed.length}):\\n\\n${formatted}`,\n }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not find tasks: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n\n // ─── complete_task ─────────────────────────────────────────────────\n server.tool(\n 'complete_task',\n 'Mark a specific task as done by replacing [ ] with [x] at the given line in a note.',\n {\n path: z.string().describe('Path to the note containing the task'),\n line: z.number().describe('Line number of the task (1-based)'),\n },\n async ({ path, line }) => {\n try {\n const content = await client.readNote(path);\n const lines = content.split('\\n');\n\n if (line < 1 || line > lines.length) {\n return {\n content: [{ type: 'text', text: `Line ${line} is out of range (note has ${lines.length} lines)` }],\n isError: true,\n };\n }\n\n const targetLine = lines[line - 1];\n const match = targetLine.match(/^(\\s*-\\s+)\\[[ ]\\](\\s+.+)$/);\n\n if (!match) {\n return {\n content: [{ type: 'text', text: `Line ${line} is not an open task: \"${targetLine.trim()}\"` }],\n isError: true,\n };\n }\n\n lines[line - 1] = `${match[1]}[x]${match[2]}`;\n await client.writeNote(path, lines.join('\\n'));\n\n const taskText = match[2].trim();\n return {\n content: [{ type: 'text', text: `Completed task: \"${taskText}\" in \"${path}\"` }],\n };\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Could not complete task: ${err instanceof Error ? err.message : String(err)}` }],\n isError: true,\n };\n }\n }\n );\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { ObsidianClient } from '@/obsidian.js';\nimport { type MindCacheConfig } from '@/config.js';\nimport { today } from '@/utils/dates.js';\nimport { extractTags } from '@/utils/markdown.js';\n\nexport function registerResources(server: McpServer, client: ObsidianClient, config: MindCacheConfig): void {\n // ─── vault://today ─────────────────────────────────────────────────\n server.resource(\n 'today',\n 'vault://today',\n { description: \"Today's daily note content. Auto-updates with the current day's note.\", mimeType: 'text/markdown' },\n async (uri) => {\n try {\n const dailyPath = `${config.dailyNotes.folder}/${today()}.md`;\n const content = await client.readNote(dailyPath);\n return {\n contents: [{ uri: uri.href, text: `# Today's Daily Note (${today()})\\n\\n${content}`, mimeType: 'text/markdown' }],\n };\n } catch {\n return {\n contents: [{ uri: uri.href, text: `No daily note for today (${today()}).`, mimeType: 'text/plain' }],\n };\n }\n }\n );\n\n // ─── vault://recent ────────────────────────────────────────────────\n server.resource(\n 'recent',\n 'vault://recent',\n { description: 'Summary of recently modified notes in the vault.', mimeType: 'text/markdown' },\n async (uri) => {\n try {\n const files = await client.listFiles();\n const mdFiles = files.filter(f => f.extension === 'md').slice(0, 10);\n\n const lines = mdFiles.map((f, i) => `${i + 1}. ${f.path}`).join('\\n');\n\n return {\n contents: [{\n uri: uri.href,\n text: `# Recent Notes\\n\\n${lines}`,\n mimeType: 'text/markdown',\n }],\n };\n } catch {\n return {\n contents: [{ uri: uri.href, text: 'Could not fetch recent notes.', mimeType: 'text/plain' }],\n };\n }\n }\n );\n\n // ─── vault://tags ──────────────────────────────────────────────────\n server.resource(\n 'tags',\n 'vault://tags',\n { description: 'Tag cloud with counts from the vault.', mimeType: 'text/markdown' },\n async (uri) => {\n try {\n const files = await client.listFiles();\n const mdFiles = files.filter(f => f.extension === 'md');\n\n const tagCounts = new Map<string, number>();\n const sampleSize = Math.min(mdFiles.length, 50);\n\n for (const file of mdFiles.slice(0, sampleSize)) {\n try {\n const content = await client.readNote(file.path);\n for (const tag of extractTags(content)) {\n tagCounts.set(tag, (tagCounts.get(tag) ?? 0) + 1);\n }\n } catch {\n // Skip\n }\n }\n\n const sorted = [...tagCounts.entries()]\n .sort((a, b) => b[1] - a[1])\n .slice(0, 30);\n\n const lines = sorted.map(([tag, count]) => `- #${tag} (${count})`).join('\\n');\n\n return {\n contents: [{\n uri: uri.href,\n text: `# Vault Tags\\n\\n${lines || 'No tags found.'}`,\n mimeType: 'text/markdown',\n }],\n };\n } catch {\n return {\n contents: [{ uri: uri.href, text: 'Could not fetch tags.', mimeType: 'text/plain' }],\n };\n }\n }\n );\n\n // ─── vault://context ───────────────────────────────────────────────\n server.resource(\n 'context',\n 'vault://context',\n {\n description: 'Contextual notes relevant to the current working directory or project. Auto-infers which notes may be useful.',\n mimeType: 'text/markdown',\n },\n async (uri) => {\n try {\n const cwd = process.cwd();\n const projectName = cwd.split('/').pop() ?? '';\n\n // Search for notes related to the current project\n let results: string[] = [];\n if (projectName) {\n try {\n const searchResults = await client.search(projectName);\n results = searchResults.slice(0, 5).map(r => r.filename);\n } catch {\n // Search failed, that's ok\n }\n }\n\n if (results.length === 0) {\n return {\n contents: [{\n uri: uri.href,\n text: `# Context\\n\\nNo vault notes found related to the current project \"${projectName}\".`,\n mimeType: 'text/markdown',\n }],\n };\n }\n\n const lines = results.map((f, i) => `${i + 1}. ${f}`).join('\\n');\n return {\n contents: [{\n uri: uri.href,\n text: `# Context for \"${projectName}\"\\n\\nRelevant vault notes:\\n\\n${lines}`,\n mimeType: 'text/markdown',\n }],\n };\n } catch {\n return {\n contents: [{ uri: uri.href, text: 'Could not determine context.', mimeType: 'text/plain' }],\n };\n }\n }\n );\n}\n","const PREFIX = 'mindcache';\n\nexport function log(message: string): void {\n process.stderr.write(`[${PREFIX}] ${message}\\n`);\n}\n\nexport function logError(message: string): void {\n process.stderr.write(`[${PREFIX}] ERROR: ${message}\\n`);\n}\n\nexport function logWarn(message: string): void {\n process.stderr.write(`[${PREFIX}] WARN: ${message}\\n`);\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { type MindCacheConfig } from '@/config.js';\nimport { ObsidianClient } from '@/obsidian.js';\nimport { registerFindTools } from '@/tools/find.js';\nimport { registerReadTools } from '@/tools/read.js';\nimport { registerRememberTools } from '@/tools/remember.js';\nimport { registerJournalTools } from '@/tools/journal.js';\nimport { registerWriteTools } from '@/tools/write.js';\nimport { registerConnectTools } from '@/tools/connect.js';\nimport { registerOrganizeTools } from '@/tools/organize.js';\nimport { registerUnderstandTools } from '@/tools/understand.js';\nimport { registerTaskTools } from '@/tools/tasks.js';\nimport { registerResources } from '@/resources/index.js';\nimport { log } from '@/utils/logger.js';\n\nexport const SERVER_VERSION = '0.1.0';\n\nexport function createServer(config: MindCacheConfig): McpServer {\n const server = new McpServer(\n {\n name: 'mindcache',\n version: SERVER_VERSION,\n },\n {\n instructions: [\n 'MindCache connects your Obsidian vault to AI.',\n 'Use the search and ask tools to find information in the user\\'s personal knowledge base.',\n 'Use the remember tools to capture decisions, meetings, ideas, learnings, and references.',\n 'Use the log tool to add entries to the daily note.',\n 'Use the connect tools to build links between related notes.',\n 'Always check the vault before asking the user to repeat information they may have already documented.',\n 'When creating notes, use appropriate templates and add relevant tags.',\n ].join(' '),\n }\n );\n\n const client = new ObsidianClient(config);\n\n // Register all tool categories\n log('Registering tools...');\n registerFindTools(server, client, config);\n registerReadTools(server, client, config);\n registerRememberTools(server, client, config);\n registerJournalTools(server, client, config);\n registerWriteTools(server, client, config);\n registerConnectTools(server, client, config);\n registerOrganizeTools(server, client, config);\n registerUnderstandTools(server, client, config);\n registerTaskTools(server, client, config);\n\n // Register resources\n log('Registering resources...');\n registerResources(server, client, config);\n\n log('Server configured with 40 tools and 4 resources');\n return server;\n}\n","import { readFileSync, existsSync } from 'fs';\nimport { resolve, join } from 'path';\nimport { homedir } from 'os';\nimport { log, logWarn } from '@/utils/logger.js';\n\nexport interface MindCacheConfig {\n vault: string;\n dailyNotes: {\n folder: string;\n format: string;\n };\n templates: {\n folder: string;\n };\n inbox: {\n folder: string;\n requireReview: boolean;\n };\n}\n\nconst DEFAULT_CONFIG: MindCacheConfig = {\n vault: '',\n dailyNotes: {\n folder: 'Daily',\n format: 'YYYY-MM-DD',\n },\n templates: {\n folder: 'Templates/MindCache',\n },\n inbox: {\n folder: 'MindCache/Inbox',\n requireReview: false,\n },\n};\n\n/**\n * Simple YAML-like parser for config files.\n * Handles flat and one-level nested key: value pairs.\n */\nfunction parseSimpleYaml(content: string): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n let currentSection = '';\n\n for (const rawLine of content.split('\\n')) {\n const line = rawLine.replace(/#.*$/, '').trimEnd();\n if (!line.trim()) continue;\n\n const indent = line.length - line.trimStart().length;\n const trimmed = line.trim();\n\n const colonIdx = trimmed.indexOf(':');\n if (colonIdx < 0) continue;\n\n const key = trimmed.slice(0, colonIdx).trim();\n const value = trimmed.slice(colonIdx + 1).trim();\n\n if (indent === 0 && !value) {\n currentSection = key;\n if (!result[currentSection]) result[currentSection] = {};\n } else if (indent > 0 && currentSection) {\n (result[currentSection] as Record<string, string>)[key] = value;\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nfunction findConfigFile(): string | null {\n const candidates = [\n resolve(process.cwd(), '.mindcache.yml'),\n resolve(process.cwd(), '.mindcache.yaml'),\n join(homedir(), '.config', 'mindcache', 'config.yml'),\n join(homedir(), '.config', 'mindcache', 'config.yaml'),\n join(homedir(), '.mindcache.yml'),\n ];\n\n for (const candidate of candidates) {\n if (existsSync(candidate)) return candidate;\n }\n return null;\n}\n\nexport function loadConfig(): MindCacheConfig {\n const config: MindCacheConfig = {\n vault: DEFAULT_CONFIG.vault,\n dailyNotes: { ...DEFAULT_CONFIG.dailyNotes },\n templates: { ...DEFAULT_CONFIG.templates },\n inbox: { ...DEFAULT_CONFIG.inbox },\n };\n\n // Check environment variables first\n if (process.env.MINDCACHE_VAULT) config.vault = process.env.MINDCACHE_VAULT;\n\n // Load config file\n const configPath = process.env.MINDCACHE_CONFIG || findConfigFile();\n if (configPath && existsSync(configPath)) {\n log(`Loading config from ${configPath}`);\n try {\n const raw = readFileSync(configPath, 'utf-8');\n const parsed = parseSimpleYaml(raw);\n\n if (typeof parsed.vault === 'string') config.vault = parsed.vault;\n\n const daily = (parsed.daily_notes ?? parsed.dailyNotes) as Record<string, string> | undefined;\n if (daily) {\n if (daily.folder) config.dailyNotes.folder = daily.folder;\n if (daily.format) config.dailyNotes.format = daily.format;\n }\n\n const templates = parsed.templates as Record<string, string> | undefined;\n if (templates) {\n if (templates.folder) config.templates.folder = templates.folder;\n }\n\n const inbox = parsed.inbox as Record<string, string> | undefined;\n if (inbox) {\n if (inbox.folder) config.inbox.folder = inbox.folder;\n if (inbox.require_review) config.inbox.requireReview = inbox.require_review === 'true';\n }\n } catch (err) {\n logWarn(`Failed to parse config: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n // Resolve ~ in vault path\n if (config.vault.startsWith('~')) {\n config.vault = config.vault.replace('~', homedir());\n }\n\n return config;\n}\n","import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { createServer, SERVER_VERSION } from '@/server.js';\nimport { loadConfig } from '@/config.js';\nimport { ObsidianClient } from '@/obsidian.js';\nimport { log, logError } from '@/utils/logger.js';\nimport { writeFileSync, existsSync, mkdirSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport { createInterface } from 'readline';\n\nconst HELP = `\nMindCache v${SERVER_VERSION} — Your Obsidian vault, connected to AI.\n\nUsage:\n mindcache Start the MCP server (default)\n mindcache init Interactive setup\n mindcache doctor Diagnose connection issues\n mindcache config Show current configuration\n mindcache --help Show this help message\n mindcache --version Show version\n\nEnvironment variables:\n MINDCACHE_VAULT Path to Obsidian vault\n MINDCACHE_CONFIG Path to config file\n\nConfig file locations (checked in order):\n .mindcache.yml (current directory)\n ~/.config/mindcache/config.yml\n ~/.mindcache.yml\n\nLearn more: https://usemindcache.com\n`;\n\nasync function prompt(question: string): Promise<string> {\n const rl = createInterface({ input: process.stdin, output: process.stderr });\n return new Promise(resolve => {\n rl.question(question, answer => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\nasync function runInit(): Promise<void> {\n process.stderr.write('\\nMindCache Setup\\n');\n process.stderr.write('===============\\n\\n');\n process.stderr.write('MindCache reads your Obsidian vault directly from the filesystem.\\n');\n process.stderr.write('No plugins required — just point it at your vault folder.\\n\\n');\n\n const defaultVault = join(homedir(), 'Documents', 'Obsidian Vault');\n const vault = await prompt(`Obsidian vault path [${defaultVault}]: `) || defaultVault;\n const dailyFolder = await prompt('Daily notes folder [Daily]: ') || 'Daily';\n\n const configContent = `# MindCache Configuration\nvault: ${vault}\n\ndaily_notes:\n folder: ${dailyFolder}\n format: YYYY-MM-DD\n\ntemplates:\n folder: Templates/MindCache\n\ninbox:\n folder: MindCache/Inbox\n require_review: false\n`;\n\n const configDir = join(homedir(), '.config', 'mindcache');\n if (!existsSync(configDir)) {\n mkdirSync(configDir, { recursive: true });\n }\n\n const configPath = join(configDir, 'config.yml');\n writeFileSync(configPath, configContent);\n\n process.stderr.write(`\\nConfig saved to: ${configPath}\\n\\n`);\n\n // Test vault access\n process.stderr.write('Checking vault...\\n');\n const config = loadConfig();\n const client = new ObsidianClient(config);\n const health = await client.health();\n\n if (health.ok) {\n process.stderr.write(` Found ${health.noteCount} notes in vault\\n\\n`);\n } else {\n process.stderr.write(` ${health.error}\\n`);\n process.stderr.write(' Check that the vault path is correct.\\n\\n');\n }\n\n process.stderr.write('Add MindCache to Claude Code:\\n');\n process.stderr.write(' claude mcp add --scope user mindcache -- npx @augmnt-sh/mindcache\\n\\n');\n\n process.exit(0);\n}\n\nasync function runDoctor(): Promise<void> {\n process.stderr.write(`\\nMindCache Doctor v${SERVER_VERSION}\\n`);\n process.stderr.write('==========================\\n\\n');\n\n const config = loadConfig();\n\n // Check config\n process.stderr.write('Checking configuration...\\n');\n if (!config.vault) {\n process.stderr.write(' [WARN] No vault path configured. Run: mindcache init\\n');\n } else {\n process.stderr.write(` [OK] Vault: ${config.vault}\\n`);\n }\n\n process.stderr.write(` [OK] Daily notes: ${config.dailyNotes.folder}/\\n`);\n process.stderr.write(` [OK] Templates: ${config.templates.folder}/\\n`);\n process.stderr.write(` [OK] Inbox: ${config.inbox.folder}/\\n`);\n\n // Check vault access\n process.stderr.write('\\nChecking vault access...\\n');\n const client = new ObsidianClient(config);\n const health = await client.health();\n\n if (health.ok) {\n process.stderr.write(` [OK] Vault readable\\n`);\n process.stderr.write(` [OK] Found ${health.noteCount} markdown notes\\n`);\n } else {\n process.stderr.write(` [FAIL] ${health.error}\\n`);\n process.stderr.write('\\n Troubleshooting:\\n');\n process.stderr.write(' 1. Check that the vault path is correct\\n');\n process.stderr.write(' 2. Check file permissions\\n');\n process.stderr.write(' 3. Run: mindcache init\\n');\n }\n\n process.stderr.write('\\n');\n process.exit(health.ok ? 0 : 1);\n}\n\nfunction showConfig(): void {\n const config = loadConfig();\n process.stderr.write(`\\nMindCache Configuration\\n`);\n process.stderr.write('=======================\\n\\n');\n process.stderr.write(`Vault: ${config.vault || '(not set)'}\\n`);\n process.stderr.write(`Daily folder: ${config.dailyNotes.folder}\\n`);\n process.stderr.write(`Daily format: ${config.dailyNotes.format}\\n`);\n process.stderr.write(`Templates: ${config.templates.folder}\\n`);\n process.stderr.write(`Inbox: ${config.inbox.folder}\\n`);\n process.stderr.write(`Review mode: ${config.inbox.requireReview ? 'on' : 'off'}\\n`);\n process.stderr.write('\\n');\n process.exit(0);\n}\n\nasync function startServer(): Promise<void> {\n const nodeVersion = process.version;\n const nodeMajor = parseInt(nodeVersion.slice(1));\n if (nodeMajor < 18) {\n logError(`Node.js >= 18 required, found ${nodeVersion}`);\n process.exit(1);\n }\n\n log(`mindcache v${SERVER_VERSION} | Node ${nodeVersion} | ${process.platform}`);\n\n const config = loadConfig();\n\n if (!config.vault) {\n log('WARN: No vault path configured. Run \"mindcache init\" for setup.');\n }\n\n const server = createServer(config);\n const transport = new StdioServerTransport();\n\n const shutdown = async () => {\n log('Shutting down...');\n await server.close();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n await server.connect(transport);\n}\n\n// Parse CLI arguments\nconst command = process.argv[2];\n\nswitch (command) {\n case 'init':\n runInit().catch(err => {\n logError(err instanceof Error ? err.message : String(err));\n process.exit(1);\n });\n break;\n case 'doctor':\n runDoctor().catch(err => {\n logError(err instanceof Error ? err.message : String(err));\n process.exit(1);\n });\n break;\n case 'config':\n showConfig();\n break;\n case '--version':\n case '-v':\n process.stderr.write(`mindcache v${SERVER_VERSION}\\n`);\n process.exit(0);\n break;\n case '--help':\n case '-h':\n process.stderr.write(HELP);\n process.exit(0);\n break;\n default:\n startServer().catch(err => {\n logError(`Fatal: ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n });\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@augmnt-sh/mindcache",
3
+ "version": "0.1.0",
4
+ "description": "Your Obsidian vault, connected to AI. MCP server for bridging personal knowledge with LLMs.",
5
+ "type": "module",
6
+ "bin": {
7
+ "mindcache": "./dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "templates",
12
+ "README.md",
13
+ "LICENSE",
14
+ "CHANGELOG.md"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsup",
18
+ "dev": "tsup --watch",
19
+ "start": "node dist/cli.js",
20
+ "lint": "tsc --noEmit",
21
+ "test": "vitest run",
22
+ "test:watch": "vitest",
23
+ "test:coverage": "vitest run --coverage",
24
+ "clean": "rm -rf dist",
25
+ "postbuild": "chmod +x dist/cli.js",
26
+ "prepublishOnly": "npm run build"
27
+ },
28
+ "dependencies": {
29
+ "@modelcontextprotocol/sdk": "^1.12.0",
30
+ "zod": "^3.23.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^20.0.0",
34
+ "tsup": "^8.0.0",
35
+ "typescript": "^5.4.0",
36
+ "vitest": "^3.2.4"
37
+ },
38
+ "engines": {
39
+ "node": ">=18.0.0"
40
+ },
41
+ "exports": {
42
+ ".": {
43
+ "types": "./dist/cli.d.ts",
44
+ "import": "./dist/cli.js"
45
+ }
46
+ },
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "https://github.com/augmnt/mindcache",
50
+ "directory": "packages/server"
51
+ },
52
+ "keywords": [
53
+ "mcp",
54
+ "model-context-protocol",
55
+ "obsidian",
56
+ "claude",
57
+ "ai",
58
+ "knowledge-base",
59
+ "second-brain",
60
+ "rag",
61
+ "personal-knowledge",
62
+ "note-taking"
63
+ ],
64
+ "author": "augmnt",
65
+ "license": "MIT",
66
+ "homepage": "https://usemindcache.com",
67
+ "publishConfig": {
68
+ "access": "public"
69
+ }
70
+ }
@@ -0,0 +1,29 @@
1
+ ---
2
+ date: {{date}}
3
+ type: article
4
+ source: {{source}}
5
+ url: {{url}}
6
+ tags:
7
+ - article
8
+ ---
9
+
10
+ # {{title}}
11
+
12
+ **Source:** {{source}}
13
+ **URL:** {{url}}
14
+
15
+ ## Summary
16
+
17
+ {{summary}}
18
+
19
+ ## Key Takeaways
20
+
21
+ {{takeaways}}
22
+
23
+ ## My Thoughts
24
+
25
+ {{thoughts}}
26
+
27
+ ## Related
28
+
29
+ {{related}}
@@ -0,0 +1,32 @@
1
+ ---
2
+ date: {{date}}
3
+ type: book
4
+ author: {{author}}
5
+ rating: {{rating}}
6
+ tags:
7
+ - book
8
+ ---
9
+
10
+ # {{title}}
11
+
12
+ **Author:** {{author}}
13
+
14
+ ## Summary
15
+
16
+ {{summary}}
17
+
18
+ ## Key Ideas
19
+
20
+ {{key_ideas}}
21
+
22
+ ## Favorite Quotes
23
+
24
+ {{quotes}}
25
+
26
+ ## How It Changed My Thinking
27
+
28
+ {{impact}}
29
+
30
+ ## Related
31
+
32
+ {{related}}
@@ -0,0 +1,29 @@
1
+ ---
2
+ date: {{date}}
3
+ type: decision
4
+ status: accepted
5
+ tags:
6
+ - decision
7
+ ---
8
+
9
+ # {{title}}
10
+
11
+ ## Context
12
+
13
+ {{context}}
14
+
15
+ ## Decision
16
+
17
+ {{decision}}
18
+
19
+ ## Consequences
20
+
21
+ {{consequences}}
22
+
23
+ ## Alternatives Considered
24
+
25
+ {{alternatives}}
26
+
27
+ ## Related
28
+
29
+ {{related}}
@@ -0,0 +1,25 @@
1
+ ---
2
+ date: {{date}}
3
+ type: idea
4
+ status: seed
5
+ tags:
6
+ - idea
7
+ ---
8
+
9
+ # {{title}}
10
+
11
+ ## The Idea
12
+
13
+ {{idea}}
14
+
15
+ ## Why It Matters
16
+
17
+ {{why}}
18
+
19
+ ## Next Steps
20
+
21
+ {{next_steps}}
22
+
23
+ ## Related
24
+
25
+ {{related}}
@@ -0,0 +1,29 @@
1
+ ---
2
+ date: {{date}}
3
+ type: learning
4
+ source: {{source}}
5
+ tags:
6
+ - learning
7
+ ---
8
+
9
+ # {{title}}
10
+
11
+ ## Concept
12
+
13
+ {{concept}}
14
+
15
+ ## Key Points
16
+
17
+ {{key_points}}
18
+
19
+ ## Examples
20
+
21
+ {{examples}}
22
+
23
+ ## How I'll Use This
24
+
25
+ {{application}}
26
+
27
+ ## Related
28
+
29
+ {{related}}
@@ -0,0 +1,29 @@
1
+ ---
2
+ date: {{date}}
3
+ type: meeting
4
+ attendees: {{attendees}}
5
+ tags:
6
+ - meeting
7
+ ---
8
+
9
+ # {{title}}
10
+
11
+ ## Attendees
12
+
13
+ {{attendees}}
14
+
15
+ ## Agenda
16
+
17
+ {{agenda}}
18
+
19
+ ## Notes
20
+
21
+ {{notes}}
22
+
23
+ ## Action Items
24
+
25
+ {{action_items}}
26
+
27
+ ## Follow Up
28
+
29
+ {{follow_up}}
@@ -0,0 +1,30 @@
1
+ ---
2
+ date: {{date}}
3
+ type: person
4
+ role: {{role}}
5
+ organization: {{organization}}
6
+ tags:
7
+ - person
8
+ ---
9
+
10
+ # {{name}}
11
+
12
+ ## About
13
+
14
+ - **Role:** {{role}}
15
+ - **Organization:** {{organization}}
16
+ - **Contact:** {{contact}}
17
+
18
+ ## Context
19
+
20
+ {{context}}
21
+
22
+ ## Interactions
23
+
24
+ ### {{date}}
25
+
26
+ {{interaction}}
27
+
28
+ ## Notes
29
+
30
+ {{notes}}
@@ -0,0 +1,33 @@
1
+ ---
2
+ date: {{date}}
3
+ type: project
4
+ status: active
5
+ tags:
6
+ - project
7
+ ---
8
+
9
+ # {{title}}
10
+
11
+ ## Overview
12
+
13
+ {{overview}}
14
+
15
+ ## Goals
16
+
17
+ {{goals}}
18
+
19
+ ## Status
20
+
21
+ {{status}}
22
+
23
+ ## Key Decisions
24
+
25
+ {{decisions}}
26
+
27
+ ## Open Questions
28
+
29
+ {{questions}}
30
+
31
+ ## Links
32
+
33
+ {{links}}
@@ -0,0 +1,31 @@
1
+ ---
2
+ date: {{date}}
3
+ type: session
4
+ project: {{project}}
5
+ tags:
6
+ - session
7
+ ---
8
+
9
+ # Session - {{date}}
10
+
11
+ **Project:** {{project}}
12
+
13
+ ## What I Built
14
+
15
+ {{built}}
16
+
17
+ ## Decisions Made
18
+
19
+ {{decisions}}
20
+
21
+ ## Blockers / Issues
22
+
23
+ {{blockers}}
24
+
25
+ ## What's Next
26
+
27
+ {{next}}
28
+
29
+ ## Related
30
+
31
+ {{related}}
@@ -0,0 +1,34 @@
1
+ ---
2
+ date: {{date}}
3
+ type: weekly-review
4
+ week: {{week}}
5
+ tags:
6
+ - review
7
+ - weekly
8
+ ---
9
+
10
+ # Weekly Review - {{date}}
11
+
12
+ ## Wins
13
+
14
+ {{wins}}
15
+
16
+ ## Challenges
17
+
18
+ {{challenges}}
19
+
20
+ ## Learnings
21
+
22
+ {{learnings}}
23
+
24
+ ## Next Week's Priorities
25
+
26
+ {{priorities}}
27
+
28
+ ## Open Questions
29
+
30
+ {{questions}}
31
+
32
+ ## Gratitude
33
+
34
+ {{gratitude}}