ctxloom-pro 1.0.31 → 1.1.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.
package/README.md CHANGED
@@ -6,6 +6,35 @@ No cloud indexing. No Python. Everything runs on your machine.
6
6
 
7
7
  > **ctxloom requires a license.** Start a free 7-day trial — no credit card required.
8
8
 
9
+ ## Multi-Project Support (v1.1.0)
10
+
11
+ ctxloom now supports analyzing multiple projects in a single MCP session. Every tool accepts an optional `project_root` parameter (alias or absolute path).
12
+
13
+ **Register a project alias:**
14
+ ```bash
15
+ ctxloom register --alias myapp /path/to/project
16
+ ```
17
+
18
+ **Use the alias in tool calls:**
19
+ ```json
20
+ {
21
+ "project_root": "myapp"
22
+ }
23
+ ```
24
+
25
+ Or use an absolute path directly:
26
+ ```json
27
+ {
28
+ "project_root": "/path/to/project"
29
+ }
30
+ ```
31
+
32
+ **Project state management:** ctxloom maintains an LRU cache of active projects (cap 5 by default, override via `CTXLOOM_MAX_PROJECTS`). First-touch auto-indexing indexes the dependency graph (sync, Tier 1) and queues vector indexing (deferred, Tier 2). Responses include a `<ctxloom_indexing>` envelope on first-touch. Project-resolution errors return structured XML: `<error code="alias_not_found" .../>`, `<error code="no_default_project" .../>`, etc.
33
+
34
+ **Backward compatibility:** Set `CTXLOOM_DISABLE_MULTIPROJECT=1` to revert to single-project (v1.0.31) behavior.
35
+
36
+ ---
37
+
9
38
  ## Getting Started
10
39
 
11
40
  **Prerequisites:** Node.js 20+ and an MCP-compatible AI tool (Claude Code, Cursor, Windsurf, etc.)
@@ -482,7 +511,8 @@ ctxloom dashboard Open the web dashboard (port 7842)
482
511
  ctxloom dashboard --port=N Start on a custom port
483
512
  ctxloom dashboard --open Open browser automatically
484
513
  ctxloom setup Detect and configure MCP-compatible AI tools (interactive)
485
- ctxloom register <path> Register a repo for cross-repo search
514
+ ctxloom register <path> Register a repo for cross-repo search (v1.0.x)
515
+ ctxloom register --alias <name> <path> Register a project with an alias for multi-project support (v1.1.0+)
486
516
  ctxloom repos List all registered repos
487
517
  ctxloom grammars Show grammar cache status
488
518
  ctxloom grammars --download Pre-download all language grammars
@@ -598,6 +628,8 @@ Token counts use the standard 4 chars/token approximation. Per-repo range (57–
598
628
  | `CTXLOOM_ROOT` | Project root directory | Current working directory |
599
629
  | `LOG_LEVEL` | Logging verbosity: `debug` / `info` / `warn` / `error` | `info` |
600
630
  | `CTXLOOM_GRAMMAR_CDN` | CDN base URL for grammar downloads (air-gapped environments) | Built-in |
631
+ | `CTXLOOM_MAX_PROJECTS` | LRU cache cap for multi-project state (v1.1.0+) | `5` |
632
+ | `CTXLOOM_DISABLE_MULTIPROJECT` | Set to `1` to revert to v1.0.31 single-project mode (v1.1.0+) | (unset) |
601
633
 
602
634
  ---
603
635
 
@@ -64,7 +64,7 @@ Error generating stack: `+a.message+`
64
64
  * LICENSE.md file in the root directory of this source tree.
65
65
  *
66
66
  * @license MIT
67
- */function bc(){return bc=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},bc.apply(this,arguments)}function OA(e,t){if(e==null)return{};var n={},r=Object.keys(e),i,a;for(a=0;a<r.length;a++)i=r[a],!(t.indexOf(i)>=0)&&(n[i]=e[i]);return n}function ON(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function AN(e,t){return e.button===0&&(!t||t==="_self")&&!ON(e)}const EN=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","viewTransition"],PN=["aria-current","caseSensitive","className","end","style","to","viewTransition","children"],TN="6";try{window.__reactRouterVersion=TN}catch{}const kN=$.createContext({isTransitioning:!1}),$N="startTransition",Pb=y$[$N];function jN(e){let{basename:t,children:n,future:r,window:i}=e,a=$.useRef();a.current==null&&(a.current=$C({window:i,v5Compat:!0}));let o=a.current,[l,s]=$.useState({action:o.action,location:o.location}),{v7_startTransition:u}=r||{},f=$.useCallback(c=>{u&&Pb?Pb(()=>s(c)):s(c)},[s,u]);return $.useLayoutEffect(()=>o.listen(f),[o,f]),$.useEffect(()=>xN(r),[r]),$.createElement(SN,{basename:t,children:n,location:l.location,navigationType:l.action,navigator:o,future:r})}const CN=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",NN=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,MN=$.forwardRef(function(t,n){let{onClick:r,relative:i,reloadDocument:a,replace:o,state:l,target:s,to:u,preventScrollReset:f,viewTransition:c}=t,d=OA(t,EN),{basename:p}=$.useContext(Gr),y,m=!1;if(typeof u=="string"&&NN.test(u)&&(y=u,CN))try{let b=new URL(window.location.href),x=u.startsWith("//")?new URL(b.protocol+u):new URL(u),w=Ra(x.pathname,p);x.origin===b.origin&&w!=null?u=w+x.search+x.hash:m=!0}catch{}let v=nN(u,{relative:i}),h=RN(u,{replace:o,state:l,target:s,preventScrollReset:f,relative:i,viewTransition:c});function g(b){r&&r(b),b.defaultPrevented||h(b)}return $.createElement("a",bc({},d,{href:y||v,onClick:m||a?r:g,ref:n,target:s}))}),tl=$.forwardRef(function(t,n){let{"aria-current":r="page",caseSensitive:i=!1,className:a="",end:o=!1,style:l,to:s,viewTransition:u,children:f}=t,c=OA(t,PN),d=Vf(s,{relative:c.relative}),p=$s(),y=$.useContext(yA),{navigator:m,basename:v}=$.useContext(Gr),h=y!=null&&LN(d)&&u===!0,g=m.encodeLocation?m.encodeLocation(d).pathname:d.pathname,b=p.pathname,x=y&&y.navigation&&y.navigation.location?y.navigation.location.pathname:null;i||(b=b.toLowerCase(),x=x?x.toLowerCase():null,g=g.toLowerCase()),x&&v&&(x=Ra(x,v)||x);const w=g!=="/"&&g.endsWith("/")?g.length-1:g.length;let S=b===g||!o&&b.startsWith(g)&&b.charAt(w)==="/",_=x!=null&&(x===g||!o&&x.startsWith(g)&&x.charAt(g.length)==="/"),A={isActive:S,isPending:_,isTransitioning:h},P=S?r:void 0,T;typeof a=="function"?T=a(A):T=[a,S?"active":null,_?"pending":null,h?"transitioning":null].filter(Boolean).join(" ");let I=typeof l=="function"?l(A):l;return $.createElement(MN,bc({},c,{"aria-current":P,className:T,ref:n,style:I,to:s,viewTransition:u}),typeof f=="function"?f(A):f)});var eg;(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(eg||(eg={}));var Tb;(function(e){e.UseFetcher="useFetcher",e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"})(Tb||(Tb={}));function IN(e){let t=$.useContext(Wf);return t||De(!1),t}function RN(e,t){let{target:n,replace:r,state:i,preventScrollReset:a,relative:o,viewTransition:l}=t===void 0?{}:t,s=rN(),u=$s(),f=Vf(e,{relative:o});return $.useCallback(c=>{if(AN(c,n)){c.preventDefault();let d=r!==void 0?r:yc(u)===yc(f);s(e,{replace:d,state:i,preventScrollReset:a,relative:o,viewTransition:l})}},[u,s,f,r,i,n,e,a,o,l])}function LN(e,t){t===void 0&&(t={});let n=$.useContext(kN);n==null&&De(!1);let{basename:r}=IN(eg.useViewTransitionState),i=Vf(e,{relative:t.relative});if(!n.isTransitioning)return!1;let a=Ra(n.currentLocation.pathname,r)||n.currentLocation.pathname,o=Ra(n.nextLocation.pathname,r)||n.nextLocation.pathname;return Qh(i.pathname,o)!=null||Qh(i.pathname,a)!=null}const Rv="/api";async function fn(e){const t=await fetch(`${Rv}${e}`);if(!t.ok)throw new Error(`API ${e} failed: ${t.status}`);return t.json()}async function DN(e,t){const n=await fetch(`${Rv}${e}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)});if(!n.ok){let r=`${n.status}`;try{const i=await n.json();i!=null&&i.error&&(r=i.error)}catch{}throw new Error(r)}return n.json()}const kn={overview:()=>fn("/overview"),graph:()=>fn("/graph"),risk:()=>fn("/risk"),communities:()=>fn("/communities"),churn:()=>fn("/churn"),ownership:()=>fn("/ownership"),status:()=>fn("/status"),tokens:()=>fn("/tokens"),trends:(e="30d")=>fn(`/trends?range=${e}`),refresh:()=>fetch(`${Rv}/refresh`,{method:"POST"}).then(e=>e.json()),listProjects:()=>fn("/projects"),activeProject:()=>fn("/projects/active"),switchProject:e=>DN("/projects/active",{slug:e})},kb="ctxloom.dashboard.activeSlug";function BN(){const[e,t]=$.useState([]),[n,r]=$.useState(null),[i,a]=$.useState(!1),[o,l]=$.useState(null),[s,u]=$.useState(null);$.useEffect(()=>{let c=!1;return kn.listProjects().then(({projects:d})=>{if(c)return;t(d);const p=d.find(m=>m.isActive)??d[0];r(p);const y=localStorage.getItem(kb);y&&y!==p.slug&&d.some(m=>m.slug===y)&&f(y)}).catch(d=>{c||u(d instanceof Error?d.message:String(d))}),()=>{c=!0}},[]),$.useEffect(()=>{if(!i)return;function c(d){var y;const p=d.target;(y=p==null?void 0:p.closest)!=null&&y.call(p,"[data-project-switcher]")||a(!1)}return document.addEventListener("click",c),()=>document.removeEventListener("click",c)},[i]);async function f(c){l(c),u(null);try{const{active:d}=await kn.switchProject(c);localStorage.setItem(kb,d.slug),window.location.reload()}catch(d){u(d instanceof Error?d.message:String(d)),l(null)}}return n?e.length<=1?O.jsx(FN,{name:n.name,root:n.root}):O.jsxs("div",{className:"relative px-2 py-2","data-project-switcher":!0,children:[O.jsxs("button",{type:"button",onClick:()=>a(c=>!c),disabled:o!==null,className:"w-full flex items-center justify-between gap-2 rounded-md px-2.5 py-2 text-xs text-white/80 hover:bg-white/5 transition-colors disabled:opacity-50",title:n.root,children:[O.jsxs("span",{className:"flex items-center gap-2 min-w-0",children:[O.jsx("span",{className:"text-white/40 shrink-0",children:"◆"}),O.jsx("span",{className:"truncate",children:n.name})]}),O.jsx("span",{className:"text-white/30 text-[10px] shrink-0",children:i?"▴":"▾"})]}),i&&O.jsx("div",{className:"absolute left-2 right-2 mt-1 z-20 rounded-md bg-[#1f1e2c] py-1 shadow-lg",style:{border:"1px solid rgba(255,255,255,0.08)"},children:e.map(c=>O.jsxs("button",{type:"button",onClick:()=>{a(!1),c.slug!==n.slug&&f(c.slug)},disabled:o!==null,className:`w-full text-left px-3 py-1.5 text-xs flex items-center gap-2 transition-colors ${c.slug===n.slug?"text-[#a78bfa] bg-[#603dc6]/10":"text-white/70 hover:bg-white/5"} disabled:opacity-50`,title:c.root,children:[O.jsx("span",{className:"shrink-0 w-3 text-center",children:c.slug===n.slug?"●":" "}),O.jsx("span",{className:"truncate flex-1",children:c.name}),!c.hasSnapshot&&O.jsx("span",{className:"text-[10px] text-white/30 shrink-0",title:"Never indexed — first switch will be slow",children:"cold"}),c.isDefault&&O.jsx("span",{className:"text-[10px] text-white/30 shrink-0",title:"Project the dashboard was launched against",children:"default"})]},c.slug))}),o&&O.jsx("div",{className:"px-2.5 py-1 text-[10px] text-white/40",children:"switching… (cold start may take a moment)"}),s&&O.jsx("div",{className:"px-2.5 py-1 text-[10px] text-red-400/80",role:"alert",children:s})]}):O.jsx("div",{className:"px-3 py-2 text-xs text-white/30",children:s?`Projects unavailable: ${s}`:"Loading projects…"})}function FN({name:e,root:t}){const[n,r]=$.useState(!1),i="ctxloom register",[a,o]=$.useState(!1);return O.jsxs("div",{className:"px-3 py-2",children:[O.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[O.jsx("span",{className:"text-white/30 shrink-0",children:"◆"}),O.jsx("span",{className:"text-white/80 truncate flex-1 min-w-0",title:t,children:e}),O.jsx("button",{type:"button",onClick:()=>r(l=>!l),className:"shrink-0 text-white/30 hover:text-white/70 transition-colors text-sm w-4 leading-none","aria-label":"How to add more projects",title:"Add more projects",children:n?"×":"+"})]}),n&&O.jsxs("div",{className:"mt-2 text-[11px] text-white/50 leading-snug",children:["Track multiple projects in one dashboard:",O.jsxs("div",{className:"mt-1.5 flex items-stretch gap-1",children:[O.jsx("code",{className:"flex-1 min-w-0 truncate rounded bg-black/40 px-2 py-1 text-white/80 font-mono text-[10px]",children:i}),O.jsx("button",{type:"button",onClick:()=>{var l;(l=navigator.clipboard)==null||l.writeText(i),o(!0),setTimeout(()=>o(!1),1200)},className:"shrink-0 rounded bg-white/5 px-2 text-[10px] text-white/60 hover:bg-white/10 transition-colors","aria-label":"Copy command",children:a?"✓":"copy"})]}),O.jsx("div",{className:"mt-1.5 text-white/30",children:"Run inside any repo, then refresh this page."})]})]})}const zN=[{to:"/",label:"Overview",icon:"◈"},{to:"/graph",label:"Graph",icon:"⬡"},{to:"/risk",label:"Risk",icon:"⚠"},{to:"/trends",label:"Trends",icon:"⤴"},{to:"/communities",label:"Communities",icon:"⬡⬡"},{to:"/ownership",label:"Ownership",icon:"◎"},{to:"/guide",label:"Guide",icon:"◉"}];function UN(){return O.jsxs("div",{className:"flex h-screen bg-[#18181f]",children:[O.jsxs("aside",{className:"w-52 shrink-0 bg-[#131220] flex flex-col",style:{borderRight:"1px solid rgba(255,255,255,0.07)"},children:[O.jsxs("div",{className:"px-4 py-4 flex items-center gap-2.5",style:{borderBottom:"1px solid rgba(255,255,255,0.07)"},children:[O.jsx("img",{src:"/logo.svg",alt:"ctxloom",className:"w-6 h-6 shrink-0"}),O.jsxs("div",{children:[O.jsxs("span",{className:"text-sm font-semibold",children:[O.jsx("span",{className:"text-white",children:"ctx"}),O.jsx("span",{className:"text-[#a78bfa]",children:"loom"})]}),O.jsx("span",{className:"ml-1 text-xs text-white/30",children:"dashboard"})]})]}),O.jsx("div",{style:{borderBottom:"1px solid rgba(255,255,255,0.07)"},children:O.jsx(BN,{})}),O.jsx("nav",{className:"flex-1 py-4 space-y-1 px-2",children:zN.map(({to:e,label:t,icon:n})=>O.jsxs(tl,{to:e,end:e==="/",className:({isActive:r})=>`flex items-center gap-2 rounded-md px-3 py-2 text-sm transition-colors ${r?"bg-[#603dc6]/15 text-[#a78bfa] font-medium":"text-white/40 hover:text-white/70 hover:bg-white/5"}`,children:[O.jsx("span",{className:"text-xs select-none shrink-0",children:n}),t]},e))})]}),O.jsx("main",{className:"flex-1 overflow-y-auto p-8 bg-[#18181f]",children:O.jsx(wN,{})})]})}function Si(e){const[t,n]=$.useState({status:"loading"});return $.useEffect(()=>{let r=!1;return n({status:"loading"}),e().then(i=>{r||n({status:"success",data:i})}).catch(i=>{r||n({status:"error",message:String(i)})}),()=>{r=!0}},[]),t}function au({label:e,value:t,sub:n}){return O.jsxs("div",{className:"bg-[#1e1d2a] border border-white/10 rounded-xl p-5 transition-transform hover:-translate-y-0.5",children:[O.jsx("p",{className:"text-white/50 text-xs uppercase tracking-wider",children:e}),O.jsx("p",{className:"text-white text-3xl font-semibold mt-1",children:t}),n&&O.jsx("p",{className:"text-white/40 text-xs mt-1",children:n})]})}const WN={critical:"bg-red-900/50 text-red-300 font-semibold",high:"bg-orange-900/50 text-orange-300",medium:"bg-yellow-900/50 text-yellow-300",low:"bg-green-900/50 text-green-300"},$b={churn:.4,bugDensity:.3,coupling:.3},HN={churn:"Churn",bugDensity:"Bug density",coupling:"Coupling"},VN={critical:"Top 5% by intrinsic risk in this repo. Prioritise refactor or test coverage.",high:"Next 10% — meaningful intrinsic risk. Review when touching this area.",medium:"Next 20% — moderate intrinsic risk. Worth keeping an eye on.",low:"Bottom 65% — healthy file by intrinsic risk metrics."},jb=296,Cb=230,wp=8;function AA({level:e,breakdown:t,score:n,busFactor:r,topOwner:i,siloed:a}){const o=WN[e]??"bg-white/10 text-white/50";if(!t)return O.jsx("span",{className:`inline-block rounded-full px-2.5 py-0.5 text-xs ${o}`,children:e});const l=$.useRef(null),[s,u]=$.useState(!1),[f,c]=$.useState(!1),[d,p]=$.useState(null),[y,m]=$.useState(!1);$.useEffect(()=>{var b;if(typeof window>"u"||!window.matchMedia)return;const h=window.matchMedia("(hover: none)"),g=()=>m(h.matches);return g(),(b=h.addEventListener)==null||b.call(h,"change",g),()=>{var x;return(x=h.removeEventListener)==null?void 0:x.call(h,"change",g)}},[]),$.useLayoutEffect(()=>{if(!s||!l.current)return;const h=l.current.getBoundingClientRect(),b=h.bottom+Cb+wp>window.innerHeight?h.top-Cb-wp:h.bottom+wp,x=Math.max(8,Math.min(window.innerWidth-jb-8,h.left));p({top:b,left:x})},[s]),$.useEffect(()=>{if(!f)return;const h=b=>{if(!l.current)return;const x=b.target;if(l.current.contains(x))return;const w=document.getElementById("risk-badge-tooltip");w&&w.contains(x)||(c(!1),u(!1))},g=b=>{b.key==="Escape"&&(c(!1),u(!1))};return document.addEventListener("mousedown",h),document.addEventListener("keydown",g),()=>{document.removeEventListener("mousedown",h),document.removeEventListener("keydown",g)}},[f]);const v=Object.keys($b).map(h=>({key:h,label:HN[h],normalized:t[h],contribution:t[h]*$b[h]})).sort((h,g)=>g.contribution-h.contribution);return O.jsxs(O.Fragment,{children:[O.jsx("button",{ref:l,type:"button","aria-expanded":s,"aria-describedby":s?"risk-badge-tooltip":void 0,className:`inline-block rounded-full px-2.5 py-0.5 text-xs cursor-pointer ${o}`,onMouseEnter:()=>!y&&!f&&u(!0),onMouseLeave:()=>!y&&!f&&u(!1),onFocus:()=>!y&&!f&&u(!0),onBlur:()=>!y&&!f&&u(!1),onClick:h=>{h.stopPropagation(),f?(c(!1),u(!1)):(c(!0),u(!0))},children:e}),s&&d&&O.jsxs("div",{id:"risk-badge-tooltip",role:"tooltip",style:{position:"fixed",top:d.top,left:d.left,width:jb},className:"z-50 rounded-lg border border-white/10 bg-[#131220] p-3 text-left text-xs shadow-xl",children:[O.jsxs("div",{className:"flex items-center justify-between mb-1",children:[O.jsxs("span",{className:"text-white font-medium",children:[e," ",typeof n=="number"&&O.jsxs("span",{className:"text-white/40 font-normal",children:["(",n.toFixed(2),")"]})]}),f&&O.jsx("span",{className:"text-[10px] text-white/40",children:y?"tap badge or outside to close":"click to unpin · esc"})]}),O.jsx("div",{className:"text-white/50 mb-2",children:VN[e]??""}),O.jsx("div",{className:"text-white/40 text-[10px] uppercase tracking-wide mb-1",children:"Intrinsic risk contribution"}),O.jsx("div",{className:"space-y-1",children:v.map(h=>O.jsxs("div",{className:"flex items-center gap-2",children:[O.jsx("span",{className:"w-20 shrink-0 text-white/60",children:h.label}),O.jsx("span",{className:"flex-1 h-1.5 rounded bg-white/5 overflow-hidden",children:O.jsx("span",{className:"block h-full bg-[#a78bfa]",style:{width:`${Math.round(h.normalized*100)}%`}})}),O.jsxs("span",{className:"w-10 shrink-0 text-right text-white/50 tabular-nums",children:["+",h.contribution.toFixed(2)]})]},h.key))}),(typeof r=="number"||i)&&O.jsxs(O.Fragment,{children:[O.jsxs("div",{className:"text-white/40 text-[10px] uppercase tracking-wide mt-3 mb-1",children:["Ownership ",O.jsx("span",{className:"text-white/30 normal-case",children:"(not in score)"})]}),O.jsxs("div",{className:"text-white/60 leading-relaxed",children:[i&&O.jsxs(O.Fragment,{children:["Owner: ",O.jsx("span",{className:"text-white/80",children:i}),O.jsx("br",{})]}),typeof r=="number"&&O.jsxs(O.Fragment,{children:["Bus factor: ",O.jsx("span",{className:"text-white/80",children:r}),a&&O.jsx("span",{className:"text-yellow-300/80",children:" · knowledge silo"})]})]})]}),O.jsx("div",{className:"mt-3 text-[10px] text-white/30 leading-relaxed",children:"Score: 40% churn + 30% bugs + 30% coupling, normalized to repo p90. Labels are percentile-banded (top 5% critical, next 10% high, next 20% medium)."})]})]})}function mo({message:e}){return O.jsx("div",{className:"bg-red-900/30 border border-red-500/30 text-red-300 rounded-lg p-3 text-sm",children:e})}function EA(e){var t,n,r="";if(typeof e=="string"||typeof e=="number")r+=e;else if(typeof e=="object")if(Array.isArray(e)){var i=e.length;for(t=0;t<i;t++)e[t]&&(n=EA(e[t]))&&(r&&(r+=" "),r+=n)}else for(n in e)e[n]&&(r&&(r+=" "),r+=n);return r}function se(){for(var e,t,n=0,r="",i=arguments.length;n<i;n++)(e=arguments[n])&&(t=EA(e))&&(r&&(r+=" "),r+=t);return r}var GN=Array.isArray,Nt=GN,KN=typeof zs=="object"&&zs&&zs.Object===Object&&zs,PA=KN,XN=PA,YN=typeof self=="object"&&self&&self.Object===Object&&self,qN=XN||YN||Function("return this")(),Dn=qN,ZN=Dn,QN=ZN.Symbol,js=QN,Nb=js,TA=Object.prototype,JN=TA.hasOwnProperty,e2=TA.toString,Bo=Nb?Nb.toStringTag:void 0;function t2(e){var t=JN.call(e,Bo),n=e[Bo];try{e[Bo]=void 0;var r=!0}catch{}var i=e2.call(e);return r&&(t?e[Bo]=n:delete e[Bo]),i}var n2=t2,r2=Object.prototype,i2=r2.toString;function a2(e){return i2.call(e)}var o2=a2,Mb=js,l2=n2,s2=o2,u2="[object Null]",c2="[object Undefined]",Ib=Mb?Mb.toStringTag:void 0;function f2(e){return e==null?e===void 0?c2:u2:Ib&&Ib in Object(e)?l2(e):s2(e)}var dr=f2;function d2(e){return e!=null&&typeof e=="object"}var pr=d2,p2=dr,h2=pr,g2="[object Symbol]";function m2(e){return typeof e=="symbol"||h2(e)&&p2(e)==g2}var vo=m2,v2=Nt,y2=vo,b2=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,x2=/^\w*$/;function w2(e,t){if(v2(e))return!1;var n=typeof e;return n=="number"||n=="symbol"||n=="boolean"||e==null||y2(e)?!0:x2.test(e)||!b2.test(e)||t!=null&&e in Object(t)}var Lv=w2;function S2(e){var t=typeof e;return e!=null&&(t=="object"||t=="function")}var Xr=S2;const yo=be(Xr);var _2=dr,O2=Xr,A2="[object AsyncFunction]",E2="[object Function]",P2="[object GeneratorFunction]",T2="[object Proxy]";function k2(e){if(!O2(e))return!1;var t=_2(e);return t==E2||t==P2||t==A2||t==T2}var Dv=k2;const ne=be(Dv);var $2=Dn,j2=$2["__core-js_shared__"],C2=j2,Sp=C2,Rb=function(){var e=/[^.]+$/.exec(Sp&&Sp.keys&&Sp.keys.IE_PROTO||"");return e?"Symbol(src)_1."+e:""}();function N2(e){return!!Rb&&Rb in e}var M2=N2,I2=Function.prototype,R2=I2.toString;function L2(e){if(e!=null){try{return R2.call(e)}catch{}try{return e+""}catch{}}return""}var kA=L2,D2=Dv,B2=M2,F2=Xr,z2=kA,U2=/[\\^$.*+?()[\]{}|]/g,W2=/^\[object .+?Constructor\]$/,H2=Function.prototype,V2=Object.prototype,G2=H2.toString,K2=V2.hasOwnProperty,X2=RegExp("^"+G2.call(K2).replace(U2,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function Y2(e){if(!F2(e)||B2(e))return!1;var t=D2(e)?X2:W2;return t.test(z2(e))}var q2=Y2;function Z2(e,t){return e==null?void 0:e[t]}var Q2=Z2,J2=q2,eM=Q2;function tM(e,t){var n=eM(e,t);return J2(n)?n:void 0}var Fi=tM,nM=Fi,rM=nM(Object,"create"),Gf=rM,Lb=Gf;function iM(){this.__data__=Lb?Lb(null):{},this.size=0}var aM=iM;function oM(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}var lM=oM,sM=Gf,uM="__lodash_hash_undefined__",cM=Object.prototype,fM=cM.hasOwnProperty;function dM(e){var t=this.__data__;if(sM){var n=t[e];return n===uM?void 0:n}return fM.call(t,e)?t[e]:void 0}var pM=dM,hM=Gf,gM=Object.prototype,mM=gM.hasOwnProperty;function vM(e){var t=this.__data__;return hM?t[e]!==void 0:mM.call(t,e)}var yM=vM,bM=Gf,xM="__lodash_hash_undefined__";function wM(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=bM&&t===void 0?xM:t,this}var SM=wM,_M=aM,OM=lM,AM=pM,EM=yM,PM=SM;function bo(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}bo.prototype.clear=_M;bo.prototype.delete=OM;bo.prototype.get=AM;bo.prototype.has=EM;bo.prototype.set=PM;var TM=bo;function kM(){this.__data__=[],this.size=0}var $M=kM;function jM(e,t){return e===t||e!==e&&t!==t}var Bv=jM,CM=Bv;function NM(e,t){for(var n=e.length;n--;)if(CM(e[n][0],t))return n;return-1}var Kf=NM,MM=Kf,IM=Array.prototype,RM=IM.splice;function LM(e){var t=this.__data__,n=MM(t,e);if(n<0)return!1;var r=t.length-1;return n==r?t.pop():RM.call(t,n,1),--this.size,!0}var DM=LM,BM=Kf;function FM(e){var t=this.__data__,n=BM(t,e);return n<0?void 0:t[n][1]}var zM=FM,UM=Kf;function WM(e){return UM(this.__data__,e)>-1}var HM=WM,VM=Kf;function GM(e,t){var n=this.__data__,r=VM(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}var KM=GM,XM=$M,YM=DM,qM=zM,ZM=HM,QM=KM;function xo(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}xo.prototype.clear=XM;xo.prototype.delete=YM;xo.prototype.get=qM;xo.prototype.has=ZM;xo.prototype.set=QM;var Xf=xo,JM=Fi,eI=Dn,tI=JM(eI,"Map"),Fv=tI,Db=TM,nI=Xf,rI=Fv;function iI(){this.size=0,this.__data__={hash:new Db,map:new(rI||nI),string:new Db}}var aI=iI;function oI(e){var t=typeof e;return t=="string"||t=="number"||t=="symbol"||t=="boolean"?e!=="__proto__":e===null}var lI=oI,sI=lI;function uI(e,t){var n=e.__data__;return sI(t)?n[typeof t=="string"?"string":"hash"]:n.map}var Yf=uI,cI=Yf;function fI(e){var t=cI(this,e).delete(e);return this.size-=t?1:0,t}var dI=fI,pI=Yf;function hI(e){return pI(this,e).get(e)}var gI=hI,mI=Yf;function vI(e){return mI(this,e).has(e)}var yI=vI,bI=Yf;function xI(e,t){var n=bI(this,e),r=n.size;return n.set(e,t),this.size+=n.size==r?0:1,this}var wI=xI,SI=aI,_I=dI,OI=gI,AI=yI,EI=wI;function wo(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}wo.prototype.clear=SI;wo.prototype.delete=_I;wo.prototype.get=OI;wo.prototype.has=AI;wo.prototype.set=EI;var zv=wo,$A=zv,PI="Expected a function";function Uv(e,t){if(typeof e!="function"||t!=null&&typeof t!="function")throw new TypeError(PI);var n=function(){var r=arguments,i=t?t.apply(this,r):r[0],a=n.cache;if(a.has(i))return a.get(i);var o=e.apply(this,r);return n.cache=a.set(i,o)||a,o};return n.cache=new(Uv.Cache||$A),n}Uv.Cache=$A;var jA=Uv;const TI=be(jA);var kI=jA,$I=500;function jI(e){var t=kI(e,function(r){return n.size===$I&&n.clear(),r}),n=t.cache;return t}var CI=jI,NI=CI,MI=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,II=/\\(\\)?/g,RI=NI(function(e){var t=[];return e.charCodeAt(0)===46&&t.push(""),e.replace(MI,function(n,r,i,a){t.push(i?a.replace(II,"$1"):r||n)}),t}),LI=RI;function DI(e,t){for(var n=-1,r=e==null?0:e.length,i=Array(r);++n<r;)i[n]=t(e[n],n,e);return i}var Wv=DI,Bb=js,BI=Wv,FI=Nt,zI=vo,Fb=Bb?Bb.prototype:void 0,zb=Fb?Fb.toString:void 0;function CA(e){if(typeof e=="string")return e;if(FI(e))return BI(e,CA)+"";if(zI(e))return zb?zb.call(e):"";var t=e+"";return t=="0"&&1/e==-1/0?"-0":t}var UI=CA,WI=UI;function HI(e){return e==null?"":WI(e)}var NA=HI,VI=Nt,GI=Lv,KI=LI,XI=NA;function YI(e,t){return VI(e)?e:GI(e,t)?[e]:KI(XI(e))}var MA=YI,qI=vo;function ZI(e){if(typeof e=="string"||qI(e))return e;var t=e+"";return t=="0"&&1/e==-1/0?"-0":t}var qf=ZI,QI=MA,JI=qf;function eR(e,t){t=QI(t,e);for(var n=0,r=t.length;e!=null&&n<r;)e=e[JI(t[n++])];return n&&n==r?e:void 0}var Hv=eR,tR=Hv;function nR(e,t,n){var r=e==null?void 0:tR(e,t);return r===void 0?n:r}var IA=nR;const Ut=be(IA);function rR(e){return e==null}var iR=rR;const ie=be(iR);var aR=dr,oR=Nt,lR=pr,sR="[object String]";function uR(e){return typeof e=="string"||!oR(e)&&lR(e)&&aR(e)==sR}var cR=uR;const ji=be(cR);var RA={exports:{}},ve={};/**
67
+ */function bc(){return bc=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},bc.apply(this,arguments)}function OA(e,t){if(e==null)return{};var n={},r=Object.keys(e),i,a;for(a=0;a<r.length;a++)i=r[a],!(t.indexOf(i)>=0)&&(n[i]=e[i]);return n}function ON(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}function AN(e,t){return e.button===0&&(!t||t==="_self")&&!ON(e)}const EN=["onClick","relative","reloadDocument","replace","state","target","to","preventScrollReset","viewTransition"],PN=["aria-current","caseSensitive","className","end","style","to","viewTransition","children"],TN="6";try{window.__reactRouterVersion=TN}catch{}const kN=$.createContext({isTransitioning:!1}),$N="startTransition",Pb=y$[$N];function jN(e){let{basename:t,children:n,future:r,window:i}=e,a=$.useRef();a.current==null&&(a.current=$C({window:i,v5Compat:!0}));let o=a.current,[l,s]=$.useState({action:o.action,location:o.location}),{v7_startTransition:u}=r||{},f=$.useCallback(c=>{u&&Pb?Pb(()=>s(c)):s(c)},[s,u]);return $.useLayoutEffect(()=>o.listen(f),[o,f]),$.useEffect(()=>xN(r),[r]),$.createElement(SN,{basename:t,children:n,location:l.location,navigationType:l.action,navigator:o,future:r})}const CN=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u",NN=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,MN=$.forwardRef(function(t,n){let{onClick:r,relative:i,reloadDocument:a,replace:o,state:l,target:s,to:u,preventScrollReset:f,viewTransition:c}=t,d=OA(t,EN),{basename:p}=$.useContext(Gr),y,m=!1;if(typeof u=="string"&&NN.test(u)&&(y=u,CN))try{let b=new URL(window.location.href),x=u.startsWith("//")?new URL(b.protocol+u):new URL(u),w=Ra(x.pathname,p);x.origin===b.origin&&w!=null?u=w+x.search+x.hash:m=!0}catch{}let v=nN(u,{relative:i}),h=RN(u,{replace:o,state:l,target:s,preventScrollReset:f,relative:i,viewTransition:c});function g(b){r&&r(b),b.defaultPrevented||h(b)}return $.createElement("a",bc({},d,{href:y||v,onClick:m||a?r:g,ref:n,target:s}))}),tl=$.forwardRef(function(t,n){let{"aria-current":r="page",caseSensitive:i=!1,className:a="",end:o=!1,style:l,to:s,viewTransition:u,children:f}=t,c=OA(t,PN),d=Vf(s,{relative:c.relative}),p=$s(),y=$.useContext(yA),{navigator:m,basename:v}=$.useContext(Gr),h=y!=null&&LN(d)&&u===!0,g=m.encodeLocation?m.encodeLocation(d).pathname:d.pathname,b=p.pathname,x=y&&y.navigation&&y.navigation.location?y.navigation.location.pathname:null;i||(b=b.toLowerCase(),x=x?x.toLowerCase():null,g=g.toLowerCase()),x&&v&&(x=Ra(x,v)||x);const w=g!=="/"&&g.endsWith("/")?g.length-1:g.length;let S=b===g||!o&&b.startsWith(g)&&b.charAt(w)==="/",_=x!=null&&(x===g||!o&&x.startsWith(g)&&x.charAt(g.length)==="/"),A={isActive:S,isPending:_,isTransitioning:h},P=S?r:void 0,T;typeof a=="function"?T=a(A):T=[a,S?"active":null,_?"pending":null,h?"transitioning":null].filter(Boolean).join(" ");let I=typeof l=="function"?l(A):l;return $.createElement(MN,bc({},c,{"aria-current":P,className:T,ref:n,style:I,to:s,viewTransition:u}),typeof f=="function"?f(A):f)});var eg;(function(e){e.UseScrollRestoration="useScrollRestoration",e.UseSubmit="useSubmit",e.UseSubmitFetcher="useSubmitFetcher",e.UseFetcher="useFetcher",e.useViewTransitionState="useViewTransitionState"})(eg||(eg={}));var Tb;(function(e){e.UseFetcher="useFetcher",e.UseFetchers="useFetchers",e.UseScrollRestoration="useScrollRestoration"})(Tb||(Tb={}));function IN(e){let t=$.useContext(Wf);return t||De(!1),t}function RN(e,t){let{target:n,replace:r,state:i,preventScrollReset:a,relative:o,viewTransition:l}=t===void 0?{}:t,s=rN(),u=$s(),f=Vf(e,{relative:o});return $.useCallback(c=>{if(AN(c,n)){c.preventDefault();let d=r!==void 0?r:yc(u)===yc(f);s(e,{replace:d,state:i,preventScrollReset:a,relative:o,viewTransition:l})}},[u,s,f,r,i,n,e,a,o,l])}function LN(e,t){t===void 0&&(t={});let n=$.useContext(kN);n==null&&De(!1);let{basename:r}=IN(eg.useViewTransitionState),i=Vf(e,{relative:t.relative});if(!n.isTransitioning)return!1;let a=Ra(n.currentLocation.pathname,r)||n.currentLocation.pathname,o=Ra(n.nextLocation.pathname,r)||n.nextLocation.pathname;return Qh(i.pathname,o)!=null||Qh(i.pathname,a)!=null}const Rv="/api";async function fn(e){const t=await fetch(`${Rv}${e}`);if(!t.ok)throw new Error(`API ${e} failed: ${t.status}`);return t.json()}async function DN(e,t){const n=await fetch(`${Rv}${e}`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t)});if(!n.ok){let r=`${n.status}`;try{const i=await n.json();i!=null&&i.error&&(r=i.error)}catch{}throw new Error(r)}return n.json()}const kn={overview:()=>fn("/overview"),graph:()=>fn("/graph"),risk:()=>fn("/risk"),communities:()=>fn("/communities"),churn:()=>fn("/churn"),ownership:()=>fn("/ownership"),status:()=>fn("/status"),tokens:()=>fn("/tokens"),trends:(e="30d")=>fn(`/trends?range=${e}`),refresh:()=>fetch(`${Rv}/refresh`,{method:"POST"}).then(e=>e.json()),listProjects:()=>fn("/projects"),activeProject:()=>fn("/projects/active"),switchProject:e=>DN("/projects/active",{slug:e})},kb="ctxloom.dashboard.activeSlug";function BN(){const[e,t]=$.useState([]),[n,r]=$.useState(null),[i,a]=$.useState(!1),[o,l]=$.useState(null),[s,u]=$.useState(null);$.useEffect(()=>{let c=!1;return kn.listProjects().then(({projects:d})=>{if(c)return;t(d);const p=d.find(m=>m.isActive)??d[0];r(p);const y=localStorage.getItem(kb);y&&y!==p.slug&&d.some(m=>m.slug===y)&&f(y)}).catch(d=>{c||u(d instanceof Error?d.message:String(d))}),()=>{c=!0}},[]),$.useEffect(()=>{if(!i)return;function c(d){var y;const p=d.target;(y=p==null?void 0:p.closest)!=null&&y.call(p,"[data-project-switcher]")||a(!1)}return document.addEventListener("click",c),()=>document.removeEventListener("click",c)},[i]);async function f(c){l(c),u(null);try{const{active:d}=await kn.switchProject(c);localStorage.setItem(kb,d.slug),window.location.reload()}catch(d){u(d instanceof Error?d.message:String(d)),l(null)}}return n?e.length<=1?O.jsx(FN,{name:n.name,alias:n.alias,root:n.root}):O.jsxs("div",{className:"relative px-2 py-2","data-project-switcher":!0,children:[O.jsxs("button",{type:"button",onClick:()=>a(c=>!c),disabled:o!==null,className:"w-full flex items-center justify-between gap-2 rounded-md px-2.5 py-2 text-xs text-white/80 hover:bg-white/5 transition-colors disabled:opacity-50",title:n.root,children:[O.jsxs("span",{className:"flex items-center gap-2 min-w-0",children:[O.jsx("span",{className:"text-white/40 shrink-0",children:"◆"}),n.alias?O.jsxs("span",{className:"truncate flex flex-col leading-none gap-0.5",children:[O.jsx("span",{className:"font-semibold",children:n.alias}),O.jsx("span",{className:"text-[10px] text-white/40",children:n.name})]}):O.jsx("span",{className:"truncate",children:n.name})]}),O.jsx("span",{className:"text-white/30 text-[10px] shrink-0",children:i?"▴":"▾"})]}),i&&O.jsx("div",{className:"absolute left-2 right-2 mt-1 z-20 rounded-md bg-[#1f1e2c] py-1 shadow-lg",style:{border:"1px solid rgba(255,255,255,0.08)"},children:e.map(c=>O.jsxs("button",{type:"button",onClick:()=>{a(!1),c.slug!==n.slug&&f(c.slug)},disabled:o!==null,className:`w-full text-left px-3 py-1.5 text-xs flex items-center gap-2 transition-colors ${c.slug===n.slug?"text-[#a78bfa] bg-[#603dc6]/10":"text-white/70 hover:bg-white/5"} disabled:opacity-50`,title:c.root,children:[O.jsx("span",{className:"shrink-0 w-3 text-center",children:c.slug===n.slug?"●":" "}),c.alias?O.jsxs("span",{className:"truncate flex-1 flex flex-col leading-none gap-0.5",children:[O.jsx("span",{className:"font-semibold",children:c.alias}),O.jsx("span",{className:"text-[10px] text-white/40",children:c.name})]}):O.jsx("span",{className:"truncate flex-1",children:c.name}),!c.hasSnapshot&&O.jsx("span",{className:"text-[10px] text-white/30 shrink-0",title:"Never indexed — first switch will be slow",children:"cold"}),c.isDefault&&O.jsx("span",{className:"text-[10px] text-white/30 shrink-0",title:"Project the dashboard was launched against",children:"default"})]},c.slug))}),o&&O.jsx("div",{className:"px-2.5 py-1 text-[10px] text-white/40",children:"switching… (cold start may take a moment)"}),s&&O.jsx("div",{className:"px-2.5 py-1 text-[10px] text-red-400/80",role:"alert",children:s})]}):O.jsx("div",{className:"px-3 py-2 text-xs text-white/30",children:s?`Projects unavailable: ${s}`:"Loading projects…"})}function FN({name:e,alias:t,root:n}){const[r,i]=$.useState(!1),a="ctxloom register",[o,l]=$.useState(!1);return O.jsxs("div",{className:"px-3 py-2",children:[O.jsxs("div",{className:"flex items-center gap-2 text-xs",children:[O.jsx("span",{className:"text-white/30 shrink-0",children:"◆"}),t?O.jsxs("span",{className:"truncate flex-1 min-w-0 flex flex-col leading-none gap-0.5",title:n,children:[O.jsx("span",{className:"text-white/80 font-semibold",children:t}),O.jsx("span",{className:"text-[10px] text-white/40",children:e})]}):O.jsx("span",{className:"text-white/80 truncate flex-1 min-w-0",title:n,children:e}),O.jsx("button",{type:"button",onClick:()=>i(s=>!s),className:"shrink-0 text-white/30 hover:text-white/70 transition-colors text-sm w-4 leading-none","aria-label":"How to add more projects",title:"Add more projects",children:r?"×":"+"})]}),r&&O.jsxs("div",{className:"mt-2 text-[11px] text-white/50 leading-snug",children:["Track multiple projects in one dashboard:",O.jsxs("div",{className:"mt-1.5 flex items-stretch gap-1",children:[O.jsx("code",{className:"flex-1 min-w-0 truncate rounded bg-black/40 px-2 py-1 text-white/80 font-mono text-[10px]",children:a}),O.jsx("button",{type:"button",onClick:()=>{var s;(s=navigator.clipboard)==null||s.writeText(a),l(!0),setTimeout(()=>l(!1),1200)},className:"shrink-0 rounded bg-white/5 px-2 text-[10px] text-white/60 hover:bg-white/10 transition-colors","aria-label":"Copy command",children:o?"✓":"copy"})]}),O.jsx("div",{className:"mt-1.5 text-white/30",children:"Run inside any repo, then refresh this page."})]})]})}const zN=[{to:"/",label:"Overview",icon:"◈"},{to:"/graph",label:"Graph",icon:"⬡"},{to:"/risk",label:"Risk",icon:"⚠"},{to:"/trends",label:"Trends",icon:"⤴"},{to:"/communities",label:"Communities",icon:"⬡⬡"},{to:"/ownership",label:"Ownership",icon:"◎"},{to:"/guide",label:"Guide",icon:"◉"}];function UN(){return O.jsxs("div",{className:"flex h-screen bg-[#18181f]",children:[O.jsxs("aside",{className:"w-52 shrink-0 bg-[#131220] flex flex-col",style:{borderRight:"1px solid rgba(255,255,255,0.07)"},children:[O.jsxs("div",{className:"px-4 py-4 flex items-center gap-2.5",style:{borderBottom:"1px solid rgba(255,255,255,0.07)"},children:[O.jsx("img",{src:"/logo.svg",alt:"ctxloom",className:"w-6 h-6 shrink-0"}),O.jsxs("div",{children:[O.jsxs("span",{className:"text-sm font-semibold",children:[O.jsx("span",{className:"text-white",children:"ctx"}),O.jsx("span",{className:"text-[#a78bfa]",children:"loom"})]}),O.jsx("span",{className:"ml-1 text-xs text-white/30",children:"dashboard"})]})]}),O.jsx("div",{style:{borderBottom:"1px solid rgba(255,255,255,0.07)"},children:O.jsx(BN,{})}),O.jsx("nav",{className:"flex-1 py-4 space-y-1 px-2",children:zN.map(({to:e,label:t,icon:n})=>O.jsxs(tl,{to:e,end:e==="/",className:({isActive:r})=>`flex items-center gap-2 rounded-md px-3 py-2 text-sm transition-colors ${r?"bg-[#603dc6]/15 text-[#a78bfa] font-medium":"text-white/40 hover:text-white/70 hover:bg-white/5"}`,children:[O.jsx("span",{className:"text-xs select-none shrink-0",children:n}),t]},e))})]}),O.jsx("main",{className:"flex-1 overflow-y-auto p-8 bg-[#18181f]",children:O.jsx(wN,{})})]})}function Si(e){const[t,n]=$.useState({status:"loading"});return $.useEffect(()=>{let r=!1;return n({status:"loading"}),e().then(i=>{r||n({status:"success",data:i})}).catch(i=>{r||n({status:"error",message:String(i)})}),()=>{r=!0}},[]),t}function au({label:e,value:t,sub:n}){return O.jsxs("div",{className:"bg-[#1e1d2a] border border-white/10 rounded-xl p-5 transition-transform hover:-translate-y-0.5",children:[O.jsx("p",{className:"text-white/50 text-xs uppercase tracking-wider",children:e}),O.jsx("p",{className:"text-white text-3xl font-semibold mt-1",children:t}),n&&O.jsx("p",{className:"text-white/40 text-xs mt-1",children:n})]})}const WN={critical:"bg-red-900/50 text-red-300 font-semibold",high:"bg-orange-900/50 text-orange-300",medium:"bg-yellow-900/50 text-yellow-300",low:"bg-green-900/50 text-green-300"},$b={churn:.4,bugDensity:.3,coupling:.3},HN={churn:"Churn",bugDensity:"Bug density",coupling:"Coupling"},VN={critical:"Top 5% by intrinsic risk in this repo. Prioritise refactor or test coverage.",high:"Next 10% — meaningful intrinsic risk. Review when touching this area.",medium:"Next 20% — moderate intrinsic risk. Worth keeping an eye on.",low:"Bottom 65% — healthy file by intrinsic risk metrics."},jb=296,Cb=230,wp=8;function AA({level:e,breakdown:t,score:n,busFactor:r,topOwner:i,siloed:a}){const o=WN[e]??"bg-white/10 text-white/50";if(!t)return O.jsx("span",{className:`inline-block rounded-full px-2.5 py-0.5 text-xs ${o}`,children:e});const l=$.useRef(null),[s,u]=$.useState(!1),[f,c]=$.useState(!1),[d,p]=$.useState(null),[y,m]=$.useState(!1);$.useEffect(()=>{var b;if(typeof window>"u"||!window.matchMedia)return;const h=window.matchMedia("(hover: none)"),g=()=>m(h.matches);return g(),(b=h.addEventListener)==null||b.call(h,"change",g),()=>{var x;return(x=h.removeEventListener)==null?void 0:x.call(h,"change",g)}},[]),$.useLayoutEffect(()=>{if(!s||!l.current)return;const h=l.current.getBoundingClientRect(),b=h.bottom+Cb+wp>window.innerHeight?h.top-Cb-wp:h.bottom+wp,x=Math.max(8,Math.min(window.innerWidth-jb-8,h.left));p({top:b,left:x})},[s]),$.useEffect(()=>{if(!f)return;const h=b=>{if(!l.current)return;const x=b.target;if(l.current.contains(x))return;const w=document.getElementById("risk-badge-tooltip");w&&w.contains(x)||(c(!1),u(!1))},g=b=>{b.key==="Escape"&&(c(!1),u(!1))};return document.addEventListener("mousedown",h),document.addEventListener("keydown",g),()=>{document.removeEventListener("mousedown",h),document.removeEventListener("keydown",g)}},[f]);const v=Object.keys($b).map(h=>({key:h,label:HN[h],normalized:t[h],contribution:t[h]*$b[h]})).sort((h,g)=>g.contribution-h.contribution);return O.jsxs(O.Fragment,{children:[O.jsx("button",{ref:l,type:"button","aria-expanded":s,"aria-describedby":s?"risk-badge-tooltip":void 0,className:`inline-block rounded-full px-2.5 py-0.5 text-xs cursor-pointer ${o}`,onMouseEnter:()=>!y&&!f&&u(!0),onMouseLeave:()=>!y&&!f&&u(!1),onFocus:()=>!y&&!f&&u(!0),onBlur:()=>!y&&!f&&u(!1),onClick:h=>{h.stopPropagation(),f?(c(!1),u(!1)):(c(!0),u(!0))},children:e}),s&&d&&O.jsxs("div",{id:"risk-badge-tooltip",role:"tooltip",style:{position:"fixed",top:d.top,left:d.left,width:jb},className:"z-50 rounded-lg border border-white/10 bg-[#131220] p-3 text-left text-xs shadow-xl",children:[O.jsxs("div",{className:"flex items-center justify-between mb-1",children:[O.jsxs("span",{className:"text-white font-medium",children:[e," ",typeof n=="number"&&O.jsxs("span",{className:"text-white/40 font-normal",children:["(",n.toFixed(2),")"]})]}),f&&O.jsx("span",{className:"text-[10px] text-white/40",children:y?"tap badge or outside to close":"click to unpin · esc"})]}),O.jsx("div",{className:"text-white/50 mb-2",children:VN[e]??""}),O.jsx("div",{className:"text-white/40 text-[10px] uppercase tracking-wide mb-1",children:"Intrinsic risk contribution"}),O.jsx("div",{className:"space-y-1",children:v.map(h=>O.jsxs("div",{className:"flex items-center gap-2",children:[O.jsx("span",{className:"w-20 shrink-0 text-white/60",children:h.label}),O.jsx("span",{className:"flex-1 h-1.5 rounded bg-white/5 overflow-hidden",children:O.jsx("span",{className:"block h-full bg-[#a78bfa]",style:{width:`${Math.round(h.normalized*100)}%`}})}),O.jsxs("span",{className:"w-10 shrink-0 text-right text-white/50 tabular-nums",children:["+",h.contribution.toFixed(2)]})]},h.key))}),(typeof r=="number"||i)&&O.jsxs(O.Fragment,{children:[O.jsxs("div",{className:"text-white/40 text-[10px] uppercase tracking-wide mt-3 mb-1",children:["Ownership ",O.jsx("span",{className:"text-white/30 normal-case",children:"(not in score)"})]}),O.jsxs("div",{className:"text-white/60 leading-relaxed",children:[i&&O.jsxs(O.Fragment,{children:["Owner: ",O.jsx("span",{className:"text-white/80",children:i}),O.jsx("br",{})]}),typeof r=="number"&&O.jsxs(O.Fragment,{children:["Bus factor: ",O.jsx("span",{className:"text-white/80",children:r}),a&&O.jsx("span",{className:"text-yellow-300/80",children:" · knowledge silo"})]})]})]}),O.jsx("div",{className:"mt-3 text-[10px] text-white/30 leading-relaxed",children:"Score: 40% churn + 30% bugs + 30% coupling, normalized to repo p90. Labels are percentile-banded (top 5% critical, next 10% high, next 20% medium)."})]})]})}function mo({message:e}){return O.jsx("div",{className:"bg-red-900/30 border border-red-500/30 text-red-300 rounded-lg p-3 text-sm",children:e})}function EA(e){var t,n,r="";if(typeof e=="string"||typeof e=="number")r+=e;else if(typeof e=="object")if(Array.isArray(e)){var i=e.length;for(t=0;t<i;t++)e[t]&&(n=EA(e[t]))&&(r&&(r+=" "),r+=n)}else for(n in e)e[n]&&(r&&(r+=" "),r+=n);return r}function se(){for(var e,t,n=0,r="",i=arguments.length;n<i;n++)(e=arguments[n])&&(t=EA(e))&&(r&&(r+=" "),r+=t);return r}var GN=Array.isArray,Nt=GN,KN=typeof zs=="object"&&zs&&zs.Object===Object&&zs,PA=KN,XN=PA,YN=typeof self=="object"&&self&&self.Object===Object&&self,qN=XN||YN||Function("return this")(),Dn=qN,ZN=Dn,QN=ZN.Symbol,js=QN,Nb=js,TA=Object.prototype,JN=TA.hasOwnProperty,e2=TA.toString,Bo=Nb?Nb.toStringTag:void 0;function t2(e){var t=JN.call(e,Bo),n=e[Bo];try{e[Bo]=void 0;var r=!0}catch{}var i=e2.call(e);return r&&(t?e[Bo]=n:delete e[Bo]),i}var n2=t2,r2=Object.prototype,i2=r2.toString;function a2(e){return i2.call(e)}var o2=a2,Mb=js,l2=n2,s2=o2,u2="[object Null]",c2="[object Undefined]",Ib=Mb?Mb.toStringTag:void 0;function f2(e){return e==null?e===void 0?c2:u2:Ib&&Ib in Object(e)?l2(e):s2(e)}var dr=f2;function d2(e){return e!=null&&typeof e=="object"}var pr=d2,p2=dr,h2=pr,g2="[object Symbol]";function m2(e){return typeof e=="symbol"||h2(e)&&p2(e)==g2}var vo=m2,v2=Nt,y2=vo,b2=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,x2=/^\w*$/;function w2(e,t){if(v2(e))return!1;var n=typeof e;return n=="number"||n=="symbol"||n=="boolean"||e==null||y2(e)?!0:x2.test(e)||!b2.test(e)||t!=null&&e in Object(t)}var Lv=w2;function S2(e){var t=typeof e;return e!=null&&(t=="object"||t=="function")}var Xr=S2;const yo=be(Xr);var _2=dr,O2=Xr,A2="[object AsyncFunction]",E2="[object Function]",P2="[object GeneratorFunction]",T2="[object Proxy]";function k2(e){if(!O2(e))return!1;var t=_2(e);return t==E2||t==P2||t==A2||t==T2}var Dv=k2;const ne=be(Dv);var $2=Dn,j2=$2["__core-js_shared__"],C2=j2,Sp=C2,Rb=function(){var e=/[^.]+$/.exec(Sp&&Sp.keys&&Sp.keys.IE_PROTO||"");return e?"Symbol(src)_1."+e:""}();function N2(e){return!!Rb&&Rb in e}var M2=N2,I2=Function.prototype,R2=I2.toString;function L2(e){if(e!=null){try{return R2.call(e)}catch{}try{return e+""}catch{}}return""}var kA=L2,D2=Dv,B2=M2,F2=Xr,z2=kA,U2=/[\\^$.*+?()[\]{}|]/g,W2=/^\[object .+?Constructor\]$/,H2=Function.prototype,V2=Object.prototype,G2=H2.toString,K2=V2.hasOwnProperty,X2=RegExp("^"+G2.call(K2).replace(U2,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");function Y2(e){if(!F2(e)||B2(e))return!1;var t=D2(e)?X2:W2;return t.test(z2(e))}var q2=Y2;function Z2(e,t){return e==null?void 0:e[t]}var Q2=Z2,J2=q2,eM=Q2;function tM(e,t){var n=eM(e,t);return J2(n)?n:void 0}var Fi=tM,nM=Fi,rM=nM(Object,"create"),Gf=rM,Lb=Gf;function iM(){this.__data__=Lb?Lb(null):{},this.size=0}var aM=iM;function oM(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}var lM=oM,sM=Gf,uM="__lodash_hash_undefined__",cM=Object.prototype,fM=cM.hasOwnProperty;function dM(e){var t=this.__data__;if(sM){var n=t[e];return n===uM?void 0:n}return fM.call(t,e)?t[e]:void 0}var pM=dM,hM=Gf,gM=Object.prototype,mM=gM.hasOwnProperty;function vM(e){var t=this.__data__;return hM?t[e]!==void 0:mM.call(t,e)}var yM=vM,bM=Gf,xM="__lodash_hash_undefined__";function wM(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=bM&&t===void 0?xM:t,this}var SM=wM,_M=aM,OM=lM,AM=pM,EM=yM,PM=SM;function bo(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}bo.prototype.clear=_M;bo.prototype.delete=OM;bo.prototype.get=AM;bo.prototype.has=EM;bo.prototype.set=PM;var TM=bo;function kM(){this.__data__=[],this.size=0}var $M=kM;function jM(e,t){return e===t||e!==e&&t!==t}var Bv=jM,CM=Bv;function NM(e,t){for(var n=e.length;n--;)if(CM(e[n][0],t))return n;return-1}var Kf=NM,MM=Kf,IM=Array.prototype,RM=IM.splice;function LM(e){var t=this.__data__,n=MM(t,e);if(n<0)return!1;var r=t.length-1;return n==r?t.pop():RM.call(t,n,1),--this.size,!0}var DM=LM,BM=Kf;function FM(e){var t=this.__data__,n=BM(t,e);return n<0?void 0:t[n][1]}var zM=FM,UM=Kf;function WM(e){return UM(this.__data__,e)>-1}var HM=WM,VM=Kf;function GM(e,t){var n=this.__data__,r=VM(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}var KM=GM,XM=$M,YM=DM,qM=zM,ZM=HM,QM=KM;function xo(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}xo.prototype.clear=XM;xo.prototype.delete=YM;xo.prototype.get=qM;xo.prototype.has=ZM;xo.prototype.set=QM;var Xf=xo,JM=Fi,eI=Dn,tI=JM(eI,"Map"),Fv=tI,Db=TM,nI=Xf,rI=Fv;function iI(){this.size=0,this.__data__={hash:new Db,map:new(rI||nI),string:new Db}}var aI=iI;function oI(e){var t=typeof e;return t=="string"||t=="number"||t=="symbol"||t=="boolean"?e!=="__proto__":e===null}var lI=oI,sI=lI;function uI(e,t){var n=e.__data__;return sI(t)?n[typeof t=="string"?"string":"hash"]:n.map}var Yf=uI,cI=Yf;function fI(e){var t=cI(this,e).delete(e);return this.size-=t?1:0,t}var dI=fI,pI=Yf;function hI(e){return pI(this,e).get(e)}var gI=hI,mI=Yf;function vI(e){return mI(this,e).has(e)}var yI=vI,bI=Yf;function xI(e,t){var n=bI(this,e),r=n.size;return n.set(e,t),this.size+=n.size==r?0:1,this}var wI=xI,SI=aI,_I=dI,OI=gI,AI=yI,EI=wI;function wo(e){var t=-1,n=e==null?0:e.length;for(this.clear();++t<n;){var r=e[t];this.set(r[0],r[1])}}wo.prototype.clear=SI;wo.prototype.delete=_I;wo.prototype.get=OI;wo.prototype.has=AI;wo.prototype.set=EI;var zv=wo,$A=zv,PI="Expected a function";function Uv(e,t){if(typeof e!="function"||t!=null&&typeof t!="function")throw new TypeError(PI);var n=function(){var r=arguments,i=t?t.apply(this,r):r[0],a=n.cache;if(a.has(i))return a.get(i);var o=e.apply(this,r);return n.cache=a.set(i,o)||a,o};return n.cache=new(Uv.Cache||$A),n}Uv.Cache=$A;var jA=Uv;const TI=be(jA);var kI=jA,$I=500;function jI(e){var t=kI(e,function(r){return n.size===$I&&n.clear(),r}),n=t.cache;return t}var CI=jI,NI=CI,MI=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,II=/\\(\\)?/g,RI=NI(function(e){var t=[];return e.charCodeAt(0)===46&&t.push(""),e.replace(MI,function(n,r,i,a){t.push(i?a.replace(II,"$1"):r||n)}),t}),LI=RI;function DI(e,t){for(var n=-1,r=e==null?0:e.length,i=Array(r);++n<r;)i[n]=t(e[n],n,e);return i}var Wv=DI,Bb=js,BI=Wv,FI=Nt,zI=vo,Fb=Bb?Bb.prototype:void 0,zb=Fb?Fb.toString:void 0;function CA(e){if(typeof e=="string")return e;if(FI(e))return BI(e,CA)+"";if(zI(e))return zb?zb.call(e):"";var t=e+"";return t=="0"&&1/e==-1/0?"-0":t}var UI=CA,WI=UI;function HI(e){return e==null?"":WI(e)}var NA=HI,VI=Nt,GI=Lv,KI=LI,XI=NA;function YI(e,t){return VI(e)?e:GI(e,t)?[e]:KI(XI(e))}var MA=YI,qI=vo;function ZI(e){if(typeof e=="string"||qI(e))return e;var t=e+"";return t=="0"&&1/e==-1/0?"-0":t}var qf=ZI,QI=MA,JI=qf;function eR(e,t){t=QI(t,e);for(var n=0,r=t.length;e!=null&&n<r;)e=e[JI(t[n++])];return n&&n==r?e:void 0}var Hv=eR,tR=Hv;function nR(e,t,n){var r=e==null?void 0:tR(e,t);return r===void 0?n:r}var IA=nR;const Ut=be(IA);function rR(e){return e==null}var iR=rR;const ie=be(iR);var aR=dr,oR=Nt,lR=pr,sR="[object String]";function uR(e){return typeof e=="string"||!oR(e)&&lR(e)&&aR(e)==sR}var cR=uR;const ji=be(cR);var RA={exports:{}},ve={};/**
68
68
  * @license React
69
69
  * react-is.production.min.js
70
70
  *
@@ -0,0 +1 @@
1
+ @import"https://cdn.jsdelivr.net/npm/geist@1.3.0/dist/fonts/geist-sans/style.css";*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.pointer-events-none{pointer-events:none}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.bottom-3{bottom:.75rem}.left-2{left:.5rem}.left-3{left:.75rem}.right-0{right:0}.right-2{right:.5rem}.right-3{right:.75rem}.top-0{top:0}.top-3{top:.75rem}.z-10{z-index:10}.z-20{z-index:20}.z-40{z-index:40}.z-50{z-index:50}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.h-1\.5{height:.375rem}.h-14{height:3.5rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-6{height:1.5rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-48{max-height:12rem}.w-10{width:2.5rem}.w-2\.5{width:.625rem}.w-20{width:5rem}.w-3{width:.75rem}.w-36{width:9rem}.w-4{width:1rem}.w-48{width:12rem}.w-52{width:13rem}.w-6{width:1.5rem}.w-\[680px\]{width:680px}.w-full{width:100%}.min-w-0{min-width:0px}.min-w-full{min-width:100%}.max-w-3xl{max-width:48rem}.max-w-\[60\%\]{max-width:60%}.max-w-full{max-width:100%}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.grow{flex-grow:1}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.scroll-mt-6{scroll-margin-top:1.5rem}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-1\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.375rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.375rem * var(--tw-space-y-reverse))}.space-y-10>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2.5rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-\[rgba\(255\,255\,255\,0\.05\)\]>:not([hidden])~:not([hidden]){border-color:#ffffff0d}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-\[rgba\(255\,255\,255\,0\.05\)\]{border-color:#ffffff0d}.border-red-500\/30{border-color:#ef44444d}.border-white\/10{border-color:#ffffff1a}.border-yellow-500\/30{border-color:#eab3084d}.bg-\[\#131220\]{--tw-bg-opacity: 1;background-color:rgb(19 18 32 / var(--tw-bg-opacity, 1))}.bg-\[\#18181f\]{--tw-bg-opacity: 1;background-color:rgb(24 24 31 / var(--tw-bg-opacity, 1))}.bg-\[\#1e1d2a\]{--tw-bg-opacity: 1;background-color:rgb(30 29 42 / var(--tw-bg-opacity, 1))}.bg-\[\#1f1e2c\]{--tw-bg-opacity: 1;background-color:rgb(31 30 44 / var(--tw-bg-opacity, 1))}.bg-\[\#603dc6\]{--tw-bg-opacity: 1;background-color:rgb(96 61 198 / var(--tw-bg-opacity, 1))}.bg-\[\#603dc6\]\/10{background-color:#603dc61a}.bg-\[\#603dc6\]\/15{background-color:#603dc626}.bg-\[\#603dc6\]\/20{background-color:#603dc633}.bg-\[\#a78bfa\]{--tw-bg-opacity: 1;background-color:rgb(167 139 250 / var(--tw-bg-opacity, 1))}.bg-black\/40{background-color:#0006}.bg-green-900\/50{background-color:#14532d80}.bg-orange-900\/50{background-color:#7c2d1280}.bg-red-900\/30{background-color:#7f1d1d4d}.bg-red-900\/50{background-color:#7f1d1d80}.bg-white\/10{background-color:#ffffff1a}.bg-white\/5{background-color:#ffffff0d}.bg-yellow-900\/10{background-color:#713f121a}.bg-yellow-900\/20{background-color:#713f1233}.bg-yellow-900\/50{background-color:#713f1280}.p-0\.5{padding:.125rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-8{padding:2rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.pb-16{padding-bottom:4rem}.pt-0\.5{padding-top:.125rem}.pt-3{padding-top:.75rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.normal-case{text-transform:none}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-snug{line-height:1.375}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.text-\[\#603dc6\]{--tw-text-opacity: 1;color:rgb(96 61 198 / var(--tw-text-opacity, 1))}.text-\[\#a78bfa\]{--tw-text-opacity: 1;color:rgb(167 139 250 / var(--tw-text-opacity, 1))}.text-green-300{--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.text-green-300\/80{color:#86efaccc}.text-orange-300{--tw-text-opacity: 1;color:rgb(253 186 116 / var(--tw-text-opacity, 1))}.text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.text-red-300\/60{color:#fca5a599}.text-red-300\/80{color:#fca5a5cc}.text-red-400\/80{color:#f87171cc}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-white\/20{color:#fff3}.text-white\/30{color:#ffffff4d}.text-white\/40{color:#fff6}.text-white\/50{color:#ffffff80}.text-white\/60{color:#fff9}.text-white\/70{color:#ffffffb3}.text-white\/80{color:#fffc}.text-white\/90{color:#ffffffe6}.text-yellow-300{--tw-text-opacity: 1;color:rgb(253 224 71 / var(--tw-text-opacity, 1))}.text-yellow-300\/80{color:#fde047cc}.text-yellow-400{--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.line-through{text-decoration-line:line-through}.decoration-white\/30{text-decoration-color:#ffffff4d}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.ring{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}:root{--brand: #603dc6;--brand-light: #7c5fd6}body{font-family:Geist,system-ui,sans-serif;background:#18181f;color:#fafafa}::-webkit-scrollbar{width:5px;height:5px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#2e2c44;border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#603dc6}.placeholder\:text-white\/30::-moz-placeholder{color:#ffffff4d}.placeholder\:text-white\/30::placeholder{color:#ffffff4d}.hover\:-translate-y-0\.5:hover{--tw-translate-y: -.125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border-\[\#603dc6\]\/60:hover{border-color:#603dc699}.hover\:border-white\/20:hover{border-color:#fff3}.hover\:bg-\[\#603dc6\]\/30:hover{background-color:#603dc64d}.hover\:bg-white\/10:hover{background-color:#ffffff1a}.hover\:bg-white\/5:hover{background-color:#ffffff0d}.hover\:text-\[\#a78bfa\]:hover{--tw-text-opacity: 1;color:rgb(167 139 250 / var(--tw-text-opacity, 1))}.hover\:text-white\/70:hover{color:#ffffffb3}.hover\:ring-1:hover{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.hover\:ring-\[\#603dc6\]\/40:hover{--tw-ring-color: rgb(96 61 198 / .4)}.focus\:border-\[\#603dc6\]\/50:focus{border-color:#603dc680}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-\[\#603dc6\]\/50:focus{--tw-ring-color: rgb(96 61 198 / .5)}.disabled\:opacity-50:disabled{opacity:.5}@media (min-width: 1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>ctxloom dashboard</title>
7
- <script type="module" crossorigin src="/assets/index-Ci5_ZKGm.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-BvSIeKR7.css">
7
+ <script type="module" crossorigin src="/assets/index-Bfa2_GyA.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-MBoNDzdn.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>