viteboard 0.2.0 → 0.2.1

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.
@@ -0,0 +1,97 @@
1
+ var Cs=Object.defineProperty;var ks=(s,t,e)=>t in s?Cs(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e;var m=(s,t,e)=>ks(s,typeof t!="symbol"?t+"":t,e);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))n(o);new MutationObserver(o=>{for(const i of o)if(i.type==="childList")for(const a of i.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&n(a)}).observe(document,{childList:!0,subtree:!0});function e(o){const i={};return o.integrity&&(i.integrity=o.integrity),o.referrerPolicy&&(i.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?i.credentials="include":o.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function n(o){if(o.ep)return;o.ep=!0;const i=e(o);fetch(o.href,i)}})();const N="/__api",Do=Ss();function Es(){return Do}function Ss(){return typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID():`ui-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`}class xe extends Error{constructor(e,n){super(e);m(this,"currentRevision");this.name="RevisionConflictError",this.currentRevision=n}}async function z(s){var t;if(!s.ok){let e="";try{e=((t=await s.json())==null?void 0:t.error)??""}catch{}throw new Error(`${s.status} ${s.statusText}${e?` — ${e}`:""}`)}return s.json()}function j(s={}){const t=new Headers(s.headers);return t.set("X-ViteBoard-Actor-Id",Do),t.set("X-ViteBoard-Actor-Type","human"),t.set("X-ViteBoard-Actor-Label","ViteBoard UI"),{...s,headers:t}}const k={async getWorkspace(){return z(await fetch(`${N}/workspace`,j()))},async removeProject(s){await z(await fetch(`${N}/workspace/project?id=${encodeURIComponent(s)}`,j({method:"DELETE"})))},async pickAndAddProject(){return z(await fetch(`${N}/workspace/pick-project`,j({method:"POST"})))},async addProject(s,t){return z(await fetch(`${N}/workspace/project`,j({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({rootPath:s,label:t})})))},async ensureProjectDocsRoot(s){return(await z(await fetch(`${N}/workspace/project/docs-root`,j({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectId:s})})))).root},async getTree(s){return(await z(await fetch(`${N}/tree?rootId=${encodeURIComponent(s)}`,j()))).tree},async getProjectTree(s){return(await z(await fetch(`${N}/project-tree?projectId=${encodeURIComponent(s)}`,j()))).tree},async getCapabilities(s){const t=s?`?rootId=${encodeURIComponent(s)}`:"";return(await z(await fetch(`${N}/capabilities${t}`,j()))).capabilities},async getCapability(s,t){return z(await fetch(`${N}/capability?rootId=${encodeURIComponent(s)}&path=${encodeURIComponent(t)}`,j()))},async createDocsFolder(s,t){await z(await fetch(`${N}/workspace/project/create-docs-folder`,j({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({projectId:s,parentPath:t})})))},async readFile(s,t){return(await z(await fetch(`${N}/file?rootId=${encodeURIComponent(s)}&path=${encodeURIComponent(t)}`,j()))).content},async readFileWithRevision(s,t){return z(await fetch(`${N}/file?rootId=${encodeURIComponent(s)}&path=${encodeURIComponent(t)}`,j()))},async writeFile(s,t,e,n){const o=await fetch(`${N}/file`,j({method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({rootId:s,path:t,content:e,expectedRevision:n})}));if(o.status===409){const a=await o.json();throw new xe(a.error??"File changed on disk",a.currentRevision??null)}return(await z(o)).revision},async createDirectory(s,t){await z(await fetch(`${N}/directory`,j({method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({rootId:s,path:t})})))},async getBoard(s,t){const e=await fetch(`${N}/board?rootId=${encodeURIComponent(s)}&id=${encodeURIComponent(t)}`,j());return e.status===404?null:(await z(e)).doc},async getBoardWithRevision(s,t){const e=await fetch(`${N}/board?rootId=${encodeURIComponent(s)}&id=${encodeURIComponent(t)}`,j());return e.status===404?null:z(e)},async saveBoard(s,t,e,n){const o=await fetch(`${N}/board`,j({method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify({rootId:s,id:t,doc:e,expectedRevision:n})}));if(o.status===409){const a=await o.json();throw new xe(a.error??"Board changed on disk",a.currentRevision??null)}return(await z(o)).revision},async deleteFile(s,t){await z(await fetch(`${N}/file?rootId=${encodeURIComponent(s)}&path=${encodeURIComponent(t)}`,j({method:"DELETE"})))},async renameFile(s,t,e,n=!1){await z(await fetch(`${N}/file`,j({method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({rootId:s,oldPath:t,newPath:e,ignoreMissing:n})})))},async deleteBoard(s,t){await z(await fetch(`${N}/board?rootId=${encodeURIComponent(s)}&id=${encodeURIComponent(t)}`,j({method:"DELETE"})))},assetUrl(s,t){return`${N}/asset?rootId=${encodeURIComponent(s)}&path=${encodeURIComponent(t)}`},async uploadAsset(s,t,e,n){return(await z(await fetch(`${N}/asset`,j({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({rootId:s,name:t,base64:e,mimeType:n})})))).path},async cleanupManagedAssets(s,t=[]){return(await z(await fetch(`${N}/asset/cleanup`,j({method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({rootId:s,preservePaths:t})})))).removed}};function Ts(s,t){const e=s.find(i=>i.type==="dir"&&i.name===t);if(!e||e.type!=="dir")return[];const n=[],o=i=>{for(const a of i)a.type==="file"?n.push(a):o(a.children)};return o(e.children),n}function gn(s){for(const t of s){if(t.type==="file"&&t.name.endsWith(".md"))return t.path;if(t.type==="dir"){const e=gn(t.children);if(e)return e}}return null}function Bt(s){const t=[];for(const e of s.replace(/\\/g,"/").split("/")){const n=e.trim();if(!(!n||n===".")){if(n===".."){t.length>0&&t.pop();continue}t.push(n)}}return t.join("/")}function Ao(s){const t=Bt(s),e=t.lastIndexOf("/");return e===-1?"":t.slice(0,e)}function Bs(s,t){if(/^(https?:|mailto:|tel:|#|data:)/.test(t))return t;if(t.startsWith("/"))return Bt(t);const e=Ao(s);return Bt(e?`${e}/${t}`:t)}function Tn(s,t){const e=Ao(s),n=e?e.split("/").filter(Boolean):[],o=Bt(t).split("/").filter(Boolean);let i=0;for(;i<n.length&&i<o.length&&n[i]===o[i];)i++;const a=n.slice(i).map(()=>".."),r=o.slice(i);return[...a,...r].join("/")||o[o.length-1]||""}const Ms=["sticky","task","rectangle","ellipse","text","line","arrow","connector","image","screenshot","frame","templateGroup"];function Ie(s){const t=new Set;for(const e of s.elements){const n=e.data.assetId;typeof n=="string"&&t.add(n)}return{...s.schemaUrl?{$schema:s.schemaUrl}:{},version:1,id:s.boardId,title:s.title,createdAt:s.createdAt,updatedAt:Date.now(),viewport:{...s.viewport},theme:s.theme,elements:s.elements,assetIds:[...t]}}function it(s){return typeof s=="number"&&Number.isFinite(s)}function No(s){if(typeof s!="object"||s===null)return null;const t=s;return typeof t.id!="string"||typeof t.type!="string"||!Ms.includes(t.type)||!it(t.x)||!it(t.y)||!it(t.width)||!it(t.height)?null:{id:t.id,type:t.type,x:t.x,y:t.y,width:t.width,height:t.height,rotation:it(t.rotation)?t.rotation:0,zIndex:it(t.zIndex)?t.zIndex:0,locked:t.locked===!0,hidden:t.hidden===!0,createdAt:it(t.createdAt)?t.createdAt:Date.now(),updatedAt:it(t.updatedAt)?t.updatedAt:Date.now(),style:typeof t.style=="object"&&t.style!==null?t.style:{},data:typeof t.data=="object"&&t.data!==null?t.data:{}}}function oe(s){if(typeof s!="object"||s===null)return null;const t=s;if(t.version!==1||typeof t.id!="string"||!Array.isArray(t.elements))return null;const e=[];for(const o of t.elements){const i=No(o);i&&e.push(i)}const n=t.viewport??{};return{...typeof t.$schema=="string"?{$schema:t.$schema}:{},version:1,id:t.id,title:typeof t.title=="string"?t.title.slice(0,200):"Imported Board",createdAt:it(t.createdAt)?t.createdAt:Date.now(),updatedAt:it(t.updatedAt)?t.updatedAt:Date.now(),viewport:{offsetX:it(n.offsetX)?n.offsetX:0,offsetY:it(n.offsetY)?n.offsetY:0,scale:it(n.scale)&&n.scale>.01&&n.scale<=40?n.scale:1},theme:t.theme==="dark"?"dark":"light",elements:e,assetIds:Array.isArray(t.assetIds)?t.assetIds.filter(o=>typeof o=="string"):[]}}const Is="/board-v1.schema.json",Rs=".board.json";function rt(s){return s.replace(/\.board\.json$/,"")}function Ls(s){return s.trim().replace(/^\/+/,"").replace(/\.board\.json$/,"")}function Ps(s,t){return Te(s,t)[0]??""}function Te(s,t){const e=s.trim(),n=Ls(s);if(!n)return[];if(e.startsWith("./")||e.startsWith("../")){const r=t.lastIndexOf("/"),c=r===-1?"":t.slice(0,r);return[Bt(c?`${c}/${n}`:n)]}if(e.startsWith("/")){const r=t.lastIndexOf("/"),c=r===-1?"":t.slice(0,r),l=Bt(c?`${c}/${n}`:n),d=[n];if(l&&l!==n&&d.push(l),c){const h=c.includes("/")?c.slice(0,c.lastIndexOf("/")):"",p=Bt(h?`${h}/${n}`:n);p&&!d.includes(p)&&d.push(p)}return d}const o=t.lastIndexOf("/"),i=o===-1?"":t.slice(0,o),a=Bt(i?`${i}/${n}`:n);return a&&a!==n?[a,n]:[n]}function jn(s){return s.toLowerCase().replace(/[^\w\s-]/g,"").trim().replace(/\s+/g,"-").slice(0,48)||"board"}function $s(s){return new Promise((t,e)=>{const n=new FileReader;n.onload=()=>{const o=n.result;t(o.slice(o.indexOf(",")+1))},n.onerror=()=>e(n.error),n.readAsDataURL(s)})}const dt={async listIds(s){const t=await k.getTree(s);return Ds(t).map(e=>rt(e.path))},async list(s){const t=await this.listIds(s),e=[];for(const n of t){const o=await this.load(s,n);o&&e.push({id:n,title:o.title,elementCount:o.elements.length,updatedAt:o.updatedAt,filePath:`${n}.board.json`})}return e.sort((n,o)=>o.updatedAt-n.updatedAt),e},async load(s,t){const e=await k.getBoard(s,t);if(e)return oe(e)??void 0},async save(s,t){await k.saveBoard(s,t.id,t)},async delete(s,t){await k.deleteBoard(s,t)},async move(s,t,e){const n=await this.load(s,t);if(!n)throw new Error("Board not found");const o=t.split("/").pop()??t,i=e.replace(/^\/+|\/+$/g,""),a=i?`${i}/${o}`:o;if(a===t)return t;if(new Set(await this.listIds(s)).has(a))throw new Error("A board already exists there");const c=Date.now();return await k.saveBoard(s,a,{...n,id:a,updatedAt:c},null),await k.deleteBoard(s,t),a},async rename(s,t,e){const n=await k.getBoardWithRevision(s,t),o=n&&oe(n.doc);if(!n||!o)throw new Error("Board not found");const i=t.includes("/")?t.slice(0,t.lastIndexOf("/")):"",a=jn(e),r=i?`${i}/${a}`:a,c=Date.now();if(r===t)return await k.saveBoard(s,t,{...o,title:e.trim()||o.title,updatedAt:c},n.revision),t;if(new Set(await this.listIds(s)).has(r))throw new Error("A board already exists with that name");return await k.saveBoard(s,r,{...o,id:r,title:e.trim()||o.title,updatedAt:c},null),await k.deleteBoard(s,t),r},async create(s,t,e,n=""){const o=new Set(await this.listIds(s)),i=jn(t);let r=`${n?`${n.replace(/^\/+|\/+$/g,"")}/`:""}${i}`;o.has(r)&&(r=`${r}-${Date.now().toString(36)}`);const c=Date.now(),l={$schema:Is,version:1,id:r,title:t.trim()||"Untitled Board",createdAt:c,updatedAt:c,viewport:{offsetX:0,offsetY:0,scale:1},theme:e,elements:[],assetIds:[]};return await k.saveBoard(s,r,l,null),r},async uploadImage(s,t,e){const n=await $s(t);return k.uploadAsset(s,e??"image.png",n,t.type)},async cleanupUnusedAssets(s,t=[]){return k.cleanupManagedAssets(s,t)}};function Ds(s){const t=[],e=n=>{for(const o of n)o.type==="file"?o.name.endsWith(Rs)&&t.push(o):e(o.children)};return e(s),t}const As=new Set(["capabilities","assets"]);class Ns{constructor(t,e){m(this,"element");m(this,"header");m(this,"nav");m(this,"footer");m(this,"links",new Map);m(this,"collapsibles",new Map);m(this,"collapsedState",new Map);m(this,"callbacks");m(this,"contextMenu");m(this,"draggedItem");m(this,"dropExpandTimer");m(this,"dropExpandTarget");m(this,"lastWorkspace",{projects:[]});m(this,"lastTreesByRoot",new Map);m(this,"lastTreesByProject",new Map);m(this,"rawModeProjects",new Set);m(this,"lastActiveHash","");m(this,"forceNextActiveSync",!0);this.callbacks=e,this.element=document.createElement("aside"),this.element.className="sidebar",this.header=document.createElement("div"),this.header.className="sidebar-header";const n=document.createElement("a");n.className="sidebar-brand",n.href="#/",n.textContent="ViteBoard",this.header.appendChild(n),this.nav=document.createElement("nav"),this.nav.className="sidebar-nav",this.footer=document.createElement("div"),this.footer.className="sidebar-footer";const o=document.createElement("button");o.className="sidebar-add-repo",o.type="button",o.textContent="Add Repo",o.title="Add a local project root",o.addEventListener("click",()=>this.callbacks.onAddRepo()),this.footer.appendChild(o),this.element.append(this.header,this.nav,this.footer),t.appendChild(this.element),document.addEventListener("pointerdown",i=>{this.contextMenu&&(this.contextMenu.contains(i.target)||this.closeContextMenu())},!0)}refresh(t,e,n){this.lastWorkspace=t,this.lastTreesByRoot=e,n&&(this.lastTreesByProject=n),this.render()}render(){const t=this.lastWorkspace,e=this.lastTreesByRoot;if(this.lastTreesByProject,this.nav.replaceChildren(),this.links.clear(),this.collapsibles.clear(),t.projects.length===0){const o=document.createElement("div");o.className="nav-group",o.appendChild(this.groupLabel("Workspace"));const i=document.createElement("div");i.className="nav-label nav-empty-copy",i.textContent="Add a project root to discover docs folders.",o.appendChild(i),this.nav.appendChild(o)}else for(const o of t.projects)this.nav.appendChild(this.projectSection(o,e));const n=document.createElement("div");n.className="nav-group",n.appendChild(this.groupLabel("System")),n.appendChild(this.link("#/tokens","Tokens","tokens-root")),this.nav.appendChild(n),this.setActive(location.hash,{forceSyncAncestors:this.forceNextActiveSync}),this.forceNextActiveSync=!1}setActive(t,e={}){var o,i;for(const a of new Set(this.links.values()))a.classList.remove("active");const n=this.links.get(t);if(n)n.classList.add("active");else if(t.startsWith("#/root/")){const a=t.match(/^#\/root\/([^/]+)\/(boards|capabilities|docs)(?:\/(.+))?$/);if(a){const[,r,c]=a,l=decodeURIComponent(r);c==="boards"?(o=this.links.get(Ws(l)))==null||o.classList.add("active"):c==="capabilities"&&((i=this.links.get(Os(l)))==null||i.classList.add("active"))}}(e.forceSyncAncestors||t!==this.lastActiveHash)&&this.syncCollapsed(t),this.lastActiveHash=t}toggleRawMode(t){this.rawModeProjects.has(t)?this.rawModeProjects.delete(t):this.rawModeProjects.add(t),this.forceNextActiveSync=!0,this.render()}syncCollapsed(t){const e=this.ancestorKeys(t);for(const n of e)this.applyCollapsed(n,!1)}ancestorKeys(t){const e=new Set,n=t.match(/^#\/project\/([^/]+)(?:\/boards)?$/);if(n)return e.add(decodeURIComponent(n[1])),e;const o=t.match(/^#\/root\/([^/]+)\/(docs|boards|capabilities)(?:\/(.+))?$/);if(!o)return e;const i=decodeURIComponent(o[1]),a=o[2],r=o[3]?decodeURIComponent(o[3]):"";let c,l;for(const p of this.lastWorkspace.projects){const u=p.docsRoots.find(g=>g.id===i);if(u){c=p.id,l=u.displayPath;break}}if(!c||!l)return e;e.add(c),e.add(i);const d=l.split("/").filter(Boolean).slice(0,-1);let h="";for(const p of d){h=h?`${h}/${p}`:p;const u=`folder:${c}:${h}`;this.collapsibles.has(u)&&e.add(u)}if((a==="docs"||a==="capabilities")&&r){const u=(a==="capabilities"?`capabilities/${r}`:r).split("/");for(let g=1;g<u.length;g++){const b=u.slice(0,g).join("/"),y=`doc:${i}:${b}`;this.collapsibles.has(y)&&e.add(y)}}return e}projectSection(t,e){const{id:n,label:o,docsRoots:i}=t,a=this.rawModeProjects.has(n),r=document.createElement("div");r.className="nav-repo-body";const c=document.createElement("div");c.className="nav-group nav-repo-group";const l=document.createElement("div");l.className="nav-repo-header-row";const d=document.createElement("button");d.className="nav-repo-header",d.type="button";const h=document.createElement("span");h.className="nav-repo-chevron",h.textContent="›";const p=document.createElement("span");p.className="nav-repo-label-text",p.textContent=o;const u=!a&&i.find(v=>Mt(v.displayPath)==="docs"),g=document.createElement("span");g.className="nav-tree-badge",g.textContent="DOCS",g.hidden=!u;const b=document.createElement("button");b.className="nav-repo-more",b.type="button",b.title="Project options",b.innerHTML='<svg viewBox="0 0 16 16" width="14" height="14" fill="currentColor"><circle cx="8" cy="3" r="1.3"/><circle cx="8" cy="8" r="1.3"/><circle cx="8" cy="13" r="1.3"/></svg>',b.addEventListener("click",v=>{v.stopPropagation();const E=b.getBoundingClientRect();this.showContextMenu(E.right+4,E.top,o,[{icon:a?Dt:Vt,iconClass:a?"nav-ctx-doc":"nav-ctx-dir",label:a?"View: Docs":"View: Raw",action:()=>this.toggleRawMode(n)},{icon:Ue,iconClass:"nav-ctx-edit",label:"Wiki",action:()=>{location.hash=`#/project/${encodeURIComponent(n)}`}},{kind:"divider"},{icon:Dt,iconClass:"nav-ctx-doc",label:"New Doc",action:()=>this.callbacks.onCreateProjectDoc(n)},{icon:Yt,iconClass:"nav-ctx-board",label:"New Board",action:()=>this.callbacks.onCreateProjectBoard(n)},{icon:Vt,iconClass:"nav-ctx-dir",label:"New Directory",action:()=>this.callbacks.onCreateProjectDirectory(n)},{kind:"divider"},{icon:ue,iconClass:"nav-ctx-delete",label:"Remove from workspace",action:()=>this.callbacks.onRemoveProject(n,o),danger:!0}])}),d.append(h,p,g),l.append(d,b),this.registerCollapsible(n,r,c,d,!0),d.addEventListener("click",()=>this.toggleCollapsible(n)),l.addEventListener("contextmenu",v=>{v.preventDefault(),v.stopPropagation(),b.click()});const y=Xs(t,this.lastTreesByProject.get(n)??[],e),x=a?y:bn(_e(y));if(x.length===0){const v=document.createElement("div");v.className="nav-label nav-empty-copy",v.textContent="No folders found.",r.appendChild(v)}else r.appendChild(this.renderCanonicalNodes(t,x,0,a));return c.append(l,r),c}renderCanonicalNodes(t,e,n,o){const i=document.createElement("div");for(const a of Ys(e)){if(a.kind==="doc"||a.kind==="board"||a.kind==="capability"||a.kind==="file"){i.appendChild(this.renderCanonicalFile(a,n));continue}const r=document.createElement("div");r.className="nav-tree-group",r.style.setProperty("--tree-depth",String(n));const c=document.createElement("div");c.className="nav-tree-children",c.style.setProperty("--tree-depth",String(n+1));const l=document.createElement("button");l.className="nav-tree-row nav-tree-folder"+(a.kind==="docsRoot"?" nav-tree-docs-root":"")+(a.docsContainerRoot?" nav-tree-docs-container":"")+(a.root?"":" nav-tree-scaffold"),l.type="button",l.style.setProperty("--tree-depth",String(n));const d=document.createElement("span");d.className="nav-repo-chevron",d.textContent="›";const h=Vs(a);h&&l.classList.add("nav-tree-capability-folder");const p=document.createElement("span");if(p.textContent=a.name,l.appendChild(d),h&&l.insertAdjacentHTML("beforeend",en),l.appendChild(p),a.kind==="docsRoot"||a.docsContainerRoot){const g=document.createElement("span");g.className="nav-tree-badge",g.textContent="DOCS",l.appendChild(g)}const u=a.kind==="docsRoot"||a.docsContainerRoot?(a.docsContainerRoot??a.root).id:a.root?`doc:${a.root.id}:${a.contentPath??""}`:`folder:${t.id}:${a.projectPath}`;if(this.registerCollapsible(u,c,r,l,!0),l.addEventListener("click",()=>this.toggleCollapsible(u)),a.kind==="docsRoot"||a.docsContainerRoot){const g=a.docsContainerRoot??a.root;l.addEventListener("contextmenu",b=>{b.preventDefault(),b.stopPropagation(),this.openDirContextMenu(b.clientX,b.clientY,g,"")}),this.enableDirectoryDropTarget(r,g.id,"")}else if(a.root){const g=a.root,b=a.contentPath??"";this.enableDragSource(l,{kind:"dir",rootId:g.id,path:b}),this.enableDirectoryDropTarget(r,g.id,b),r.addEventListener("contextmenu",y=>{y.preventDefault(),y.stopPropagation(),this.openDirContextMenu(y.clientX,y.clientY,g,b)})}else l.addEventListener("contextmenu",g=>{g.preventDefault(),g.stopPropagation(),this.showContextMenu(g.clientX,g.clientY,a.name,[{icon:Vt,iconClass:"nav-ctx-dir",label:"Create docs folder here",action:()=>this.callbacks.onCreateDocsFolder(t.id,a.projectPath)}])});c.appendChild(this.renderCanonicalNodes(t,a.children,n+1,o)),r.append(l,c),i.appendChild(r)}return i}renderCanonicalFile(t,e){if(t.kind==="file"){if(t.root&&t.contentPath&&Ce(t.contentPath)){const l=document.createElement("button");return l.className="nav-link nav-tree-row nav-tree-file nav-tree-capability-file",l.type="button",l.style.setProperty("--tree-depth",String(e)),l.insertAdjacentHTML("afterbegin",nn),l.appendChild(document.createTextNode(t.name)),l.addEventListener("click",d=>{d.preventDefault(),this.callbacks.onOpenTextFile(t.root.id,t.contentPath)}),l.addEventListener("contextmenu",d=>{d.preventDefault(),d.stopPropagation(),this.openTextFileContextMenu(d.clientX,d.clientY,t.root,t.contentPath)}),l}const c=document.createElement("div");return c.className="nav-tree-row nav-tree-file",c.style.setProperty("--tree-depth",String(e)),c.textContent=t.name,c}const n=t.root,o=t.contentPath,i=t.kind==="doc"?Hn(n.id,o):t.kind==="board"?Wn(n.id,rt(o)):Us(n.id,o),a=t.kind==="doc"&&t.name==="index.md"?"Overview":qt(t.kind==="board"?rt(t.name):t.name),r=this.link(i,a,`${t.kind}:${n.id}:${o}`);return r.classList.add("nav-tree-row",`nav-tree-${t.kind}`),r.style.setProperty("--tree-depth",String(e)),r.insertAdjacentHTML("afterbegin",t.kind==="board"?Yt:t.kind==="capability"?en:Dt),this.enableDragSource(r,t.kind==="board"?{kind:"board",rootId:n.id,boardId:rt(o)}:t.kind==="capability"?{kind:"capability",rootId:n.id,path:o}:{kind:"doc",rootId:n.id,path:o}),r.addEventListener("contextmenu",c=>{c.preventDefault(),c.stopPropagation(),t.kind==="board"?this.openBoardContextMenu(c.clientX,c.clientY,n,rt(o)):t.kind==="doc"&&this.openDocContextMenu(c.clientX,c.clientY,n,o)}),r}renderBrowseNode(t,e,n){if(e.type==="file"){const p=document.createElement("div");return p.className="nav-browse-file",p.textContent=e.name,p}if(e.name==="docs"){const p=t.docsRoots.find(u=>u.displayPath===e.path||u.displayPath.endsWith("/"+e.path));if(p){const u=n.get(p.id)??[];return this.docsRootSection(p,u)}}const i=jo(e),a=`browse:${t.id}:${e.path}`,r=document.createElement("div");r.className=i?"nav-subgroup nav-collapsible-dir":"nav-subgroup nav-browse-dir";const c=document.createElement("div");c.className="nav-dir-body";const l=document.createElement("button");l.className=i?"nav-dir-toggle nav-dir-project":"nav-browse-dir-toggle",l.type="button";const d=document.createElement("span");d.className="nav-repo-chevron",d.textContent="›";const h=document.createElement("span");if(h.textContent=e.name,l.append(d,h),l.addEventListener("click",()=>this.toggleCollapsible(a)),i){const p=t.docsRoots.find(u=>u.displayPath.startsWith(e.path+"/")||u.displayPath===e.path);p&&l.addEventListener("contextmenu",u=>{u.preventDefault(),u.stopPropagation(),this.openDirContextMenu(u.clientX,u.clientY,p,"")})}else l.addEventListener("contextmenu",p=>{p.preventDefault(),p.stopPropagation(),this.showContextMenu(p.clientX,p.clientY,e.name,[{icon:Vt,iconClass:"nav-ctx-dir",label:"Create /docs/",action:()=>this.callbacks.onCreateDocsFolder(t.id,e.path)}])});for(const p of e.children)p.type==="dir"&&c.appendChild(this.renderBrowseNode(t,p,n));return this.registerCollapsible(a,c,r,l,!0),r.append(l,c),r}renderPathNodes(t,e,n,o=""){const i=document.createElement("div");for(const a of t)if(a.kind==="root")i.appendChild(this.docsRootSection(a.root,e.get(a.root.id)??[]));else{const r=o?`${o}/${a.segment}`:a.segment,c=`pathseg:${n}:${r}`,l=this.renderPathNodes(a.children,e,n,r);l.classList.add("nav-dir-body");const d=document.createElement("div");d.className="nav-subgroup nav-collapsible-dir";const h=Ho(a),{row:p,toggle:u}=this.createDirectoryRow(a.segment,`#/project/${encodeURIComponent(n)}`,`${a.segment} wiki`,()=>this.toggleCollapsible(c),!0);h&&d.addEventListener("contextmenu",g=>{g.preventDefault(),g.stopPropagation(),this.openDirContextMenu(g.clientX,g.clientY,h,"")}),this.registerCollapsible(c,l,d,u,!0),d.append(p,l),i.appendChild(d)}return i}docsRootSection(t,e){const n=document.createElement("div");n.className="nav-subgroup nav-docs-root";const o=t.displayPath.split("/").pop()??t.displayPath;if(o.toLowerCase()!=="docs"){const a=document.createElement("div");a.className="nav-root-path-label",a.textContent=o,n.appendChild(a),a.addEventListener("contextmenu",r=>{r.preventDefault(),r.stopPropagation(),this.openDirContextMenu(r.clientX,r.clientY,t,"")})}return n.addEventListener("contextmenu",a=>{var r;(r=a.target)!=null&&r.closest(".nav-link, .nav-dir-toggle")||(a.preventDefault(),a.stopPropagation(),this.openDirContextMenu(a.clientX,a.clientY,t,""))}),this.enableDirectoryDropTarget(n,t.id,""),n.appendChild(this.docsNodes(t,zs(e),"",e)),n}createDirectoryRow(t,e,n,o,i=!1){const a=document.createElement("div");a.className="nav-dir-header-row";const r=document.createElement("button");r.className=i?"nav-dir-toggle nav-dir-project":"nav-dir-toggle nav-dir-docs",r.type="button";const c=document.createElement("span");c.className="nav-repo-chevron",c.innerHTML='<svg viewBox="0 0 16 16" width="10" height="10" fill="currentColor"><path d="M6 4l4 4-4 4"/></svg>';const l=document.createElement("span");l.textContent=t,r.append(c,l),r.addEventListener("click",o);const d=document.createElement("a");return d.className="nav-repo-wiki-link nav-dir-wiki-link",d.href=e,d.title=n,d.innerHTML='<svg viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="2" y="2" width="10" height="10" rx="2"/><path d="M5 5h4M5 7h4M5 9h2"/></svg>',d.addEventListener("click",h=>h.stopPropagation()),this.links.set(e,d),a.append(r,d),{row:a,toggle:r}}docsNodes(t,e,n,o){const i=document.createElement("div"),a=Fo(e),r=js(o,n),c=[...a.map(l=>({kind:l.type==="file"&&Ce(l.path)?"file":"doc",node:l})),...r.map(l=>({kind:"board",name:qt(rt(l.path).split("/").pop()??rt(l.path)),boardId:rt(l.path)}))].sort((l,d)=>{const h=l.kind==="doc"&&l.node.type==="file"&&l.node.name==="index.md",p=d.kind==="doc"&&d.node.type==="file"&&d.node.name==="index.md";if(h!==p)return h?-1:1;const u=(l.kind==="doc"||l.kind==="file")&&l.node.type==="file"&&yn(l.node.name),g=(d.kind==="doc"||d.kind==="file")&&d.node.type==="file"&&yn(d.node.name);if(u!==g)return u?-1:1;const b=(l.kind==="doc"||l.kind==="file")&&l.node.type==="dir",y=(d.kind==="doc"||d.kind==="file")&&d.node.type==="dir";if(b!==y)return b?-1:1;const x=l.kind==="board"?l.name:l.node.name,v=d.kind==="board"?d.name:d.node.name;return x.localeCompare(v)});for(const l of c)if(l.kind==="board"){const d=document.createElement("a");d.className="nav-link nav-link-board",d.href=Wn(t.id,l.boardId),d.insertAdjacentHTML("afterbegin",Yt),d.appendChild(document.createTextNode(l.name));const h=`board:${t.id}:${l.boardId}`;this.links.set(h,d),this.links.set(d.href,d),this.enableDragSource(d,{kind:"board",rootId:t.id,boardId:l.boardId}),d.addEventListener("contextmenu",p=>{p.preventDefault(),p.stopPropagation(),this.openBoardContextMenu(p.clientX,p.clientY,t,l.boardId)}),i.appendChild(d)}else{const{node:d}=l;if(d.type==="file"){if(l.kind==="file"){const u=document.createElement("button");u.className="nav-link nav-tree-file nav-tree-capability-file",u.type="button",u.insertAdjacentHTML("afterbegin",nn),u.appendChild(document.createTextNode(d.name)),u.addEventListener("click",()=>this.callbacks.onOpenTextFile(t.id,d.path)),u.addEventListener("contextmenu",g=>{g.preventDefault(),g.stopPropagation(),this.openTextFileContextMenu(g.clientX,g.clientY,t,d.path)}),i.appendChild(u);continue}if(!d.name.endsWith(".md"))continue;const h=d.name==="index.md"?"Overview":qt(d.name),p=this.link(Hn(t.id,d.path),h,`doc:${t.id}:${d.path}`);p.insertAdjacentHTML("afterbegin",Dt),this.enableDragSource(p,{kind:"doc",rootId:t.id,path:d.path}),p.addEventListener("contextmenu",u=>{u.preventDefault(),u.stopPropagation(),this.openDocContextMenu(u.clientX,u.clientY,t,d.path)}),i.appendChild(p)}else{const h=`doc:${t.id}:${d.path}`,p=this.docsNodes(t,d.children,d.path,o);p.classList.add("nav-dir-body");const u=document.createElement("div");u.className="nav-subgroup nav-collapsible-dir";const{row:g,toggle:b}=this.createDirectoryRow(qt(d.name),`#/root/${encodeURIComponent(t.id)}/directory/${encodeURIComponent(d.path)}`,`${d.name} wiki`,y=>{y.button===0&&this.toggleCollapsible(h)},!1);this.enableDragSource(b,{kind:"dir",rootId:t.id,path:d.path}),u.addEventListener("contextmenu",y=>{y.preventDefault(),y.stopPropagation(),this.openDirContextMenu(y.clientX,y.clientY,t,d.path)}),this.enableDirectoryDropTarget(u,t.id,d.path),this.registerCollapsible(h,p,u,b,!0),u.append(g,p),i.appendChild(u)}}return i}enableDragSource(t,e){t.draggable=!0,t.addEventListener("dragstart",n=>{var o,i;this.closeContextMenu(),this.draggedItem=e,t.classList.add("nav-dragging"),(o=n.dataTransfer)==null||o.setData("application/x-docs-nav-item",JSON.stringify(e)),(i=n.dataTransfer)==null||i.setData("text/plain",qs(e)),n.dataTransfer&&(n.dataTransfer.effectAllowed="move")}),t.addEventListener("dragend",()=>{t.classList.remove("nav-dragging"),this.draggedItem=void 0,this.clearDropTargets()})}enableDirectoryDropTarget(t,e,n){t.addEventListener("dragover",o=>{const i=this.currentDragItem(o);!i||!this.canDropItem(i,e,n)||(o.preventDefault(),o.stopPropagation(),o.dataTransfer&&(o.dataTransfer.dropEffect="move"),t.classList.add("nav-drop-target"),this.scheduleDropExpand(t))}),t.addEventListener("dragleave",o=>{t.contains(o.relatedTarget)||(t.classList.remove("nav-drop-target"),this.clearDropExpand(t))}),t.addEventListener("drop",o=>{const i=this.currentDragItem(o);!i||!this.canDropItem(i,e,n)||(o.preventDefault(),o.stopPropagation(),this.clearDropExpand(t),this.clearDropTargets(),this.moveDraggedItem(i,n))})}scheduleDropExpand(t){this.dropExpandTarget===t||!t.dataset.collapsibleKey||(this.clearDropExpand(),this.dropExpandTarget=t,this.dropExpandTimer=window.setTimeout(()=>{const e=t.dataset.collapsibleKey;e&&this.applyCollapsed(e,!1),t.classList.add("nav-drop-auto-expanded"),this.dropExpandTimer=void 0},650))}clearDropExpand(t){var e;t&&this.dropExpandTarget!==t||(this.dropExpandTimer!==void 0&&window.clearTimeout(this.dropExpandTimer),this.dropExpandTimer=void 0,(e=this.dropExpandTarget)==null||e.classList.remove("nav-drop-auto-expanded"),this.dropExpandTarget=void 0)}currentDragItem(t){var n;if(this.draggedItem)return this.draggedItem;const e=(n=t.dataTransfer)==null?void 0:n.getData("application/x-docs-nav-item");if(e)try{const o=JSON.parse(e);if(o&&(o.kind==="doc"||o.kind==="capability"||o.kind==="board"||o.kind==="dir")&&typeof o.rootId=="string")return o}catch{}}canDropItem(t,e,n){if(t.rootId!==e)return!1;const o=Mt(n);if(t.kind==="doc")return It(t.path)!==o;if(t.kind==="capability")return o==="capabilities"||o.startsWith("capabilities/")&&It(t.path)!==o;if(t.kind==="board")return It(t.boardId)!==o;const i=Mt(t.path);return!i||i===o||It(i)===o?!1:!o.startsWith(`${i}/`)}moveDraggedItem(t,e){const n=Mt(e);t.kind==="doc"||t.kind==="capability"?this.callbacks.onMoveDoc(t.rootId,t.path,n):t.kind==="board"?this.callbacks.onMoveBoard(t.rootId,t.boardId,n):this.callbacks.onMoveDirectory(t.rootId,t.path,n)}clearDropTargets(){this.clearDropExpand(),this.element.querySelectorAll(".nav-drop-target").forEach(t=>{t.classList.remove("nav-drop-target")})}startInlineRename(t,e,n){const o=document.createElement("input");o.className="nav-inline-input",o.value=e.replace(/\.md$/,"");const i=t.parentElement;if(!i)return;t.style.display="none",i.insertBefore(o,t.nextSibling),o.focus(),o.select();let a=!1;const r=c=>{if(!a&&(a=!0,o.remove(),t.style.display="",c)){const l=o.value.trim();l&&l!==e.replace(/\.md$/,"")&&n(l)}};o.addEventListener("keydown",c=>{c.stopPropagation(),c.key==="Enter"&&(c.preventDefault(),r(!0)),c.key==="Escape"&&(c.preventDefault(),r(!1))}),o.addEventListener("blur",()=>r(!0))}startInlineCreate(t,e,n){const o=document.createElement("input");o.className="nav-inline-input",o.placeholder=e,t.insertBefore(o,t.firstChild),o.focus();let i=!1;const a=r=>{if(!i&&(i=!0,o.remove(),r)){const c=o.value.trim();c&&n(c)}};o.addEventListener("keydown",r=>{r.stopPropagation(),r.key==="Enter"&&(r.preventDefault(),a(!0)),r.key==="Escape"&&(r.preventDefault(),a(!1))}),o.addEventListener("blur",()=>a(!0))}registerCollapsible(t,e,n,o,i){this.collapsibles.set(t,{body:e,group:n,btn:o}),n.dataset.collapsibleKey=t,this.applyCollapsed(t,this.collapsedState.get(t)??i)}applyCollapsed(t,e){const n=this.collapsibles.get(t);n&&(this.collapsedState.set(t,e),n.body.hidden=e,n.group.classList.toggle("collapsed",e),n.btn.setAttribute("aria-expanded",String(!e)))}toggleCollapsible(t){const e=this.collapsibles.get(t);e&&this.applyCollapsed(t,!e.body.hidden)}openDirContextMenu(t,e,n,o){const i=o?qt(o.split("/").pop()??o):n.displayPath.split("/").pop()??n.displayPath,a=[{icon:Vt,iconClass:"nav-ctx-dir",label:"New Directory",action:()=>this.callbacks.onCreateDirectory(n.id,o)},{icon:Yt,iconClass:"nav-ctx-board",label:"New Board",action:()=>this.callbacks.onCreateBoard(n.id,o)},{icon:Dt,iconClass:"nav-ctx-doc",label:"New Doc",action:()=>this.callbacks.onCreateDoc(n.id,o)},{icon:en,iconClass:"nav-ctx-cap",label:"New Capability",action:()=>this.callbacks.onCreateCapability(n.id,o)},{icon:Le,iconClass:"nav-ctx-export",label:"Export",children:[{icon:Le,iconClass:"nav-ctx-export",label:"Export to PDF",action:()=>this.callbacks.onExportDirectory(n.id,o)}]}];o&&a.push({icon:Re,iconClass:"nav-ctx-rename",label:"Rename",action:()=>this.callbacks.onRenameDirectory(n.id,o)},{icon:ue,iconClass:"nav-ctx-delete",label:"Delete",action:()=>this.callbacks.onDeleteDirectory(n.id,o)}),this.showContextMenu(t,e,i,a)}openEmptyProjectContextMenu(t,e,n,o){this.showContextMenu(t,e,o,[{icon:Vt,iconClass:"nav-ctx-dir",label:"New Directory",action:()=>this.callbacks.onCreateProjectDirectory(n)},{icon:Yt,iconClass:"nav-ctx-board",label:"New Board",action:()=>this.callbacks.onCreateProjectBoard(n)},{icon:Dt,iconClass:"nav-ctx-doc",label:"New Doc",action:()=>this.callbacks.onCreateProjectDoc(n)}])}openDocContextMenu(t,e,n,o){const i=o.split("/").pop()??o;this.showContextMenu(t,e,i,[{icon:Dt,iconClass:"nav-ctx-doc",label:"Open",action:()=>this.callbacks.onOpenDoc(n.id,o)},{icon:Ue,iconClass:"nav-ctx-edit",label:"Edit",action:()=>this.callbacks.onEditDoc(n.id,o)},{icon:Le,iconClass:"nav-ctx-export",label:"Export",children:[{icon:Le,iconClass:"nav-ctx-export",label:"Export to PDF",action:()=>this.callbacks.onExportDoc(n.id,o)}]},{kind:"divider"},{icon:Re,iconClass:"nav-ctx-rename",label:"Rename",action:()=>this.callbacks.onRenameDoc(n.id,o)},{icon:ue,iconClass:"nav-ctx-delete",label:"Delete",action:()=>this.callbacks.onDeleteDoc(n.id,o),danger:!0}])}openTextFileContextMenu(t,e,n,o){const i=o.split("/").pop()??o;this.showContextMenu(t,e,i,[{icon:nn,iconClass:"nav-ctx-doc",label:"Open",action:()=>this.callbacks.onOpenTextFile(n.id,o)},{icon:Ue,iconClass:"nav-ctx-edit",label:"Edit",action:()=>this.callbacks.onOpenTextFile(n.id,o)},{kind:"divider"},{icon:Re,iconClass:"nav-ctx-rename",label:"Rename",action:()=>this.callbacks.onRenameDoc(n.id,o)},{icon:ue,iconClass:"nav-ctx-delete",label:"Delete",action:()=>this.callbacks.onDeleteDoc(n.id,o),danger:!0}])}openBoardContextMenu(t,e,n,o){const i=qt(o.split("/").pop()??o);this.showContextMenu(t,e,i,[{icon:Yt,iconClass:"nav-ctx-board",label:"Open",action:()=>this.callbacks.onOpenBoard(n.id,o)},{kind:"divider"},{icon:Re,iconClass:"nav-ctx-rename",label:"Rename",action:()=>this.callbacks.onRenameBoard(n.id,o)},{icon:ue,iconClass:"nav-ctx-delete",label:"Delete",action:()=>this.callbacks.onDeleteBoard(n.id,o),danger:!0}])}showContextMenu(t,e,n,o){var c;this.closeContextMenu();const i=document.createElement("div");i.className="nav-context-menu",i.addEventListener("pointerdown",l=>l.stopPropagation());const a=document.createElement("div");a.className="nav-context-label",a.textContent=n,i.appendChild(a);const r=document.createElement("div");r.className="nav-context-divider",i.appendChild(r);for(const l of o){if(l.kind==="divider"){const g=document.createElement("div");g.className="nav-context-divider",i.appendChild(g);continue}const d=document.createElement("button"),h=!!((c=l.children)!=null&&c.length);d.className="nav-context-item"+(l.danger?" nav-context-item-danger":"")+(h?" nav-context-item-parent":""),d.type="button";const p=document.createElement("span");p.className=`nav-ctx-icon ${l.iconClass}`,p.innerHTML=l.icon;const u=document.createElement("span");if(u.textContent=l.label,d.append(p,u),h){const g=document.createElement("span");g.className="nav-context-chevron",g.innerHTML=Fs,d.appendChild(g);const b=document.createElement("div");b.className="nav-context-submenu",b.addEventListener("pointerdown",y=>y.stopPropagation());for(const y of l.children??[]){const x=document.createElement("button");x.className="nav-context-item"+(y.danger?" nav-context-item-danger":""),x.type="button";const v=document.createElement("span");v.className=`nav-ctx-icon ${y.iconClass}`,v.innerHTML=y.icon;const E=document.createElement("span");E.textContent=y.label,x.append(v,E),x.addEventListener("click",()=>{this.closeContextMenu(),y.action()}),b.appendChild(x)}d.appendChild(b)}else if(l.action){const g=l.action;d.addEventListener("click",()=>{this.closeContextMenu(),g()})}i.appendChild(d)}i.style.position="fixed",i.style.left=`${t}px`,i.style.top=`${e}px`,document.body.appendChild(i),this.contextMenu=i,requestAnimationFrame(()=>{if(!this.contextMenu)return;const l=i.getBoundingClientRect();l.right>window.innerWidth&&(i.style.left=`${Math.max(0,t-l.width)}px`),l.bottom>window.innerHeight&&(i.style.top=`${Math.max(0,e-l.height)}px`)})}closeContextMenu(){var t;(t=this.contextMenu)==null||t.remove(),this.contextMenu=void 0}groupLabel(t){const e=document.createElement("div");return e.className="nav-label",e.textContent=t,e}link(t,e,n){const o=document.createElement("a");return o.className="nav-link",o.href=t,o.textContent=e,this.links.set(n,o),this.links.set(t,o),o}}const Yt='<svg class="nav-node-icon nav-node-icon-board" viewBox="0 0 16 16" aria-hidden="true"><rect x="1" y="1" width="6" height="6" rx="1"/><rect x="9" y="1" width="6" height="6" rx="1"/><rect x="1" y="9" width="6" height="6" rx="1"/><rect x="9" y="9" width="6" height="6" rx="1"/></svg>',en='<svg class="nav-node-icon nav-node-icon-capability" viewBox="0 0 16 16" aria-hidden="true"><path d="M8 1l2 4.5 4.5 0.7-3.3 3.1 0.8 4.7-4-2.1-4 2.1 0.8-4.7L1.5 6.2l4.5-0.7z"/></svg>',Dt='<svg class="nav-node-icon nav-node-icon-doc" viewBox="0 0 16 16" aria-hidden="true"><path d="M3 1.5h6.5l3 3V14.5H3z"/><path d="M9.5 1.5V4.5h3" stroke="none"/><line x1="5" y1="7" x2="11" y2="7" stroke="var(--bg-canvas)" stroke-width="0.8"/><line x1="5" y1="9.5" x2="11" y2="9.5" stroke="var(--bg-canvas)" stroke-width="0.8"/><line x1="5" y1="12" x2="9" y2="12" stroke="var(--bg-canvas)" stroke-width="0.8"/></svg>',nn='<svg class="nav-node-icon nav-node-icon-doc" viewBox="0 0 16 16" aria-hidden="true"><path d="M3 1.5h6.5l3 3V14.5H3z"/><path d="M9.5 1.5V4.5h3" stroke="none"/><line x1="5" y1="7" x2="11" y2="7" stroke="var(--bg-canvas)" stroke-width="0.8"/><line x1="5" y1="9.5" x2="11" y2="9.5" stroke="var(--bg-canvas)" stroke-width="0.8"/></svg>',Vt='<svg class="nav-ctx-svg" viewBox="0 0 16 16" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.45" stroke-linecap="round" stroke-linejoin="round"><path d="M2 4.5h4l1.4 1.6H14v6.4a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1z"/><path d="M2 4.5v-1a1 1 0 0 1 1-1h3l1.4 2"/></svg>',Ue='<svg class="nav-ctx-svg" viewBox="0 0 16 16" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M11 2l3 3-8 8H3v-3z"/></svg>',Re=Ue,Le='<svg class="nav-ctx-svg" viewBox="0 0 16 16" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M8 10.5V2.5M8 2.5L5.5 5M8 2.5L10.5 5M2.5 11.5V13a1 1 0 0 0 1 1h9a1 1 0 0 0 1-1v-1.5"/></svg>',Fs='<svg class="nav-ctx-svg nav-ctx-chevron-svg" viewBox="0 0 16 16" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3.5L10.5 8 6 12.5"/></svg>',ue='<svg class="nav-ctx-svg" viewBox="0 0 16 16" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M2 4h12M5 4V2h6v2M6 7v5M10 7v5M3 4l1 9a1 1 0 001 1h6a1 1 0 001-1l1-9"/></svg>';function Fo(s){return s.filter(t=>t.type==="file"?t.name.endsWith(".md")||Ce(t.path):!As.has(t.name)).map(t=>t.type==="file"?t:{...t,children:Fo(t.children)})}function zs(s){const t=s.find(e=>e.type==="dir"&&e.name.toLowerCase()==="docs");return!t||t.type!=="dir"?s:s.filter(e=>e!==t).concat(t.children)}function js(s,t){const e=t?`${t}/`:"";return Hs(s).filter(n=>e?n.path.startsWith(e)?!n.path.slice(e.length).includes("/"):!1:!n.path.includes("/"))}function Hs(s){const t=[],e=n=>{for(const o of n)o.type==="file"?o.name.endsWith(".board.json")&&t.push(o):e(o.children)};return e(s),t}function Hn(s,t){return`#/root/${encodeURIComponent(s)}/docs/${encodeURIComponent(t)}`}function Ws(s){return`#/root/${encodeURIComponent(s)}/boards`}function Wn(s,t){return`#/root/${encodeURIComponent(s)}/boards/${encodeURIComponent(t)}`}function Os(s){return`#/root/${encodeURIComponent(s)}/capabilities`}function Us(s,t){return`#/root/${encodeURIComponent(s)}/capabilities/${encodeURIComponent(_s(t))}`}function _s(s){return s.replace(/^capabilities\//,"")}function Xs(s,t,e){const n=new Map,o=[],i=c=>{const l=Mt(c),d=n.get(l);if(d)return d;const h=It(l),p={id:`folder:${s.id}:${l}`,kind:"folder",name:l.split("/").pop()??s.label,projectPath:l,children:[]};return n.set(l,p),l&&h?i(h).children.push(p):o.push(p),p},a=c=>{for(const l of c)if(l.type==="dir")i(l.path),a(l.children);else{const d={id:`file:${s.id}:${l.path}`,kind:"file",name:l.name,projectPath:l.path,children:[]};n.set(l.path,d);const h=It(l.path);h?i(h).children.push(d):o.push(d)}};a(t);for(const c of s.docsRoots){const l=Mt(c.displayPath),d=i(l);d.kind="docsRoot",d.id=`root:${c.id}`,d.root=c,d.contentPath="";const h=p=>{for(const u of p){const g=[l,u.path].filter(Boolean).join("/");if(u.type==="dir"){const S=i(g);S.kind!=="docsRoot"&&(S.root=c,S.contentPath=u.path),h(u.children);continue}const b=u.name.endsWith(".board.json"),y=zo(u.path),x=Ce(u.path);if(!u.name.endsWith(".md")&&!b&&!x)continue;const v=It(g),E=n.get(g),w=E??{id:"",kind:"file",name:u.name,projectPath:g,children:[]};w.id=`${b?"board":y?"capability":x?"file":"doc"}:${c.id}:${u.path}`,w.kind=b?"board":y?"capability":x?"file":"doc",w.root=c,w.contentPath=u.path,E||(n.set(g,w),v?i(v).children.push(w):o.push(w))}};h(e.get(c.id)??[])}const r=(c,l)=>{const d=c.kind==="docsRoot"?c.root:c.root??l;if(d&&(c.kind==="folder"||c.kind==="file")&&!c.contentPath){c.root=d;const h=Mt(d.displayPath);c.contentPath=c.projectPath.slice(h.length).replace(/^\//,"")}for(const h of c.children)r(h,d)};for(const c of o)r(c);return o}function Ys(s){return[...s].sort((t,e)=>{const n=o=>o.kind==="doc"&&o.name==="index.md"?0:(o.kind==="doc"||o.kind==="file")&&yn(o.name)?1:o.kind==="doc"?2:o.kind==="capability"?3:o.kind==="board"?4:o.kind==="folder"&&o.root&&!o.docsContainerRoot?5:o.kind==="folder"&&o.docsContainerRoot?6:o.kind==="folder"&&!o.root?7:o.kind==="docsRoot"?8:9;return n(t)-n(e)||t.name.localeCompare(e.name,void 0,{sensitivity:"accent"})})}function yn(s){return/^readme\.(md|txt)$/i.test(s)}function _e(s,t,e=!1){const n=[];for(const o of s){if(o.kind==="docsRoot"){n.push({...o,children:_e(o.children,!1,!0)});continue}if(e){if(o.kind==="file"){Ce(o.contentPath??"")&&n.push(o);continue}if(o.kind==="folder"){const i=_e(o.children,!1,!0);(o.name!=="assets"||i.length>0)&&n.push({...o,children:i})}else n.push(o);continue}if(o.kind==="folder"){const i=_e(o.children);i.length>0&&n.push({...o,children:i})}}return n}function bn(s){var e;const t=[];for(const n of s){if(n.kind==="docsRoot"){t.push(...bn(n.children));continue}if(n.kind!=="folder"){t.push(n);continue}const o=(e=n.children.find(i=>i.kind==="docsRoot"))==null?void 0:e.root;t.push({...n,docsContainerRoot:o,children:bn(n.children)})}return t}function qt(s){const t=s.replace(/\.md$/,"").replace(/[-_]/g," ");return t.charAt(0).toUpperCase()+t.slice(1)}function zo(s){if(!s.startsWith("capabilities/")||!s.endsWith(".md"))return!1;const t=s.slice(13);return t.includes("/")?t.endsWith("/index.md"):!0}function Ce(s){return!s.startsWith("capabilities/")||s.endsWith(".board.json")?!1:!zo(s)}function Vs(s){var t;return s.kind!=="folder"||!((t=s.contentPath)!=null&&t.startsWith("capabilities/"))?null:s.children.find(e=>e.kind==="capability"&&It(e.contentPath??"")===s.contentPath)??null}function jo(s){if(s.type==="file")return!1;for(const t of s.children)if(t.type==="dir"&&t.name==="docs"||t.type==="dir"&&jo(t))return!0;return!1}function Mt(s){return s.replace(/^\/+|\/+$/g,"")}function It(s){const t=Mt(s),e=t.lastIndexOf("/");return e===-1?"":t.slice(0,e)}function qs(s){return s.kind==="doc"||s.kind==="capability"?s.path:s.kind==="board"?s.boardId:s.path}function Ho(s){if(s.kind==="root")return s.root;for(const t of s.children){const e=Ho(t);if(e)return e}return null}const Ks=["workspace-changed","file-changed","board-changed","asset-changed"];class Gs{constructor(){m(this,"source",null);m(this,"listeners",new Set);m(this,"handlers",new Map);m(this,"hasOpened",!1)}subscribe(t){return this.listeners.add(t),this.connect(),()=>{this.listeners.delete(t),this.listeners.size===0&&this.disconnect()}}connect(){if(this.source||typeof EventSource>"u")return;const t=new EventSource("/__api/events");this.source=t,t.onopen=()=>{const e=this.hasOpened;this.hasOpened=!0,this.emit({type:"stream-open",reconnecting:e})};for(const e of Ks){const n=o=>{const i=o;let a;try{a=JSON.parse(i.data)}catch{return}typeof a!="object"||a===null||this.emit({...a,type:e})};this.handlers.set(e,n),t.addEventListener(e,n)}}emit(t){for(const e of this.listeners)e(t)}disconnect(){if(this.source){for(const[t,e]of this.handlers)this.source.removeEventListener(t,e);this.handlers.clear(),this.source.close(),this.source=null}}}const Zs=new Gs;function ne(s,t={}){const{frontmatter:e,body:n}=Js(s);try{const o=Wo(n.split(`
2
+ `),t);return{frontmatter:e,html:o}}catch(o){return console.error("Markdown render failed",o),{frontmatter:e,html:`<div class="md-error"><strong>Could not render this document.</strong><pre>${se(String(o))}</pre></div>`}}}function Js(s){const t={};if(!s.startsWith("---"))return{frontmatter:t,body:s};const e=s.indexOf(`
3
+ ---`,3);if(e===-1)return{frontmatter:t,body:s};const n=s.slice(3,e).trim();for(const i of n.split(`
4
+ `)){const a=i.indexOf(":");a!==-1&&(t[i.slice(0,a).trim()]=i.slice(a+1).trim())}const o=s.slice(e+4).replace(/^\n+/,"");return{frontmatter:t,body:o}}function Wo(s,t){const e=[];let n=0,o=0;const i=s.length*4+1e3;for(;n<s.length;){if(++o>i)throw new Error(`renderBlocks exceeded ${i} iterations at line ${n} — aborting to avoid an infinite loop`);const a=s[n];if(a.trim()===""){n++;continue}const r=a.match(/^(`{3,})\s*(\w+)?\s*$/);if(r){const d=r[1].length,h=(r[2]??"").toLowerCase(),p=new RegExp("^`{"+d+",}\\s*$"),u=[];for(n++;n<s.length&&!p.test(s[n]);)u.push(s[n]),n++;n++,h==="board"?e.push(ei(Uo(u.join(`
5
+ `)))):e.push(`<pre class="code-block"><code${h?` class="language-${h}"`:""}>${se(u.join(`
6
+ `))}</code></pre>`);continue}const c=a.match(/^(#{1,6})\s+(.*)$/);if(c){const d=c[1].length,h=Ut(c[2].trim(),t),p=si(c[2]);e.push(`<h${d} id="${p}">${h}</h${d}>`),n++;continue}if(/^(-{3,}|\*{3,}|_{3,})\s*$/.test(a)){e.push("<hr />"),n++;continue}if(/^>\s?/.test(a)){const d=[];for(;n<s.length&&/^>\s?/.test(s[n]);)d.push(s[n].replace(/^>\s?/,"")),n++;e.push(`<blockquote>${Wo(d,t)}</blockquote>`);continue}if(a.includes("|")&&n+1<s.length&&Qs(s[n+1])){const d=[];for(;n<s.length&&s[n].includes("|")&&s[n].trim()!=="";)d.push(s[n]),n++;e.push(ti(d,t));continue}if(te(a)){const d=[];for(;n<s.length&&(te(s[n])||/^\s+\S/.test(s[n])||s[n].trim()==="");){if(s[n].trim()===""){const h=s[n+1];if(h===void 0||!te(h)&&!/^\s+\S/.test(h))break}d.push(s[n]),n++}e.push(Oo(d,t));continue}const l=[s[n]];for(n++;n<s.length&&s[n].trim()!==""&&!/^`{3,}/.test(s[n])&&!/^#{1,6}\s/.test(s[n])&&!/^>\s?/.test(s[n])&&!te(s[n])&&!/^(-{3,}|\*{3,}|_{3,})\s*$/.test(s[n]);)l.push(s[n]),n++;e.push(`<p>${Ut(l.join(" ").trim(),t)}</p>`)}return e.join(`
7
+ `)}function te(s){return/^\s*([-*+]|\d+\.)\s+/.test(s)}function Oo(s,t){const e=s.filter(l=>te(l)).map(l=>l.match(/^\s*/)[0].length);if(e.length===0)return Ut(s.join(" ").trim(),t);const n=Math.min(...e),o=[];let i=!1,a=null;for(const l of s){const d=l.match(/^\s*/)[0].length,h=l.match(/^\s*([-*+]|\d+\.)\s+(.*)$/);if(h&&d===n){i=/\d+\./.test(h[1]);let p=h[2],u=null;const g=p.match(/^\[([ xX])\]\s+(.*)$/);g&&(u=g[1].toLowerCase()==="x",p=g[2]),a={ordered:i,content:[p],checked:u},o.push(a)}else a&&a.content.push(l.slice(n))}const r=i?"ol":"ul",c=o.map(l=>{const d=l.content[0],h=l.content.slice(1);let p=Ut(d,t);const u=h.filter(g=>g.trim()!=="");return u.some(g=>te(g))?p+=Oo(h,t):u.length&&(p+=" "+Ut(u.join(" ").trim(),t)),l.checked!==null?`<li class="task">${`<input type="checkbox" disabled${l.checked?" checked":""} /> `}${p}</li>`:`<li>${p}</li>`}).join("");return`<${r}>${c}</${r}>`}function Qs(s){return/^\s*\|?\s*:?-{1,}:?\s*(\|\s*:?-{1,}:?\s*)*\|?\s*$/.test(s)}function on(s){return s.trim().replace(/^\|/,"").replace(/\|$/,"").split("|").map(t=>t.trim())}function ti(s,t){const e=on(s[0]),n=on(s[1]).map(r=>{const c=r.startsWith(":"),l=r.endsWith(":");return c&&l?"center":l?"right":c?"left":""}),o=s.slice(2).map(on),i=e.map((r,c)=>`<th${n[c]?` style="text-align:${n[c]}"`:""}>${Ut(r,t)}</th>`).join(""),a=o.map(r=>`<tr>${r.map((c,l)=>`<td${n[l]?` style="text-align:${n[l]}"`:""}>${Ut(c,t)}</td>`).join("")}</tr>`).join("");return`<div class="markdown-table-scroll"><table><thead><tr>${i}</tr></thead><tbody>${a}</tbody></table></div>`}function Uo(s){const t={};for(const n of s.split(`
8
+ `)){const o=n.replace(/#.*$/,"").trim();if(!o)continue;const i=o.indexOf(":");i!==-1&&(t[o.slice(0,i).trim()]=o.slice(i+1).trim())}let e=null;if(t.region){const n=t.region.split(",").map(o=>parseFloat(o.trim()));n.length===4&&n.every(o=>Number.isFinite(o))&&(e=[n[0],n[1],n[2],n[3]])}return{src:t.src??"",region:e,height:t.height?Math.max(120,parseInt(t.height,10)||360):360,title:t.title??null}}function ei(s){const t=s.region?s.region.join(","):"";return`<figure class="board-embed" data-src="${Ht(s.src)}" data-region="${t}" data-height="${s.height}" data-title="${Ht(s.title??"")}"></figure>`}function Ut(s,t){let e=s;const n=[];e=e.replace(/\\([\\`*_{}\[\]()#+\-.!|])/g,(a,r)=>(n.push(r),`${n.length-1}`));const o=[];e=e.replace(/`([^`]+)`/g,(a,r)=>(o.push(`<code>${se(Pe(r,n))}</code>`),`\0${o.length-1}\0`));const i=[];return e=e.replace(/!\[([^\]]*)\]\(([^)\s]+)\)/g,(a,r,c)=>{const l=Pe(c,n),d=Bn(l,t),h=ni(l,t),p=Pe(r,n),u=d===l?"":` data-md-src="${Ht(l)}"`;return i.push(`<img src="${Ht(h)}" alt="${Ht(p)}" loading="lazy"${u} />`),`${i.length-1}`}),e=e.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g,(a,r,c)=>{const l=Pe(c,n),d=oi(l,t),p=/^(https?:|mailto:|tel:)/.test(l)?' target="_blank" rel="noopener noreferrer"':"",u=d===l?"":` data-md-href="${Ht(l)}"`;return i.push(`<a href="${Ht(d)}"${p}${u}>${On(r,n,o)}</a>`),`${i.length-1}`}),e=On(e,n,o),e=e.replace(/\u0002(\d+)\u0002/g,(a,r)=>i[Number(r)]??""),e}function On(s,t,e){let n=se(s);return n=n.replace(/\*\*([\s\S]+?)\*\*/g,"<strong>$1</strong>"),n=n.replace(/__([\s\S]+?)__/g,"<strong>$1</strong>"),n=n.replace(/(^|[^*])\*([^*\s][^*]*)\*/g,"$1<em>$2</em>"),n=n.replace(/(^|[^_])_([^_\s][^_]*)_/g,"$1<em>$2</em>"),n=n.replace(/\u0000(\d+)\u0000/g,(o,i)=>e[Number(i)]??""),n=n.replace(/\u0001(\d+)\u0001/g,(o,i)=>se(t[Number(i)]??"")),n}function Pe(s,t){return s.replace(/\u0001(\d+)\u0001/g,(e,n)=>t[Number(n)]??"")}function ni(s,t){if(/^(https?:|data:)/.test(s)||!t.rootId||!t.docPath)return s;const e=Bn(s,t);return e?k.assetUrl(t.rootId,e):s}function oi(s,t){if(/^(https?:|mailto:|tel:|#|data:)/.test(s)||!t.rootId||!t.docPath)return s;const e=Bn(s,t);return e?e.endsWith(".md")?`#/root/${encodeURIComponent(t.rootId)}/docs/${encodeURIComponent(e)}`:k.assetUrl(t.rootId,e):s}function Bn(s,t){return t.docPath?Bs(t.docPath,s):s}function se(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Ht(s){return se(s).replace(/"/g,"&quot;")}function si(s){return s.toLowerCase().replace(/[^\w\s-]/g,"").trim().replace(/\s+/g,"-")}class Mn{constructor(t,e,n){m(this,"cache",new Map);m(this,"loading",new Set);m(this,"idleWaiters",new Set);m(this,"missing",new Set);m(this,"assetStore");m(this,"onLoaded");m(this,"resolveSrcUrl");this.assetStore=t,this.onLoaded=e,this.resolveSrcUrl=n}get(t){const e=this.cache.get(t);return e||(!this.loading.has(t)&&!this.missing.has(t)&&this.load(t),null)}isMissing(t){return this.missing.has(t)}srcToUrl(t){return this.resolveSrcUrl?this.resolveSrcUrl(t):/^(https?:)?\/\//.test(t)||t.startsWith("/")||t.startsWith("data:")?t:`/__api/asset?path=${encodeURIComponent(t)}`}keyForSrc(t){return this.srcToUrl(t)}getBySrc(t){const e=this.srcToUrl(t),n=this.cache.get(e);return n||(!this.loading.has(e)&&!this.missing.has(e)&&this.loadUrl(e),null)}isMissingSrc(t){return this.missing.has(this.srcToUrl(t))}async loadUrl(t){this.loading.add(t);try{const e=await fetch(t);if(!e.ok){this.missing.add(t);return}const n=await e.blob(),o=await createImageBitmap(n);this.cache.set(t,o),this.onLoaded()}catch{this.missing.add(t)}finally{this.finishLoad(t)}}set(t,e){this.cache.set(t,e),this.missing.delete(t)}setBySrc(t,e){this.set(this.srcToUrl(t),e)}async load(t){this.loading.add(t);try{const e=await this.assetStore.get(t);if(!e){this.missing.add(t);return}const n=await createImageBitmap(e.blob);this.cache.set(t,n),this.onLoaded()}catch{this.missing.add(t)}finally{this.finishLoad(t)}}finishLoad(t){if(this.loading.delete(t),!(this.loading.size>0)){for(const e of this.idleWaiters)e();this.idleWaiters.clear()}}evict(t){const e=this.cache.get(t);e&&e.close(),this.cache.delete(t),this.missing.delete(t)}clear(){for(const t of this.cache.values())t.close();this.cache.clear(),this.missing.clear()}get size(){return this.cache.size}async whenIdle(){this.loading.size!==0&&await new Promise(t=>this.idleWaiters.add(t))}}const ii="viteboard",ai=1;class ri{constructor(){m(this,"dbPromise",null)}open(){return this.dbPromise?this.dbPromise:(this.dbPromise=new Promise((t,e)=>{const n=indexedDB.open(ii,ai);n.onupgradeneeded=()=>{const o=n.result;o.objectStoreNames.contains("boards")||o.createObjectStore("boards",{keyPath:"id"}),o.objectStoreNames.contains("assets")||o.createObjectStore("assets",{keyPath:"id"})},n.onsuccess=()=>t(n.result),n.onerror=()=>e(n.error??new Error("IndexedDB open failed")),n.onblocked=()=>e(new Error("IndexedDB blocked"))}),this.dbPromise)}async put(t,e){const n=await this.open();return new Promise((o,i)=>{const a=n.transaction(t,"readwrite");a.objectStore(t).put(e),a.oncomplete=()=>o(),a.onerror=()=>i(a.error??new Error("IndexedDB write failed"))})}async get(t,e){const n=await this.open();return new Promise((o,i)=>{const r=n.transaction(t,"readonly").objectStore(t).get(e);r.onsuccess=()=>o(r.result),r.onerror=()=>i(r.error??new Error("IndexedDB read failed"))})}async delete(t,e){const n=await this.open();return new Promise((o,i)=>{const a=n.transaction(t,"readwrite");a.objectStore(t).delete(e),a.oncomplete=()=>o(),a.onerror=()=>i(a.error??new Error("IndexedDB delete failed"))})}async getAllKeys(t){const e=await this.open();return new Promise((n,o)=>{const a=e.transaction(t,"readonly").objectStore(t).getAllKeys();a.onsuccess=()=>n(a.result),a.onerror=()=>o(a.error??new Error("IndexedDB keys failed"))})}async getAll(t){const e=await this.open();return new Promise((n,o)=>{const a=e.transaction(t,"readonly").objectStore(t).getAll();a.onsuccess=()=>n(a.result),a.onerror=()=>o(a.error??new Error("IndexedDB read failed"))})}async clearStore(t){const e=await this.open();return new Promise((n,o)=>{const i=e.transaction(t,"readwrite");i.objectStore(t).clear(),i.oncomplete=()=>n(),i.onerror=()=>o(i.error??new Error("IndexedDB clear failed"))})}}const at=new ri;class ci{async get(t){try{return await at.get("assets",t)}catch{return}}async createFromBlob(t,e){const n=await li(t),o=await this.get(n);if(o)return o;const i=await createImageBitmap(t),a=Date.now(),r={id:n,type:"image",mimeType:t.type||"image/png",blob:t,width:i.width,height:i.height,sizeBytes:t.size,createdAt:a,updatedAt:a,name:e};return i.close(),await at.put("assets",r),r}async put(t){await at.put("assets",t)}async delete(t){await at.delete("assets",t)}async getAllKeys(){try{return await at.getAllKeys("assets")}catch{return[]}}async getAll(){try{return await at.getAll("assets")}catch{return[]}}async totalSizeBytes(){return(await this.getAll()).reduce((e,n)=>e+n.sizeBytes,0)}async clearUnused(t){const e=await this.getAllKeys();let n=0;for(const o of e)t.has(o)||(await at.delete("assets",o),n++);return n}async clearAll(){await at.clearStore("assets")}}const ut=new ci;async function li(s){const t=await crypto.subtle.digest("SHA-256",await s.arrayBuffer());return Array.from(new Uint8Array(t),e=>e.toString(16).padStart(2,"0")).join("")}const ee=new Map,di=2e3;function nt(s){for(const t of ee.keys())t.startsWith(s+"|")&&ee.delete(t)}function Je(s){if(s.data.shapeKind==="chevron"){if(typeof s.style.fontSize=="number"&&Number.isFinite(s.style.fontSize))return s.style.fontSize;const t=Math.abs(s.height)*.34,e=Math.abs(s.width)*.18;return Math.round(Math.max(13,Math.min(48,t,e)))}return s.style.fontSize??14}function hi(s,t,e,n){const o=ee.get(t);if(o)return o;const i=[];for(const a of e.split(`
9
+ `)){if(a===""){i.push("");continue}const r=a.split(" ");let c="";for(const l of r){const d=c===""?l:c+" "+l;s.measureText(d).width>n&&c!==""?(i.push(c),c=l):c=d}i.push(c)}return ee.size>di&&ee.clear(),ee.set(t,i),i}function ie(s,t,e,n,o,i){const a=Math.min(i,n/2,o/2);s.beginPath(),s.moveTo(t+a,e),s.arcTo(t+n,e,t+n,e+o,a),s.arcTo(t+n,e+o,t,e+o,a),s.arcTo(t,e+o,t,e,a),s.arcTo(t,e,t+n,e,a),s.closePath()}function Ye(s,t){const{ctx:e,lod:n}=t;if(e.save(),e.globalAlpha=s.style.opacity??1,n===0){pi(s,t),e.restore();return}switch(s.type){case"sticky":ui(s,t);break;case"task":mi(s,t);break;case"rectangle":case"frame":Un(s,t);break;case"ellipse":xi(s,t);break;case"text":Ci(s,t);break;case"line":case"arrow":case"connector":Si(s,t);break;case"image":case"screenshot":Ti(s,t);break;default:Un(s,t)}e.restore()}function pi(s,t){const{ctx:e}=t;if(s.type==="line"||s.type==="arrow"||s.type==="connector"){e.strokeStyle=s.style.stroke??(t.theme==="dark"?"#888":"#999"),e.lineWidth=Math.max(1/t.scale,s.style.strokeWidth??2),e.beginPath(),e.moveTo(s.x,s.y),e.lineTo(s.x+s.width,s.y+s.height),e.stroke();return}e.fillStyle=s.style.fill??(t.theme==="dark"?"#3a3d42":"#d8d8d4"),e.fillRect(s.x,s.y,s.width,s.height)}function Qe(s,t){s.style.shadow&&t.lod===2&&(t.ctx.shadowColor=t.theme==="dark"?"rgba(0,0,0,0.5)":"rgba(0,0,0,0.14)",t.ctx.shadowBlur=8*t.scale,t.ctx.shadowOffsetY=2*t.scale)}function tn(s){s.ctx.shadowColor="transparent",s.ctx.shadowBlur=0,s.ctx.shadowOffsetY=0}function ui(s,t){const{ctx:e,lod:n}=t,o=s.style.fill??"#fef08a";if(Qe(s,t),ie(e,s.x,s.y,s.width,s.height,s.style.borderRadius??12),e.fillStyle=o,e.fill(),tn(t),n===2){const i=s.data.text??"";i&&In(s,t,i,14)}}function mi(s,t){const{ctx:e,lod:n}=t,o=s.data.checked===!0,i=t.theme==="dark",a=s.style.borderRadius??14;if(Qe(s,t),ie(e,s.x,s.y,s.width,s.height,a),e.fillStyle=s.style.fill??(i?"#17191b":"#ffffff"),e.fill(),tn(t),e.strokeStyle=s.style.stroke??(i?"rgba(255,255,255,0.12)":"rgba(0,0,0,0.09)"),e.lineWidth=s.style.strokeWidth??1,e.stroke(),n<2)return;const r=Math.min(22,Math.max(16,s.height*.38)),c=s.x+16,l=s.y+s.height/2-r/2;ie(e,c,l,r,r,6),e.fillStyle=o?"#0078d4":i?"#111314":"#f3f2f1",e.fill(),e.strokeStyle=o?"#0078d4":i?"rgba(255,255,255,0.18)":"rgba(0,0,0,0.13)",e.lineWidth=1.4,e.stroke(),o&&(e.strokeStyle="#ffffff",e.lineWidth=2.1,e.lineCap="round",e.lineJoin="round",e.beginPath(),e.moveTo(c+r*.26,l+r*.52),e.lineTo(c+r*.43,l+r*.68),e.lineTo(c+r*.75,l+r*.32),e.stroke());const d=s.data.text??"";if(!d)return;const h=50,p=16,u=s.style.fontSize??15,g=s.style.fontFamily??'-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';if(e.font=`${s.style.fontWeight??"650"} ${u}px ${g}`,e.fillStyle=o?i?"#a7aaa8":"#777777":s.style.textColor??(i?"#f6f6f3":"#252829"),e.textAlign="left",e.textBaseline="middle",e.save(),e.beginPath(),e.rect(s.x+h,s.y,Math.max(10,s.width-h-p),s.height),e.clip(),e.fillText(d,s.x+h,s.y+s.height/2),o){const b=e.measureText(d),y=s.y+s.height/2+1;e.strokeStyle=i?"rgba(167,170,168,0.58)":"rgba(119,119,119,0.48)",e.lineWidth=1.3,e.beginPath(),e.moveTo(s.x+h,y),e.lineTo(s.x+h+Math.min(b.width,s.width-h-p),y),e.stroke()}e.restore()}function Un(s,t){const{ctx:e,lod:n}=t,o=s.data.shapeKind??"rectangle",i=s.style.borderRadius??0;if(Qe(s,t),o==="diamond"?fi(e,s):o==="triangle"?gi(e,s):o==="chevron"?yi(e,s):o==="parallelogram"?bi(e,s):o==="hexagon"?vi(e,s):o==="cylinder"?wi(e,s):o==="pill"?ie(e,s.x,s.y,s.width,s.height,Math.min(Math.abs(s.height)/2,Math.abs(s.width)/2)):i>0?ie(e,s.x,s.y,s.width,s.height,i):(e.beginPath(),e.rect(s.x,s.y,s.width,s.height)),s.style.fill&&s.style.fill!=="transparent"&&(e.fillStyle=s.style.fill,e.fill()),tn(t),s.style.stroke&&(s.style.strokeWidth??0)>0&&(e.strokeStyle=s.style.stroke,e.lineWidth=s.style.strokeWidth??1,e.stroke(),o==="cylinder")){const a=Math.abs(s.width)/2,r=Math.min(Math.abs(s.height)*.18,18);e.beginPath(),e.ellipse(s.x+s.width/2,s.y+r,a,r,0,0,Math.PI*2),e.stroke()}if(n===2){const a=s.data.text??"";if(a){const r=o==="chevron"?Math.min(Math.abs(s.width)*.18,Math.abs(s.height)*.55)+8:10;In(s,t,a,r)}}}function fi(s,t){const e=t.x,n=t.y,o=t.width,i=t.height;s.beginPath(),s.moveTo(e+o/2,n),s.lineTo(e+o,n+i/2),s.lineTo(e+o/2,n+i),s.lineTo(e,n+i/2),s.closePath()}function gi(s,t){const e=t.x,n=t.y,o=t.width,i=t.height;s.beginPath(),s.moveTo(e+o/2,n),s.lineTo(e+o,n+i),s.lineTo(e,n+i),s.closePath()}function yi(s,t){const e=t.x,n=t.y,o=t.width,i=t.height,a=Math.min(Math.abs(o)*.22,Math.abs(i)*.62);s.beginPath(),s.moveTo(e,n),s.lineTo(e+o-a,n),s.lineTo(e+o,n+i/2),s.lineTo(e+o-a,n+i),s.lineTo(e,n+i),s.lineTo(e+a,n+i/2),s.closePath()}function bi(s,t){const e=Math.min(Math.abs(t.width)*.2,Math.abs(t.height)*.55);s.beginPath(),s.moveTo(t.x+e,t.y),s.lineTo(t.x+t.width,t.y),s.lineTo(t.x+t.width-e,t.y+t.height),s.lineTo(t.x,t.y+t.height),s.closePath()}function vi(s,t){const e=Math.min(Math.abs(t.width)*.22,Math.abs(t.height)*.5);s.beginPath(),s.moveTo(t.x+e,t.y),s.lineTo(t.x+t.width-e,t.y),s.lineTo(t.x+t.width,t.y+t.height/2),s.lineTo(t.x+t.width-e,t.y+t.height),s.lineTo(t.x+e,t.y+t.height),s.lineTo(t.x,t.y+t.height/2),s.closePath()}function wi(s,t){const e=Math.abs(t.width)/2,n=Math.min(Math.abs(t.height)*.18,18),o=t.x+t.width/2;s.beginPath(),s.ellipse(o,t.y+n,e,n,0,Math.PI,Math.PI*2),s.lineTo(t.x+t.width,t.y+t.height-n),s.ellipse(o,t.y+t.height-n,e,n,0,0,Math.PI),s.lineTo(t.x,t.y+n),s.closePath()}function xi(s,t){const{ctx:e,lod:n}=t;if(Qe(s,t),e.beginPath(),e.ellipse(s.x+s.width/2,s.y+s.height/2,Math.abs(s.width/2),Math.abs(s.height/2),0,0,Math.PI*2),s.style.fill&&s.style.fill!=="transparent"&&(e.fillStyle=s.style.fill,e.fill()),tn(t),s.style.stroke&&(s.style.strokeWidth??0)>0&&(e.strokeStyle=s.style.stroke,e.lineWidth=s.style.strokeWidth??1,e.stroke()),n===2){const o=s.data.text??"";o&&In(s,t,o,10)}}function Ci(s,t){if(t.lod<2){t.ctx.fillStyle=t.theme==="dark"?"#55585e":"#c5c5c0",t.ctx.fillRect(s.x,s.y,s.width,Math.min(s.height,6/t.scale));return}const e=s.data.text??"";ki(s,t,e)}function ki(s,t,e){const{ctx:n}=t,o=Je(s),i=s.style.fontFamily??'-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',a=s.style.textColor??(t.theme==="dark"?"#f2f2f2":"#1f2933"),r=Math.max(10,s.width),c=_o(e),l=o*1.35;let d=s.y+l/2;n.save(),n.beginPath(),n.rect(s.x,s.y,s.width,s.height),n.clip(),n.textBaseline="middle",n.textAlign="left";for(const h of c){if(d>s.y+s.height)break;let p=h.text,u=s.x,g=o,b=a;if(h.kind==="heading"?g=h.level===1?o*1.35:h.level===2?o*1.18:o*1.08:h.kind==="quote"?(u+=14,b=t.theme==="dark"?"#cbd5e1":"#475569",n.fillStyle=t.theme==="dark"?"#334155":"#cbd5e1",n.fillRect(s.x+2,d-l/2+2,3,Math.max(l-4,10))):h.kind==="list"&&(u+=16,n.fillStyle=b,n.beginPath(),n.arc(s.x+6,d,2.2,0,Math.PI*2),n.fill()),h.kind==="code"){const v=p.split(/\r?\n/),E=g*1.45,w=v.length*E+12;n.fillStyle=t.theme==="dark"?"#111827":"#eef2f7",n.fillRect(s.x,d-l/2,Math.max(80,s.width),w);for(const S of v){if(d>s.y+s.height)break;const T=_n(n,[{text:S,code:!0}],r-12,g,i);for(const M of T){let I=s.x+8;for(const $ of M)vn(n,$,g,i),n.fillStyle=b,n.fillText($.text,I,d+6),I+=n.measureText($.text).width;d+=E}}d+=8;continue}const y=Ei(p),x=_n(n,y,r-(u-s.x),g,i);for(const v of x){if(d>s.y+s.height)break;let E=u;for(const w of v){if(vn(n,w,g,i),w.code){const S=n.measureText(w.text).width;n.fillStyle=t.theme==="dark"?"#1f2937":"#eef2f7",n.fillRect(E-2,d-g*.48,S+4,g*.96),n.fillStyle=b}else n.fillStyle=b;n.fillText(w.text,E,d),E+=n.measureText(w.text).width}d+=l}}n.restore()}function _o(s){const t=s.split(/\r?\n/),e=[];for(let n=0;n<t.length;n++){const o=t[n],i=o.trimStart();if(!i){e.push({kind:"paragraph",text:""});continue}if(/^```/.test(i)){const l=[];for(n++;n<t.length&&!/^```/.test(t[n].trimStart());)l.push(t[n]),n++;e.push({kind:"code",text:l.join(`
10
+ `)});continue}const a=i.match(/^(#{1,3})\s+(.*)$/);if(a){e.push({kind:"heading",level:a[1].length,text:a[2]});continue}const r=i.match(/^>\s?(.*)$/);if(r){e.push({kind:"quote",text:r[1]});continue}const c=i.match(/^([-*+]|\d+\.)\s+(.*)$/);if(c){e.push({kind:"list",text:c[2]});continue}e.push({kind:"paragraph",text:o})}return e}function Wt(s){if(s.type!=="text")return;const t=String(s.data.text??""),e=_o(t),n=Je(s);let o=0;for(const i of e){if(i.kind==="code"){o+=Math.max(1,i.text.split(/\r?\n/).length)+1;continue}const a=Math.max(1,Math.floor(Math.max(120,s.width)/Math.max(6,n*.6))),r=i.text.replace(/[*_`#>-]/g,"");o+=Math.max(1,Math.ceil(Math.max(1,r.length)/a))}s.height=Math.max(n*1.45,o*n*1.35+8)}function Ei(s){const t=[];let e=0;for(;e<s.length;){if(s.startsWith("**",e)){const o=s.indexOf("**",e+2);if(o!==-1){t.push({text:s.slice(e+2,o),bold:!0}),e=o+2;continue}}if(s.startsWith("*",e)){const o=s.indexOf("*",e+1);if(o!==-1){t.push({text:s.slice(e+1,o),italic:!0}),e=o+1;continue}}if(s.startsWith("`",e)){const o=s.indexOf("`",e+1);if(o!==-1){t.push({text:s.slice(e+1,o),code:!0}),e=o+1;continue}}let n=s.length;for(const o of["**","*","`"]){const i=s.indexOf(o,e+1);i!==-1&&i<n&&(n=i)}t.push({text:s.slice(e,n)}),e=n}return t.filter(n=>n.text.length>0)}function _n(s,t,e,n,o){const i=[[]];let a=0;for(const r of t){const c=r.text.split(/(\s+)/);for(const l of c){if(!l)continue;const d={...r,text:l};vn(s,d,n,o);const h=s.measureText(l).width;a>0&&a+h>e&&l.trim()&&(i.push([]),a=0),i[i.length-1].push(d),a+=h}}return i}function vn(s,t,e,n){const o=t.bold?"700":"400",i=t.italic?"italic ":"",a=t.code?'"SF Mono", ui-monospace, Menlo, monospace':n;s.font=`${i}${o} ${e}px ${a}`}function In(s,t,e,n,o="center",i="middle"){const{ctx:a}=t,r=s.data.shapeKind==="chevron",c=Je(s),l=s.style.fontFamily??'-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',d=r?"750":s.style.fontWeight??"400";a.font=`${d} ${c}px ${l}`,a.fillStyle=s.style.textColor??(t.theme==="dark"&&s.type==="text"?"#f2f2f2":"#1f2933");const h=Math.max(10,s.width-n*2),p=`${s.id}|${s.updatedAt}|${c}|${h.toFixed(0)}`,u=hi(a,p,e,h),g=c*1.35,b=u.length*g;let y;i==="middle"?y=s.y+s.height/2-b/2+g/2:y=s.y+n+g/2,a.textBaseline="middle",a.textAlign=o;const x=o==="center"?s.x+s.width/2:s.x+n;a.save(),a.beginPath(),a.rect(s.x,s.y,s.width,s.height),a.clip();for(let v=0;v<u.length;v++)a.fillText(u[v],x,y+v*g);a.restore()}function Si(s,t){const{ctx:e,lod:n}=t,o=s.x,i=s.y,a=s.x+s.width,r=s.y+s.height,c=s.style.stroke??(t.theme==="dark"?"#d1d5db":"#374151"),l=s.style.strokeWidth??2;if(e.strokeStyle=c,e.fillStyle=c,e.lineWidth=l,e.setLineDash(s.style.strokeDash??[]),e.beginPath(),e.moveTo(o,i),e.lineTo(a,r),e.stroke(),e.setLineDash([]),n>=1){const d=Math.atan2(r-i,a-o),h=Math.max(11,l*5.5);(s.style.arrowEnd??s.type==="arrow")&&Xn(e,a,r,d,h),s.style.arrowStart&&Xn(e,o,i,d+Math.PI,h);const p=typeof s.data.text=="string"?s.data.text.trim():"";if(p)if(s.data.labelPosition==="sides"){const[u,g]=p.split("|").map(b=>b.trim());u&&sn(e,u,o,i,a,r,t,.24),g&&sn(e,g,o,i,a,r,t,.76)}else sn(e,p,o,i,a,r,t)}}function sn(s,t,e,n,o,i,a,r=.5){s.font='600 13px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif';const h=s.measureText(t).width+7*2,p=21,u=e+(o-e)*r-h/2,g=n+(i-n)*r-p/2;s.fillStyle=a.theme==="dark"?"#202328":"#ffffff",ie(s,u,g,h,p,4),s.fill(),s.strokeStyle=a.theme==="dark"?"#4a4d52":"#d8dade",s.lineWidth=1,s.stroke(),s.fillStyle=a.theme==="dark"?"#f2f2f2":"#1f2933",s.textAlign="center",s.textBaseline="middle",s.fillText(t,u+h/2,g+p/2)}function Xn(s,t,e,n,o){s.beginPath(),s.moveTo(t,e),s.lineTo(t-o*Math.cos(n-Math.PI/6),e-o*Math.sin(n-Math.PI/6)),s.lineTo(t-o*Math.cos(n+Math.PI/6),e-o*Math.sin(n+Math.PI/6)),s.closePath(),s.fill()}function Ti(s,t){const{ctx:e,imageCache:n}=t,o=s.data.src,i=s.data.assetId,a=o?n.getBySrc(o):i?n.get(i):null;if(a){if(t.lod===1&&t.scale<.15){e.fillStyle=t.theme==="dark"?"#3a3d42":"#d8d8d4",e.fillRect(s.x,s.y,s.width,s.height);return}e.drawImage(a,s.x,s.y,s.width,s.height)}else if(e.fillStyle=t.theme==="dark"?"#2a2d31":"#ececea",e.fillRect(s.x,s.y,s.width,s.height),e.strokeStyle=t.theme==="dark"?"#4a4d52":"#c9c9c5",e.lineWidth=1/t.scale,e.strokeRect(s.x,s.y,s.width,s.height),t.lod===2){const c=(o?n.isMissingSrc(o):i?n.isMissing(i):!1)?"Missing image":"Loading…";e.font="12px -apple-system, sans-serif",e.fillStyle=t.theme==="dark"?"#9ca3af":"#6b7280",e.textAlign="center",e.textBaseline="middle",e.fillText(c,s.x+s.width/2,s.y+s.height/2)}}class Bi{constructor(t,e){m(this,"element");m(this,"canvas");m(this,"ctx");m(this,"imageCache");m(this,"doc",null);m(this,"region",[0,0,100,100]);m(this,"opts");m(this,"openLink");m(this,"ro");m(this,"loadPromise");this.opts=e,this.element=t,t.classList.add("board-embed"),t.textContent="";const n=document.createElement("div");n.className="board-embed-frame",n.style.height=e.height+"px",this.canvas=document.createElement("canvas"),this.ctx=this.canvas.getContext("2d"),n.appendChild(this.canvas),t.appendChild(n);const o=document.createElement("a");o.className="board-embed-open";const i=e.region?`?region=${encodeURIComponent(e.region.join(","))}`:"";if(o.href=`#/root/${encodeURIComponent(e.rootId)}/boards/${encodeURIComponent(e.src)}${i}`,o.textContent="Open board →",this.openLink=o,n.appendChild(o),e.title){const a=document.createElement("figcaption");a.textContent=e.title,t.appendChild(a)}this.imageCache=new Mn(ut,()=>this.render(),a=>k.assetUrl(this.opts.rootId,a)),this.ro=new ResizeObserver(()=>this.render()),this.ro.observe(n),this.loadPromise=this.load()}async whenReady(){await this.loadPromise,this.render(),await this.imageCache.whenIdle(),this.render()}async load(){var t;try{const e=(t=this.opts.srcCandidates)!=null&&t.length?this.opts.srcCandidates:[this.opts.src];let n=null,o=this.opts.src;for(const a of e){const r=await k.getBoard(this.opts.rootId,a);if(n=r?oe(r):null,n){o=a;break}}if(!n)return this.renderError(`Board "${this.opts.src}" not found`);this.opts.src=o;const i=this.opts.region?`?region=${encodeURIComponent(this.opts.region.join(","))}`:"";this.openLink.href=`#/root/${encodeURIComponent(this.opts.rootId)}/boards/${encodeURIComponent(o)}${i}`,this.doc=n,this.region=this.opts.region??Mi(n.elements),this.render()}catch{this.renderError("Failed to load board")}}renderError(t){var n;(n=this.element.querySelector(".board-embed-frame"))==null||n.classList.add("error");const e=this.element.querySelector(".board-embed-frame");if(e){e.innerHTML="";const o=document.createElement("span");o.className="board-embed-msg",o.textContent=t,e.appendChild(o)}}render(){if(!this.doc)return;const t=this.canvas.parentElement,e=Math.max(1,t.clientWidth),n=Math.max(1,t.clientHeight),o=Math.max(1,Math.min(4,(window.devicePixelRatio||1)*(this.opts.pixelRatioMultiplier??1)));this.canvas.width=Math.round(e*o),this.canvas.height=Math.round(n*o),this.canvas.style.width=e+"px",this.canvas.style.height=n+"px";const i=this.ctx;i.setTransform(o,0,0,o,0,0),i.clearRect(0,0,e,n),i.fillStyle=this.opts.theme==="dark"?"#111315":"#f3f2f1",i.fillRect(0,0,e,n);const[a,r,c,l]=this.region;if(c<=0||l<=0)return;const d=Math.min(e/c,n/l),h=(e-c*d)/2-a*d,p=(n-l*d)/2-r*d;i.save(),i.translate(h,p),i.scale(d,d);const u={ctx:i,scale:d,lod:2,theme:this.opts.theme,imageCache:this.imageCache},g=Math.max(c,l)*.1;for(const b of[...this.doc.elements].sort((y,x)=>y.zIndex-x.zIndex))b.hidden||b.x+b.width<a-g||b.x>a+c+g||b.y+b.height<r-g||b.y>r+l+g||Ye(b,u);i.restore()}setTheme(t){this.opts.theme!==t&&(this.opts.theme=t,this.render())}destroy(){this.ro.disconnect(),this.imageCache.clear()}}function Mi(s){if(s.length===0)return[0,0,800,600];let t=1/0,e=1/0,n=-1/0,o=-1/0;for(const a of s)t=Math.min(t,a.x,a.x+a.width),e=Math.min(e,a.y,a.y+a.height),n=Math.max(n,a.x,a.x+a.width),o=Math.max(o,a.y,a.y+a.height);const i=40;return[t-i,e-i,n-t+i*2,o-e+i*2]}function we(){return document.documentElement.getAttribute("data-theme")==="dark"?"dark":"light"}function wn(s,t,e){const{html:n,frontmatter:o}=ne(t,e),i=document.createElement("article");i.className="markdown-body",i.innerHTML=n,s.replaceChildren(i),i.querySelectorAll("pre.code-block").forEach(r=>{var h;const c=r.querySelector("code"),l=(h=c==null?void 0:c.textContent)==null?void 0:h.trimEnd();if(!l)return;const d=document.createElement("button");d.className="code-copy-btn",d.type="button",d.textContent="Copy",d.addEventListener("click",async()=>{try{await navigator.clipboard.writeText(l),d.textContent="Copied"}catch{d.textContent="Failed"}window.setTimeout(()=>{d.textContent="Copy"},1200)}),r.appendChild(d)});const a=[];return i.querySelectorAll("figure.board-embed").forEach(r=>{const c=r.dataset.src??"";if(!c)return;const l=Te(c,e.docPath),d=l[0]??"",h=r.dataset.region??"",p=h?h.split(",").map(Number):[],u=p.length===4&&p.every(y=>Number.isFinite(y))?[p[0],p[1],p[2],p[3]]:null,g=parseInt(r.dataset.height??"360",10)||360,b=r.dataset.title||null;try{a.push(new Bi(r,{rootId:e.rootId,src:d,srcCandidates:l,region:u,height:g,title:b,theme:e.theme??we(),pixelRatioMultiplier:e.boardPreviewScale}))}catch(y){console.error("Board embed failed to mount",c,y),r.textContent=`Could not load board "${c}".`}}),{frontmatter:o,ready:Promise.all(a.map(r=>r.whenReady())).then(()=>{}),destroy:()=>{for(const r of a)r.destroy()},setTheme:r=>{for(const c of a)c.setTheme(r)}}}function et(s,t){const e=document.createElement("div");e.className="modal-backdrop";const n=document.createElement("div");n.className="modal",n.setAttribute("role","dialog"),n.setAttribute("aria-label",s);const o=document.createElement("button");o.className="modal-close",o.textContent="✕",o.setAttribute("aria-label","Close");const i=document.createElement("h2");i.textContent=s;const a=document.createElement("div"),r=()=>e.remove();o.addEventListener("click",r),e.addEventListener("click",c=>{c.target===e&&r()}),e.addEventListener("keydown",c=>{c.stopPropagation(),c.key==="Escape"&&r()}),n.appendChild(o),n.appendChild(i),n.appendChild(a),e.appendChild(n),document.body.appendChild(e),t(a,r),o.focus()}let ft=null,an=null;function C(s){ft||(ft=document.createElement("div"),ft.className="toast",document.body.appendChild(ft)),ft.textContent=s,ft.classList.add("visible"),an!==null&&clearTimeout(an),an=window.setTimeout(()=>{ft==null||ft.classList.remove("visible")},2600)}const Q={select:'<svg viewBox="0 0 24 24"><path d="M4 3l7 18 2.5-7.5L21 11z"/></svg>',hand:'<svg viewBox="0 0 24 24"><path d="M18 11V6.5a1.5 1.5 0 0 0-3 0V11m0-1V4.5a1.5 1.5 0 0 0-3 0V10m0 .5v-5a1.5 1.5 0 0 0-3 0V12m9-1v1.5a1.5 1.5 0 0 1 3 0V14c0 4-2.5 7-6.5 7S8 18.5 6 15l-1.8-3.2a1.4 1.4 0 0 1 2.3-1.5L8 12V7"/></svg>',sticky:'<svg viewBox="0 0 24 24"><path d="M5 4h14a1 1 0 0 1 1 1v9l-6 6H5a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1z"/><path d="M14 20v-5a1 1 0 0 1 1-1h5"/></svg>',task:'<svg viewBox="0 0 24 24"><rect x="4" y="5" width="16" height="14" rx="3"/><path d="M8 12l2.3 2.3L16 8.8"/></svg>',rectangle:'<svg viewBox="0 0 24 24"><rect x="4" y="5" width="16" height="14" rx="2"/></svg>',ellipse:'<svg viewBox="0 0 24 24"><ellipse cx="12" cy="12" rx="8.5" ry="7"/></svg>',diamond:'<svg viewBox="0 0 24 24"><path d="M12 3l8 9-8 9-8-9z"/></svg>',triangle:'<svg viewBox="0 0 24 24"><path d="M12 4l9 16H3z"/></svg>',pill:'<svg viewBox="0 0 24 24"><rect x="3.5" y="7" width="17" height="10" rx="5"/></svg>',chevron:'<svg viewBox="0 0 24 24"><path d="M4 6h12l5 6-5 6H4l5-6z"/></svg>',parallelogram:'<svg viewBox="0 0 24 24"><path d="M7 5h13l-3 14H4z"/></svg>',hexagon:'<svg viewBox="0 0 24 24"><path d="M8 4h8l5 8-5 8H8l-5-8z"/></svg>',cylinder:'<svg viewBox="0 0 24 24"><ellipse cx="12" cy="6" rx="7" ry="3"/><path d="M5 6v11c0 1.7 3.1 3 7 3s7-1.3 7-3V6"/></svg>',arrowDashed:'<svg viewBox="0 0 24 24"><path stroke-dasharray="4 3" d="M4 12h14m0 0l-5-5m5 5l-5 5"/></svg>',arrowBoth:'<svg viewBox="0 0 24 24"><path d="M4 12h16m-16 0l5-5m-5 5l5 5m11-5l-5-5m5 5l-5 5"/></svg>',arrowLabel:'<svg viewBox="0 0 24 24"><path d="M3 17L17 7m0 0h-6m6 0v6"/><rect x="7" y="9" width="10" height="6" rx="1"/></svg>',text:'<svg viewBox="0 0 24 24"><path d="M5 6V4h14v2M12 4v16m-3 0h6"/></svg>',arrow:'<svg viewBox="0 0 24 24"><path d="M5 19L19 5m0 0h-7m7 0v7"/></svg>',image:'<svg viewBox="0 0 24 24"><rect x="3" y="4" width="18" height="16" rx="2"/><circle cx="9" cy="10" r="1.6"/><path d="M21 16l-5-5-9 9"/></svg>',templates:'<svg viewBox="0 0 24 24"><rect x="3" y="3" width="8" height="8" rx="1.5"/><rect x="13" y="3" width="8" height="8" rx="1.5"/><rect x="3" y="13" width="8" height="8" rx="1.5"/><rect x="13" y="13" width="8" height="8" rx="1.5"/></svg>',shapes:'<svg viewBox="0 0 24 24"><rect x="4" y="5" width="7" height="7" rx="1.5"/><circle cx="16.5" cy="8.5" r="3.5"/><path d="M7.5 14l3.8 6H3.7z"/><path d="M15 14h4l2 3-2 3h-4l2-3z"/></svg>',sun:'<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="4"/><path d="M12 2v2m0 16v2M4.9 4.9l1.4 1.4m11.4 11.4l1.4 1.4M2 12h2m16 0h2M4.9 19.1l1.4-1.4m11.4-11.4l1.4-1.4"/></svg>',moon:'<svg viewBox="0 0 24 24"><path d="M21 12.8A9 9 0 1 1 11.2 3 7 7 0 0 0 21 12.8z"/></svg>',export:'<svg viewBox="0 0 24 24"><path d="M12 15V3m0 0L7 8m5-5l5 5M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/></svg>',import:'<svg viewBox="0 0 24 24"><path d="M12 3v12m0 0l-5-5m5 5l5-5M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2"/></svg>',gauge:'<svg viewBox="0 0 24 24"><path d="M12 14l4-4M3.3 14a9 9 0 1 1 17.4 0"/></svg>',storage:'<svg viewBox="0 0 24 24"><ellipse cx="12" cy="5.5" rx="8" ry="2.5"/><path d="M4 5.5V12c0 1.4 3.6 2.5 8 2.5s8-1.1 8-2.5V5.5M4 12v6.5C4 19.9 7.6 21 12 21s8-1.1 8-2.5V12"/></svg>',flask:'<svg viewBox="0 0 24 24"><path d="M9 3h6M10 3v6L4.5 18a2 2 0 0 0 1.8 3h11.4a2 2 0 0 0 1.8-3L14 9V3"/><path d="M7 15h10"/></svg>',reset:'<svg viewBox="0 0 24 24"><path d="M3 12a9 9 0 1 0 2.6-6.3M3 4v5h5"/></svg>',camera:'<svg viewBox="0 0 24 24"><path d="M3 8a2 2 0 0 1 2-2h2l2-2h6l2 2h2a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><circle cx="12" cy="13" r="3.5"/></svg>',trash:'<svg viewBox="0 0 24 24"><path d="M4 7h16M10 11v6m4-6v6M6 7l1 13a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1l1-13M9 7V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v3"/></svg>',embed:'<svg viewBox="0 0 24 24"><rect x="3" y="5" width="18" height="14" rx="2" stroke-dasharray="3 3"/><path d="M9 10l-2 2 2 2m6-4l2 2-2 2"/></svg>',arrowLeft:'<svg viewBox="0 0 24 24"><path d="M19 12H5m0 0l6-6m-6 6l6 6"/></svg>',search:'<svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="M20 20l-4-4"/></svg>',panelLeft:'<svg viewBox="0 0 24 24"><rect x="4" y="4" width="16" height="16" rx="2"/><path d="M10 4v16"/></svg>',edit:'<svg viewBox="0 0 24 24"><path d="M12 20h9"/><path d="M16.5 3.5a2.1 2.1 0 0 1 3 3L7 19l-4 1 1-4z"/></svg>',copy:'<svg viewBox="0 0 24 24"><rect x="8" y="8" width="11" height="11" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v1"/></svg>',folder:'<svg viewBox="0 0 24 24"><path d="M4 7a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2z"/></svg>',folderOpen:'<svg viewBox="0 0 24 24"><path d="M4 7a2 2 0 0 1 2-2h4l2 2h6a2 2 0 0 1 2 2v1M4 8l1.5 9c.1.6.6 1 1.2 1h10.6c.6 0 1.1-.4 1.2-1L20 8z"/></svg>',file:'<svg viewBox="0 0 24 24"><path d="M13 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V10z"/><path d="M13 3v7h7"/></svg>',fileText:'<svg viewBox="0 0 24 24"><path d="M13 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V10z"/><path d="M13 3v7h7M10 13h4m-4 4h4"/></svg>',board:'<svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="12" y="3" width="9" height="7" rx="1"/><rect x="3" y="12" width="9" height="9" rx="1"/><rect x="14" y="12" width="7" height="9" rx="1"/></svg>',doc:'<svg viewBox="0 0 24 24"><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><path d="M14 3v6h6M10 13h4m-4 4h4m-4-8h1"/></svg>',skill:'<svg viewBox="0 0 24 24"><path d="M12 2l3.1 6.3 6.9 1-5 4.9 1.2 6.8-6.2-3.3-6.2 3.3 1.2-6.8-5-4.9 6.9-1z"/></svg>',plus:'<svg viewBox="0 0 24 24"><path d="M12 5v14m-7-7h14"/></svg>',moreVertical:'<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>',chevronRight:'<svg viewBox="0 0 24 24"><path d="M9 18l6-6-6-6"/></svg>',chevronDown:'<svg viewBox="0 0 24 24"><path d="M6 9l6 6 6-6"/></svg>',wiki:'<svg viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6M8 13h2m-2 4h6m-6-8h1"/></svg>',list:'<svg viewBox="0 0 24 24"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><circle cx="4" cy="6" r="1"/><circle cx="4" cy="12" r="1"/><circle cx="4" cy="18" r="1"/></svg>'};let me=null;async function Yn(s){const t=await Xo(s);if(t.length===0)throw new Error("No markdown documents were found to export.");me==null||me();const e=Yo(s,t);let n={...e};const o=new Set(t.map(A=>A.path));let i=null,a=!1;const r=R("docs-export-studio-backdrop"),c=R("docs-export-studio");c.setAttribute("role","dialog"),c.setAttribute("aria-modal","true"),c.setAttribute("aria-label","Publication studio");const l=R("docs-export-studio-header"),d=R("docs-export-studio-header-copy"),h=document.createElement("span");h.textContent="Publication studio";const p=document.createElement("h2");p.textContent=n.title;const u=document.createElement("p");u.textContent="Tune the publication, inspect the exact preview, then export the same document you are looking at.",d.append(h,p,u);const g=R("docs-export-studio-header-actions"),b=ae("btn docs-export-primary-btn","Export PDF");b.innerHTML=`${Q.export}<span>Export PDF</span>`;const y=ae("btn docs-export-secondary-btn docs-export-studio-close","Close");y.innerHTML='<span aria-hidden="true">x</span>',y.title="Close publication studio",y.setAttribute("aria-label","Close publication studio"),y.addEventListener("click",()=>Be()),g.append(b,y),l.append(d,g);const x=R("docs-export-studio-layout"),v=R("docs-export-studio-controls"),E=R("docs-export-studio-controls-body");v.appendChild(E);const w=R("docs-export-preview-shell"),S=R("docs-export-preview-header"),B=R("docs-export-preview-header-copy"),T=document.createElement("span");T.textContent="Live preview";const M=document.createElement("strong");M.textContent=ke(n.title),B.append(T,M);const I=R("docs-export-preview-meta");S.append(B,I);const $=R("docs-export-preview-scroll");w.append(S,$),x.append(v,w),c.append(l,x),r.appendChild(c),document.body.appendChild(r);const P=Nt("Publication title",n.title),ot=Nt("Subtitle",n.subtitle,{placeholder:"Optional context line"}),tt=Nt("Author",n.author,{placeholder:"Optional"}),W=Nt("Organization",n.organization,{placeholder:"Optional"}),Z=Nt("Publication date",n.publicationDate,{type:"date"}),st=Nt("Classification",n.classification),O=Ki("Notice",n.legalNotice,{placeholder:"Optional legal or distribution note"}),_=rn("Style",[{value:"clean",label:"Clean"},{value:"report",label:"Report"}],n.style),V=rn("Paper",[{value:"A4",label:"A4"},{value:"Letter",label:"Letter"}],n.paper),D=rn("Scale",[{value:"90",label:"90%"},{value:"100",label:"100%"},{value:"110",label:"110%"}],n.scale),q=Gt("Include cover page",n.includeCoverPage,"Adds a formal front page before the content."),F=Gt("Include table of contents",n.includeTableOfContents,"Lists the included document sections before the publication begins."),K=Gt("Show file paths",n.includeFilePaths,"Displays repo-relative paths above included documents."),ct=Gt("Start each document on a new page",n.pageBreakBetweenDocs,"Useful when compiling a directory tree into one publication."),Lt=Gt("Show page header",n.showHeaderChrome,"Adds a compact publication header bar to each included document section."),Xt=Gt("Show page footer",n.showFooterChrome,"Adds a compact publication footer bar to each included document section."),he=Wi(n.logoDataUrl,()=>pe()),Pt=()=>t.filter(A=>o.has(A.path)),$t=s.kind==="dir"?Hi(t,o,{onSelectionChange:()=>pe()}):null;E.append($e(1,"Publication",[P.field,ot.field,_.field,V.field,D.field,he.field]),$e(2,"Metadata",[tt.field,W.field,Z.field,st.field,O.field]),$e(3,"Structure",[q.wrapper,F.wrapper,K.wrapper,ct.wrapper,Lt.wrapper,Xt.wrapper])),$t&&E.appendChild($e(4,"Included documents",[$t.element]));const xs=()=>{const A=Pt();i==null||i.handles.forEach(Me=>Me.destroy()),i==null||i.shell.remove(),i=Vo(s,A,n),$.replaceChildren(i.shell)},Nn=()=>{const A=Pt();p.textContent=n.title,M.textContent=ke(n.title),I.replaceChildren(De(`${A.length} ${A.length===1?"doc":"docs"}`),De(n.style==="report"?"Report style":"Clean style"),De(n.paper),De(`${n.scale}%`)),b.disabled=A.length===0},pe=()=>{n={title:P.input.value.trim()||e.title,subtitle:ot.input.value.trim(),style:Zo(_.select.value)?_.select.value:e.style,paper:Jo(V.select.value)?V.select.value:e.paper,scale:Qo(D.select.value)?D.select.value:e.scale,includeCoverPage:q.input.checked,includeTableOfContents:F.input.checked&&Pt().length>1,includeFilePaths:K.input.checked,pageBreakBetweenDocs:ct.input.checked,showHeaderChrome:Lt.input.checked,showFooterChrome:Xt.input.checked,author:tt.input.value.trim(),organization:W.input.value.trim(),publicationDate:Z.input.value.trim(),classification:st.input.value.trim(),legalNotice:O.textarea.value.trim(),logoDataUrl:he.getValue()},$t==null||$t.refresh(),Nn(),xs()};b.addEventListener("click",async()=>{const A=Pt();if(A.length===0){C("Select at least one document to export.");return}if(!i){C("Preview is still preparing.");return}b.disabled=!0;try{await Li(i,s,A,n)}catch(Me){C(Me instanceof Error?Me.message:"Could not export PDF")}finally{b.disabled=!1,Nn()}}),[P.input,ot.input,tt.input,W.input,Z.input,st.input,O.textarea].forEach(A=>A.addEventListener("input",pe)),[_.select,V.select,D.select,q.input,F.input,K.input,ct.input,Lt.input,Xt.input].forEach(A=>{A.addEventListener("change",pe)});const Fn=A=>{A.target===r&&Be()},zn=A=>{A.key==="Escape"&&(A.preventDefault(),Be())};r.addEventListener("mousedown",Fn),document.addEventListener("keydown",zn,!0);function Be(){a||(a=!0,me=null,r.removeEventListener("mousedown",Fn),document.removeEventListener("keydown",zn,!0),i==null||i.handles.forEach(A=>A.destroy()),i=null,r.remove())}me=Be,pe(),P.input.focus()}async function Ii(s){const e=(await k.getWorkspace()).projects.flatMap(l=>l.docsRoots).find(l=>l.id===s.rootId);if(!e)throw new Error("Docs root not found");const n=s.kind==="doc"?{kind:"doc",root:e,filePath:s.path}:{kind:"dir",root:e,dirPath:s.path},o=await Xo(n),i=s.selectedPaths?new Set(s.selectedPaths):null,a=i?o.filter(l=>i.has(l.path)):o;if(a.length===0)throw new Error("No markdown documents were selected for export");const r=Ri(Yo(n,a),s.options??{},a.length),c=Vo(n,a,r);return qo(c,n,a,r)}function Ri(s,t,e){return{...s,...t,style:typeof t.style=="string"&&Zo(t.style)?t.style:s.style,paper:typeof t.paper=="string"&&Jo(t.paper)?t.paper:s.paper,scale:typeof t.scale=="string"&&Qo(t.scale)?t.scale:s.scale,title:typeof t.title=="string"?t.title:s.title,subtitle:typeof t.subtitle=="string"?t.subtitle:"",author:typeof t.author=="string"?t.author:"",organization:typeof t.organization=="string"?t.organization:"",publicationDate:typeof t.publicationDate=="string"?t.publicationDate:"",classification:typeof t.classification=="string"?t.classification:"",legalNotice:typeof t.legalNotice=="string"?t.legalNotice:"",logoDataUrl:typeof t.logoDataUrl=="string"&&/^data:image\/(png|jpeg|webp);base64,/i.test(t.logoDataUrl)?t.logoDataUrl:"",includeCoverPage:t.includeCoverPage===!0,includeTableOfContents:t.includeTableOfContents===!0&&e>1,includeFilePaths:t.includeFilePaths===!0,pageBreakBetweenDocs:t.pageBreakBetweenDocs===!0,showHeaderChrome:t.showHeaderChrome===!0,showFooterChrome:t.showFooterChrome===!0}}async function Xo(s){const t=s.tree??await k.getTree(s.root.id),e=s.kind==="doc"?[s.filePath]:Oi(t,s.dirPath),n=[...new Set(e)].sort(_i);return(await Promise.all(n.map(async i=>({path:i,markdown:await k.readFile(s.root.id,i)})))).map(({path:i,markdown:a})=>{var c,l;const{frontmatter:r}=ne(a);return{path:i,title:((c=r.title)==null?void 0:c.trim())||Yi(a)||Rt(Ko(i)),summary:((l=r.summary)==null?void 0:l.trim())||"",markdown:a}})}function Yo(s,t){var n;return{title:s.kind==="doc"?((n=t[0])==null?void 0:n.title)||Rt(Ko(s.filePath)):s.dirPath?Rt(Rn(s.dirPath)||s.root.displayPath.split("/").pop()||s.root.projectLabel):`${s.root.projectLabel} Docs`,subtitle:"",style:s.kind==="doc"?"clean":"report",paper:"A4",scale:"100",includeCoverPage:!1,includeTableOfContents:!1,includeFilePaths:!1,pageBreakBetweenDocs:!1,showHeaderChrome:!1,showFooterChrome:!1,author:"",organization:"",publicationDate:"",classification:"",legalNotice:"",logoDataUrl:""}}function Vo(s,t,e){const n=R("docs-export-publication-shell");n.dataset.docsExportStyle=e.style,n.dataset.docsExportPaper=e.paper,n.dataset.docsExportMode=s.kind,n.dataset.docsExportScale=e.scale;const o=R("docs-export-publication");if(n.appendChild(o),t.length===0)return o.appendChild(ji()),{shell:n,handles:[]};e.includeCoverPage&&o.appendChild(Ni(s,t,e)),e.includeTableOfContents&&t.length>1&&o.appendChild(Fi(t,s,e));const i=[],a=s.kind==="dir"?t.map(c=>Vn(s,c.path).key):[];let r="";return t.forEach((c,l)=>{let d=null,h=!1;s.kind==="dir"&&(d=Vn(s,c.path),d.key&&d.key!==r&&(h=!0,r=d.key));const p=document.createElement("section");p.className="docs-export-doc",p.id=`docs-export-section-${l+1}`,h&&d&&p.appendChild(zi(d));const u=Di(s,c,e,l,t.length);u&&p.appendChild(u);const g=R("docs-export-doc-body");p.appendChild(g);const b=s.kind==="dir"?l<t.length-1&&a[l+1]!==a[l]:!1;l<t.length-1&&(e.pageBreakBetweenDocs||b)&&p.classList.add("docs-export-doc-break-after"),o.appendChild(p),i.push(wn(g,qi(c.markdown,c.title),{rootId:s.root.id,docPath:c.path,theme:"light",boardPreviewScale:2.5}))}),{shell:n,handles:i}}async function Li(s,t,e,n){var r;const o=await qo(s,t,e,n),i=await fetch("/__api/export/pdf",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(o)});if(!i.ok){let c="";try{c=((r=await i.json())==null?void 0:r.error)??""}catch{}throw new Error(c||`PDF export failed (${i.status})`)}const a=await i.blob();Zi(a,ke(n.title))}async function qo(s,t,e,n){var i;const o=s.shell.isConnected?null:Pi(s.shell);try{await Promise.all(s.handles.map(r=>r.ready)),await((i=document.fonts)==null?void 0:i.ready),await Promise.all(Array.from(s.shell.querySelectorAll("img")).map(r=>r.decode().catch(()=>{})));const a=Ai(t,e,n);return{html:await $i(s.shell,n),fileName:ke(n.title),pdf:{paper:n.paper,marginTopMm:a.marginTopMm,marginBottomMm:a.marginBottomMm,marginLeftMm:14,marginRightMm:14,displayHeaderFooter:a.displayHeaderFooter,headerTemplate:a.headerTemplate,footerTemplate:a.footerTemplate}}}finally{o==null||o.remove()}}function Pi(s){const t=document.createElement("div");return t.setAttribute("aria-hidden","true"),t.style.cssText="position:fixed;left:-100000px;top:0;width:900px;visibility:hidden;pointer-events:none;z-index:-1;",t.appendChild(s),document.body.appendChild(t),t}async function $i(s,t){const e=s.cloneNode(!0),n=Array.from(s.querySelectorAll("canvas")),o=Array.from(e.querySelectorAll("canvas"));n.forEach((r,c)=>{var d;const l=document.createElement("img");l.src=r.toDataURL("image/png"),l.width=r.width,l.height=r.height,l.className=r.className,l.style.cssText=r.style.cssText,l.alt="Board preview",(d=o[c])==null||d.replaceWith(l)}),e.querySelectorAll(".code-copy-btn, .board-embed-open").forEach(r=>r.remove());const i=Gi(),a=t.paper==="Letter"?"@page { size: Letter; }":"@page { size: A4; }";return["<!doctype html>",'<html data-theme="light" data-docs-export-print="true">',"<head>",'<meta charset="utf-8" />','<meta name="viewport" content="width=device-width, initial-scale=1" />',`<title>${Xe(ke("publication"))}</title>`,`<style>${i}</style>`,`<style>${a} html,body{margin:0;padding:0;background:var(--surface-raised);-webkit-print-color-adjust:exact;print-color-adjust:exact;} .docs-export-publication-shell{position:static!important;visibility:visible!important;pointer-events:auto!important;} .docs-export-publication{padding:0!important;background:transparent!important;} .docs-export-cover,.docs-export-toc,.docs-export-doc,.docs-export-branch-break{box-shadow:none!important;} </style>`,"</head>",`<body>${e.outerHTML}</body>`,"</html>"].join("")}function Di(s,t,e,n,o){const i=R("docs-export-doc-header"),a=document.createElement("p");a.className="docs-export-doc-eyebrow",a.textContent=s.kind==="dir"?Xi(s,t.path):"Document";const r=document.createElement("div");r.className="docs-export-doc-context";const c=document.createElement("span");c.textContent=s.kind==="dir"?[s.root.projectLabel,le(s.dirPath)||s.root.displayPath].filter(Boolean).join(" / "):e.title.trim();const l=document.createElement("span");l.textContent=`Document ${String(n+1).padStart(2,"0")} of ${o}`;const d=document.createElement("h2");if(d.textContent=t.title,i.append(a,r,d),r.append(c,l),e.includeFilePaths){const h=document.createElement("div");h.className=`docs-export-doc-path${s.kind==="doc"?" docs-export-doc-path-single":""}`,h.textContent=t.path,i.appendChild(h)}return i}function Ai(s,t,e){var l;const n=e.showHeaderChrome||e.showFooterChrome,o=Gn([e.title.trim(),e.classification.trim()]).join(" / "),i=Gn([e.organization.trim(),e.organization.trim().toLowerCase()===s.root.projectLabel.trim().toLowerCase()?"":s.root.projectLabel,Go(e.publicationDate.trim())]).join(" / "),a=s.kind==="doc"?((l=t[0])==null?void 0:l.title)??e.title.trim():[le(s.dirPath)||s.root.displayPath,`${t.length} ${t.length===1?"doc":"docs"}`].filter(Boolean).join(" / "),r=e.showHeaderChrome?`<div style="width:100%;font:700 10px/1.2 Inter,Arial,sans-serif;color:#707070;letter-spacing:.05em;text-transform:uppercase;padding:0 2mm 3.5mm 2mm;border-bottom:1px solid rgba(0,0,0,.12);display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px;"><span style="color:#5a5a5a;">${Xe(o)}</span><span style="text-align:right;color:#777777;">${Xe(i)}</span></div>`:"<div></div>",c=e.showFooterChrome?`<div style="width:100%;font:700 10px/1.2 Inter,Arial,sans-serif;color:#707070;letter-spacing:.05em;text-transform:uppercase;padding:3.5mm 2mm 0 2mm;border-top:1px solid rgba(0,0,0,.12);display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px;"><span style="color:#5a5a5a;">${Xe(a)}</span><span style="text-align:right;color:#777777;">Page <span class="pageNumber"></span> of <span class="totalPages"></span></span></div>`:"<div></div>";return{displayHeaderFooter:n,headerTemplate:r,footerTemplate:c,marginTopMm:e.showHeaderChrome?28:14,marginBottomMm:e.showFooterChrome?20:14}}function Ni(s,t,e){const n=document.createElement("section");n.className="docs-export-cover";const o=document.createElement("div");o.className="docs-export-cover-eyebrow",o.textContent=s.kind==="doc"?"Document export":"Directory export";const i=document.createElement("h1");i.textContent=e.title;const a=document.createElement("p");if(a.className="docs-export-cover-subtitle",a.textContent=e.subtitle.trim(),e.logoDataUrl){const l=document.createElement("img");l.className="docs-export-cover-logo",l.src=e.logoDataUrl,l.alt="Publication logo",n.appendChild(l)}const r=R("docs-export-cover-meta"),c=[Kt("Scope",s.kind==="doc"?"Single document":`${t.length} documents compiled`),Kt("Source",`${s.root.projectLabel} / ${s.root.displayPath}`),Kt("Author",e.author.trim()),Kt("Organization",e.organization.trim()),Kt("Date",Go(e.publicationDate.trim())),Kt("Classification",e.classification.trim())].filter(Boolean);if(n.appendChild(o),n.appendChild(i),a.textContent&&n.appendChild(a),c.length&&(r.append(...c),n.appendChild(r)),e.legalNotice.trim()){const l=document.createElement("p");l.className="docs-export-cover-notice",l.textContent=e.legalNotice.trim(),n.appendChild(l)}return n}function Fi(s,t,e){const n=document.createElement("section");n.className="docs-export-toc";const o=document.createElement("h2");o.textContent="Contents";const i=document.createElement("p");i.className="docs-export-toc-note",i.textContent=t.kind==="doc"?"Compiled from the current markdown file.":`${s.length} documents were flattened from the selected directory tree.`;const a=document.createElement("ol");return a.className="docs-export-toc-list",s.forEach((r,c)=>{const l=document.createElement("li"),d=document.createElement("a");d.className="docs-export-toc-row",d.href=`#docs-export-section-${c+1}`;const h=R("docs-export-toc-label"),p=document.createElement("strong");if(p.textContent=r.title,h.appendChild(p),e.includeFilePaths){const g=document.createElement("small");g.textContent=r.path,h.appendChild(g)}const u=document.createElement("span");u.textContent=String(c+1).padStart(2,"0"),d.append(h,u),l.appendChild(d),a.appendChild(l)}),n.append(o,i,a),n}function zi(s){const t=document.createElement("section");t.className="docs-export-branch-break";const e=document.createElement("p");e.className="docs-export-branch-breadcrumb",e.textContent=s.breadcrumb;const n=document.createElement("h2");n.textContent=s.title;const o=R("docs-export-branch-rule");return t.append(e,n,o),t}function ji(){const s=document.createElement("section");s.className="docs-export-empty-publication";const t=document.createElement("h2");t.textContent="No documents selected";const e=document.createElement("p");return e.textContent="Use the Included documents section to choose at least one document for this publication.",s.append(t,e),s}function Vn(s,t){const e=le(s.dirPath),o=(e&&t.startsWith(`${e}/`)?t.slice(e.length+1):t).split("/").filter(Boolean).slice(0,-1),i=o.join("/");return i?{key:i,breadcrumb:o.slice(0,-1).map(Rt).join(" / ")||s.root.projectLabel,title:Rt(o[o.length-1])}:{key:i,breadcrumb:s.root.projectLabel,title:Rt(Rn(e)||s.root.displayPath.split("/").pop()||s.root.projectLabel)}}function Hi(s,t,e){const n=document.createElement("details");n.className="docs-export-disclosure";const o=document.createElement("summary");o.className="docs-export-disclosure-summary";const i=R("docs-export-disclosure-summary-text"),a=document.createElement("strong");a.textContent="Choose included documents";const r=document.createElement("small");i.append(a,r);const c=document.createElement("span");c.className="docs-export-disclosure-badge",o.append(i,c);const l=R("docs-export-disclosure-body"),d=Nt("Search documents","",{placeholder:"Filter by title or path"});d.field.classList.add("docs-export-doc-search");const h=R("docs-export-doc-picker-actions"),p=ae("btn docs-export-secondary-btn","Select all"),u=ae("btn docs-export-secondary-btn","Clear all");p.addEventListener("click",v=>{v.preventDefault(),s.forEach(E=>t.add(E.path)),x(),e.onSelectionChange()}),u.addEventListener("click",v=>{v.preventDefault(),t.clear(),x(),e.onSelectionChange()}),h.append(p,u);const g=R("docs-export-doc-picker-list"),b=new Map,y=new Map;s.forEach(v=>{const E=document.createElement("label");E.className="docs-export-doc-picker-item",y.set(v.path,E);const w=document.createElement("input");w.type="checkbox",w.checked=!0,w.addEventListener("change",()=>{w.checked?t.add(v.path):t.delete(v.path),x(),e.onSelectionChange()}),b.set(v.path,w);const S=R("docs-export-doc-picker-copy"),B=document.createElement("strong");B.textContent=v.title;const T=document.createElement("small");if(T.textContent=v.path,S.append(B,T),v.summary){const M=document.createElement("p");M.textContent=v.summary,S.appendChild(M)}E.append(w,S),g.appendChild(E)}),d.input.addEventListener("input",()=>x()),l.append(d.field,h,g),n.append(o,l);function x(){const v=s.filter(w=>t.has(w.path)).length,E=Kn(d.input.value);r.textContent=`${v} of ${s.length} included`,c.textContent=`${v}`,n.dataset.selectionState=v===0?"empty":v===s.length?"full":"partial",b.forEach((w,S)=>{w.checked=t.has(S);const B=y.get(S);if(!B)return;if(!E){B.hidden=!1;return}const T=s.find(I=>I.path===S),M=Kn(`${(T==null?void 0:T.title)??""} ${S}`);B.hidden=!M.includes(E)}),u.disabled=v===0,p.disabled=v===s.length}return x(),{element:n,refresh:x}}function $e(s,t,e){const n=document.createElement("section");n.className="docs-export-studio-section";const o=R("docs-export-studio-section-heading"),i=document.createElement("span");i.textContent=String(s).padStart(2,"0");const a=document.createElement("strong");return a.textContent=t,o.append(i,a),n.appendChild(o),e.forEach(r=>n.appendChild(r)),n}function Kt(s,t){if(!t.trim())return null;const e=R("docs-export-cover-row"),n=document.createElement("span");n.textContent=s;const o=document.createElement("strong");return o.textContent=t,e.append(n,o),e}function De(s){const t=document.createElement("span");return t.className="docs-export-preview-chip",t.textContent=s,t}function Wi(s,t){let e=s;const n=R("docs-export-logo-field"),o=document.createElement("span");o.className="docs-export-logo-field-label",o.textContent="Title page logo";const i=R("docs-export-logo-actions"),a=document.createElement("input");a.type="file",a.accept="image/*",a.hidden=!0;const r=ae("btn docs-export-secondary-btn","Upload logo"),c=ae("btn docs-export-secondary-btn","Clear"),l=R("docs-export-logo-preview"),d=()=>{if(l.replaceChildren(),e){const h=document.createElement("img");h.src=e,h.alt="Selected logo preview",l.appendChild(h)}else l.textContent="No logo selected";c.disabled=!e};return r.addEventListener("click",()=>a.click()),c.addEventListener("click",()=>{e="",a.value="",d(),t()}),a.addEventListener("change",()=>{var u;const h=(u=a.files)==null?void 0:u[0];if(!h)return;const p=new FileReader;p.onload=()=>{e=typeof p.result=="string"?p.result:"",d(),t()},p.readAsDataURL(h)}),i.append(r,c),n.append(o,i,l,a),d(),{field:n,getValue:()=>e}}function Oi(s,t){const e=le(t);return Ui(xn(s)).map(n=>n.path).filter(n=>e?n===e||n.startsWith(`${e}/`):!0)}function xn(s){return s.filter(t=>t.type==="file"?t.name.endsWith(".md"):t.name==="capabilities"||t.name==="assets"?!1:xn(t.children).length>0).map(t=>t.type==="file"?t:{...t,children:xn(t.children)})}function Ui(s){const t=[],e=n=>{for(const o of n)o.type==="file"?t.push(o):e(o.children)};return e(s),t}function _i(s,t){const e=qn(s),n=qn(t);return e.localeCompare(n)||s.localeCompare(t)}function qn(s){return s.split("/").filter(Boolean).map(t=>{const e=t.toLowerCase();if(e==="index.md")return"00000-index";if(e==="readme.md")return"00001-readme";const n=t.match(/^(\d+)/);return`${n?n[1].padStart(5,"0"):"99999"}-${e}`}).join("/")}function Xi(s,t){if(s.kind!=="dir")return`${s.root.projectLabel} / ${t}`;const e=le(s.dirPath),o=(e&&t.startsWith(`${e}/`)?t.slice(e.length+1):t).split("/").filter(Boolean).slice(0,-1).map(i=>Rt(i));return o.length?o.join(" / "):e?Rt(Rn(e)):s.root.projectLabel}function ke(s){return`${Vi(s)}.pdf`}function Yi(s){for(const t of s.split(/\r?\n/)){const e=t.match(/^#{1,6}\s+(.+?)\s*#*\s*$/);if(e!=null&&e[1])return Cn(e[1])}return null}function Cn(s){return s.replace(/`([^`]+)`/g,"$1").replace(/\*\*([^*]+)\*\*/g,"$1").replace(/__([^_]+)__/g,"$1").replace(/\*([^*]+)\*/g,"$1").replace(/_([^_]+)_/g,"$1").replace(/\[([^\]]+)\]\([^)]+\)/g,"$1").replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim()}function le(s){return s.replace(/^\/+|\/+$/g,"")}function Kn(s){return s.toLowerCase().replace(/\s+/g," ").trim()}function Vi(s){return s.trim().replace(/[\\/:*?"<>|]+/g,"-").replace(/\s+/g," ").slice(0,120)||"export"}function Ko(s){return s.split("/").pop()??s}function Rn(s){return le(s).split("/").filter(Boolean).pop()??""}function Rt(s){return s.replace(/\.md$/i,"").replace(/^\d+[-_\s]*/,"").replace(/[-_]+/g," ").replace(/\s+/g," ").trim().replace(/\b\w/g,t=>t.toUpperCase())||s}function Go(s){if(!s)return"";const t=new Date(`${s}T12:00:00Z`);return Number.isNaN(t.getTime())?s:new Intl.DateTimeFormat("en-CA",{timeZone:"UTC",month:"long",day:"numeric",year:"numeric"}).format(t)}function Gn(s){const t=new Set,e=[];for(const n of s.map(o=>o.trim()).filter(Boolean)){const o=n.toLowerCase();t.has(o)||(t.add(o),e.push(n))}return e}function qi(s,t){var i;const e=s.split(/\r?\n/);let n=0;for(;n<e.length&&!e[n].trim();)n+=1;const o=(i=e[n])==null?void 0:i.match(/^#\s+(.+?)\s*#*\s*$/);if(!o||Cn(o[1]).toLowerCase()!==Cn(t).toLowerCase())return s;for(e.splice(n,1);n<e.length&&!e[n].trim();)e.splice(n,1);return e.join(`
11
+ `)}function Nt(s,t,e={}){const n=document.createElement("label");n.className="docs-export-field";const o=document.createElement("span");o.textContent=s;const i=document.createElement("input");return i.type=e.type||"text",i.value=t,e.placeholder&&(i.placeholder=e.placeholder),n.append(o,i),{field:n,input:i}}function Ki(s,t,e={}){const n=document.createElement("label");n.className="docs-export-field docs-export-field-textarea";const o=document.createElement("span");o.textContent=s;const i=document.createElement("textarea");return i.rows=4,i.value=t,e.placeholder&&(i.placeholder=e.placeholder),n.append(o,i),{field:n,textarea:i}}function rn(s,t,e){const n=document.createElement("label");n.className="docs-export-field";const o=document.createElement("span");o.textContent=s;const i=document.createElement("select");return t.forEach(a=>{const r=document.createElement("option");r.value=a.value,r.textContent=a.label,r.selected=a.value===e,i.appendChild(r)}),n.append(o,i),{field:n,select:i}}function Gt(s,t,e){const n=document.createElement("label");n.className="docs-export-checkbox";const o=document.createElement("input");o.type="checkbox",o.checked=t;const i=R("docs-export-checkbox-copy"),a=document.createElement("strong");a.textContent=s;const r=document.createElement("small");return r.textContent=e,i.append(a,r),n.append(o,i),{input:o,wrapper:n}}function R(s){const t=document.createElement("div");return t.className=s,t}function ae(s,t){const e=document.createElement("button");return e.className=s,e.type="button",e.textContent=t,e}function Zo(s){return s==="clean"||s==="report"}function Jo(s){return s==="A4"||s==="Letter"}function Qo(s){return s==="90"||s==="100"||s==="110"}function Gi(){let s="";for(const t of Array.from(document.styleSheets))try{const e=t.cssRules;for(const n of Array.from(e))s+=`${n.cssText}
12
+ `}catch{}return s}function Zi(s,t){const e=URL.createObjectURL(s),n=document.createElement("a");n.href=e,n.download=t,n.click(),URL.revokeObjectURL(e)}function Xe(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\"/g,"&quot;").replace(/'/g,"&#39;")}const Ji=.05,Qi=40,ts=1;function H(s,t,e){return{x:(s-e.offsetX)/e.scale,y:(t-e.offsetY)/e.scale}}function Ot(s,t,e){return{x:s*e.scale+e.offsetX,y:t*e.scale+e.offsetY}}function es(s){return Math.min(Qi,Math.max(Ji,s))}function Ee(s,t,e,n){const o=es(n),i={x:(t-s.offsetX)/s.scale,y:(e-s.offsetY)/s.scale};s.scale=o,s.offsetX=t-i.x*s.scale,s.offsetY=e-i.y*s.scale}function ta(s,t,e){const n=H(0,0,s),o=H(t,e,s);return{left:n.x,top:n.y,right:o.x,bottom:o.y}}class ns{constructor(){m(this,"schemaUrl");m(this,"boardId","default-board");m(this,"title","Untitled Board");m(this,"createdAt",Date.now());m(this,"viewport",{offsetX:0,offsetY:0,scale:ts});m(this,"theme","light");m(this,"elements",[]);m(this,"elementsById",new Map);m(this,"selectedIds",new Set);m(this,"hoveredId",null);m(this,"sortedCache",null);m(this,"changeListeners",[]);m(this,"renderListeners",[])}onChange(t){this.changeListeners.push(t)}onRenderNeeded(t){this.renderListeners.push(t)}emitChange(){this.sortedCache=null;for(const t of this.changeListeners)t();this.requestRender()}requestRender(){for(const t of this.renderListeners)t()}addElement(t){this.elements.push(t),this.elementsById.set(t.id,t),this.sortedCache=null}removeElement(t){const e=this.elementsById.get(t);if(!e)return;this.elementsById.delete(t);const n=this.elements.indexOf(e);return n>=0&&this.elements.splice(n,1),this.selectedIds.delete(t),this.sortedCache=null,e}getSorted(){return this.sortedCache||(this.sortedCache=[...this.elements].sort((t,e)=>t.zIndex-e.zIndex)),this.sortedCache}invalidateSort(){this.sortedCache=null}maxZIndex(){let t=0;for(const e of this.elements)e.zIndex>t&&(t=e.zIndex);return t}minZIndex(){let t=0;for(const e of this.elements)e.zIndex<t&&(t=e.zIndex);return t}getSelected(){const t=[];for(const e of this.selectedIds){const n=this.elementsById.get(e);n&&t.push(n)}return t}clearSelection(){this.selectedIds.clear()}getVisibleElements(t){const e=[];for(const n of this.getSorted())n.hidden||ea(n,t)&&e.push(n);return e}}function ea(s,t){const e=Math.min(s.x,s.x+s.width),n=Math.max(s.x,s.x+s.width),o=Math.min(s.y,s.y+s.height),i=Math.max(s.y,s.y+s.height);return!(n<t.left||e>t.right||i<t.top||o>t.bottom)}let cn=0;function Se(){return cn=(cn+1)%65535,Date.now().toString(36)+"-"+cn.toString(36)+"-"+Math.random().toString(36).slice(2,8)}function Y(s,t={}){const e=Date.now();return{id:Se(),type:s,x:0,y:0,width:100,height:100,rotation:0,zIndex:0,locked:!1,hidden:!1,createdAt:e,updatedAt:e,style:{},data:{},...t}}const Zn=200;class na{constructor(){m(this,"undoStack",[]);m(this,"redoStack",[])}execute(t,e,n){const o={id:Se(),type:t,timestamp:Date.now(),do:e,undo:n};o.do(),this.undoStack.push(o),this.undoStack.length>Zn&&this.undoStack.shift(),this.redoStack.length=0}push(t,e,n){const o={id:Se(),type:t,timestamp:Date.now(),do:e,undo:n};this.undoStack.push(o),this.undoStack.length>Zn&&this.undoStack.shift(),this.redoStack.length=0}undo(){const t=this.undoStack.pop();return t?(t.undo(),this.redoStack.push(t),!0):!1}redo(){const t=this.redoStack.pop();return t?(t.do(),this.undoStack.push(t),!0):!1}clear(){this.undoStack.length=0,this.redoStack.length=0}}class oa{constructor(t,e){m(this,"state");m(this,"commands");this.state=t,this.commands=e}deleteSelection(){const t=this.state.getSelected().filter(o=>!o.locked);if(t.length===0)return;const e=this.state,n=t.map(o=>o);this.commands.execute("delete",()=>{for(const o of n)e.removeElement(o.id);e.emitChange()},()=>{for(const o of n)e.elementsById.has(o.id)||e.addElement(o);e.emitChange()})}duplicateSelection(t=24){const e=this.state.getSelected();if(e.length===0)return[];const n=e.map(o=>this.cloneElement(o,t));this.insertElements(n,"duplicate"),this.state.clearSelection();for(const o of n)this.state.selectedIds.add(o.id);return this.state.requestRender(),n}cloneElement(t,e){const n=Date.now();return{...t,id:Se(),x:t.x+e,y:t.y+e,zIndex:this.state.maxZIndex()+1,createdAt:n,updatedAt:n,style:{...t.style},data:{...t.data}}}insertElements(t,e){const n=this.state;this.commands.execute(e,()=>{for(const o of t)n.elementsById.has(o.id)||n.addElement(o);n.emitChange()},()=>{for(const o of t)n.removeElement(o.id);n.emitChange()})}nudgeSelection(t,e){const n=this.state.getSelected().filter(c=>!c.locked);if(n.length===0)return;const o=this.state,i=n.map(c=>({id:c.id,x:c.x,y:c.y,updatedAt:c.updatedAt})),a=n.map(c=>({id:c.id,x:c.x+t,y:c.y+e,updatedAt:Date.now()})),r=c=>{for(const l of c){const d=o.elementsById.get(l.id);d&&(d.x=l.x,d.y=l.y,d.updatedAt=l.updatedAt)}o.emitChange()};this.commands.execute("nudge",()=>r(a),()=>r(i))}applyZChange(t){const e=this.state.getSelected();if(e.length===0)return;const n=this.state,o=e.map(r=>({id:r.id,z:r.zIndex}));for(const r of e)t(r);n.invalidateSort();const i=e.map(r=>({id:r.id,z:r.zIndex})),a=r=>{for(const c of r){const l=n.elementsById.get(c.id);l&&(l.zIndex=c.z)}n.invalidateSort(),n.emitChange()};this.commands.push("layer",()=>a(i),()=>a(o)),n.emitChange()}bringForward(){this.applyZChange(t=>t.zIndex+=1)}sendBackward(){this.applyZChange(t=>t.zIndex-=1)}bringToFront(){let t=this.state.maxZIndex();this.applyZChange(e=>e.zIndex=++t)}sendToBack(){let t=this.state.minZIndex();this.applyZChange(e=>e.zIndex=--t)}}const sa=["image/png","image/jpeg","image/webp","image/gif"],ia=5*1024*1024;class aa{constructor(t,e,n,o,i){m(this,"state");m(this,"commands");m(this,"imageCache");m(this,"notify");m(this,"uploadImage");m(this,"uploadedImageByHash",new Map);this.state=t,this.commands=e,this.imageCache=n,this.notify=o,this.uploadImage=i}async insertBlob(t,e,n,o){if(!sa.includes(t.type)){this.notify("Unsupported image type");return}t.size>ia&&this.notify("Large image added — consider optimizing it for git");let i=0,a=0,r=null;try{r=await createImageBitmap(t),i=r.width,a=r.height}catch{this.notify("Could not decode image");return}const c={originalWidth:i,originalHeight:a,alt:o};if(this.uploadImage)try{const y=await this.uploadOrReuseImage(t,o);c.src=y,r&&this.imageCache.setBySrc(y,r)}catch(y){this.notify("Failed to save image to disk"),console.error("Image upload failed",y);return}else try{const y=await ut.createFromBlob(t,o);c.assetId=y.id,r&&this.imageCache.set(y.id,r)}catch(y){this.notify("Failed to store image (storage quota?)"),console.error("Asset store failed",y);return}const l=H(e,n,this.state.viewport),d=480/Math.min(1,this.state.viewport.scale);let h=i,p=a;const u=Math.max(h,p);if(u>d){const y=d/u;h*=y,p*=y}const g=Y("image",{x:l.x-h/2,y:l.y-p/2,width:h,height:p,zIndex:this.state.maxZIndex()+1,data:c}),b=this.state;this.commands.execute("insert-image",()=>{b.elementsById.has(g.id)||b.addElement(g),b.emitChange()},()=>{b.removeElement(g.id),b.emitChange()}),b.clearSelection(),b.selectedIds.add(g.id),b.requestRender()}async insertFiles(t,e,n){let o=0;for(const i of Array.from(t))i.type.startsWith("image/")&&(await this.insertBlob(i,e+o,n+o,i.name),o+=24)}async uploadOrReuseImage(t,e){if(!this.uploadImage)throw new Error("Missing uploadImage");const n=await ra(t),o=this.uploadedImageByHash.get(n);if(o)return o;const i=await this.uploadImage(t,e);return this.uploadedImageByHash.set(n,i),i}}async function ra(s){const t=await crypto.subtle.digest("SHA-256",await s.arrayBuffer());return Array.from(new Uint8Array(t),e=>e.toString(16).padStart(2,"0")).join("")}const Jn="application/x-viteboard-elements";class ca{constructor(t,e,n,o){m(this,"state");m(this,"actions");m(this,"imageInsert");m(this,"internalClipboard",[]);m(this,"internalClipboardToken","");m(this,"lastPointer",{x:window.innerWidth/2,y:window.innerHeight/2});this.state=t,this.actions=e,this.imageInsert=n,window.addEventListener("pointermove",i=>{this.lastPointer={x:i.clientX,y:i.clientY}},{signal:o}),window.addEventListener("paste",i=>{this.isEditingText(i.target)||this.handlePaste(i)},{signal:o}),window.addEventListener("copy",i=>{this.isEditingText(i.target)||this.copySelection(i.clipboardData)&&i.preventDefault()},{signal:o}),window.addEventListener("cut",i=>{this.isEditingText(i.target)||this.copySelection(i.clipboardData)&&(this.actions.deleteSelection(),i.preventDefault())},{signal:o})}isEditingText(t){const e=t;return!!e&&(e.tagName==="TEXTAREA"||e.tagName==="INPUT"||e.isContentEditable)}copySelection(t){const e=this.state.getSelected();return e.length===0?!1:(this.internalClipboard=e.map(n=>({...n,style:{...n.style},data:{...n.data}})),this.internalClipboardToken=Date.now().toString(36)+"-"+Math.random().toString(36).slice(2,8),t&&this.writeClipboardPayload(t,e),!0)}async handlePaste(t){const e=t.clipboardData,n=e==null?void 0:e.items,o=e==null?void 0:e.getData("text/plain").trim();if(e&&this.isInternalClipboardPaste(e)){t.preventDefault(),this.pasteInternal();return}if(n){for(const i of n)if(i.type.startsWith("image/")){const a=i.getAsFile();if(a&&!o){t.preventDefault(),await this.imageInsert.insertBlob(a,this.lastPointer.x,this.lastPointer.y,"Pasted screenshot");return}}}if(!e&&this.internalClipboard.length>0){t.preventDefault(),this.pasteInternal();return}o&&(t.preventDefault(),this.pasteText(o))}writeClipboardPayload(t,e){try{t.clearData(),t.setData(Jn,this.internalClipboardToken),t.setData("text/plain",this.selectionText(e))}catch{}}isInternalClipboardPaste(t){const e=t.getData(Jn).trim();return!!e&&e===this.internalClipboardToken&&this.internalClipboard.length>0}selectionText(t){return t.map(n=>typeof n.data.text=="string"?n.data.text.trim():"").filter(Boolean).join(`
13
+
14
+ `)}pasteInternal(){const t=H(this.lastPointer.x,this.lastPointer.y,this.state.viewport);let e=1/0,n=1/0,o=-1/0,i=-1/0;for(const d of this.internalClipboard)e=Math.min(e,Math.min(d.x,d.x+d.width)),n=Math.min(n,Math.min(d.y,d.y+d.height)),o=Math.max(o,Math.max(d.x,d.x+d.width)),i=Math.max(i,Math.max(d.y,d.y+d.height));const a=(e+o)/2,r=(n+i)/2;let c=this.state.maxZIndex();const l=[];for(const d of this.internalClipboard){const h=No(d);if(!h)continue;const p=this.actions.cloneElement(h,0);p.x=h.x+(t.x-a),p.y=h.y+(t.y-r),p.zIndex=++c,l.push(p)}if(l.length!==0){this.actions.insertElements(l,"paste"),this.state.clearSelection();for(const d of l)this.state.selectedIds.add(d.id);this.state.requestRender()}}pasteText(t){const e=H(this.lastPointer.x,this.lastPointer.y,this.state.viewport),n=Y("text",{x:e.x,y:e.y,width:Math.min(420,Math.max(160,t.length*8)),height:28,zIndex:this.state.maxZIndex()+1,style:{fontSize:16,textColor:this.state.theme==="dark"?"#f2f2f2":"#1f2933"},data:{text:t.slice(0,5e3)}});Wt(n),this.actions.insertElements([n],"paste-text"),this.state.clearSelection(),this.state.selectedIds.add(n.id),this.state.requestRender()}}function la(s,t){const{state:e,commands:n,actions:o,toolController:i}=s;window.addEventListener("keydown",a=>{const r=a.target;if(r&&(r.tagName==="TEXTAREA"||r.tagName==="INPUT"||r.isContentEditable))return;const c=a.metaKey||a.ctrlKey,l=a.shiftKey?10:1;if(!c)switch(a.key){case"ArrowLeft":a.preventDefault(),o.nudgeSelection(-l,0);return;case"ArrowRight":a.preventDefault(),o.nudgeSelection(l,0);return;case"ArrowUp":a.preventDefault(),o.nudgeSelection(0,-l);return;case"ArrowDown":a.preventDefault(),o.nudgeSelection(0,l);return}if(c){switch(a.key.toLowerCase()){case"d":a.preventDefault(),o.duplicateSelection();return;case"z":a.preventDefault(),a.shiftKey?n.redo():n.undo();return;case"]":a.preventDefault(),a.shiftKey?o.bringToFront():o.bringForward();return;case"[":a.preventDefault(),a.shiftKey?o.sendToBack():o.sendBackward();return;case"=":case"+":a.preventDefault(),Ee(e.viewport,window.innerWidth/2,window.innerHeight/2,e.viewport.scale*1.2),e.requestRender();return;case"-":a.preventDefault(),Ee(e.viewport,window.innerWidth/2,window.innerHeight/2,e.viewport.scale/1.2),e.requestRender();return;case"0":a.preventDefault(),s.resetView();return;case"a":a.preventDefault(),e.clearSelection();for(const d of e.elements)!d.locked&&!d.hidden&&e.selectedIds.add(d.id);e.requestRender();return}return}switch(a.key){case"Delete":case"Backspace":a.preventDefault(),o.deleteSelection();return;case"Escape":i.cancel(),i.setTool("select");return}switch(a.key.toLowerCase()){case"v":i.setTool("select");return;case"h":i.setTool("hand");return;case"s":i.setTool("sticky");return;case"r":i.setTool("rectangle");return;case"o":i.setTool("ellipse");return;case"t":i.setTool(a.shiftKey?"task":"text");return;case"a":i.setTool("arrow");return;case"i":i.setTool("image");return}},{signal:t})}const ln=8192,Qn=8e6;function os(s,t=48){if(!Number.isFinite(t)||t<0)return null;let e=1/0,n=1/0,o=-1/0,i=-1/0;for(const a of s.elements){if(a.hidden)continue;const r=Math.abs(a.width)/2,c=Math.abs(a.height)/2,l=a.rotation*Math.PI/180,d=Math.abs(Math.cos(l))*r+Math.abs(Math.sin(l))*c,h=Math.abs(Math.sin(l))*r+Math.abs(Math.cos(l))*c,p=a.x+a.width/2,u=a.y+a.height/2;e=Math.min(e,p-d),n=Math.min(n,u-h),o=Math.max(o,p+d),i=Math.max(i,u+h)}return Number.isFinite(e)?{x:e-t,y:n-t,w:o-e+t*2,h:i-n+t*2}:null}function Ve(s,t,e,n){if(![e.x,e.y,e.w,e.h,n].every(Number.isFinite)||e.w<=0||e.h<=0||n<=0||n>64)throw new Error("The selected board region or export scale is invalid.");if(e.w>1e7||e.h>1e7)throw new Error("The selected board region is too large.");let o=Math.round(e.w*n),i=Math.round(e.h*n);if(o>ln||i>ln||o*i>Qn){const d=ln/Math.max(o,i),h=Math.sqrt(Qn/(o*i));n*=Math.min(d,h),o=Math.round(e.w*n),i=Math.round(e.h*n)}const a=document.createElement("canvas");a.width=Math.max(1,o),a.height=Math.max(1,i);const r=a.getContext("2d"),c=s.theme==="dark"?"#111315":"#f3f2f1";r.fillStyle=c,r.fillRect(0,0,a.width,a.height),r.scale(n,n),r.translate(-e.x,-e.y);const l=s.getSorted();for(const d of l){if(d.hidden)continue;const h=Math.abs(d.width)/2,p=Math.abs(d.height)/2,u=d.rotation*Math.PI/180,g=Math.abs(Math.cos(u))*h+Math.abs(Math.sin(u))*p,b=Math.abs(Math.sin(u))*h+Math.abs(Math.cos(u))*p,y=d.x+d.width/2,x=d.y+d.height/2;y+g<e.x||y-g>e.x+e.w||x+b<e.y||x-b>e.y+e.h||Ye(d,{ctx:r,scale:n,lod:2,theme:s.theme,imageCache:t})}return a}function ss(s,t="image/png",e){return new Promise((n,o)=>{s.toBlob(i=>{i?n(i):o(new Error(`${t} encode failed`))},t,e)})}async function is(s,t,e,n,o={}){var h;await((h=document.fonts)==null?void 0:h.ready),Ve(s,t,e,o.scale??2),await t.whenIdle();const i=Ve(s,t,e,o.scale??2),a=pa(s.title,n);if(n==="jpeg"){const p=Number.isFinite(o.quality)?Math.max(.1,Math.min(1,o.quality)):.92;return{format:n,fileName:a,mimeType:"image/jpeg",dataUrl:i.toDataURL("image/jpeg",p),width:i.width,height:i.height}}const r=i.toDataURL("image/png");if(n==="svg"){const p=[`<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="${i.width}" height="${i.height}" viewBox="0 0 ${i.width} ${i.height}">`,`<title>${as(s.title)}</title>`,`<image x="0" y="0" width="${i.width}" height="${i.height}" href="${r}" xlink:href="${r}" />`,"</svg>"].join("");return{format:n,fileName:a,mimeType:"image/svg+xml",dataUrl:`data:image/svg+xml;charset=utf-8,${encodeURIComponent(p)}`,width:i.width,height:i.height}}const c=o.paper==="Letter"?"Letter":"A4",l=i.width>=i.height?"landscape":"portrait",d=['<!doctype html><html><head><meta charset="utf-8" />',`<title>${to(s.title)}</title>`,`<style>@page{size:${c} ${l};margin:0}*{box-sizing:border-box}html,body{width:100%;height:100%;margin:0;padding:0;-webkit-print-color-adjust:exact;print-color-adjust:exact}body{display:grid;place-items:center}img{display:block;width:100vw;height:100vh;object-fit:contain}</style>`,`</head><body><img src="${r}" width="${i.width}" height="${i.height}" alt="${to(s.title)}" /></body></html>`].join("");return{format:n,fileName:a,html:d,pdf:{paper:c,displayHeaderFooter:!1,headerTemplate:"<div></div>",footerTemplate:"<div></div>",marginTopMm:0,marginBottomMm:0,marginLeftMm:0,marginRightMm:0},width:i.width,height:i.height}}async function da(s){var e;let t;if(s.format==="pdf"){const n=await fetch("/__api/export/pdf",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({html:s.html,fileName:s.fileName,pdf:s.pdf})});if(!n.ok){let o="";try{o=((e=await n.json())==null?void 0:e.error)??""}catch{}throw new Error(o||`PDF export failed (${n.status})`)}t=await n.blob()}else t=ha(s.dataUrl);kn(t,s.fileName)}function ha(s){const t=s.indexOf(",");if(!s.startsWith("data:")||t<0)throw new Error("Board renderer returned invalid image data.");const e=s.slice(5,t),n=e.split(";")[0],o=s.slice(t+1);if(!e.split(";").includes("base64"))return new Blob([decodeURIComponent(o)],{type:n});const i=atob(o),a=new Uint8Array(i.length);for(let r=0;r<i.length;r+=1)a[r]=i.charCodeAt(r);return new Blob([a],{type:n})}function pa(s,t){return`${String(s??"").trim().replace(/[\\/:*?"<>|]+/g,"-").replace(/[\u0000-\u001f\u007f]/g,"").replace(/\s+/g," ").replace(/\.(pdf|jpe?g|svg)$/i,"").slice(0,120)||"board"}.${t==="jpeg"?"jpg":t}`}function as(s){return s.replace(/[<>&"']/g,t=>({"<":"&lt;",">":"&gt;","&":"&amp;",'"':"&quot;","'":"&apos;"})[t])}function to(s){return as(s)}async function ua(s,t,e,n){const o=s.viewport,i={x:-o.offsetX/o.scale,y:-o.offsetY/o.scale,w:e/o.scale,h:n/o.scale},a=Ve(s,t,i,o.scale);return ss(a)}async function ma(s,t){const e=os(s);if(!e)return null;const n=Ve(s,t,e,1);return ss(n)}function kn(s,t){const e=URL.createObjectURL(s),n=document.createElement("a");n.href=e,n.download=t,n.style.display="none",document.body.appendChild(n),n.click(),n.remove(),window.setTimeout(()=>URL.revokeObjectURL(e),1e3)}class Ln{constructor(t,e){m(this,"overlay");m(this,"rectEl");m(this,"abort",new AbortController);m(this,"start",null);m(this,"onComplete");m(this,"done",!1);this.onComplete=e,this.overlay=document.createElement("div"),this.overlay.className="embed-select-overlay";const n=document.createElement("div");n.className="embed-select-hint",n.textContent="Drag to select a region to embed or export · Esc to cancel",this.overlay.appendChild(n),this.rectEl=document.createElement("div"),this.rectEl.className="embed-select-rect",this.rectEl.style.display="none",this.overlay.appendChild(this.rectEl),t.appendChild(this.overlay);const o=this.abort.signal;this.overlay.addEventListener("pointerdown",i=>this.onDown(i),{signal:o}),this.overlay.addEventListener("pointermove",i=>this.onMove(i),{signal:o}),this.overlay.addEventListener("pointerup",i=>this.onUp(i),{signal:o}),window.addEventListener("keydown",i=>{i.key==="Escape"&&(i.preventDefault(),this.finish(null))},{signal:o})}static begin(t,e){new Ln(t,e)}onDown(t){t.preventDefault(),this.start={x:t.clientX,y:t.clientY},this.rectEl.style.display="block",this.draw(t.clientX,t.clientY),this.overlay.setPointerCapture(t.pointerId)}onMove(t){this.start&&this.draw(t.clientX,t.clientY)}onUp(t){if(!this.start)return;const e=this.rectFrom(t.clientX,t.clientY);if(e.w<8||e.h<8){this.finish(null);return}this.finish(e)}rectFrom(t,e){const n=this.start;return{x:Math.min(n.x,t),y:Math.min(n.y,e),w:Math.abs(t-n.x),h:Math.abs(e-n.y)}}draw(t,e){const n=this.rectFrom(t,e);this.rectEl.style.left=`${n.x}px`,this.rectEl.style.top=`${n.y}px`,this.rectEl.style.width=`${n.w}px`,this.rectEl.style.height=`${n.h}px`}finish(t){this.done||(this.done=!0,this.abort.abort(),this.overlay.remove(),this.onComplete(t))}}class fa{constructor(t,e=3,n){m(this,"container");m(this,"layers",[]);m(this,"contexts",[]);m(this,"width",0);m(this,"height",0);m(this,"dpr",1);m(this,"resizeListeners",[]);this.container=document.createElement("div"),this.container.className="canvas-stack",t.appendChild(this.container);for(let o=0;o<e;o++){const i=document.createElement("canvas"),a=i.getContext("2d",{alpha:o!==0});this.container.appendChild(i),this.layers.push(i),this.contexts.push(a)}this.resize(),window.addEventListener("resize",()=>{this.resize();for(const o of this.resizeListeners)o()},{signal:n})}get interactionLayer(){return this.layers[this.layers.length-1]}onResize(t){this.resizeListeners.push(t)}resize(){this.dpr=Math.max(1,window.devicePixelRatio||1),this.width=window.innerWidth,this.height=window.innerHeight;for(const t of this.layers)t.width=Math.round(this.width*this.dpr),t.height=Math.round(this.height*this.dpr),t.style.width=this.width+"px",t.style.height=this.height+"px"}beginLayer(t){const e=this.contexts[t];return e.setTransform(this.dpr,0,0,this.dpr,0,0),e.clearRect(0,0,this.width,this.height),e}}class ga{constructor(t,e,n){m(this,"surface");m(this,"state");m(this,"imageCache");m(this,"overlay",{marquee:null,preview:null});m(this,"lastRenderMs",0);m(this,"visibleCount",0);m(this,"cullingEnabled",!0);m(this,"lodEnabled",!0);this.surface=t,this.state=e,this.imageCache=n}getLod(){if(!this.lodEnabled)return 2;const t=this.state.viewport.scale;return t<.1?0:t<.25?1:2}render(){const t=performance.now();this.renderGrid(),this.renderObjects(),this.renderOverlay(),this.lastRenderMs=performance.now()-t}renderGrid(){const{surface:t,state:e}=this,n=t.beginLayer(0),o=e.viewport,i=getComputedStyle(document.documentElement).getPropertyValue("--bg-canvas").trim(),a=getComputedStyle(document.documentElement).getPropertyValue("--grid-dot").trim();n.fillStyle=i||"#f3f2f1",n.fillRect(0,0,t.width,t.height);let c=32*o.scale;if(!Number.isFinite(c)||c<=0)return;for(;c<16;)c*=2;for(;c>64;)c/=2;if(c<4)return;const l=(o.offsetX%c+c)%c,d=(o.offsetY%c+c)%c,h=Math.min(1.5,Math.max(.75,o.scale*.9));n.fillStyle=a||"rgba(0,0,0,0.14)",n.beginPath();for(let p=l;p<t.width;p+=c)for(let u=d;u<t.height;u+=c)n.moveTo(p+h,u),n.arc(p,u,h,0,Math.PI*2);n.fill()}renderObjects(){const{surface:t,state:e}=this,n=t.beginLayer(1),o=e.viewport;n.translate(o.offsetX,o.offsetY),n.scale(o.scale,o.scale);const i=ta(o,t.width,t.height),a=this.cullingEnabled?e.getVisibleElements(i):e.getSorted().filter(c=>!c.hidden);this.visibleCount=a.length;const r={ctx:n,scale:o.scale,lod:this.getLod(),theme:e.theme,imageCache:this.imageCache};for(const c of a)Ye(c,r)}renderOverlay(){const{surface:t,state:e}=this,n=t.beginLayer(2),o=e.viewport,i=getComputedStyle(document.documentElement).getPropertyValue("--selection").trim()||"#6e6e6e";if(e.hoveredId&&!e.selectedIds.has(e.hoveredId)){const r=e.elementsById.get(e.hoveredId);if(r){const c=this.elementScreenBBox(r);n.strokeStyle=i,n.globalAlpha=.45,n.lineWidth=1.5,n.strokeRect(c.x,c.y,c.w,c.h),n.globalAlpha=1}}const a=e.getSelected();if(a.length>0){n.strokeStyle=i,n.lineWidth=1.5;let r=1/0,c=1/0,l=-1/0,d=-1/0;for(const p of a){const u=this.elementScreenBBox(p);n.strokeRect(u.x,u.y,u.w,u.h),r=Math.min(r,u.x),c=Math.min(c,u.y),l=Math.max(l,u.x+u.w),d=Math.max(d,u.y+u.h)}a.length>1&&(n.setLineDash([4,4]),n.strokeRect(r-4,c-4,l-r+8,d-c+8),n.setLineDash([]));const h=a.length===1?this.elementScreenBBox(a[0]):{x:r,y:c,w:l-r,h:d-c};this.drawHandles(n,h,i)}if(this.overlay.marquee){const r=this.overlay.marquee;n.fillStyle=i+"22",n.strokeStyle=i,n.lineWidth=1,n.fillRect(r.x,r.y,r.w,r.h),n.strokeRect(r.x,r.y,r.w,r.h)}this.overlay.preview&&(n.save(),n.translate(o.offsetX,o.offsetY),n.scale(o.scale,o.scale),n.globalAlpha=.8,Ye(this.overlay.preview,{ctx:n,scale:o.scale,lod:2,theme:e.theme,imageCache:this.imageCache}),n.restore())}elementScreenBBox(t){const e=this.state.viewport,n=Math.min(t.x,t.x+t.width),o=Math.min(t.y,t.y+t.height),i=Math.max(t.x,t.x+t.width),a=Math.max(t.y,t.y+t.height),r=Ot(n,o,e),c=Ot(i,a,e);return{x:r.x,y:r.y,w:c.x-r.x,h:c.y-r.y}}drawHandles(t,e,n){const a=rs(e);t.fillStyle=getComputedStyle(document.documentElement).getPropertyValue("--bg-panel").trim()||"#fff",t.strokeStyle=n,t.lineWidth=1.5;for(const r of a)t.beginPath(),t.rect(r.x-4,r.y-4,8,8),t.fill(),t.stroke()}}function rs(s){const{x:t,y:e,w:n,h:o}=s;return[{id:"nw",x:t,y:e},{id:"n",x:t+n/2,y:e},{id:"ne",x:t+n,y:e},{id:"e",x:t+n,y:e+o/2},{id:"se",x:t+n,y:e+o},{id:"s",x:t+n/2,y:e+o},{id:"sw",x:t,y:e+o},{id:"w",x:t,y:e+o/2}]}class ya{constructor(t){m(this,"rafId",null);m(this,"renderFn");this.renderFn=t}requestRender(){this.rafId===null&&(this.rafId=requestAnimationFrame(()=>{this.rafId=null,this.renderFn()}))}cancel(){this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null)}}function ba(s,t,e,n,o,i){const a=o-e,r=i-n,c=a*a+r*r;if(c===0)return Math.hypot(s-e,t-n);let l=((s-e)*a+(t-n)*r)/c;return l=Math.max(0,Math.min(1,l)),Math.hypot(s-(e+l*a),t-(n+l*r))}class va{constructor(t){m(this,"state");m(this,"lastHitTestMs",0);this.state=t}hitTest(t,e,n){const o=performance.now(),i=this.state.getSorted(),a=6/n;let r=null;for(let c=i.length-1;c>=0;c--){const l=i[c];if(!(l.hidden||l.locked)&&this.hitsElement(l,t,e,a)){r=l;break}}return this.lastHitTestMs=performance.now()-o,r}hitsElement(t,e,n,o){if(t.type==="line"||t.type==="arrow"||t.type==="connector")return ba(e,n,t.x,t.y,t.x+t.width,t.y+t.height)<=Math.max(o,(t.style.strokeWidth??2)/2+o);const i=Math.min(t.x,t.x+t.width),a=Math.max(t.x,t.x+t.width),r=Math.min(t.y,t.y+t.height),c=Math.max(t.y,t.y+t.height);if(e<i||e>a||n<r||n>c)return!1;if(t.type==="ellipse"){const l=(i+a)/2,d=(r+c)/2,h=(a-i)/2,p=(c-r)/2;if(h===0||p===0)return!1;const u=(e-l)/h,g=(n-d)/p;return u*u+g*g<=1}return!0}elementsInRect(t,e,n,o){const i=Math.min(t,t+n),a=Math.max(t,t+n),r=Math.min(e,e+o),c=Math.max(e,e+o),l=[];for(const d of this.state.elements){if(d.hidden||d.locked)continue;const h=Math.min(d.x,d.x+d.width),p=Math.max(d.x,d.x+d.width),u=Math.min(d.y,d.y+d.height),g=Math.max(d.y,d.y+d.height);h>=i&&p<=a&&u>=r&&g<=c&&l.push(d)}return l}}class wa{constructor(){m(this,"fps",0);m(this,"frameCount",0);m(this,"lastSample",performance.now());m(this,"running",!1)}start(){if(this.running)return;this.running=!0;const t=()=>{if(!this.running)return;this.frameCount++;const e=performance.now(),n=e-this.lastSample;n>=1e3&&(this.fps=Math.round(this.frameCount*1e3/n),this.frameCount=0,this.lastSample=e),requestAnimationFrame(t)};requestAnimationFrame(t)}stop(){this.running=!1}}const xa=16,Ca=720,eo=120,ka=.0032;class Ea{constructor(t,e,n,o){m(this,"tools",new Map);m(this,"active");m(this,"ctx");m(this,"target");m(this,"spaceDown",!1);m(this,"tempPanning",!1);m(this,"panLast",{x:0,y:0});m(this,"toolChangeListeners",[]);m(this,"signal");this.target=t,this.ctx=e,this.signal=o;for(const i of n)this.tools.set(i.name,i);this.active=this.tools.get("select"),this.bindEvents()}get activeName(){return this.active.name}onToolChange(t){this.toolChangeListeners.push(t)}setTool(t){var n,o,i,a,r;if(this.active.name===t){(o=(n=this.active).onActivate)==null||o.call(n,this.ctx);return}(a=(i=this.active).onDeactivate)==null||a.call(i,this.ctx);const e=this.tools.get(t);if(e){this.active=e,this.ctx.setCursor(e.cursor),(r=e.onActivate)==null||r.call(e,this.ctx);for(const c of this.toolChangeListeners)c(t)}}cancel(){var t,e;(e=(t=this.active).onCancel)==null||e.call(t,this.ctx)}bindEvents(){const t=this.target;t.addEventListener("pointerdown",e=>{if(e.button===1||e.button===2||this.spaceDown){e.preventDefault(),this.tempPanning=!0,this.panLast={x:e.clientX,y:e.clientY},this.ctx.setCursor("grabbing"),t.setPointerCapture(e.pointerId);return}e.button===0&&(t.setPointerCapture(e.pointerId),this.active.onPointerDown(e,this.ctx))}),t.addEventListener("pointermove",e=>{if(this.tempPanning){const n=this.ctx.state.viewport;n.offsetX+=e.clientX-this.panLast.x,n.offsetY+=e.clientY-this.panLast.y,this.panLast={x:e.clientX,y:e.clientY},this.ctx.state.requestRender();return}this.active.onPointerMove(e,this.ctx)}),t.addEventListener("pointerup",e=>{if(this.tempPanning){this.tempPanning=!1,this.ctx.setCursor(this.spaceDown?"grab":this.active.cursor);return}this.active.onPointerUp(e,this.ctx)}),t.addEventListener("pointercancel",()=>{this.tempPanning&&(this.tempPanning=!1,this.ctx.setCursor(this.spaceDown?"grab":this.active.cursor))}),t.addEventListener("dblclick",e=>{var n,o;(o=(n=this.active).onDoubleClick)==null||o.call(n,e,this.ctx)}),t.addEventListener("wheel",e=>{e.preventDefault();const n=this.ctx.state.viewport,o=no(e.deltaX,e.deltaMode,this.ctx.state.viewport.scale),i=no(e.deltaY,e.deltaMode,this.ctx.state.viewport.scale);if(e.ctrlKey||e.metaKey){const a=Math.exp(-Sa(i)*ka);Ee(n,e.clientX,e.clientY,n.scale*a)}else e.shiftKey&&Math.abs(o)<Math.abs(i)?n.offsetX-=i:(n.offsetX-=o,n.offsetY-=i);this.ctx.state.requestRender()},{passive:!1}),window.addEventListener("keydown",e=>{e.code==="Space"&&!this.isEditingText(e)&&(this.spaceDown||(this.spaceDown=!0,this.tempPanning||this.ctx.setCursor("grab")),e.preventDefault())},{signal:this.signal}),window.addEventListener("keyup",e=>{e.code==="Space"&&(this.spaceDown=!1,this.tempPanning||this.ctx.setCursor(this.active.cursor))},{signal:this.signal}),t.addEventListener("contextmenu",e=>e.preventDefault())}isEditingText(t){const e=t.target;return!!e&&(e.tagName==="TEXTAREA"||e.tagName==="INPUT"||e.isContentEditable)}}function no(s,t,e){const o=s*(t===1?xa:t===2?Ca:1),i=e<.5?.8:e>2?1.08:1;return o*i}function Sa(s){return Math.max(-eo,Math.min(eo,s))}const Ae=7,Ta={nw:"nwse-resize",n:"ns-resize",ne:"nesw-resize",e:"ew-resize",se:"nwse-resize",s:"ns-resize",sw:"nesw-resize",w:"ew-resize"};class Ba{constructor(){m(this,"name","select");m(this,"cursor","default");m(this,"mode","none");m(this,"startScreen",{x:0,y:0});m(this,"startWorld",{x:0,y:0});m(this,"snapshots",[]);m(this,"activeHandle",null);m(this,"endpointIsStart",!1);m(this,"moved",!1);m(this,"pointerDownHitId",null)}onPointerDown(t,e){const{state:n,hitTester:o,renderer:i}=e;this.startScreen={x:t.clientX,y:t.clientY},this.startWorld=H(t.clientX,t.clientY,n.viewport),this.moved=!1;const a=this.hitHandle(t,e);if(a){this.mode="resize",this.activeHandle=a,this.takeSnapshots(n.getSelected());return}const r=n.getSelected();if(r.length===1&&this.isLinear(r[0])){const l=this.hitEndpoint(t,r[0],e);if(l!==null){this.mode="endpoint",this.endpointIsStart=l,this.takeSnapshots(r);return}}const c=o.hitTest(this.startWorld.x,this.startWorld.y,n.viewport.scale);if(c){this.pointerDownHitId=c.id,t.shiftKey?n.selectedIds.has(c.id)?n.selectedIds.delete(c.id):n.selectedIds.add(c.id):n.selectedIds.has(c.id)||(n.clearSelection(),n.selectedIds.add(c.id)),this.mode="move",this.takeSnapshots(n.getSelected()),n.requestRender();return}t.shiftKey||n.clearSelection(),this.mode="marquee",i.overlay.marquee={x:t.clientX,y:t.clientY,w:0,h:0},n.requestRender()}onPointerMove(t,e){const{state:n,renderer:o,hitTester:i}=e;if(this.mode==="none"){const d=this.hitHandle(t,e);if(d){e.setCursor(Ta[d]);return}const h=H(t.clientX,t.clientY,n.viewport),p=i.hitTest(h.x,h.y,n.viewport.scale),u=p?p.id:null;e.setCursor(p?"move":"default"),u!==n.hoveredId&&(n.hoveredId=u,n.requestRender());return}const a=t.clientX-this.startScreen.x,r=t.clientY-this.startScreen.y;Math.abs(a)+Math.abs(r)>2&&(this.moved=!0);const c=a/n.viewport.scale,l=r/n.viewport.scale;if(this.mode==="move"){for(const d of this.snapshots){const h=n.elementsById.get(d.id);!h||h.locked||(h.x=d.x+c,h.y=d.y+l)}n.requestRender()}else if(this.mode==="marquee")o.overlay.marquee={x:this.startScreen.x,y:this.startScreen.y,w:a,h:r},n.requestRender();else if(this.mode==="resize"&&this.activeHandle)this.applyResize(c,l,t.shiftKey,e),n.requestRender();else if(this.mode==="endpoint"){const d=this.snapshots[0],h=n.elementsById.get(d.id);h&&(this.endpointIsStart?(h.x=d.x+c,h.y=d.y+l,h.width=d.width-c,h.height=d.height-l):(h.width=d.width+c,h.height=d.height+l)),n.requestRender()}}onPointerUp(t,e){const{state:n,renderer:o,hitTester:i,commands:a}=e;if(this.mode==="marquee"){const r=o.overlay.marquee;if(o.overlay.marquee=null,r&&(Math.abs(r.w)>3||Math.abs(r.h)>3)){const c=H(r.x,r.y,n.viewport),l=H(r.x+r.w,r.y+r.h,n.viewport),d=i.elementsInRect(c.x,c.y,l.x-c.x,l.y-c.y);for(const h of d)n.selectedIds.add(h.id)}n.requestRender()}else if((this.mode==="move"||this.mode==="resize"||this.mode==="endpoint")&&this.moved){const r=this.snapshots,c=r.map(d=>{const h=n.elementsById.get(d.id);return{id:d.id,x:h.x,y:h.y,width:h.width,height:h.height}}),l=d=>{for(const h of d){const p=n.elementsById.get(h.id);p&&(p.x=h.x,p.y=h.y,p.width=h.width,p.height=h.height,p.updatedAt=Date.now(),nt(p.id))}n.emitChange()};for(const d of c){const h=n.elementsById.get(d.id);h&&(h.updatedAt=Date.now(),nt(h.id))}a.push(this.mode,()=>l(c),()=>l(r)),n.emitChange()}else this.mode==="move"&&!this.moved&&this.toggleTaskIfCheckboxClick(t,e);this.mode="none",this.activeHandle=null,this.snapshots=[],this.pointerDownHitId=null}onDoubleClick(t,e){const{state:n,hitTester:o}=e,i=H(t.clientX,t.clientY,n.viewport),a=o.hitTest(i.x,i.y,n.viewport.scale);a&&(a.type==="sticky"||a.type==="task"||a.type==="text"||a.type==="rectangle"||a.type==="ellipse"||a.type==="frame"||a.type==="arrow"||a.type==="line"||a.type==="connector")&&e.openTextEditor(a)}onCancel(t){if(this.mode!=="none"&&this.snapshots.length>0)for(const e of this.snapshots){const n=t.state.elementsById.get(e.id);n&&(n.x=e.x,n.y=e.y,n.width=e.width,n.height=e.height)}t.renderer.overlay.marquee=null,this.mode="none",t.state.clearSelection(),t.state.requestRender()}isLinear(t){return t.type==="line"||t.type==="arrow"||t.type==="connector"}takeSnapshots(t){this.snapshots=t.map(e=>({id:e.id,x:e.x,y:e.y,width:e.width,height:e.height}))}toggleTaskIfCheckboxClick(t,e){const{state:n,hitTester:o,commands:i}=e,a=H(t.clientX,t.clientY,n.viewport),r=o.hitTest(a.x,a.y,n.viewport.scale);if(!r||r.id!==this.pointerDownHitId||r.type!=="task"||!this.hitTaskCheckbox(a.x,a.y,r))return;const c=r.data.checked===!0,l=!c,d=r.id,h=p=>{const u=n.elementsById.get(d);u&&(u.data.checked=p,u.updatedAt=Date.now(),n.emitChange())};i.execute("toggle-task",()=>h(l),()=>h(c))}hitTaskCheckbox(t,e,n){const o=Math.min(22,Math.max(16,n.height*.38)),i=n.x+16,a=n.y+n.height/2-o/2,r=8;return t>=i-r&&t<=i+o+r&&e>=a-r&&e<=a+o+r}hitHandle(t,e){const{state:n,renderer:o}=e,i=n.getSelected();if(i.length===0||i.length===1&&this.isLinear(i[0]))return null;let a;if(i.length===1)a=o.elementScreenBBox(i[0]);else{let r=1/0,c=1/0,l=-1/0,d=-1/0;for(const h of i){const p=o.elementScreenBBox(h);r=Math.min(r,p.x),c=Math.min(c,p.y),l=Math.max(l,p.x+p.w),d=Math.max(d,p.y+p.h)}a={x:r,y:c,w:l-r,h:d-c}}for(const r of rs(a))if(Math.abs(t.clientX-r.x)<=Ae&&Math.abs(t.clientY-r.y)<=Ae)return r.id;return null}hitEndpoint(t,e,n){const o=n.state.viewport,i=e.x*o.scale+o.offsetX,a=e.y*o.scale+o.offsetY,r=(e.x+e.width)*o.scale+o.offsetX,c=(e.y+e.height)*o.scale+o.offsetY;return Math.hypot(t.clientX-i,t.clientY-a)<=Ae+2?!0:Math.hypot(t.clientX-r,t.clientY-c)<=Ae+2?!1:null}applyResize(t,e,n,o){const{state:i}=o,a=this.activeHandle;let r=1/0,c=1/0,l=-1/0,d=-1/0;for(const w of this.snapshots)r=Math.min(r,Math.min(w.x,w.x+w.width)),c=Math.min(c,Math.min(w.y,w.y+w.height)),l=Math.max(l,Math.max(w.x,w.x+w.width)),d=Math.max(d,Math.max(w.y,w.y+w.height));const h=l-r,p=d-c;if(h===0||p===0)return;let u=r,g=c,b=h,y=p;if(a.includes("e")&&(b=h+t),a.includes("w")&&(u=r+t,b=h-t),a.includes("s")&&(y=p+e),a.includes("n")&&(g=c+e,y=p-e),n&&(a==="nw"||a==="ne"||a==="se"||a==="sw")){const w=h/p;if(Math.abs(b/h)>Math.abs(y/p)){const S=b/w;a.includes("n")&&(g=g+(y-S)),y=S}else{const S=y*w;a.includes("w")&&(u=u+(b-S)),b=S}}const x=4;if(Math.abs(b)<x||Math.abs(y)<x)return;const v=b/h,E=y/p;for(const w of this.snapshots){const S=i.elementsById.get(w.id);!S||S.locked||(S.x=u+(w.x-r)*v,S.y=g+(w.y-c)*E,S.width=w.width*v,S.height=w.height*E,S.updatedAt=Date.now(),nt(S.id))}}}class Ma{constructor(){m(this,"name","hand");m(this,"cursor","grab");m(this,"panning",!1);m(this,"last",{x:0,y:0})}onPointerDown(t,e){this.panning=!0,this.last={x:t.clientX,y:t.clientY},e.setCursor("grabbing")}onPointerMove(t,e){if(!this.panning)return;const n=e.state.viewport;n.offsetX+=t.clientX-this.last.x,n.offsetY+=t.clientY-this.last.y,this.last={x:t.clientX,y:t.clientY},e.state.requestRender()}onPointerUp(t,e){this.panning=!1,e.setCursor("grab")}onCancel(t){this.panning=!1,t.setCursor("grab")}}const qe=["#fef08a","#fdba74","#fca5a5","#f9a8d4","#d8b4fe","#a5b4fc","#93c5fd","#86efac"];let cs=qe[0];function Ia(){return cs}function Ra(s){cs=s}class La{constructor(){m(this,"name","sticky");m(this,"cursor","crosshair")}onPointerDown(t,e){const{state:n,commands:o}=e,i=H(t.clientX,t.clientY,n.viewport),a=Y("sticky",{x:i.x-110,y:i.y-80,width:220,height:160,zIndex:n.maxZIndex()+1,style:{fill:Ia(),borderRadius:12,shadow:!0,fontSize:15,textColor:"#1f2933"},data:{text:""}});o.execute("create-sticky",()=>{n.elementsById.has(a.id)||n.addElement(a),n.emitChange()},()=>{n.removeElement(a.id),n.emitChange()}),n.clearSelection(),n.selectedIds.add(a.id),e.setTool("select"),e.openTextEditor(a)}onPointerMove(t,e){}onPointerUp(t,e){}}class Pa{constructor(){m(this,"name","task");m(this,"cursor","crosshair")}onPointerDown(t,e){const{state:n,commands:o}=e,i=H(t.clientX,t.clientY,n.viewport),a=n.theme==="dark",r=Y("task",{x:i.x-140,y:i.y-28,width:280,height:56,zIndex:n.maxZIndex()+1,style:{fill:a?"#17191b":"#ffffff",stroke:a?"rgba(255,255,255,0.12)":"rgba(0,0,0,0.09)",strokeWidth:1,borderRadius:14,shadow:!0,fontSize:15,fontWeight:"650",textColor:a?"#f6f6f3":"#252829"},data:{text:"Task title",checked:!1}});o.execute("create-task",()=>{n.elementsById.has(r.id)||n.addElement(r),n.emitChange()},()=>{n.removeElement(r.id),n.emitChange()}),n.clearSelection(),n.selectedIds.add(r.id),e.setTool("select"),e.openTextEditor(r)}onPointerMove(t,e){}onPointerUp(t,e){}}class gt{constructor(t){m(this,"name");m(this,"cursor","crosshair");m(this,"shapeType");m(this,"shapeKind");m(this,"drawing",!1);m(this,"startWorld",{x:0,y:0});m(this,"preview",null);this.name=t,this.shapeKind=t,this.shapeType=t==="ellipse"?"ellipse":"rectangle"}onPointerDown(t,e){const{state:n}=e;this.drawing=!0,this.startWorld=H(t.clientX,t.clientY,n.viewport);const o=n.theme==="dark",i=!["rectangle","ellipse","pill","cylinder"].includes(this.shapeKind);this.preview=Y(this.shapeType,{x:this.startWorld.x,y:this.startWorld.y,width:0,height:0,zIndex:n.maxZIndex()+1,style:{fill:i?"#0078d4":o?"#2a2d33":"#ffffff",stroke:i?"#495057":o?"#9ca3af":"#374151",strokeWidth:i?0:1.5,borderRadius:this.shapeKind==="pill"?999:this.shapeKind==="rectangle"?8:0,fontSize:14,textColor:i?"#ffffff":o?"#f2f2f2":"#1f2933"},data:{text:"",shapeKind:this.shapeKind}}),e.renderer.overlay.preview=this.preview}onPointerMove(t,e){if(!this.drawing||!this.preview)return;const n=H(t.clientX,t.clientY,e.state.viewport);let o=n.x-this.startWorld.x,i=n.y-this.startWorld.y;if(t.shiftKey){const a=Math.max(Math.abs(o),Math.abs(i));o=Math.sign(o||1)*a,i=Math.sign(i||1)*a}this.preview.x=Math.min(this.startWorld.x,this.startWorld.x+o),this.preview.y=Math.min(this.startWorld.y,this.startWorld.y+i),this.preview.width=Math.abs(o),this.preview.height=Math.abs(i),e.state.requestRender()}onPointerUp(t,e){const{state:n,commands:o}=e;if(!this.drawing||!this.preview)return;this.drawing=!1,e.renderer.overlay.preview=null;const i=this.preview;this.preview=null,(i.width<4||i.height<4)&&(i.width=this.shapeKind==="chevron"?210:160,i.height=this.shapeKind==="chevron"?76:100,i.x-=i.width/2,i.y-=i.height/2),o.execute("create-shape",()=>{n.elementsById.has(i.id)||n.addElement(i),n.emitChange()},()=>{n.removeElement(i.id),n.emitChange()}),n.clearSelection(),n.selectedIds.add(i.id),e.setTool("select")}onCancel(t){this.drawing=!1,this.preview=null,t.renderer.overlay.preview=null,t.state.requestRender()}}class $a{constructor(){m(this,"name","text");m(this,"cursor","text")}onPointerDown(t,e){const{state:n,commands:o}=e,i=H(t.clientX,t.clientY,n.viewport),a=Y("text",{x:i.x,y:i.y-12,width:240,height:28,zIndex:n.maxZIndex()+1,style:{fontSize:16,textColor:n.theme==="dark"?"#f2f2f2":"#1f2933"},data:{text:""}});Wt(a),o.execute("create-text",()=>{n.elementsById.has(a.id)||n.addElement(a),n.emitChange()},()=>{n.removeElement(a.id),n.emitChange()}),n.clearSelection(),n.selectedIds.add(a.id),e.setTool("select"),e.openTextEditor(a)}onPointerMove(t,e){}onPointerUp(t,e){}}class fe{constructor(t="arrow"){m(this,"name");m(this,"cursor","crosshair");m(this,"drawing",!1);m(this,"startWorld",{x:0,y:0});m(this,"preview",null);this.name=t}onPointerDown(t,e){const{state:n}=e;this.drawing=!0,this.startWorld=H(t.clientX,t.clientY,n.viewport),this.preview=Y("arrow",{x:this.startWorld.x,y:this.startWorld.y,width:0,height:0,zIndex:n.maxZIndex()+1,style:{stroke:n.theme==="dark"?"#d1d5db":"#374151",strokeWidth:2,arrowEnd:!0,arrowStart:this.name==="twoWayArrow",strokeDash:this.name==="dashedArrow"||t.altKey?[8,6]:void 0},data:{text:"",labelPosition:this.name==="sidedLabelArrow"?"sides":"center"}}),e.renderer.overlay.preview=this.preview}onPointerMove(t,e){if(!this.drawing||!this.preview)return;const n=H(t.clientX,t.clientY,e.state.viewport);let o=n.x-this.startWorld.x,i=n.y-this.startWorld.y;if(t.shiftKey){const a=Math.atan2(i,o),r=Math.round(a/(Math.PI/4))*(Math.PI/4),c=Math.hypot(o,i);o=Math.cos(r)*c,i=Math.sin(r)*c}this.preview.width=o,this.preview.height=i,e.state.requestRender()}onPointerUp(t,e){const{state:n,commands:o}=e;if(!this.drawing||!this.preview)return;this.drawing=!1,e.renderer.overlay.preview=null;const i=this.preview;if(this.preview=null,Math.hypot(i.width,i.height)<8){n.requestRender();return}o.execute("create-arrow",()=>{n.elementsById.has(i.id)||n.addElement(i),n.emitChange()},()=>{n.removeElement(i.id),n.emitChange()}),n.clearSelection(),n.selectedIds.add(i.id),e.setTool("select"),(this.name==="labeledArrow"||this.name==="sidedLabelArrow")&&e.openTextEditor(i)}onCancel(t){this.drawing=!1,this.preview=null,t.renderer.overlay.preview=null,t.state.requestRender()}}class Da{constructor(t){m(this,"name","image");m(this,"cursor","default");m(this,"onInsert");this.onInsert=t}onActivate(t){const e=document.createElement("input");e.type="file",e.accept="image/png,image/jpeg,image/webp,image/gif",e.multiple=!0,e.onchange=()=>{e.files&&e.files.length>0&&this.onInsert(e.files,window.innerWidth/2,window.innerHeight/2),t.setTool("select")},e.oncancel=()=>t.setTool("select"),e.click()}onPointerDown(t,e){}onPointerMove(t,e){}onPointerUp(t,e){}}const Ne="psc:";class Aa{constructor(){m(this,"lastSaveMs",0)}async saveBoard(t){const e=performance.now();try{await at.put("boards",t),this.lastSaveMs=performance.now()-e,this.setPref("lastBoardId",t.id),this.setPref("recovery",JSON.stringify({id:t.id,title:t.title,updatedAt:t.updatedAt,elementCount:t.elements.length}))}catch(n){throw console.error("Board save failed",n),n}}async loadBoard(t){try{return await at.get("boards",t)}catch(e){console.error("Board load failed",e);return}}async deleteBoard(t){await at.delete("boards",t)}async clearAllBoards(){await at.clearStore("boards")}async getAllBoards(){try{return await at.getAll("boards")}catch{return[]}}setPref(t,e){try{localStorage.setItem(Ne+t,e)}catch{}}getPref(t){try{return localStorage.getItem(Ne+t)}catch{return null}}removePref(t){try{localStorage.removeItem(Ne+t)}catch{}}clearPrefs(){try{const t=[];for(let e=0;e<localStorage.length;e++){const n=localStorage.key(e);n&&n.startsWith(Ne)&&t.push(n)}for(const e of t)localStorage.removeItem(e)}catch{}}async estimateStorage(){try{if(navigator.storage&&navigator.storage.estimate){const t=await navigator.storage.estimate();return{usage:t.usage??0,quota:t.quota??0}}}catch{}return{usage:0,quota:0}}}const pt=new Aa;function Na(s){return new Promise((t,e)=>{const n=new FileReader;n.onload=()=>{const o=n.result;t(o.slice(o.indexOf(",")+1))},n.onerror=()=>e(n.error),n.readAsDataURL(s)})}function Fa(s,t){const e=atob(s),n=new Uint8Array(e.length);for(let o=0;o<e.length;o++)n[o]=e.charCodeAt(o);return new Blob([n],{type:t})}function oo(s,t){const e=new Blob([JSON.stringify(t)],{type:"application/json"}),n=URL.createObjectURL(e),o=document.createElement("a");o.href=n,o.download=s,o.click(),URL.revokeObjectURL(n)}function so(s){return s.replace(/[^a-z0-9-_ ]/gi,"").trim().slice(0,60)||"board"}class za{exportBoardJson(t){oo(`${so(t.title)}.json`,t)}async exportFullBundle(t){const e=[];for(const o of t.assetIds){const i=await ut.get(o);i&&e.push({id:i.id,mimeType:i.mimeType,width:i.width,height:i.height,name:i.name,base64:await Na(i.blob)})}const n={bundleVersion:1,board:t,assets:e};oo(`${so(t.title)}-bundle.json`,n)}async importFromFile(t){let e;try{e=JSON.parse(await t.text())}catch{return null}if(typeof e!="object"||e===null)return null;const n=e;if(n.bundleVersion===1&&Array.isArray(n.assets)){const o=oe(n.board);if(!o)return null;const i=new Map;for(const a of n.assets){const r=await this.importAsset(a);r&&i.set(r.originalId,r.asset.id)}for(const a of o.elements){const r=a.data.assetId;typeof r=="string"&&i.has(r)&&(a.data.assetId=i.get(r))}return o.assetIds=[...i.values()],o}return oe(e)}async importAsset(t){if(typeof t!="object"||t===null)return null;const e=t;if(typeof e.id!="string"||typeof e.base64!="string"||typeof e.mimeType!="string"||!e.mimeType.startsWith("image/"))return null;try{const n=Fa(e.base64,e.mimeType),o=Date.now(),i={id:Se(),type:"image",mimeType:e.mimeType,blob:n,width:typeof e.width=="number"?e.width:0,height:typeof e.height=="number"?e.height:0,sizeBytes:n.size,createdAt:o,updatedAt:o,name:typeof e.name=="string"?e.name.slice(0,100):void 0};return await ut.put(i),{originalId:e.id,asset:i}}catch{return null}}}const dn=new za,ja=[{tool:"select",icon:"select",label:"Select",key:"V"},{tool:"hand",icon:"hand",label:"Hand",key:"H"},{tool:"sticky",icon:"sticky",label:"Sticky note",key:"S"},{tool:"task",icon:"task",label:"Task",key:""},{tool:"text",icon:"text",label:"Text",key:"T"},{tool:"image",icon:"image",label:"Image",key:"I"}],ls=[{tool:"rectangle",icon:"rectangle",label:"Rectangle",key:"R"},{tool:"ellipse",icon:"ellipse",label:"Ellipse",key:"O"},{tool:"diamond",icon:"diamond",label:"Diamond",key:""},{tool:"triangle",icon:"triangle",label:"Triangle",key:""},{tool:"pill",icon:"pill",label:"Pill",key:""},{tool:"chevron",icon:"chevron",label:"Chevron",key:""},{tool:"parallelogram",icon:"parallelogram",label:"Parallelogram",key:""},{tool:"hexagon",icon:"hexagon",label:"Hexagon",key:""},{tool:"cylinder",icon:"cylinder",label:"Cylinder",key:""}],Ha=[{tool:"arrow",icon:"arrow",label:"Arrow (hold Shift to snap)",key:"A"},{tool:"dashedArrow",icon:"arrowDashed",label:"Dashed arrow",key:""},{tool:"twoWayArrow",icon:"arrowBoth",label:"Two-way arrow",key:""},{tool:"labeledArrow",icon:"arrowLabel",label:"Centered label arrow",key:""},{tool:"sidedLabelArrow",icon:"arrowLabel",label:"Left and right labels",key:""}],Wa=new Set(ls.map(s=>s.tool));class Oa{constructor(t,e){m(this,"element");m(this,"toolButtons",new Map);m(this,"shapeButtons",new Map);m(this,"shapeBtn");m(this,"shapeGroup");m(this,"arrowGroup");m(this,"themeBtn");this.element=document.createElement("div"),this.element.className="toolbar";for(const a of ja){const r=this.makeButton(a.icon,a.label,a.key);r.addEventListener("click",()=>e.setTool(a.tool)),this.toolButtons.set(a.tool,r),this.element.appendChild(r),a.tool==="sticky"&&this.element.appendChild(this.makeShapePicker(e)),a.tool==="text"&&this.element.appendChild(this.makeArrowPicker(e))}this.element.appendChild(this.divider());const n=this.makeButton("templates","Templates","");n.addEventListener("click",e.openTemplates),this.element.appendChild(n),this.element.appendChild(this.divider()),this.themeBtn=this.makeButton("moon","Toggle theme",""),this.themeBtn.addEventListener("click",e.toggleTheme),this.element.appendChild(this.themeBtn);const o=this.makeButton("export","Export / Import","");o.addEventListener("click",e.openExportMenu),this.element.appendChild(o);const i=this.makeButton("flask","Stress test","");if(i.addEventListener("click",e.toggleStressPanel),this.element.appendChild(i),e.selectRegion){this.element.appendChild(this.divider());const a=this.makeButton("embed","Select region to embed or export","");a.addEventListener("click",e.selectRegion),this.element.appendChild(a)}t.appendChild(this.element)}makeButton(t,e,n){const o=document.createElement("button");o.className="tool-btn",o.setAttribute("aria-label",e),o.innerHTML=Q[t]??"";const i=document.createElement("span");if(i.className="tooltip",i.textContent=e,n){const a=document.createElement("kbd");a.textContent=n,i.appendChild(a)}return o.appendChild(i),o}makeShapePicker(t){this.shapeGroup=document.createElement("div"),this.shapeGroup.className="shape-tool-group",this.shapeBtn=this.makeButton("shapes","Shapes",""),this.shapeBtn.classList.add("shape-tool-trigger"),this.shapeBtn.addEventListener("click",n=>{n.stopPropagation(),this.shapeGroup.classList.toggle("open")});const e=document.createElement("div");e.className="shape-tool-popover";for(const n of ls){const o=this.makeButton(n.icon,n.label,n.key);o.classList.add("shape-option-btn"),o.addEventListener("click",i=>{i.stopPropagation(),t.setTool(n.tool),this.shapeGroup.classList.remove("open")}),this.shapeButtons.set(n.tool,o),e.appendChild(o)}return this.shapeGroup.append(this.shapeBtn,e),this.shapeGroup}makeArrowPicker(t){this.arrowGroup=document.createElement("div"),this.arrowGroup.className="shape-tool-group";const e=this.makeButton("arrow","Arrow types","");e.classList.add("shape-tool-trigger"),e.addEventListener("click",o=>{o.stopPropagation(),this.arrowGroup.classList.toggle("open")});const n=document.createElement("div");n.className="shape-tool-popover";for(const o of Ha){const i=this.makeButton(o.icon,o.label,o.key);i.classList.add("shape-option-btn"),i.addEventListener("click",a=>{a.stopPropagation(),t.setTool(o.tool),this.arrowGroup.classList.remove("open")}),this.toolButtons.set(o.tool,i),n.appendChild(i)}return this.arrowGroup.append(e,n),this.arrowGroup}divider(){const t=document.createElement("div");return t.className="toolbar-divider",t}setActiveTool(t){var e;for(const[n,o]of this.toolButtons)o.classList.toggle("active",n===t);for(const[n,o]of this.shapeButtons)o.classList.toggle("active",n===t);(e=this.shapeBtn)==null||e.classList.toggle("active",Wa.has(t))}setTheme(t){const e=this.themeBtn.querySelector(".tooltip");this.themeBtn.innerHTML=Q[t==="dark"?"sun":"moon"],e&&this.themeBtn.appendChild(e)}}class Ua{constructor(t,e,n){m(this,"zoomLabel");m(this,"titleInput");m(this,"titleMeasure");m(this,"statusEl");m(this,"statusTextEl");m(this,"statusActionBtn");const o=document.createElement("div");if(o.className="top-left",e.onExit){const u=document.createElement("button");u.className="control-btn back-btn",u.innerHTML=`${Q.arrowLeft}<span>ViteBoard</span>`,u.title="Save and back to ViteBoard",u.setAttribute("aria-label","Back to ViteBoard"),u.addEventListener("click",e.onExit),o.appendChild(u)}this.titleInput=document.createElement("input"),this.titleInput.className="board-title",this.titleInput.value=n,this.titleInput.maxLength=120,this.titleInput.setAttribute("aria-label","Board title"),this.titleInput.addEventListener("change",()=>e.onTitleChange(this.titleInput.value.trim()||"Untitled Board")),this.titleInput.addEventListener("input",()=>this.resizeTitleInput()),this.titleInput.addEventListener("keydown",u=>{u.stopPropagation(),u.key==="Enter"&&this.titleInput.blur()}),this.titleMeasure=document.createElement("span"),this.titleMeasure.className="board-title-measure",o.appendChild(this.titleInput),o.appendChild(this.titleMeasure),t.appendChild(o),this.resizeTitleInput();const i=document.createElement("div");i.className="top-right";const a=document.createElement("div");a.className="control-group";const r=this.btn("−","Zoom out (Ctrl/Cmd + wheel or Ctrl/Cmd + -)");r.addEventListener("click",e.zoomOut),a.appendChild(r),this.zoomLabel=this.btn("100%","Reset zoom to 100% (Ctrl/Cmd + 0)"),this.zoomLabel.classList.add("zoom-label"),this.zoomLabel.addEventListener("click",e.resetView),a.appendChild(this.zoomLabel);const c=this.btn("+","Zoom in (Ctrl/Cmd + wheel or Ctrl/Cmd + +)");c.addEventListener("click",e.zoomIn),a.appendChild(c),i.appendChild(a);const l=document.createElement("div");l.className="control-group";const d=this.iconBtn("reset","Reset view");d.addEventListener("click",e.resetView),l.appendChild(d);const h=this.iconBtn("storage","Storage manager");h.addEventListener("click",e.openStorageManager),l.appendChild(h);const p=this.iconBtn("gauge","Performance overlay");if(p.addEventListener("click",e.togglePerfOverlay),l.appendChild(p),e.deleteBoard){const u=this.iconBtn("trash","Delete board");u.classList.add("danger-control"),u.addEventListener("click",e.deleteBoard),l.appendChild(u)}i.appendChild(l),this.statusEl=document.createElement("div"),this.statusEl.className="board-live-status",this.statusEl.hidden=!0,this.statusTextEl=document.createElement("span"),this.statusActionBtn=document.createElement("button"),this.statusActionBtn.className="status-action-btn",this.statusActionBtn.hidden=!0,this.statusEl.append(this.statusTextEl,this.statusActionBtn),i.appendChild(this.statusEl),t.appendChild(i)}btn(t,e){const n=document.createElement("button");return n.className="control-btn",n.textContent=t,n.title=e,n.setAttribute("aria-label",e),n}iconBtn(t,e){const n=document.createElement("button");return n.className="control-btn",n.innerHTML=Q[t]??"",n.title=e,n.setAttribute("aria-label",e),n}setZoom(t){this.zoomLabel.textContent=Math.round(t*100)+"%"}setTitle(t){this.titleInput.value=t,this.resizeTitleInput()}setStatus(t,e,n){this.statusEl.hidden=!t,this.statusTextEl.textContent=t,this.statusEl.dataset.state=e,this.statusActionBtn.hidden=!n,this.statusActionBtn.textContent=(n==null?void 0:n.label)??"",this.statusActionBtn.onclick=(n==null?void 0:n.onClick)??null}resizeTitleInput(){if(!this.titleMeasure||!this.titleInput)return;this.titleMeasure.textContent=this.titleInput.value||"Untitled Board";const t=Math.ceil(this.titleMeasure.getBoundingClientRect().width+22),e=Math.max(180,window.innerWidth-460);this.titleInput.style.width=Math.min(Math.max(90,t),e)+"px"}}class _a{constructor(t,e){m(this,"state");m(this,"commands");m(this,"textareas",[]);m(this,"editingId",null);this.state=t,this.commands=e}get isEditing(){return this.editingId!==null}open(t){if(this.close(),this.editingId=t.id,t.data.labelPosition==="sides"){this.openSideEditors(t);return}const e=document.createElement("textarea");e.className="text-editor",e.value=t.data.text??"",t.data.labelPosition==="sides"&&(e.placeholder="left label | right label"),this.position(e,t),document.body.appendChild(e),this.textareas=[e],e.focus(),e.select();const n=t.data.text??"";t.data.text="",t.updatedAt=Date.now(),nt(t.id),this.state.requestRender();const o=()=>{const i=e.value;if(t.data.text=i,Wt(t),t.updatedAt=Date.now(),nt(t.id),i!==n){const a=t.id,r=this.state;this.commands.push("edit-text",()=>{const c=r.elementsById.get(a);c&&(c.data.text=i,Wt(c),c.updatedAt=Date.now(),nt(a),r.emitChange())},()=>{const c=r.elementsById.get(a);c&&(c.data.text=n,Wt(c),c.updatedAt=Date.now(),nt(a),r.emitChange())})}this.state.emitChange(),this.close()};e.addEventListener("blur",o),e.addEventListener("keydown",i=>{i.stopPropagation(),i.key==="Escape"?(t.data.text=n,nt(t.id),this.close(),this.state.requestRender()):i.key==="Enter"&&(i.metaKey||i.ctrlKey)&&e.blur()})}openSideEditors(t){const e=String(t.data.text??""),[n="",o=""]=e.split("|",2).map(d=>d.trim()),i=this.makeSideEditor("Left label",n),a=this.makeSideEditor("Right label",o);this.positionSideEditors(i,a,t),document.body.append(i,a),this.textareas=[i,a],i.focus(),i.select(),t.data.text="",t.updatedAt=Date.now(),nt(t.id),this.state.requestRender();let r=!1;const c=()=>{if(r)return;r=!0;const d=`${i.value.trim()} | ${a.value.trim()}`;t.data.text=d,t.updatedAt=Date.now(),nt(t.id),d!==e&&this.pushTextCommand(t.id,e,d),this.state.emitChange(),this.close()},l=()=>{r||(r=!0,t.data.text=e,nt(t.id),this.close(),this.state.requestRender())};for(const d of[i,a])d.addEventListener("keydown",h=>{h.stopPropagation(),h.key==="Escape"?l():h.key==="Enter"&&(h.metaKey||h.ctrlKey)&&c()}),d.addEventListener("blur",()=>{window.setTimeout(()=>{this.textareas.includes(document.activeElement)||c()},0)})}makeSideEditor(t,e){const n=document.createElement("textarea");return n.className="text-editor text-editor-side",n.placeholder=t,n.value=e,n.style.fontFamily='-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',n.style.fontWeight="600",n.style.textAlign="center",n.style.lineHeight="1.35",n.style.color=this.state.theme==="dark"?"#f2f2f2":"#1f2933",n}positionSideEditors(t,e,n){const o=this.state.viewport,i=Ot(n.x,n.y,o),a=Ot(n.x+n.width,n.y+n.height,o),r=13*o.scale,c=Math.max(82,Math.min(150,Math.hypot(a.x-i.x,a.y-i.y)*.34)),l=Math.max(24,r*1.35+4);for(const[d,h]of[[t,.24],[e,.76]])d.style.left=i.x+(a.x-i.x)*h-c/2+"px",d.style.top=i.y+(a.y-i.y)*h-l/2+"px",d.style.width=c+"px",d.style.height=l+"px",d.style.fontSize=r+"px"}pushTextCommand(t,e,n){const o=this.state;this.commands.push("edit-text",()=>{const i=o.elementsById.get(t);i&&(i.data.text=n,Wt(i),i.updatedAt=Date.now(),nt(t),o.emitChange())},()=>{const i=o.elementsById.get(t);i&&(i.data.text=e,Wt(i),i.updatedAt=Date.now(),nt(t),o.emitChange())})}position(t,e){const n=this.state.viewport;if(e.type==="arrow"||e.type==="line"||e.type==="connector"){const y=Ot(e.x,e.y,n),x=Ot(e.x+e.width,e.y+e.height,n),v=13*n.scale,E=Math.max(100,Math.min(240,Math.hypot(x.x-y.x,x.y-y.y)-16)),w=Math.max(24,v*1.35+4);t.style.left=(y.x+x.x)/2-E/2+"px",t.style.top=(y.y+x.y)/2-w/2+"px",t.style.width=E+"px",t.style.height=w+"px",t.style.fontSize=v+"px",t.style.lineHeight="1.35",t.style.fontFamily='-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',t.style.fontWeight="600",t.style.color=this.state.theme==="dark"?"#f2f2f2":"#1f2933",t.style.textAlign="center";return}const o=Ot(e.x,e.y,n),i=e.data.shapeKind==="chevron",a=Je(e)*n.scale,r=i?Math.min(Math.abs(e.width)*.18,Math.abs(e.height)*.55)+8:10,c=(e.type==="sticky"?14:e.type==="task"?50:e.type==="text"?0:r)*n.scale,l=e.type!=="text"&&e.type!=="task",d=i?e.height*n.scale:e.height*n.scale-(e.type==="sticky"?28:l?r*2:0)*n.scale,h=Math.max(1,String(e.data.text??"").split(/\r?\n/).length),p=Math.max(24,a*(i?1.18:1.35)*h+4),u=l?Math.min(Math.max(24,d),p):Math.max(24,d),g=l?Math.max(0,(e.height*n.scale-u)/2):e.type==="sticky"?14*n.scale:0,b=(e.type==="task"?16:e.type==="sticky"?14:e.type==="text"?0:r)*n.scale;t.style.left=o.x+c+"px",t.style.top=o.y+g+"px",t.style.width=Math.max(40,e.width*n.scale-c-b)+"px",t.style.height=u+"px",t.style.fontSize=a+"px",t.style.lineHeight=i?"1.18":"1.35",t.style.fontFamily=e.style.fontFamily??'-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',t.style.fontWeight=i?"750":e.style.fontWeight??"400",t.style.color=e.style.textColor??(this.state.theme==="dark"?"#f2f2f2":"#1f2933"),t.style.textAlign=e.type==="text"||e.type==="task"?"left":"center"}close(){if(this.textareas.length){const t=this.textareas;this.textareas=[],this.editingId=null;for(const e of t)e.remove()}}}function kt(s){return s==="dark"?{card:"#1e2126",cardStroke:"#3a3f46",heading:"#f2f2f2",text:"#c8cdd4",accent:"#4dabf7",sticky:"#fef08a",zone:"#22262c"}:{card:"#ffffff",cardStroke:"#d8dade",heading:"#1f2933",text:"#4b5563",accent:"#6e6e6e",sticky:"#fef08a",zone:"#f0f0ed"}}let de=0;function Et(s){de=s}function U(s,t,e,n,o,i=""){return Y("rectangle",{x:s,y:t,width:e,height:n,zIndex:++de,style:{borderRadius:10,...o},data:{text:i}})}function L(s,t,e,n,o,i,a="600"){return Y("text",{x:s,y:t,width:e,height:o*1.6,zIndex:++de,style:{fontSize:o,textColor:i,fontWeight:a},data:{text:n}})}function G(s,t,e,n,o=180,i=120){return Y("sticky",{x:s,y:t,width:o,height:i,zIndex:++de,style:{fill:n,borderRadius:12,shadow:!0,fontSize:13,textColor:"#1f2933"},data:{text:e}})}function X(s,t,e,n,o,i={}){return Y("arrow",{x:s,y:t,width:e-s,height:n-t,zIndex:++de,style:{stroke:o,strokeWidth:2,arrowEnd:!0,arrowStart:i.arrowStart,strokeDash:i.dashed?[8,6]:void 0},data:{text:i.label??"",labelPosition:i.sides?"sides":"center"}})}function Xa(s,t,e,n,o,i=""){return Y("ellipse",{x:s,y:t,width:e,height:n,zIndex:++de,style:o,data:{text:i}})}function Ya(s,t,e,n){const o=kt(e);Et(n);const i=[];return i.push(U(s,t,760,560,{fill:o.card,stroke:o.cardStroke,strokeWidth:1.5,borderRadius:16,shadow:!0})),i.push(L(s+28,t+22,400,"User Persona",22,o.heading,"700")),i.push(L(s+28,t+60,300,"Name",13,o.accent)),i.push(G(s+28,t+86,"Jordan Lee",o.sticky,200,64)),i.push(L(s+260,t+60,300,"Role",13,o.accent)),i.push(G(s+260,t+86,"Senior Product Manager","#a5b4fc",220,64)),i.push(L(s+510,t+60,300,"Buying trigger",13,o.accent)),i.push(G(s+510,t+86,"Team scaling pains","#fdba74",220,64)),[["Goals","Ship the right features faster","#86efac"],["Pain points","Scattered docs, unclear priorities","#fca5a5"],["Jobs to be done","Align team on what to build next","#93c5fd"],["Current workaround","Spreadsheets + slide decks","#d8b4fe"],["Success criteria","Stakeholders aligned in 1 meeting","#f9a8d4"],["Key quote",'"I need clarity, not more tools."',"#fef08a"]].forEach(([r,c,l],d)=>{const h=d%3,p=Math.floor(d/3),u=s+28+h*242,g=t+188+p*178;i.push(L(u,g,230,r,13,o.accent)),i.push(G(u,g+26,c,l,220,124))}),i}const hn=["Awareness","Discovery","Evaluation","Onboarding","Activation","Retention"],Va=["#93c5fd","#a5b4fc","#d8b4fe","#f9a8d4","#fdba74","#86efac"];function qa(s,t,e,n){const o=kt(e);Et(n);const i=[],a=230,r=hn.length*a+56;return i.push(U(s,t,r,640,{fill:o.card,stroke:o.cardStroke,strokeWidth:1.5,borderRadius:16,shadow:!0})),i.push(L(s+28,t+22,500,"User Journey Map",22,o.heading,"700")),hn.forEach((c,l)=>{const d=s+28+l*a,h=t+70;i.push(U(d,h,a-16,48,{fill:Va[l],borderRadius:10},c)),l<hn.length-1&&i.push(X(d+a-14,h+24,d+a-2,h+24,o.heading)),i.push(U(d,h+64,a-16,150,{fill:o.zone,borderRadius:10},"")),i.push(L(d+10,h+70,a-36,"Actions",12,o.accent)),i.push(G(d+14,h+96,"","#fef08a",a-44,100)),i.push(U(d,h+226,a-16,150,{fill:o.zone,borderRadius:10},"")),i.push(L(d+10,h+232,a-36,"Pain points",12,o.accent)),i.push(G(d+14,h+258,"","#fca5a5",a-44,100)),i.push(U(d,h+388,a-16,150,{fill:o.zone,borderRadius:10},"")),i.push(L(d+10,h+394,a-36,"Opportunities",12,o.accent)),i.push(G(d+14,h+420,"","#86efac",a-44,100))}),i}function Ka(s,t,e,n){const o=kt(e);Et(n);const i=[],a=680;i.push(U(s,t,a+120,a+130,{fill:o.card,stroke:o.cardStroke,strokeWidth:1.5,borderRadius:16,shadow:!0})),i.push(L(s+28,t+22,500,"Feature Prioritization Matrix",22,o.heading,"700"));const r=s+80,c=t+80,l=a/2;return i.push(U(r,c,l,l,{fill:"#86efac55",borderRadius:8})),i.push(U(r+l,c,l,l,{fill:"#93c5fd55",borderRadius:8})),i.push(U(r,c+l,l,l,{fill:"#fef08a55",borderRadius:8})),i.push(U(r+l,c+l,l,l,{fill:"#fca5a555",borderRadius:8})),i.push(L(r+16,c+12,300,"Quick wins",16,o.heading,"700")),i.push(L(r+l+16,c+12,300,"Strategic bets",16,o.heading,"700")),i.push(L(r+16,c+l+12,300,"Fill-ins",16,o.heading,"700")),i.push(L(r+l+16,c+l+12,300,"Avoid",16,o.heading,"700")),i.push(X(r-24,c+a,r-24,c,o.heading)),i.push(L(r-64,c+l-12,60,"Impact",14,o.text,"600")),i.push(X(r,c+a+24,r+a,c+a+24,o.heading)),i.push(L(r+l-30,c+a+34,80,"Effort",14,o.text,"600")),i.push(G(r+40,c+60,"Feature idea","#fef08a",150,90)),i.push(G(r+l+40,c+60,"Big bet","#a5b4fc",150,90)),i}const io=[["Problem","#fca5a5"],["User","#93c5fd"],["Context","#d8b4fe"],["Current workflow","#fdba74"],["Proposed solution","#86efac"],["Edge cases","#f9a8d4"],["Acceptance criteria","#a5b4fc"],["Dependencies","#fef08a"],["Risks","#fca5a5"]];function Ga(s,t,e,n){const o=kt(e);Et(n);const i=[],a=3,r=280,c=210,l=a*r+56,h=Math.ceil(io.length/a)*c+100;return i.push(U(s,t,l,h,{fill:o.card,stroke:o.cardStroke,strokeWidth:1.5,borderRadius:16,shadow:!0})),i.push(L(s+28,t+22,500,"Product Requirements Flow",22,o.heading,"700")),io.forEach(([p,u],g)=>{const b=g%a,y=Math.floor(g/a),x=s+28+b*r,v=t+72+y*c;i.push(L(x,v,r-30,`${g+1}. ${p}`,14,o.accent)),i.push(G(x,v+30,"",u,r-28,c-60))}),i}function Za(s,t,e,n){const o=kt(e);Et(n);const i=[];i.push(L(s,t-40,400,"System Diagram",22,o.heading,"700"));const a=(r,c,l,d,h,p)=>U(r,c,l,d,{fill:h,stroke:o.cardStroke,strokeWidth:1.5,borderRadius:12,shadow:!0,fontSize:15,fontWeight:"600",textColor:"#1f2933"},p);return i.push(Xa(s,t+130,110,110,{fill:"#f9a8d4",stroke:o.cardStroke,strokeWidth:1.5,fontSize:14,fontWeight:"600",textColor:"#1f2933"},"User")),i.push(a(s+200,t+140,180,90,"#93c5fd","Frontend")),i.push(a(s+470,t+140,180,90,"#a5b4fc","API / Server")),i.push(a(s+740,t+60,180,90,"#86efac","Database")),i.push(a(s+740,t+200,180,90,"#fdba74","External Service")),i.push(a(s+470,t+330,180,90,"#fef08a","Notification Service")),i.push(X(s+115,t+185,s+195,t+185,o.heading,{label:"uses"})),i.push(X(s+385,t+185,s+465,t+185,o.heading,{label:"request | response",sides:!0,arrowStart:!0})),i.push(X(s+655,t+165,s+735,t+110,o.heading,{label:"read"})),i.push(X(s+655,t+205,s+735,t+240,o.heading,{label:"webhook",dashed:!0})),i.push(X(s+560,t+235,s+560,t+325,o.heading,{label:"event",dashed:!0})),i.push(X(s+470,t+375,s+80,t+245,o.heading,{label:"notify",dashed:!0})),i}function Ja(s,t,e,n){const o=kt(e);Et(n);const i=[];i.push(L(s+280,t-40,500,"Opportunity Solution Tree",22,o.heading,"700")),i.push(U(s+300,t,280,80,{fill:"#a5b4fc",borderRadius:12,shadow:!0,fontSize:15,fontWeight:"600",textColor:"#1f2933"},"Desired outcome"));const a=t+160,r=[s,s+300,s+600];for(const d of r)i.push(G(d,a,"Opportunity","#93c5fd",220,100)),i.push(X(s+440,t+85,d+110,a-5,o.heading));const c=a+180;for(const d of r)i.push(G(d,c,"Solution","#86efac",220,100)),i.push(X(d+110,a+105,d+110,c-5,o.heading));const l=c+180;for(const d of r)i.push(G(d,l,"Experiment","#fdba74",220,90)),i.push(X(d+110,c+105,d+110,l-5,o.heading));return i.push(L(s,l+120,400,"Signals / metrics",14,o.accent)),i.push(G(s,l+150,"What signal tells us this is working?","#fef08a",380,100)),i}function Qa(s,t,e,n){const o=kt(e);Et(n);const i=[];i.push(U(s,t,1060,620,{fill:o.card,stroke:o.cardStroke,strokeWidth:1.5,borderRadius:16,shadow:!0})),i.push(L(s+28,t+22,500,"Screenshot Review",22,o.heading,"700")),i.push(L(s+28,t+64,300,"Screenshot",13,o.accent));const a=Y("frame",{x:s+28,y:t+92,width:480,height:360,zIndex:n+100,style:{fill:o.zone,stroke:o.cardStroke,strokeWidth:1.5,borderRadius:12,fontSize:13,textColor:o.text},data:{text:"Paste a screenshot here (Cmd/Ctrl+V)"}});return i.push(a),[["Observations","#93c5fd"],["Problems","#fca5a5"],["UX notes","#d8b4fe"],["Requirements","#86efac"]].forEach(([c,l],d)=>{const h=d%2,p=Math.floor(d/2),u=s+540+h*250,g=t+64+p*200;i.push(L(u,g,230,c,13,o.accent)),i.push(G(u,g+28,"",l,230,140))}),i.push(L(s+28,t+470,300,"Follow-up tasks",13,o.accent)),i.push(G(s+28,t+498,"","#fef08a",480,96)),i.push(L(s+540,t+470,300,"Decision",13,o.accent)),i.push(G(s+540,t+498,"","#fdba74",480,96)),i}function tr(s,t,e,n){const o=kt(e);Et(n);const i=[];i.push(L(s,t,880,"Workflow map",26,o.heading,"700"));const a=[["Request","#dbeafe"],["Review","#fef3c7"],["Deliver","#dcfce7"]];for(let r=0;r<a.length;r++){const c=s+r*280;i.push(U(c,t+130,180,96,{fill:a[r][1],stroke:o.cardStroke,strokeWidth:1.5,borderRadius:12,fontSize:16,fontWeight:"650",textColor:"#1f2933",shadow:!0},a[r][0]))}return i.push(X(s+180,t+178,s+280,t+178,o.accent,{label:"approve"})),i.push(X(s+460,t+178,s+560,t+178,o.accent,{label:"ship"})),i.push(X(s+650,t+226,s+370,t+310,"#9ca3af",{label:"feedback",dashed:!0})),i.push(U(s+280,t+300,180,72,{fill:o.zone,stroke:o.cardStroke,strokeWidth:1.5,borderRadius:10,fontSize:14,textColor:o.text},"Learn and iterate")),i}function er(s,t,e,n){const o=kt(e);Et(n);const i=[];return i.push(L(s,t,800,"Handoff map",26,o.heading,"700")),[["Explore","#dbeafe"],["Decide","#fef3c7"],["Act","#dcfce7"]].forEach(([r,c],l)=>{i.push(U(s+l*270,t+150,170,92,{fill:c,stroke:o.cardStroke,strokeWidth:1.5,borderRadius:12,shadow:!0,fontSize:16,fontWeight:"650",textColor:"#1f2933"},r))}),i.push(X(s+170,t+196,s+270,t+196,o.accent,{label:"proposal"})),i.push(X(s+440,t+196,s+540,t+196,o.accent,{label:"owner | outcome",sides:!0,arrowStart:!0})),i.push(X(s+625,t+245,s+355,t+330,"#9ca3af",{label:"feedback",dashed:!0})),i.push(U(s+265,t+320,180,70,{fill:o.zone,stroke:o.cardStroke,strokeWidth:1.5,borderRadius:10,fontSize:14,textColor:o.text},"Review signal")),i}const nr=[{id:"persona",name:"User Persona Card",description:"Name, role, goals, pain points, JTBD, success criteria.",build:Ya},{id:"journey",name:"User Journey Map",description:"Awareness → Retention stages with sticky note areas.",build:qa},{id:"matrix",name:"Prioritization Matrix",description:"Impact vs effort: quick wins, strategic bets, fill-ins, avoid.",build:Ka},{id:"requirements",name:"Requirements Flow",description:"Problem, user, context, solution, edge cases, risks.",build:Ga},{id:"system",name:"System Diagram Starter",description:"User, frontend, API, database, external services + arrows.",build:Za},{id:"ost",name:"Opportunity Solution Tree",description:"Outcome, opportunities, solutions, experiments, signals.",build:Ja},{id:"screenshot-review",name:"Screenshot Review Board",description:"Screenshot zone with observations, problems, UX notes.",build:Qa},{id:"workflow",name:"Workflow Map",description:"Labeled handoffs, a dashed feedback loop, and editable steps.",build:tr},{id:"handoff",name:"Handoff Map",description:"A shared decision flow with ownership, outcomes, and feedback.",build:er}];function or(s,t){et("Insert a template",(e,n)=>{const o=document.createElement("div");o.className="template-grid";for(const i of nr){const a=document.createElement("button");a.className="template-card";const r=document.createElement("span");r.className="t-name",r.textContent=i.name;const c=document.createElement("span");c.className="t-desc",c.textContent=i.description,a.appendChild(r),a.appendChild(c),a.addEventListener("click",()=>{sr(s,t,i.build),n()}),o.appendChild(a)}e.appendChild(o)})}function sr(s,t,e){const n=H(window.innerWidth/2,window.innerHeight/2,s.viewport),o=e(n.x-380,n.y-280,s.theme,s.maxZIndex());t.execute("insert-template",()=>{for(const i of o)s.elementsById.has(i.id)||s.addElement(i);s.emitChange()},()=>{for(const i of o)s.removeElement(i.id);s.emitChange()}),s.clearSelection();for(const i of o)s.selectedIds.add(i.id);s.requestRender()}function Fe(s){return s<1024?s+" B":s<1024*1024?(s/1024).toFixed(1)+" KB":(s/(1024*1024)).toFixed(1)+" MB"}function ir(s,t,e,n){et(n?"Storage":"Local storage",async(o,i)=>{const a=document.createElement("div");o.appendChild(a);const r=(g,b)=>{const y=document.createElement("div");y.className="storage-row";const x=document.createElement("span");x.textContent=g;const v=document.createElement("span");v.textContent=b,y.appendChild(x),y.appendChild(v),a.appendChild(y)};r("Elements on board",String(s.elements.length));const c=JSON.stringify(s.elements);if(r("Board data size",Fe(c.length)),n)r("Workspace assets","Stored on disk under docs/assets");else{const g=await ut.getAllKeys();r("Image assets",String(g.length));const b=await ut.totalSizeBytes();r("Image asset size",Fe(b))}const l=await pt.estimateStorage();!n&&l.quota>0&&r("Browser storage",`${Fe(l.usage)} of ${Fe(l.quota)}`);const d=document.createElement("div");d.className="modal-actions";const h=document.createElement("button");h.className="btn",h.textContent=n?"Clean unused managed assets":"Clear unused assets",h.addEventListener("click",async()=>{if(n){const x=s.elements.map(v=>typeof v.data.src=="string"?v.data.src:"").filter(Boolean);try{const v=await n(x);C(`Removed ${v} unused managed asset${v===1?"":"s"}`),i()}catch{C("Could not clean workspace assets")}return}const g=new Set,b=await pt.getAllBoards();for(const x of b)for(const v of x.elements){const E=v.data.assetId;typeof E=="string"&&g.add(E)}const y=await ut.clearUnused(g);C(`Removed ${y} unused asset${y===1?"":"s"}`),i()}),d.appendChild(h);const p=document.createElement("button");p.className="btn danger",p.textContent="Clear board",p.addEventListener("click",()=>{confirm("Remove all elements from this board?")&&(t(),i())}),d.appendChild(p);const u=document.createElement("button");u.className="btn danger",u.textContent=n?"Reset local-only data":"Reset all local data",u.addEventListener("click",()=>{confirm("Delete ALL local boards, assets and preferences? This cannot be undone.")&&(e(),i())}),d.appendChild(u),o.appendChild(d)})}class ar{constructor(t,e,n,o,i,a){m(this,"element");m(this,"visible",!1);m(this,"state");m(this,"renderer");m(this,"hitTester");m(this,"monitor");m(this,"imageCache");m(this,"timer",null);m(this,"storageEstimate","–");this.state=e,this.renderer=n,this.hitTester=o,this.monitor=i,this.imageCache=a,this.element=document.createElement("div"),this.element.className="perf-overlay",t.appendChild(this.element)}toggle(){this.visible=!this.visible,this.element.classList.toggle("visible",this.visible),this.visible?(this.monitor.start(),this.update(),this.timer=window.setInterval(()=>this.update(),500),this.refreshStorage()):this.timer!==null&&(clearInterval(this.timer),this.timer=null)}async refreshStorage(){const t=await ut.totalSizeBytes();this.storageEstimate=(t/(1024*1024)).toFixed(1)+"MB"}update(){const t=this.state.viewport,e=[`FPS: ${this.monitor.fps}`,`Total elements: ${this.state.elements.length.toLocaleString()}`,`Visible elements: ${this.renderer.visibleCount.toLocaleString()}`,`Render time: ${this.renderer.lastRenderMs.toFixed(1)}ms`,`Hit-test time: ${this.hitTester.lastHitTestMs.toFixed(2)}ms`,`Save time: ${pt.lastSaveMs.toFixed(0)}ms`,`Image cache: ${this.imageCache.size}`,`Estimated storage: ${this.storageEstimate}`,`Zoom: ${Math.round(t.scale*100)}%`,`Viewport: x: ${Math.round(-t.offsetX/t.scale)}, y: ${Math.round(-t.offsetY/t.scale)}`,`Culling: ${this.renderer.cullingEnabled?"on":"off"} LOD: ${this.renderer.lodEnabled?"on":"off"}`];this.element.textContent=e.join(`
15
+ `)}}const ze=["#93c5fd","#a5b4fc","#86efac","#fdba74","#fca5a5","#d8b4fe","#f9a8d4","#fef08a","#ffffff","#e5e7eb"],ao=["Onboarding","Checkout","Retention","Activation","Churn risk","API gateway","User insight","Edge case","Quick win","Tech debt","Experiment","Metric","Persona","Journey","Feature flag"];function ht(s,t){return s+Math.random()*(t-s)}function yt(s){return s[Math.floor(Math.random()*s.length)]}const bt="stress";class rr{constructor(t){m(this,"state");m(this,"lastGenerateMs",0);this.state=t}generate(t){const e=performance.now(),n=Math.sqrt(t)*280,o=["sticky","rectangle","ellipse","text","arrow"];let i=this.state.maxZIndex();const a=[];for(let r=0;r<t;r++){const c=yt(o),l=ht(-n/2,n/2),d=ht(-n/2,n/2);let h;c==="sticky"?h=Y("sticky",{x:l,y:d,width:220,height:160,zIndex:++i,style:{fill:yt(qe),borderRadius:12,shadow:!0,fontSize:14,textColor:"#1f2933"},data:{text:yt(ao),[bt]:!0}}):c==="rectangle"||c==="ellipse"?h=Y(c,{x:l,y:d,width:ht(80,300),height:ht(60,200),zIndex:++i,style:{fill:yt(ze),stroke:"#37415188",strokeWidth:1.5,borderRadius:c==="rectangle"?8:0},data:{[bt]:!0}}):c==="text"?h=Y("text",{x:l,y:d,width:200,height:28,zIndex:++i,style:{fontSize:16,textColor:this.state.theme==="dark"?"#f2f2f2":"#1f2933"},data:{text:yt(ao),[bt]:!0}}):h=Y("arrow",{x:l,y:d,width:ht(-250,250),height:ht(-250,250),zIndex:++i,style:{stroke:yt(ze),strokeWidth:2,arrowEnd:!0},data:{[bt]:!0}}),a.push(h)}for(const r of a)this.state.addElement(r);this.lastGenerateMs=performance.now()-e,this.state.emitChange()}generateImagePlaceholders(t){const e=Math.sqrt(t)*420;let n=this.state.maxZIndex();for(let o=0;o<t;o++){const i=Y("image",{x:ht(-e/2,e/2),y:ht(-e/2,e/2),width:320,height:220,zIndex:++n,data:{assetId:"stress-placeholder-"+o,[bt]:!0}});this.state.addElement(i)}this.state.emitChange()}generateMixedPmBoard(){this.generate(300)}randomizePositions(){const t=Math.sqrt(this.state.elements.length)*280;for(const e of this.state.elements)e.data[bt]&&(e.x=ht(-t/2,t/2),e.y=ht(-t/2,t/2));this.state.emitChange()}randomizeColors(){for(const t of this.state.elements)t.data[bt]&&(t.type==="sticky"?t.style.fill=yt(qe):t.type==="rectangle"||t.type==="ellipse"?t.style.fill=yt(ze):t.type==="arrow"&&(t.style.stroke=yt(ze)));this.state.emitChange()}randomizeZIndex(){for(const t of this.state.elements)t.data[bt]&&(t.zIndex=Math.floor(ht(0,this.state.elements.length)));this.state.invalidateSort(),this.state.emitChange()}clearGenerated(){const t=this.state.elements.filter(e=>e.data[bt]);for(const e of t)this.state.removeElement(e.id);this.state.emitChange()}}class cr{constructor(t,e,n){m(this,"element");m(this,"visible",!1);this.element=document.createElement("div"),this.element.className="stress-panel";const o=(a,r,c=!1)=>{const l=document.createElement("button");l.className="btn"+(c?" danger":""),l.textContent=a,l.addEventListener("click",r),this.element.appendChild(l)},i=a=>()=>{e.generate(a),C(`Generated ${a.toLocaleString()} elements in ${e.lastGenerateMs.toFixed(0)}ms`)};o("+100",i(100)),o("+1,000",i(1e3)),o("+5,000",i(5e3)),o("+10,000",i(1e4)),o("+20,000",i(2e4)),o("+100 images",()=>{e.generateImagePlaceholders(100),C("Generated 100 image placeholders")}),o("Mixed PM board",()=>{e.generateMixedPmBoard(),C("Generated mixed PM board")}),o("Shuffle positions",()=>e.randomizePositions()),o("Shuffle colors",()=>e.randomizeColors()),o("Shuffle z-index",()=>e.randomizeZIndex()),o("Toggle culling",()=>{n.cullingEnabled=!n.cullingEnabled,C(`Viewport culling ${n.cullingEnabled?"enabled":"disabled"}`),n.state.requestRender()}),o("Toggle LOD",()=>{n.lodEnabled=!n.lodEnabled,C(`Simplified rendering ${n.lodEnabled?"enabled":"disabled"}`),n.state.requestRender()}),o("Clear generated",()=>{e.clearGenerated(),C("Cleared generated elements")},!0),t.appendChild(this.element)}toggle(){this.visible=!this.visible,this.element.classList.toggle("visible",this.visible)}}const lr=300,dr=1e3,ro=[{label:"Small",shortLabel:"S",fontSize:13,fontWeight:"400"},{label:"Body",shortLabel:"Body",fontSize:16,fontWeight:"400"},{label:"H3",shortLabel:"H3",fontSize:18,fontWeight:"650"},{label:"H2",shortLabel:"H2",fontSize:24,fontWeight:"700"},{label:"H1",shortLabel:"H1",fontSize:32,fontWeight:"750"}],hr=new Set(["text"]),pr=new Set(["rectangle","ellipse","frame"]),ur=["#0078d4","#4dabf7","#6e6e6e","#ffffff","#0f0f0f","#fef08a","#93c5fd","#fca5a5"],mr=[{label:"Black text",value:"#1f2933"},{label:"White text",value:"#ffffff"}];class fr{constructor(t,e={}){m(this,"state",new ns);m(this,"commands",new na);m(this,"surface");m(this,"renderer");m(this,"scheduler");m(this,"hitTester");m(this,"imageCache");m(this,"monitor",new wa);m(this,"actions");m(this,"imageInsert");m(this,"toolController");m(this,"textEditor");m(this,"toolbar");m(this,"topControls");m(this,"perfOverlay");m(this,"stressPanel");m(this,"boardSaveTimer",null);m(this,"viewportSaveTimer",null);m(this,"saveInFlight",null);m(this,"saveQueued",!1);m(this,"suppressPersistence",!1);m(this,"options");m(this,"listenerAbort",new AbortController);m(this,"root");m(this,"revision",null);m(this,"stale",!1);m(this,"bottomToolCluster",null);m(this,"stickyColorPopover",null);m(this,"textSizePopover",null);m(this,"shapeStylePopover",null);m(this,"layerMenu",null);m(this,"regionActionMenu",null);m(this,"regionActionAbort",null);this.root=t,this.options=e,e.boardId&&(this.state.boardId=e.boardId);const n=this.listenerAbort.signal;this.surface=new fa(t,3,n),this.imageCache=new Mn(ut,()=>this.state.requestRender(),e.resolveAssetUrl),this.renderer=new ga(this.surface,this.state,this.imageCache),this.scheduler=new ya(()=>this.renderer.render()),this.hitTester=new va(this.state),this.actions=new oa(this.state,this.commands),this.textEditor=new _a(this.state,this.commands),this.imageInsert=new aa(this.state,this.commands,this.imageCache,C,e.uploadImage),this.state.onRenderNeeded(()=>{var o;this.scheduler.requestRender(),(o=this.topControls)==null||o.setZoom(this.state.viewport.scale),this.suppressPersistence||this.scheduleViewportSave(),this.updateContextualToolPanels()}),this.state.onChange(()=>{this.suppressPersistence||this.scheduleBoardSave()}),this.surface.onResize(()=>this.state.requestRender()),this.setupTools(t,n),this.setupUi(t),this.setupSelectionOverlays(t,n),this.setupDragDrop(t),new ca(this.state,this.actions,this.imageInsert,n),la({state:this.state,commands:this.commands,actions:this.actions,toolController:this.toolController,resetView:()=>this.resetView()},n),this.loadInitialState()}destroy(){this.boardSaveTimer!==null&&clearTimeout(this.boardSaveTimer),this.viewportSaveTimer!==null&&clearTimeout(this.viewportSaveTimer),this.listenerAbort.abort(),this.closeRegionActionMenu(),this.imageCache.clear()}setupTools(t,e){const n={state:this.state,renderer:this.renderer,surface:this.surface,hitTester:this.hitTester,commands:this.commands,setTool:o=>this.toolController.setTool(o),setCursor:o=>{this.surface.container.style.cursor=o},openTextEditor:o=>this.textEditor.open(o)};this.toolController=new Ea(this.surface.container,n,[new Ba,new Ma,new La,new Pa,new gt("rectangle"),new gt("ellipse"),new gt("diamond"),new gt("triangle"),new gt("pill"),new gt("chevron"),new gt("parallelogram"),new gt("hexagon"),new gt("cylinder"),new $a,new fe,new fe("dashedArrow"),new fe("twoWayArrow"),new fe("labeledArrow"),new fe("sidedLabelArrow"),new Da((o,i,a)=>void this.imageInsert.insertFiles(o,i,a))],e),this.toolController.onToolChange(o=>{var i;(i=this.toolbar)==null||i.setActiveTool(o)})}setupUi(t){this.toolbar=new Oa(t,{setTool:n=>this.toolController.setTool(n),openTemplates:()=>or(this.state,this.commands),toggleTheme:()=>this.toggleTheme(),openExportMenu:()=>this.openExportMenu(),toggleStressPanel:()=>this.stressPanel.toggle(),selectRegion:()=>this.startRegionSelection()}),this.toolbar.setActiveTool("select"),this.topControls=new Ua(t,{onExit:this.options.onExit?()=>this.exitToDocs():void 0,resetView:()=>this.resetView(),zoomIn:()=>{Ee(this.state.viewport,window.innerWidth/2,window.innerHeight/2,this.state.viewport.scale*1.2),this.state.requestRender()},zoomOut:()=>{Ee(this.state.viewport,window.innerWidth/2,window.innerHeight/2,this.state.viewport.scale/1.2),this.state.requestRender()},openStorageManager:()=>ir(this.state,()=>this.clearBoard(),()=>void this.resetAllLocalData(),this.options.cleanupUnusedAssets),togglePerfOverlay:()=>this.perfOverlay.toggle(),deleteBoard:this.options.deleteBoard?()=>this.confirmDeleteBoard():void 0,onTitleChange:n=>{this.state.title=n,this.state.emitChange()}},this.state.title),this.perfOverlay=new ar(t,this.state,this.renderer,this.hitTester,this.monitor,this.imageCache);const e=new rr(this.state);this.stressPanel=new cr(t,e,this.renderer)}setupSelectionOverlays(t,e){this.bottomToolCluster=document.createElement("div"),this.bottomToolCluster.className="bottom-tool-cluster",t.appendChild(this.bottomToolCluster),this.bottomToolCluster.appendChild(this.toolbar.element),this.stickyColorPopover=document.createElement("div"),this.stickyColorPopover.className="context-tool-popover sticky-color-popover",this.stickyColorPopover.setAttribute("aria-hidden","true");for(const o of qe){const i=document.createElement("button");i.type="button",i.className="sticky-color-btn",i.title="Set sticky color",i.setAttribute("aria-label",`Set sticky color ${o}`),i.style.setProperty("--swatch",o),i.addEventListener("click",()=>this.setSelectedStickyColor(o)),this.stickyColorPopover.appendChild(i)}this.bottomToolCluster.appendChild(this.stickyColorPopover),this.textSizePopover=document.createElement("div"),this.textSizePopover.className="context-tool-popover text-size-popover",this.textSizePopover.setAttribute("aria-hidden","true");for(const o of ro){const i=document.createElement("button");i.type="button",i.className="text-size-btn",i.textContent=o.shortLabel,i.setAttribute("aria-label",`Set text size ${o.label}`),i.addEventListener("click",()=>this.setSelectedTextSize(o)),this.textSizePopover.appendChild(i)}this.bottomToolCluster.appendChild(this.textSizePopover),this.shapeStylePopover=document.createElement("div"),this.shapeStylePopover.className="context-tool-popover shape-style-popover",this.shapeStylePopover.setAttribute("aria-hidden","true");for(const o of ur){const i=document.createElement("button");i.type="button",i.className="shape-fill-btn",i.title="Set shape color",i.setAttribute("aria-label",`Set shape color ${o}`),i.style.setProperty("--swatch",o),i.addEventListener("click",()=>this.setSelectedShapeFill(o)),this.shapeStylePopover.appendChild(i)}const n=document.createElement("div");n.className="context-tool-divider",this.shapeStylePopover.appendChild(n);for(const o of mr){const i=document.createElement("button");i.type="button",i.className="shape-text-color-btn",i.textContent=o.value==="#ffffff"?"W":"B",i.setAttribute("aria-label",o.label),i.addEventListener("click",()=>this.setSelectedShapeTextColor(o.value)),this.shapeStylePopover.appendChild(i)}this.bottomToolCluster.appendChild(this.shapeStylePopover),this.surface.interactionLayer.addEventListener("contextmenu",o=>this.openLayerMenu(o),{signal:e,capture:!0}),document.addEventListener("pointerdown",o=>{this.layerMenu&&!this.layerMenu.contains(o.target)&&this.closeLayerMenu()},{signal:e}),document.addEventListener("keydown",o=>{o.key==="Escape"&&this.closeLayerMenu()},{signal:e})}updateContextualToolPanels(){this.updateStickyColorPopover(),this.updateTextSizePopover(),this.updateShapeStylePopover()}setContextPanelVisible(t,e){t&&(t.classList.toggle("is-visible",e),t.setAttribute("aria-hidden",String(!e)))}updateStickyColorPopover(){var i;const t=this.stickyColorPopover;if(!t)return;const e=this.state.getSelected().filter(a=>a.type==="sticky"),n=e.length>0&&!this.textEditor.isEditing;if(this.setContextPanelVisible(t,n),!n)return;const o=(i=e[0])==null?void 0:i.style.fill;for(const a of t.children){const r=a,c=r.style.getPropertyValue("--swatch")===o;r.classList.toggle("active",c),r.setAttribute("aria-pressed",String(c))}}setSelectedStickyColor(t){Ra(t);const e=this.state.getSelected().filter(r=>r.type==="sticky"&&!r.locked);if(e.length===0)return;const n=this.state,o=e.map(r=>({id:r.id,fill:r.style.fill,textColor:r.style.textColor,updatedAt:r.updatedAt})),i=e.map(r=>({id:r.id,fill:t,textColor:"#1f2933",updatedAt:Date.now()})),a=r=>{for(const c of r){const l=n.elementsById.get(c.id);l&&(l.style.fill=c.fill,l.style.textColor=c.textColor,l.updatedAt=c.updatedAt)}n.emitChange()};this.commands.execute("sticky-color",()=>a(i),()=>a(o))}updateTextSizePopover(){var i,a;const t=this.textSizePopover;if(!t)return;const e=this.selectedTextTargets(),n=e.length>0&&!this.textEditor.isEditing;if(this.setContextPanelVisible(t,n),!n)return;const o=((i=e[0])==null?void 0:i.style.fontSize)??(((a=e[0])==null?void 0:a.type)==="sticky"?15:16);for(const r of t.children){const c=r,l=ro.find(h=>h.shortLabel===c.textContent),d=(l==null?void 0:l.fontSize)===o;c.classList.toggle("active",d),c.setAttribute("aria-pressed",String(d))}}selectedTextTargets(){return this.state.getSelected().filter(t=>hr.has(t.type)&&!t.locked)}setSelectedTextSize(t){const e=this.selectedTextTargets();if(e.length===0)return;const n=this.state,o=e.map(r=>({id:r.id,fontSize:r.style.fontSize,fontWeight:r.style.fontWeight,height:r.height,updatedAt:r.updatedAt})),i=e.map(r=>({id:r.id,fontSize:t.fontSize,fontWeight:t.fontWeight,height:r.type==="text"?Math.max(r.height,Math.ceil(t.fontSize*1.45)):r.height,updatedAt:Date.now()})),a=r=>{for(const c of r){const l=n.elementsById.get(c.id);l&&(l.style.fontSize=c.fontSize,l.style.fontWeight=c.fontWeight,l.height=c.height,l.updatedAt=c.updatedAt,nt(l.id))}n.emitChange()};this.commands.execute("text-size",()=>a(i),()=>a(o))}updateShapeStylePopover(){var a,r;const t=this.shapeStylePopover;if(!t)return;const e=this.selectedShapeTargets(),n=e.length>0&&!this.textEditor.isEditing;if(this.setContextPanelVisible(t,n),!n)return;const o=(a=e[0])==null?void 0:a.style.fill,i=((r=e[0])==null?void 0:r.style.textColor)??"#1f2933";for(const c of t.children){const l=c;if(l.classList.contains("shape-fill-btn")){const d=l.style.getPropertyValue("--swatch")===o;l.classList.toggle("active",d),l.setAttribute("aria-pressed",String(d))}if(l.classList.contains("shape-text-color-btn")){const h=l.textContent==="W"?i==="#ffffff":i!=="#ffffff";l.classList.toggle("active",h),l.setAttribute("aria-pressed",String(h))}}}selectedShapeTargets(){return this.state.getSelected().filter(t=>pr.has(t.type)&&!t.locked)}setSelectedShapeFill(t){const e=this.selectedShapeTargets();if(e.length===0)return;const n=this.state,o=e.map(r=>({id:r.id,fill:r.style.fill,updatedAt:r.updatedAt})),i=e.map(r=>({id:r.id,fill:t,updatedAt:Date.now()})),a=r=>{for(const c of r){const l=n.elementsById.get(c.id);l&&(l.style.fill=c.fill,l.updatedAt=c.updatedAt)}n.emitChange()};this.commands.execute("shape-fill",()=>a(i),()=>a(o))}setSelectedShapeTextColor(t){const e=this.selectedShapeTargets();if(e.length===0)return;const n=this.state,o=e.map(r=>({id:r.id,textColor:r.style.textColor,updatedAt:r.updatedAt})),i=e.map(r=>({id:r.id,textColor:t,updatedAt:Date.now()})),a=r=>{for(const c of r){const l=n.elementsById.get(c.id);l&&(l.style.textColor=c.textColor,l.updatedAt=c.updatedAt,nt(l.id))}n.emitChange()};this.commands.execute("shape-text-color",()=>a(i),()=>a(o))}openLayerMenu(t){if(t.preventDefault(),t.stopPropagation(),this.textEditor.isEditing)return;const e=H(t.clientX,t.clientY,this.state.viewport),n=this.hitTester.hitTest(e.x,e.y,this.state.viewport.scale);n&&!this.state.selectedIds.has(n.id)&&(this.state.clearSelection(),this.state.selectedIds.add(n.id),this.state.requestRender());const o=this.state.getSelected();if(o.length===0){this.closeLayerMenu();return}this.closeLayerMenu();const i=document.createElement("div");i.className="layer-menu",i.setAttribute("role","menu");const a=document.createElement("div");a.className="layer-menu-label",a.textContent=o.length===1?"Layer":`${o.length} layers`,i.appendChild(a);const r=(l,d)=>{const h=document.createElement("button");h.type="button",h.setAttribute("role","menuitem"),h.textContent=l,h.addEventListener("click",()=>{d(),this.closeLayerMenu()}),i.appendChild(h)},c=()=>{const l=document.createElement("div");l.className="layer-menu-divider",i.appendChild(l)};r("Bring forward",()=>this.actions.bringForward()),r("Send backward",()=>this.actions.sendBackward()),c(),r("Bring to front",()=>this.actions.bringToFront()),r("Send to back",()=>this.actions.sendToBack()),this.root.appendChild(i),this.layerMenu=i,this.positionLayerMenu(i,t.clientX,t.clientY)}positionLayerMenu(t,e,n){t.style.left="0px",t.style.top="0px",requestAnimationFrame(()=>{const i=t.getBoundingClientRect(),a=Math.min(Math.max(12,e),window.innerWidth-i.width-12),r=Math.min(Math.max(12,n),window.innerHeight-i.height-12);t.style.left=`${a}px`,t.style.top=`${r}px`})}closeLayerMenu(){var t;(t=this.layerMenu)==null||t.remove(),this.layerMenu=null}exitToDocs(){this.boardSaveTimer!==null&&(clearTimeout(this.boardSaveTimer),this.boardSaveTimer=null),this.saveBoard().then(t=>{var e,n;t&&((n=(e=this.options).onExit)==null||n.call(e))})}startRegionSelection(){Ln.begin(this.root,t=>{t&&this.openRegionActionMenu(t)})}screenRectToWorld(t){const e=this.state.viewport,n=H(t.x,t.y,e),o=H(t.x+t.w,t.y+t.h,e);return{x:n.x,y:n.y,w:o.x-n.x,h:o.y-n.y}}openRegionActionMenu(t){var c;this.closeRegionActionMenu();const e=this.screenRectToWorld(t),n=document.createElement("div");n.className="board-region-action-menu",n.setAttribute("role","menu"),n.setAttribute("aria-label","Selected board region actions");const o=document.createElement("div");o.className="board-region-action-heading",o.textContent="Use selected region",n.appendChild(o);const i=(l,d)=>{const h=document.createElement("button");h.type="button",h.setAttribute("role","menuitem"),h.className="board-region-action-item",h.textContent=l,h.addEventListener("click",()=>{this.closeRegionActionMenu(),d()}),n.appendChild(h)};this.options.onExit&&i("Embed in a document",()=>this.copyEmbedSnippet(e)),i("Export as PDF…",()=>this.exportBoardRegion(e,"pdf")),i("Export as JPEG",()=>this.exportBoardRegion(e,"jpeg")),i("Export as SVG",()=>this.exportBoardRegion(e,"svg"));const a=document.createElement("button");a.type="button",a.className="board-region-action-cancel",a.textContent="Cancel",a.addEventListener("click",()=>this.closeRegionActionMenu()),n.appendChild(a),document.body.appendChild(n),this.regionActionMenu=n;const r=new AbortController;this.regionActionAbort=r,document.addEventListener("pointerdown",l=>{l.target instanceof Node&&!n.contains(l.target)&&this.closeRegionActionMenu()},{capture:!0,signal:r.signal}),window.addEventListener("keydown",l=>{l.key==="Escape"&&(l.preventDefault(),this.closeRegionActionMenu())},{signal:r.signal}),n.style.left="0px",n.style.top="0px",requestAnimationFrame(()=>{if(!n.isConnected)return;const l=n.getBoundingClientRect(),d=12,h=t.x+t.w/2-l.width/2;let p=t.y+t.h+10;p+l.height>window.innerHeight-d&&(p=t.y-l.height-10),n.style.left=`${Math.max(d,Math.min(h,window.innerWidth-l.width-d))}px`,n.style.top=`${Math.max(d,Math.min(p,window.innerHeight-l.height-d))}px`}),(c=n.querySelector("button"))==null||c.focus()}closeRegionActionMenu(){var t,e;(t=this.regionActionAbort)==null||t.abort(),this.regionActionAbort=null,(e=this.regionActionMenu)==null||e.remove(),this.regionActionMenu=null}async exportBoardRegion(t,e){try{const n=await is(this.state,this.imageCache,t,e,{scale:2,quality:.92,paper:"A4"});await da(n),C(`${e.toUpperCase()} region exported`)}catch(n){C(n instanceof Error?n.message:"Could not export board region")}}async copyEmbedSnippet(t){const e=Math.round(t.x),n=Math.round(t.y),o=Math.round(t.w),i=Math.round(t.h),a=`\`\`\`board
16
+ src: /${this.state.boardId}
17
+ region: ${e}, ${n}, ${o}, ${i}
18
+ height: 360
19
+ title: ${this.state.title}
20
+ \`\`\``;try{await navigator.clipboard.writeText(a),C("Embed snippet copied — paste it into any doc")}catch{C("Could not access clipboard")}}setupDragDrop(t){t.addEventListener("dragover",e=>{e.preventDefault(),e.dataTransfer&&(e.dataTransfer.dropEffect="copy")}),t.addEventListener("drop",e=>{var n;e.preventDefault(),(n=e.dataTransfer)!=null&&n.files&&e.dataTransfer.files.length>0&&this.imageInsert.insertFiles(e.dataTransfer.files,e.clientX,e.clientY)})}async loadInitialState(){this.suppressPersistence=!0;const t=pt.getPref("theme");if(t==="dark"||t==="light"?this.applyTheme(t):window.matchMedia("(prefers-color-scheme: dark)").matches&&this.applyTheme("dark"),this.options.loadBoard){try{const n=await this.options.loadBoard(this.options.boardId??this.state.boardId);n&&(this.revision=n.revision,this.stale=!1,this.applyDocument(n.doc),this.fitInitialRegion())}catch(n){console.error("Board file load failed",n),C("Could not load board file")}finally{this.suppressPersistence=!1}this.state.requestRender();return}const e=pt.getPref("lastBoardId")??"default-board";try{const n=await pt.loadBoard(e);n&&this.applyDocument(n)}catch(n){console.error("Board recovery failed",n),pt.getPref("recovery")&&C("Could not load saved board — starting fresh")}this.suppressPersistence=!1,this.state.requestRender()}applyDocument(t){this.state.schemaUrl=t.$schema,this.state.boardId=t.id,this.state.title=t.title,this.state.createdAt=t.createdAt,this.state.viewport={...t.viewport},this.state.elements=[],this.state.elementsById.clear();for(const e of t.elements)this.state.addElement(e);this.applyTheme(t.theme),this.topControls.setTitle(t.title),this.topControls.setZoom(t.viewport.scale),this.state.invalidateSort()}fitInitialRegion(){const t=this.options.initialRegion;if(!t)return;const[e,n,o,i]=t;if(o<=0||i<=0)return;const a=Math.min(120,Math.max(48,this.surface.width*.08)),r=88,c=124,l=Math.max(240,this.surface.width-a*2),d=Math.max(180,this.surface.height-r-c),h=Math.min(l/o,d/i),p=Math.max(.7,Math.min(1.1,this.state.viewport.scale*1.15)),u=es(Math.min(h*.58,p));this.state.viewport={scale:u,offsetX:a+(l-o*u)/2-e*u,offsetY:r+(d-i*u)/2-n*u},this.topControls.setZoom(u)}scheduleBoardSave(){this.boardSaveTimer!==null&&clearTimeout(this.boardSaveTimer),this.boardSaveTimer=window.setTimeout(()=>{this.boardSaveTimer=null,this.saveBoard()},lr)}scheduleViewportSave(){this.viewportSaveTimer===null&&(this.viewportSaveTimer=window.setTimeout(()=>{this.viewportSaveTimer=null,this.saveBoard()},dr))}async saveBoard(){if(this.saveInFlight)return this.saveQueued=!0,this.saveInFlight;const t=async()=>{if(this.stale)return C("Board changed elsewhere — reload before saving"),this.setBoardStatus("Changed elsewhere","stale"),!1;try{return this.options.saveBoard?(this.revision=await this.options.saveBoard(Ie(this.state),this.revision),this.stale=!1,this.setBoardStatus("Saved","saved")):await pt.saveBoard(Ie(this.state)),!0}catch(n){return n instanceof xe?(this.revision=n.currentRevision,this.stale=!0,this.setBoardStatus("Changed elsewhere","stale"),C("Board changed elsewhere — reload before saving"),!1):(C(this.options.saveBoard?"Save to file failed":"Save failed — browser storage may be full"),this.options.saveBoard&&this.setBoardStatus("Save failed","error"),!1)}};this.saveInFlight=t();const e=await this.saveInFlight;return this.saveInFlight=null,this.saveQueued&&!this.stale?(this.saveQueued=!1,this.saveBoard()):(this.saveQueued=!1,e)}markStale(){this.stale=!0,this.setBoardStatus("Changed elsewhere","stale")}refreshAssets(){this.imageCache.clear(),this.state.requestRender()}async reloadLatest(){if(this.options.loadBoard&&window.confirm("Discard local edits and reload the latest board version?"))try{this.suppressPersistence=!0;const t=await this.options.loadBoard(this.options.boardId??this.state.boardId);if(!t){C("Could not reload board file"),this.suppressPersistence=!1;return}this.revision=t.revision,this.stale=!1,this.applyDocument(t.doc),this.state.requestRender(),this.setBoardStatus("Reloaded latest","saved")}catch{this.setBoardStatus("Reload failed","error"),C("Could not reload board file")}finally{this.suppressPersistence=!1}}setBoardStatus(t,e){var n;(n=this.topControls)==null||n.setStatus(t,e,e==="stale"&&this.options.loadBoard?{label:"Reload latest",onClick:()=>void this.reloadLatest()}:void 0)}applyTheme(t){var e;this.state.theme=t,document.documentElement.setAttribute("data-theme",t),pt.setPref("theme",t),(e=this.toolbar)==null||e.setTheme(t),this.state.requestRender()}toggleTheme(){this.applyTheme(this.state.theme==="dark"?"light":"dark"),this.scheduleBoardSave()}resetView(){this.state.viewport.offsetX=0,this.state.viewport.offsetY=0,this.state.viewport.scale=ts,this.state.requestRender()}clearBoard(){const t=this.state,e=[...t.elements];this.commands.execute("clear-board",()=>{for(const n of e)t.removeElement(n.id);t.emitChange()},()=>{for(const n of e)t.elementsById.has(n.id)||t.addElement(n);t.emitChange()}),C("Board cleared")}async resetAllLocalData(){await pt.clearAllBoards(),await ut.clearAll(),pt.clearPrefs(),this.imageCache.clear(),this.commands.clear(),this.state.elements=[],this.state.elementsById.clear(),this.state.clearSelection(),this.state.invalidateSort(),this.resetView(),C("All local data cleared")}confirmDeleteBoard(){et("Delete board?",(t,e)=>{const n=document.createElement("p");n.className="modal-copy",n.textContent=`This will permanently delete "${this.state.title}" from the active docs root. This cannot be undone.`;const o=document.createElement("div");o.className="modal-actions";const i=document.createElement("button");i.className="btn",i.textContent="Cancel",i.addEventListener("click",e);const a=document.createElement("button");a.className="btn danger",a.textContent="Delete board",a.addEventListener("click",async()=>{var r,c,l;a.disabled=!0,this.boardSaveTimer!==null&&(clearTimeout(this.boardSaveTimer),this.boardSaveTimer=null),this.viewportSaveTimer!==null&&(clearTimeout(this.viewportSaveTimer),this.viewportSaveTimer=null);try{await((c=(r=this.options).deleteBoard)==null?void 0:c.call(r,this.state.boardId)),e(),C("Board deleted"),(l=this.options.onDeleted??this.options.onExit)==null||l()}catch{a.disabled=!1,C("Could not delete board")}}),o.append(i,a),t.append(n,o)})}openExportMenu(){et("Export & import",(t,e)=>{const n=document.createElement("div");n.className="modal-actions",n.style.flexDirection="column",n.style.alignItems="stretch";const o=(i,a,r=!1)=>{const c=document.createElement("button");c.className="btn"+(r?" primary":""),c.textContent=i,c.addEventListener("click",()=>{a(),e()}),n.appendChild(c)};o("Export current view as PNG",async()=>{const i=await ua(this.state,this.imageCache,this.surface.width,this.surface.height);kn(i,this.state.title+"-view.png")},!0),o("Export full board as PNG",async()=>{const i=await ma(this.state,this.imageCache);i?kn(i,this.state.title+"-board.png"):C("Board is empty")}),o("Export board JSON (no images)",()=>{dn.exportBoardJson(Ie(this.state))}),o("Export full bundle (JSON + images)",async()=>{await dn.exportFullBundle(Ie(this.state))}),o("Import board from file…",()=>this.pickImportFile()),t.appendChild(n)})}pickImportFile(){const t=document.createElement("input");t.type="file",t.accept="application/json,.json",t.onchange=async()=>{var o;const e=(o=t.files)==null?void 0:o[0];if(!e)return;const n=await dn.importFromFile(e);if(!n){C("Import failed — invalid board file");return}this.state.boardId=n.id,this.state.title=n.title,this.state.createdAt=n.createdAt,this.state.viewport={...n.viewport},this.state.elements=[],this.state.elementsById.clear(),this.state.clearSelection();for(const i of n.elements)this.state.addElement(i);this.applyTheme(n.theme),this.topControls.setTitle(n.title),this.commands.clear(),this.state.emitChange(),C("Board imported")},t.click()}}const co="/__api/asset?path=",ds=new Set(["P","DIV","UL","OL","H1","H2","H3","H4","H5","H6","BLOCKQUOTE","PRE","TABLE","FIGURE","HR"]);function gr(s){const t=[];for(const e of Array.from(s.childNodes))Pn(t,e);return t.map(e=>e.replace(/[ \t]+$/gm,"")).join(`
21
+
22
+ `).replace(/\n{3,}/g,`
23
+
24
+ `).trim()+`
25
+ `}function Pn(s,t){const e=yr(t);e!==null&&e.trim()!==""&&s.push(e)}function yr(s){if(s.nodeType===Node.TEXT_NODE){const n=(s.textContent??"").trim();return n||null}if(s.nodeType!==Node.ELEMENT_NODE)return null;const t=s,e=t.tagName;switch(e){case"H1":case"H2":case"H3":case"H4":case"H5":case"H6":return"#".repeat(Number(e[1]))+" "+Ct(t).trim();case"HR":return"---";case"P":return t.classList.contains("embed-caret-spacer")&&!vr(t)?null:ho(t)?po(t):En(Ct(t).trim());case"BLOCKQUOTE":return lo(t).split(`
26
+ `).map(o=>o?`> ${o}`:">").join(`
27
+ `);case"UL":return Ke(t,!1,0);case"OL":return Ke(t,!0,0);case"PRE":{const n=t.querySelector("code"),o=kr(n??t),i=(n??t).textContent??"";return"```"+o+`
28
+ `+i.replace(/\n$/,"")+"\n```"}case"TABLE":return wr(t);case"FIGURE":return t.classList.contains("board-embed")?xr(t):lo(t)||null;case"DIV":return ho(t)?po(t):En(Ct(t).trim());case"BR":return null;default:return Ct(t).trim()||null}}function lo(s){const t=[];for(const e of Array.from(s.childNodes))Pn(t,e);return t.join(`
29
+
30
+ `)}function ho(s){for(const t of Array.from(s.children))if(ds.has(t.tagName))return!0;return!1}function po(s){const t=[];let e="";const n=()=>{const o=En(e.trim());o&&t.push(o),e=""};for(const o of Array.from(s.childNodes)){if(br(o)){n(),Pn(t,o);continue}e+=$n(o)}return n(),t.join(`
31
+
32
+ `)||null}function br(s){return s.nodeType===Node.ELEMENT_NODE&&ds.has(s.tagName)}function vr(s){for(const t of Array.from(s.childNodes)){if(t.nodeType===Node.TEXT_NODE&&(t.textContent??"").trim())return!0;if(t.nodeType!==Node.ELEMENT_NODE)continue;const e=t;if(e.tagName!=="BR"&&((e.textContent??"").trim()||["IMG","FIGURE","HR"].includes(e.tagName)))return!0}return!1}function Ke(s,t,e){const n=[],o=" ".repeat(e);let i=0;for(const a of Array.from(s.children)){if(a.tagName!=="LI")continue;i++;const r=t?`${i}. `:"- ";let c="";const l=[];let d=null;for(const h of Array.from(a.childNodes)){if(h.nodeType===Node.ELEMENT_NODE){const p=h;if(p.tagName==="UL"){l.push(Ke(p,!1,e+1));continue}if(p.tagName==="OL"){l.push(Ke(p,!0,e+1));continue}if(p.tagName==="INPUT"){d=p.checked?"[x] ":"[ ] ";continue}}c+=$n(h)}n.push(o+r+(d??"")+c.trim());for(const h of l)h&&n.push(h)}return n.join(`
33
+ `)}function wr(s){const t=Array.from(s.querySelectorAll("tr"));if(t.length===0)return"";const e=i=>Array.from(i.querySelectorAll("th,td")).map(a=>Ct(a).trim()),n=e(t[0]),o=[];o.push("| "+n.join(" | ")+" |"),o.push("| "+n.map(()=>"---").join(" | ")+" |");for(let i=1;i<t.length;i++)o.push("| "+e(t[i]).join(" | ")+" |");return o.join(`
34
+ `)}function xr(s){const t=["```board",`src: ${s.dataset.src??""}`];return s.dataset.region&&t.push(`region: ${s.dataset.region.split(",").map(e=>e.trim()).join(", ")}`),s.dataset.height&&t.push(`height: ${s.dataset.height}`),s.dataset.title&&t.push(`title: ${s.dataset.title}`),t.push("```"),t.join(`
35
+ `)}function Ct(s){let t="";for(const e of Array.from(s.childNodes))t+=$n(e);return t}function $n(s){if(s.nodeType===Node.TEXT_NODE)return mo(s.textContent??"");if(s.nodeType!==Node.ELEMENT_NODE)return"";const t=s;switch(t.tagName){case"STRONG":case"B":return uo("**",Ct(t));case"EM":case"I":return uo("*",Ct(t));case"CODE":return Er(t.textContent??"");case"A":{const e=(t.getAttribute("data-md-href")??t.getAttribute("href")??"").trim(),n=Ct(t).trim()||mo(e);return e?`[${fo(n)}](${go(e)})`:n}case"IMG":return`![${fo(t.alt)}](${go(Cr(t))})`;case"BR":return`
36
+ `;default:return Ct(t)}}function Cr(s){const t=s.getAttribute("data-md-src");if(t)return t;const e=s.getAttribute("src")??"";return e.startsWith(co)?decodeURIComponent(e.slice(co.length)):e}function kr(s){const e=(s.getAttribute("class")??"").match(/language-(\w+)/);return e?e[1]:""}function uo(s,t){const e=t.trim();return e?`${s}${e}${s}`:""}function Er(s){if(!s.includes("`"))return"`"+s+"`";const t=Math.max(...(s.match(/`+/g)??[""]).map(n=>n.length)),e="`".repeat(t+1);return`${e} ${s} ${e}`}function mo(s){return s.replace(/\\/g,"\\\\").replace(/\[/g,"\\[").replace(/\]/g,"\\]").replace(/\*/g,"\\*").replace(/_/g,"\\_").replace(/`/g,"\\`")}function En(s){return s?/^#{1,6}\s/.test(s)||/^>\s?/.test(s)||/^([-+*]|\d+\.)\s+/.test(s)||/^`{3,}/.test(s)||/^(-{3,}|\*{3,}|_{3,})$/.test(s)?"\\"+s:s:null}function fo(s){return s.replace(/\\/g,"\\\\").replace(/\]/g,"\\]")}function go(s){return s.trim().replace(/\s/g,"%20").replace(/\)/g,"%29").replace(/</g,"%3C").replace(/>/g,"%3E")}class Dn{constructor(t){m(this,"opts");m(this,"overlay");m(this,"scrollEl");m(this,"surface");m(this,"statusEl");m(this,"statusTextEl");m(this,"reloadBtn");m(this,"fileInput");m(this,"toolbarButtons",[]);m(this,"abort",new AbortController);m(this,"frontmatter","");m(this,"revision",null);m(this,"stale",!1);m(this,"saveTimer",null);m(this,"closed",!1);m(this,"history",[]);m(this,"historyIndex",-1);m(this,"applyingHistory",!1);this.opts=t,this.build(),this.load()}static open(t){return new Dn(t)}build(){this.overlay=vt("doc-editor");const t=vt("doc-editor-bar"),e=vt("doc-editor-bar-left"),n=pn("doc-editor-done","Done");n.addEventListener("click",()=>void this.close());const o=vt("doc-editor-path");o.textContent=this.opts.path,e.append(n,o),this.statusEl=vt("doc-editor-status"),this.statusTextEl=document.createElement("span"),this.reloadBtn=pn("status-action-btn","Reload latest"),this.reloadBtn.hidden=!0,this.reloadBtn.addEventListener("click",()=>void this.reloadLatest()),this.statusEl.append(this.statusTextEl,this.reloadBtn),this.setStatus("idle"),t.append(e,this.statusEl);const i=this.buildToolbar();this.scrollEl=vt("doc-editor-scroll"),this.surface=vt("markdown-body doc-editor-surface"),this.surface.contentEditable="true",this.surface.spellcheck=!0,this.scrollEl.appendChild(this.surface),this.fileInput=document.createElement("input"),this.fileInput.type="file",this.fileInput.accept="image/*",this.fileInput.style.display="none",this.fileInput.addEventListener("change",()=>{var c;const r=(c=this.fileInput.files)==null?void 0:c[0];r&&this.insertImageFile(r),this.fileInput.value=""}),this.overlay.append(t,i,this.scrollEl,this.fileInput),document.body.appendChild(this.overlay);const a=this.abort.signal;this.surface.addEventListener("input",()=>this.handleInput(),{signal:a}),this.surface.addEventListener("keyup",()=>this.updateToolbarState(),{signal:a}),this.surface.addEventListener("mouseup",()=>this.updateToolbarState(),{signal:a}),this.surface.addEventListener("click",r=>this.handleSurfaceClick(r),{signal:a}),document.addEventListener("selectionchange",()=>this.updateToolbarState(),{signal:a}),this.surface.addEventListener("paste",r=>this.onPaste(r),{signal:a}),this.surface.addEventListener("dragover",r=>r.preventDefault(),{signal:a}),this.surface.addEventListener("drop",r=>this.onDrop(r),{signal:a}),window.addEventListener("keydown",r=>{if(r.key==="Escape"&&document.activeElement!==this.surface&&this.close(),(r.metaKey||r.ctrlKey)&&r.key.toLowerCase()==="s"&&(r.preventDefault(),this.save()),(r.metaKey||r.ctrlKey)&&r.key.toLowerCase()==="z"){r.preventDefault(),r.shiftKey?this.redoHistory():this.undoHistory();return}if(r.ctrlKey&&!r.metaKey&&r.key.toLowerCase()==="y"){r.preventDefault(),this.redoHistory();return}this.handleEmbedDeleteKey(r)},{signal:a})}buildToolbar(){const t=vt("doc-editor-toolbar"),e=o=>{const i=vt("doc-editor-tb-group");return i.append(...o),i},n=(o,i,a,r=!1)=>{const c=pn("doc-editor-tb-btn",r?"":o);return r&&(c.innerHTML=Q[o]??"",c.classList.add("icon")),c.title=i,c.addEventListener("mousedown",l=>{l.preventDefault(),this.surface.focus(),a(),this.updateToolbarState(),this.scheduleSave()}),this.toolbarButtons.push(c),c};return t.append(e([n("¶","Paragraph",()=>this.formatBlock("P")),wt(n("H1","Heading 1",()=>this.formatBlock("H1")),"block","H1"),wt(n("H2","Heading 2",()=>this.formatBlock("H2")),"block","H2"),wt(n("H3","Heading 3",()=>this.formatBlock("H3")),"block","H3")]),e([wt(n("B","Bold (Cmd+B)",()=>document.execCommand("bold")),"command","bold"),wt(n("I","Italic (Cmd+I)",()=>document.execCommand("italic")),"command","italic"),wt(n("</>","Inline code",()=>this.toggleInlineCode()),"inline","CODE")]),e([wt(n("❝","Quote",()=>this.formatBlock("BLOCKQUOTE")),"block","BLOCKQUOTE"),wt(n("•","Bulleted list",()=>document.execCommand("insertUnorderedList")),"command","insertUnorderedList"),wt(n("1.","Numbered list",()=>document.execCommand("insertOrderedList")),"command","insertOrderedList"),n("{ }","Code block",()=>this.insertCodeBlock())]),e([n("↗","Link",()=>this.insertLink()),n("image","Image",()=>this.fileInput.click(),!0),n("―","Divider",()=>document.execCommand("insertHorizontalRule"))])),t}async load(t=this.opts.initialScrollTop??0,e=this.opts.initialScrollProgress){try{const n=await k.readFileWithRevision(this.opts.rootId,this.opts.path);this.revision=n.revision,this.stale=!1;const o=n.content,{fm:i,body:a}=Tr(o);this.frontmatter=i;const{html:r}=ne(a,{rootId:this.opts.rootId,docPath:this.opts.path});this.surface.innerHTML=r||"<p></p>",this.decorateEmbeds(),document.execCommand("defaultParagraphSeparator",!1,"p"),this.recordHistorySnapshot(!0),this.updateToolbarState(),this.setStatus("idle"),requestAnimationFrame(()=>{if(!this.closed){if(typeof e=="number"){Sr(this.scrollEl,e);return}this.scrollEl.scrollTop=t}})}catch{this.surface.innerHTML="<p></p>",this.setStatus("error","Could not load file");return}}decorateEmbeds(){this.normalizeEmbedSpacing(),this.surface.querySelectorAll("figure.board-embed").forEach(t=>{t.contentEditable="false",t.tabIndex=0,t.setAttribute("role","button"),t.setAttribute("aria-label",`Board embed ${t.dataset.src??""}. Press Delete to remove.`),t.classList.add("embed-chip");const e=t.dataset.region?" · region":"";t.innerHTML=`<span class="embed-chip-icon">▦</span> Board embed: <strong>${t.dataset.src??""}</strong>${e}<span class="embed-chip-remove" aria-hidden="true">Delete</span>`,this.ensureEmbedCaretSpace(t)})}ensureEmbedCaretSpace(t){Ft(t.previousElementSibling)||t.before(ge()),Ft(t.nextElementSibling)||t.after(ge())}normalizeEmbedSpacing(){const t=Array.from(this.surface.querySelectorAll("figure.board-embed"));for(const n of t)yo(n.previousElementSibling),yo(n.nextElementSibling);let e=!1;for(const n of Array.from(this.surface.children)){if(!Ft(n)){e=!1;continue}if(hs(n)){n.classList.remove("embed-caret-spacer"),e=!1;continue}if(e){n.remove();continue}e=!0}}handleSurfaceClick(t){const e=t.target,n=e==null?void 0:e.closest("figure.board-embed.embed-chip");!n||!this.surface.contains(n)||(t.preventDefault(),this.selectEmbed(n))}selectEmbed(t){this.surface.querySelectorAll(".embed-chip.selected").forEach(o=>o.classList.remove("selected")),t.classList.add("selected");const e=document.createRange();e.selectNode(t);const n=window.getSelection();n==null||n.removeAllRanges(),n==null||n.addRange(e),t.focus()}clearEmbedSelection(){this.surface.querySelectorAll(".embed-chip.selected").forEach(t=>t.classList.remove("selected"))}handleEmbedDeleteKey(t){if(t.key!=="Backspace"&&t.key!=="Delete")return!1;const e=document.activeElement,o=(e==null?void 0:e.closest("figure.board-embed.embed-chip.selected"))??this.surface.querySelector("figure.board-embed.embed-chip.selected")??this.embedAdjacentToCaret(t.key);if(!o||!this.surface.contains(o))return!1;t.preventDefault();const i=t.key==="Backspace"?o.previousElementSibling:o.nextElementSibling;return o.remove(),this.clearEmbedSelection(),this.placeCaretInBlock(Ft(i)?i:this.surface),this.recordHistorySnapshot(),this.scheduleSave(),!0}embedAdjacentToCaret(t){const e=window.getSelection();if(!e||e.rangeCount===0||!e.isCollapsed)return null;const n=e.anchorNode,o=Br(n,"P");if(!o||!this.surface.contains(o)||!Ft(o))return null;const i=t==="Backspace"?o.previousElementSibling:o.nextElementSibling;return i instanceof HTMLElement&&i.matches("figure.board-embed.embed-chip")?i:null}handleInput(){this.applyingHistory||(this.clearEmbedSelection(),this.recordHistorySnapshot(),this.scheduleSave())}placeCaretInBlock(t){const e=document.createRange();e.selectNodeContents(t),e.collapse(!1);const n=window.getSelection();n==null||n.removeAllRanges(),n==null||n.addRange(e),this.surface.focus()}scheduleSave(){this.normalizeEmbedSpacing(),this.saveTimer!==null&&clearTimeout(this.saveTimer),this.setStatus("saving"),this.saveTimer=window.setTimeout(()=>{this.saveTimer=null,this.save()},700)}async save(){if(this.saveTimer!==null&&(clearTimeout(this.saveTimer),this.saveTimer=null),this.stale)return this.setStatus("stale","Changed elsewhere — reload before saving"),!1;this.normalizeEmbedSpacing();const t=gr(this.surface),e=this.frontmatter?`${this.frontmatter}
37
+
38
+ ${t}`:t;try{return this.setStatus("saving"),this.revision=await k.writeFile(this.opts.rootId,this.opts.path,e,this.revision),this.stale=!1,this.setStatus("saved"),!0}catch(n){return n instanceof xe?(this.revision=n.currentRevision,this.stale=!0,this.setStatus("stale","Changed elsewhere — reload before saving"),!1):(this.setStatus("error","Save failed"),!1)}}async close(){if(this.closed||!await this.save())return;this.closed=!0;const e=this.scrollEl.scrollTop,n=bo(this.scrollEl);this.abort.abort(),this.overlay.remove(),this.opts.onClose(e,n)}markStale(){this.saveTimer!==null&&(clearTimeout(this.saveTimer),this.saveTimer=null),this.stale=!0,this.setStatus("stale","Changed elsewhere — reload before saving")}async reloadLatest(){window.confirm("Discard local edits and reload the latest version?")&&(this.saveTimer!==null&&(clearTimeout(this.saveTimer),this.saveTimer=null),await this.load(this.scrollEl.scrollTop,bo(this.scrollEl)))}formatBlock(t){document.execCommand("formatBlock",!1,`<${t}>`)}insertLink(){const t=window.getSelection(),e=t&&!t.isCollapsed?t.toString().trim():"",n=window.prompt("Link URL","https://");if(!n)return;const o=n.trim();o&&(e?document.execCommand("createLink",!1,o):document.execCommand("insertHTML",!1,`<a href="${wo(o)}">${Pr(o)}</a>`))}toggleInlineCode(){const t=window.getSelection();if(!t||t.rangeCount===0||t.isCollapsed)return;const e=t.getRangeAt(0),n=un(e.commonAncestorContainer,"CODE");if(n){const i=n.parentNode;for(;n.firstChild;)i.insertBefore(n.firstChild,n);i.removeChild(n);return}const o=document.createElement("code");o.appendChild(e.extractContents()),e.insertNode(o),e.setStartAfter(o),e.collapse(!0),t.removeAllRanges(),t.addRange(e)}insertCodeBlock(){document.execCommand("insertHTML",!1,'<pre class="code-block"><code>code</code></pre><p><br></p>')}updateToolbarState(){const t=window.getSelection(),e=(t==null?void 0:t.anchorNode)??null,n=!!e&&this.surface.contains(e);for(const o of this.toolbarButtons){const i=o.dataset.stateType,a=o.dataset.stateValue;let r=!1;if(n&&i==="command"&&a)try{r=document.queryCommandState(a)}catch{r=!1}else(n&&i==="block"&&a||n&&i==="inline"&&a)&&(r=!!un(e,a));o.classList.toggle("active",r),o.setAttribute("aria-pressed",r?"true":"false")}}onPaste(t){var o,i;const e=Dr(((o=t.clipboardData)==null?void 0:o.getData("text/plain"))??"");if(e){t.preventDefault(),this.insertSpecialBlock(e);return}const n=(i=t.clipboardData)==null?void 0:i.items;if(n){for(const a of n)if(a.type.startsWith("image/")){const r=a.getAsFile();if(r){t.preventDefault(),this.insertImageFile(r);return}}}}insertSpecialBlock(t){this.surface.focus();const e=Nr(t);this.insertBlockNode(e),this.decorateEmbeds(),this.selectEmbed(e),this.recordHistorySnapshot(),this.updateToolbarState(),this.scheduleSave()}insertBlockNode(t){const e=window.getSelection(),n=e&&e.rangeCount>0?e.getRangeAt(0):null;if(!n||!this.surface.contains(n.commonAncestorContainer)){this.surface.append(t,ge()),this.placeCaretInBlock(this.surface.lastElementChild??this.surface);return}const o=Mr(this.surface,n.commonAncestorContainer);if(o&&Ir(o)&&!Ft(o)){this.replaceBlockWithInsertedNode(o,n,t);return}n.deleteContents();const i=ge();n.insertNode(i),n.insertNode(t),this.placeCaretInBlock(i)}replaceBlockWithInsertedNode(t,e,n){const o=document.createRange();o.selectNodeContents(t),o.setEnd(e.startContainer,e.startOffset);const i=document.createRange();i.selectNodeContents(t),i.setStart(e.endContainer,e.endOffset);const a=vo(t,o.cloneContents()),r=vo(t,i.cloneContents()),c=t.parentNode;if(!c)return;a&&c.insertBefore(a,t),c.insertBefore(n,t),r&&c.insertBefore(r,t),c.removeChild(t);const l=r??ge();r||c.insertBefore(l,n.nextSibling),this.placeCaretInBlock(l)}onDrop(t){var n,o;const e=(o=(n=t.dataTransfer)==null?void 0:n.files)==null?void 0:o[0];e&&e.type.startsWith("image/")&&(t.preventDefault(),this.insertImageFile(e))}async insertImageFile(t){this.setStatus("saving","Uploading image…");try{const e=await Lr(t),n=await k.uploadAsset(this.opts.rootId,t.name,e),o=Tn(this.opts.path,n),i=k.assetUrl(this.opts.rootId,n),a=t.name.replace(/\.[^.]+$/,"");this.surface.focus(),document.execCommand("insertHTML",!1,`<img src="${i}" data-md-src="${o}" alt="${wo(a)}" /><p><br></p>`),this.recordHistorySnapshot(),await this.save()}catch{this.setStatus("error","Image upload failed")}}recordHistorySnapshot(t=!1){if(this.applyingHistory)return;this.normalizeEmbedSpacing();const e=this.surface.innerHTML;if(t){this.history=[e],this.historyIndex=0;return}this.history[this.historyIndex]!==e&&(this.history=this.history.slice(0,this.historyIndex+1),this.history.push(e),this.history.length>100&&this.history.shift(),this.historyIndex=this.history.length-1)}undoHistory(){this.historyIndex<=0||this.applyHistorySnapshot(this.historyIndex-1)}redoHistory(){this.historyIndex>=this.history.length-1||this.applyHistorySnapshot(this.historyIndex+1)}applyHistorySnapshot(t){const e=this.history[t];e!==void 0&&(this.applyingHistory=!0,this.historyIndex=t,this.surface.innerHTML=e,this.decorateEmbeds(),this.clearEmbedSelection(),this.placeCaretInBlock(this.surface.lastElementChild??this.surface),this.applyingHistory=!1,this.updateToolbarState(),this.scheduleSave())}setStatus(t,e){const n={idle:"",saving:e??"Saving…",saved:"Saved",stale:e??"Changed elsewhere",error:e??"Couldn't save"};this.statusTextEl.textContent=n[t],this.statusEl.dataset.state=t,this.reloadBtn.hidden=t!=="stale"}}function vt(s){const t=document.createElement("div");return t.className=s,t}function pn(s,t){const e=document.createElement("button");return e.className=s,e.textContent=t,e}function wt(s,t,e){return s.dataset.stateType=t,s.dataset.stateValue=e,s.setAttribute("aria-pressed","false"),s}function ge(){const s=document.createElement("p");return s.className="embed-caret-spacer",s.appendChild(document.createElement("br")),s}function Ft(s){return!!s&&s.tagName==="P"&&s.classList.contains("embed-caret-spacer")}function yo(s){Ft(s)&&hs(s)&&s.classList.remove("embed-caret-spacer")}function hs(s){for(const t of Array.from(s.childNodes)){if(t.nodeType===Node.TEXT_NODE&&(t.textContent??"").trim())return!0;if(t.nodeType!==Node.ELEMENT_NODE)continue;const e=t;if(e.tagName!=="BR"&&((e.textContent??"").trim()||["IMG","FIGURE","HR"].includes(e.tagName)))return!0}return!1}function bo(s){const t=Math.max(1,s.scrollHeight-s.clientHeight);return s.scrollTop/t}function Sr(s,t){const e=Math.max(0,s.scrollHeight-s.clientHeight);s.scrollTop=Math.max(0,Math.min(1,t))*e}function Tr(s){if(!s.startsWith("---"))return{fm:"",body:s};const t=s.indexOf(`
39
+ ---`,3);if(t===-1)return{fm:"",body:s};const e=s.slice(0,t+4),n=s.slice(t+4).replace(/^\n+/,"");return{fm:e,body:n}}function un(s,t){let e=s;for(;e;){if(e.nodeType===Node.ELEMENT_NODE&&e.tagName===t)return e;e=e.parentNode}return null}function Br(s,t){let e=s;for(;e;){if(e.nodeType===Node.ELEMENT_NODE&&e.matches(t))return e;e=e.parentNode}return null}function Mr(s,t){let e=t;for(;e&&e.parentNode!==s;)e=e.parentNode;return e instanceof HTMLElement?e:null}function Ir(s){return s.tagName==="P"||s.tagName==="DIV"}function vo(s,t){if(!Rr(t))return null;const e=document.createElement(s.tagName);return s.tagName==="P"&&s.classList.contains("embed-caret-spacer")&&(e.className="embed-caret-spacer"),e.appendChild(t),e}function Rr(s){for(const t of Array.from(s.childNodes)){if(t.nodeType===Node.TEXT_NODE&&(t.textContent??"").trim())return!0;if(t.nodeType!==Node.ELEMENT_NODE)continue;const e=t;if(e.tagName!=="BR"&&!(e.tagName==="P"&&e.classList.contains("embed-caret-spacer"))&&((e.textContent??"").trim()||["IMG","FIGURE","HR"].includes(e.tagName)))return!0}return!1}function Lr(s){return new Promise((t,e)=>{const n=new FileReader;n.onload=()=>{const o=n.result;t(o.slice(o.indexOf(",")+1))},n.onerror=()=>e(n.error),n.readAsDataURL(s)})}function wo(s){return s.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;")}function Pr(s){return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}const $r={board:s=>{const t=Uo(s);return t.src?{kind:"board",src:t.src,region:t.region,height:t.height,title:t.title}:null}};function Dr(s){const t=Ar(s);if(!t)return null;const e=$r[t.language];return e?e(t.body):null}function Ar(s){const e=s.trim().match(/^(`{3,})\s*([^\s`]+)?\s*\n([\s\S]*?)\n\1\s*$/);return e?{language:(e[2]??"").toLowerCase(),body:e[3]}:null}function Nr(s){switch(s.kind){case"board":return Fr(s)}}function Fr(s){const t=document.createElement("figure");return t.className="board-embed",t.dataset.src=s.src,t.dataset.height=String(s.height),s.region&&(t.dataset.region=s.region.join(",")),s.title&&(t.dataset.title=s.title),t}class An{constructor(t){m(this,"opts");m(this,"root");m(this,"statusEl");m(this,"statusTextEl");m(this,"reloadBtn");m(this,"textarea");m(this,"abort",new AbortController);m(this,"revision",null);m(this,"stale",!1);m(this,"saveTimer",null);m(this,"closed",!1);this.opts=t,this.build(),this.load()}static open(t){return new An(t)}build(){this.root=Zt("doc-editor text-file-editor");const t=Zt("doc-editor-bar"),e=Zt("doc-editor-bar-left"),n=xo("doc-editor-done","Done");n.addEventListener("click",()=>void this.close());const o=Zt("doc-editor-path");o.textContent=this.opts.path,e.append(n,o),this.statusEl=Zt("doc-editor-status"),this.statusTextEl=document.createElement("span"),this.reloadBtn=xo("status-action-btn","Reload latest"),this.reloadBtn.hidden=!0,this.reloadBtn.addEventListener("click",()=>void this.reloadLatest()),this.statusEl.append(this.statusTextEl,this.reloadBtn),this.setStatus("idle"),t.append(e,this.statusEl);const i=Zt("doc-editor-scroll text-file-editor-scroll");this.textarea=document.createElement("textarea"),this.textarea.className="text-file-editor-textarea",this.textarea.spellcheck=!1,i.appendChild(this.textarea),this.root.append(t,i),this.opts.host.appendChild(this.root);const a=this.abort.signal;this.textarea.addEventListener("input",()=>this.scheduleSave(),{signal:a}),window.addEventListener("keydown",r=>{if((r.metaKey||r.ctrlKey)&&r.key.toLowerCase()==="s"){r.preventDefault(),this.save();return}r.key==="Escape"&&document.activeElement!==this.textarea&&this.close()},{signal:a})}async load(){try{const t=await k.readFileWithRevision(this.opts.rootId,this.opts.path);this.revision=t.revision,this.stale=!1,this.textarea.value=t.content,this.setStatus("idle"),requestAnimationFrame(()=>this.textarea.focus())}catch{this.textarea.value="",this.setStatus("error","Could not load file")}}scheduleSave(){this.saveTimer!==null&&clearTimeout(this.saveTimer),this.setStatus("saving"),this.saveTimer=window.setTimeout(()=>{this.saveTimer=null,this.save()},700)}async save(){if(this.saveTimer!==null&&(clearTimeout(this.saveTimer),this.saveTimer=null),this.stale)return this.setStatus("stale","Changed elsewhere — reload before saving"),!1;try{return this.setStatus("saving"),this.revision=await k.writeFile(this.opts.rootId,this.opts.path,this.textarea.value,this.revision),this.stale=!1,this.setStatus("saved"),!0}catch(t){return t instanceof xe?(this.revision=t.currentRevision,this.stale=!0,this.setStatus("stale","Changed elsewhere — reload before saving"),!1):(this.setStatus("error","Save failed"),!1)}}async close(){return this.closed?!0:await this.save()?(this.closed=!0,this.abort.abort(),this.root.remove(),this.opts.onClose(),!0):!1}destroy(){this.saveTimer!==null&&clearTimeout(this.saveTimer),this.saveTimer=null,this.closed=!0,this.abort.abort(),this.root.remove()}markStale(){this.stale||this.closed||(this.saveTimer!==null&&(clearTimeout(this.saveTimer),this.saveTimer=null),this.stale=!0,this.setStatus("stale","Changed elsewhere — reload before saving"))}async reloadLatest(){window.confirm("Discard local edits and reload the latest version?")&&(this.saveTimer!==null&&(clearTimeout(this.saveTimer),this.saveTimer=null),await this.load())}setStatus(t,e){const n={idle:e??"Ready",saving:e??"Saving…",saved:e??"Saved",error:e??"Save failed",stale:e??"Changed elsewhere"};this.statusEl.dataset.state=t,this.statusTextEl.textContent=n[t],this.reloadBtn.hidden=t!=="stale"}}function Zt(s){const t=document.createElement("div");return t.className=s,t}function xo(s,t){const e=document.createElement("button");return e.className=s,e.type="button",e.textContent=t,e}const Co="docs:theme",ko="docs:sidebar-collapsed",Eo="docs:sidebar-width",zr=220,jr=420,mn=[{group:"Brand Colors",name:"100",variable:"--brand-100",value:"#FFFFFF",description:"lightest brand tone"},{group:"Brand Colors",name:"200",variable:"--brand-200",value:"#4DABF7",description:"light azure accent"},{group:"Brand Colors",name:"300",variable:"--brand-300",value:"#0078D4",description:"primary azure blue"},{group:"Brand Colors",name:"400",variable:"--brand-400",value:"#495057",description:"deep slate gray"},{group:"Brand Colors",name:"500",variable:"--brand-500",value:"#0078D4",description:"primary azure blue"},{group:"Brand Colors",name:"600",variable:"--brand-600",value:"#005A9E",description:"darker azure blue"},{group:"Neutral Colors",name:"100",variable:"--neutral-100",value:"#F3F2F1",description:"page background"},{group:"Neutral Colors",name:"200",variable:"--neutral-200",value:"#EAEAEA",description:"subtle surface"},{group:"Neutral Colors",name:"300",variable:"--neutral-300",value:"#D1D1D1",description:"soft border"},{group:"Neutral Colors",name:"400",variable:"--neutral-400",value:"#C8C8C8",description:"medium gray"},{group:"Neutral Colors",name:"500",variable:"--neutral-500",value:"#6E6E6E",description:"neutral mid-tone"},{group:"Neutral Colors",name:"600",variable:"--neutral-600",value:"#7A7A7A",description:"secondary text"},{group:"Neutral Colors",name:"700",variable:"--neutral-700",value:"#495057",description:"deep slate gray"},{group:"Neutral Colors",name:"800",variable:"--neutral-800",value:"#4A4A4A",description:"strong text"},{group:"Neutral Colors",name:"900",variable:"--neutral-900",value:"#0F0F0F",description:"primary text"},{group:"Neutral Colors",name:"000",variable:"--neutral-000",value:"#FFFFFF",description:"white"},{group:"Semantic Colors",name:"Success Main",variable:"--success-main",value:"#28A745",description:"positive actions"},{group:"Semantic Colors",name:"Success Background",variable:"--success-bg",value:"#E6F4EA",description:"positive surface"},{group:"Semantic Colors",name:"Success Text",variable:"--success-text",value:"#1E7E34",description:"positive text"},{group:"Semantic Colors",name:"Warning Main",variable:"--warning-main",value:"#DC2626",description:"warning actions"},{group:"Semantic Colors",name:"Warning Background",variable:"--warning-bg",value:"#FEF2F2",description:"warning surface"},{group:"Semantic Colors",name:"Warning Text",variable:"--warning-text",value:"#FFFFFF",description:"warning text"},{group:"Semantic Colors",name:"Error Main",variable:"--error-main",value:"#CD0000",description:"destructive actions"},{group:"Semantic Colors",name:"Error Background",variable:"--error-bg",value:"#FFE5E5",description:"destructive surface"},{group:"Semantic Colors",name:"Error Text",variable:"--error-text",value:"#B91C1C",description:"destructive text"},{group:"Semantic Colors",name:"Info Main",variable:"--info-main",value:"#1080A6",description:"informational actions"},{group:"Semantic Colors",name:"Info Background",variable:"--info-bg",value:"#E0F7FA",description:"informational surface"},{group:"Semantic Colors",name:"Info Text",variable:"--info-text",value:"#0369A1",description:"informational text"}];class Hr{constructor(t){m(this,"root");m(this,"layout");m(this,"main");m(this,"topbar");m(this,"contentScroll");m(this,"content");m(this,"sidebar");m(this,"searchBtn");m(this,"cartBtn");m(this,"exportBtn");m(this,"editBtn");m(this,"themeBtn");m(this,"palette");m(this,"paletteInput");m(this,"paletteResults");m(this,"cartPopover");m(this,"exportMenu");m(this,"searchIndex",[]);m(this,"searchIndexing",!1);m(this,"searchIndexRun",0);m(this,"searchIndexReady",!1);m(this,"pendingContentEvents",[]);m(this,"contentEventTimer",null);m(this,"rootRefreshRuns",new Map);m(this,"capabilityCart",new Map);m(this,"selectedTokens",new Set);m(this,"currentEditableFile");m(this,"workspace",{projects:[]});m(this,"treesByRoot",new Map);m(this,"treesByProject",new Map);m(this,"cleanup");m(this,"updateRenderedTheme");m(this,"editor");m(this,"docEditor");m(this,"textFileEditor");m(this,"currentTextFile");m(this,"editorHost");m(this,"editingId");m(this,"lastNonBoardHash","#/");m(this,"lastNonBoardScrollTop",0);m(this,"pendingScrollRestore");m(this,"sidebarResizeHandle");this.root=t,this.applyInitialTheme(),this.layout=f("div","shell");const e={onAddRepo:()=>void this.addRepoDocs(),onRemoveProject:(n,o)=>void this.promptRemoveProject(n,o),onCreateDirectory:(n,o)=>this.promptNewDirectory(n,o),onCreateDoc:(n,o)=>this.promptNewDoc(n,o),onCreateBoard:(n,o)=>this.promptNewBoard(n,o),onCreateCapability:(n,o)=>this.promptNewCapability(n,o),onCreateDocsFolder:(n,o)=>void this.createDocsFolder(n,o),onCreateProjectDirectory:n=>void this.promptNewProjectDirectory(n),onCreateProjectDoc:n=>void this.promptNewProjectDoc(n),onCreateProjectBoard:n=>void this.promptNewProjectBoard(n),onRenameDirectory:(n,o)=>void this.promptRenameDirectory(n,o),onDeleteDirectory:(n,o)=>void this.promptDeleteDirectory(n,o),onExportDirectory:(n,o)=>void this.exportDirectoryPdf(n,o),onOpenDoc:(n,o)=>{location.hash=J(n,o)},onEditDoc:(n,o)=>this.openDocEditor({rootId:n,path:o}),onOpenTextFile:(n,o)=>{this.openTextFileEditor({rootId:n,path:o})},onRenameDoc:(n,o)=>void this.promptRenameDoc(n,o),onDeleteDoc:(n,o)=>void this.promptDeleteDoc(n,o),onExportDoc:(n,o)=>void this.exportDocPdf(n,o),onOpenBoard:(n,o)=>{location.hash=lt(n,o)},onRenameBoard:(n,o)=>void this.promptRenameBoard(n,o),onDeleteBoard:(n,o)=>void this.promptDeleteBoard(n,o),onMoveDoc:(n,o,i)=>void this.moveDoc(n,o,i),onMoveBoard:(n,o,i)=>void this.moveBoard(n,o,i),onMoveDirectory:(n,o,i)=>void this.moveDirectory(n,o,i)};this.sidebar=new Ns(this.layout,e),this.sidebarResizeHandle=f("button","sidebar-resize-handle"),this.sidebarResizeHandle.type="button",this.sidebarResizeHandle.innerHTML=Q.arrowBoth,this.sidebarResizeHandle.setAttribute("aria-label","Resize sidebar"),this.sidebarResizeHandle.title="Resize sidebar",this.main=f("div","shell-main"),this.topbar=this.createTopbar(),this.contentScroll=f("div","content-scroll"),this.content=f("div","content"),this.contentScroll.appendChild(this.content),this.main.append(this.topbar,this.contentScroll),this.layout.appendChild(this.sidebarResizeHandle),this.layout.appendChild(this.main),this.root.appendChild(this.layout),window.addEventListener("hashchange",()=>this.route()),window.addEventListener("keydown",n=>this.handleGlobalKeydown(n)),document.addEventListener("pointerdown",n=>this.handleGlobalPointerDown(n),!0),localStorage.getItem(ko)==="true"&&this.setSidebarCollapsed(!0),this.applySidebarWidth(this.readSidebarWidth()),this.setupSidebarResize(),Zs.subscribe(n=>this.queueContentEvent(n)),this.refreshContentIndex().then(()=>this.route())}route(t={}){const e=t.preserveScroll?this.contentScroll.scrollTop:this.pendingScrollRestore;this.pendingScrollRestore=void 0;const n=location.hash||"#/";this.sidebar.setActive(n);const o=n.replace(/^#/,"");this.setEditableFile(void 0);const i=o.match(/^\/root\/([^/]+)\/boards\/([^?]+)(?:\?(.*))?$/);if(i){this.lastNonBoardScrollTop=this.contentScroll.scrollTop,this.updateTopbarCart(!0),this.closeCartPopover(),this.openEditor(decodeURIComponent(i[1]),decodeURIComponent(i[2]),rc(i[3]));return}if(this.lastNonBoardHash=n,this.exitEditor(),this.layout.style.display="",this.updateTopbarCart(/\/root\/[^/]+\/boards/.test(o)),/\/root\/[^/]+\/boards/.test(o)&&this.closeCartPopover(),o==="/"||o==="")return void this.renderWorkspaceHome(e);const a=o.match(/^\/root\/([^/]+)\//);if(a){const g=decodeURIComponent(a[1]);if(!this.docsRootById(g))return void this.renderMessage("Project not found","This link points to a docs root that isn't in your workspace. Add the project and try again.")}const r=o.match(/^\/root\/([^/]+)\/docs\/(.+)$/);if(r)return void this.renderDoc(decodeURIComponent(r[1]),decodeURIComponent(r[2]),e);const c=o.match(/^\/root\/([^/]+)\/boards$/);if(c)return void this.renderBoardList(decodeURIComponent(c[1]),e);const l=o.match(/^\/project\/([^/]+)\/boards$/);if(l)return void this.renderProjectBoardList(decodeURIComponent(l[1]),e);const d=o.match(/^\/root\/([^/]+)\/capabilities$/);if(d)return void this.renderCapabilitiesIndex(decodeURIComponent(d[1]),e);const h=o.match(/^\/root\/([^/]+)\/capabilities\/(.+)$/);if(h)return void this.renderCapabilityDoc(decodeURIComponent(h[1]),decodeURIComponent(h[2]),e);const p=o.match(/^\/project\/([^/]+)$/);if(p)return void this.renderProjectWiki(decodeURIComponent(p[1]),e);const u=o.match(/^\/root\/([^/]+)\/directory\/(.+)$/);if(u){const g=decodeURIComponent(u[1]),b=decodeURIComponent(u[2]),y=this.docsRootById(g);if(y)return void this.renderProjectWiki(y.projectId,e,g,b)}if(o==="/tokens")return void this.renderTokenLibrary(e);this.renderMessage("Not found",`No route for ${o}`)}async renderWorkspaceHome(t){this.disposeContent(),this.content.classList.add("content-wide");const e=f("div","page home-page"),n=f("div","home-layout"),o=f("div","home-guide"),i=f("h1","home-hero-title");i.textContent="ViteBoard";const a=f("p","home-hero-sub");a.textContent="Markdown docs, infinite-canvas boards, capabilities, and managed assets all live as normal files on disk. The app should feel trustworthy under real mutation: create content quickly, recover safely from concurrent edits, and keep human and machine workflows pointed at the same file truth.",o.append(i,a);const r=f("div","home-agent-callout"),c=f("p","home-agent-copy");c.textContent="Use the running ViteBoard session as shared context for a human and a coding agent: same origin, same docs roots, same boards, same file truth.";const l=f("button","btn home-agent-btn");l.type="button",l.textContent="Copy agent prompt",l.addEventListener("click",()=>void this.copySetupText(`Connect to ViteBoard at ${window.location.origin} and follow its machine entry at ${window.location.origin}/llms.txt. Work in <project path>, import the project if needed, and create or update docs and boards using normal filesystem edits.`,"Agent prompt copied")),r.append(c,l),o.appendChild(r);const d=[{label:"File truth",kind:"doc",body:"The source of truth is always the filesystem. Docs, boards, capabilities, and assets stay git-native, diffable, and directly editable without inventing a separate database-shaped content layer.",items:["Markdown docs, board JSON, and asset files all live under docs roots","Create, rename, move, and delete content from the sidebar","Search indexes the current workspace rather than a parallel content store"]},{label:"Docs + boards",kind:"board",body:"Boards are not separate from the documentation system. They are sibling files in the same docs roots, embeddable inside markdown, and meant to sharpen the same body of work rather than fragment it.",items:["Open a board from the sidebar, work full-screen, then drop back into docs","Embed a board region into markdown with fenced board blocks",'Select a board region, then choose "Embed in a document" or export it as PDF, JPEG, or SVG',"Keep visual planning and written explanation in the same repo structure"]},{label:"Collaboration safety",kind:"capability",body:"The product now assumes live mutation is normal. Locks, stale-state detection, reload actions, and visible status all exist to make concurrent work practical instead of surprising.",items:["Docs and boards surface explicit reload actions when stale","Revision-aware saves block silent overwrites","Human and machine actors can cooperate through the same running workspace"]},{label:"Machine workflow",kind:"",body:"ViteBoard is also a machine-readable workspace surface. The app can expose docs roots, boards, schema references, and live coordination routes while the files remain the only persistent truth.",items:["The local HTTP surface advertises machine docs and workspace discovery","Capabilities and selected docs can be assembled into prompts from the UI","The practical goal is faster real work, not another disconnected abstraction layer"]}];for(const v of d){const E=f("div","home-feature"),w=f("div","home-feature-header"),S=f("span",`home-feature-badge home-feature-badge-${v.kind||"neutral"}`);S.textContent=v.label,w.appendChild(S),E.appendChild(w);const B=f("p","home-feature-body");if(B.textContent=v.body,E.appendChild(B),v.items){const T=document.createElement("ul");T.className="home-feature-list";for(const M of v.items){const I=document.createElement("li");I.textContent=M,T.appendChild(I)}E.appendChild(T)}o.appendChild(E)}const h=f("div","home-shortcut-title");h.textContent="Current operating model",o.appendChild(h);const p=[["1. Add repo","Bring a local project into the workspace"],["2. Create docs/ if needed","Start the repo as a writable docs root"],["3. Right-click in the tree","Create docs, boards, directories, and capabilities in place"],["4. Open a board","Think visually, then embed the useful region back into docs"],["5. Cmd K / Ctrl K","Search across the current workspace"],["6. Stale state appears","Use Reload latest instead of guessing which copy is current"],["7. Copy agent prompt","Hand the same workspace context to an AI assistant"],["8. Git stays normal","The files on disk remain the real source of truth"]],u=f("div","home-shortcut-table");for(const[v,E]of p){const w=f("div","home-shortcut-row"),S=f("kbd","home-shortcut-key");S.textContent=v;const B=f("span","home-shortcut-desc");B.textContent=E,w.append(S,B),u.appendChild(w)}o.appendChild(u),n.appendChild(o);const g=f("div","home-panel"),b=f("div","home-panel-head"),y=f("div","home-panel-title");y.textContent="Active workspace";const x=f("button","btn primary home-panel-add");if(x.textContent="+ Add repo",x.addEventListener("click",()=>void this.addRepoDocs()),b.append(y,x),g.appendChild(b),this.workspace.projects.length===0){const v=f("div","home-panel-empty");v.textContent="No projects yet. Add a project root, create docs/ if needed, and start writing against the real filesystem.",g.appendChild(v)}else for(const v of this.workspace.projects){const E=f("div","home-panel-project"),w=f("a","home-panel-project-head");w.href=jt(v.id);const S=f("span","home-panel-project-name");S.textContent=v.label;const B=v.docsRoots.reduce((W,Z)=>{const st=this.treesByRoot.get(Z.id)??[];return W+ye(st).length},0),T=v.docsRoots.reduce((W,Z)=>{const st=this.treesByRoot.get(Z.id)??[];return W+Tt(st).length},0),M=f("span","home-panel-project-meta"),I=[`${v.docsRoots.length} root${v.docsRoots.length===1?"":"s"}`];B&&I.push(`${B} doc${B===1?"":"s"}`),T&&I.push(`${T} board${T===1?"":"s"}`),M.textContent=I.join(" · "),w.append(S,M),E.appendChild(w);const $=6,P=v.docsRoots,ot=P.slice(0,$),tt=f("div","home-panel-roots");for(const W of ot){const Z=this.treesByRoot.get(W.id)??[],st=gn(re(Z)),O=st?J(W.id,st):zt(W.id),_=f("a","home-panel-root");_.href=O;const V=f("span","home-panel-root-path");V.textContent=W.displayPath;const D=ye(Z).length,q=Tt(Z).length;if(D||q){const F=f("span","home-panel-root-meta"),K=[];D&&K.push(String(D)),q&&K.push(`${q}▦`),F.textContent=K.join(" · "),_.append(V,F)}else _.appendChild(V);tt.appendChild(_)}if(P.length>$){const W=f("a","home-panel-more");W.href=jt(v.id),W.textContent=`+ ${P.length-$} more roots`,tt.appendChild(W)}E.appendChild(tt),g.appendChild(E)}n.appendChild(g),e.appendChild(n),this.content.replaceChildren(e),this.contentScroll.scrollTop=t??0}async copySetupText(t,e){try{await navigator.clipboard.writeText(t),C(e)}catch{C("Could not access clipboard")}}async renderProjectWiki(t,e,n,o){this.disposeContent(),this.content.classList.add("content-wide");const i=this.workspace.projects.find(p=>p.id===t);if(!i){this.renderMessage("Project not found","This project is no longer registered.");return}const a=f("div","page wiki-page"),r=!!n,c=!!o;let l=!1;if(c&&n){const p=this.docsRootById(n);p&&(l=p.displayPath===o||p.displayPath.startsWith(o+"/"))}const d=f("div","wiki-head");if(c&&n){const p=[{label:"Home",href:"#/"}];p.push({label:i.label,href:jt(i.id)});const u=o.split("/").filter(Boolean);for(let b=0;b<u.length;b++){const y=u.slice(0,b+1).join("/"),x=b===u.length-1;p.push({label:u[b],href:x?void 0:Ze(n,y)})}d.appendChild(St(p));const g=f("h1","wiki-title");g.textContent=u[u.length-1]||i.label,d.appendChild(g)}else if(r&&n){const p=this.docsRootById(n),u=[{label:"Home",href:"#/"}];if(u.push({label:i.label,href:jt(i.id)}),p){const b=p.displayPath.split("/").filter(Boolean);for(let y=0;y<b.length;y++){const x=b.slice(0,y+1).join("/"),v=y===b.length-1;u.push({label:b[y],href:v?void 0:Ze(n,x)})}}d.appendChild(St(u));const g=f("h1","wiki-title");g.textContent=(p==null?void 0:p.displayPath.split("/").pop())||i.label,d.appendChild(g)}else{d.appendChild(St([{label:"Home",href:"#/"},{label:i.label}]));const p=f("h1","wiki-title");p.textContent=i.label,d.appendChild(p)}if(!r&&!c){const p=i.docsRoots.reduce((y,x)=>{const v=this.treesByRoot.get(x.id)??[];return y+ye(v).length},0),u=i.docsRoots.reduce((y,x)=>{const v=this.treesByRoot.get(x.id)??[];return y+Tt(v).length},0),g=i.docsRoots.reduce((y,x)=>y+_t(this.treesByRoot.get(x.id)??[]).length,0),b=f("div","wiki-stats");for(const[y,x]of[[String(i.docsRoots.length),"docs roots"],[String(p),"documents"],[String(u),"boards"],[String(g),"capabilities"]]){const v=f("div","wiki-stat"),E=f("div","wiki-stat-val");E.textContent=y;const w=f("div","wiki-stat-label");w.textContent=x,v.append(E,w),b.appendChild(v)}d.appendChild(b)}a.appendChild(d);const h=n?i.docsRoots.filter(p=>p.id===n):i.docsRoots;for(const p of h){const u=this.treesByRoot.get(p.id)??[];let g=u;if(o&&!l){const w=(B,T)=>{for(const M of B){if(M.type==="dir"&&M.path===T)return M;if(M.type==="dir"){const I=w(M.children,T);if(I)return I}}return null},S=w(u,o);g=(S==null?void 0:S.type)==="dir"?S.children:[]}const b=ye(g),y=Tt(g),x=_t(g),v=f("div","wiki-root-section");if(!o||l){const w=f("div","wiki-root-head"),S=f("div","wiki-root-path");S.textContent=p.displayPath,w.appendChild(S),v.appendChild(w)}if(!b.length&&!y.length&&!x.length){const w=f("div","wiki-root-empty");w.textContent="No docs, boards, or capabilities yet. Right-click in the sidebar to add content.",v.appendChild(w),a.appendChild(v);continue}const E=f("div","wiki-root-cols");if(b.length>0){const w=f("div","wiki-col"),S=f("div","wiki-col-head");S.textContent=`Docs (${b.length})`,w.appendChild(S);const B=f("div","wiki-col-list");for(const T of b){const M=f("a","wiki-col-item wiki-col-item-doc");M.href=J(p.id,T.path),M.textContent=T.name==="index.md"?"Overview":T.name.replace(/\.md$/,"").replace(/[-_]/g," ");const I=f("span","wiki-col-item-path"),$=T.path.includes("/")?T.path.slice(0,T.path.lastIndexOf("/")):"";I.textContent=$,$&&M.appendChild(I),B.appendChild(M)}w.appendChild(B),E.appendChild(w)}if(y.length>0){const w=f("div","wiki-col"),S=f("div","wiki-col-head");S.textContent=`Boards (${y.length})`,w.appendChild(S);const B=f("div","wiki-col-list");for(const T of y){const M=rt(T.path),I=f("a","wiki-col-item wiki-col-item-board");I.href=lt(p.id,M),I.textContent=M.split("/").pop().replace(/[-_]/g," ");const $=f("span","wiki-col-item-path");$.textContent=M.includes("/")?M.slice(0,M.lastIndexOf("/")):p.displayPath,I.appendChild($),B.appendChild(I)}w.appendChild(B),E.appendChild(w)}if(x.length>0){const w=f("div","wiki-col"),S=f("div","wiki-col-head");S.textContent=`Capabilities (${x.length})`,w.appendChild(S);const B=f("div","wiki-col-list");for(const T of x){const M=f("a","wiki-col-item wiki-col-item-cap");M.href=Qt(p.id,T.entryPath),M.textContent=Ge(T.entryPath),B.appendChild(M)}w.appendChild(B),E.appendChild(w)}v.appendChild(E),a.appendChild(v)}this.content.replaceChildren(a),this.contentScroll.scrollTop=e??0}async renderDoc(t,e,n){if(this.disposeContent(),!this.docsRootById(t)){this.renderMessage("Docs root unavailable","This docs root is no longer registered. Re-add the project root if needed.");return}try{const o=await k.readFile(t,e);this.setEditableFile({rootId:t,path:e});const i=f("div","doc-page"),a=je(this.workspace,t,{filePath:e});i.appendChild(St(a));const r=f("div","");i.appendChild(r),this.content.replaceChildren(i);const{destroy:c,setTheme:l}=wn(r,o,{rootId:t,docPath:e});this.cleanup=c,this.updateRenderedTheme=l;const d=await k.getTree(t),h=He(t,d),p=We(h,J(t,e));p&&i.appendChild(p),this.contentScroll.scrollTop=n??0}catch{this.renderMessage("Document not found",e)}}async exportDocPdf(t,e){const n=this.docsRootById(t);if(!n){C("Docs root unavailable");return}try{await Yn({kind:"doc",root:n,filePath:e,tree:this.treesByRoot.get(t)})}catch(o){C(o instanceof Error?o.message:"Could not export PDF")}}async exportDirectoryPdf(t,e){const n=this.docsRootById(t);if(!n){C("Docs root unavailable");return}try{await Yn({kind:"dir",root:n,dirPath:e,tree:this.treesByRoot.get(t)})}catch(o){C(o instanceof Error?o.message:"Could not export PDF")}}openDocEditor(t){const e=this.contentScroll.scrollTop;this.topbar.classList.add("editing-doc"),this.closeCartPopover(),this.docEditor=Dn.open({rootId:t.rootId,path:t.path,initialScrollTop:e,onClose:n=>{this.docEditor=void 0,this.topbar.classList.remove("editing-doc"),this.pendingScrollRestore=n,this.route()}})}async openTextFileEditor(t){this.textFileEditor&&!await this.textFileEditor.close()||(this.closeCartPopover(),this.currentTextFile=t,this.textFileEditor=An.open({rootId:t.rootId,path:t.path,host:document.body,onClose:()=>{this.textFileEditor=void 0,this.currentTextFile=void 0}}))}async renderCapabilityDoc(t,e,n){if(this.disposeContent(),!this.docsRootById(t)){this.renderMessage("Docs root unavailable","This docs root is no longer registered. Re-add the project root if needed.");return}const o=this.treesByRoot.get(t)??await k.getTree(t),i=Wr(o,e)??e,a=To(o,e)??To(o,i);let r;try{r=await k.readFile(t,i),this.setEditableFile(void 0)}catch{this.renderMessage("Capability not found",e);return}const c=f("div","page"),l=this.docsRootById(t);l&&this.workspace.projects.find(O=>O.id===l.projectId);const d=Ge(i),h=je(this.workspace,t,{filePath:i,currentLabel:d});c.appendChild(St(h));const p=f("div","page-bar"),u=f("div","doc-actions capability-doc-actions"),{frontmatter:g}=ne(r),b=f("button","btn");b.classList.add("capability-detail-btn");const y=So(t,a??Or(i),r,g),x=await k.getCapability(t,y.branchPath).catch(()=>null);this.updateCartButton(b,y.path),b.addEventListener("click",()=>{this.toggleCapabilityCart(y),this.updateCartButton(b,y.path)});const v=f("button","btn primary");v.classList.add("capability-detail-btn"),v.textContent="Copy capability context",v.addEventListener("click",async()=>{await this.copyCapabilityContext(y,o)});const E=f("button","btn");E.classList.add("capability-detail-btn"),E.textContent="Open entry doc",E.addEventListener("click",()=>{location.hash=J(t,i)}),u.append(b,v,E),p.append(u),c.appendChild(p);const w=f("div","card-tags capability-meta-tags"),S=f("span","tag");if(S.textContent=y.displayPath,w.appendChild(S),y.kind){const O=f("span","tag");O.textContent=y.kind,w.appendChild(O)}c.appendChild(w);const B=_r(y.branchPath),T=B?await this.readOptionalFile(t,B):null;if(B&&T){const O=f("section","token-section capability-machine-section"),_=f("div","page-bar"),V=f("h2","");V.textContent="Machine entrypoint";const D=f("div","doc-actions capability-doc-actions"),q=f("button","btn primary");q.textContent="Copy llms.txt",q.addEventListener("click",async()=>{try{await navigator.clipboard.writeText(T),C("Capability machine entrypoint copied")}catch{C("Could not access clipboard")}}),D.appendChild(q),_.append(V,D);const F=f("p","page-lead capability-entry-lead");F.textContent="This is the capability-local machine entrypoint. It should be the first file an LLM reads to understand what this capability branch is for, what files matter, and how to use it.";const K=document.createElement("pre");K.className="code-block";const ct=document.createElement("code");ct.textContent=T,K.appendChild(ct),O.append(_,F,K),c.appendChild(O)}if(x){const O=f("section","token-section capability-skill-section"),_=f("div","page-bar"),V=f("h2","");V.textContent="Agent skill";const D=f("div","doc-actions capability-doc-actions"),q=f("button","btn primary");q.textContent="Copy SKILL.md",q.addEventListener("click",async()=>{try{await navigator.clipboard.writeText(x.skillMarkdown),C("Agent skill copied")}catch{C("Could not access clipboard")}});const F=f("button","btn");F.textContent="Copy OpenCode config",F.addEventListener("click",async()=>{const $t=`"skills": [${JSON.stringify(`${location.origin}${x.openCodeCatalog}`)}]`;try{await navigator.clipboard.writeText($t),C("OpenCode skill catalog config copied")}catch{C("Could not access clipboard")}}),D.append(q,F),_.append(V,D);const K=f("p","page-lead capability-entry-lead");K.textContent="This branch is exposed as a portable Agent Skill. The generated instructions include its llms.txt rules and link its supporting files; OpenCode can consume the live catalog, while Codex and Claude Code can use the same SKILL.md in their native skill folders.";const ct=f("p","capability-skill-meta");ct.textContent=`Skill ID: ${x.skillId} · Codex: .agents/skills/${x.skillId}/ · Claude Code: .claude/skills/${x.skillId}/`;const Lt=document.createElement("details");Lt.className="capability-skill-preview";const Xt=document.createElement("summary");Xt.textContent="Preview generated SKILL.md";const he=f("pre","code-block"),Pt=document.createElement("code");Pt.textContent=x.skillMarkdown,he.appendChild(Pt),Lt.append(Xt,he),O.append(_,K,ct,Lt),c.appendChild(O)}const M=f("div",""),I=f("section","token-section capability-entry-section"),$=f("h2","");$.textContent="Entry document";const P=f("p","page-lead capability-entry-lead");P.textContent="This markdown entry explains the capability branch. The capability itself may also include nested files, scripts, helpers, and other reusable execution material.",I.append($,P,M),c.appendChild(I),this.content.replaceChildren(c);const{destroy:ot,setTheme:tt}=wn(M,r,{rootId:t,docPath:i});this.cleanup=ot,this.updateRenderedTheme=tt;const W=Bo(o,y.branchPath);if(W.length>1){const O=f("section","token-section capability-files-section"),_=f("h2","");_.textContent="Files in this capability";const V=f("div","card-grid capability-files-grid");for(const D of W){const q=D.path.endsWith(".md")&&D.path===y.entryPath,F=document.createElement(q?"a":"button");F.className="card",F instanceof HTMLAnchorElement&&(F.href=J(t,D.path)),F instanceof HTMLButtonElement&&(F.type="button",F.addEventListener("click",()=>{this.openTextFileEditor({rootId:t,path:D.path})}));const K=f("div","card-title");K.textContent=D.path===y.entryPath?`${Oe(D.path)} (entry)`:D.path===B?`${Oe(D.path)} (machine entrypoint)`:Oe(D.path);const ct=f("div","card-desc");ct.textContent=ce(D.path),F.append(K,ct),V.appendChild(F)}O.append(_,V),c.appendChild(O)}const Z=He(t,o),st=We(Z,Qt(t,y.branchPath));st&&c.appendChild(st),this.contentScroll.scrollTop=n??0}async renderCapabilitiesIndex(t,e){if(this.disposeContent(),!this.docsRootById(t)){this.renderMessage("Docs root unavailable","This docs root is no longer registered. Re-add the project root if needed.");return}this.content.classList.add("content-wide");const n=f("div","page capability-library"),o=je(this.workspace,t,{currentLabel:"Capabilities"});n.appendChild(St(o));const i=f("h1","");i.textContent="Capability library";const a=f("p","page-lead");a.textContent="Browse open-ended capability branches. Inspect their files, understand their entrypoints, and reuse them as working context, automations, or tool-bearing capability units.",n.append(i,a);const r=f("section","token-section capability-agent-skills"),c=f("h2","");c.textContent="Agent Skills";const l=f("p","page-lead capability-entry-lead");l.textContent="Capabilities across this workspace are available through the Agent Skills API. OpenCode can load the live catalog; other compatible agents can install a standard SKILL.md with the capability files.";const d=f("code","capability-catalog-url");d.textContent=`${location.origin}/__api/skills/catalog/`;const h=f("button","btn");h.textContent="Copy OpenCode config",h.addEventListener("click",async()=>{const b=`"skills": [${JSON.stringify(`${location.origin}/__api/skills/catalog/`)}]`;try{await navigator.clipboard.writeText(b),C("OpenCode skill catalog config copied")}catch{C("Could not access clipboard")}}),r.append(c,l,d,h),n.appendChild(r);const p=f("div","capability-layout"),u=f("div","card-grid capability-grid"),g=this.renderCapabilityCart();p.append(u,g),n.appendChild(p),this.content.replaceChildren(n);try{const b=this.treesByRoot.get(t)??await k.getTree(t),y=_t(b);for(const E of y){const w=await k.readFile(t,E.entryPath),{frontmatter:S}=ne(w),B=So(t,E,w,S),T=document.createElement("article");T.className="card";const M=f("div","card-title"),I=document.createElement("a");I.href=Qt(t,E.branchPath),I.textContent=B.title,M.appendChild(I);const $=f("div","card-desc");$.textContent=B.summary,T.append(M,$);const P=f("div","card-tags"),ot=f("span","tag");if(ot.textContent=B.displayPath,P.appendChild(ot),B.kind){const tt=f("span","tag");tt.textContent=B.kind,P.appendChild(tt)}if(T.appendChild(P),B.tags.length){const tt=f("div","card-tags");for(const W of B.tags){const Z=f("span","tag");Z.textContent=W,tt.appendChild(Z)}T.appendChild(tt)}u.appendChild(T)}y.length===0&&u.appendChild(Jt("No capabilities yet."));const x=He(t,b),v=We(x,Sn(t));v&&n.appendChild(v)}catch{u.appendChild(Jt("Could not load capabilities."))}this.contentScroll.scrollTop=e??0}renderTokenLibrary(t){this.disposeContent(),this.content.classList.add("content-wide");const e=f("div","page token-library"),n=f("div","page-bar"),o=f("h1","");o.textContent="Tokens";const i=f("div","token-actions"),a=f("button","btn");a.textContent="Select all",a.addEventListener("click",()=>{this.selectedTokens=new Set(mn.map(d=>d.variable)),this.renderTokenLibrary(this.contentScroll.scrollTop)});const r=f("button","btn");r.textContent="Clear",r.addEventListener("click",()=>{this.selectedTokens.clear(),this.renderTokenLibrary(this.contentScroll.scrollTop)});const c=f("button","btn primary");c.textContent=`Copy selected (${this.selectedTokens.size})`,c.disabled=this.selectedTokens.size===0,c.addEventListener("click",()=>void this.copySelectedTokens()),i.append(a,r,c),n.append(o,i);const l=f("p","page-lead");l.textContent="Brand, neutral, and semantic CSS variables used throughout the app. Select tokens and copy them as a ready-to-paste :root block.",e.append(n,l);for(const d of["Brand Colors","Neutral Colors","Semantic Colors"]){const h=f("section","token-section"),p=f("h2","");p.textContent=d;const u=f("div","token-grid");for(const g of mn.filter(b=>b.group===d)){const b=f("div","token-card");this.selectedTokens.has(g.variable)&&b.classList.add("selected");const y=f("label","token-select-zone"),x=document.createElement("input");x.type="checkbox",x.checked=this.selectedTokens.has(g.variable),x.addEventListener("change",()=>{x.checked?this.selectedTokens.add(g.variable):this.selectedTokens.delete(g.variable),this.renderTokenLibrary(this.contentScroll.scrollTop)});const v=f("span","token-swatch");v.style.background=g.value;const E=f("span","token-copy"),w=f("strong","");w.textContent=g.name;const S=f("code","");S.textContent=g.value;const B=f("small","");B.textContent=g.description,E.append(w,S,B),y.append(x,v,E);const T=f("button","token-copy-btn");T.type="button",T.innerHTML=Q.copy,T.title=`Copy ${g.variable}`,T.setAttribute("aria-label",`Copy ${g.variable}`),T.addEventListener("click",M=>{M.stopPropagation(),this.copyToken(g)}),b.append(y,T),u.appendChild(b)}h.append(p,u),e.appendChild(h)}this.content.replaceChildren(e),this.contentScroll.scrollTop=t??0}async copySelectedTokens(){const t=mn.filter(n=>this.selectedTokens.has(n.variable));if(t.length===0)return;const e=[":root {",...t.map(n=>` ${n.variable}: ${n.value};`),"}"].join(`
40
+ `);try{await navigator.clipboard.writeText(e),C(`${t.length} token${t.length===1?"":"s"} copied`)}catch{C("Could not access clipboard")}}async copyToken(t){try{await navigator.clipboard.writeText(`${t.variable}: ${t.value};`),C(`${t.variable} copied`)}catch{C("Could not access clipboard")}}renderCapabilityCart(t){const e=t??(()=>{const h=qr(location.hash);h&&this.renderCapabilitiesIndex(h,this.contentScroll.scrollTop)}),n=f("aside","capability-cart"),o=f("div","capability-cart-head"),i=f("h2","");i.textContent="Capability toolbelt";const a=f("span","capability-cart-count");a.textContent=String(this.capabilityCart.size),o.append(i,a);const r=f("div","capability-cart-body");if(this.capabilityCart.size===0){const h=f("div","capability-cart-empty");h.textContent="Equip capabilities to build an active toolbelt for the current task.",r.appendChild(h)}else for(const h of this.capabilityCart.values()){const p=f("div","capability-cart-item"),u=f("div",""),g=f("div","capability-cart-item-title");g.textContent=h.title;const b=f("div","capability-cart-item-meta");b.textContent=h.displayPath,u.append(g,b);const y=f("button","capability-cart-remove");y.type="button",y.textContent="Remove",y.addEventListener("click",()=>{this.capabilityCart.delete(h.path),this.updateTopbarCart(),e()}),p.append(u,y),r.appendChild(p)}const c=f("div","capability-cart-actions"),l=f("button","btn primary");l.textContent="Copy toolbelt context",l.disabled=this.capabilityCart.size===0,l.addEventListener("click",()=>void this.copyCapabilityCartPrompt());const d=f("button","btn");return d.textContent="Clear",d.disabled=this.capabilityCart.size===0,d.addEventListener("click",()=>{this.capabilityCart.clear(),this.updateTopbarCart(),e()}),c.append(l,d),n.append(o,r,c),n}toggleCapabilityCart(t){this.capabilityCart.has(t.path)?this.capabilityCart.delete(t.path):this.capabilityCart.set(t.path,t),this.updateTopbarCart()}updateCartButton(t,e){const n=this.capabilityCart.has(e);t.textContent=n?"Unequip":"Equip",t.classList.toggle("primary",!n),t.classList.toggle("is-selected",n)}async copyCapabilityCartPrompt(){if(this.capabilityCart.size===0)return;const e=`Use this capability toolbelt as implementation guidance for the next coding task. These are integrated capability branches that may contain context, workflows, scripts, helpers, or other reusable execution material.
41
+
42
+ `+(await Promise.all([...this.capabilityCart.values()].map(async(n,o)=>{const i=this.treesByRoot.get(n.rootId)??await k.getTree(n.rootId);return`## ${o+1}. ${n.title}
43
+
44
+ ${await this.capabilityBranchContext(n,i)}`}))).join(`
45
+
46
+ ---
47
+
48
+ `);try{await navigator.clipboard.writeText(e),C(`${this.capabilityCart.size} capabilit${this.capabilityCart.size===1?"y":"ies"} copied`)}catch{C("Could not access clipboard")}}async copyCapabilityContext(t,e){try{const n=e??this.treesByRoot.get(t.rootId)??await k.getTree(t.rootId);await navigator.clipboard.writeText(await this.capabilityBranchContext(t,n)),C("Capability context copied")}catch{C("Could not access clipboard")}}async capabilityBranchContext(t,e){const n=Bo(e,t.branchPath).filter(i=>Xr(i.path)),o=await Promise.all(n.map(async i=>{const a=await k.readFile(t.rootId,i.path);return`### ${Oe(i.path)}
49
+
50
+ ${a.trim()}`}));return[`Capability: ${t.title}`,`Branch: ${t.displayPath}`,...t.kind?[`Kind: ${t.kind}`]:[],"",...o].join(`
51
+ `)}async readOptionalFile(t,e){try{return await k.readFile(t,e)}catch{return null}}async renderBoardList(t,e){if(this.disposeContent(),!this.docsRootById(t)){this.renderMessage("Docs root unavailable","This docs root is no longer registered. Re-add the project root if needed.");return}this.content.classList.add("content-wide");const n=f("div","page board-library"),o=je(this.workspace,t,{currentLabel:"Boards"});n.appendChild(St(o));const i=f("div","page-bar"),a=f("h1","");a.textContent="Boards";const r=f("button","btn primary");r.textContent="+ New board",r.addEventListener("click",()=>this.promptNewBoard(t)),i.append(a,r),n.appendChild(i);const c=f("p","page-lead");c.textContent="Each board is a git-tracked JSON file. Open one to edit it, select a region, then choose whether to embed it in a doc or export it as PDF, JPEG, or SVG.",n.appendChild(c);const l=f("div","card-grid board-grid");n.appendChild(l),this.content.replaceChildren(n);try{const d=await dt.list(t);for(const g of d){const b=document.createElement("a");b.className="card",b.href=lt(t,g.id);const y=f("div","card-title");y.textContent=g.title;const x=f("div","card-desc");x.textContent=`${g.elementCount} element${g.elementCount===1?"":"s"} · ${g.filePath}`,b.append(y,x),l.appendChild(b)}d.length===0&&l.appendChild(Jt("No boards yet — create one."));const h=await k.getTree(t),p=He(t,h),u=We(p,zt(t));u&&n.appendChild(u)}catch{l.appendChild(Jt("Could not load boards."))}this.contentScroll.scrollTop=e??0}async renderProjectBoardList(t,e){this.disposeContent(),this.content.classList.add("content-wide");const n=this.workspace.projects.find(d=>d.id===t);if(!n){this.renderMessage("Project unavailable","This project is no longer registered. Re-add it if needed.");return}const o=f("div","page boards-page"),i=[{label:"Home",href:"#/"},{label:n.label,href:jt(t)},{label:"Boards"}];o.appendChild(St(i));const a=f("div","page-bar"),r=f("h1","");r.textContent=`${n.label} boards`,a.appendChild(r),o.appendChild(a);const c=f("p","page-lead");c.textContent="Boards across every mounted docs root in this project. Each card shows the docs root and board file path.",o.appendChild(c);const l=f("div","card-grid board-grid");o.appendChild(l),this.content.replaceChildren(o);try{const d=await this.listProjectBoards(n);for(const h of d){const p=document.createElement("a");p.className="card",p.href=lt(h.root.id,h.board.id);const u=f("div","card-title");u.textContent=h.board.title;const g=f("div","card-desc");g.textContent=`${h.board.elementCount} element${h.board.elementCount===1?"":"s"} · ${h.root.displayPath} · ${h.board.filePath}`,p.append(u,g),l.appendChild(p)}d.length===0&&l.appendChild(Jt("No boards yet — create one."))}catch{l.appendChild(Jt("Could not load boards."))}this.contentScroll.scrollTop=e??0}async listProjectBoards(t){const e=[];for(const n of t.docsRoots){const o=await dt.list(n.id);for(const i of o)e.push({root:n,board:i})}return e.sort((n,o)=>o.board.updatedAt!==n.board.updatedAt?o.board.updatedAt-n.board.updatedAt:n.root.displayPath!==o.root.displayPath?n.root.displayPath.localeCompare(o.root.displayPath):n.board.filePath.localeCompare(o.board.filePath)),e}promptNewBoard(t,e=""){const n=e?`doc:${t}:${e}`:t,o=this.sidebar.collapsibles.get(n),i=(o==null?void 0:o.body)??this.sidebar.element.querySelector(".nav-repo-body");i?this.sidebar.startInlineCreate(i,"board-name",async a=>{const r=At(a,"board");if(!r.ok){C(r.message);return}try{const c=await dt.create(t,r.raw,we(),e);await this.refreshContentIndex(),location.hash=lt(t,c)}catch{C("Could not create board")}}):et("New board",(a,r)=>{const c=document.createElement("input");c.className="board-title",c.placeholder="Board title",c.style.width="100%",c.style.marginBottom="12px";const l=f("div","modal-actions"),d=f("button","btn primary");d.textContent="Create";const h=async()=>{const p=At(c.value,"board");if(!p.ok){C(p.message),c.focus();return}try{const u=await dt.create(t,p.raw,we(),e);r(),await this.refreshContentIndex(),location.hash=lt(t,u)}catch{C("Could not create board file")}};d.addEventListener("click",()=>void h()),c.addEventListener("keydown",p=>{p.stopPropagation(),p.key==="Enter"&&h()}),l.appendChild(d),a.append(c,l),c.focus()})}promptNewDirectory(t,e){const n=e?`doc:${t}:${e}`:t,o=this.sidebar.collapsibles.get(n),i=(o==null?void 0:o.body)??this.sidebar.element.querySelector(".nav-repo-body");i?this.sidebar.startInlineCreate(i,"directory-name",async a=>{const r=At(a,"directory");if(!r.ok){C(r.message);return}const c=e?`${e}/${r.slug}`:r.slug;try{await k.createDirectory(t,c),await this.refreshContentIndex()}catch{C("Could not create directory")}}):et("New directory",(a,r)=>{const c=document.createElement("input");c.className="board-title",c.placeholder="Directory name",c.style.width="100%",c.style.marginBottom="12px";const l=f("div","modal-actions"),d=f("button","btn primary");d.textContent="Create";const h=async()=>{const p=At(c.value,"directory");if(!p.ok){C(p.message),c.focus();return}const u=e?`${e}/${p.slug}`:p.slug;try{await k.createDirectory(t,u),r(),await this.refreshContentIndex()}catch{C("Could not create directory")}};d.addEventListener("click",()=>void h()),c.addEventListener("keydown",p=>{p.stopPropagation(),p.key==="Enter"&&h()}),l.appendChild(d),a.append(c,l),c.focus()})}async ensureProjectDocsRoot(t){var n;const e=(n=this.workspace.projects.find(o=>o.id===t))==null?void 0:n.docsRoots[0];if(e)return e;try{const o=await k.ensureProjectDocsRoot(t);return await this.refreshContentIndex(),this.docsRootById(o.id)??o}catch{C("Could not create docs folder");return}}async createDocsFolder(t,e){try{await k.createDocsFolder(t,e),await this.refreshContentIndex(),C(`Created docs/ in ${e||"project root"}`)}catch{C("Could not create docs folder")}}async promptNewProjectDirectory(t){const e=await this.ensureProjectDocsRoot(t);e&&this.promptNewDirectory(e.id,"")}async promptNewProjectDoc(t){const e=await this.ensureProjectDocsRoot(t);e&&this.promptNewDoc(e.id,"")}async promptNewProjectBoard(t){const e=await this.ensureProjectDocsRoot(t);e&&this.promptNewBoard(e.id,"")}promptNewDoc(t,e){const n=e?`doc:${t}:${e}`:t,o=this.sidebar.collapsibles.get(n),i=(o==null?void 0:o.body)??this.sidebar.element.querySelector(".nav-repo-body");i?this.sidebar.startInlineCreate(i,"document-name.md",async a=>{const r=At(a.replace(/\.md$/i,""),"doc");if(!r.ok){C(r.message);return}const c=e?`${e}/${r.slug}.md`:`${r.slug}.md`;try{await k.writeFile(t,c,`# ${mt(r.slug)}
52
+ `,null),await this.refreshContentIndex(),location.hash=J(t,c)}catch{C("Could not create doc")}}):et("New doc",(a,r)=>{const c=document.createElement("input");c.className="board-title",c.placeholder="Document name (e.g. overview)",c.style.width="100%",c.style.marginBottom="12px";const l=f("div","modal-actions"),d=f("button","btn primary");d.textContent="Create";const h=async()=>{const p=At(c.value.replace(/\.md$/i,""),"doc");if(!p.ok){C(p.message),c.focus();return}const u=e?`${e}/${p.slug}.md`:`${p.slug}.md`;try{await k.writeFile(t,u,`# ${mt(p.slug)}
53
+ `,null),r(),await this.refreshContentIndex(),location.hash=J(t,u)}catch{C("Could not create doc file")}};d.addEventListener("click",()=>void h()),c.addEventListener("keydown",p=>{p.stopPropagation(),p.key==="Enter"&&h()}),l.appendChild(d),a.append(c,l),c.focus()})}promptNewCapability(t,e){et("New capability",(n,o)=>{const i=document.createElement("input");i.className="board-title",i.placeholder="Capability name (e.g. auth-flow)",i.style.width="100%",i.style.marginBottom="12px";const a=f("div","modal-actions"),r=f("button","btn primary");r.textContent="Create";const c=async()=>{const l=(i.value.trim()||"untitled").replace(/\.md$/,"").replace(/\s+/g,"-").toLowerCase(),d=e.replace(/^capabilities\/?/,""),h=d?`capabilities/${d}/${l}`:`capabilities/${l}`,p=`${h}/index.md`,u=`${h}/llms.txt`,g=mt(l),b=`---
54
+ title: ${g}
55
+ summary:
56
+ tags:
57
+ kind:
58
+ ---
59
+
60
+ # ${g}
61
+
62
+ ## Purpose
63
+
64
+ ## When to use
65
+
66
+ ## Important files
67
+
68
+ ## Outputs
69
+ `,y=`# ${g}
70
+
71
+ Read index.md first for the human overview of this capability branch.
72
+
73
+ ## Purpose
74
+
75
+ Describe what this capability helps an LLM do.
76
+
77
+ ## Entry points
78
+
79
+ - Human entry: index.md
80
+ - Machine entry: llms.txt
81
+
82
+ ## Important files
83
+
84
+ List the files or subdirectories an LLM should inspect before acting.
85
+
86
+ ## Working rules
87
+
88
+ Record the constraints, tools, scripts, or workflows that matter for this capability.
89
+ `;try{await k.createDirectory(t,h),await k.writeFile(t,p,b,null),await k.writeFile(t,u,y,null),o(),await this.refreshContentIndex(),location.hash=Qt(t,p)}catch{C("Could not create capability")}};r.addEventListener("click",()=>void c()),i.addEventListener("keydown",l=>{l.stopPropagation(),l.key==="Enter"&&c()}),a.appendChild(r),n.append(i,a),i.focus()})}promptRenameDoc(t,e){const n=e.includes("/")?e.slice(0,e.lastIndexOf("/")+1):"",o=e.replace(/\.md$/,"").split("/").pop()??"",i=`doc:${t}:${e}`,a=this.sidebar.links.get(i);a?this.sidebar.startInlineRename(a,o,async r=>{const c=r.replace(/\.md$/,"").replace(/\s+/g,"-").toLowerCase(),l=`${n}${c}.md`;if(l!==e)try{await k.renameFile(t,e,l),await this.refreshContentIndex(),location.hash=J(t,l)}catch{C("Could not rename doc")}}):et("Rename doc",(r,c)=>{const l=document.createElement("input");l.className="board-title",l.value=o,l.style.width="100%",l.style.marginBottom="12px",l.select();const d=f("div","modal-actions"),h=f("button","btn primary");h.textContent="Rename";const p=async()=>{const u=(l.value.trim()||o).replace(/\.md$/,"").replace(/\s+/g,"-").toLowerCase(),g=`${n}${u}.md`;if(g===e){c();return}try{await k.renameFile(t,e,g),c(),await this.refreshContentIndex(),location.hash=J(t,g)}catch{C("Could not rename doc")}};h.addEventListener("click",()=>void p()),l.addEventListener("keydown",u=>{u.stopPropagation(),u.key==="Enter"&&p()}),d.appendChild(h),r.append(l,d),l.focus()})}async moveDoc(t,e,n){const o=$o(n,ve(e));if(o!==e)try{const i=new Set(Tt(await k.getTree(t)).map(c=>rt(c.path))),a=await k.readFileWithRevision(t,e),r=Lo(a.content,e,o,i);await k.renameFile(t,e,o),r!==a.content&&await k.writeFile(t,o,r,a.revision),await this.refreshContentIndex(),location.hash===J(t,e)&&(location.hash=J(t,o)),C(`Moved ${ve(e)}`)}catch{C("Could not move doc")}}async moveBoard(t,e,n){try{const o=await dt.move(t,e,n),i=await this.updateBoardEmbedReferences(t,e,o);await this.refreshContentIndex(),location.hash===lt(t,e)&&(location.hash=lt(t,o)),C(i>0?`Moved ${ve(e)} and updated ${i} embed${i===1?"":"s"}`:`Moved ${ve(e)}`)}catch(o){C(o instanceof Error?o.message:"Could not move board")}}async updateBoardEmbedReferences(t,e,n){if(e===n)return 0;const o=await k.getTree(t),i=ys(o);let a=0;for(const r of i){const c=await k.readFileWithRevision(t,r.path),l=tc(c.content,r.path,e,n);l!==c.content&&(await k.writeFile(t,r.path,l,c.revision),a++)}return a}async moveDirectory(t,e,n){const o=ve(e),i=$o(n,o);if(i!==e)try{const a=await k.getTree(t),r=new Set(Tt(a).map(p=>rt(p.path))),c=Jr(a,e),l=Qr(a,e),d=await Promise.all(l.map(async p=>{const u=await k.readFileWithRevision(t,p.path);return{oldPath:p.path,content:u.content,revision:u.revision}}));await k.renameFile(t,e,i);let h=0;for(const{oldPath:p,content:u,revision:g}of d){const b=`${i}${p.slice(e.length)}`,y=Lo(u,p,b,r);y!==u&&(await k.writeFile(t,b,y,g),h++)}for(const p of c){const u=`${i}${p.slice(e.length)}`;await this.rewriteMovedBoardDocumentId(t,u),h+=await this.updateBoardEmbedReferences(t,p,u)}await this.refreshContentIndex(),this.rewriteRouteAfterDirectoryMove(t,e,i),C(h>0?`Moved ${o} and updated ${h} embed${h===1?"":"s"}`:`Moved ${o}`)}catch{C("Could not move directory")}}promptRenameDirectory(t,e){const n=e.includes("/")?e.slice(0,e.lastIndexOf("/")+1):"",o=e.split("/").pop()??"";et("Rename directory",(i,a)=>{const r=document.createElement("input");r.className="board-title",r.value=o,r.style.width="100%",r.style.marginBottom="12px",r.select();const c=f("div","modal-actions"),l=f("button","btn primary");l.textContent="Rename";const d=async()=>{const h=(r.value.trim()||o).replace(/\s+/g,"-").toLowerCase(),p=`${n}${h}`;if(p===e){a();return}try{await k.renameFile(t,e,p),a(),await this.refreshContentIndex(),C(`Renamed to ${h}`)}catch{C("Could not rename directory")}};l.addEventListener("click",()=>void d()),r.addEventListener("keydown",h=>{h.stopPropagation(),h.key==="Enter"&&d()}),c.appendChild(l),i.append(r,c),r.focus()})}async promptDeleteDirectory(t,e){const n=e.split("/").pop()??e;if(confirm(`Delete "${n}" and all its contents? This cannot be undone.`))try{await k.deleteFile(t,e),await this.refreshContentIndex(),C(`Deleted ${n}`)}catch{C("Could not delete directory")}}async rewriteMovedBoardDocumentId(t,e){const n=await k.getBoardWithRevision(t,e);!n||n.doc.id===e||await k.saveBoard(t,e,{...n.doc,id:e,updatedAt:Date.now()},n.revision)}rewriteRouteAfterDirectoryMove(t,e,n){const o=encodeURIComponent(t),i=`#/root/${o}/docs/`,a=`#/root/${o}/boards/`,r=location.hash;if(r.startsWith(i)){const c=decodeURIComponent(r.slice(i.length));(c===e||c.startsWith(`${e}/`))&&(location.hash=J(t,`${n}${c.slice(e.length)}`))}else if(r.startsWith(a)){const c=decodeURIComponent(r.slice(a.length));(c===e||c.startsWith(`${e}/`))&&(location.hash=lt(t,`${n}${c.slice(e.length)}`))}}async promptDeleteDoc(t,e){const n=e.split("/").pop()??e;et("Delete doc",(o,i)=>{const a=f("p","modal-copy");a.textContent=`Delete "${n}"? This cannot be undone.`;const r=f("div","modal-actions"),c=f("button","btn danger");c.textContent="Delete",c.addEventListener("click",async()=>{try{await k.deleteFile(t,e),i(),await this.refreshContentIndex(),location.hash="#/"}catch{C("Could not delete doc")}});const l=f("button","btn");l.textContent="Cancel",l.addEventListener("click",i),r.append(c,l),o.append(a,r)})}async promptRenameBoard(t,e){const n=await dt.load(t,e);if(!n){C("Board not found");return}et("Rename board",(o,i)=>{const a=document.createElement("input");a.className="board-title",a.value=n.title,a.style.width="100%",a.style.marginBottom="12px",a.select();const r=f("div","modal-actions"),c=f("button","btn primary");c.textContent="Rename";const l=async()=>{const d=At(a.value,"board");if(!d.ok){C(d.message),a.focus();return}try{const h=await dt.rename(t,e,d.raw),p=await this.updateBoardEmbedReferences(t,e,h);i(),await this.refreshContentIndex(),location.hash===lt(t,e)&&(location.hash=lt(t,h)),p>0&&C(`Renamed board and updated ${p} embed${p===1?"":"s"}`)}catch(h){C(h instanceof Error?h.message:"Could not rename board")}};c.addEventListener("click",()=>void l()),a.addEventListener("keydown",d=>{d.stopPropagation(),d.key==="Enter"&&l()}),r.appendChild(c),o.append(a,r),a.focus()})}promptDeleteBoard(t,e){et("Delete board",(n,o)=>{const i=f("p","modal-copy");i.textContent=`Delete "${e}.board.json"? This cannot be undone.`;const a=f("div","modal-actions"),r=f("button","btn danger");r.textContent="Delete",r.addEventListener("click",async()=>{try{await dt.delete(t,e),o(),await this.refreshContentIndex(),location.hash=zt(t)}catch{C("Could not delete board")}});const c=f("button","btn");c.textContent="Cancel",c.addEventListener("click",o),a.append(r,c),n.append(i,a)})}async openEditor(t,e,n){if(!this.docsRootById(t)){this.renderMessage("Docs root unavailable","This docs root is no longer registered. Re-add the project root if needed.");return}this.editor&&this.editingId===`${t}:${e}`||(this.exitEditor(),this.disposeContent(),this.layout.style.display="none",this.editorHost=f("div","board-editor-host"),this.root.appendChild(this.editorHost),this.editingId=`${t}:${e}`,this.editor=new fr(this.editorHost,{boardId:e,loadBoard:async o=>{const i=await k.getBoardWithRevision(t,o);return i||void 0},saveBoard:(o,i)=>k.saveBoard(t,o.id,o,i),deleteBoard:o=>dt.delete(t,o),uploadImage:(o,i)=>dt.uploadImage(t,o,i),cleanupUnusedAssets:o=>dt.cleanupUnusedAssets(t,o),resolveAssetUrl:o=>k.assetUrl(t,o),initialRegion:n,onExit:()=>{this.pendingScrollRestore=this.lastNonBoardScrollTop,location.hash=this.lastNonBoardHash},onDeleted:()=>{location.hash=zt(t)}}))}exitEditor(){this.editor&&(this.editor.destroy(),this.editor=void 0),this.editorHost&&(this.editorHost.remove(),this.editorHost=void 0),this.editingId=void 0,this.applyInitialTheme()}applyInitialTheme(){const t=localStorage.getItem(Co),e=t==="dark"||t==="light"?t:window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";document.documentElement.setAttribute("data-theme",e)}toggleTheme(){var e;const t=we()==="dark"?"light":"dark";document.documentElement.setAttribute("data-theme",t),localStorage.setItem(Co,t),this.updateThemeButton(),(e=this.updateRenderedTheme)==null||e.call(this,t)}createTopbar(){const t=f("div","shell-topbar"),e=f("button","topbar-icon-btn");return e.innerHTML=Q.panelLeft,e.title="Toggle navigation",e.setAttribute("aria-label","Toggle navigation"),e.addEventListener("click",()=>this.setSidebarCollapsed(!this.layout.classList.contains("sidebar-collapsed"))),this.searchBtn=f("button","topbar-search"),this.searchBtn.type="button",this.searchBtn.innerHTML=`${Q.search}<span>Search docs</span><kbd>${this.shortcutLabel()}</kbd>`,this.searchBtn.addEventListener("click",()=>this.openCommandPalette()),this.cartBtn=f("button","topbar-cart"),this.cartBtn.type="button",this.cartBtn.hidden=!0,this.exportBtn=f("button","topbar-icon-btn topbar-export"),this.exportBtn.type="button",this.exportBtn.innerHTML=Q.export,this.exportBtn.title="Export options",this.exportBtn.setAttribute("aria-label","Export options"),this.exportBtn.setAttribute("aria-haspopup","menu"),this.exportBtn.setAttribute("aria-expanded","false"),this.exportBtn.addEventListener("click",()=>{this.toggleExportMenu()}),this.editBtn=f("button","btn topbar-edit"),this.editBtn.type="button",this.editBtn.innerHTML=`${Q.edit}<span>Edit</span>`,this.editBtn.title="Edit this document",this.editBtn.addEventListener("click",()=>{this.currentEditableFile&&this.openDocEditor(this.currentEditableFile)}),this.themeBtn=f("button","topbar-icon-btn topbar-theme"),this.themeBtn.type="button",this.themeBtn.title="Toggle theme",this.themeBtn.setAttribute("aria-label","Toggle theme"),this.themeBtn.addEventListener("click",()=>this.toggleTheme()),this.updateThemeButton(),t.append(e,this.searchBtn,this.exportBtn,this.editBtn,this.themeBtn),t}setSidebarCollapsed(t){this.layout.classList.toggle("sidebar-collapsed",t),localStorage.setItem(ko,String(t))}setupSidebarResize(){this.sidebarResizeHandle&&this.sidebarResizeHandle.addEventListener("pointerdown",t=>{var r;if(this.layout.classList.contains("sidebar-collapsed"))return;t.preventDefault();const e=t.clientX,n=this.readSidebarWidth(),o=t.pointerId;(r=this.sidebarResizeHandle)==null||r.setPointerCapture(o),document.body.classList.add("sidebar-resizing");const i=c=>{const l=fn(n+c.clientX-e);this.applySidebarWidth(l)},a=()=>{var c;(c=this.sidebarResizeHandle)==null||c.releasePointerCapture(o),document.body.classList.remove("sidebar-resizing"),window.removeEventListener("pointermove",i),window.removeEventListener("pointerup",a)};window.addEventListener("pointermove",i),window.addEventListener("pointerup",a)})}readSidebarWidth(){const t=Number(localStorage.getItem(Eo)??270);return fn(t)}applySidebarWidth(t){const e=fn(t);this.layout.style.setProperty("--sidebar-width",`${e}px`),localStorage.setItem(Eo,String(e))}setEditableFile(t){this.currentEditableFile=t,this.editBtn&&(this.exportBtn.hidden=!t,this.exportBtn.disabled=!t,this.editBtn.hidden=!t,this.editBtn.disabled=!t)}promptRemoveProject(t,e){et("Remove from workspace",(n,o)=>{const i=f("p","modal-copy");i.textContent=`Remove "${e}" from the workspace? The files on disk are not deleted.`;const a=f("div","modal-actions"),r=f("button","btn danger");r.textContent="Remove",r.addEventListener("click",async()=>{try{await k.removeProject(t),o(),await this.refreshContentIndex(),location.hash="#/"}catch{C("Could not remove project")}});const c=f("button","btn");c.textContent="Cancel",c.addEventListener("click",o),a.append(r,c),n.append(i,a)})}async addRepoDocs(){var t;try{const e=new Set(this.allDocsRoots().map(h=>h.id)),n=new Set(this.workspace.projects.map(h=>h.id));let o={cancelled:!1};try{o=await k.pickAndAddProject()}catch{const p=window.prompt("Project root path","");if(!p||!p.trim())return;const u=await k.addProject(p.trim());this.workspace=u,o={cancelled:!1,addedProjectId:(t=u.projects.find(g=>!n.has(g.id)))==null?void 0:t.id}}if(o.cancelled)return;await this.refreshContentIndex();let i=o.addedProjectId?this.workspace.projects.find(h=>h.id===o.addedProjectId):void 0,a=i==null?void 0:i.docsRoots[0];if(i&&i.docsRoots.length===0){const h=await this.promptCreateProjectDocsRoot(i.id,i.label);if(!h){location.hash=jt(i.id),C(`Added ${i.label}. Create docs/ later or switch to Raw view from the project menu.`);return}i=this.workspace.projects.find(p=>p.id===(i==null?void 0:i.id)),a=h}const r=this.allDocsRoots(),c=a??r.find(h=>!e.has(h.id));if(!c){C("No docs folders found under that project root.");return}const l=this.treesByRoot.get(c.id)??[],d=gn(re(l));d?location.hash=J(c.id,d):location.hash=zt(c.id),C(`Added ${c.projectLabel}.`)}catch(e){C(e instanceof Error?e.message:"Could not add project root.")}}promptCreateProjectDocsRoot(t,e){return new Promise(n=>{et("Create docs folder",(o,i)=>{let a=!1;const r=u=>{a||(a=!0,i(),n(u))},c=document.createElement("p");c.textContent=`${e} does not have a docs/ folder yet. Create one at the project root now?`;const l=document.createElement("p");l.textContent="You can keep the repo in the workspace and switch to Raw view later if you prefer.";const d=f("div","modal-actions"),h=f("button","btn primary");h.textContent="Create docs/",h.addEventListener("click",()=>{h.disabled=!0,p.disabled=!0,this.ensureProjectDocsRoot(t).then(u=>{if(!u){h.disabled=!1,p.disabled=!1;return}r(u)})});const p=f("button","btn");p.textContent="Maybe later",p.addEventListener("click",()=>r(void 0)),d.append(h,p),o.append(c,l,d)})})}updateTopbarCart(t=!1){this.cartBtn&&(this.cartBtn.hidden=!0)}toggleExportMenu(){var n;if(!this.exportBtn||this.exportBtn.hidden||!this.currentEditableFile)return;if((n=this.exportMenu)!=null&&n.classList.contains("visible")){this.closeExportMenu();return}this.closeCartPopover(),this.closeExportMenu();const t=f("div","topbar-export-menu");t.setAttribute("role","menu"),t.setAttribute("aria-label","Export options");const e=document.createElement("button");e.className="topbar-export-item",e.type="button",e.setAttribute("role","menuitem"),e.innerHTML=`${Q.export}<span>Export to PDF</span>`,e.addEventListener("click",()=>{const o=this.currentEditableFile;this.closeExportMenu(),o&&this.exportDocPdf(o.rootId,o.path)}),t.appendChild(e),this.topbar.appendChild(t),this.exportMenu=t,this.exportBtn.setAttribute("aria-expanded","true"),requestAnimationFrame(()=>e.focus()),t.classList.add("visible")}closeExportMenu(){var t,e;(t=this.exportMenu)==null||t.remove(),this.exportMenu=void 0,(e=this.exportBtn)==null||e.setAttribute("aria-expanded","false")}toggleCartPopover(){this.closeCartPopover()}closeCartPopover(){var t;this.content.classList.remove("cart-popover-open"),(t=this.cartPopover)==null||t.classList.remove("visible")}handleGlobalPointerDown(t){if(!this.exportMenu)return;const e=t.target;e&&(this.exportMenu.contains(e)||this.exportBtn.contains(e)||this.closeExportMenu())}updateThemeButton(){if(!this.themeBtn)return;const t=we()==="dark";this.themeBtn.innerHTML=t?Q.sun:Q.moon,this.themeBtn.title=t?"Switch to light mode":"Switch to dark mode",this.themeBtn.setAttribute("aria-label",this.themeBtn.title)}handleGlobalKeydown(t){if(t.key==="Escape"&&this.closeExportMenu(),(t.metaKey||t.ctrlKey)&&t.key.toLowerCase()==="k"){const e=t.target;if(e!=null&&e.closest(".doc-editor"))return;t.preventDefault(),this.openCommandPalette();return}if(t.key==="F2"){const e=location.hash,n=t.target;if(n!=null&&n.closest(".doc-editor, input, textarea, [contenteditable]"))return;t.preventDefault();const o=e.match(/^#\/root\/([^/]+)\/docs\/(.+)$/);if(o){const r=decodeURIComponent(o[1]),c=decodeURIComponent(o[2]);this.promptRenameDoc(r,c);return}const i=e.match(/^#\/root\/([^/]+)\/boards\/(.+)$/);if(i){const r=decodeURIComponent(i[1]),c=decodeURIComponent(i[2]);this.promptRenameBoard(r,c);return}const a=e.match(/^#\/root\/([^/]+)\/directory\/(.+)$/);if(a){const r=decodeURIComponent(a[1]),c=decodeURIComponent(a[2]);this.promptRenameDirectory(r,c);return}}}allDocsRoots(){return this.workspace.projects.flatMap(t=>t.docsRoots)}docsRootById(t){return this.allDocsRoots().find(e=>e.id===t)}queueContentEvent(t){"actorId"in t&&t.actorId&&t.actorId===Es()||(this.pendingContentEvents.push(t),this.contentEventTimer===null&&(this.contentEventTimer=window.setTimeout(()=>void this.flushContentEvents(),120)))}async flushContentEvents(){this.contentEventTimer=null;const t=this.pendingContentEvents.splice(0);if(t.length===0)return;const e=t.some(a=>a.type==="workspace-changed"),n=t.some(a=>a.type==="stream-open"&&a.reconnecting);(e||n)&&await this.refreshWorkspaceAfterEvent(t);const o=new Map;for(const a of t){if(a.type==="workspace-changed"||a.type==="stream-open")continue;const r=o.get(a.rootId)??[];r.push(a),o.set(a.rootId,r)}await Promise.all([...o].map(([a,r])=>this.refreshChangedRoot(a,r)));const i=[...o].filter(([,a])=>a.some(r=>r.type==="file-changed"&&[r.path,r.oldPath].some(c=>c==null?void 0:c.toLowerCase().endsWith(".md")))).map(([a])=>a);i.length>0&&(e||n||!this.searchIndexReady?this.refreshSearchIndexInBackground(this.allDocsRoots(),this.treesByRoot):this.refreshSearchIndexForRoots(i))}async refreshWorkspaceAfterEvent(t){var n;await this.refreshContentIndex();const e=t.some(o=>o.type==="stream-open"&&o.reconnecting);if(this.editor){const o=(n=this.editingId)==null?void 0:n.split(":",1)[0];(e||!o||!this.docsRootById(o))&&this.editor.markStale();return}if(this.docEditor){(e||!this.currentEditableFile||!this.docsRootById(this.currentEditableFile.rootId))&&this.docEditor.markStale();return}if(this.textFileEditor){(e||!this.currentTextFile||!this.docsRootById(this.currentTextFile.rootId))&&this.textFileEditor.markStale();return}this.route({preserveScroll:!0})}async refreshChangedRoot(t,e){var u,g,b;const n=this.docsRootById(t);if(!n){await this.refreshContentIndex();return}const o=e.filter(y=>y.type==="file-changed"),i=e.filter(y=>y.type==="board-changed"),a=e.filter(y=>y.type==="asset-changed");(o.some(y=>y.action!=="write"||y.created===!0)||i.some(y=>y.action!=="write")||a.length>0)&&await this.refreshRootTree(n);const c=a.length>0,l=(y,x)=>(y==null?void 0:y.rootId)===t&&(y.path===x.path||y.path===x.oldPath),d=o.find(y=>l(this.currentEditableFile,y)),h=o.find(y=>l(this.currentTextFile,y));this.docEditor&&d&&this.docEditor.markStale(),this.textFileEditor&&h&&this.textFileEditor.markStale(),i.find(y=>this.editingId===`${t}:${y.boardId}`)&&((u=this.editor)==null||u.markStale()),c&&((g=this.editingId)!=null&&g.startsWith(`${t}:`))&&((b=this.editor)==null||b.refreshAssets()),this.refreshVisibleRoute(t,e,d,h)}async refreshRootTree(t){const e=(this.rootRefreshRuns.get(t.id)??0)+1;this.rootRefreshRuns.set(t.id,e);const[n,o]=await Promise.all([k.getTree(t.id).catch(()=>null),k.getProjectTree(t.projectId).catch(()=>null)]);e!==this.rootRefreshRuns.get(t.id)||!n||!o||(this.treesByRoot=new Map(this.treesByRoot).set(t.id,n),this.treesByProject=new Map(this.treesByProject).set(t.projectId,o),this.sidebar.refresh(this.workspace,this.treesByRoot,this.treesByProject))}refreshVisibleRoute(t,e,n,o){var I,$;if(this.docEditor||this.textFileEditor||this.editor)return;const i=location.hash,a=`#/root/${encodeURIComponent(t)}/`;if(!i.startsWith(a))return;const r=e.filter(P=>P.type==="file-changed"),c=e.filter(P=>P.type==="board-changed"),l=e.filter(P=>P.type==="asset-changed"),d=!!n||!!o,h=r.some(P=>{var ot;return P.path.startsWith("capabilities/")||((ot=P.oldPath)==null?void 0:ot.startsWith("capabilities/"))}),p=i===Sn(t)&&h,u=i.startsWith(`${a}capabilities/`)&&h,g=i.match(/^#\/root\/[^/]+\/docs\/(.+)$/);let b="";if(g)try{b=decodeURIComponent(g[1])}catch{b=g[1]}const y=!!b&&r.some(P=>P.path===b||P.oldPath===b),x=i.startsWith(`${a}directory/`)&&(r.length>0||c.length>0),v=i===zt(t)&&c.length>0,E=((I=this.currentEditableFile)==null?void 0:I.rootId)===t&&c.length>0,w=l.length>0&&i.startsWith(`${a}docs/`),S=($=this.docsRootById(t))==null?void 0:$.projectId,B=S?`#/project/${encodeURIComponent(S)}`:"",T=!!B&&(i===B||i===`${B}/boards`)&&(r.length>0||c.length>0),M=i==="#/"&&(r.length>0||c.length>0);(d||y||p||u||x||v||E||w||T||M)&&this.route({preserveScroll:!0})}async refreshContentIndex(){try{this.workspace=await k.getWorkspace()}catch{this.workspace={projects:[]},this.treesByRoot=new Map,this.treesByProject=new Map,this.sidebar.refresh(this.workspace,this.treesByRoot),this.searchIndex=[],this.searchIndexing=!1,this.searchIndexReady=!1;return}const t=this.allDocsRoots(),e=await Promise.all(t.map(async o=>{try{return[o.id,await k.getTree(o.id)]}catch{return[o.id,[]]}}));this.treesByRoot=new Map(e);const n=await Promise.all(this.workspace.projects.map(async o=>{try{return[o.id,await k.getProjectTree(o.id)]}catch{return[o.id,[]]}}));this.treesByProject=new Map(n),this.sidebar.refresh(this.workspace,this.treesByRoot,this.treesByProject),this.refreshSearchIndexInBackground(t,this.treesByRoot)}async refreshSearchIndexInBackground(t,e){const n=++this.searchIndexRun;this.searchIndexing=!0;const o=await Promise.all(t.map(i=>this.buildSearchEntriesForRoot(i,e.get(i.id)??[])));n===this.searchIndexRun&&(this.searchIndex=o.flat().filter(i=>i.body||i.title),this.searchIndexing=!1,this.searchIndexReady=!0,this.refreshVisibleSearchResults())}async refreshSearchIndexForRoots(t){const e=t.map(a=>this.docsRootById(a)).filter(a=>!!a);if(e.length===0)return;const n=++this.searchIndexRun;this.searchIndexing=!0;const o=await Promise.all(e.map(a=>this.buildSearchEntriesForRoot(a,this.treesByRoot.get(a.id)??[])));if(n!==this.searchIndexRun)return;const i=new Set(e.map(a=>a.id));this.searchIndex=[...this.searchIndex.filter(a=>!a.rootId||!i.has(a.rootId)),...o.flat()].filter(a=>a.body||a.title),this.searchIndexing=!1,this.searchIndexReady=!0,this.refreshVisibleSearchResults()}async buildSearchEntriesForRoot(t,e){const n=[...ye(e),...Ts(e,"capabilities")].filter(i=>i.type==="file"&&i.name.endsWith(".md")),o=[];for(const i of n){const a="path"in i?i.path:"";let r="";try{r=await k.readFile(t.id,a)}catch{}const{frontmatter:c}=ne(r),l=gs(r),d=c.title??ms(r)??mt(i.name),h=c.summary??fs(l),p=a.startsWith("capabilities/")?"Capability":"Doc",u=a.startsWith("capabilities/")?Qt(t.id,a):J(t.id,a);o.push({title:d,path:`${t.projectLabel}/${t.displayPath}/${a}`,href:u,section:p,summary:h,body:l.map(g=>g.text).join(" "),chunks:l,rootId:t.id})}return o}refreshVisibleSearchResults(){var t,e;this.paletteResults&&((t=this.palette)!=null&&t.classList.contains("visible"))&&this.renderSearchResults(((e=this.paletteInput)==null?void 0:e.value)??"")}openCommandPalette(){var t;this.palette||this.createCommandPalette(),(t=this.palette)==null||t.classList.add("visible"),document.body.style.overflow="hidden",this.paletteInput.value="",this.renderSearchResults(""),requestAnimationFrame(()=>{var e;return(e=this.paletteInput)==null?void 0:e.focus()})}closeCommandPalette(){var t;(t=this.palette)==null||t.classList.remove("visible"),document.body.style.overflow=""}createCommandPalette(){this.palette=f("div","command-palette");const t=f("div","command-panel"),e=f("div","command-search");e.innerHTML=Q.search,this.paletteInput=document.createElement("input"),this.paletteInput.type="search",this.paletteInput.placeholder="Search docs",this.paletteInput.setAttribute("aria-label","Search docs"),e.appendChild(this.paletteInput),this.paletteResults=f("div","command-results"),t.append(e,this.paletteResults),this.palette.appendChild(t),document.body.appendChild(this.palette),this.palette.addEventListener("mousedown",n=>{n.target===this.palette&&this.closeCommandPalette()}),this.paletteInput.addEventListener("input",()=>this.renderSearchResults(this.paletteInput.value)),this.paletteInput.addEventListener("keydown",n=>this.handlePaletteKeydown(n))}handlePaletteKeydown(t){var i,a,r,c,l;if(t.key==="Escape"){t.preventDefault(),this.closeCommandPalette();return}const e=[...((i=this.paletteResults)==null?void 0:i.querySelectorAll(".command-result"))??[]],n=(a=this.paletteResults)==null?void 0:a.querySelector(".command-result.active"),o=n?e.indexOf(n):-1;if(t.key==="ArrowDown"||t.key==="ArrowUp"){t.preventDefault();const d=t.key==="ArrowDown"?Math.min(o+1,e.length-1):Math.max(o-1,0);e.forEach(h=>h.classList.remove("active")),(r=e[d])==null||r.classList.add("active"),(c=e[d])==null||c.scrollIntoView({block:"nearest"})}t.key==="Enter"&&(t.preventDefault(),(l=n??e[0])==null||l.click())}renderSearchResults(t){if(!this.paletteResults)return;const e=Kr(t),n=this.rankSearch(e).slice(0,8);if(this.paletteResults.replaceChildren(),n.length===0){const o=f("div","command-empty");o.textContent=this.searchIndex.length?"No matching docs.":this.searchIndexing?"Indexing docs...":"No docs indexed yet.",this.paletteResults.appendChild(o);return}for(const[o,i]of n.entries()){const{entry:a}=i,r=document.createElement("a");r.className="command-result",o===0&&r.classList.add("active"),r.href=a.href,r.addEventListener("click",()=>this.closeCommandPalette());const c=f("div","command-result-title");Ro(c,a.title,e);const l=f("div","command-result-meta");l.textContent=[a.section,i.heading,a.path].filter(Boolean).join(" · ");const d=f("div","command-result-summary");Ro(d,i.preview,e),r.append(c,l),d.textContent&&r.appendChild(d),this.paletteResults.appendChild(r)}}rankSearch(t){if(t.length===0)return this.searchIndex.map(o=>({entry:o,score:0,heading:"",preview:o.summary||o.body.slice(0,220)}));const e=t.map(xt).filter(Boolean),n=xt(t.join(" "));return this.searchIndex.map(o=>{const i=xt(o.title),a=xt(o.path),r=xt(o.summary);let c=be(i,e,n,10);c+=be(a,e,n,4),c+=be(r,e,n,3);let l,d=0;for(const p of o.chunks){const u=be(xt(p.heading),e,n,5),g=be(p.normalized,e,n,p.kind==="heading"?8:2),b=u+g;b>d&&(d=b,l=p)}const h=c+d;return{entry:o,score:h,heading:l!=null&&l.heading&&l.heading!==o.title?l.heading:"",preview:l?oc(l.text,e):o.summary}}).filter(o=>o.score>0).sort((o,i)=>i.score-o.score||o.entry.title.localeCompare(i.entry.title))}shortcutLabel(){return/Mac|iPhone|iPad/.test(navigator.platform)?"⌘K":"Ctrl K"}disposeContent(){this.cleanup&&(this.cleanup(),this.cleanup=void 0),this.updateRenderedTheme=void 0,this.content.classList.remove("content-wide"),this.content.replaceChildren()}renderMessage(t,e){this.disposeContent();const n=f("div","page"),o=f("h1","");o.textContent=t;const i=f("p","page-lead");i.textContent=e,n.append(o,i),this.content.replaceChildren(n)}}function je(s,t,e={}){const n=[{label:"Home",href:"#/"}];let o;for(const c of s.projects){const l=c.docsRoots.find(d=>d.id===t);if(l){n.push({label:c.label,href:jt(c.id)}),o=l;break}}if(o){const c=o.displayPath.split("/").filter(Boolean);for(let l=0;l<c.length;l++){const d=c.slice(0,l+1).join("/");n.push({label:c[l],href:Ze(t,d)})}}const a=(e.filePath??e.dirPath??"").split("/").filter(Boolean),r=e.filePath?a.slice(0,-1):a;for(let c=0;c<r.length;c++){const l=r.slice(0,c+1).join("/");n.push({label:mt(r[c]),href:Ze(t,l)})}if(e.currentLabel)n.push({label:e.currentLabel});else if(e.filePath){const c=a[a.length-1];n.push({label:c==="index.md"?"Overview":mt(c)})}return n}function St(s){const t=f("nav","breadcrumb");t.setAttribute("aria-label","Breadcrumb");for(let e=0;e<s.length;e++){const n=s[e],o=e===s.length-1;if(!o&&n.href){const i=document.createElement("a");i.className="breadcrumb-link",i.href=n.href,i.textContent=n.label,t.appendChild(i)}else{const i=f("span","breadcrumb-current");i.textContent=n.label,t.appendChild(i)}if(!o){const i=f("span","breadcrumb-sep");i.textContent="/",i.setAttribute("aria-hidden","true"),t.appendChild(i)}}return t}function f(s,t){const e=document.createElement(s);return t&&(e.className=t),e}function Jt(s){const t=f("div","empty-note");return t.textContent=s,t}function So(s,t,e,n){var o;return{path:`${s}:${t.branchPath}`,rootId:s,branchPath:t.branchPath,entryPath:t.entryPath,displayPath:t.routePath,title:n.title??ms(e)??Ge(t.entryPath),summary:n.summary??fs(gs(e)),kind:((o=n.kind)==null?void 0:o.trim())||void 0,tags:n.tags?n.tags.split(",").map(i=>i.trim()).filter(Boolean):[],md:e}}function He(s,t){const e=[];function n(a){const c=[...re(a)].sort((l,d)=>{const h=l.type==="file"&&l.name==="index.md"?-1:0,p=d.type==="file"&&d.name==="index.md"?-1:0;return h!==p?h-p:l.type!==d.type?l.type==="dir"?-1:1:l.name.localeCompare(d.name)});for(const l of c)if(l.type==="file"){const d=l.name==="index.md"?"Overview":mt(l.name);e.push({label:d,href:J(s,l.path)})}else n(l.children)}n(t);const o=Tt(t).sort((a,r)=>a.path.localeCompare(r.path));if(o.length>0){e.push({label:"All Boards",href:zt(s)});for(const a of o){const r=rt(a.path);e.push({label:mt(r.split("/").pop()??r),href:lt(s,r)})}}const i=_t(t);if(i.length>0){e.push({label:"All Capabilities",href:Sn(s)});for(const a of i)e.push({label:Ge(a.entryPath),href:Qt(s,a.entryPath)})}return e}function We(s,t){const e=s.findIndex(a=>a.href===t);if(e===-1)return null;const n=e>0?s[e-1]:null,o=e<s.length-1?s[e+1]:null;if(!n&&!o)return null;const i=f("nav","page-nav");if(n){const a=f("a","page-nav-prev");a.href=n.href,a.innerHTML=`<span class="page-nav-arrow">←</span><span class="page-nav-label">${n.label}</span>`,i.appendChild(a)}else i.appendChild(f("span","page-nav-spacer"));if(o){const a=f("a","page-nav-next");a.href=o.href,a.innerHTML=`<span class="page-nav-label">${o.label}</span><span class="page-nav-arrow">→</span>`,i.appendChild(a)}return i}function Sn(s){return`#/root/${encodeURIComponent(s)}/capabilities`}function re(s){return s.filter(t=>t.type==="file"?t.name.endsWith(".md"):t.name==="capabilities"||t.name==="assets"?!1:re(t.children).length>0).map(t=>t.type==="file"?t:{...t,children:re(t.children)})}function ye(s){const t=[],e=n=>{for(const o of re(n))o.type==="file"?t.push(o):e(o.children)};return e(s),t}function J(s,t){return`#/root/${encodeURIComponent(s)}/docs/${encodeURIComponent(t)}`}function Qt(s,t){return`#/root/${encodeURIComponent(s)}/capabilities/${encodeURIComponent(ce(t))}`}function _t(s){const t=s.find(o=>o.type==="dir"&&o.name==="capabilities");if(!t||t.type!=="dir")return[];const e=[],n=o=>{for(const i of o){if(i.type==="file"){i.path.startsWith("capabilities/")&&i.name.endsWith(".md")&&!i.path.slice(13).includes("/")&&e.push({branchPath:i.path,entryPath:i.path,routePath:ce(i.path)});continue}const a=Vr(i);a&&e.push({branchPath:i.path,entryPath:a.path,routePath:ce(i.path)}),n(i.children)}};return n(t.children),e.sort((o,i)=>o.branchPath.localeCompare(i.branchPath))}function Wr(s,t){const e=t.replace(/^\/+|\/+$/g,""),n=e.startsWith("capabilities/")?e:`capabilities/${e}`;if(n.endsWith(".md"))return n;const o=_t(s).find(i=>i.branchPath===n||i.routePath===e);return(o==null?void 0:o.entryPath)??null}function To(s,t){const e=t.replace(/^\/+|\/+$/g,""),n=e.startsWith("capabilities/")?e:`capabilities/${e}`,o=_t(s).find(i=>i.branchPath===n||i.entryPath===n||i.routePath===e);return o||(_t(s).filter(i=>n.startsWith(`${i.branchPath}/`)).sort((i,a)=>a.branchPath.length-i.branchPath.length)[0]??null)}function Ge(s){if(s.endsWith("/index.md")){const t=s.slice(0,-9);return mt(t.split("/").pop()??t)}return mt(s.split("/").pop()??s)}function ce(s){const t=s.replace(/^capabilities\//,"");return t.endsWith("/index.md")?t.slice(0,-9):t}function Or(s){return{branchPath:Ur(s),entryPath:s,routePath:ce(s)}}function Ur(s){return s.endsWith("/index.md")?s.slice(0,-9):s}function Bo(s,t){const e=ps(s,t);return e?e.type==="file"?[e]:us(e.children).sort(Yr):[]}function Oe(s){return ce(s)||"index.md"}function _r(s){return s.endsWith(".md")?null:`${s}/llms.txt`}function Xr(s){return/\.(md|txt|json|ya?ml|js|ts|mjs|cjs|sh|css|html)$/i.test(s)}function ps(s,t){for(const e of s){if(e.path===t)return e;if(e.type==="dir"){const n=ps(e.children,t);if(n)return n}}return null}function us(s){const t=[];for(const e of s)e.type==="file"?t.push(e):t.push(...us(e.children));return t}function Yr(s,t){const e=Mo(s.path),n=Mo(t.path);if(e!==n)return e.localeCompare(n);const o=Io(s.name),i=Io(t.name);return o!==i?o?-1:1:s.path.localeCompare(t.path)}function Mo(s){const t=s.lastIndexOf("/");return t===-1?"":s.slice(0,t)}function Io(s){return/^readme\.(md|txt)$/i.test(s)}function Vr(s){const t=s.children.find(e=>e.type==="file"&&e.name==="index.md");return t||(s.children.find(e=>e.type==="file"&&e.name.endsWith(".md"))??null)}function zt(s){return`#/root/${encodeURIComponent(s)}/boards`}function lt(s,t){return`#/root/${encodeURIComponent(s)}/boards/${encodeURIComponent(t)}`}function jt(s){return`#/project/${encodeURIComponent(s)}`}function Ze(s,t){return`#/root/${encodeURIComponent(s)}/directory/${encodeURIComponent(t)}`}function qr(s){const t=s.match(/^#\/root\/([^/]+)/);return t?decodeURIComponent(t[1]):null}function ms(s){var t,e;return((e=(t=s.match(/^#\s+(.+)$/m))==null?void 0:t[1])==null?void 0:e.trim())??null}function Kr(s){return[...new Set(s.trim().split(/\s+/).map(xt).filter(Boolean))]}function Ro(s,t,e){const n=e.filter(Boolean).sort((a,r)=>r.length-a.length);if(n.length===0){s.textContent=t;return}const o=new RegExp(`(${n.map(Gr).join("|")})`,"ig");let i=0;for(const a of t.matchAll(o)){const r=a.index??0;r>i&&s.appendChild(document.createTextNode(t.slice(i,r)));const c=document.createElement("mark");c.textContent=a[0],s.appendChild(c),i=r+a[0].length}i<t.length&&s.appendChild(document.createTextNode(t.slice(i)))}function Gr(s){return s.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function fs(s){var t;return((t=s.find(e=>e.kind==="text"&&e.text.length>0))==null?void 0:t.text.slice(0,180))??""}function gs(s){const e=s.replace(/^---[\s\S]*?---\s*/,"").split(`
90
+ `),n=[];let o="",i=[];const a=(c,l="text",d=o)=>{const h=Po(c);h&&n.push({heading:d,text:h,normalized:xt(h),kind:l})},r=()=>{i.length!==0&&(a(i.join(" "),"text"),i=[])};for(let c=0;c<e.length;c++){const l=e[c],d=l.match(/^(`{3,})\s*([\w-]+)?\s*$/);if(d){r();const u=d[1].length,g=(d[2]??"").toLowerCase(),b=new RegExp("^`{"+u+",}\\s*$"),y=[];for(c++;c<e.length&&!b.test(e[c]);)y.push(e[c]),c++;a(g==="board"?Zr(y.join(`
91
+ `)):y.join(`
92
+ `),g==="board"?"board":"code");continue}const h=l.match(/^(#{1,6})\s+(.+)$/);if(h){r(),o=Po(h[2]),a(o,"heading",o);continue}if(l.trim()===""||/^(-{3,}|\*{3,}|_{3,})\s*$/.test(l)){r();continue}if(sc(l))continue;const p=l.replace(/^>\s?/,"").replace(/^\s*([-*+]|\d+\.)\s+/,"").replace(/^\[([ xX])\]\s+/,"").replace(/\|/g," ");i.push(p)}return r(),n}function Zr(s){return s.split(`
93
+ `).map(t=>t.replace(/#.*$/,"").trim()).filter(Boolean).map(t=>t.replace(/^(\w+)\s*:\s*/,"$1 ")).join(" ")}function ys(s){const t=[],e=n=>{for(const o of n)o.type==="file"?o.name.endsWith(".md")&&t.push(o):e(o.children)};return e(s),t}function Tt(s){const t=[],e=n=>{for(const o of n)o.type==="file"?o.name.endsWith(".board.json")&&t.push(o):e(o.children)};return e(s),t}function Jr(s,t){const e=t.replace(/^\/+|\/+$/g,"");return Tt(s).map(n=>rt(n.path)).filter(n=>n===e||n.startsWith(`${e}/`))}function Qr(s,t){const e=t.replace(/^\/+|\/+$/g,"");return ys(s).filter(n=>n.path.startsWith(`${e}/`))}function Lo(s,t,e,n){if(t===e)return s;const o=s.split(`
94
+ `);let i=!1,a,r=!1;const c=o.map(l=>{if(!i){const u=l.match(/^(`{3,})\s*board\s*$/i);return u&&(i=!0,a=new RegExp("^`{"+u[1].length+",}\\s*$")),l}if(a!=null&&a.test(l))return i=!1,a=void 0,l;const d=l.match(/^(\s*src\s*:\s*)(.*)$/i);if(!d)return l;const h=bs(d[2]);if(!h.value)return l;const p=nc(h.value,t,e,n);return p===h.value?l:(r=!0,`${d[1]}${p}${h.suffix}`)});return r?c.join(`
95
+ `):s}function tc(s,t,e,n){const o=s.split(`
96
+ `);let i=!1,a,r=!1;const c=o.map(l=>{if(!i){const u=l.match(/^(`{3,})\s*board\s*$/i);return u&&(i=!0,a=new RegExp("^`{"+u[1].length+",}\\s*$")),l}if(a!=null&&a.test(l))return i=!1,a=void 0,l;const d=l.match(/^(\s*src\s*:\s*)(.*)$/i);if(!d)return l;const h=bs(d[2]);return!h.value||!Te(h.value,t).includes(e)?l:(r=!0,`${d[1]}${ec(h.value,t,e,n)}${h.suffix}`)});return r?c.join(`
97
+ `):s}function bs(s){var i;const t=s.indexOf("#"),e=t===-1?s:s.slice(0,t),n=t===-1?"":s.slice(t),o=((i=e.match(/\s*$/))==null?void 0:i[0])??"";return{value:e.trim(),suffix:`${o}${n}`}}function ec(s,t,e,n){const o=s.trim(),i=o.startsWith("/"),a=o.startsWith("./")||o.startsWith("../"),r=o.endsWith(".board.json"),c=Te(o,t),l=!a&&c[0]!==e&&c.includes(e);if(i){const h=`/${n}`;return r&&!h.endsWith(".board.json")?`${h}.board.json`:h}let d=a||l?vs(Tn(t,n)):n;return r&&!d.endsWith(".board.json")&&(d=`${d}.board.json`),d}function nc(s,t,e,n){const o=s.trim(),i=o.startsWith("./")||o.startsWith("../"),a=Te(o,t),r=a[0]??"",c=a.find(p=>p!==r&&n.has(p));if(!i&&(!c||n.has(r)))return s;const l=o.endsWith(".board.json"),d=i?Ps(o,t):c;if(!d)return s;let h=vs(Tn(e,d));return l&&!h.endsWith(".board.json")&&(h=`${h}.board.json`),h}function vs(s){return!s||s.startsWith("./")||s.startsWith("../")?s:`./${s}`}function Po(s){return s.replace(/!\[([^\]]*)\]\(([^)]+)\)/g,"$1 $2").replace(/\[([^\]]+)\]\(([^)]+)\)/g,"$1 $2").replace(/`([^`]+)`/g,"$1").replace(/~~([\s\S]*?)~~/g,"$1").replace(/\*\*\*([\s\S]*?)\*\*\*/g,"$1").replace(/___([\s\S]*?)___/g,"$1").replace(/\*\*([\s\S]*?)\*\*/g,"$1").replace(/__([\s\S]*?)__/g,"$1").replace(/(^|[\s([{])\*([^*\s][\s\S]*?[^*\s])\*(?=$|[\s)\]},.!?:;])/g,"$1$2").replace(/(^|[\s([{])_([^_\s][\s\S]*?[^_\s])_(?=$|[\s)\]},.!?:;])/g,"$1$2").replace(/\\([\\`*_[\]{}()#+\-.!|>])/g,"$1").replace(/<[^>]+>/g," ").replace(/&nbsp;/g," ").replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/(^|[\s([{])[*_]{1,3}(?=\S)/g,"$1").replace(new RegExp("(?<=\\S)[*_]{1,3}(?=$|[\\s)\\]},.!?:;])","g"),"").replace(/\s+/g," ").trim()}function xt(s){return s.normalize("NFKD").replace(/[\u0300-\u036f]/g,"").toLowerCase().replace(/[^a-z0-9]+/g," ").trim()}function be(s,t,e,n){if(!s)return 0;let o=e&&s.includes(e)?n*4:0;for(const i of t)s===i&&(o+=n*5),s.startsWith(i)&&(o+=n*3),s.includes(i)&&(o+=n);return o}function oc(s,t){if(t.length===0)return s.slice(0,220);const e=xt(s),n=t.map(l=>e.indexOf(l)).filter(l=>l>=0).sort((l,d)=>l-d)[0];if(n===void 0)return s.slice(0,220);const o=e.length===0?0:n/e.length,i=Math.round(s.length*o),a=Math.max(0,i-90),r=Math.min(s.length,i+170),c=s.slice(a,r).trim();return`${a>0?"... ":""}${c}${r<s.length?" ...":""}`}function sc(s){return/^\s*\|?\s*:?-{1,}:?\s*(\|\s*:?-{1,}:?\s*)*\|?\s*$/.test(s)}function mt(s){const t=s.replace(/\.md$/,"").replace(/[-_]/g," ");return t.charAt(0).toUpperCase()+t.slice(1)}function ic(s){return s.trim().replace(/[\\/]+/g,"-").replace(/\s+/g,"-").replace(/[^a-z0-9-_]/gi,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").toLowerCase()}const ac=new Set([".","..","assets","boards","capabilities","docs"]);function At(s,t){const e=t==="doc"?"doc":t,n=s.trim();if(!n)return{ok:!1,message:`Enter a ${e} name.`};if(n.length>80)return{ok:!1,message:"Name must be 80 characters or fewer."};if(/[\\/]/.test(n))return{ok:!1,message:"Name cannot contain slashes."};if(/^\.+$/.test(n))return{ok:!1,message:"Name cannot contain only dots."};if(n.startsWith("."))return{ok:!1,message:"Name cannot start with a dot."};if(/[<>:"|?*\x00-\x1F]/.test(n))return{ok:!1,message:"Name contains characters that are not allowed in files."};const o=ic(n);return o?o.length>64?{ok:!1,message:"Name is too long after formatting."}:ac.has(o)?{ok:!1,message:`"${o}" is reserved by the workspace.`}:/[a-z0-9]/.test(o)?{ok:!0,raw:n,slug:o}:{ok:!1,message:"Name must include letters or numbers."}:{ok:!1,message:"Name must include letters or numbers."}}function ve(s){const t=s.replace(/^\/+|\/+$/g,"");return t.split("/").pop()??t}function $o(s,t){const e=s.replace(/^\/+|\/+$/g,""),n=t.replace(/^\/+|\/+$/g,"");return e?`${e}/${n}`:n}function rc(s){if(!s)return;const t=new URLSearchParams(s).get("region");if(!t)return;const e=t.split(",").map(n=>Number(n.trim()));if(!(e.length!==4||e.some(n=>!Number.isFinite(n))||e[2]<=0||e[3]<=0))return[e[0],e[1],e[2],e[3]]}function fn(s){return Math.max(zr,Math.min(jr,s))}async function cc(s){const t=s.boardId.trim().replace(/^\/+/,"").replace(/\.board\.json$/i,"");if(!t)throw new Error("A boardId is required.");const e=await k.getBoard(s.rootId,t),n=oe(e);if(!n)throw new Error("Board not found or invalid.");const o=new ns;o.boardId=n.id,o.title=n.title,o.theme=n.theme,o.createdAt=n.createdAt,o.viewport={...n.viewport};for(const c of n.elements)o.addElement(c);o.invalidateSort();const i=s.padding??48;let a;if(s.region){const[c,l,d,h]=s.region,p=s.padding??0;a={x:c-p,y:l-p,w:d+p*2,h:h+p*2}}else a=os(o,i);if(!a)throw new Error("Board has no visible content. Provide an explicit region to export.");const r=new Mn(ut,()=>{},c=>k.assetUrl(s.rootId,c));try{return await is(o,r,a,s.format,{scale:s.scale??2,quality:s.quality,paper:s.paper})}finally{r.clear()}}window.__viteboardPreparePdf=Ii;window.__viteboardPrepareBoardExport=cc;const ws=document.getElementById("app");if(!ws)throw new Error("Missing #app root element");new Hr(ws);