llmd 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/client.js +3 -30
  2. package/dist/llmd +263 -326
  3. package/package.json +4 -6
package/dist/client.js CHANGED
@@ -1,4 +1,4 @@
1
- var G=()=>{let C=document.querySelector(".admin-section"),q=document.querySelector(".admin-header");if(!(C&&q))return;if(localStorage.getItem("llmd-admin-collapsed")==="true")C.classList.add("collapsed");q.addEventListener("click",()=>{let J=C.classList.toggle("collapsed");localStorage.setItem("llmd-admin-collapsed",J.toString())})};var W=(C)=>{return C.getAttribute("data-dir-path")||null},H=()=>{let C=[],q=document.querySelectorAll(".dir-group.collapsed");for(let j of Array.from(q)){let J=W(j);if(J)C.push(J)}localStorage.setItem("llmd-nav-collapsed",JSON.stringify(C))},O=()=>{try{let C=localStorage.getItem("llmd-nav-collapsed");if(!C)return;let q=JSON.parse(C),j=document.querySelectorAll(".dir-group");for(let J of Array.from(j)){let K=W(J);if(K&&q.includes(K))J.classList.add("collapsed")}}catch(C){console.error("[collapsible] Failed to restore state:",C)}},v=()=>{let C=document.querySelectorAll(".dir-group-header");for(let q of Array.from(C)){let j=q;j.addEventListener("click",(J)=>{J.preventDefault();let K=j.closest(".dir-group");if(K)K.classList.toggle("collapsed"),H()})}O()},P=()=>{let C=document.querySelector(".toc");if(!C)return;let q=C.querySelector("h3");if(!q)return;let j=document.createElement("span");j.className="toc-chevron",j.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>',q.style.cursor="pointer",q.insertBefore(j,q.firstChild),q.addEventListener("click",()=>{C.classList.toggle("collapsed")})},E=()=>{v(),P()};var A=()=>{for(let C of Array.from(document.querySelectorAll("pre code"))){let q=C.parentElement;if(!q)continue;if(q.querySelector(".copy-button"))continue;let j=document.createElement("button");j.className="copy-button",j.textContent="Copy",j.setAttribute("aria-label","Copy code to clipboard"),j.addEventListener("click",async()=>{try{await navigator.clipboard.writeText(C.textContent||""),j.textContent="Copied!",j.classList.add("copied"),setTimeout(()=>{j.textContent="Copy",j.classList.remove("copied")},2000)}catch(J){console.error("Failed to copy:",J),j.textContent="Failed",setTimeout(()=>{j.textContent="Copy"},2000)}}),q.appendChild(j)}};if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",A);else A();var x=(C)=>{let j=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/_ws`,J=null,K=null,Q=()=>{J=new WebSocket(j),J.addEventListener("open",()=>{console.log("[llmd] Connected to file watcher"),J?.send(JSON.stringify({type:"watch",file:C}))}),J.addEventListener("message",(Z)=>{try{let _=JSON.parse(Z.data);if(_.type==="reload"&&_.file===C)console.log(`[llmd] File changed: ${C}, reloading...`),window.location.reload()}catch(_){console.error("[llmd] Failed to parse message:",_)}}),J.addEventListener("close",()=>{console.log("[llmd] Disconnected from file watcher"),K=window.setTimeout(()=>{console.log("[llmd] Reconnecting..."),Q()},2000)}),J.addEventListener("error",(Z)=>{console.error("[llmd] WebSocket error:",Z),J?.close()})};Q(),window.addEventListener("beforeunload",()=>{if(K)clearTimeout(K);J?.close()})};window.connectFileWatcher=x;var z=(C,q="smooth")=>{let j=document.querySelectorAll(`mark.llmd-highlight[data-highlight-id="${C}"]`);if(j.length===0)return!1;let J=j[0];if(!J)return!1;J.scrollIntoView({behavior:q,block:"center"});for(let K of Array.from(j))K.classList.add("highlight-flash"),setTimeout(()=>{K.classList.remove("highlight-flash")},1000);return!0};var R=[],V=null,D=null,y=new Map,S=()=>{if(!document.querySelector(".content"))return;f(),document.addEventListener("mouseup",N),document.addEventListener("touchend",N),k()},k=()=>{let C=window.location.hash;if(!C.startsWith("#highlight-"))return;let q=C.slice(11);if(!q)return;setTimeout(()=>{if(!z(q,"smooth"))console.warn(`[highlights] Could not find highlight with ID: ${q}`)},100)},f=async()=>{try{let C=window.location.pathname.replace("/view/",""),q=await fetch(`/api/highlights/resource?path=${encodeURIComponent(C)}`);if(!q.ok)return;R=(await q.json()).highlights||[],m()}catch(C){console.error("[highlights] Failed to fetch highlights:",C)}},m=()=>{let C=document.querySelector(".content");if(!C)return;let q=C.querySelectorAll("mark.llmd-highlight");for(let j of Array.from(q)){let J=j.getAttribute("data-highlight-id");if(!J)continue;let K=R.find((Q)=>Q.id===J);if(!K)continue;j.addEventListener("click",(Q)=>{Q.stopPropagation(),c(K,Q)})}},N=(C)=>{let q=C.target;if(V?.contains(q))return;let j=window.getSelection();if(!j||j.isCollapsed){B();return}let J=j.toString().trim();if(!J){B();return}let K=document.querySelector(".content");if(!K)return;let Q=j.getRangeAt(0),Z=(L)=>{let U=L.nodeType===Node.TEXT_NODE?L.parentElement:L;while(U&&U!==K){let F=U.tagName?.toLowerCase();if(F&&["p","h1","h2","h3","h4","h5","h6","li","blockquote","pre"].includes(F))return U;U=U.parentElement}return null},_=Z(Q.startContainer),$=Z(Q.endContainer);if(_!==$){B();return}let Y=Q.commonAncestorContainer,X=Y.nodeType===Node.TEXT_NODE?Y.parentElement:Y;if(!(X&&K.contains(X))){B();return}D={text:J,range:Q.cloneRange()},u(C)},u=(C)=>{if(!V)V=p(),document.body.appendChild(V);let{pageX:q,pageY:j}=C;V.style.left=`${q}px`,V.style.top=`${j-50}px`,V.style.display="block"},B=()=>{if(V)V.style.display="none";D=null},c=(C,q)=>{let j=y.get(C.id);if(j){j.remove(),y.delete(C.id);return}let J=document.createElement("div");J.className="highlight-notes-popup",J.style.cssText=`
1
+ var N=()=>{let C=document.querySelector(".admin-section"),q=document.querySelector(".admin-header");if(!(C&&q))return;if(localStorage.getItem("llmd-admin-collapsed")==="true")C.classList.add("collapsed");q.addEventListener("click",()=>{let L=C.classList.toggle("collapsed");localStorage.setItem("llmd-admin-collapsed",L.toString())})};var G=(C)=>{return C.getAttribute("data-dir-path")||null},v=()=>{let C=[],q=document.querySelectorAll(".dir-group.collapsed");for(let M of Array.from(q)){let L=G(M);if(L)C.push(L)}localStorage.setItem("llmd-nav-collapsed",JSON.stringify(C))},w=()=>{try{let C=localStorage.getItem("llmd-nav-collapsed");if(!C)return;let q=JSON.parse(C),M=document.querySelectorAll(".dir-group");for(let L of Array.from(M)){let j=G(L);if(j&&q.includes(j))L.classList.add("collapsed")}}catch(C){console.error("[collapsible] Failed to restore state:",C)}},x=()=>{let C=document.querySelectorAll(".dir-group-header");for(let q of Array.from(C)){let M=q;M.addEventListener("click",(L)=>{L.preventDefault();let j=M.closest(".dir-group");if(j)j.classList.toggle("collapsed"),v()})}w()},m=()=>{let C=document.querySelector(".toc");if(!C)return;let q=C.querySelector("h3");if(!q)return;let M=document.createElement("span");M.className="toc-chevron",M.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>',q.style.cursor="pointer",q.insertBefore(M,q.firstChild),q.addEventListener("click",()=>{C.classList.toggle("collapsed")})},W=()=>{x(),m()};var B=()=>{for(let C of Array.from(document.querySelectorAll("pre code"))){let q=C.parentElement;if(!q)continue;if(q.querySelector(".copy-button"))continue;let M=document.createElement("button");M.className="copy-button",M.textContent="Copy",M.setAttribute("aria-label","Copy code to clipboard"),M.addEventListener("click",async()=>{try{await navigator.clipboard.writeText(C.textContent||""),M.textContent="Copied!",M.classList.add("copied"),setTimeout(()=>{M.textContent="Copy",M.classList.remove("copied")},2000)}catch(L){console.error("Failed to copy:",L),M.textContent="Failed",setTimeout(()=>{M.textContent="Copy"},2000)}}),q.appendChild(M)}};if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",B);else B();var F=(C,q,M)=>{fetch("/api/events",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:C,path:q,resourceType:M})}).catch(()=>{})},S=(C)=>{F("open",C,"dir")},b=(C)=>{F("view",C,"file")};var P=(C)=>{let M=`${window.location.protocol==="https:"?"wss:":"ws:"}//${window.location.host}/_ws`,L=null,j=null,$=0,J=!1,Q=()=>{L=new WebSocket(M),L.addEventListener("open",()=>{$=0,console.log("[llmd] Connected to file watcher"),L?.send(JSON.stringify({type:"watch",file:C}))}),L.addEventListener("message",(V)=>{try{let K=JSON.parse(V.data);if(K.type==="reload"&&K.file===C)console.log(`[llmd] File changed: ${C}, reloading...`),window.location.reload()}catch(K){console.error("[llmd] Failed to parse message:",K)}}),L.addEventListener("close",()=>{if(J)return;let V=Math.min(30000,1000*2**$);$+=1,j=window.setTimeout(Q,V)}),L.addEventListener("error",()=>{console.error("[llmd] WebSocket error")})};Q(),window.addEventListener("beforeunload",()=>{if(J=!0,j)clearTimeout(j);L?.close()})},f=()=>{let C=document.body?.dataset.watchFile;if(C)P(C)};var A=(C,q="smooth")=>{let M=document.querySelectorAll(`mark.llmd-highlight[data-highlight-id="${C}"]`),L=M[0];if(!L)return!1;L.scrollIntoView({behavior:q,block:"center"});for(let j of Array.from(M))j.classList.add("highlight-flash"),setTimeout(()=>{j.classList.remove("highlight-flash")},1000);return!0};var R=[],Y=null,U=null,D=new Map,E=(C)=>{let q=D.get(C);if(!q)return;q.el.remove(),document.removeEventListener("click",q.onOutsideClick),D.delete(C)},T=()=>{if(!document.querySelector(".content"))return;d(),document.addEventListener("mouseup",k),document.addEventListener("touchend",k),u()},u=()=>{let C=window.location.hash;if(!C.startsWith("#highlight-"))return;let q=C.slice(11);if(!q)return;setTimeout(()=>{if(!A(q,"smooth"))console.warn(`[highlights] Could not find highlight with ID: ${q}`)},100)},d=async()=>{try{let C=window.location.pathname.replace("/view/",""),q=await fetch(`/api/highlights/resource?path=${encodeURIComponent(C)}`);if(!q.ok)return;R=(await q.json()).highlights||[],g()}catch(C){console.error("[highlights] Failed to fetch highlights:",C)}},g=()=>{let C=document.querySelector(".content");if(!C)return;let q=C.querySelectorAll("mark.llmd-highlight");for(let M of Array.from(q)){let L=M.getAttribute("data-highlight-id");if(!L)continue;let j=R.find(($)=>$.id===L);if(!j)continue;M.addEventListener("click",($)=>{$.stopPropagation(),s(j,$)})}},k=(C)=>{let q=C.target;if(Y?.contains(q))return;let M=window.getSelection();if(!M||M.isCollapsed){O();return}let L=M.toString().trim();if(!L){O();return}let j=document.querySelector(".content");if(!j)return;let $=M.getRangeAt(0),J=(_)=>{let Z=_.nodeType===Node.TEXT_NODE?_.parentElement:_;while(Z&&Z!==j){let y=Z.tagName?.toLowerCase();if(y&&["p","h1","h2","h3","h4","h5","h6","li","blockquote","pre"].includes(y))return Z;Z=Z.parentElement}return null},Q=J($.startContainer),V=J($.endContainer);if(Q!==V){O();return}let K=$.commonAncestorContainer,X=K.nodeType===Node.TEXT_NODE?K.parentElement:K;if(!(X&&j.contains(X))){O();return}U={text:L,range:$.cloneRange()},c(C)},c=(C)=>{if(!Y)Y=p(),document.body.appendChild(Y);let{pageX:q,pageY:M}=C;Y.style.left=`${q}px`,Y.style.top=`${M-50}px`,Y.style.display="block"},O=()=>{if(Y)Y.style.display="none";U=null},s=(C,q)=>{if(D.has(C.id)){E(C.id);return}let M=document.createElement("div");M.className="highlight-notes-popup",M.style.cssText=`
2
2
  position: absolute;
3
3
  background: var(--bg);
4
4
  border: 1px solid var(--border);
@@ -9,7 +9,7 @@ var G=()=>{let C=document.querySelector(".admin-section"),q=document.querySelect
9
9
  z-index: 10000;
10
10
  font-size: 13px;
11
11
  line-height: 1.5;
12
- `;let K=document.createElement("div");K.style.cssText="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;";let Q=document.createElement("span");Q.textContent="Highlight Notes",Q.style.cssText="font-weight: 600; color: var(--fg);";let Z=document.createElement("button");Z.textContent="×",Z.style.cssText="background: none; border: none; color: var(--fg); cursor: pointer; padding: 0; font-size: 18px; line-height: 1; opacity: 0.7;",Z.addEventListener("click",(Y)=>{Y.stopPropagation(),J.remove(),y.delete(C.id)}),K.appendChild(Q),K.appendChild(Z);let _=document.createElement("div");_.style.cssText="color: var(--fg); white-space: pre-wrap; word-wrap: break-word;",_.textContent=C.notes||"(No notes)",J.appendChild(K),J.appendChild(_),J.addEventListener("click",(Y)=>{Y.stopPropagation()}),J.style.left=`${q.pageX}px`,J.style.top=`${q.pageY+10}px`,document.body.appendChild(J),y.set(C.id,J);let $=(Y)=>{if(!J.contains(Y.target))J.remove(),y.delete(C.id),document.removeEventListener("click",$)};setTimeout(()=>{document.addEventListener("click",$)},0)},p=()=>{let C=document.createElement("div");C.className="highlight-popup",C.innerHTML=`
12
+ `;let L=document.createElement("div");L.style.cssText="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;";let j=document.createElement("span");j.textContent="Highlight Notes",j.style.cssText="font-weight: 600; color: var(--fg);";let $=document.createElement("button");$.textContent="×",$.style.cssText="background: none; border: none; color: var(--fg); cursor: pointer; padding: 0; font-size: 18px; line-height: 1; opacity: 0.7;",$.addEventListener("click",(V)=>{V.stopPropagation(),E(C.id)}),L.appendChild(j),L.appendChild($);let J=document.createElement("div");J.style.cssText="color: var(--fg); white-space: pre-wrap; word-wrap: break-word;",J.textContent=C.notes||"(No notes)",M.appendChild(L),M.appendChild(J),M.addEventListener("click",(V)=>{V.stopPropagation()}),M.style.left=`${q.pageX}px`,M.style.top=`${q.pageY+10}px`,document.body.appendChild(M);let Q=(V)=>{if(!M.contains(V.target))E(C.id)};D.set(C.id,{el:M,onOutsideClick:Q}),setTimeout(()=>{document.addEventListener("click",Q)},0)},p=()=>{let C=document.createElement("div");C.className="highlight-popup",C.innerHTML=`
13
13
  <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
14
14
  <span style="font-size: 13px; font-weight: 500; color: var(--fg);">Add Highlight</span>
15
15
  <button class="highlight-close-btn" type="button" style="background: none; border: none; color: var(--fg); cursor: pointer; padding: 0; font-size: 18px; line-height: 1; opacity: 0.7;">&times;</button>
@@ -23,31 +23,4 @@ var G=()=>{let C=document.querySelector(".admin-section"),q=document.querySelect
23
23
  <button class="highlight-create-btn" type="button">
24
24
  Create Highlight
25
25
  </button>
26
- `;let q=C.querySelector(".highlight-create-btn");if(q)q.addEventListener("click",async(J)=>{J.stopPropagation(),await l()});let j=C.querySelector(".highlight-close-btn");if(j)j.addEventListener("click",(J)=>{J.stopPropagation(),B()});return C},d=(C,q)=>{let j=document.querySelector(".content");if(!j)return 0;let J=document.createRange();J.selectNodeContents(j),J.setEnd(q.startContainer,q.startOffset);let K=J.toString(),Q=0,Z=0;while(!0){let _=K.indexOf(C,Z);if(_===-1)break;Q+=1,Z=_+1}return Q},l=async()=>{if(!D)return;try{let{text:C,range:q}=D,j=d(C,q),K=V?.querySelector(".highlight-notes-input")?.value.trim()||void 0,Q=window.location.pathname.replace("/view/",""),Z=await fetch("/api/highlights",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({resourcePath:Q,highlightedText:C,occurrenceIndex:j,notes:K})});if(!Z.ok){let _=await Z.json();console.error("[highlights] Server error:",_.error||"Failed to create highlight");return}window.location.reload()}catch(C){console.error("[highlights] Failed to create highlight:",C)}};var g=(C)=>{return new Date(C).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"})},h=(C)=>{let q=document.querySelector(`[data-highlight-id="${C}"]`);if(q)q.scrollIntoView({behavior:"smooth",block:"center"}),q.classList.add("highlight-flash"),setTimeout(()=>{q.classList.remove("highlight-flash")},1000)},s=(C,q)=>C.length>q?`${C.slice(0,q)}...`:C,T=()=>{let C=document.querySelector(".content");if(!C)return;let q=window.location.pathname;if(!q.startsWith("/view/"))return;let j=q.slice(6);fetch(`/api/highlights/resource?path=${encodeURIComponent(j)}`).then((J)=>J.json()).then((J)=>{let K=J.highlights||[];if(K.length===0)return;let Q=document.createElement("div");Q.className="highlights-summary",Q.innerHTML=`
27
- <div style="background: var(--code-bg); border: 1px solid var(--border); border-radius: 8px; padding: 16px 20px; margin: 24px 0;">
28
- <h3 style="font-size: 0.875rem; margin: 0 0 12px 0; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; opacity: 0.8; display: flex; align-items: center; gap: 6px;">
29
- <span style="font-size: 16px;">✨</span>
30
- Highlights (${K.length})
31
- </h3>
32
- <ul style="list-style: none; padding: 0; margin: 0; font-size: 14px;">
33
- ${K.map(($)=>{let Y=$.isStale?'<span style="color: #f44336; margin-left: 4px;" title="Stale - file has changed">⚠️</span>':"",X=$.isStale?' style="text-decoration: line-through; opacity: 0.5;"':"",L=$.highlightedText.length>80?`${$.highlightedText.slice(0,80)}...`:$.highlightedText,U=$.notes?s($.notes,60):"",F=U?`<div style="margin-top: 4px; padding: 6px; background: var(--sidebar-bg); border-radius: 3px; font-size: 11px; opacity: 0.8;">\uD83D\uDCAD ${U}</div>`:"";return`
34
- <li style="margin: 8px 0; padding: 8px; background: var(--bg); border-radius: 4px; border-left: 3px solid var(--accent); cursor: pointer; transition: background 0.2s;"
35
- data-highlight-id="${$.id}"
36
- class="highlight-summary-item"
37
- onmouseover="this.style.background='var(--hover)'"
38
- onmouseout="this.style.background='var(--bg)'">
39
- <div${X}>${L}</div>
40
- ${F}
41
- <div style="opacity: 0.5; font-size: 12px; margin-top: 4px;">
42
- ${g($.createdAt)}${Y}
43
- </div>
44
- </li>
45
- `}).join("")}
46
- </ul>
47
- <div style="margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border);">
48
- <a href="/highlights" style="color: var(--accent); text-decoration: none; font-size: 13px; font-weight: 500;">
49
- View all highlights →
50
- </a>
51
- </div>
52
- </div>
53
- `;let Z=C.querySelector("h1, h2");if(Z)Z.parentNode?.insertBefore(Q,Z);else C.insertBefore(Q,C.firstChild);let _=Q.querySelectorAll(".highlight-summary-item");for(let $ of Array.from(_)){let Y=$.getAttribute("data-highlight-id");if(Y)$.addEventListener("click",()=>h(Y))}}).catch((J)=>{console.error("Failed to load highlights summary:",J)})};var o=()=>{let C=document.querySelector(".sidebar");if(!C)return;let q=document.createElement("div");q.className="sidebar-resize-handle",C.appendChild(q);let j=!1,J=0,K=0,Q=(Y)=>{j=!0,J=Y.clientX,K=C.offsetWidth,document.body.style.cursor="ew-resize",document.body.style.userSelect="none",Y.preventDefault()},Z=(Y)=>{if(!j)return;let X=Y.clientX-J,L=K+X,U=Math.max(200,Math.min(600,L));C.style.width=`${U}px`,localStorage.setItem("llmd-sidebar-width",U.toString())},_=()=>{if(!j)return;j=!1,document.body.style.cursor="",document.body.style.userSelect=""};q.addEventListener("mousedown",Q),document.addEventListener("mousemove",Z),document.addEventListener("mouseup",_);let $=localStorage.getItem("llmd-sidebar-width");if($){let Y=Number.parseInt($,10);if(Y>=200&&Y<=600)C.style.width=`${Y}px`}};if(typeof window<"u")window.addEventListener("DOMContentLoaded",()=>{o()});var b=(C,q,j)=>{fetch("/api/events",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:C,path:q,resourceType:j})}).catch(()=>{})},I=(C)=>{b("open",C,"dir")},w=(C)=>{b("view",C,"file")};var M=async()=>{try{let C=window.location.pathname.replace("/view/",""),q=C.includes("/")?C.substring(0,C.lastIndexOf("/")):"",j=await fetch(`/api/highlights/directory?path=${encodeURIComponent(q||".")}`);if(!j.ok)return;let K=(await j.json()).highlights||[],Q=new Set;for(let _ of K)Q.add(_.resourcePath);let Z=document.querySelectorAll("a[data-file-path]");for(let _ of Array.from(Z)){let $=_.getAttribute("data-file-path");if($&&Q.has($)){let Y=_.querySelector(".file-icon svg");if(Y)Y.setAttribute("fill","var(--accent)"),Y.setAttribute("fill-opacity","0.3")}}}catch(C){console.error("[file-highlights] Failed to load highlight indicators:",C)}};if(typeof window<"u")window.addEventListener("DOMContentLoaded",()=>{M()});window.trackDirectoryOpen=I;window.trackFileView=w;G();E();M();if(document.querySelector(".content"))S(),T();console.log("[llmd] Client initialized");
26
+ `;let q=C.querySelector(".highlight-create-btn");if(q)q.addEventListener("click",async(L)=>{L.stopPropagation(),await o()});let M=C.querySelector(".highlight-close-btn");if(M)M.addEventListener("click",(L)=>{L.stopPropagation(),O()});return C},l=(C,q)=>{let M=document.querySelector(".content");if(!M)return 0;let L=document.createRange();L.selectNodeContents(M),L.setEnd(q.startContainer,q.startOffset);let j=L.toString(),$=0,J=0;while(!0){let Q=j.indexOf(C,J);if(Q===-1)break;$+=1,J=Q+1}return $},o=async()=>{if(!U)return;try{let{text:C,range:q}=U,M=l(C,q),j=Y?.querySelector(".highlight-notes-input")?.value.trim()||void 0,$=window.location.pathname.replace("/view/",""),J=await fetch("/api/highlights",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({resourcePath:$,highlightedText:C,occurrenceIndex:M,notes:j})});if(!J.ok){let Q=await J.json();console.error("[highlights] Server error:",Q.error||"Failed to create highlight");return}window.location.reload()}catch(C){console.error("[highlights] Failed to create highlight:",C)}};var I=(C)=>{return new Date(C).toLocaleString("en-US",{month:"short",day:"numeric",hour:"numeric",minute:"2-digit"})},z=(C,q)=>C.length>q?`${C.slice(0,q)}...`:C,a=(C)=>{let q=document.createElement("li");q.className="highlight-summary-item",q.dataset.highlightId=C.id,q.style.cssText="margin: 8px 0; padding: 8px; background: var(--bg); border-radius: 4px; border-left: 3px solid var(--accent); cursor: pointer; transition: background 0.2s;",q.addEventListener("mouseover",()=>{q.style.background="var(--hover)"}),q.addEventListener("mouseout",()=>{q.style.background="var(--bg)"}),q.addEventListener("click",()=>A(C.id));let M=document.createElement("div");if(C.isStale)M.style.cssText="text-decoration: line-through; opacity: 0.5;";if(M.textContent=z(C.highlightedText,80),q.appendChild(M),C.notes){let j=document.createElement("div");j.style.cssText="margin-top: 4px; padding: 6px; background: var(--sidebar-bg); border-radius: 3px; font-size: 11px; opacity: 0.8;",j.textContent=`Note: ${z(C.notes,60)}`,q.appendChild(j)}let L=document.createElement("div");return L.style.cssText="opacity: 0.5; font-size: 12px; margin-top: 4px;",L.textContent=C.isStale?`${I(C.createdAt)} (stale)`:I(C.createdAt),q.appendChild(L),q},r=(C)=>{let q=document.createElement("div");q.className="highlights-summary";let M=document.createElement("div");M.style.cssText="background: var(--code-bg); border: 1px solid var(--border); border-radius: 8px; padding: 16px 20px; margin: 24px 0;";let L=document.createElement("h3");L.style.cssText="font-size: 0.875rem; margin: 0 0 12px 0; text-transform: uppercase; letter-spacing: 0.08em; font-weight: 700; opacity: 0.8;",L.textContent=`Highlights (${C.length})`,M.appendChild(L);let j=document.createElement("ul");j.style.cssText="list-style: none; padding: 0; margin: 0; font-size: 14px;";for(let Q of C)j.appendChild(a(Q));M.appendChild(j);let $=document.createElement("div");$.style.cssText="margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border);";let J=document.createElement("a");return J.href="/highlights",J.style.cssText="color: var(--accent); text-decoration: none; font-size: 13px; font-weight: 500;",J.textContent="View all highlights",$.appendChild(J),M.appendChild($),q.appendChild(M),q},H=()=>{let C=document.querySelector(".content");if(!C)return;let q=window.location.pathname;if(!q.startsWith("/view/"))return;let M=q.slice(6);fetch(`/api/highlights/resource?path=${encodeURIComponent(M)}`).then((L)=>L.json()).then((L)=>{let j=L.highlights||[];if(j.length===0)return;let $=r(j),J=C.querySelector("h1, h2");if(J)J.parentNode?.insertBefore($,J);else C.insertBefore($,C.firstChild)}).catch((L)=>{console.error("Failed to load highlights summary:",L)})};var n=()=>{let C=document.querySelector(".sidebar");if(!C)return;let q=document.createElement("div");q.className="sidebar-resize-handle",C.appendChild(q);let M=!1,L=0,j=0,$=(K)=>{M=!0,L=K.clientX,j=C.offsetWidth,document.body.style.cursor="ew-resize",document.body.style.userSelect="none",K.preventDefault()},J=(K)=>{if(!M)return;let X=K.clientX-L,_=j+X,Z=Math.max(200,Math.min(600,_));C.style.width=`${Z}px`,localStorage.setItem("llmd-sidebar-width",Z.toString())},Q=()=>{if(!M)return;M=!1,document.body.style.cursor="",document.body.style.userSelect=""};q.addEventListener("mousedown",$),document.addEventListener("mousemove",J),document.addEventListener("mouseup",Q);let V=localStorage.getItem("llmd-sidebar-width");if(V){let K=Number.parseInt(V,10);if(K>=200&&K<=600)C.style.width=`${K}px`}};if(typeof window<"u")window.addEventListener("DOMContentLoaded",()=>{n()});window.trackDirectoryOpen=S;window.trackFileView=b;N();W();f();if(document.querySelector(".content"))T(),H();console.log("[llmd] Client initialized");