From 245101ca6d648ec315964899c7487453df3dbd34 Mon Sep 17 00:00:00 2001 From: Umang Dhawan Date: Tue, 21 Jul 2026 15:26:35 -0500 Subject: [PATCH] fix: expose the first-run gate on mobile Signed-off-by: Umang Dhawan --- CHANGELOG.md | 9 +++++++ CLAUDE.md | 8 +++++- codemble/__init__.py | 2 +- .../{index-0OmvUbwQ.js => index-_4l8WmkY.js} | 2 +- codemble/web_dist/index.html | 2 +- docs-site/package.json | 2 +- docs/releases/v0.6.2.md | 25 +++++++++++++++++++ pyproject.toml | 2 +- web/package-lock.json | 4 +-- web/package.json | 4 +-- web/scripts/check_mode_gate_portal.mjs | 13 ++++++++++ web/src/ModeControl.jsx | 11 ++++++-- 12 files changed, 72 insertions(+), 12 deletions(-) rename codemble/web_dist/assets/{index-0OmvUbwQ.js => index-_4l8WmkY.js} (96%) create mode 100644 docs/releases/v0.6.2.md create mode 100644 web/scripts/check_mode_gate_portal.mjs diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f80f6b..4b35fe3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) · Versioning: ## [Unreleased] +## [0.6.2] - 2026-07-21 + +### Fixed +- **The first-run audience question is visible on a fresh narrow window.** + v0.6.1 moved the audience control into the compact Menu, but its native modal + stayed inside that closed disclosure. The browser opened an invisible modal + backdrop that blocked the page. The gate now portals directly to the document + top layer while the post-choice Easy/Expert toggle remains in the Menu. + ## [0.6.1] - 2026-07-21 ### Fixed diff --git a/CLAUDE.md b/CLAUDE.md index 2225e3e..50627d4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -168,7 +168,12 @@ Polish, then the coordinated launch (Show HN / X; lit-galaxy GIF as hero). ## Current State **[AGENT-MAINTAINED]** **Current milestone: Phase 1 tester evidence** · Last updated: 2026-07-21 · -Session note: v0.6.1 closes the four verified user-flow gaps from the +Session note: v0.6.2 is the immediate installed-artifact hotfix for v0.6.1: +the first-run audience modal now portals to the document top layer, so the +closed compact Menu cannot hide the dialog while its modal backdrop blocks a +fresh narrow window. The public PyPI smoke caught the containment defect after +v0.6.1 publication; v0.6.2 supersedes it rather than pretending an immutable +artifact can be replaced. v0.6.1 closes the four verified user-flow gaps from the 2026-07-21 usability audit: the 320 px shell reserves a usable map/study stage, Modules and Find render from the Star chart, required Home calibration finishes before coach marks begin, and parser-owned 3D nodes no longer install drag @@ -542,6 +547,7 @@ shows lower repeated-commit work without changing derived values. | 2026-07-21 | The Map gains zoom, Fit, and drag-to-pan; panning rides the container's own scroll and zoom only scales the rendered size | The 2D counterpart of bounded orbit: a 960x2640 diagram in a plain scroll box showed four of nine layers and no way to see the whole shape. Scroll-based panning keeps native scrollbars, keyboard scrolling and screen-reader behaviour intact, and because every coordinate inside the SVG stays backend-computed, React remains a pure renderer of graph-owned geometry. It opens at true size rather than auto-fitting: fitting on mount measured the scroller before layout settled and landed on a scale that was neither fitted nor honest | | 2026-07-21 | v0.6.0 deepens five private boundaries without changing the HTTP, graph, check, persistence, or learner-visible contracts: Project Selection, Project Activation, Project Mapping Run, Name Atlas, and Learner Projection | Approved by UD as five behavior-preserving waves in one release PR. The deletion test now holds at each seam, stale activation and mapping responses lose atomically, and dependency-scoped learner projections measured ~0.331 ms → ~0.001 ms per hover commit on a synthetic 1,000-node project while preserving derived outputs | | 2026-07-21 | v0.6.1 treats Modules and Find as global surfaces, sequences first-run decisions as audience → required Home → coach, and makes the 3D parser-owned layout explicitly non-draggable | Approved by UD as implementation of every verified user-flow audit finding. Global commands must never accept hidden state, onboarding must expose one foreground decision at a time, and learners orbit the immutable graph rather than editing its coordinates. The compact shell is a structural breakpoint of the existing Formal Edo interface, not a new visual system | +| 2026-07-21 | First-run audience modal portals to `document.body`; the persistent Easy/Expert toggle remains in responsive header chrome | A native modal inside the closed compact Menu entered the top layer but inherited `display:none` from its ancestor, leaving an invisible backdrop that blocked fresh mobile runs. Modal ownership is a document boundary, not header layout. Caught only by the clean public v0.6.1 installed-artifact smoke; PyPI immutability requires v0.6.2 rather than replacing 0.6.1 | ## Non-Goals — do NOT build (point here when asked) diff --git a/codemble/__init__.py b/codemble/__init__.py index 28ed4e3..ba03db3 100644 --- a/codemble/__init__.py +++ b/codemble/__init__.py @@ -1,4 +1,4 @@ """Codemble — a learning game that turns the code AI wrote for you into a galaxy you light up by understanding it. See CLAUDE.md for the agent brief and roadmap.""" -__version__ = "0.6.1" +__version__ = "0.6.2" diff --git a/codemble/web_dist/assets/index-0OmvUbwQ.js b/codemble/web_dist/assets/index-_4l8WmkY.js similarity index 96% rename from codemble/web_dist/assets/index-0OmvUbwQ.js rename to codemble/web_dist/assets/index-_4l8WmkY.js index 73cdc7b..5ce4fb7 100644 --- a/codemble/web_dist/assets/index-0OmvUbwQ.js +++ b/codemble/web_dist/assets/index-_4l8WmkY.js @@ -5349,4 +5349,4 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho float bloomAlpha = max( bloom.r, max( bloom.g, bloom.b ) ); gl_FragColor = vec4( bloom, bloomAlpha ); - }`})}};UW.BlurDirectionX=new L(1,0),UW.BlurDirectionY=new L(0,1);var WW=.9,GW=.45,KW=.52,qW=1600;function JW(e){let t=e.postProcessingComposer(),n=new UW(new L(t._width??1,t._height??1),WW,GW,KW),r=n.setSize.bind(n);n.setSize=(e,t)=>{let n=Math.min(1,qW/Math.max(e,t,1));r(Math.max(1,Math.round(e*n)),Math.max(1,Math.round(t*n)))},t.addPass(n);let i=new Ez(xz);return t.addPass(i),{pass:n,composer:t,dispose(){t.removePass(i),i.dispose(),t.removePass(n),n.dispose()}}}var YW=1200;function XW(){return globalThis.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches??!1}function ZW({scene:e,regionId:t,palette:n}){if(XW())return()=>{};let r=e.getObjectByName(`codemble-system-${t}`);if(!r)return()=>{};let i=[];r.traverse(e=>{e.isSprite&&i.push([e,e.material.opacity,e.scale.x])});let a=new B(n.star),o=i.map(([e])=>e.material.color.clone()),s=0,c=performance.now(),l=()=>{let e=Math.min(1,(performance.now()-c)/YW);1-(1-e)**3;let t=Math.sin(e*Math.PI);if(i.forEach(([e,n,r],i)=>{e.material.color.copy(o[i]).lerp(a,t*.85),e.material.opacity=n+t*.5,e.scale.setScalar(r*(1+t*.45))}),e<1){s=requestAnimationFrame(l);return}i.forEach(([e,t,n],r)=>{e.material.color.copy(o[r]),e.material.opacity=t,e.scale.setScalar(n)})};return s=requestAnimationFrame(l),()=>{cancelAnimationFrame(s),i.forEach(([e,t,n],r)=>{e.material.color.copy(o[r]),e.material.opacity=t,e.scale.setScalar(n)})}}var QW=Object.freeze({width:132,height:30}),$W=Object.freeze({far:14,near:44}),eG=Object.freeze([0,-1,1,-2,2]),tG=4,nG=.034;function rG(e,{radius:t,aspect:n}){return e.scale.set(nG*n,nG,1),e.userData.baseOffsetY=t*2.2+1.2,e.position.set(0,e.userData.baseOffsetY,0),e.visible=!1,e.userData.codembleLabel=!0,e.userData.screenWidthFraction=nG*n,e.userData.screenHeightFraction=nG,e}function iG(e){let t=aG(e),n=new R,r=new R;function i({scene:e,camera:i,width:a,height:o,distance:s,distanceBounds:c,hoverNodeId:l=null}){let u=oG(e);for(let e of u)e.visible=!1;if(!u.length||!t.size)return Object.freeze({budget:0,shown:0,visibleIds:Object.freeze([])});let d=sG(s,c),f=[];for(let e of u){let s=e.userData.nodeId,c=e.parent;if(!c)continue;c.getWorldPosition(r);let u=e.userData.baseOffsetY??0,d=cG(r,u,i,a,o,n);if(!d)continue;let p=cG(r,u+1,i,a,o,n),m=p?Math.abs(p.screenY-d.screenY):0;f.push({sprite:e,nodeId:s,origin:r.clone(),base:u,pixelsPerUnit:m,anchor:d,halfWidth:(e.userData.screenWidthFraction??.14)*o/2,halfHeight:(e.userData.screenHeightFraction??.034)*o/2,rank:s===l?-1:t.get(s)??1/0})}f.sort((e,t)=>e.rank-t.rank||e.nodeId.localeCompare(t.nodeId));let p=new Set,m=[];for(let e of f){if(m.length>=d)break;let t=lG(e,{camera:i,width:a,height:o,projected:n,taken:p});if(t){for(let e of t.cells)p.add(e);e.sprite.position.y=e.base+t.offset,e.sprite.visible=!0,m.push(e.nodeId)}}return Object.freeze({budget:d,shown:m.length,visibleIds:Object.freeze(m)})}function a(e){for(let t of oG(e))t.visible=!1}return Object.freeze({hide:a,place:i})}function aG(e){let t=e.filter(e=>e.label).map(e=>({id:e.id,weight:(e.home?3e6:0)+(e.understood?1e6:0)+(e.centrality??0)*1e3})).sort((e,t)=>t.weight-e.weight||e.id.localeCompare(t.id));return new Map(t.map((e,t)=>[e.id,t]))}function oG(e){let t=[];return e.traverse(e=>{e.userData?.codembleLabel&&t.push(e)}),t}function sG(e,t){let n=Math.max(1,t.max-t.min),r=1-Math.min(1,Math.max(0,(e-t.min)/n));return Math.round($W.far+($W.near-$W.far)*r)}function cG(e,t,n,r,i,a){if(a.set(e.x,e.y+t,e.z).project(n),a.z>1)return null;let o=(a.x*.5+.5)*r,s=(-a.y*.5+.5)*i;return o<0||o>r||s<0||s>i?null:{screenX:o,screenY:s}}function lG(e,{camera:t,width:n,height:r,projected:i,taken:a}){let o=e.pixelsPerUnit?(e.halfHeight*2+tG)/e.pixelsPerUnit:0;for(let s of eG){let c=s*o,l=s===0?e.anchor:cG(e.origin,e.base+c,t,n,r,i);if(!l)continue;let u=uG(l,e);if(!u.some(e=>a.has(e)))return{cells:u,offset:c}}return null}function uG(e,{halfWidth:t,halfHeight:n}){let r=Math.floor((e.screenX-t)/QW.width),i=Math.floor((e.screenX+t)/QW.width),a=Math.floor((e.screenY-n)/QW.height),o=Math.floor((e.screenY+n)/QW.height),s=[];for(let e=r;e<=i;e+=1)for(let t=a;t<=o;t+=1)s.push(`${e}:${t}`);return s}var dG=128,fG=256;function pG(e,t){let n=document.createElement(`canvas`);n.width=e,n.height=e;let r=n.getContext(`2d`),i=r.createRadialGradient(e/2,e/2,0,e/2,e/2,e/2);for(let[e,n]of t)i.addColorStop(e,`rgba(255, 255, 255, ${n})`);r.fillStyle=i,r.fillRect(0,0,e,e);let a=new Ra(n);return a.colorSpace=lt,a}function mG(e){let t=document.createElement(`canvas`);t.width=e,t.height=e;let n=t.getContext(`2d`);n.strokeStyle=`rgba(255, 255, 255, 1)`,n.lineWidth=e*.05,n.beginPath(),n.arc(e/2,e/2,e*.4,0,Math.PI*2),n.stroke();let r=new Ra(t);return r.colorSpace=lt,r}function hG(e){let t=[];function n(e){let n=e.dispose.bind(e);return e.dispose=()=>{},t.push(n),e}let r=n(pG(dG,[[0,.85],[.25,.42],[.6,.1],[1,0]])),i=n(pG(fG,[[0,.32],[.45,.14],[.8,.03],[1,0]])),a=n(mG(dG)),o=new Map,s=new Map,c=new Map;function l(t){return c.has(t)||c.set(t,n(vG(t,e))),c.get(t)}function u(t){return o.has(t)||o.set(t,n(new Si({map:r,color:new B(t).multiply(new B(e.starHalo)),blending:2,transparent:!0,depthWrite:!1,opacity:.6}))),o.get(t)}return{halo(e,t){let n=new Ii(u(e.color));return n.scale.setScalar(t*6.5),n.renderOrder=-1,n},nebula(e,t){s.has(e)||s.set(e,n(new Si({map:i,color:new B(e),blending:2,transparent:!0,depthWrite:!1,opacity:.16})));let r=new Ii(s.get(e));return r.scale.setScalar(t),r.renderOrder=-2,r},reticle(t){let n=new Ii(new Si({map:a,color:new B(e.orbit),transparent:!0,depthWrite:!1,depthTest:!1}));return n.scale.setScalar(t*5),n.renderOrder=3,n},label(e,t){let n=l(e),r=new Ii(n);return rG(r,{radius:t,aspect:n.userData.aspect??4}),r.renderOrder=4,r},dispose(){for(let e of t)e();t.length=0,o.clear(),s.clear(),c.clear()}}}var gG=34,_G=12;function vG(e,t){let n=document.createElement(`canvas`),r=n.getContext(`2d`),i=`${gG}px "JetBrains Mono", ui-monospace, monospace`;r.font=i;let a=Math.ceil(r.measureText(e).width)+_G*2;n.width=a,n.height=58,r.font=i,r.textBaseline=`middle`,r.textAlign=`center`,r.fillStyle=t.labelPlate,yG(r,0,0,a,58,8),r.fill(),r.fillStyle=t.labelInk,r.fillText(e,a/2,30);let o=new Ra(n);o.colorSpace=lt;let s=new Si({map:o,transparent:!0,depthWrite:!1,depthTest:!1,sizeAttenuation:!1});s.userData.aspect=a/58;let c=s.dispose.bind(s);return s.dispose=()=>{o.dispose(),c()},s}function yG(e,t,n,r,i,a){e.beginPath(),e.moveTo(t+a,n),e.arcTo(t+r,n,t+r,n+i,a),e.arcTo(t+r,n+i,t,n+i,a),e.arcTo(t,n+i,t,n,a),e.arcTo(t,n,t+r,n,a),e.closePath()}function bG(e){return Object.entries(e??{}).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${e}:${t}`).join(`|`)}function xG(e){let t=e>>>0;return function(){t=t+1831565813>>>0;let e=Math.imul(t^t>>>15,1|t);return e=e+Math.imul(e^e>>>7,61|e)^e,((e^e>>>14)>>>0)/4294967296}}function SG(e){let t=2166136261;for(let n=0;n>>0}function CG(e,t,n=1400,r=1600){let i=xG(SG(e)),a=new Float32Array(n*3);for(let e=0;ee.language===t),r=new Set(n.map(e=>e.id)),i=new Set(e.nodes.map(e=>e.id)),a=new Set(n.map(e=>e.region)),o=new Set(n.map(e=>e.file));return{...e,nodes:n,edges:e.edges.filter(e=>r.has(e.src)&&(r.has(e.dst)||e.external||!i.has(e.dst))),entrypoint_candidates:e.entrypoint_candidates.filter(e=>r.has(e)),selected_entrypoint:r.has(e.selected_entrypoint)?e.selected_entrypoint:null,file_hashes:Object.fromEntries(Object.entries(e.file_hashes).filter(([e])=>o.has(e))),concept_annotations:e.concept_annotations.filter(e=>e.language===t&&r.has(e.node_id)),regions:e.regions.filter(e=>a.has(e.id)),region_edges:e.region_edges.filter(e=>a.has(e.src)&&a.has(e.dst)),partial_files:e.partial_files.filter(e=>o.has(e))}}function EG(e,t){if(!e||!t||t===`all`)return e;let n=e.architecture,r=n.boxes.filter(e=>e.language===t),i=new Set(r.map(e=>e.id)),a=e.workflow,o=`${t}:`;return{...e,architecture:{...n,boxes:r,edges:n.edges.filter(e=>i.has(e.src)&&i.has(e.dst)),unreachable:n.unreachable.filter(e=>i.has(e))},workflow:{...a,nodes:a.nodes.filter(e=>e.language===t),unreachable:a.unreachable.filter(e=>e.startsWith(o))}}}function DG(e){let t=new Map;for(let n of e.regions)t.set(n.language,(t.get(n.language)??0)+1);let n=[...t].map(([e,t])=>({id:e,label:AG(e),shortLabel:jG(e),count:t})).sort((e,t)=>e.label.localeCompare(t.label));return[{id:`all`,label:`All languages`,shortLabel:`All`,count:e.regions.length},...n]}function OG(e,t){let n=new Map(e.nodes.map(e=>[e.id,e])),r=new Map;for(let i of e.concept_annotations??[]){let e=`${i.language}:${i.concept}`,a=r.get(e)??{language:i.language,concept:i.concept,occurrences:0,nodeIds:new Set,studiedNodeIds:new Set,understoodNodeIds:new Set};a.occurrences+=1,a.nodeIds.add(i.node_id),t.has(i.node_id)&&a.studiedNodeIds.add(i.node_id),n.get(i.node_id)?.understood&&a.understoodNodeIds.add(i.node_id),r.set(e,a)}return[...r.values()].map(e=>({language:e.language,concept:e.concept,occurrences:e.occurrences,nodes:e.nodeIds.size,studied_nodes:e.studiedNodeIds.size,understood_nodes:e.understoodNodeIds.size})).sort((e,t)=>e.language.localeCompare(t.language)||e.concept.localeCompare(t.concept))}function kG(e){let t={javascript:`JavaScript`,jsx:`JSX`,typescript:`TypeScript`};return t[e]?t[e]:e.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}function AG(e){return kG(e)}function jG(e){return e===`javascript`?`JS`:e===`typescript`?`TS`:AG(e)}function MG(e){return e===`python`?`nebPython`:e===`javascript`?`nebJs`:e===`typescript`?`nebTs`:null}var NG=2;function PG(e,{showAll:t=!1,selectionId:n=null}={}){let r=()=>new Set(e.regions.map(e=>e.id));if(t||!e.regions.some(e=>e.home))return r();let i=new Set,a=new Set;for(let t of e.regions)typeof t.hops_from_home==`number`&&t.hops_from_home<=NG&&i.add(t.id),t.understood&&a.add(t.id);n&&a.add(n);for(let e of a)i.add(e);for(let t of e.region_edges)(a.has(t.src)||a.has(t.dst))&&(i.add(t.src),i.add(t.dst));return i}function FG(e){let t=new Map;for(let n of e.nodes)t.has(n.region)||t.set(n.region,n.file);return t}function IG(e){return e.split(`/`).filter(Boolean).at(-1)??e}function LG(e){let t=FG(e);return e.regions.map(e=>({id:e.id,file:t.get(e.id)??e.id,label:IG(t.get(e.id)??e.id),language:e.language,community:e.community,understood:e.understood,home:e.home,hops:typeof e.hops_from_home==`number`?e.hops_from_home:null,centrality:e.centrality,loc:e.loc})).sort((e,t)=>e.label.localeCompare(t.label)||e.id.localeCompare(t.id))}function RG(e){if(!e.length)return``;let t=e.map(e=>e.file.split(`/`).slice(0,-1)),n=t[0];for(let e of t.slice(1)){let t=0;for(;t{let n=RG(t),r=n.endsWith(`/`)?n:``;return{community:e,name:n,members:t.map(e=>({...e,display:r&&e.file.startsWith(r)?e.file.slice(r.length):e.file})).sort((e,t)=>e.display.localeCompare(t.display))}}).sort((e,t)=>t.members.length-e.members.length||e.community-t.community)}var BG=5,VG=2;function HG(e,t,n=null){let r=e=>n===null||n.has(e),i=FG(e);return{nodes:e.regions.map(n=>{let a=r(n.id);return{...n,kind:`region`,name:n.id,label:a?IG(i.get(n.id)??n.id):``,charted:a,fx:n.x,fy:n.y,fz:n.z,val:qG(n.loc,5,24),color:a?n.understood?t.star:e.nodes.some(e=>e.region===n.id&&e.partial)?t.routePossible:JG(n.centrality,t,BG):t.nodeDim,focusDim:!1}}),links:e.region_edges.filter(e=>r(e.src)&&r(e.dst)).map(e=>({...e,source:e.src,target:e.dst,color:e.certain?t.route:t.routePossible,focusDim:!1}))}}function UG(e,t,n,{selectedId:r=null}={}){let i=e.nodes.filter(e=>e.region===t),a=new Set(i.map(e=>e.id)),o=e.edges.filter(e=>e.kind===`call`&&!e.external&&a.has(e.src)&&a.has(e.dst)),s=new Set(r?[r]:[]);if(r)for(let e of o)e.src===r&&s.add(e.dst),e.dst===r&&s.add(e.src);return{nodes:i.map(e=>({...e,fx:e.system_x,fy:e.system_y,fz:e.system_z,val:qG(e.loc,2.8,11),color:e.understood?n.star:e.partial?n.routePossible:JG(e.centrality,n,VG),selected:e.id===r,focusDim:!!r&&!s.has(e.id)})),links:o.map(e=>({...e,source:e.src,target:e.dst,color:e.certain?n.route:n.routePossible,focusDim:!!r&&e.src!==r&&e.dst!==r}))}}function WG(e){return e.regions.find(e=>e.home)??e.regions[0]??null}function GG(e){let t=e.kind===`region`?`star system`:e.kind,n=e.partial?` · unchartable · syntax error`:``,r=e.home?` · Home`:``;return`${e.name} · ${t} · ${e.loc} LOC${r}${n}`}function KG(e){let t=e.kind===`import`?`import`:e.kind===`call`?`call`:`import route`,n=e.certain?`certain`:t===`call`?`possible call`:`possible import`,r=typeof e.weight==`number`?` · ${e.weight} ${e.weight===1?`import`:`imports`}`:``,i=typeof e.lineno==`number`?` · line ${e.lineno}`:``;return`${e.src} → ${e.dst} · ${t} · ${n}${r}${i}`}function qG(e,t,n){return Math.min(n,Math.max(t,Math.sqrt(Math.max(1,e))*1.15))}function JG(e,t,n){return e>=n?t.nodeBright:e>=1?t.node:t.nodeDim}function YG(e,t){if(t?.pointerType===`touch`||!Array.isArray(e?._pointers)||e._pointers.length===0)return!1;if(e._pointers.splice(0,e._pointers.length),e._pointerPositions&&typeof e._pointerPositions==`object`)for(let t of Object.keys(e._pointerPositions))delete e._pointerPositions[t];return!0}function XG(e,t){let n=e=>YG(t,e),r=e=>YG(t,e);return e.addEventListener(`pointerdown`,n,{capture:!0}),e.addEventListener(`lostpointercapture`,r,{capture:!0}),()=>{e.removeEventListener(`pointerdown`,n,{capture:!0}),e.removeEventListener(`lostpointercapture`,r,{capture:!0})}}var ZG=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),$=o(((e,t)=>{t.exports=ZG()}))(),QG=420,$G=1.6,eK={GALAXY:{min:120,max:640},SYSTEM:{min:55,max:320},STUDY:{min:22,max:170}},tK=.16,nK=1.5,rK=110,iK=6;function aK({graph:e,level:t,region:n,selectedNode:r,hoverNodeId:i,pendingDawnRegionId:a,revealedRegionIds:o,mode:s,onHoverNode:c,onAdvance:l,onRetreat:u,onDawnConsumed:d}){let f=(0,_.useRef)(null),p=(0,_.useRef)(null),m=(0,_.useRef)(null),h=(0,_.useRef)(l),g=(0,_.useRef)(u),v=(0,_.useRef)(c),y=(0,_.useRef)(a),b=(0,_.useRef)(d),x=(0,_.useRef)(null),S=(0,_.useRef)({activeId:null,neighborIds:new Set}),C=(0,_.useRef)(null),w=(0,_.useRef)(null),T=(0,_.useRef)(null),[E,D]=(0,_.useState)(0),[O,k]=(0,_.useState)(``),A=(0,_.useMemo)(lK,[]),ee=(0,_.useMemo)(XW,[]),te=bG(e.file_hashes),ne=(0,_.useMemo)(()=>t===wG.GALAXY?HG(e,A,o):UG(e,n?.id,A,{selectedId:r?.id}),[e,t,A,n?.id,o,r?.id]);(0,_.useEffect)(()=>{h.current=l,g.current=u,v.current=c,y.current=a,b.current=d},[l,u,c,a,d]);function re(e){let{activeId:t,neighborIds:n}=S.current;return t?e.id===t?A.orbit:n.has(e.id)?e.color:A.faded:e.color}function ie(e){if(e.focusDim)return A.faded;let{activeId:t,neighborIds:n}=S.current,r=e.certain?A.route:A.routePossible;if(!t)return r;let i=sK(e.source),a=sK(e.target);return i===t||a===t?A.orbit:n.has(i)&&n.has(a)?r:A.faded}function j(e){if(e.focusDim)return .4;let{activeId:t}=S.current,n=Math.min(2.2,.45+(e.weight??1)*.25);if(!t)return n;let r=sK(e.source),i=sK(e.target);return r===t||i===t?n+.9:n}(0,_.useEffect)(()=>{let e=f.current;if(!e)return;let t=document.createElement(`canvas`);if(!t.getContext(`webgl2`)&&!t.getContext(`webgl`)){k(`Codemble needs WebGL to draw your galaxy. Enable WebGL and reload.`);return}try{let t=hG(A);C.current=t;let n=BW({controlType:`orbit`})(e).backgroundColor(A.ground).showNavInfo(!1).enableNavigationControls(!0).enableNodeDrag(!1).warmupTicks(0).cooldownTicks(0).nodeId(`id`).nodeLabel(GG).nodeVal(`val`).nodeColor(re).nodeRelSize($G).nodeResolution(8).nodeOpacity(.82).nodeThreeObject(e=>oK(e,A,t,T.current)).nodeThreeObjectExtend(!0).linkColor(ie).linkLabel(KG).linkOpacity(.32).linkWidth(j).linkCurvature(.12).linkVisibility(e=>!(s===`easy`&&e.focusDim)).linkHoverPrecision(4).linkDirectionalArrowRelPos(1).linkDirectionalArrowColor(ie).linkDirectionalParticles(e=>e.kind===`call`&&e.certain&&!e.focusDim&&!ee?2:0).linkDirectionalParticleSpeed(.006).linkDirectionalParticleWidth(1.1).linkDirectionalParticleColor(()=>A.orbit).onNodeHover(t=>{e.style.cursor=t?`pointer`:`default`,v.current(t?.id??null)}).onNodeClick(e=>h.current(e)),r=requestAnimationFrame(()=>{e.querySelector(`.scene-nav-info`)?.remove()}),i=n.controls();i.enablePan=!1,i.enableDamping=!ee,i.dampingFactor=.12,i.rotateSpeed=.55,i.zoomSpeed=.7,i.minPolarAngle=tK,i.maxPolarAngle=nK,m.current=i;let a=XG(e,i);w.current=JW(n),p.current=n;let o=new ResizeObserver(([e])=>{n.width(e.contentRect.width).height(e.contentRect.height)});return o.observe(e),()=>{o.disconnect(),cancelAnimationFrame(r),a(),n.pauseAnimation(),w.current?.dispose(),w.current=null,n._destructor(),t.dispose(),C.current=null,m.current=null,e.replaceChildren(),p.current=null}}catch(e){k(`The galaxy could not start: ${e.message}`);return}},[A]),(0,_.useEffect)(()=>{let e=p.current;if(!e)return;e.nodeResolution(ne.nodes.length>=900?4:8).linkVisibility(e=>!(s===`easy`&&e.focusDim)).linkDirectionalArrowLength(t===wG.GALAXY?0:3.2).graphData(ne);let n=eK[t]??eK.GALAXY;m.current&&(m.current.minDistance=n.min,m.current.maxDistance=n.max),t===wG.GALAXY?e.cameraPosition({x:0,y:105,z:310},{x:0,y:0,z:0},QG):e.cameraPosition({x:0,y:52,z:150},{x:0,y:0,z:0},QG),D(0)},[ne,t,s]),(0,_.useEffect)(()=>{T.current=ne.nodes[E]?.id??null,p.current?.refresh()},[ne.nodes,E]),(0,_.useEffect)(()=>{let e=p.current;if(!e)return;let t=e.scene(),n=t.getObjectByName(`codemble-starfield`);n&&(t.remove(n),n.geometry.dispose(),n.material.dispose());let r=CG(te,A);return t.add(r),()=>{t.remove(r),r.geometry.dispose(),r.material.dispose()}},[te,A]),(0,_.useEffect)(()=>{let e=p.current;if(!e||t!==wG.GALAXY)return;let n=y.current;if(!n||x.current===n)return;x.current=n,b.current?.(n);let r=!1,i=()=>{},a=t=>{if(r)return;let s=e.scene();if(s.getObjectByName(`codemble-system-${n}`)||t>=iK){i=ZW({scene:s,regionId:n,palette:A});return}o=requestAnimationFrame(()=>a(t+1))},o=requestAnimationFrame(()=>a(0));return()=>{r=!0,cancelAnimationFrame(o),i()}},[t,A]),(0,_.useEffect)(()=>{let e=i??(t===wG.STUDY?r?.id??null:null),n=new Set;if(e)for(let t of ne.links){let r=sK(t.source),i=sK(t.target);r===e&&n.add(i),i===e&&n.add(r)}S.current={activeId:e,neighborIds:n};let a=p.current;a&&a.nodeColor(a.nodeColor()).linkColor(a.linkColor()).linkWidth(a.linkWidth()).linkDirectionalArrowColor(a.linkDirectionalArrowColor())},[ne,i,t,r?.id]);let M=(0,_.useMemo)(()=>iG(ne.nodes),[ne.nodes]);(0,_.useEffect)(()=>{let e=p.current;if(!e)return;let n=e.scene();function r(){let r=e.camera(),a=m.current,o=eK[t]??eK.GALAXY,s=a?r.position.distanceTo(a.target):r.position.length();M.place({scene:n,camera:r,width:e.width(),height:e.height(),distance:s,distanceBounds:o,hoverNodeId:i})}let a=null;function o(){try{r()}catch(e){a!==null&&clearInterval(a),M.hide(n),console.error(`Codemble: label declutter failed, names disabled`,e)}}return o(),a=setInterval(o,rK),()=>{clearInterval(a),M.hide(n)}},[i,t,M]),(0,_.useEffect)(()=>{if(!new URLSearchParams(window.location.search).has(`benchmark`)||ne.nodes.length<900)return;document.documentElement.removeAttribute(`data-codemble-fps`);let e=setTimeout(()=>{let e=p.current;if(!e)return;let t=e.renderer(),n=e.postProcessingComposer(),r=performance.now();for(let e=0;e<60;e+=1)n.render();t.getContext().finish();let i=performance.now()-r;document.documentElement.dataset.codembleFps=(60*1e3/i).toFixed(1)},1e3);return()=>clearTimeout(e)},[ne.nodes.length]),(0,_.useEffect)(()=>{!r||!p.current||t!==wG.STUDY||p.current.cameraPosition({x:r.system_x+20,y:r.system_y+15,z:r.system_z+42},{x:r.system_x,y:r.system_y,z:r.system_z},QG)},[t,r]);let ae=ne.nodes[E]??null;function oe(e){e.key===`ArrowRight`||e.key===`ArrowDown`?(e.preventDefault(),D(e=>(e+1)%Math.max(1,ne.nodes.length))):e.key===`ArrowLeft`||e.key===`ArrowUp`?(e.preventDefault(),D(e=>(e-1+ne.nodes.length)%Math.max(1,ne.nodes.length))):e.key===`Enter`&&ae?(e.preventDefault(),h.current(ae)):(e.key===`Escape`||e.key===`Backspace`)&&(e.preventDefault(),g.current())}return O?(0,$.jsxs)(`section`,{className:`webgl-error`,role:`alert`,children:[(0,$.jsx)(`h1`,{children:`The sky could not open.`}),(0,$.jsx)(`p`,{children:O}),(0,$.jsxs)(`p`,{children:[`The `,s===`easy`?`Diagram`:`Map`,` layer works without WebGL — switch to it at the top of the window to explore the same code.`]})]}):(0,$.jsxs)(`div`,{className:`galaxy-frame`,role:`application`,tabIndex:`0`,"aria-label":`Codemble ${t.toLowerCase()} view. Drag to orbit, scroll to zoom. Use arrow keys to choose a node and Enter to move closer.`,onKeyDown:oe,children:[(0,$.jsx)(`div`,{ref:f,className:`galaxy-canvas`,"aria-hidden":`true`}),ae?(0,$.jsx)(`output`,{className:`keyboard-focus`,"aria-live":`polite`,children:GG(ae)}):null]})}function oK(e,t,n,r){let i=new lr;i.name=e.kind===`region`?`codemble-system-${e.id}`:`codemble-node-${e.id}`;let a=Math.cbrt(e.val??1)*$G,o=e.charted===!1;if(!e.focusDim&&!o&&i.add(n.halo(e,a)),e.kind===`region`&&!o){let r=MG(e.language);r&&i.add(n.nebula(t[r],a*14))}if(e.label){let t=n.label(e.label,a);t.userData.nodeId=e.id,i.add(t)}if(e.home){let e=new ia(new xo(a*1.7,Math.max(.18,a*.07),8,36),new Ki({color:t.home}));e.rotation.x=Math.PI/2.8,i.add(e)}if(e.selected){let e=new ia(new xo(a*2.1,Math.max(.16,a*.05),6,24),new Ki({color:t.orbit}));e.rotation.x=Math.PI/2.8,i.add(e)}return e.id===r&&i.add(n.reticle(a)),i}function sK(e){return typeof e==`object`&&e?e.id:e}function cK(e){let t=document.createElement(`canvas`).getContext(`2d`);t.fillStyle=`#000000`,t.fillStyle=e,t.fillRect(0,0,1,1);let[n,r,i]=t.getImageData(0,0,1,1).data;return`rgb(${n}, ${r}, ${i})`}function lK(){let e=getComputedStyle(document.documentElement),t=t=>cK(e.getPropertyValue(t).trim());return Object.freeze({ground:t(`--cm-ground`),home:t(`--cm-ink`),orbit:t(`--cm-orbit`),nodeBright:t(`--cm-ink-2`),node:t(`--cm-ink-3`),nodeDim:t(`--cm-node-unlit`),route:t(`--cm-hairline`),routePossible:t(`--cm-route-possible`),faded:t(`--cm-hairline-soft`),star:t(`--cm-star-high`),starHalo:t(`--cm-star-halo`),nebPython:t(`--cm-neb-python`),nebJs:t(`--cm-neb-js`),nebTs:t(`--cm-neb-ts`),labelPlate:e.getPropertyValue(`--cm-label-plate`).trim(),labelInk:e.getPropertyValue(`--cm-label-ink`).trim()})}function uK({hint:e,onStudy:t}){return e?(0,$.jsxs)(`output`,{className:`hint-chip`,"aria-live":`polite`,children:[(0,$.jsx)(`span`,{"aria-hidden":`true`,children:`→`}),(0,$.jsxs)(`span`,{children:[`Study `,(0,$.jsx)(`strong`,{children:e.regionId}),` next`]}),(0,$.jsx)(`small`,{children:e.reason}),(0,$.jsx)(`button`,{type:`button`,onClick:()=>t(e.regionId),children:`Take me there`})]}):null}var dK=[{title:`What you see`,body:`Every star system is one file, named once you have charted it. Size is how much code it holds; brightness is how many places in your project call it. Faint unnamed markers are modules you have not reached yet.`},{title:`How to move`,body:`Drag to look around and scroll to zoom — the view stays locked on whatever you are studying, so you cannot get lost. Click a system to go in, Escape to come back, and press ⌘K to jump straight to any module by name.`},{title:`What lights stars`,body:`A system lights up only after you answer questions drawn from your own code. Nothing lights up just by looking at it — and each one you light reveals the modules it connects to.`}],fK=[{title:`What you see`,body:`Every box is one file, placed by how your imports connect them. A dashed link is a relationship the parser could not fully prove.`},{title:`How to move`,body:`Click a box to study that module, or press ⌘K to jump to one by name. The tabs above show how it fits together and what runs first. Switch to the Galaxy anytime to fly through the same code.`},{title:`What lights up`,body:`A module lights up only after you answer questions drawn from your own code. Nothing lights up just by looking at it.`}];function pK({layer:e,onDismiss:t}){let[n,r]=(0,_.useState)(0),i=(0,_.useRef)(null),a=e===`map`?fK:dK,o=a[n];(0,_.useLayoutEffect)(()=>{let e=i.current;e&&!e.open&&e.showModal()},[]);function s(){i.current?.close(),t()}return(0,$.jsxs)(`dialog`,{ref:i,className:`coach-marks`,"aria-labelledby":`coach-heading`,onCancel:e=>{e.preventDefault(),s()},children:[(0,$.jsxs)(`p`,{className:`coach-marks__progress`,children:[`Step `,n+1,` of `,a.length]}),(0,$.jsx)(`h1`,{id:`coach-heading`,children:o.title}),(0,$.jsx)(`p`,{children:o.body}),(0,$.jsxs)(`div`,{className:`coach-marks__actions`,children:[(0,$.jsx)(`button`,{type:`button`,className:`coach-skip`,onClick:s,children:`Skip`}),(0,$.jsx)(`button`,{type:`button`,className:`check-primary`,onClick:()=>n+1{let n=i.current?.getBoundingClientRect();!n||!e||!t||o(_K(Math.min(n.width/e,n.height/t)))},[e,t]);(0,_.useEffect)(()=>{let n=i.current;if(!n||typeof ResizeObserver>`u`)return;u.current=!1;let r=0,a=()=>{if(u.current)return;let i=n.getBoundingClientRect();i.width>480||i.width<=0||i.height<=0||(cancelAnimationFrame(r),r=requestAnimationFrame(()=>{let r=n.getBoundingClientRect();r.width>480||r.width<=0||r.height<=0||(o(_K(Math.min(r.width/e,r.height/t))),u.current=!0)}))},s=new ResizeObserver(a);return s.observe(n),a(),()=>{cancelAnimationFrame(r),s.disconnect()}},[e,t]);function f(e){if(e.button!==0||e.target.closest(`[role='button']`))return;let t=i.current;l.current={x:e.clientX,y:e.clientY,left:t.scrollLeft,top:t.scrollTop},c(!0),t.setPointerCapture(e.pointerId)}function p(e){if(!l.current)return;let t=i.current;t.scrollLeft=l.current.left-(e.clientX-l.current.x),t.scrollTop=l.current.top-(e.clientY-l.current.y)}function m(e){l.current&&(l.current=null,c(!1),i.current?.releasePointerCapture?.(e.pointerId))}return(0,$.jsxs)(`div`,{className:`map-canvas`,children:[(0,$.jsxs)(`div`,{className:`map-zoom`,role:`group`,"aria-label":`Zoom ${n}`,children:[(0,$.jsx)(`button`,{type:`button`,"aria-label":`Zoom out`,disabled:a<=mK,onClick:()=>o(e=>_K(e/gK)),children:`−`}),(0,$.jsx)(`button`,{type:`button`,onClick:d,children:`Fit`}),(0,$.jsxs)(`button`,{type:`button`,onClick:()=>o(1),children:[Math.round(a*100),`%`]}),(0,$.jsx)(`button`,{type:`button`,"aria-label":`Zoom in`,disabled:a>=hK,onClick:()=>o(e=>_K(e*gK)),children:`+`})]}),(0,$.jsx)(`div`,{ref:i,className:`map-scroll`,"data-panning":s||void 0,onPointerDown:f,onPointerMove:p,onPointerUp:m,onPointerCancel:m,children:(0,$.jsx)(`div`,{className:`map-canvas__sized`,style:{width:e*a,height:t*a},children:r})})]})}var yK={nebPython:`var(--cm-neb-python)`,nebJs:`var(--cm-neb-js)`,nebTs:`var(--cm-neb-ts)`};function bK(e){let t=MG(e);return t?yK[t]:`var(--cm-hairline)`}function xK(e){return e.map(([e,t],n)=>`${n===0?`M`:`L`} ${e} ${t}`).join(` `)}function SK(e){return 1+Math.min(2.5,(Math.max(1,e)-1)*.5)}var CK=13,wK=.62,TK=14,EK=6;function DK(e,t){let n=t-TK-EK,r=Math.max(1,Math.floor(n/(CK*wK)));return e.length<=r?e:`${e.slice(0,Math.max(1,r-1))}…`}function OK({data:e,mapTab:t,mode:n,selectedRegionId:r,hasEntrypointCandidates:i,error:a,onSelectTab:o,onSelectRegion:s,onSelectNode:c,onRetry:l,children:u}){return(0,$.jsxs)(`section`,{className:`map-view`,"aria-label":`Two-dimensional project map`,children:[(0,$.jsxs)(`nav`,{className:`map-tabs`,"aria-label":`Map view`,children:[(0,$.jsx)(`button`,{type:`button`,"aria-pressed":t===`architecture`,onClick:()=>o(`architecture`),children:n===`easy`?`How it fits together`:`Architecture`}),(0,$.jsx)(`button`,{type:`button`,"aria-pressed":t===`workflow`,onClick:()=>o(`workflow`),children:n===`easy`?`What runs first`:`Workflow`})]}),u,a?(0,$.jsxs)(`div`,{className:`map-state`,role:`alert`,children:[(0,$.jsx)(`h2`,{children:`The map did not load.`}),(0,$.jsxs)(`p`,{children:[a,` The galaxy layer is unaffected.`]}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:l,children:`Try again`})]}):e?t===`architecture`?(0,$.jsx)(kK,{architecture:e.architecture,mode:n,selectedRegionId:r,hasEntrypointCandidates:i,onSelectRegion:s}):(0,$.jsx)(AK,{workflow:e.workflow,mode:n,selectedRegionId:r,hasEntrypointCandidates:i,onSelectNode:c}):(0,$.jsx)(`p`,{className:`map-loading`,role:`status`,children:`Laying out parser evidence…`})]})}function kK({architecture:e,mode:t,selectedRegionId:n,hasEntrypointCandidates:r,onSelectRegion:i}){let a=new Map(e.boxes.map(e=>[e.id,e]));return(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(vK,{contentWidth:e.width+64,contentHeight:e.height+64,label:`the architecture map`,children:(0,$.jsxs)(`svg`,{className:`architecture-map`,width:`100%`,height:`100%`,preserveAspectRatio:`xMidYMin meet`,viewBox:`-32 -32 ${e.width+64} ${e.height+64}`,role:`group`,"aria-label":e.home?`${e.boxes.length} modules in ${e.layer_count} import layers from Home`:`${e.boxes.length} modules in ${e.layer_count} import layers, measured from the modules nothing imports`,children:[(0,$.jsxs)(`defs`,{children:[(0,$.jsx)(`marker`,{id:`architecture-arrow`,className:`architecture-map__arrow`,markerWidth:`8`,markerHeight:`8`,refX:`8`,refY:`4`,orient:`auto`,markerUnits:`strokeWidth`,children:(0,$.jsx)(`path`,{d:`M 0 0 L 8 4 L 0 8 Z`,fill:`currentColor`})}),(0,$.jsx)(`marker`,{id:`architecture-cycle-arrow`,className:`architecture-map__arrow is-cycle`,markerWidth:`8`,markerHeight:`8`,refX:`8`,refY:`4`,orient:`auto`,markerUnits:`strokeWidth`,children:(0,$.jsx)(`path`,{d:`M 0 0 L 8 4 L 0 8 Z`,fill:`currentColor`})})]}),(0,$.jsx)(`g`,{className:`architecture-map__edges`,children:e.edges.map(e=>{let t=a.get(e.src),n=a.get(e.dst);return!t||!n?null:(0,$.jsx)(`path`,{d:xK(e.points),strokeDasharray:e.certain?void 0:`5 4`,strokeWidth:SK(e.weight),markerEnd:`url(#${e.cycle?`architecture-cycle-arrow`:`architecture-arrow`})`,className:`architecture-map__edge${e.cycle?` is-cycle`:``}`},`${e.src}->${e.dst}`)})}),e.boxes.map(e=>(0,$.jsxs)(`g`,{className:`architecture-map__box`,"data-understood":e.understood,"data-home":e.home,"data-reachable":e.reachable,"data-partial":e.partial,"data-selected":e.id===n,transform:`translate(${e.x} ${e.y})`,role:`button`,tabIndex:0,"aria-label":`${e.label}, ${e.node_count} structures, ${e.loc} lines${e.understood?`, understood`:`, not yet understood`}${e.home?`, Home`:``}${e.reachable?``:`, no import route from Home`}${e.partial?`, unchartable, syntax error`:``}`,onClick:()=>i(e.id),onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),i(e.id))},children:[(0,$.jsxs)(`title`,{children:[e.label,e.partial?` — unchartable, syntax error`:``]}),(0,$.jsx)(`rect`,{width:e.width,height:e.height,rx:`3`}),(0,$.jsx)(`rect`,{className:`box-tint`,width:`4`,height:e.height,fill:bK(e.language)}),e.partial?(0,$.jsx)(`path`,{className:`box-partial`,d:`M ${e.width-16} 2 L ${e.width-2} 2 L ${e.width-2} 16 Z`}):null,(0,$.jsx)(`text`,{x:TK,y:`24`,children:DK(e.short_label??e.label,e.width)}),(0,$.jsx)(`text`,{className:`box-meta`,x:`14`,y:`42`,children:t===`easy`?`${e.node_count} ${e.node_count===1?`piece`:`pieces`}`:`${e.node_count} nodes · ${e.loc} LOC`})]},e.id))]})}),e.home?null:(0,$.jsxs)(`p`,{className:`map-note`,children:[`No Home is selected, so these layers run from the modules nothing else imports rather than from your entrypoint. Both are read from your imports, not guessed.`,` `,r?`Pick your starting point with “Change Home” to see the same modules layered by what the project runs first.`:`This project has no parser-recognisable entrypoint, so there is no “runs first” order to layer by instead.`]}),e.unreachable.length?(0,$.jsxs)(`p`,{className:`map-note`,children:[e.unreachable.length,` `,e.unreachable.length===1?`module has`:`modules have`,` no import route from Home, so `,e.unreachable.length===1?`it sits`:`they sit`,` `,`in the bottom row rather than being placed by guesswork.`]}):null]})}function AK({workflow:e,mode:t,selectedRegionId:n,hasEntrypointCandidates:r,onSelectNode:i}){if(!e.root)return r?(0,$.jsxs)(`div`,{className:`map-state`,children:[(0,$.jsx)(`h2`,{children:`No Home is selected.`}),(0,$.jsx)(`p`,{children:`The workflow tree starts at your entrypoint. Pick Home and this tab will show what runs first, then what that calls.`})]}):(0,$.jsxs)(`div`,{className:`map-state`,children:[(0,$.jsx)(`h2`,{children:`No “runs first” order to show.`}),(0,$.jsx)(`p`,{children:`This project has no parser-recognisable entrypoint — nothing here declares a startup structure Codemble recognises, and it will not guess one. The other tab still maps how your modules import each other.`})]});let a=new Map(e.nodes.map(e=>[e.order,e]));return(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(vK,{contentWidth:e.width+32,contentHeight:e.height+32,label:`the workflow tree`,children:(0,$.jsxs)(`svg`,{className:`workflow-tree`,width:`100%`,height:`100%`,preserveAspectRatio:`xMinYMin meet`,viewBox:`-16 -16 ${e.width+32} ${e.height+32}`,role:`group`,"aria-label":`Call tree from ${e.root}, ${e.nodes.length} steps deep to ${e.depth_count} levels`,children:[(0,$.jsx)(`g`,{className:`workflow-tree__edges`,children:e.nodes.map(e=>{if(e.parent===null)return null;let t=[...a.values()].filter(t=>t.id===e.parent&&t.order(0,$.jsxs)(`g`,{className:`workflow-tree__row`,"data-understood":e.understood,"data-cut":e.cut??void 0,"data-partial":e.partial,"data-relation":e.relation,"data-selected":e.region===n,transform:`translate(${e.x} ${e.y})`,role:`button`,tabIndex:0,"aria-label":`${e.label} at ${e.file}:${e.lineno}${e.certain?``:`, possible call`}${e.cut===`cycle`?`, repeats an earlier step`:``}${e.cut===`repeat`?`, already shown above`:``}${e.partial?`, unchartable, syntax error`:``}`,onClick:()=>i(e.id),onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),i(e.id))},children:[(0,$.jsx)(`circle`,{cx:`8`,cy:`16`,r:`4`}),(0,$.jsx)(`text`,{x:`20`,y:`20`,children:e.label}),(0,$.jsxs)(`text`,{className:`row-meta`,x:`20`,y:`20`,dx:`${e.label.length*.62}em`,children:[e.relation===`defines`?t===`easy`?` — lives here`:` — defined in this module`:e.certain?``:` — possible call`,e.cut===`cycle`?` — loops back`:``,e.cut===`repeat`?` — shown above`:``,e.partial?t===`easy`?` — could not be read`:` — unchartable`:``]})]},e.order))]})}),e.unreachable.length?(0,$.jsxs)(`p`,{className:`map-note`,children:[e.unreachable.length,` `,e.unreachable.length===1?`structure is`:`structures are`,` never reached from Home by a parser-proven call. They are listed as unreached rather than attached to the tree by guesswork.`]}):null]})}var jK=[{mode:`easy`,label:`New to coding?`},{mode:`expert`,label:`I build software`}],MK=[{mode:`easy`,label:`Easy`},{mode:`expert`,label:`Expert`}];function NK({mode:e,modeChosen:t,onChoose:n}){let r=(0,_.useRef)(null),i=(0,_.useRef)(null),a=(0,_.useRef)(t);(0,_.useLayoutEffect)(()=>{let e=r.current;e&&t===!1&&!e.open&&e.showModal()},[t]),(0,_.useEffect)(()=>{t===!0&&a.current===!1&&i.current?.focus(),a.current=t},[t]);function o(e){r.current?.close(),n(e)}return t===null?null:t?(0,$.jsxs)(`fieldset`,{className:`mode-toggle`,children:[(0,$.jsx)(`legend`,{className:`mode-toggle__label`,children:`Audience`}),(0,$.jsx)(`div`,{className:`mode-toggle__options`,children:MK.map(t=>(0,$.jsxs)(`label`,{children:[(0,$.jsx)(`input`,{type:`radio`,name:`audience-mode`,value:t.mode,checked:e===t.mode,ref:e===t.mode?i:void 0,onChange:()=>o(t.mode)}),(0,$.jsx)(`span`,{children:t.label})]},t.mode))})]}):(0,$.jsxs)(`dialog`,{ref:r,className:`mode-gate`,"aria-labelledby":`mode-gate-heading`,"aria-describedby":`mode-gate-detail`,onCancel:e=>e.preventDefault(),children:[(0,$.jsx)(`h1`,{id:`mode-gate-heading`,children:`New to coding, or do you build software already?`}),(0,$.jsx)(`p`,{id:`mode-gate-detail`,children:`This changes how much Codemble explains and how much it assumes you already know.`}),(0,$.jsx)(`div`,{className:`mode-gate__options`,children:jK.map(e=>(0,$.jsx)(`button`,{type:`button`,onClick:()=>o(e.mode),children:e.label},e.mode))})]})}function PK({node:e,study:t,error:n,mode:r,explanation:i,explanationLoading:a,explanationError:o,llmStatus:s,onSelectNode:c,onRetryNarration:l}){return(0,$.jsxs)(`aside`,{className:`study-preview`,"aria-label":`Selected source structure`,"aria-busy":!t&&!n,children:[(0,$.jsxs)(`header`,{className:`study-preview__header`,children:[(0,$.jsxs)(`p`,{className:`study-preview__path`,children:[e.file,`:`,e.lineno]}),(0,$.jsx)(`h1`,{children:e.name}),(0,$.jsxs)(`dl`,{children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Kind`}),(0,$.jsx)(`dd`,{children:e.kind})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Span`}),(0,$.jsxs)(`dd`,{children:[e.loc,` lines`]})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:r===`easy`?`Used by`:`Callers`}),(0,$.jsx)(`dd`,{children:e.centrality})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Resolution`}),(0,$.jsx)(`dd`,{children:e.partial?`Partial parse`:`Parser-proven`})]})]})]}),n?(0,$.jsxs)(`section`,{className:`study-notice`,role:`alert`,children:[(0,$.jsx)(`h2`,{children:`Study data did not load.`}),(0,$.jsxs)(`p`,{children:[n,` The parser map is still available.`]}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:()=>c(e.id),children:`Try again`})]}):null,!t&&!n?(0,$.jsx)(`p`,{className:`study-loading`,role:`status`,children:`Reading parser evidence…`}):null,t?(0,$.jsxs)(`div`,{className:`study-content`,children:[(0,$.jsx)(FK,{structural:t.structural,mode:r}),(0,$.jsx)(WK,{explanation:i,loading:a,error:o,llmStatus:s,mode:r,node:e,onSelectNode:c,onRetry:l}),(0,$.jsx)(LK,{neighbors:t.neighbors,node:e,mode:r,onSelectNode:c}),(0,$.jsx)(UK,{source:t.source}),(0,$.jsx)(HK,{lens:t.lens,language:e.language,mode:r})]}):null]})}function FK({structural:e,mode:t}){return e?(0,$.jsxs)(`section`,{className:`structural-summary`,"aria-labelledby":`structural-heading`,children:[(0,$.jsxs)(`div`,{className:`study-section-heading`,children:[(0,$.jsx)(`h2`,{id:`structural-heading`,children:t===`easy`?`What this is`:`Structural summary`}),(0,$.jsx)(`span`,{children:`No model needed`})]}),(0,$.jsx)(`p`,{children:e[t]??e.easy})]}):null}var IK=8;function LK({neighbors:e,node:t,mode:n,onSelectNode:r}){let i=e??[],a=i.filter(e=>e.direction===`inbound`),o=i.filter(e=>e.direction===`outbound`);return(0,$.jsxs)(`section`,{className:`connections`,"aria-labelledby":`connections-heading`,children:[(0,$.jsxs)(`div`,{className:`study-section-heading`,children:[(0,$.jsx)(`h2`,{id:`connections-heading`,children:n===`easy`?`What this connects to`:`Parser connections`}),(0,$.jsxs)(`span`,{children:[i.length,` parser `,i.length===1?`relationship`:`relationships`]})]}),i.length===0?(0,$.jsx)(`p`,{className:`study-loading`,children:n===`easy`?`Nothing in your code reaches this yet, and it does not reach anything else.`:`The parser observed no relationship into or out of this structure.`}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(VK,{inbound:a,outbound:o,node:t}),(0,$.jsx)(RK,{title:n===`easy`?`Uses this`:`Inbound`,items:a,mode:n,onSelectNode:r}),(0,$.jsx)(RK,{title:n===`easy`?`This uses`:`Outbound`,items:o,mode:n,onSelectNode:r})]})]})}function RK({title:e,items:t,mode:n,onSelectNode:r}){return t.length?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`h3`,{children:e}),(0,$.jsx)(`ul`,{className:`connection-list`,children:t.map(e=>(0,$.jsx)(`li`,{children:(0,$.jsxs)(`button`,{type:`button`,onClick:()=>r(e.node_id),children:[(0,$.jsx)(`span`,{className:`connection-name`,children:e.name}),(0,$.jsxs)(`span`,{className:`connection-meta`,children:[zK(e,n),` · `,BK(e,n)]}),(0,$.jsx)(`span`,{className:`source-citation`,children:e.citation})]})},`${e.direction}-${e.node_id}`))})]}):null}function zK(e,t){return e.relationship===`import`?e.direction===`inbound`?t===`easy`?`brings this in`:`import · inbound`:t===`easy`?`this brings it in`:`import · outbound`:e.direction===`inbound`?t===`easy`?`calls this`:`call · inbound`:t===`easy`?`this calls it`:`call · outbound`}function BK(e,t){return e.certain?`certain`:e.relationship===`import`?t===`easy`?`possible link, not certain`:`possible import`:t===`easy`?`possible link, not certain`:`possible call`}function VK({inbound:e,outbound:t,node:n}){let r=e.slice(0,IK),i=t.slice(0,IK),a=Math.max(r.length,i.length,1)*22+16,o=a/2,s=(e,t)=>(e+1)*a/(t+1);return(0,$.jsxs)(`svg`,{className:`mini-constellation`,viewBox:`0 0 280 ${a}`,role:`img`,"aria-label":`${e.length} inbound and ${t.length} outbound parser relationships for ${n.name}`,children:[r.map((e,t)=>(0,$.jsx)(`line`,{x1:`26`,y1:s(t,r.length),x2:`132`,y2:o,strokeDasharray:e.certain?void 0:`3 3`},`in-line-${e.node_id}`)),i.map((e,t)=>(0,$.jsx)(`line`,{x1:`148`,y1:o,x2:`254`,y2:s(t,i.length),strokeDasharray:e.certain?void 0:`3 3`},`out-line-${e.node_id}`)),r.map((e,t)=>(0,$.jsx)(`circle`,{cx:`22`,cy:s(t,r.length),r:`4`},`in-dot-${e.node_id}`)),i.map((e,t)=>(0,$.jsx)(`circle`,{cx:`258`,cy:s(t,i.length),r:`4`},`out-dot-${e.node_id}`)),(0,$.jsx)(`circle`,{className:`mini-constellation__self`,cx:`140`,cy:o,r:`6`})]})}function HK({lens:e,language:t,mode:n}){return e?.length?(0,$.jsxs)(`section`,{className:`lens-study`,"aria-labelledby":`lens-heading`,children:[(0,$.jsxs)(`div`,{className:`study-section-heading`,children:[(0,$.jsxs)(`h2`,{id:`lens-heading`,children:[kG(t),` lens`]}),(0,$.jsxs)(`span`,{children:[e.length,` detected`]})]}),(0,$.jsx)(`div`,{className:`lens-notes`,children:e.map(e=>(0,$.jsxs)(`article`,{className:`lens-note`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`h3`,{children:e.title}),(0,$.jsx)(KK,{citation:e.citation,fallbackLine:e.line})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`p`,{children:e.note_voices[n]}),(0,$.jsx)(`code`,{children:e.snippet})]})]},`${e.concept}-${e.line}-${e.snippet}`))})]}):null}function UK({source:e}){return(0,$.jsxs)(`section`,{className:`source-study`,"aria-labelledby":`source-heading`,children:[(0,$.jsxs)(`div`,{className:`study-section-heading`,children:[(0,$.jsx)(`h2`,{id:`source-heading`,children:`Real source`}),(0,$.jsxs)(`span`,{children:[e.file,`:`,e.start_line,`–`,e.end_line]})]}),(0,$.jsx)(`ol`,{className:`source-code`,start:e.start_line,"aria-label":`Source excerpt from ${e.file}`,children:e.lines.map(e=>(0,$.jsx)(`li`,{id:`source-L${e.number}`,"data-line":e.number,children:(0,$.jsx)(`code`,{children:e.text||` `})},e.number))})]})}function WK({explanation:e,loading:t,error:n,llmStatus:r,mode:i,node:a,onSelectNode:o,onRetry:s}){return t?(0,$.jsx)(`p`,{className:`study-loading`,role:`status`,children:i===`easy`?`Asking your model to explain this in plain language…`:`Requesting a grounded narration for this structure…`}):n?(0,$.jsxs)(`section`,{className:`study-notice`,role:`alert`,"aria-labelledby":`explanation-heading`,children:[(0,$.jsx)(`h2`,{id:`explanation-heading`,children:`The explanation request failed.`}),(0,$.jsx)(`p`,{children:n}),(0,$.jsx)(`p`,{children:`Every fact above and below this block came from the parser and is unaffected.`}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:s,children:`Try again`})]}):e?e.status===`no_key`?(0,$.jsx)(GK,{message:e.message,llmStatus:r,mode:i}):e.status===`error`?(0,$.jsxs)(`section`,{className:`study-notice`,role:`alert`,"aria-labelledby":`explanation-heading`,children:[(0,$.jsx)(`h2`,{id:`explanation-heading`,children:`The explanation was withheld.`}),(0,$.jsx)(`p`,{children:e.message}),(0,$.jsx)(`p`,{children:`Codemble will not display provider output that falls outside parser evidence.`}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:s,children:`Try again`})]}):e.status===`partial`?(0,$.jsxs)(`section`,{className:`study-notice`,"aria-labelledby":`explanation-heading`,children:[(0,$.jsx)(`h2`,{id:`explanation-heading`,children:`Narration stays off for partial source.`}),(0,$.jsx)(`p`,{children:e.message})]}):(0,$.jsxs)(`section`,{className:`grounded-explanation`,"aria-labelledby":`explanation-heading`,children:[(0,$.jsxs)(`div`,{className:`study-section-heading`,role:`status`,children:[(0,$.jsx)(`h2`,{id:`explanation-heading`,children:i===`easy`?`In plain language`:`Grounded explanation`}),(0,$.jsx)(`span`,{children:e.cached?`Local cache`:e.provider})]}),(0,$.jsxs)(`p`,{children:[e.summary.text,` `,(0,$.jsx)(KK,{citation:e.summary.citation,fallbackLine:a.lineno})]}),(0,$.jsx)(`h3`,{children:i===`easy`?`Line by line`:`Walkthrough`}),(0,$.jsx)(`ul`,{className:`evidence-list`,children:e.walkthrough.map(e=>(0,$.jsxs)(`li`,{children:[(0,$.jsx)(`p`,{children:e.text}),(0,$.jsx)(KK,{citation:e.citation,fallbackLine:e.line})]},`${e.citation}-${e.text}`))}),e.relationships.length?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`h3`,{children:i===`easy`?`How it fits in`:`Parser relationships`}),(0,$.jsx)(`ul`,{className:`evidence-list`,children:e.relationships.map(e=>(0,$.jsxs)(`li`,{children:[(0,$.jsx)(`strong`,{children:e.certain?e.node_id:`Possible: ${e.node_id}`}),(0,$.jsx)(`p`,{children:e.text}),(0,$.jsxs)(`button`,{className:`source-citation source-citation--button`,type:`button`,onClick:()=>o(e.node_id),children:[`Study `,e.citation]})]},`${e.node_id}-${e.text}`))})]}):null]}):null}function GK({message:e,llmStatus:t,mode:n}){let r=t?.ollama??null;return(0,$.jsxs)(`section`,{className:`study-notice`,"aria-labelledby":`explanation-heading`,children:[(0,$.jsx)(`h2`,{id:`explanation-heading`,children:n===`easy`?`The plain-language write-up needs a model.`:`No narration provider is configured.`}),(0,$.jsx)(`p`,{children:e}),r?(0,$.jsx)(`p`,{children:r.running?`Ollama is already running on this machine. Set CODEMBLE_PROVIDER=ollama and CODEMBLE_OLLAMA_MODEL=${r.recommended}, then restart Codemble to narrate without sending code anywhere.`:`Want to stay fully local? Install Ollama, run "ollama pull ${r.recommended}" (or ${r.fallback} on a smaller machine), set CODEMBLE_PROVIDER=ollama, then restart Codemble.`}):null,(0,$.jsx)(`p`,{children:`Everything else on this panel is parser evidence and works without any model at all.`})]})}function KK({citation:e,fallbackLine:t}){return(0,$.jsx)(`a`,{className:`source-citation`,href:`#source-L${Number(e.split(`:`).at(-1))||t}`,children:e})}var qK=Object.freeze([]),JK=new Set;function YK(){let e=new WeakMap,t=new WeakMap,n=new WeakMap,r=new WeakMap,i=new WeakMap,a=new WeakMap,o=null,s=null,c=null,l=null;function u(e){let t=e.graph,n=t?d(t,e.languageFocus):null,r=n?p(n):null,i=e.level,a=r?.regionById.get(e.region?.id)??null,o=e.selectedNode;n&&(a?o&&(o=r.nodeById.get(o.id)??null,!o&&i===wG.STUDY&&(i=wG.SYSTEM)):(a=WG(n),o=null,i=wG.GALAXY));let s=e.studiedNodeIds;return{...e,focusedGraph:n,focusedMapData:f(e.mapData,e.languageFocus),entrypointOpen:!!t&&!e.entrypointDismissed,level:i,region:a,selectedNode:o,languageOptions:t?m(t):qK,projectName:t?g(t):`Loading local project`,chart:n?_(n,s):qK,focusedStudiedCount:n?v(n,s):0,hint:n?y(n,e.mode):null,revealedRegionIds:n?b(n,e.showAll,a?.id??null):JK,moduleIndex:n?h(n):qK}}function d(t,n){let r=e.get(t);r||(r=new Map,e.set(t,r));let i=n||`all`;return r.has(i)||r.set(i,TG(t,n)),r.get(i)}function f(e,n){if(!e)return e;let r=t.get(e);r||(r=new Map,t.set(e,r));let i=n||`all`;return r.has(i)||r.set(i,EG(e,n)),r.get(i)}function p(e){return n.has(e)||n.set(e,{nodeById:new Map(e.nodes.map(e=>[e.id,e])),regionById:new Map(e.regions.map(e=>[e.id,e]))}),n.get(e)}function m(e){return r.has(e)||r.set(e,DG(e)),r.get(e)}function h(e){return i.has(e)||i.set(e,LG(e)),i.get(e)}function g(e){return a.has(e)||a.set(e,e.project_root.split(`/`).filter(Boolean).at(-1)??e.project_root),a.get(e)}function _(e,t){return(!o||o.graph!==e||o.studiedNodeIds!==t)&&(o={graph:e,studiedNodeIds:t,value:OG(e,t)}),o.value}function v(e,t){return(!s||s.graph!==e||s.studiedNodeIds!==t)&&(s={graph:e,studiedNodeIds:t,value:e.nodes.filter(e=>t.has(e.id)).length}),s.value}function y(e,t){return(!c||c.graph!==e||c.mode!==t)&&(c={graph:e,mode:t,value:XK(e,t)}),c.value}function b(e,t,n){return(!l||l.graph!==e||l.showAll!==t||l.selectionId!==n)&&(l={graph:e,showAll:t,selectionId:n,value:PG(e,{showAll:t,selectionId:n})}),l.value}return Object.freeze({derive:u})}function XK(e,t){if(t!==`easy`)return null;let n=e.regions.filter(e=>!e.understood);if(!n.length)return null;let r=n.map(e=>({regionId:e.id,hops:typeof e.hops_from_home==`number`?e.hops_from_home:1/0})).sort((e,t)=>e.hops-t.hops||e.regionId.localeCompare(t.regionId))[0];return{...r,reason:r.hops===0?`Home is not lit yet.`:Number.isFinite(r.hops)?`${r.hops} ${r.hops===1?`route`:`routes`} from Home.`:`No import route reaches it from Home.`}}var ZK=Object.freeze({setTimeout(e,t){return globalThis.setTimeout(e,t)},clearTimeout(e){globalThis.clearTimeout(e)}}),QK=300,$K=400,eq=4e3,tq=8,nq=Object.freeze([Object.freeze({id:`discovering`,copy:`Finding your source files`}),Object.freeze({id:`parsing`,copy:`Reading each file`}),Object.freeze({id:`resolving`,copy:`Connecting imports and calls`}),Object.freeze({id:`checks`,copy:`Building graph-only checks`}),Object.freeze({id:`layout`,copy:`Placing your galaxy`})]);function rq({adapter:e,clock:t=ZK,onReady:n=async()=>{}}={}){if(!e)throw TypeError(`Project mapping requires a learner adapter.`);let r=new Set,i=iq({phase:`idle`,error:``,picker:null,progress:null,failure:null}),a=0,o=null,s=null,c=null,l=null;function u(){return i}function d(e){return r.add(e),()=>r.delete(e)}function f(e){i=iq({...i,...e});for(let e of r)e()}async function p(){a+=1;let t=a;b(),aq(o),o=new AbortController;let n=o;f({phase:`idle`,error:``,picker:null,progress:null,failure:null});try{let[r,o]=await Promise.all([e.loadRecents({signal:n.signal}),e.browsePicker(null,{signal:n.signal})]);if(t!==a||n.signal.aborted)return i;f({phase:`picking`,picker:{...o,recents:r.recents,error:``,scale:null,busy:!1}})}catch(e){!oq(e)&&t===a&&f({phase:`error`,error:cq(e)})}return i}async function m(t){if(i.phase!==`picking`||i.picker?.busy)return;aq(o),o=new AbortController;let n=o,r=a;f({failure:null});try{let s=await e.browsePicker(t,{signal:n.signal});o===n&&r===a&&!n.signal.aborted&&i.phase===`picking`&&f({picker:{...i.picker,...s,error:``}})}catch(e){o===n&&r===a&&!oq(e)&&i.phase===`picking`&&f({picker:{...i.picker,error:cq(e)}})}}async function h(t){if(i.phase!==`picking`||i.picker?.busy)return;a+=1;let r=a;aq(o),b(),o=new AbortController;let s=o;f({failure:null,picker:{...i.picker,busy:!0,error:``,scale:null}});try{let o=await e.selectProject(t,{signal:s.signal});if(r!==a||s.signal.aborted||i.phase!==`picking`)return o;if(o.state===`parsing`)return f({progress:{state:`parsing`,stage:`discovering`,detail:null,files_done:0,files_total:0,error:null,pollError:``,attempts:0,pollOutage:!1,path:t}}),_(0,r),o;if(o.state===`ready`)return y(),await n(),o;if(o.state===`scale`){let t=await e.browsePicker(o.root,{signal:s.signal});return r===a&&!s.signal.aborted&&i.phase===`picking`&&f({picker:{...i.picker,...t,busy:!1,scale:o}}),o}let c=o.detail??``;return f({picker:{...i.picker,busy:!1,error:c},failure:c?{path:t,detail:c}:null}),o}catch(e){if(r===a&&!oq(e)&&i.phase===`picking`){let n=cq(e);f({picker:{...i.picker,busy:!1,error:n},failure:{path:t,detail:n}})}return}}async function g(){aq(c),c=new AbortController;let t=c;try{await e.resetProject({signal:t.signal})}catch(e){if(oq(e))return!1;if(sq(e))throw e}return t.signal.aborted?!1:(a+=1,aq(o),o=null,b(),f({phase:`idle`,error:``,picker:null,progress:null,failure:null}),!0)}function _(e,n){l!==null&&t.clearTimeout(l),l=t.setTimeout(async()=>{l=null,await v(n)},e)}async function v(t){if(!i.progress||t!==a)return;aq(s),s=new AbortController;let r=s,o=i.progress,c;try{c=await e.fetchParseProgress({signal:r.signal})}catch(e){if(s!==r||t!==a||oq(e)||!i.progress)return;let n=o.attempts+1;f({progress:{...o,pollError:cq(e),attempts:n,pollOutage:n>=tq}}),_(Math.min(eq,$K*2**(n-1)),t);return}if(!(s!==r||t!==a||!i.progress)){if(c.state===`ready`){y(),await n();return}if(c.state===`error`||c.state===`idle`){b();let e=c.error??``;f({progress:null,picker:{...i.picker,busy:!1,error:e},failure:e?{path:o.path,detail:e}:null});return}f({progress:{...o,...c,pollError:``,attempts:0,pollOutage:!1}}),_(QK,t)}}function y(){a+=1,b(),f({phase:`idle`,error:``,picker:null,progress:null,failure:null})}function b(){aq(s),s=null,l!==null&&(t.clearTimeout(l),l=null)}function x(){a+=1;for(let e of[o,s,c])aq(e);o=null,c=null,b(),r.clear()}return Object.freeze({browse:m,dispose:x,getSnapshot:u,reset:g,select:h,start:p,subscribe:d})}function iq(e){return Object.freeze(e)}function aq(e){e&&!e.signal.aborted&&e.abort()}function oq(e){return e?.name===`AbortError`}function sq(e){return Number.isInteger(e?.status)}function cq(e){return e instanceof Error?e.message:String(e)}var lq=Object.freeze({setTimeout(e,t){return globalThis.setTimeout(e,t)},clearTimeout(e){globalThis.clearTimeout(e)}});function uq({adapter:e=dq(),clock:t=lq}={}){let n=new Set,r=YK(),i=r.derive({status:`idle`,error:``,graph:null,level:wG.GALAXY,region:null,selectedNode:null,studyData:null,studyError:``,explanation:null,explanationLoading:!1,explanationError:``,showChart:!1,studiedNodeIds:new Set,showChecks:!1,checkData:null,checkError:``,entrypointDismissed:!1,entrypointError:``,litRegionId:null,pendingDawnRegionId:null,languageFocus:`all`,picker:null,parseProgress:null,projectFailure:null,layer:`galaxy`,layerChosen:!1,mapTab:`architecture`,mapData:null,mapError:``,coachmarksSeen:mq(),llmStatus:null,hoverNodeId:null,showAll:_q(),finderOpen:!1,sidebarOpen:!1,legendOpen:!1,mode:`easy`,modeChosen:null}),a=0,o=0,s=null,c=null,l=null,u=null,d=null,f=null,p=null,m=null,h=null;function g(){return i}function _(e){return n.add(e),()=>n.delete(e)}function v(e,{preserveChecks:t=!1}={}){let a=i,o=r.derive({...a,...e});if(o.level!==a.level||o.region?.id!==a.region?.id){let e={hoverNodeId:null};t||(yq(u),yq(d),u=null,d=null,e.showChecks=!1,e.checkData=null,e.checkError=``),o=r.derive({...o,...e})}i=Object.freeze(o);for(let e of n)e()}let y=rq({adapter:e,clock:t,async onReady(){a+=1;let e=a;return yq(s),s=new AbortController,S(s,e)}}),b=y.subscribe(()=>{let e=y.getSnapshot(),t={picker:e.picker,parseProgress:e.progress,projectFailure:e.failure};e.phase===`picking`&&(t.status=`picking`),e.phase===`error`&&(t.status=`error`,t.error=e.error),v(t)});async function x(){a+=1;let t=a;yq(s),s=new AbortController;let n=s;v({status:`loading`,error:``});let r;try{r=await e.loadPickerState({signal:n.signal})}catch(e){return!bq(e)&&t===a&&v({status:`error`,error:Cq(e)}),i}return t!==a||n.signal.aborted?i:r.state===`unpicked`?(await y.start(),i):S(n,t)}async function S(t,n){v({status:`loading`,error:``,picker:null});try{let r=await e.loadGraph({signal:t.signal});if(n!==a||t.signal.aborted)return i;v({status:`ready`,graph:r,region:WG(r),error:``,entrypointDismissed:!!r.selected_entrypoint})}catch(e){!bq(e)&&n===a&&v({status:`error`,error:Cq(e)})}return await C(t,n),i}async function C(t,n){let r=o,[s,c]=await Promise.allSettled([(async()=>e.loadMode({signal:t.signal}))(),(async()=>e.fetchLlmStatus({signal:t.signal}))()]);if(!(n!==a||t.signal.aborted)){if(r===o){let e=s.status===`fulfilled`?s.value:null;e?.mode===`easy`||e?.mode===`expert`?te(e.mode,e.chosen===!0):i.modeChosen===null&&v({modeChosen:!0})}c.status===`fulfilled`&&v({llmStatus:c.value})}}async function w(){let t=a;if(await e.clearProgress({}),t!==a)return i;a+=1;let n=a;return yq(s),s=new AbortController,S(s,n)}async function T(){return await y.reset()?(ie(),yq(f),f=null,yq(p),p=null,yq(m),m=null,v({graph:null,parseProgress:null,projectFailure:null,region:null,selectedNode:null,level:wG.GALAXY,studyData:null,studyError:``,explanation:null,explanationError:``,explanationLoading:!1,showChart:!1,studiedNodeIds:new Set,showChecks:!1,checkData:null,checkError:``,entrypointDismissed:!1,entrypointError:``,litRegionId:null,pendingDawnRegionId:null,languageFocus:`all`,llmStatus:null,picker:null,mapData:null,mapError:``}),x()):i}async function E(e){switch(e.type){case`ADVANCE`:return O(e.node);case`ADVANCE_REGION`:D(e.regionId);return;case`RETREAT`:k();return;case`SELECT_STUDY_NODE`:return A(e.nodeId);case`SET_LANGUAGE_FOCUS`:ee(e.language);return;case`SET_MODE`:return ne(e.mode);case`HOVER_NODE`:i.hoverNodeId!==(e.nodeId??null)&&v({hoverNodeId:e.nodeId??null});return;case`SHOW_CHART`:v({showChart:!0});return;case`HIDE_CHART`:v({showChart:!1});return;case`OPEN_CHECKS`:return M();case`CLOSE_CHECKS`:oe();return;case`SUBMIT_CHECK`:return se(e.checkId,e.selectedIds);case`CONSUME_DAWN`:pe(e.regionId);return;case`SELECT_ENTRYPOINT`:return ce(e.nodeId);case`DISMISS_ENTRYPOINT`:v({entrypointDismissed:!0});return;case`CHANGE_HOME`:ie(),v({entrypointDismissed:!1,entrypointError:``,level:wG.GALAXY,selectedNode:null,showChart:!1,studyData:null,studyError:``,explanation:null,explanationError:``,explanationLoading:!1});return;case`BROWSE_PICKER`:return y.browse(e.path);case`SELECT_PROJECT`:return y.select(e.path);case`RESET_PROJECT`:return T();case`CLEAR_PROGRESS`:return w();case`SET_LAYER`:return le(e.layer);case`SET_MAP_TAB`:v({mapTab:e.tab});return;case`DISMISS_COACHMARKS`:hq(),v({coachmarksSeen:!0});return;case`SET_LEVEL_GALAXY`:ie(),v({level:wG.GALAXY,selectedNode:null});return;case`TOGGLE_SHOW_ALL`:vq(!i.showAll),v({showAll:!i.showAll});return;case`SET_FINDER_OPEN`:v({finderOpen:e.open});return;case`TOGGLE_SIDEBAR`:v({sidebarOpen:!i.sidebarOpen});return;case`TOGGLE_LEGEND`:v({legendOpen:!i.legendOpen});return;case`GO_TO_REGION`:return v({finderOpen:!1}),D(e.regionId);default:throw Error(`Unknown learner-session event: ${e.type}`)}}function D(e){let t=i.graph?.regions.find(t=>t.id===e);t&&(ie(),v({languageFocus:i.languageFocus!==`all`&&t.language!==i.languageFocus?t.language:i.languageFocus,region:t,selectedNode:null,level:wG.SYSTEM,studyData:null,studyError:``,explanation:null,explanationError:``,explanationLoading:!1}))}async function O(e){if(!(!i.focusedGraph||!e)){if(i.level===wG.GALAXY){let t=i.focusedGraph.regions.find(t=>t.id===e.id)??e;ie(),v({region:t,selectedNode:null,level:wG.SYSTEM,studyData:null,studyError:``,explanation:null,explanationError:``});return}if(i.level===wG.SYSTEM){let t=i.focusedGraph.nodes.find(t=>t.id===e.id)??e;return v({selectedNode:t,level:wG.STUDY}),re(t.id)}}}function k(){i.level===wG.STUDY?(ie(),v({selectedNode:null,level:wG.SYSTEM,studyData:null,studyError:``,explanation:null,explanationError:``,explanationLoading:!1})):i.level===wG.SYSTEM&&v({level:wG.GALAXY})}async function A(e){let t=i.graph?.nodes.find(t=>t.id===e);if(!t)return;let n=i.graph.regions.find(e=>e.id===t.region);return v({languageFocus:i.languageFocus!==`all`&&t.language!==i.languageFocus?t.language:i.languageFocus,region:n??i.region,selectedNode:t,level:wG.STUDY}),re(t.id)}function ee(e){let t=i.selectedNode?.id;v({languageFocus:e}),t&&i.selectedNode?.id!==t&&(ie(),v({studyData:null,studyError:``,explanation:null,explanationError:``,explanationLoading:!1}))}function te(e,t){let n=i.layerChosen?i.layer:e===`easy`?`map`:`galaxy`;v({mode:e,layer:n,modeChosen:t}),n===`map`&&ue()}async function ne(t){if(t!==`easy`&&t!==`expert`)return;let n=i.mode,r=i.modeChosen;if(t===n&&i.modeChosen)return;o+=1,yq(m),m=new AbortController;let s=m,c=a;te(t,!0);try{await e.saveMode(t,{signal:s.signal})}catch(e){m===s&&c===a&&!bq(e)&&te(n,r);return}if(!(c!==a||s.signal.aborted)&&i.level===wG.STUDY&&i.selectedNode)return j(i.selectedNode.id)}async function re(t){ie(),c=new AbortController;let n=c;v({studyData:null,studyError:``}),j(t);try{let r=await e.loadStudy(t,{signal:n.signal});if(n.signal.aborted||i.level!==wG.STUDY||i.selectedNode?.id!==t)return;v({studyData:r,studiedNodeIds:new Set(i.studiedNodeIds).add(r.node.id)})}catch(e){c===n&&!n.signal.aborted&&!bq(e)&&i.selectedNode?.id===t&&v({studyError:Sq(e)})}}function ie(){yq(c),c=null,yq(l),l=null}async function j(t){yq(l),l=new AbortController;let n=l;v({explanation:null,explanationError:``,explanationLoading:!0});try{let r=await e.loadExplanation(t,i.mode,{signal:n.signal});if(n.signal.aborted||i.level!==wG.STUDY||i.selectedNode?.id!==t)return;v({explanation:r,explanationLoading:!1})}catch(e){l===n&&!n.signal.aborted&&!bq(e)&&i.selectedNode?.id===t&&v({explanationError:Sq(e),explanationLoading:!1})}}async function M(){if(!i.region)return;let e=i.region.id;return v({showChecks:!0,checkData:null,checkError:``}),ae(e)}async function ae(t){yq(u),u=new AbortController;let n=u;try{let r=await e.loadChecks(t,{signal:n.signal});return!n.signal.aborted&&i.showChecks&&i.region?.id===t&&v({checkData:r,checkError:``},{preserveChecks:!0}),r}catch(e){u===n&&!bq(e)&&!n.signal.aborted&&i.showChecks&&i.region?.id===t&&v({checkError:Sq(e)},{preserveChecks:!0});return}}function oe(){yq(u),u=null,v({showChecks:!1,checkData:null,checkError:``})}async function se(t,n){if(!i.region)return;let r=i.region.id;yq(d),d=new AbortController;let a=d,o=await e.submitCheck(r,t,n,{signal:a.signal});if(a.signal.aborted||i.region?.id!==r)return o;if(o.correct&&await ae(r),o.region_understood){let t=await e.loadGraph({signal:a.signal});!a.signal.aborted&&i.region?.id===r&&(yq(p),p=null,v({graph:t,region:t.regions.find(e=>e.id===r),mapData:null,mapError:``},{preserveChecks:!0}),fe(r),i.layer===`map`&&await ue())}return o}async function ce(t){let n=a;yq(f),f=new AbortController;let r=f;v({entrypointError:``});try{let o=await e.selectEntrypoint(t,{signal:r.signal});return n!==a||r.signal.aborted?i:(yq(p),p=null,v({graph:o,region:WG(o),entrypointError:``,entrypointDismissed:!0,mapData:null,mapError:``}),i.layer===`map`&&await ue(),o)}catch(e){f===r&&n===a&&!r.signal.aborted&&!bq(e)&&v({entrypointError:Sq(e)});return}}async function le(e){if(v({layer:e,layerChosen:!0}),e===`map`)return ue()}function ue(){if(!i.mapData)return p&&!p.signal.aborted&&!i.mapError?void 0:de()}async function de(){let t=a;yq(p),p=new AbortController;let n=p;v({mapError:``});try{let r=await e.fetchMap({signal:n.signal});return t===a&&!n.signal.aborted&&v({mapData:r,mapError:``}),r}catch(e){p===n&&t===a&&!n.signal.aborted&&!bq(e)&&v({mapError:Sq(e),mapData:null});return}}function fe(e){h!==null&&t.clearTimeout(h),v({litRegionId:e,pendingDawnRegionId:e}),h=t.setTimeout(()=>{h=null,i.litRegionId===e&&v({litRegionId:null})},520)}function pe(e){i.pendingDawnRegionId===e&&v({pendingDawnRegionId:null})}function me(){a+=1;for(let e of[s,c,l,u,d,f,p,m])yq(e);s=null,c=null,l=null,u=null,d=null,f=null,p=null,m=null,b(),y.dispose(),h!==null&&(t.clearTimeout(h),h=null)}return Object.freeze({dispatch:E,dispose:me,getSnapshot:g,start:x,subscribe:_})}function dq(e=globalThis.fetch){if(typeof e!=`function`)throw TypeError(`Learner-session HTTP adapter requires fetch.`);async function t(t,n,r={}){let i=await e(t,r);if(!i.ok){let e=(await i.json().catch(()=>null))?.detail,t=Error(typeof e==`string`&&e?e:`${n} returned ${i.status}.`);throw t.status=i.status,t}return i.json()}return Object.freeze({loadGraph(e={}){return t(`/api/graph`,`Graph request`,e)},fetchMap(e={}){return t(`/api/map`,`Map request`,e)},loadStudy(e,n={}){return t(`/api/node/${encodeURIComponent(e)}/study`,`Study request`,n)},loadExplanation(e,n,r={}){return t(`/api/node/${encodeURIComponent(e)}/explanation?mode=${encodeURIComponent(n)}`,`Explanation request`,r)},loadChecks(e,n={}){return t(`/api/regions/${encodeURIComponent(e)}/checks`,`Checks request`,n)},submitCheck(e,n,r,i={}){return t(`/api/regions/${encodeURIComponent(e)}/checks/${encodeURIComponent(n)}`,`Check submission`,{...i,method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({selected_ids:r})})},selectEntrypoint(e,n={}){return t(`/api/entrypoint`,`Home selection`,{...n,method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({node_id:e})})},loadMode(e={}){return t(`/api/mode`,`Mode request`,e)},saveMode(e,n={}){return t(`/api/mode`,`Mode update`,{...n,method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({mode:e})})},fetchLlmStatus(e={}){return t(`/api/llm/status`,`Model status`,e)},resetProject(e={}){return t(`/api/picker/reset`,`Project reset`,{...e,method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({confirmed:!0})})},loadPickerState(e={}){return t(`/api/picker/state`,`Picker state`,e)},browsePicker(e,n={}){return t(`/api/picker/browse${e?`?path=${encodeURIComponent(e)}`:``}`,`Folder listing`,n)},loadRecents(e={}){return t(`/api/picker/recents`,`Recent projects`,e)},fetchParseProgress(e={}){return t(`/api/picker/progress`,`Parse progress`,e)},clearProgress(e={}){return t(`/api/progress`,`Progress reset`,{...e,method:`DELETE`})},async selectProject(t,n={}){let r=await e(`/api/picker/select`,{...n,method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({path:t})}),i=await r.json().catch(()=>null);if(r.ok)return{state:r.status===202?`parsing`:`ready`};let a=i?.detail;return a&&typeof a==`object`&&a.reason===`scale`?{state:`scale`,...a}:{state:`error`,detail:typeof a==`string`?a:`Project selection returned ${r.status}.`}}})}var fq=`codemble.coachmarks.seen`;function pq(){if(typeof document>`u`)return null;try{return globalThis.localStorage??null}catch{return null}}function mq(){try{return pq()?.getItem(fq)===`1`}catch{return!1}}function hq(){try{pq()?.setItem(fq,`1`)}catch{}}var gq=`codemble.galaxy.showAll`;function _q(){try{return pq()?.getItem(gq)===`1`}catch{return!1}}function vq(e){try{let t=pq();e?t?.setItem(gq,`1`):t?.removeItem(gq)}catch{}}function yq(e){e&&!e.signal.aborted&&e.abort()}function bq(e){return e instanceof Error&&e.name===`AbortError`}function xq(e){return Number.isInteger(e?.status)}function Sq(e){return e instanceof Error?e.message:String(e)}function Cq(e){return xq(e)?Sq(e):`Codemble's local server is not responding, so nothing can be loaded from it. It may have stopped — start it again by running codemble in your terminal. (${Sq(e)})`}function wq(){let e=(0,_.useRef)(null),[t,n]=(0,_.useState)(!1),r=(0,_.useMemo)(()=>uq({adapter:dq()}),[]),i=(0,_.useSyncExternalStore)(r.subscribe,r.getSnapshot,r.getSnapshot);(0,_.useEffect)(()=>(r.start(),()=>r.dispose()),[r]),(0,_.useEffect)(()=>{function e(e){(e.metaKey||e.ctrlKey)&&e.key.toLowerCase()===`k`&&(e.preventDefault(),r.dispatch({type:`SET_FINDER_OPEN`,open:!0}))}return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[r]);let{chart:a,checkData:o,checkError:s,coachmarksSeen:c,entrypointError:l,entrypointOpen:u,error:d,explanation:f,explanationError:p,explanationLoading:m,finderOpen:h,focusedGraph:g,focusedMapData:v,focusedStudiedCount:y,graph:b,hint:x,hoverNodeId:S,languageFocus:C,languageOptions:w,layer:T,legendOpen:E,level:D,litRegionId:O,llmStatus:k,mapError:A,mapTab:ee,mode:te,modeChosen:ne,moduleIndex:re,parseProgress:ie,pendingDawnRegionId:j,picker:M,projectName:ae,projectFailure:oe,region:se,revealedRegionIds:ce,selectedNode:le,showAll:ue,showChart:de,showChecks:fe,sidebarOpen:pe,status:me,studyData:he,studyError:ge}=i;if(d)return(0,$.jsxs)(`main`,{className:`load-state`,role:`alert`,children:[(0,$.jsx)(`h1`,{children:`The graph did not load.`}),(0,$.jsx)(`p`,{children:d}),(0,$.jsx)(`p`,{children:`Your progress is stored on this machine and is not affected.`}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:()=>r.start(),children:`Try again`})]});if(ie)return(0,$.jsx)(Dq,{progress:ie,onCancel:()=>r.dispatch({type:`RESET_PROJECT`})});if(me===`picking`&&M)return(0,$.jsx)(Oq,{picker:M,failure:oe,onBrowse:e=>r.dispatch({type:`BROWSE_PICKER`,path:e}),onSelect:e=>r.dispatch({type:`SELECT_PROJECT`,path:e})});if(!b||!g||!se)return(0,$.jsx)(`main`,{className:`load-state`,"aria-busy":`true`,children:(0,$.jsx)(`p`,{children:`Mapping parser evidence…`})});let _e=D===wG.SYSTEM?(0,$.jsxs)(`section`,{className:`orientation-copy orientation-copy--system${T===`map`?` orientation-copy--inline`:``}`,children:[(0,$.jsx)(`p`,{children:g.nodes.some(e=>e.region===se.id&&e.partial)?`${se.node_count} source ${se.node_count===1?`file remains`:`files remain`} visible · ${se.loc} lines. The module is unchartable beyond raw source because it has a syntax error.`:T===`map`?`The ${se.node_count} parser-proven ${se.node_count===1?`structure`:`structures`} inside this module ${se.node_count===1?`is`:`are`} drawn as planets in the Galaxy layer. This map shows how modules connect, not what is inside them.`:`${se.node_count} parser-proven structures · ${se.loc} lines in this system.`}),(0,$.jsx)(`button`,{className:`check-launch`,type:`button`,onClick:()=>r.dispatch({type:`OPEN_CHECKS`}),children:g.nodes.some(e=>e.region===se.id&&e.partial)?`Check availability`:se.understood?`Review understanding`:`Prove understanding`})]}):null;return(0,$.jsxs)(`main`,{className:`app-shell`,"data-level":de?`chart`:D.toLowerCase(),"data-mode":te,children:[(0,$.jsxs)(`header`,{className:`instrument-rail`,children:[(0,$.jsxs)(`div`,{className:`brand-lockup`,children:[(0,$.jsx)(`span`,{className:`brand-mark`,"aria-hidden":`true`}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`strong`,{children:`Codemble`}),(0,$.jsx)(`span`,{children:ae})]})]}),(0,$.jsx)(`nav`,{className:`location`,"aria-label":`Breadcrumb`,"aria-live":`polite`,children:de?(0,$.jsx)(`span`,{"aria-current":`page`,children:`Star chart`}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`button`,{type:`button`,disabled:D===wG.GALAXY,"aria-current":D===wG.GALAXY?`page`:void 0,onClick:()=>r.dispatch({type:`SET_LEVEL_GALAXY`}),children:`Galaxy`}),D===wG.GALAXY?(0,$.jsxs)(`small`,{children:[` · Home `,b.selected_entrypoint?WG(b)?.id??`unresolved`:`unselected`]}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`span`,{"aria-hidden":`true`,children:`/`}),(0,$.jsx)(`button`,{type:`button`,disabled:D===wG.SYSTEM,"aria-current":D===wG.SYSTEM?`page`:void 0,onClick:()=>r.dispatch({type:`RETREAT`}),children:se.id})]}),D===wG.STUDY&&le?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`span`,{"aria-hidden":`true`,children:`/`}),(0,$.jsx)(`span`,{"aria-current":`page`,children:le.name})]}):null,C===`all`?null:(0,$.jsxs)(`small`,{children:[` · `,AG(C),` focus`]})]})}),(0,$.jsxs)(`div`,{className:`rail-overflow`,"data-open":t||void 0,onKeyDown:r=>{r.key===`Escape`&&t&&(r.preventDefault(),n(!1),e.current?.focus())},children:[(0,$.jsx)(`button`,{ref:e,className:`mobile-menu-trigger`,type:`button`,"aria-expanded":t,"aria-controls":`rail-overflow-panel`,onClick:()=>n(e=>!e),children:`Menu`}),(0,$.jsxs)(`div`,{className:`rail-overflow__panel`,id:`rail-overflow-panel`,onClickCapture:e=>{e.target.closest(`button`)&&!e.target.closest(`.switch-project`)&&n(!1)},children:[(0,$.jsxs)(`div`,{className:`rail-actions`,children:[(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,"aria-pressed":pe,onClick:()=>r.dispatch({type:`TOGGLE_SIDEBAR`}),children:`Modules`}),(0,$.jsxs)(`button`,{className:`rail-action`,type:`button`,onClick:()=>r.dispatch({type:`SET_FINDER_OPEN`,open:!0}),children:[`Find `,(0,$.jsx)(`kbd`,{children:`⌘K`})]}),de?(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,onClick:()=>r.dispatch({type:`HIDE_CHART`}),children:`Return to galaxy`}):D===wG.GALAXY?(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,onClick:()=>r.dispatch({type:`SHOW_CHART`}),children:`Star chart`}):(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,onClick:()=>r.dispatch({type:`RETREAT`}),children:D===wG.STUDY?`Return to system`:`Return to galaxy`}),b.entrypoint_candidates.length?(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,onClick:()=>r.dispatch({type:`CHANGE_HOME`}),children:`Change Home`}):null,(0,$.jsx)(Iq,{onConfirm:()=>r.dispatch({type:`RESET_PROJECT`})})]}),(0,$.jsxs)(`div`,{className:`rail-controls`,children:[T===`galaxy`?(0,$.jsx)(`button`,{className:`rail-action rail-action--toggle`,type:`button`,"aria-pressed":ue,title:`Draw every module at once, including the ones no route from Home reaches`,onClick:()=>r.dispatch({type:`TOGGLE_SHOW_ALL`}),children:`Show all`}):null,(0,$.jsx)(Pq,{layer:T,mode:te,onChange:e=>r.dispatch({type:`SET_LAYER`,layer:e})}),(0,$.jsx)(Fq,{options:w,value:C,onChange:e=>r.dispatch({type:`SET_LANGUAGE_FOCUS`,language:e})}),(0,$.jsx)(NK,{mode:te,modeChosen:ne,onChoose:e=>r.dispatch({type:`SET_MODE`,mode:e})})]})]})]})]}),de?(0,$.jsxs)(`section`,{className:`chart-stage`,"aria-label":`Language concept progress`,children:[pe?(0,$.jsx)(Nq,{index:re,currentRegionId:null,onGo:e=>r.dispatch({type:`GO_TO_REGION`,regionId:e}),onClose:()=>r.dispatch({type:`TOGGLE_SIDEBAR`})}):null,(0,$.jsx)(zq,{chart:a,studiedCount:y,projectName:ae,onClearProgress:()=>r.dispatch({type:`CLEAR_PROGRESS`})})]}):(0,$.jsxs)(`section`,{className:`map-stage`,"aria-label":`Parser-proven project map`,children:[pe?(0,$.jsx)(Nq,{index:re,currentRegionId:D===wG.GALAXY?null:se?.id,onGo:e=>r.dispatch({type:`GO_TO_REGION`,regionId:e}),onClose:()=>r.dispatch({type:`TOGGLE_SIDEBAR`})}):null,T===`map`?(0,$.jsx)(OK,{data:v,mapTab:ee,mode:te,selectedRegionId:D===wG.GALAXY?void 0:se?.id,hasEntrypointCandidates:b.entrypoint_candidates.length>0,error:A,onSelectTab:e=>r.dispatch({type:`SET_MAP_TAB`,tab:e}),onSelectRegion:e=>r.dispatch({type:`ADVANCE_REGION`,regionId:e}),onSelectNode:e=>r.dispatch({type:`SELECT_STUDY_NODE`,nodeId:e}),onRetry:()=>r.dispatch({type:`SET_LAYER`,layer:`map`}),children:_e}):(0,$.jsx)(aK,{graph:g,level:D,region:se,selectedNode:le,hoverNodeId:S,pendingDawnRegionId:j,revealedRegionIds:ce,mode:te,onHoverNode:e=>r.dispatch({type:`HOVER_NODE`,nodeId:e}),onAdvance:e=>r.dispatch({type:`ADVANCE`,node:e}),onRetreat:()=>r.dispatch({type:`RETREAT`}),onDawnConsumed:e=>r.dispatch({type:`CONSUME_DAWN`,regionId:e})}),(0,$.jsx)(`button`,{className:`legend-toggle`,type:`button`,"aria-expanded":E,onClick:()=>r.dispatch({type:`TOGGLE_LEGEND`}),children:`Key`}),(0,$.jsxs)(`aside`,{className:`map-legend`,hidden:!E,"aria-label":T===`map`?`Map legend`:`Galaxy legend`,children:[T===`galaxy`?(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-size`}),`Size · `,te===`easy`?`how much code`:`lines of code`]}),(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-brightness`}),`Brighter · `,te===`easy`?`used in more places`:`more distinct callers`]})]}):null,(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-dot legend-dot--dim`}),`Dim · `,te===`easy`?`not proven yet`:`not understood`]}),(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-dot legend-dot--lit`}),`Amber · `,te===`easy`?`you proved you understand it`:`understood`]}),(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-dot legend-dot--partial`}),te===`easy`?`Could not be read`:`Unchartable · syntax error`]}),(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-route`}),te===`easy`?`Certain connection`:`Parser edge · certain`]}),(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:T===`map`?`legend-route legend-route--possible legend-route--dashed`:`legend-route legend-route--possible`}),te===`easy`?`Possible connection`:`Possible relationship`]}),T===`galaxy`&&D===wG.GALAXY||T===`map`&&ee===`architecture`?w.filter(e=>e.id!==`all`).map(e=>(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-tint legend-tint--${e.id}`}),` `,e.label]},e.id)):null]}),T===`galaxy`&&D===wG.GALAXY?(0,$.jsxs)(`p`,{className:`orientation-bar`,children:[(0,$.jsxs)(`span`,{children:[g.regions.length,` `,C===`all`?g.regions.length===1?`system`:`systems`:`${AG(C)} ${g.regions.length===1?`system`:`systems`}`]}),(0,$.jsx)(`span`,{className:`orientation-bar__charted`,children:ue?`all charted`:`${ce.size} charted`}),g.partial_files.length?(0,$.jsxs)(`span`,{className:`partial-summary`,children:[g.partial_files.length,` unchartable · syntax error`]}):null]}):null,T===`galaxy`?_e:null,D===wG.SYSTEM&&fe?(0,$.jsx)(Rq,{suite:o,error:s,mode:te,onClose:()=>r.dispatch({type:`CLOSE_CHECKS`}),onSubmit:(e,t)=>r.dispatch({type:`SUBMIT_CHECK`,checkId:e,selectedIds:t})}):null,u&&D===wG.GALAXY?(0,$.jsx)(Lq,{candidates:b.entrypoint_candidates,nodes:b.nodes,selectedEntrypoint:b.selected_entrypoint,error:l,onSelect:e=>r.dispatch({type:`SELECT_ENTRYPOINT`,nodeId:e}),onContinue:()=>r.dispatch({type:`DISMISS_ENTRYPOINT`})}):null,O?(0,$.jsxs)(`output`,{className:`illumination-pulse`,"aria-live":`polite`,children:[(0,$.jsx)(`span`,{"aria-hidden":`true`,children:`✦`}),(0,$.jsxs)(`strong`,{children:[O,` understood`]})]}):null,D===wG.STUDY&&le?(0,$.jsx)(PK,{node:le,study:he,error:ge,mode:te,explanation:f,explanationLoading:m,explanationError:p,llmStatus:k,onSelectNode:e=>r.dispatch({type:`SELECT_STUDY_NODE`,nodeId:e}),onRetryNarration:()=>r.dispatch({type:`SELECT_STUDY_NODE`,nodeId:le.id})}):null,ne===!0&&!u&&!c?(0,$.jsx)(pK,{layer:T,onDismiss:()=>r.dispatch({type:`DISMISS_COACHMARKS`})}):null]}),h?(0,$.jsx)(Mq,{index:re,onGo:e=>r.dispatch({type:`GO_TO_REGION`,regionId:e}),onClose:()=>r.dispatch({type:`SET_FINDER_OPEN`,open:!1})}):null,de?null:(0,$.jsx)(uK,{hint:x,onStudy:e=>r.dispatch({type:`ADVANCE_REGION`,regionId:e})}),(0,$.jsxs)(`footer`,{className:`status-line`,children:[(0,$.jsx)(`span`,{children:de?`${a.length} concepts detected`:C===`all`?`${b.nodes.length} nodes · ${b.edges.length} edges`:`${g.nodes.length}/${b.nodes.length} nodes · ${g.edges.length} focused edges`}),(0,$.jsx)(`span`,{children:de?`${y} focused structures studied this session`:T===`map`?`Click a box or row to study · Switch tabs to change view`:`Drag to orbit · Scroll to zoom · Click to move closer · Escape to move back`}),(0,$.jsx)(`span`,{children:`Local only`})]})]})}var Tq=Object.fromEntries(nq.map(({id:e,copy:t})=>[e,t])),Eq=nq.map(({id:e})=>e);function Dq({progress:e,onCancel:t}){let{stage:n,detail:r,files_done:i,files_total:a,pollError:o,pollOutage:s,attempts:c,path:l}=e,[u,d]=(0,_.useState)(!1),[f,p]=(0,_.useState)(``),m=(0,_.useRef)(null),h=Eq.indexOf(n);(0,_.useEffect)(()=>{m.current?.focus()},[]);async function g(){d(!0),p(``);try{await t()}catch(e){p(e.message),d(!1)}}return(0,$.jsxs)(`main`,{className:`loading-screen`,children:[(0,$.jsxs)(`header`,{className:`loading-header`,children:[(0,$.jsx)(`p`,{className:`picker-wordmark`,children:`Codemble`}),(0,$.jsxs)(`h1`,{ref:m,tabIndex:-1,children:[`Mapping `,(0,$.jsx)(`span`,{className:`loading-path`,children:l})]}),(0,$.jsx)(`p`,{className:`loading-subtitle`,children:`Parsing runs on your machine. Nothing is sent anywhere.`})]}),(0,$.jsx)(`ol`,{className:`loading-stages`,"aria-label":`Parse stages`,children:Eq.map((e,t)=>{let n=t(0,$.jsx)(`li`,{children:(0,$.jsxs)(`button`,{type:`button`,disabled:u,onClick:()=>r(e.project_root),children:[(0,$.jsx)(`span`,{className:`picker-recent-path`,children:e.project_root}),(0,$.jsxs)(`span`,{className:`picker-recent-lit`,children:[e.understood_count,` `,e.understood_count===1?`system`:`systems`,` lit last visit`]})]})},e.project_root))})]}):null,l?(0,$.jsx)(kq,{scale:l,busy:u,onBrowse:n}):null,t?(0,$.jsx)(jq,{failure:t,busy:u,onSelect:r}):c?(0,$.jsx)(`p`,{className:`picker-error`,role:`alert`,children:c}):null,(0,$.jsxs)(`section`,{className:`picker-browser`,"aria-labelledby":`picker-browser-heading`,children:[(0,$.jsx)(`h2`,{id:`picker-browser-heading`,children:`Browse folders`}),(0,$.jsx)(`p`,{className:`picker-path`,children:i}),(0,$.jsxs)(`ul`,{children:[a?(0,$.jsx)(`li`,{children:(0,$.jsx)(`button`,{type:`button`,disabled:u,onClick:()=>n(a),children:`↑ Up`})}):null,o.map(e=>(0,$.jsx)(`li`,{children:(0,$.jsxs)(`button`,{type:`button`,disabled:u,onClick:()=>n(e.path),children:[e.name,`/`]})},e.path))]}),(0,$.jsx)(`button`,{className:`picker-select`,type:`button`,disabled:u,onClick:()=>r(i),children:u?`Mapping…`:`Map this folder`})]})]})}function kq({scale:e,busy:t,onBrowse:n}){let r=e.suggestions.filter(e=>e.path!==`.`);return(0,$.jsxs)(`section`,{className:`picker-scale`,role:`alert`,"aria-labelledby":`picker-scale-heading`,children:[(0,$.jsx)(`h2`,{id:`picker-scale-heading`,children:`That folder is too big to map at once.`}),(0,$.jsxs)(`p`,{children:[`It has `,e.file_count,` supported source files; Codemble maps up to`,` `,e.scale_cap,`. Choose a smaller scope — busiest first.`]}),r.length?(0,$.jsx)(`ul`,{className:`picker-scale-scopes`,children:r.map(r=>(0,$.jsx)(`li`,{children:(0,$.jsxs)(`button`,{type:`button`,disabled:t,onClick:()=>n(`${e.root}/${r.path}`),children:[(0,$.jsxs)(`span`,{children:[r.path,`/`]}),(0,$.jsxs)(`small`,{children:[r.file_count,` files`]})]})},r.path))}):null,(0,$.jsx)(Aq,{busy:t,onBrowse:n})]})}function Aq({busy:e,onBrowse:t}){let[n,r]=(0,_.useState)(``);return(0,$.jsxs)(`form`,{className:`picker-path-entry`,onSubmit:e=>{e.preventDefault();let r=n.trim();r&&t(r)},children:[(0,$.jsx)(`label`,{htmlFor:`picker-path-input`,children:`Or type a folder path`}),(0,$.jsx)(`input`,{id:`picker-path-input`,type:`text`,value:n,disabled:e,placeholder:`/Users/you/project/src`,onChange:e=>r(e.target.value)}),(0,$.jsx)(`button`,{type:`submit`,disabled:e||!n.trim(),children:`Go`})]})}function jq({failure:e,busy:t,onSelect:n}){return(0,$.jsxs)(`section`,{className:`picker-failure`,role:`alert`,children:[(0,$.jsx)(`h2`,{children:`Codemble could not map that folder.`}),(0,$.jsx)(`p`,{children:`Nothing on disk changed, and no project's saved progress was touched. Try it again, or choose a different folder below.`}),(0,$.jsxs)(`p`,{className:`picker-failure__detail`,children:[(0,$.jsx)(`span`,{children:`What the parser reported`}),(0,$.jsx)(`code`,{children:e.detail})]}),(0,$.jsxs)(`button`,{className:`picker-select`,type:`button`,disabled:t,onClick:()=>n(e.path),children:[`Try `,(0,$.jsx)(`span`,{className:`picker-recent-path`,children:e.path}),` again`]})]})}function Mq({index:e,onGo:t,onClose:n}){let[r,i]=(0,_.useState)(``),[a,o]=(0,_.useState)(0),s=(0,_.useRef)(null),c=(0,_.useRef)(null),l=(0,_.useMemo)(()=>{let t=r.trim().toLowerCase();return(t?e.filter(e=>e.label.toLowerCase().includes(t)||e.file.toLowerCase().includes(t)):e).slice(0,60)},[e,r]);(0,_.useLayoutEffect)(()=>{let e=s.current;e&&!e.open&&e.showModal(),c.current?.focus()},[]),(0,_.useEffect)(()=>o(0),[r]);let u=l[Math.min(a,l.length-1)]??null;function d(e){e.key===`ArrowDown`?(e.preventDefault(),o(e=>Math.min(e+1,l.length-1))):e.key===`ArrowUp`?(e.preventDefault(),o(e=>Math.max(e-1,0))):e.key===`Enter`&&u&&(e.preventDefault(),t(u.id))}return(0,$.jsxs)(`dialog`,{ref:s,className:`module-finder`,"aria-label":`Find a module`,onCancel:e=>{e.preventDefault(),n()},onClose:n,children:[(0,$.jsx)(`input`,{ref:c,type:`search`,value:r,placeholder:`Find a module…`,"aria-label":`Find a module by name or path`,onChange:e=>i(e.target.value),onKeyDown:d}),(0,$.jsx)(`ul`,{role:`listbox`,"aria-label":`Matching modules`,children:l.map((e,n)=>(0,$.jsx)(`li`,{children:(0,$.jsxs)(`button`,{type:`button`,role:`option`,"aria-selected":n===a,"data-active":n===a||void 0,onMouseEnter:()=>o(n),onClick:()=>t(e.id),children:[(0,$.jsx)(`strong`,{children:e.label}),(0,$.jsx)(`small`,{children:e.file}),e.home?(0,$.jsx)(`em`,{children:`Home`}):e.understood?(0,$.jsx)(`em`,{children:`lit`}):null]})},e.id))}),l.length?null:(0,$.jsx)(`p`,{className:`module-finder__empty`,children:`No module matches that.`})]})}function Nq({index:e,currentRegionId:t,onGo:n,onClose:r}){let i=(0,_.useMemo)(()=>zG(e),[e]);return(0,$.jsxs)(`aside`,{className:`index-sidebar`,"aria-label":`Project index`,children:[(0,$.jsxs)(`header`,{children:[(0,$.jsx)(`h2`,{children:`Modules`}),(0,$.jsx)(`button`,{type:`button`,onClick:r,"aria-label":`Close the project index`,children:`×`})]}),(0,$.jsx)(`div`,{className:`index-sidebar__scroll`,children:i.map(e=>(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{title:e.name,children:e.name}),(0,$.jsx)(`ul`,{children:e.members.map(e=>(0,$.jsx)(`li`,{children:(0,$.jsxs)(`button`,{type:`button`,"aria-current":e.id===t?`true`:void 0,"data-lit":e.understood||void 0,title:e.file,onClick:()=>n(e.id),children:[(0,$.jsx)(`span`,{children:e.display??e.label}),e.home?(0,$.jsx)(`em`,{children:`Home`}):null]})},e.id))})]},e.community))})]})}function Pq({layer:e,mode:t,onChange:n}){return(0,$.jsx)(`nav`,{className:`layer-switcher`,"aria-label":`View layer`,children:[{id:`galaxy`,label:`Galaxy`},{id:`map`,label:t===`easy`?`Diagram`:`Map`}].map(t=>(0,$.jsx)(`button`,{type:`button`,"aria-pressed":e===t.id,onClick:()=>n(t.id),children:t.label},t.id))})}function Fq({options:e,value:t,onChange:n}){return e.length<=2?null:(0,$.jsxs)(`nav`,{className:`language-focus`,"aria-label":`Language focus`,children:[(0,$.jsx)(`span`,{className:`language-focus__label`,children:`Focus`}),(0,$.jsx)(`div`,{children:e.map(e=>(0,$.jsxs)(`button`,{type:`button`,"aria-label":`Focus ${e.label}: ${e.count} ${e.count===1?`system`:`systems`}`,"aria-pressed":t===e.id,title:e.label,onClick:()=>n(e.id),children:[(0,$.jsx)(`span`,{children:e.shortLabel}),(0,$.jsx)(`small`,{children:e.count})]},e.id))})]})}function Iq({onConfirm:e}){let[t,n]=(0,_.useState)(!1),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)(``),s=(0,_.useRef)(null),c=(0,_.useRef)(null),l=(0,_.useRef)(!1);(0,_.useEffect)(()=>{t?c.current?.focus():l.current&&s.current?.focus(),l.current=t},[t]);function u(){n(!1),o(``)}async function d(){i(!0),o(``);try{await e()}catch(e){o(e.message),i(!1)}}return t?(0,$.jsxs)(`div`,{className:`switch-project`,role:`group`,"aria-label":`Switch project`,tabIndex:-1,ref:c,onKeyDown:e=>{e.key===`Escape`&&!r&&u()},children:[(0,$.jsx)(`p`,{children:`Progress is saved per project, so this galaxy comes back lit.`}),a?(0,$.jsx)(`p`,{className:`switch-project__error`,role:`alert`,children:a}):null,(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,disabled:r,onClick:d,children:r?`Releasing…`:`Switch`}),(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,disabled:r,onClick:u,children:`Cancel`})]})]}):(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,ref:s,onClick:()=>n(!0),children:`Switch project`})}function Lq({candidates:e,nodes:t,selectedEntrypoint:n,error:r,onSelect:i,onContinue:a}){let o=new Map(t.map(e=>[e.id,e]));return(0,$.jsxs)(`aside`,{className:`entrypoint-picker`,"aria-labelledby":`entrypoint-heading`,children:[(0,$.jsx)(`p`,{children:`Home calibration`}),(0,$.jsx)(`h1`,{id:`entrypoint-heading`,children:e.length?`Where does your project start?`:`No clear entrypoint found.`}),(0,$.jsx)(`p`,{children:e.length?`The parser found ranked candidates but cannot choose one honestly. Select the structure you run.`:`No file here declares a startup structure the parser recognises, and Codemble will not guess one. Explore the map without Home — every system, check, explanation, and lens note still works.`}),e.length?(0,$.jsx)(`div`,{className:`entrypoint-candidates`,children:e.map(e=>{let t=o.get(e);return(0,$.jsxs)(`button`,{type:`button`,onClick:()=>i(e),children:[(0,$.jsx)(`span`,{children:e}),(0,$.jsxs)(`small`,{children:[t?.file,`:`,t?.lineno,` · parser rank `,t?.entrypoint_rank]})]},e)})}):null,r?(0,$.jsx)(`p`,{className:`entrypoint-error`,role:`alert`,children:r}):null,(0,$.jsx)(`button`,{className:`entrypoint-continue`,type:`button`,onClick:a,children:n?`Keep current Home`:`Explore without Home`})]})}function Rq({suite:e,error:t,mode:n,onClose:r,onSubmit:i}){let a=e?.checks.find(e=>!e.passed)??null,o=e?.checks.filter(e=>e.passed).length??0,[s,c]=(0,_.useState)(()=>new Set),[l,u]=(0,_.useState)(null),[d,f]=(0,_.useState)(``),[p,m]=(0,_.useState)(!1),[h,g]=(0,_.useState)(``);(0,_.useEffect)(()=>{c(new Set),u(null),g(``)},[a?.id]);function v(e,t){f(``),c(n=>{if(!t)return new Set([e]);let r=new Set(n);return r.has(e)?r.delete(e):r.add(e),r})}async function y(e){if(e.preventDefault(),!(!a||s.size===0)){m(!0),g(``);try{let e=await i(a.id,[...s]);e.correct?(f(e.message),u(null)):(f(``),u(e))}catch(e){g(e.message)}finally{m(!1)}}}return(0,$.jsxs)(`aside`,{className:`check-panel`,"aria-label":`Graph-derived understanding checks`,children:[(0,$.jsxs)(`header`,{className:`check-panel__header`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`p`,{children:`Active recall · graph only`}),(0,$.jsx)(`h1`,{children:e?.region_id??`Loading checks`})]}),(0,$.jsx)(`button`,{className:`check-close`,type:`button`,onClick:r,children:`Close`})]}),t||h?(0,$.jsxs)(`div`,{className:`check-state`,role:`alert`,children:[(0,$.jsx)(`h2`,{children:`The checks did not load.`}),(0,$.jsxs)(`p`,{children:[t||h,` The galaxy remains available.`]})]}):null,!e&&!t?(0,$.jsx)(`p`,{className:`check-loading`,role:`status`,children:`Deriving answers from parser edges…`}):null,e?.region_understood?(0,$.jsxs)(`div`,{className:`check-complete`,"aria-live":`polite`,children:[(0,$.jsx)(`span`,{className:`check-complete__star`,"aria-hidden":`true`,children:`✦`}),(0,$.jsx)(`h2`,{children:`System lit.`}),(0,$.jsx)(`p`,{children:`This region's source hash matches the checks you passed. Edit its file and only this system will dim again.`}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:r,children:`Return to the system`})]}):null,e&&!e.region_understood&&e.checks.length===0?(0,$.jsxs)(`div`,{className:`check-state`,children:[(0,$.jsx)(`h2`,{children:`No safe check yet.`}),(0,$.jsx)(`p`,{children:`Every question here is answered by the parser graph, and this region has no certain relationship Codemble can build one from. It stays dim rather than lighting on a question that would prove nothing. Import this module somewhere, or call something inside it, and its checks appear.`})]}):null,a&&!e.region_understood?(0,$.jsxs)(`form`,{className:`active-check`,onSubmit:y,children:[(0,$.jsxs)(`div`,{className:`check-progress`,children:[(0,$.jsxs)(`span`,{children:[`Check `,o+1,` of `,e.checks.length]}),(0,$.jsx)(`progress`,{value:o,max:e.checks.length})]}),d?(0,$.jsxs)(`p`,{className:`check-affirmation`,role:`status`,children:[(0,$.jsx)(`span`,{"aria-hidden":`true`,children:`✦`}),` `,d]}):null,(0,$.jsxs)(`fieldset`,{children:[(0,$.jsx)(`legend`,{children:a.prompt_voices[n]}),a.multiple?(0,$.jsx)(`p`,{children:`Select every answer supported by the graph.`}):null,(0,$.jsx)(`div`,{className:`check-options`,children:a.options.map(e=>(0,$.jsxs)(`label`,{children:[(0,$.jsx)(`input`,{type:a.multiple?`checkbox`:`radio`,name:`answer-${a.id}`,value:e.id,checked:s.has(e.id),onChange:()=>v(e.id,a.multiple)}),(0,$.jsx)(`span`,{children:e.label})]},e.id))})]}),l&&!l.correct?(0,$.jsxs)(`div`,{className:`check-feedback`,role:`status`,children:[(0,$.jsx)(`strong`,{children:l.message}),(0,$.jsxs)(`span`,{children:[`Parser answer: `,l.answer_labels.join(`, `)]}),(0,$.jsxs)(`span`,{children:[`Evidence: `,l.evidence.join(`, `)]})]}):null,(0,$.jsx)(`button`,{className:`check-primary`,type:`submit`,disabled:!s.size||p,children:p?`Checking parser evidence…`:`Check answer`})]}):null]})}function zq({chart:e,studiedCount:t,projectName:n,onClearProgress:r}){let i=e.filter(e=>e.understood_nodes>0).length;return(0,$.jsxs)(`section`,{className:`star-chart-screen`,"aria-labelledby":`star-chart-heading`,children:[(0,$.jsxs)(`header`,{className:`star-chart-intro`,children:[(0,$.jsx)(`p`,{children:`Parser-detected concepts`}),(0,$.jsx)(`h1`,{id:`star-chart-heading`,children:`Your language star chart.`}),(0,$.jsx)(`p`,{children:`Encountered comes from real syntax. Studied tracks this session. Understood lights only after graph-derived checks pass.`}),(0,$.jsxs)(`dl`,{children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Concepts encountered`}),(0,$.jsx)(`dd`,{children:e.length})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Studied this session`}),(0,$.jsx)(`dd`,{children:t})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Concepts understood`}),(0,$.jsx)(`dd`,{children:i})]})]})]}),(0,$.jsx)(`div`,{className:`concept-ledger`,role:`list`,"aria-label":`Language concept progress`,children:e.map(e=>(0,$.jsxs)(`article`,{className:`concept-row`,role:`listitem`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`h2`,{children:kG(e.concept)}),(0,$.jsxs)(`span`,{children:[kG(e.language),` · `,e.occurrences,` parser `,e.occurrences===1?`occurrence`:`occurrences`]})]}),(0,$.jsx)(`div`,{className:`concept-meter`,"aria-label":`${e.understood_nodes} of ${e.nodes} structures understood`,children:(0,$.jsx)(`span`,{style:{width:`${e.nodes?e.understood_nodes/e.nodes*100:0}%`}})}),(0,$.jsxs)(`dl`,{children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Studied (session)`}),(0,$.jsxs)(`dd`,{children:[e.studied_nodes,`/`,e.nodes]})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Understood`}),(0,$.jsxs)(`dd`,{children:[e.understood_nodes,`/`,e.nodes]})]})]})]},`${e.language}:${e.concept}`))}),(0,$.jsx)(Bq,{projectName:n,onConfirm:r})]})}function Bq({projectName:e,onConfirm:t}){let[n,r]=(0,_.useState)(!1),[i,a]=(0,_.useState)(!1),[o,s]=(0,_.useState)(``),c=(0,_.useRef)(null),l=(0,_.useRef)(null),u=(0,_.useRef)(!1);(0,_.useEffect)(()=>{n?l.current?.focus():u.current&&c.current?.focus(),u.current=n},[n]);function d(){r(!1),s(``)}async function f(){a(!0),s(``);try{await t(),r(!1)}catch(e){s(e.message)}finally{a(!1)}}return n?(0,$.jsxs)(`section`,{className:`progress-reset progress-reset--confirming`,role:`group`,"aria-label":`Clear this project's progress`,tabIndex:-1,ref:l,onKeyDown:e=>{e.key===`Escape`&&!i&&d()},children:[(0,$.jsxs)(`p`,{role:`alert`,children:[`This dims every system you lit in `,e,` and cannot be undone. Your other projects keep their progress, and no source file is touched.`]}),o?(0,$.jsx)(`p`,{className:`progress-reset__error`,role:`alert`,children:o}):null,(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`button`,{className:`check-primary progress-reset__confirm`,type:`button`,disabled:i,onClick:f,children:i?`Clearing…`:`Yes, clear ${e}`}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,disabled:i,onClick:d,children:`Keep it`})]})]}):(0,$.jsxs)(`section`,{className:`progress-reset`,children:[(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,ref:c,onClick:()=>r(!0),children:`Clear this project's progress`}),(0,$.jsxs)(`p`,{children:[`Start `,e,` over with every system dim again.`]})]})}var Vq=class extends _.Component{constructor(e){super(e),this.state={message:``}}static getDerivedStateFromError(e){return{message:e instanceof Error?e.message:String(e)}}componentDidCatch(e,t){console.error(`Codemble stopped rendering:`,e,t?.componentStack)}render(){return this.state.message?(0,$.jsxs)(`main`,{className:`load-state`,role:`alert`,children:[(0,$.jsx)(`h1`,{children:`The galaxy stopped rendering.`}),(0,$.jsx)(`p`,{children:this.state.message}),(0,$.jsx)(`p`,{children:`Your progress is saved on this machine; reloading re-reads it.`}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:()=>window.location.reload(),children:`Reload Codemble`})]}):this.props.children}};(0,v.createRoot)(document.getElementById(`root`)).render((0,$.jsx)(_.StrictMode,{children:(0,$.jsx)(Vq,{children:(0,$.jsx)(wq,{})})})); \ No newline at end of file + }`})}};UW.BlurDirectionX=new L(1,0),UW.BlurDirectionY=new L(0,1);var WW=.9,GW=.45,KW=.52,qW=1600;function JW(e){let t=e.postProcessingComposer(),n=new UW(new L(t._width??1,t._height??1),WW,GW,KW),r=n.setSize.bind(n);n.setSize=(e,t)=>{let n=Math.min(1,qW/Math.max(e,t,1));r(Math.max(1,Math.round(e*n)),Math.max(1,Math.round(t*n)))},t.addPass(n);let i=new Ez(xz);return t.addPass(i),{pass:n,composer:t,dispose(){t.removePass(i),i.dispose(),t.removePass(n),n.dispose()}}}var YW=1200;function XW(){return globalThis.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches??!1}function ZW({scene:e,regionId:t,palette:n}){if(XW())return()=>{};let r=e.getObjectByName(`codemble-system-${t}`);if(!r)return()=>{};let i=[];r.traverse(e=>{e.isSprite&&i.push([e,e.material.opacity,e.scale.x])});let a=new B(n.star),o=i.map(([e])=>e.material.color.clone()),s=0,c=performance.now(),l=()=>{let e=Math.min(1,(performance.now()-c)/YW);1-(1-e)**3;let t=Math.sin(e*Math.PI);if(i.forEach(([e,n,r],i)=>{e.material.color.copy(o[i]).lerp(a,t*.85),e.material.opacity=n+t*.5,e.scale.setScalar(r*(1+t*.45))}),e<1){s=requestAnimationFrame(l);return}i.forEach(([e,t,n],r)=>{e.material.color.copy(o[r]),e.material.opacity=t,e.scale.setScalar(n)})};return s=requestAnimationFrame(l),()=>{cancelAnimationFrame(s),i.forEach(([e,t,n],r)=>{e.material.color.copy(o[r]),e.material.opacity=t,e.scale.setScalar(n)})}}var QW=Object.freeze({width:132,height:30}),$W=Object.freeze({far:14,near:44}),eG=Object.freeze([0,-1,1,-2,2]),tG=4,nG=.034;function rG(e,{radius:t,aspect:n}){return e.scale.set(nG*n,nG,1),e.userData.baseOffsetY=t*2.2+1.2,e.position.set(0,e.userData.baseOffsetY,0),e.visible=!1,e.userData.codembleLabel=!0,e.userData.screenWidthFraction=nG*n,e.userData.screenHeightFraction=nG,e}function iG(e){let t=aG(e),n=new R,r=new R;function i({scene:e,camera:i,width:a,height:o,distance:s,distanceBounds:c,hoverNodeId:l=null}){let u=oG(e);for(let e of u)e.visible=!1;if(!u.length||!t.size)return Object.freeze({budget:0,shown:0,visibleIds:Object.freeze([])});let d=sG(s,c),f=[];for(let e of u){let s=e.userData.nodeId,c=e.parent;if(!c)continue;c.getWorldPosition(r);let u=e.userData.baseOffsetY??0,d=cG(r,u,i,a,o,n);if(!d)continue;let p=cG(r,u+1,i,a,o,n),m=p?Math.abs(p.screenY-d.screenY):0;f.push({sprite:e,nodeId:s,origin:r.clone(),base:u,pixelsPerUnit:m,anchor:d,halfWidth:(e.userData.screenWidthFraction??.14)*o/2,halfHeight:(e.userData.screenHeightFraction??.034)*o/2,rank:s===l?-1:t.get(s)??1/0})}f.sort((e,t)=>e.rank-t.rank||e.nodeId.localeCompare(t.nodeId));let p=new Set,m=[];for(let e of f){if(m.length>=d)break;let t=lG(e,{camera:i,width:a,height:o,projected:n,taken:p});if(t){for(let e of t.cells)p.add(e);e.sprite.position.y=e.base+t.offset,e.sprite.visible=!0,m.push(e.nodeId)}}return Object.freeze({budget:d,shown:m.length,visibleIds:Object.freeze(m)})}function a(e){for(let t of oG(e))t.visible=!1}return Object.freeze({hide:a,place:i})}function aG(e){let t=e.filter(e=>e.label).map(e=>({id:e.id,weight:(e.home?3e6:0)+(e.understood?1e6:0)+(e.centrality??0)*1e3})).sort((e,t)=>t.weight-e.weight||e.id.localeCompare(t.id));return new Map(t.map((e,t)=>[e.id,t]))}function oG(e){let t=[];return e.traverse(e=>{e.userData?.codembleLabel&&t.push(e)}),t}function sG(e,t){let n=Math.max(1,t.max-t.min),r=1-Math.min(1,Math.max(0,(e-t.min)/n));return Math.round($W.far+($W.near-$W.far)*r)}function cG(e,t,n,r,i,a){if(a.set(e.x,e.y+t,e.z).project(n),a.z>1)return null;let o=(a.x*.5+.5)*r,s=(-a.y*.5+.5)*i;return o<0||o>r||s<0||s>i?null:{screenX:o,screenY:s}}function lG(e,{camera:t,width:n,height:r,projected:i,taken:a}){let o=e.pixelsPerUnit?(e.halfHeight*2+tG)/e.pixelsPerUnit:0;for(let s of eG){let c=s*o,l=s===0?e.anchor:cG(e.origin,e.base+c,t,n,r,i);if(!l)continue;let u=uG(l,e);if(!u.some(e=>a.has(e)))return{cells:u,offset:c}}return null}function uG(e,{halfWidth:t,halfHeight:n}){let r=Math.floor((e.screenX-t)/QW.width),i=Math.floor((e.screenX+t)/QW.width),a=Math.floor((e.screenY-n)/QW.height),o=Math.floor((e.screenY+n)/QW.height),s=[];for(let e=r;e<=i;e+=1)for(let t=a;t<=o;t+=1)s.push(`${e}:${t}`);return s}var dG=128,fG=256;function pG(e,t){let n=document.createElement(`canvas`);n.width=e,n.height=e;let r=n.getContext(`2d`),i=r.createRadialGradient(e/2,e/2,0,e/2,e/2,e/2);for(let[e,n]of t)i.addColorStop(e,`rgba(255, 255, 255, ${n})`);r.fillStyle=i,r.fillRect(0,0,e,e);let a=new Ra(n);return a.colorSpace=lt,a}function mG(e){let t=document.createElement(`canvas`);t.width=e,t.height=e;let n=t.getContext(`2d`);n.strokeStyle=`rgba(255, 255, 255, 1)`,n.lineWidth=e*.05,n.beginPath(),n.arc(e/2,e/2,e*.4,0,Math.PI*2),n.stroke();let r=new Ra(t);return r.colorSpace=lt,r}function hG(e){let t=[];function n(e){let n=e.dispose.bind(e);return e.dispose=()=>{},t.push(n),e}let r=n(pG(dG,[[0,.85],[.25,.42],[.6,.1],[1,0]])),i=n(pG(fG,[[0,.32],[.45,.14],[.8,.03],[1,0]])),a=n(mG(dG)),o=new Map,s=new Map,c=new Map;function l(t){return c.has(t)||c.set(t,n(vG(t,e))),c.get(t)}function u(t){return o.has(t)||o.set(t,n(new Si({map:r,color:new B(t).multiply(new B(e.starHalo)),blending:2,transparent:!0,depthWrite:!1,opacity:.6}))),o.get(t)}return{halo(e,t){let n=new Ii(u(e.color));return n.scale.setScalar(t*6.5),n.renderOrder=-1,n},nebula(e,t){s.has(e)||s.set(e,n(new Si({map:i,color:new B(e),blending:2,transparent:!0,depthWrite:!1,opacity:.16})));let r=new Ii(s.get(e));return r.scale.setScalar(t),r.renderOrder=-2,r},reticle(t){let n=new Ii(new Si({map:a,color:new B(e.orbit),transparent:!0,depthWrite:!1,depthTest:!1}));return n.scale.setScalar(t*5),n.renderOrder=3,n},label(e,t){let n=l(e),r=new Ii(n);return rG(r,{radius:t,aspect:n.userData.aspect??4}),r.renderOrder=4,r},dispose(){for(let e of t)e();t.length=0,o.clear(),s.clear(),c.clear()}}}var gG=34,_G=12;function vG(e,t){let n=document.createElement(`canvas`),r=n.getContext(`2d`),i=`${gG}px "JetBrains Mono", ui-monospace, monospace`;r.font=i;let a=Math.ceil(r.measureText(e).width)+_G*2;n.width=a,n.height=58,r.font=i,r.textBaseline=`middle`,r.textAlign=`center`,r.fillStyle=t.labelPlate,yG(r,0,0,a,58,8),r.fill(),r.fillStyle=t.labelInk,r.fillText(e,a/2,30);let o=new Ra(n);o.colorSpace=lt;let s=new Si({map:o,transparent:!0,depthWrite:!1,depthTest:!1,sizeAttenuation:!1});s.userData.aspect=a/58;let c=s.dispose.bind(s);return s.dispose=()=>{o.dispose(),c()},s}function yG(e,t,n,r,i,a){e.beginPath(),e.moveTo(t+a,n),e.arcTo(t+r,n,t+r,n+i,a),e.arcTo(t+r,n+i,t,n+i,a),e.arcTo(t,n+i,t,n,a),e.arcTo(t,n,t+r,n,a),e.closePath()}function bG(e){return Object.entries(e??{}).sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>`${e}:${t}`).join(`|`)}function xG(e){let t=e>>>0;return function(){t=t+1831565813>>>0;let e=Math.imul(t^t>>>15,1|t);return e=e+Math.imul(e^e>>>7,61|e)^e,((e^e>>>14)>>>0)/4294967296}}function SG(e){let t=2166136261;for(let n=0;n>>0}function CG(e,t,n=1400,r=1600){let i=xG(SG(e)),a=new Float32Array(n*3);for(let e=0;ee.language===t),r=new Set(n.map(e=>e.id)),i=new Set(e.nodes.map(e=>e.id)),a=new Set(n.map(e=>e.region)),o=new Set(n.map(e=>e.file));return{...e,nodes:n,edges:e.edges.filter(e=>r.has(e.src)&&(r.has(e.dst)||e.external||!i.has(e.dst))),entrypoint_candidates:e.entrypoint_candidates.filter(e=>r.has(e)),selected_entrypoint:r.has(e.selected_entrypoint)?e.selected_entrypoint:null,file_hashes:Object.fromEntries(Object.entries(e.file_hashes).filter(([e])=>o.has(e))),concept_annotations:e.concept_annotations.filter(e=>e.language===t&&r.has(e.node_id)),regions:e.regions.filter(e=>a.has(e.id)),region_edges:e.region_edges.filter(e=>a.has(e.src)&&a.has(e.dst)),partial_files:e.partial_files.filter(e=>o.has(e))}}function EG(e,t){if(!e||!t||t===`all`)return e;let n=e.architecture,r=n.boxes.filter(e=>e.language===t),i=new Set(r.map(e=>e.id)),a=e.workflow,o=`${t}:`;return{...e,architecture:{...n,boxes:r,edges:n.edges.filter(e=>i.has(e.src)&&i.has(e.dst)),unreachable:n.unreachable.filter(e=>i.has(e))},workflow:{...a,nodes:a.nodes.filter(e=>e.language===t),unreachable:a.unreachable.filter(e=>e.startsWith(o))}}}function DG(e){let t=new Map;for(let n of e.regions)t.set(n.language,(t.get(n.language)??0)+1);let n=[...t].map(([e,t])=>({id:e,label:AG(e),shortLabel:jG(e),count:t})).sort((e,t)=>e.label.localeCompare(t.label));return[{id:`all`,label:`All languages`,shortLabel:`All`,count:e.regions.length},...n]}function OG(e,t){let n=new Map(e.nodes.map(e=>[e.id,e])),r=new Map;for(let i of e.concept_annotations??[]){let e=`${i.language}:${i.concept}`,a=r.get(e)??{language:i.language,concept:i.concept,occurrences:0,nodeIds:new Set,studiedNodeIds:new Set,understoodNodeIds:new Set};a.occurrences+=1,a.nodeIds.add(i.node_id),t.has(i.node_id)&&a.studiedNodeIds.add(i.node_id),n.get(i.node_id)?.understood&&a.understoodNodeIds.add(i.node_id),r.set(e,a)}return[...r.values()].map(e=>({language:e.language,concept:e.concept,occurrences:e.occurrences,nodes:e.nodeIds.size,studied_nodes:e.studiedNodeIds.size,understood_nodes:e.understoodNodeIds.size})).sort((e,t)=>e.language.localeCompare(t.language)||e.concept.localeCompare(t.concept))}function kG(e){let t={javascript:`JavaScript`,jsx:`JSX`,typescript:`TypeScript`};return t[e]?t[e]:e.split(`-`).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(` `)}function AG(e){return kG(e)}function jG(e){return e===`javascript`?`JS`:e===`typescript`?`TS`:AG(e)}function MG(e){return e===`python`?`nebPython`:e===`javascript`?`nebJs`:e===`typescript`?`nebTs`:null}var NG=2;function PG(e,{showAll:t=!1,selectionId:n=null}={}){let r=()=>new Set(e.regions.map(e=>e.id));if(t||!e.regions.some(e=>e.home))return r();let i=new Set,a=new Set;for(let t of e.regions)typeof t.hops_from_home==`number`&&t.hops_from_home<=NG&&i.add(t.id),t.understood&&a.add(t.id);n&&a.add(n);for(let e of a)i.add(e);for(let t of e.region_edges)(a.has(t.src)||a.has(t.dst))&&(i.add(t.src),i.add(t.dst));return i}function FG(e){let t=new Map;for(let n of e.nodes)t.has(n.region)||t.set(n.region,n.file);return t}function IG(e){return e.split(`/`).filter(Boolean).at(-1)??e}function LG(e){let t=FG(e);return e.regions.map(e=>({id:e.id,file:t.get(e.id)??e.id,label:IG(t.get(e.id)??e.id),language:e.language,community:e.community,understood:e.understood,home:e.home,hops:typeof e.hops_from_home==`number`?e.hops_from_home:null,centrality:e.centrality,loc:e.loc})).sort((e,t)=>e.label.localeCompare(t.label)||e.id.localeCompare(t.id))}function RG(e){if(!e.length)return``;let t=e.map(e=>e.file.split(`/`).slice(0,-1)),n=t[0];for(let e of t.slice(1)){let t=0;for(;t{let n=RG(t),r=n.endsWith(`/`)?n:``;return{community:e,name:n,members:t.map(e=>({...e,display:r&&e.file.startsWith(r)?e.file.slice(r.length):e.file})).sort((e,t)=>e.display.localeCompare(t.display))}}).sort((e,t)=>t.members.length-e.members.length||e.community-t.community)}var BG=5,VG=2;function HG(e,t,n=null){let r=e=>n===null||n.has(e),i=FG(e);return{nodes:e.regions.map(n=>{let a=r(n.id);return{...n,kind:`region`,name:n.id,label:a?IG(i.get(n.id)??n.id):``,charted:a,fx:n.x,fy:n.y,fz:n.z,val:qG(n.loc,5,24),color:a?n.understood?t.star:e.nodes.some(e=>e.region===n.id&&e.partial)?t.routePossible:JG(n.centrality,t,BG):t.nodeDim,focusDim:!1}}),links:e.region_edges.filter(e=>r(e.src)&&r(e.dst)).map(e=>({...e,source:e.src,target:e.dst,color:e.certain?t.route:t.routePossible,focusDim:!1}))}}function UG(e,t,n,{selectedId:r=null}={}){let i=e.nodes.filter(e=>e.region===t),a=new Set(i.map(e=>e.id)),o=e.edges.filter(e=>e.kind===`call`&&!e.external&&a.has(e.src)&&a.has(e.dst)),s=new Set(r?[r]:[]);if(r)for(let e of o)e.src===r&&s.add(e.dst),e.dst===r&&s.add(e.src);return{nodes:i.map(e=>({...e,fx:e.system_x,fy:e.system_y,fz:e.system_z,val:qG(e.loc,2.8,11),color:e.understood?n.star:e.partial?n.routePossible:JG(e.centrality,n,VG),selected:e.id===r,focusDim:!!r&&!s.has(e.id)})),links:o.map(e=>({...e,source:e.src,target:e.dst,color:e.certain?n.route:n.routePossible,focusDim:!!r&&e.src!==r&&e.dst!==r}))}}function WG(e){return e.regions.find(e=>e.home)??e.regions[0]??null}function GG(e){let t=e.kind===`region`?`star system`:e.kind,n=e.partial?` · unchartable · syntax error`:``,r=e.home?` · Home`:``;return`${e.name} · ${t} · ${e.loc} LOC${r}${n}`}function KG(e){let t=e.kind===`import`?`import`:e.kind===`call`?`call`:`import route`,n=e.certain?`certain`:t===`call`?`possible call`:`possible import`,r=typeof e.weight==`number`?` · ${e.weight} ${e.weight===1?`import`:`imports`}`:``,i=typeof e.lineno==`number`?` · line ${e.lineno}`:``;return`${e.src} → ${e.dst} · ${t} · ${n}${r}${i}`}function qG(e,t,n){return Math.min(n,Math.max(t,Math.sqrt(Math.max(1,e))*1.15))}function JG(e,t,n){return e>=n?t.nodeBright:e>=1?t.node:t.nodeDim}function YG(e,t){if(t?.pointerType===`touch`||!Array.isArray(e?._pointers)||e._pointers.length===0)return!1;if(e._pointers.splice(0,e._pointers.length),e._pointerPositions&&typeof e._pointerPositions==`object`)for(let t of Object.keys(e._pointerPositions))delete e._pointerPositions[t];return!0}function XG(e,t){let n=e=>YG(t,e),r=e=>YG(t,e);return e.addEventListener(`pointerdown`,n,{capture:!0}),e.addEventListener(`lostpointercapture`,r,{capture:!0}),()=>{e.removeEventListener(`pointerdown`,n,{capture:!0}),e.removeEventListener(`lostpointercapture`,r,{capture:!0})}}var ZG=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.fragment`);function r(e,n,r){var i=null;if(r!==void 0&&(i=``+r),n.key!==void 0&&(i=``+n.key),`key`in n)for(var a in r={},n)a!==`key`&&(r[a]=n[a]);else r=n;return n=r.ref,{$$typeof:t,type:e,key:i,ref:n===void 0?null:n,props:r}}e.Fragment=n,e.jsx=r,e.jsxs=r})),$=o(((e,t)=>{t.exports=ZG()}))(),QG=420,$G=1.6,eK={GALAXY:{min:120,max:640},SYSTEM:{min:55,max:320},STUDY:{min:22,max:170}},tK=.16,nK=1.5,rK=110,iK=6;function aK({graph:e,level:t,region:n,selectedNode:r,hoverNodeId:i,pendingDawnRegionId:a,revealedRegionIds:o,mode:s,onHoverNode:c,onAdvance:l,onRetreat:u,onDawnConsumed:d}){let f=(0,_.useRef)(null),p=(0,_.useRef)(null),m=(0,_.useRef)(null),h=(0,_.useRef)(l),g=(0,_.useRef)(u),v=(0,_.useRef)(c),y=(0,_.useRef)(a),b=(0,_.useRef)(d),x=(0,_.useRef)(null),S=(0,_.useRef)({activeId:null,neighborIds:new Set}),C=(0,_.useRef)(null),w=(0,_.useRef)(null),T=(0,_.useRef)(null),[E,D]=(0,_.useState)(0),[O,k]=(0,_.useState)(``),A=(0,_.useMemo)(lK,[]),ee=(0,_.useMemo)(XW,[]),te=bG(e.file_hashes),ne=(0,_.useMemo)(()=>t===wG.GALAXY?HG(e,A,o):UG(e,n?.id,A,{selectedId:r?.id}),[e,t,A,n?.id,o,r?.id]);(0,_.useEffect)(()=>{h.current=l,g.current=u,v.current=c,y.current=a,b.current=d},[l,u,c,a,d]);function re(e){let{activeId:t,neighborIds:n}=S.current;return t?e.id===t?A.orbit:n.has(e.id)?e.color:A.faded:e.color}function ie(e){if(e.focusDim)return A.faded;let{activeId:t,neighborIds:n}=S.current,r=e.certain?A.route:A.routePossible;if(!t)return r;let i=sK(e.source),a=sK(e.target);return i===t||a===t?A.orbit:n.has(i)&&n.has(a)?r:A.faded}function j(e){if(e.focusDim)return .4;let{activeId:t}=S.current,n=Math.min(2.2,.45+(e.weight??1)*.25);if(!t)return n;let r=sK(e.source),i=sK(e.target);return r===t||i===t?n+.9:n}(0,_.useEffect)(()=>{let e=f.current;if(!e)return;let t=document.createElement(`canvas`);if(!t.getContext(`webgl2`)&&!t.getContext(`webgl`)){k(`Codemble needs WebGL to draw your galaxy. Enable WebGL and reload.`);return}try{let t=hG(A);C.current=t;let n=BW({controlType:`orbit`})(e).backgroundColor(A.ground).showNavInfo(!1).enableNavigationControls(!0).enableNodeDrag(!1).warmupTicks(0).cooldownTicks(0).nodeId(`id`).nodeLabel(GG).nodeVal(`val`).nodeColor(re).nodeRelSize($G).nodeResolution(8).nodeOpacity(.82).nodeThreeObject(e=>oK(e,A,t,T.current)).nodeThreeObjectExtend(!0).linkColor(ie).linkLabel(KG).linkOpacity(.32).linkWidth(j).linkCurvature(.12).linkVisibility(e=>!(s===`easy`&&e.focusDim)).linkHoverPrecision(4).linkDirectionalArrowRelPos(1).linkDirectionalArrowColor(ie).linkDirectionalParticles(e=>e.kind===`call`&&e.certain&&!e.focusDim&&!ee?2:0).linkDirectionalParticleSpeed(.006).linkDirectionalParticleWidth(1.1).linkDirectionalParticleColor(()=>A.orbit).onNodeHover(t=>{e.style.cursor=t?`pointer`:`default`,v.current(t?.id??null)}).onNodeClick(e=>h.current(e)),r=requestAnimationFrame(()=>{e.querySelector(`.scene-nav-info`)?.remove()}),i=n.controls();i.enablePan=!1,i.enableDamping=!ee,i.dampingFactor=.12,i.rotateSpeed=.55,i.zoomSpeed=.7,i.minPolarAngle=tK,i.maxPolarAngle=nK,m.current=i;let a=XG(e,i);w.current=JW(n),p.current=n;let o=new ResizeObserver(([e])=>{n.width(e.contentRect.width).height(e.contentRect.height)});return o.observe(e),()=>{o.disconnect(),cancelAnimationFrame(r),a(),n.pauseAnimation(),w.current?.dispose(),w.current=null,n._destructor(),t.dispose(),C.current=null,m.current=null,e.replaceChildren(),p.current=null}}catch(e){k(`The galaxy could not start: ${e.message}`);return}},[A]),(0,_.useEffect)(()=>{let e=p.current;if(!e)return;e.nodeResolution(ne.nodes.length>=900?4:8).linkVisibility(e=>!(s===`easy`&&e.focusDim)).linkDirectionalArrowLength(t===wG.GALAXY?0:3.2).graphData(ne);let n=eK[t]??eK.GALAXY;m.current&&(m.current.minDistance=n.min,m.current.maxDistance=n.max),t===wG.GALAXY?e.cameraPosition({x:0,y:105,z:310},{x:0,y:0,z:0},QG):e.cameraPosition({x:0,y:52,z:150},{x:0,y:0,z:0},QG),D(0)},[ne,t,s]),(0,_.useEffect)(()=>{T.current=ne.nodes[E]?.id??null,p.current?.refresh()},[ne.nodes,E]),(0,_.useEffect)(()=>{let e=p.current;if(!e)return;let t=e.scene(),n=t.getObjectByName(`codemble-starfield`);n&&(t.remove(n),n.geometry.dispose(),n.material.dispose());let r=CG(te,A);return t.add(r),()=>{t.remove(r),r.geometry.dispose(),r.material.dispose()}},[te,A]),(0,_.useEffect)(()=>{let e=p.current;if(!e||t!==wG.GALAXY)return;let n=y.current;if(!n||x.current===n)return;x.current=n,b.current?.(n);let r=!1,i=()=>{},a=t=>{if(r)return;let s=e.scene();if(s.getObjectByName(`codemble-system-${n}`)||t>=iK){i=ZW({scene:s,regionId:n,palette:A});return}o=requestAnimationFrame(()=>a(t+1))},o=requestAnimationFrame(()=>a(0));return()=>{r=!0,cancelAnimationFrame(o),i()}},[t,A]),(0,_.useEffect)(()=>{let e=i??(t===wG.STUDY?r?.id??null:null),n=new Set;if(e)for(let t of ne.links){let r=sK(t.source),i=sK(t.target);r===e&&n.add(i),i===e&&n.add(r)}S.current={activeId:e,neighborIds:n};let a=p.current;a&&a.nodeColor(a.nodeColor()).linkColor(a.linkColor()).linkWidth(a.linkWidth()).linkDirectionalArrowColor(a.linkDirectionalArrowColor())},[ne,i,t,r?.id]);let M=(0,_.useMemo)(()=>iG(ne.nodes),[ne.nodes]);(0,_.useEffect)(()=>{let e=p.current;if(!e)return;let n=e.scene();function r(){let r=e.camera(),a=m.current,o=eK[t]??eK.GALAXY,s=a?r.position.distanceTo(a.target):r.position.length();M.place({scene:n,camera:r,width:e.width(),height:e.height(),distance:s,distanceBounds:o,hoverNodeId:i})}let a=null;function o(){try{r()}catch(e){a!==null&&clearInterval(a),M.hide(n),console.error(`Codemble: label declutter failed, names disabled`,e)}}return o(),a=setInterval(o,rK),()=>{clearInterval(a),M.hide(n)}},[i,t,M]),(0,_.useEffect)(()=>{if(!new URLSearchParams(window.location.search).has(`benchmark`)||ne.nodes.length<900)return;document.documentElement.removeAttribute(`data-codemble-fps`);let e=setTimeout(()=>{let e=p.current;if(!e)return;let t=e.renderer(),n=e.postProcessingComposer(),r=performance.now();for(let e=0;e<60;e+=1)n.render();t.getContext().finish();let i=performance.now()-r;document.documentElement.dataset.codembleFps=(60*1e3/i).toFixed(1)},1e3);return()=>clearTimeout(e)},[ne.nodes.length]),(0,_.useEffect)(()=>{!r||!p.current||t!==wG.STUDY||p.current.cameraPosition({x:r.system_x+20,y:r.system_y+15,z:r.system_z+42},{x:r.system_x,y:r.system_y,z:r.system_z},QG)},[t,r]);let ae=ne.nodes[E]??null;function oe(e){e.key===`ArrowRight`||e.key===`ArrowDown`?(e.preventDefault(),D(e=>(e+1)%Math.max(1,ne.nodes.length))):e.key===`ArrowLeft`||e.key===`ArrowUp`?(e.preventDefault(),D(e=>(e-1+ne.nodes.length)%Math.max(1,ne.nodes.length))):e.key===`Enter`&&ae?(e.preventDefault(),h.current(ae)):(e.key===`Escape`||e.key===`Backspace`)&&(e.preventDefault(),g.current())}return O?(0,$.jsxs)(`section`,{className:`webgl-error`,role:`alert`,children:[(0,$.jsx)(`h1`,{children:`The sky could not open.`}),(0,$.jsx)(`p`,{children:O}),(0,$.jsxs)(`p`,{children:[`The `,s===`easy`?`Diagram`:`Map`,` layer works without WebGL — switch to it at the top of the window to explore the same code.`]})]}):(0,$.jsxs)(`div`,{className:`galaxy-frame`,role:`application`,tabIndex:`0`,"aria-label":`Codemble ${t.toLowerCase()} view. Drag to orbit, scroll to zoom. Use arrow keys to choose a node and Enter to move closer.`,onKeyDown:oe,children:[(0,$.jsx)(`div`,{ref:f,className:`galaxy-canvas`,"aria-hidden":`true`}),ae?(0,$.jsx)(`output`,{className:`keyboard-focus`,"aria-live":`polite`,children:GG(ae)}):null]})}function oK(e,t,n,r){let i=new lr;i.name=e.kind===`region`?`codemble-system-${e.id}`:`codemble-node-${e.id}`;let a=Math.cbrt(e.val??1)*$G,o=e.charted===!1;if(!e.focusDim&&!o&&i.add(n.halo(e,a)),e.kind===`region`&&!o){let r=MG(e.language);r&&i.add(n.nebula(t[r],a*14))}if(e.label){let t=n.label(e.label,a);t.userData.nodeId=e.id,i.add(t)}if(e.home){let e=new ia(new xo(a*1.7,Math.max(.18,a*.07),8,36),new Ki({color:t.home}));e.rotation.x=Math.PI/2.8,i.add(e)}if(e.selected){let e=new ia(new xo(a*2.1,Math.max(.16,a*.05),6,24),new Ki({color:t.orbit}));e.rotation.x=Math.PI/2.8,i.add(e)}return e.id===r&&i.add(n.reticle(a)),i}function sK(e){return typeof e==`object`&&e?e.id:e}function cK(e){let t=document.createElement(`canvas`).getContext(`2d`);t.fillStyle=`#000000`,t.fillStyle=e,t.fillRect(0,0,1,1);let[n,r,i]=t.getImageData(0,0,1,1).data;return`rgb(${n}, ${r}, ${i})`}function lK(){let e=getComputedStyle(document.documentElement),t=t=>cK(e.getPropertyValue(t).trim());return Object.freeze({ground:t(`--cm-ground`),home:t(`--cm-ink`),orbit:t(`--cm-orbit`),nodeBright:t(`--cm-ink-2`),node:t(`--cm-ink-3`),nodeDim:t(`--cm-node-unlit`),route:t(`--cm-hairline`),routePossible:t(`--cm-route-possible`),faded:t(`--cm-hairline-soft`),star:t(`--cm-star-high`),starHalo:t(`--cm-star-halo`),nebPython:t(`--cm-neb-python`),nebJs:t(`--cm-neb-js`),nebTs:t(`--cm-neb-ts`),labelPlate:e.getPropertyValue(`--cm-label-plate`).trim(),labelInk:e.getPropertyValue(`--cm-label-ink`).trim()})}function uK({hint:e,onStudy:t}){return e?(0,$.jsxs)(`output`,{className:`hint-chip`,"aria-live":`polite`,children:[(0,$.jsx)(`span`,{"aria-hidden":`true`,children:`→`}),(0,$.jsxs)(`span`,{children:[`Study `,(0,$.jsx)(`strong`,{children:e.regionId}),` next`]}),(0,$.jsx)(`small`,{children:e.reason}),(0,$.jsx)(`button`,{type:`button`,onClick:()=>t(e.regionId),children:`Take me there`})]}):null}var dK=[{title:`What you see`,body:`Every star system is one file, named once you have charted it. Size is how much code it holds; brightness is how many places in your project call it. Faint unnamed markers are modules you have not reached yet.`},{title:`How to move`,body:`Drag to look around and scroll to zoom — the view stays locked on whatever you are studying, so you cannot get lost. Click a system to go in, Escape to come back, and press ⌘K to jump straight to any module by name.`},{title:`What lights stars`,body:`A system lights up only after you answer questions drawn from your own code. Nothing lights up just by looking at it — and each one you light reveals the modules it connects to.`}],fK=[{title:`What you see`,body:`Every box is one file, placed by how your imports connect them. A dashed link is a relationship the parser could not fully prove.`},{title:`How to move`,body:`Click a box to study that module, or press ⌘K to jump to one by name. The tabs above show how it fits together and what runs first. Switch to the Galaxy anytime to fly through the same code.`},{title:`What lights up`,body:`A module lights up only after you answer questions drawn from your own code. Nothing lights up just by looking at it.`}];function pK({layer:e,onDismiss:t}){let[n,r]=(0,_.useState)(0),i=(0,_.useRef)(null),a=e===`map`?fK:dK,o=a[n];(0,_.useLayoutEffect)(()=>{let e=i.current;e&&!e.open&&e.showModal()},[]);function s(){i.current?.close(),t()}return(0,$.jsxs)(`dialog`,{ref:i,className:`coach-marks`,"aria-labelledby":`coach-heading`,onCancel:e=>{e.preventDefault(),s()},children:[(0,$.jsxs)(`p`,{className:`coach-marks__progress`,children:[`Step `,n+1,` of `,a.length]}),(0,$.jsx)(`h1`,{id:`coach-heading`,children:o.title}),(0,$.jsx)(`p`,{children:o.body}),(0,$.jsxs)(`div`,{className:`coach-marks__actions`,children:[(0,$.jsx)(`button`,{type:`button`,className:`coach-skip`,onClick:s,children:`Skip`}),(0,$.jsx)(`button`,{type:`button`,className:`check-primary`,onClick:()=>n+1{let n=i.current?.getBoundingClientRect();!n||!e||!t||o(_K(Math.min(n.width/e,n.height/t)))},[e,t]);(0,_.useEffect)(()=>{let n=i.current;if(!n||typeof ResizeObserver>`u`)return;u.current=!1;let r=0,a=()=>{if(u.current)return;let i=n.getBoundingClientRect();i.width>480||i.width<=0||i.height<=0||(cancelAnimationFrame(r),r=requestAnimationFrame(()=>{let r=n.getBoundingClientRect();r.width>480||r.width<=0||r.height<=0||(o(_K(Math.min(r.width/e,r.height/t))),u.current=!0)}))},s=new ResizeObserver(a);return s.observe(n),a(),()=>{cancelAnimationFrame(r),s.disconnect()}},[e,t]);function f(e){if(e.button!==0||e.target.closest(`[role='button']`))return;let t=i.current;l.current={x:e.clientX,y:e.clientY,left:t.scrollLeft,top:t.scrollTop},c(!0),t.setPointerCapture(e.pointerId)}function p(e){if(!l.current)return;let t=i.current;t.scrollLeft=l.current.left-(e.clientX-l.current.x),t.scrollTop=l.current.top-(e.clientY-l.current.y)}function m(e){l.current&&(l.current=null,c(!1),i.current?.releasePointerCapture?.(e.pointerId))}return(0,$.jsxs)(`div`,{className:`map-canvas`,children:[(0,$.jsxs)(`div`,{className:`map-zoom`,role:`group`,"aria-label":`Zoom ${n}`,children:[(0,$.jsx)(`button`,{type:`button`,"aria-label":`Zoom out`,disabled:a<=mK,onClick:()=>o(e=>_K(e/gK)),children:`−`}),(0,$.jsx)(`button`,{type:`button`,onClick:d,children:`Fit`}),(0,$.jsxs)(`button`,{type:`button`,onClick:()=>o(1),children:[Math.round(a*100),`%`]}),(0,$.jsx)(`button`,{type:`button`,"aria-label":`Zoom in`,disabled:a>=hK,onClick:()=>o(e=>_K(e*gK)),children:`+`})]}),(0,$.jsx)(`div`,{ref:i,className:`map-scroll`,"data-panning":s||void 0,onPointerDown:f,onPointerMove:p,onPointerUp:m,onPointerCancel:m,children:(0,$.jsx)(`div`,{className:`map-canvas__sized`,style:{width:e*a,height:t*a},children:r})})]})}var yK={nebPython:`var(--cm-neb-python)`,nebJs:`var(--cm-neb-js)`,nebTs:`var(--cm-neb-ts)`};function bK(e){let t=MG(e);return t?yK[t]:`var(--cm-hairline)`}function xK(e){return e.map(([e,t],n)=>`${n===0?`M`:`L`} ${e} ${t}`).join(` `)}function SK(e){return 1+Math.min(2.5,(Math.max(1,e)-1)*.5)}var CK=13,wK=.62,TK=14,EK=6;function DK(e,t){let n=t-TK-EK,r=Math.max(1,Math.floor(n/(CK*wK)));return e.length<=r?e:`${e.slice(0,Math.max(1,r-1))}…`}function OK({data:e,mapTab:t,mode:n,selectedRegionId:r,hasEntrypointCandidates:i,error:a,onSelectTab:o,onSelectRegion:s,onSelectNode:c,onRetry:l,children:u}){return(0,$.jsxs)(`section`,{className:`map-view`,"aria-label":`Two-dimensional project map`,children:[(0,$.jsxs)(`nav`,{className:`map-tabs`,"aria-label":`Map view`,children:[(0,$.jsx)(`button`,{type:`button`,"aria-pressed":t===`architecture`,onClick:()=>o(`architecture`),children:n===`easy`?`How it fits together`:`Architecture`}),(0,$.jsx)(`button`,{type:`button`,"aria-pressed":t===`workflow`,onClick:()=>o(`workflow`),children:n===`easy`?`What runs first`:`Workflow`})]}),u,a?(0,$.jsxs)(`div`,{className:`map-state`,role:`alert`,children:[(0,$.jsx)(`h2`,{children:`The map did not load.`}),(0,$.jsxs)(`p`,{children:[a,` The galaxy layer is unaffected.`]}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:l,children:`Try again`})]}):e?t===`architecture`?(0,$.jsx)(kK,{architecture:e.architecture,mode:n,selectedRegionId:r,hasEntrypointCandidates:i,onSelectRegion:s}):(0,$.jsx)(AK,{workflow:e.workflow,mode:n,selectedRegionId:r,hasEntrypointCandidates:i,onSelectNode:c}):(0,$.jsx)(`p`,{className:`map-loading`,role:`status`,children:`Laying out parser evidence…`})]})}function kK({architecture:e,mode:t,selectedRegionId:n,hasEntrypointCandidates:r,onSelectRegion:i}){let a=new Map(e.boxes.map(e=>[e.id,e]));return(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(vK,{contentWidth:e.width+64,contentHeight:e.height+64,label:`the architecture map`,children:(0,$.jsxs)(`svg`,{className:`architecture-map`,width:`100%`,height:`100%`,preserveAspectRatio:`xMidYMin meet`,viewBox:`-32 -32 ${e.width+64} ${e.height+64}`,role:`group`,"aria-label":e.home?`${e.boxes.length} modules in ${e.layer_count} import layers from Home`:`${e.boxes.length} modules in ${e.layer_count} import layers, measured from the modules nothing imports`,children:[(0,$.jsxs)(`defs`,{children:[(0,$.jsx)(`marker`,{id:`architecture-arrow`,className:`architecture-map__arrow`,markerWidth:`8`,markerHeight:`8`,refX:`8`,refY:`4`,orient:`auto`,markerUnits:`strokeWidth`,children:(0,$.jsx)(`path`,{d:`M 0 0 L 8 4 L 0 8 Z`,fill:`currentColor`})}),(0,$.jsx)(`marker`,{id:`architecture-cycle-arrow`,className:`architecture-map__arrow is-cycle`,markerWidth:`8`,markerHeight:`8`,refX:`8`,refY:`4`,orient:`auto`,markerUnits:`strokeWidth`,children:(0,$.jsx)(`path`,{d:`M 0 0 L 8 4 L 0 8 Z`,fill:`currentColor`})})]}),(0,$.jsx)(`g`,{className:`architecture-map__edges`,children:e.edges.map(e=>{let t=a.get(e.src),n=a.get(e.dst);return!t||!n?null:(0,$.jsx)(`path`,{d:xK(e.points),strokeDasharray:e.certain?void 0:`5 4`,strokeWidth:SK(e.weight),markerEnd:`url(#${e.cycle?`architecture-cycle-arrow`:`architecture-arrow`})`,className:`architecture-map__edge${e.cycle?` is-cycle`:``}`},`${e.src}->${e.dst}`)})}),e.boxes.map(e=>(0,$.jsxs)(`g`,{className:`architecture-map__box`,"data-understood":e.understood,"data-home":e.home,"data-reachable":e.reachable,"data-partial":e.partial,"data-selected":e.id===n,transform:`translate(${e.x} ${e.y})`,role:`button`,tabIndex:0,"aria-label":`${e.label}, ${e.node_count} structures, ${e.loc} lines${e.understood?`, understood`:`, not yet understood`}${e.home?`, Home`:``}${e.reachable?``:`, no import route from Home`}${e.partial?`, unchartable, syntax error`:``}`,onClick:()=>i(e.id),onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),i(e.id))},children:[(0,$.jsxs)(`title`,{children:[e.label,e.partial?` — unchartable, syntax error`:``]}),(0,$.jsx)(`rect`,{width:e.width,height:e.height,rx:`3`}),(0,$.jsx)(`rect`,{className:`box-tint`,width:`4`,height:e.height,fill:bK(e.language)}),e.partial?(0,$.jsx)(`path`,{className:`box-partial`,d:`M ${e.width-16} 2 L ${e.width-2} 2 L ${e.width-2} 16 Z`}):null,(0,$.jsx)(`text`,{x:TK,y:`24`,children:DK(e.short_label??e.label,e.width)}),(0,$.jsx)(`text`,{className:`box-meta`,x:`14`,y:`42`,children:t===`easy`?`${e.node_count} ${e.node_count===1?`piece`:`pieces`}`:`${e.node_count} nodes · ${e.loc} LOC`})]},e.id))]})}),e.home?null:(0,$.jsxs)(`p`,{className:`map-note`,children:[`No Home is selected, so these layers run from the modules nothing else imports rather than from your entrypoint. Both are read from your imports, not guessed.`,` `,r?`Pick your starting point with “Change Home” to see the same modules layered by what the project runs first.`:`This project has no parser-recognisable entrypoint, so there is no “runs first” order to layer by instead.`]}),e.unreachable.length?(0,$.jsxs)(`p`,{className:`map-note`,children:[e.unreachable.length,` `,e.unreachable.length===1?`module has`:`modules have`,` no import route from Home, so `,e.unreachable.length===1?`it sits`:`they sit`,` `,`in the bottom row rather than being placed by guesswork.`]}):null]})}function AK({workflow:e,mode:t,selectedRegionId:n,hasEntrypointCandidates:r,onSelectNode:i}){if(!e.root)return r?(0,$.jsxs)(`div`,{className:`map-state`,children:[(0,$.jsx)(`h2`,{children:`No Home is selected.`}),(0,$.jsx)(`p`,{children:`The workflow tree starts at your entrypoint. Pick Home and this tab will show what runs first, then what that calls.`})]}):(0,$.jsxs)(`div`,{className:`map-state`,children:[(0,$.jsx)(`h2`,{children:`No “runs first” order to show.`}),(0,$.jsx)(`p`,{children:`This project has no parser-recognisable entrypoint — nothing here declares a startup structure Codemble recognises, and it will not guess one. The other tab still maps how your modules import each other.`})]});let a=new Map(e.nodes.map(e=>[e.order,e]));return(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(vK,{contentWidth:e.width+32,contentHeight:e.height+32,label:`the workflow tree`,children:(0,$.jsxs)(`svg`,{className:`workflow-tree`,width:`100%`,height:`100%`,preserveAspectRatio:`xMinYMin meet`,viewBox:`-16 -16 ${e.width+32} ${e.height+32}`,role:`group`,"aria-label":`Call tree from ${e.root}, ${e.nodes.length} steps deep to ${e.depth_count} levels`,children:[(0,$.jsx)(`g`,{className:`workflow-tree__edges`,children:e.nodes.map(e=>{if(e.parent===null)return null;let t=[...a.values()].filter(t=>t.id===e.parent&&t.order(0,$.jsxs)(`g`,{className:`workflow-tree__row`,"data-understood":e.understood,"data-cut":e.cut??void 0,"data-partial":e.partial,"data-relation":e.relation,"data-selected":e.region===n,transform:`translate(${e.x} ${e.y})`,role:`button`,tabIndex:0,"aria-label":`${e.label} at ${e.file}:${e.lineno}${e.certain?``:`, possible call`}${e.cut===`cycle`?`, repeats an earlier step`:``}${e.cut===`repeat`?`, already shown above`:``}${e.partial?`, unchartable, syntax error`:``}`,onClick:()=>i(e.id),onKeyDown:t=>{(t.key===`Enter`||t.key===` `)&&(t.preventDefault(),i(e.id))},children:[(0,$.jsx)(`circle`,{cx:`8`,cy:`16`,r:`4`}),(0,$.jsx)(`text`,{x:`20`,y:`20`,children:e.label}),(0,$.jsxs)(`text`,{className:`row-meta`,x:`20`,y:`20`,dx:`${e.label.length*.62}em`,children:[e.relation===`defines`?t===`easy`?` — lives here`:` — defined in this module`:e.certain?``:` — possible call`,e.cut===`cycle`?` — loops back`:``,e.cut===`repeat`?` — shown above`:``,e.partial?t===`easy`?` — could not be read`:` — unchartable`:``]})]},e.order))]})}),e.unreachable.length?(0,$.jsxs)(`p`,{className:`map-note`,children:[e.unreachable.length,` `,e.unreachable.length===1?`structure is`:`structures are`,` never reached from Home by a parser-proven call. They are listed as unreached rather than attached to the tree by guesswork.`]}):null]})}var jK=m(),MK=[{mode:`easy`,label:`New to coding?`},{mode:`expert`,label:`I build software`}],NK=[{mode:`easy`,label:`Easy`},{mode:`expert`,label:`Expert`}];function PK({mode:e,modeChosen:t,onChoose:n}){let r=(0,_.useRef)(null),i=(0,_.useRef)(null),a=(0,_.useRef)(t);(0,_.useLayoutEffect)(()=>{let e=r.current;e&&t===!1&&!e.open&&e.showModal()},[t]),(0,_.useEffect)(()=>{t===!0&&a.current===!1&&i.current?.focus(),a.current=t},[t]);function o(e){r.current?.close(),n(e)}return t===null?null:t?(0,$.jsxs)(`fieldset`,{className:`mode-toggle`,children:[(0,$.jsx)(`legend`,{className:`mode-toggle__label`,children:`Audience`}),(0,$.jsx)(`div`,{className:`mode-toggle__options`,children:NK.map(t=>(0,$.jsxs)(`label`,{children:[(0,$.jsx)(`input`,{type:`radio`,name:`audience-mode`,value:t.mode,checked:e===t.mode,ref:e===t.mode?i:void 0,onChange:()=>o(t.mode)}),(0,$.jsx)(`span`,{children:t.label})]},t.mode))})]}):(0,jK.createPortal)((0,$.jsxs)(`dialog`,{ref:r,className:`mode-gate`,"aria-labelledby":`mode-gate-heading`,"aria-describedby":`mode-gate-detail`,onCancel:e=>e.preventDefault(),children:[(0,$.jsx)(`h1`,{id:`mode-gate-heading`,children:`New to coding, or do you build software already?`}),(0,$.jsx)(`p`,{id:`mode-gate-detail`,children:`This changes how much Codemble explains and how much it assumes you already know.`}),(0,$.jsx)(`div`,{className:`mode-gate__options`,children:MK.map(e=>(0,$.jsx)(`button`,{type:`button`,onClick:()=>o(e.mode),children:e.label},e.mode))})]}),document.body)}function FK({node:e,study:t,error:n,mode:r,explanation:i,explanationLoading:a,explanationError:o,llmStatus:s,onSelectNode:c,onRetryNarration:l}){return(0,$.jsxs)(`aside`,{className:`study-preview`,"aria-label":`Selected source structure`,"aria-busy":!t&&!n,children:[(0,$.jsxs)(`header`,{className:`study-preview__header`,children:[(0,$.jsxs)(`p`,{className:`study-preview__path`,children:[e.file,`:`,e.lineno]}),(0,$.jsx)(`h1`,{children:e.name}),(0,$.jsxs)(`dl`,{children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Kind`}),(0,$.jsx)(`dd`,{children:e.kind})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Span`}),(0,$.jsxs)(`dd`,{children:[e.loc,` lines`]})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:r===`easy`?`Used by`:`Callers`}),(0,$.jsx)(`dd`,{children:e.centrality})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Resolution`}),(0,$.jsx)(`dd`,{children:e.partial?`Partial parse`:`Parser-proven`})]})]})]}),n?(0,$.jsxs)(`section`,{className:`study-notice`,role:`alert`,children:[(0,$.jsx)(`h2`,{children:`Study data did not load.`}),(0,$.jsxs)(`p`,{children:[n,` The parser map is still available.`]}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:()=>c(e.id),children:`Try again`})]}):null,!t&&!n?(0,$.jsx)(`p`,{className:`study-loading`,role:`status`,children:`Reading parser evidence…`}):null,t?(0,$.jsxs)(`div`,{className:`study-content`,children:[(0,$.jsx)(IK,{structural:t.structural,mode:r}),(0,$.jsx)(GK,{explanation:i,loading:a,error:o,llmStatus:s,mode:r,node:e,onSelectNode:c,onRetry:l}),(0,$.jsx)(RK,{neighbors:t.neighbors,node:e,mode:r,onSelectNode:c}),(0,$.jsx)(WK,{source:t.source}),(0,$.jsx)(UK,{lens:t.lens,language:e.language,mode:r})]}):null]})}function IK({structural:e,mode:t}){return e?(0,$.jsxs)(`section`,{className:`structural-summary`,"aria-labelledby":`structural-heading`,children:[(0,$.jsxs)(`div`,{className:`study-section-heading`,children:[(0,$.jsx)(`h2`,{id:`structural-heading`,children:t===`easy`?`What this is`:`Structural summary`}),(0,$.jsx)(`span`,{children:`No model needed`})]}),(0,$.jsx)(`p`,{children:e[t]??e.easy})]}):null}var LK=8;function RK({neighbors:e,node:t,mode:n,onSelectNode:r}){let i=e??[],a=i.filter(e=>e.direction===`inbound`),o=i.filter(e=>e.direction===`outbound`);return(0,$.jsxs)(`section`,{className:`connections`,"aria-labelledby":`connections-heading`,children:[(0,$.jsxs)(`div`,{className:`study-section-heading`,children:[(0,$.jsx)(`h2`,{id:`connections-heading`,children:n===`easy`?`What this connects to`:`Parser connections`}),(0,$.jsxs)(`span`,{children:[i.length,` parser `,i.length===1?`relationship`:`relationships`]})]}),i.length===0?(0,$.jsx)(`p`,{className:`study-loading`,children:n===`easy`?`Nothing in your code reaches this yet, and it does not reach anything else.`:`The parser observed no relationship into or out of this structure.`}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(HK,{inbound:a,outbound:o,node:t}),(0,$.jsx)(zK,{title:n===`easy`?`Uses this`:`Inbound`,items:a,mode:n,onSelectNode:r}),(0,$.jsx)(zK,{title:n===`easy`?`This uses`:`Outbound`,items:o,mode:n,onSelectNode:r})]})]})}function zK({title:e,items:t,mode:n,onSelectNode:r}){return t.length?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`h3`,{children:e}),(0,$.jsx)(`ul`,{className:`connection-list`,children:t.map(e=>(0,$.jsx)(`li`,{children:(0,$.jsxs)(`button`,{type:`button`,onClick:()=>r(e.node_id),children:[(0,$.jsx)(`span`,{className:`connection-name`,children:e.name}),(0,$.jsxs)(`span`,{className:`connection-meta`,children:[BK(e,n),` · `,VK(e,n)]}),(0,$.jsx)(`span`,{className:`source-citation`,children:e.citation})]})},`${e.direction}-${e.node_id}`))})]}):null}function BK(e,t){return e.relationship===`import`?e.direction===`inbound`?t===`easy`?`brings this in`:`import · inbound`:t===`easy`?`this brings it in`:`import · outbound`:e.direction===`inbound`?t===`easy`?`calls this`:`call · inbound`:t===`easy`?`this calls it`:`call · outbound`}function VK(e,t){return e.certain?`certain`:e.relationship===`import`?t===`easy`?`possible link, not certain`:`possible import`:t===`easy`?`possible link, not certain`:`possible call`}function HK({inbound:e,outbound:t,node:n}){let r=e.slice(0,LK),i=t.slice(0,LK),a=Math.max(r.length,i.length,1)*22+16,o=a/2,s=(e,t)=>(e+1)*a/(t+1);return(0,$.jsxs)(`svg`,{className:`mini-constellation`,viewBox:`0 0 280 ${a}`,role:`img`,"aria-label":`${e.length} inbound and ${t.length} outbound parser relationships for ${n.name}`,children:[r.map((e,t)=>(0,$.jsx)(`line`,{x1:`26`,y1:s(t,r.length),x2:`132`,y2:o,strokeDasharray:e.certain?void 0:`3 3`},`in-line-${e.node_id}`)),i.map((e,t)=>(0,$.jsx)(`line`,{x1:`148`,y1:o,x2:`254`,y2:s(t,i.length),strokeDasharray:e.certain?void 0:`3 3`},`out-line-${e.node_id}`)),r.map((e,t)=>(0,$.jsx)(`circle`,{cx:`22`,cy:s(t,r.length),r:`4`},`in-dot-${e.node_id}`)),i.map((e,t)=>(0,$.jsx)(`circle`,{cx:`258`,cy:s(t,i.length),r:`4`},`out-dot-${e.node_id}`)),(0,$.jsx)(`circle`,{className:`mini-constellation__self`,cx:`140`,cy:o,r:`6`})]})}function UK({lens:e,language:t,mode:n}){return e?.length?(0,$.jsxs)(`section`,{className:`lens-study`,"aria-labelledby":`lens-heading`,children:[(0,$.jsxs)(`div`,{className:`study-section-heading`,children:[(0,$.jsxs)(`h2`,{id:`lens-heading`,children:[kG(t),` lens`]}),(0,$.jsxs)(`span`,{children:[e.length,` detected`]})]}),(0,$.jsx)(`div`,{className:`lens-notes`,children:e.map(e=>(0,$.jsxs)(`article`,{className:`lens-note`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`h3`,{children:e.title}),(0,$.jsx)(qK,{citation:e.citation,fallbackLine:e.line})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`p`,{children:e.note_voices[n]}),(0,$.jsx)(`code`,{children:e.snippet})]})]},`${e.concept}-${e.line}-${e.snippet}`))})]}):null}function WK({source:e}){return(0,$.jsxs)(`section`,{className:`source-study`,"aria-labelledby":`source-heading`,children:[(0,$.jsxs)(`div`,{className:`study-section-heading`,children:[(0,$.jsx)(`h2`,{id:`source-heading`,children:`Real source`}),(0,$.jsxs)(`span`,{children:[e.file,`:`,e.start_line,`–`,e.end_line]})]}),(0,$.jsx)(`ol`,{className:`source-code`,start:e.start_line,"aria-label":`Source excerpt from ${e.file}`,children:e.lines.map(e=>(0,$.jsx)(`li`,{id:`source-L${e.number}`,"data-line":e.number,children:(0,$.jsx)(`code`,{children:e.text||` `})},e.number))})]})}function GK({explanation:e,loading:t,error:n,llmStatus:r,mode:i,node:a,onSelectNode:o,onRetry:s}){return t?(0,$.jsx)(`p`,{className:`study-loading`,role:`status`,children:i===`easy`?`Asking your model to explain this in plain language…`:`Requesting a grounded narration for this structure…`}):n?(0,$.jsxs)(`section`,{className:`study-notice`,role:`alert`,"aria-labelledby":`explanation-heading`,children:[(0,$.jsx)(`h2`,{id:`explanation-heading`,children:`The explanation request failed.`}),(0,$.jsx)(`p`,{children:n}),(0,$.jsx)(`p`,{children:`Every fact above and below this block came from the parser and is unaffected.`}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:s,children:`Try again`})]}):e?e.status===`no_key`?(0,$.jsx)(KK,{message:e.message,llmStatus:r,mode:i}):e.status===`error`?(0,$.jsxs)(`section`,{className:`study-notice`,role:`alert`,"aria-labelledby":`explanation-heading`,children:[(0,$.jsx)(`h2`,{id:`explanation-heading`,children:`The explanation was withheld.`}),(0,$.jsx)(`p`,{children:e.message}),(0,$.jsx)(`p`,{children:`Codemble will not display provider output that falls outside parser evidence.`}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:s,children:`Try again`})]}):e.status===`partial`?(0,$.jsxs)(`section`,{className:`study-notice`,"aria-labelledby":`explanation-heading`,children:[(0,$.jsx)(`h2`,{id:`explanation-heading`,children:`Narration stays off for partial source.`}),(0,$.jsx)(`p`,{children:e.message})]}):(0,$.jsxs)(`section`,{className:`grounded-explanation`,"aria-labelledby":`explanation-heading`,children:[(0,$.jsxs)(`div`,{className:`study-section-heading`,role:`status`,children:[(0,$.jsx)(`h2`,{id:`explanation-heading`,children:i===`easy`?`In plain language`:`Grounded explanation`}),(0,$.jsx)(`span`,{children:e.cached?`Local cache`:e.provider})]}),(0,$.jsxs)(`p`,{children:[e.summary.text,` `,(0,$.jsx)(qK,{citation:e.summary.citation,fallbackLine:a.lineno})]}),(0,$.jsx)(`h3`,{children:i===`easy`?`Line by line`:`Walkthrough`}),(0,$.jsx)(`ul`,{className:`evidence-list`,children:e.walkthrough.map(e=>(0,$.jsxs)(`li`,{children:[(0,$.jsx)(`p`,{children:e.text}),(0,$.jsx)(qK,{citation:e.citation,fallbackLine:e.line})]},`${e.citation}-${e.text}`))}),e.relationships.length?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`h3`,{children:i===`easy`?`How it fits in`:`Parser relationships`}),(0,$.jsx)(`ul`,{className:`evidence-list`,children:e.relationships.map(e=>(0,$.jsxs)(`li`,{children:[(0,$.jsx)(`strong`,{children:e.certain?e.node_id:`Possible: ${e.node_id}`}),(0,$.jsx)(`p`,{children:e.text}),(0,$.jsxs)(`button`,{className:`source-citation source-citation--button`,type:`button`,onClick:()=>o(e.node_id),children:[`Study `,e.citation]})]},`${e.node_id}-${e.text}`))})]}):null]}):null}function KK({message:e,llmStatus:t,mode:n}){let r=t?.ollama??null;return(0,$.jsxs)(`section`,{className:`study-notice`,"aria-labelledby":`explanation-heading`,children:[(0,$.jsx)(`h2`,{id:`explanation-heading`,children:n===`easy`?`The plain-language write-up needs a model.`:`No narration provider is configured.`}),(0,$.jsx)(`p`,{children:e}),r?(0,$.jsx)(`p`,{children:r.running?`Ollama is already running on this machine. Set CODEMBLE_PROVIDER=ollama and CODEMBLE_OLLAMA_MODEL=${r.recommended}, then restart Codemble to narrate without sending code anywhere.`:`Want to stay fully local? Install Ollama, run "ollama pull ${r.recommended}" (or ${r.fallback} on a smaller machine), set CODEMBLE_PROVIDER=ollama, then restart Codemble.`}):null,(0,$.jsx)(`p`,{children:`Everything else on this panel is parser evidence and works without any model at all.`})]})}function qK({citation:e,fallbackLine:t}){return(0,$.jsx)(`a`,{className:`source-citation`,href:`#source-L${Number(e.split(`:`).at(-1))||t}`,children:e})}var JK=Object.freeze([]),YK=new Set;function XK(){let e=new WeakMap,t=new WeakMap,n=new WeakMap,r=new WeakMap,i=new WeakMap,a=new WeakMap,o=null,s=null,c=null,l=null;function u(e){let t=e.graph,n=t?d(t,e.languageFocus):null,r=n?p(n):null,i=e.level,a=r?.regionById.get(e.region?.id)??null,o=e.selectedNode;n&&(a?o&&(o=r.nodeById.get(o.id)??null,!o&&i===wG.STUDY&&(i=wG.SYSTEM)):(a=WG(n),o=null,i=wG.GALAXY));let s=e.studiedNodeIds;return{...e,focusedGraph:n,focusedMapData:f(e.mapData,e.languageFocus),entrypointOpen:!!t&&!e.entrypointDismissed,level:i,region:a,selectedNode:o,languageOptions:t?m(t):JK,projectName:t?g(t):`Loading local project`,chart:n?_(n,s):JK,focusedStudiedCount:n?v(n,s):0,hint:n?y(n,e.mode):null,revealedRegionIds:n?b(n,e.showAll,a?.id??null):YK,moduleIndex:n?h(n):JK}}function d(t,n){let r=e.get(t);r||(r=new Map,e.set(t,r));let i=n||`all`;return r.has(i)||r.set(i,TG(t,n)),r.get(i)}function f(e,n){if(!e)return e;let r=t.get(e);r||(r=new Map,t.set(e,r));let i=n||`all`;return r.has(i)||r.set(i,EG(e,n)),r.get(i)}function p(e){return n.has(e)||n.set(e,{nodeById:new Map(e.nodes.map(e=>[e.id,e])),regionById:new Map(e.regions.map(e=>[e.id,e]))}),n.get(e)}function m(e){return r.has(e)||r.set(e,DG(e)),r.get(e)}function h(e){return i.has(e)||i.set(e,LG(e)),i.get(e)}function g(e){return a.has(e)||a.set(e,e.project_root.split(`/`).filter(Boolean).at(-1)??e.project_root),a.get(e)}function _(e,t){return(!o||o.graph!==e||o.studiedNodeIds!==t)&&(o={graph:e,studiedNodeIds:t,value:OG(e,t)}),o.value}function v(e,t){return(!s||s.graph!==e||s.studiedNodeIds!==t)&&(s={graph:e,studiedNodeIds:t,value:e.nodes.filter(e=>t.has(e.id)).length}),s.value}function y(e,t){return(!c||c.graph!==e||c.mode!==t)&&(c={graph:e,mode:t,value:ZK(e,t)}),c.value}function b(e,t,n){return(!l||l.graph!==e||l.showAll!==t||l.selectionId!==n)&&(l={graph:e,showAll:t,selectionId:n,value:PG(e,{showAll:t,selectionId:n})}),l.value}return Object.freeze({derive:u})}function ZK(e,t){if(t!==`easy`)return null;let n=e.regions.filter(e=>!e.understood);if(!n.length)return null;let r=n.map(e=>({regionId:e.id,hops:typeof e.hops_from_home==`number`?e.hops_from_home:1/0})).sort((e,t)=>e.hops-t.hops||e.regionId.localeCompare(t.regionId))[0];return{...r,reason:r.hops===0?`Home is not lit yet.`:Number.isFinite(r.hops)?`${r.hops} ${r.hops===1?`route`:`routes`} from Home.`:`No import route reaches it from Home.`}}var QK=Object.freeze({setTimeout(e,t){return globalThis.setTimeout(e,t)},clearTimeout(e){globalThis.clearTimeout(e)}}),$K=300,eq=400,tq=4e3,nq=8,rq=Object.freeze([Object.freeze({id:`discovering`,copy:`Finding your source files`}),Object.freeze({id:`parsing`,copy:`Reading each file`}),Object.freeze({id:`resolving`,copy:`Connecting imports and calls`}),Object.freeze({id:`checks`,copy:`Building graph-only checks`}),Object.freeze({id:`layout`,copy:`Placing your galaxy`})]);function iq({adapter:e,clock:t=QK,onReady:n=async()=>{}}={}){if(!e)throw TypeError(`Project mapping requires a learner adapter.`);let r=new Set,i=aq({phase:`idle`,error:``,picker:null,progress:null,failure:null}),a=0,o=null,s=null,c=null,l=null;function u(){return i}function d(e){return r.add(e),()=>r.delete(e)}function f(e){i=aq({...i,...e});for(let e of r)e()}async function p(){a+=1;let t=a;b(),oq(o),o=new AbortController;let n=o;f({phase:`idle`,error:``,picker:null,progress:null,failure:null});try{let[r,o]=await Promise.all([e.loadRecents({signal:n.signal}),e.browsePicker(null,{signal:n.signal})]);if(t!==a||n.signal.aborted)return i;f({phase:`picking`,picker:{...o,recents:r.recents,error:``,scale:null,busy:!1}})}catch(e){!sq(e)&&t===a&&f({phase:`error`,error:lq(e)})}return i}async function m(t){if(i.phase!==`picking`||i.picker?.busy)return;oq(o),o=new AbortController;let n=o,r=a;f({failure:null});try{let s=await e.browsePicker(t,{signal:n.signal});o===n&&r===a&&!n.signal.aborted&&i.phase===`picking`&&f({picker:{...i.picker,...s,error:``}})}catch(e){o===n&&r===a&&!sq(e)&&i.phase===`picking`&&f({picker:{...i.picker,error:lq(e)}})}}async function h(t){if(i.phase!==`picking`||i.picker?.busy)return;a+=1;let r=a;oq(o),b(),o=new AbortController;let s=o;f({failure:null,picker:{...i.picker,busy:!0,error:``,scale:null}});try{let o=await e.selectProject(t,{signal:s.signal});if(r!==a||s.signal.aborted||i.phase!==`picking`)return o;if(o.state===`parsing`)return f({progress:{state:`parsing`,stage:`discovering`,detail:null,files_done:0,files_total:0,error:null,pollError:``,attempts:0,pollOutage:!1,path:t}}),_(0,r),o;if(o.state===`ready`)return y(),await n(),o;if(o.state===`scale`){let t=await e.browsePicker(o.root,{signal:s.signal});return r===a&&!s.signal.aborted&&i.phase===`picking`&&f({picker:{...i.picker,...t,busy:!1,scale:o}}),o}let c=o.detail??``;return f({picker:{...i.picker,busy:!1,error:c},failure:c?{path:t,detail:c}:null}),o}catch(e){if(r===a&&!sq(e)&&i.phase===`picking`){let n=lq(e);f({picker:{...i.picker,busy:!1,error:n},failure:{path:t,detail:n}})}return}}async function g(){oq(c),c=new AbortController;let t=c;try{await e.resetProject({signal:t.signal})}catch(e){if(sq(e))return!1;if(cq(e))throw e}return t.signal.aborted?!1:(a+=1,oq(o),o=null,b(),f({phase:`idle`,error:``,picker:null,progress:null,failure:null}),!0)}function _(e,n){l!==null&&t.clearTimeout(l),l=t.setTimeout(async()=>{l=null,await v(n)},e)}async function v(t){if(!i.progress||t!==a)return;oq(s),s=new AbortController;let r=s,o=i.progress,c;try{c=await e.fetchParseProgress({signal:r.signal})}catch(e){if(s!==r||t!==a||sq(e)||!i.progress)return;let n=o.attempts+1;f({progress:{...o,pollError:lq(e),attempts:n,pollOutage:n>=nq}}),_(Math.min(tq,eq*2**(n-1)),t);return}if(!(s!==r||t!==a||!i.progress)){if(c.state===`ready`){y(),await n();return}if(c.state===`error`||c.state===`idle`){b();let e=c.error??``;f({progress:null,picker:{...i.picker,busy:!1,error:e},failure:e?{path:o.path,detail:e}:null});return}f({progress:{...o,...c,pollError:``,attempts:0,pollOutage:!1}}),_($K,t)}}function y(){a+=1,b(),f({phase:`idle`,error:``,picker:null,progress:null,failure:null})}function b(){oq(s),s=null,l!==null&&(t.clearTimeout(l),l=null)}function x(){a+=1;for(let e of[o,s,c])oq(e);o=null,c=null,b(),r.clear()}return Object.freeze({browse:m,dispose:x,getSnapshot:u,reset:g,select:h,start:p,subscribe:d})}function aq(e){return Object.freeze(e)}function oq(e){e&&!e.signal.aborted&&e.abort()}function sq(e){return e?.name===`AbortError`}function cq(e){return Number.isInteger(e?.status)}function lq(e){return e instanceof Error?e.message:String(e)}var uq=Object.freeze({setTimeout(e,t){return globalThis.setTimeout(e,t)},clearTimeout(e){globalThis.clearTimeout(e)}});function dq({adapter:e=fq(),clock:t=uq}={}){let n=new Set,r=XK(),i=r.derive({status:`idle`,error:``,graph:null,level:wG.GALAXY,region:null,selectedNode:null,studyData:null,studyError:``,explanation:null,explanationLoading:!1,explanationError:``,showChart:!1,studiedNodeIds:new Set,showChecks:!1,checkData:null,checkError:``,entrypointDismissed:!1,entrypointError:``,litRegionId:null,pendingDawnRegionId:null,languageFocus:`all`,picker:null,parseProgress:null,projectFailure:null,layer:`galaxy`,layerChosen:!1,mapTab:`architecture`,mapData:null,mapError:``,coachmarksSeen:hq(),llmStatus:null,hoverNodeId:null,showAll:vq(),finderOpen:!1,sidebarOpen:!1,legendOpen:!1,mode:`easy`,modeChosen:null}),a=0,o=0,s=null,c=null,l=null,u=null,d=null,f=null,p=null,m=null,h=null;function g(){return i}function _(e){return n.add(e),()=>n.delete(e)}function v(e,{preserveChecks:t=!1}={}){let a=i,o=r.derive({...a,...e});if(o.level!==a.level||o.region?.id!==a.region?.id){let e={hoverNodeId:null};t||(bq(u),bq(d),u=null,d=null,e.showChecks=!1,e.checkData=null,e.checkError=``),o=r.derive({...o,...e})}i=Object.freeze(o);for(let e of n)e()}let y=iq({adapter:e,clock:t,async onReady(){a+=1;let e=a;return bq(s),s=new AbortController,S(s,e)}}),b=y.subscribe(()=>{let e=y.getSnapshot(),t={picker:e.picker,parseProgress:e.progress,projectFailure:e.failure};e.phase===`picking`&&(t.status=`picking`),e.phase===`error`&&(t.status=`error`,t.error=e.error),v(t)});async function x(){a+=1;let t=a;bq(s),s=new AbortController;let n=s;v({status:`loading`,error:``});let r;try{r=await e.loadPickerState({signal:n.signal})}catch(e){return!xq(e)&&t===a&&v({status:`error`,error:wq(e)}),i}return t!==a||n.signal.aborted?i:r.state===`unpicked`?(await y.start(),i):S(n,t)}async function S(t,n){v({status:`loading`,error:``,picker:null});try{let r=await e.loadGraph({signal:t.signal});if(n!==a||t.signal.aborted)return i;v({status:`ready`,graph:r,region:WG(r),error:``,entrypointDismissed:!!r.selected_entrypoint})}catch(e){!xq(e)&&n===a&&v({status:`error`,error:wq(e)})}return await C(t,n),i}async function C(t,n){let r=o,[s,c]=await Promise.allSettled([(async()=>e.loadMode({signal:t.signal}))(),(async()=>e.fetchLlmStatus({signal:t.signal}))()]);if(!(n!==a||t.signal.aborted)){if(r===o){let e=s.status===`fulfilled`?s.value:null;e?.mode===`easy`||e?.mode===`expert`?te(e.mode,e.chosen===!0):i.modeChosen===null&&v({modeChosen:!0})}c.status===`fulfilled`&&v({llmStatus:c.value})}}async function w(){let t=a;if(await e.clearProgress({}),t!==a)return i;a+=1;let n=a;return bq(s),s=new AbortController,S(s,n)}async function T(){return await y.reset()?(ie(),bq(f),f=null,bq(p),p=null,bq(m),m=null,v({graph:null,parseProgress:null,projectFailure:null,region:null,selectedNode:null,level:wG.GALAXY,studyData:null,studyError:``,explanation:null,explanationError:``,explanationLoading:!1,showChart:!1,studiedNodeIds:new Set,showChecks:!1,checkData:null,checkError:``,entrypointDismissed:!1,entrypointError:``,litRegionId:null,pendingDawnRegionId:null,languageFocus:`all`,llmStatus:null,picker:null,mapData:null,mapError:``}),x()):i}async function E(e){switch(e.type){case`ADVANCE`:return O(e.node);case`ADVANCE_REGION`:D(e.regionId);return;case`RETREAT`:k();return;case`SELECT_STUDY_NODE`:return A(e.nodeId);case`SET_LANGUAGE_FOCUS`:ee(e.language);return;case`SET_MODE`:return ne(e.mode);case`HOVER_NODE`:i.hoverNodeId!==(e.nodeId??null)&&v({hoverNodeId:e.nodeId??null});return;case`SHOW_CHART`:v({showChart:!0});return;case`HIDE_CHART`:v({showChart:!1});return;case`OPEN_CHECKS`:return M();case`CLOSE_CHECKS`:oe();return;case`SUBMIT_CHECK`:return se(e.checkId,e.selectedIds);case`CONSUME_DAWN`:pe(e.regionId);return;case`SELECT_ENTRYPOINT`:return ce(e.nodeId);case`DISMISS_ENTRYPOINT`:v({entrypointDismissed:!0});return;case`CHANGE_HOME`:ie(),v({entrypointDismissed:!1,entrypointError:``,level:wG.GALAXY,selectedNode:null,showChart:!1,studyData:null,studyError:``,explanation:null,explanationError:``,explanationLoading:!1});return;case`BROWSE_PICKER`:return y.browse(e.path);case`SELECT_PROJECT`:return y.select(e.path);case`RESET_PROJECT`:return T();case`CLEAR_PROGRESS`:return w();case`SET_LAYER`:return le(e.layer);case`SET_MAP_TAB`:v({mapTab:e.tab});return;case`DISMISS_COACHMARKS`:gq(),v({coachmarksSeen:!0});return;case`SET_LEVEL_GALAXY`:ie(),v({level:wG.GALAXY,selectedNode:null});return;case`TOGGLE_SHOW_ALL`:yq(!i.showAll),v({showAll:!i.showAll});return;case`SET_FINDER_OPEN`:v({finderOpen:e.open});return;case`TOGGLE_SIDEBAR`:v({sidebarOpen:!i.sidebarOpen});return;case`TOGGLE_LEGEND`:v({legendOpen:!i.legendOpen});return;case`GO_TO_REGION`:return v({finderOpen:!1}),D(e.regionId);default:throw Error(`Unknown learner-session event: ${e.type}`)}}function D(e){let t=i.graph?.regions.find(t=>t.id===e);t&&(ie(),v({languageFocus:i.languageFocus!==`all`&&t.language!==i.languageFocus?t.language:i.languageFocus,region:t,selectedNode:null,level:wG.SYSTEM,studyData:null,studyError:``,explanation:null,explanationError:``,explanationLoading:!1}))}async function O(e){if(!(!i.focusedGraph||!e)){if(i.level===wG.GALAXY){let t=i.focusedGraph.regions.find(t=>t.id===e.id)??e;ie(),v({region:t,selectedNode:null,level:wG.SYSTEM,studyData:null,studyError:``,explanation:null,explanationError:``});return}if(i.level===wG.SYSTEM){let t=i.focusedGraph.nodes.find(t=>t.id===e.id)??e;return v({selectedNode:t,level:wG.STUDY}),re(t.id)}}}function k(){i.level===wG.STUDY?(ie(),v({selectedNode:null,level:wG.SYSTEM,studyData:null,studyError:``,explanation:null,explanationError:``,explanationLoading:!1})):i.level===wG.SYSTEM&&v({level:wG.GALAXY})}async function A(e){let t=i.graph?.nodes.find(t=>t.id===e);if(!t)return;let n=i.graph.regions.find(e=>e.id===t.region);return v({languageFocus:i.languageFocus!==`all`&&t.language!==i.languageFocus?t.language:i.languageFocus,region:n??i.region,selectedNode:t,level:wG.STUDY}),re(t.id)}function ee(e){let t=i.selectedNode?.id;v({languageFocus:e}),t&&i.selectedNode?.id!==t&&(ie(),v({studyData:null,studyError:``,explanation:null,explanationError:``,explanationLoading:!1}))}function te(e,t){let n=i.layerChosen?i.layer:e===`easy`?`map`:`galaxy`;v({mode:e,layer:n,modeChosen:t}),n===`map`&&ue()}async function ne(t){if(t!==`easy`&&t!==`expert`)return;let n=i.mode,r=i.modeChosen;if(t===n&&i.modeChosen)return;o+=1,bq(m),m=new AbortController;let s=m,c=a;te(t,!0);try{await e.saveMode(t,{signal:s.signal})}catch(e){m===s&&c===a&&!xq(e)&&te(n,r);return}if(!(c!==a||s.signal.aborted)&&i.level===wG.STUDY&&i.selectedNode)return j(i.selectedNode.id)}async function re(t){ie(),c=new AbortController;let n=c;v({studyData:null,studyError:``}),j(t);try{let r=await e.loadStudy(t,{signal:n.signal});if(n.signal.aborted||i.level!==wG.STUDY||i.selectedNode?.id!==t)return;v({studyData:r,studiedNodeIds:new Set(i.studiedNodeIds).add(r.node.id)})}catch(e){c===n&&!n.signal.aborted&&!xq(e)&&i.selectedNode?.id===t&&v({studyError:Cq(e)})}}function ie(){bq(c),c=null,bq(l),l=null}async function j(t){bq(l),l=new AbortController;let n=l;v({explanation:null,explanationError:``,explanationLoading:!0});try{let r=await e.loadExplanation(t,i.mode,{signal:n.signal});if(n.signal.aborted||i.level!==wG.STUDY||i.selectedNode?.id!==t)return;v({explanation:r,explanationLoading:!1})}catch(e){l===n&&!n.signal.aborted&&!xq(e)&&i.selectedNode?.id===t&&v({explanationError:Cq(e),explanationLoading:!1})}}async function M(){if(!i.region)return;let e=i.region.id;return v({showChecks:!0,checkData:null,checkError:``}),ae(e)}async function ae(t){bq(u),u=new AbortController;let n=u;try{let r=await e.loadChecks(t,{signal:n.signal});return!n.signal.aborted&&i.showChecks&&i.region?.id===t&&v({checkData:r,checkError:``},{preserveChecks:!0}),r}catch(e){u===n&&!xq(e)&&!n.signal.aborted&&i.showChecks&&i.region?.id===t&&v({checkError:Cq(e)},{preserveChecks:!0});return}}function oe(){bq(u),u=null,v({showChecks:!1,checkData:null,checkError:``})}async function se(t,n){if(!i.region)return;let r=i.region.id;bq(d),d=new AbortController;let a=d,o=await e.submitCheck(r,t,n,{signal:a.signal});if(a.signal.aborted||i.region?.id!==r)return o;if(o.correct&&await ae(r),o.region_understood){let t=await e.loadGraph({signal:a.signal});!a.signal.aborted&&i.region?.id===r&&(bq(p),p=null,v({graph:t,region:t.regions.find(e=>e.id===r),mapData:null,mapError:``},{preserveChecks:!0}),fe(r),i.layer===`map`&&await ue())}return o}async function ce(t){let n=a;bq(f),f=new AbortController;let r=f;v({entrypointError:``});try{let o=await e.selectEntrypoint(t,{signal:r.signal});return n!==a||r.signal.aborted?i:(bq(p),p=null,v({graph:o,region:WG(o),entrypointError:``,entrypointDismissed:!0,mapData:null,mapError:``}),i.layer===`map`&&await ue(),o)}catch(e){f===r&&n===a&&!r.signal.aborted&&!xq(e)&&v({entrypointError:Cq(e)});return}}async function le(e){if(v({layer:e,layerChosen:!0}),e===`map`)return ue()}function ue(){if(!i.mapData)return p&&!p.signal.aborted&&!i.mapError?void 0:de()}async function de(){let t=a;bq(p),p=new AbortController;let n=p;v({mapError:``});try{let r=await e.fetchMap({signal:n.signal});return t===a&&!n.signal.aborted&&v({mapData:r,mapError:``}),r}catch(e){p===n&&t===a&&!n.signal.aborted&&!xq(e)&&v({mapError:Cq(e),mapData:null});return}}function fe(e){h!==null&&t.clearTimeout(h),v({litRegionId:e,pendingDawnRegionId:e}),h=t.setTimeout(()=>{h=null,i.litRegionId===e&&v({litRegionId:null})},520)}function pe(e){i.pendingDawnRegionId===e&&v({pendingDawnRegionId:null})}function me(){a+=1;for(let e of[s,c,l,u,d,f,p,m])bq(e);s=null,c=null,l=null,u=null,d=null,f=null,p=null,m=null,b(),y.dispose(),h!==null&&(t.clearTimeout(h),h=null)}return Object.freeze({dispatch:E,dispose:me,getSnapshot:g,start:x,subscribe:_})}function fq(e=globalThis.fetch){if(typeof e!=`function`)throw TypeError(`Learner-session HTTP adapter requires fetch.`);async function t(t,n,r={}){let i=await e(t,r);if(!i.ok){let e=(await i.json().catch(()=>null))?.detail,t=Error(typeof e==`string`&&e?e:`${n} returned ${i.status}.`);throw t.status=i.status,t}return i.json()}return Object.freeze({loadGraph(e={}){return t(`/api/graph`,`Graph request`,e)},fetchMap(e={}){return t(`/api/map`,`Map request`,e)},loadStudy(e,n={}){return t(`/api/node/${encodeURIComponent(e)}/study`,`Study request`,n)},loadExplanation(e,n,r={}){return t(`/api/node/${encodeURIComponent(e)}/explanation?mode=${encodeURIComponent(n)}`,`Explanation request`,r)},loadChecks(e,n={}){return t(`/api/regions/${encodeURIComponent(e)}/checks`,`Checks request`,n)},submitCheck(e,n,r,i={}){return t(`/api/regions/${encodeURIComponent(e)}/checks/${encodeURIComponent(n)}`,`Check submission`,{...i,method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({selected_ids:r})})},selectEntrypoint(e,n={}){return t(`/api/entrypoint`,`Home selection`,{...n,method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({node_id:e})})},loadMode(e={}){return t(`/api/mode`,`Mode request`,e)},saveMode(e,n={}){return t(`/api/mode`,`Mode update`,{...n,method:`PUT`,headers:{"Content-Type":`application/json`},body:JSON.stringify({mode:e})})},fetchLlmStatus(e={}){return t(`/api/llm/status`,`Model status`,e)},resetProject(e={}){return t(`/api/picker/reset`,`Project reset`,{...e,method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({confirmed:!0})})},loadPickerState(e={}){return t(`/api/picker/state`,`Picker state`,e)},browsePicker(e,n={}){return t(`/api/picker/browse${e?`?path=${encodeURIComponent(e)}`:``}`,`Folder listing`,n)},loadRecents(e={}){return t(`/api/picker/recents`,`Recent projects`,e)},fetchParseProgress(e={}){return t(`/api/picker/progress`,`Parse progress`,e)},clearProgress(e={}){return t(`/api/progress`,`Progress reset`,{...e,method:`DELETE`})},async selectProject(t,n={}){let r=await e(`/api/picker/select`,{...n,method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({path:t})}),i=await r.json().catch(()=>null);if(r.ok)return{state:r.status===202?`parsing`:`ready`};let a=i?.detail;return a&&typeof a==`object`&&a.reason===`scale`?{state:`scale`,...a}:{state:`error`,detail:typeof a==`string`?a:`Project selection returned ${r.status}.`}}})}var pq=`codemble.coachmarks.seen`;function mq(){if(typeof document>`u`)return null;try{return globalThis.localStorage??null}catch{return null}}function hq(){try{return mq()?.getItem(pq)===`1`}catch{return!1}}function gq(){try{mq()?.setItem(pq,`1`)}catch{}}var _q=`codemble.galaxy.showAll`;function vq(){try{return mq()?.getItem(_q)===`1`}catch{return!1}}function yq(e){try{let t=mq();e?t?.setItem(_q,`1`):t?.removeItem(_q)}catch{}}function bq(e){e&&!e.signal.aborted&&e.abort()}function xq(e){return e instanceof Error&&e.name===`AbortError`}function Sq(e){return Number.isInteger(e?.status)}function Cq(e){return e instanceof Error?e.message:String(e)}function wq(e){return Sq(e)?Cq(e):`Codemble's local server is not responding, so nothing can be loaded from it. It may have stopped — start it again by running codemble in your terminal. (${Cq(e)})`}function Tq(){let e=(0,_.useRef)(null),[t,n]=(0,_.useState)(!1),r=(0,_.useMemo)(()=>dq({adapter:fq()}),[]),i=(0,_.useSyncExternalStore)(r.subscribe,r.getSnapshot,r.getSnapshot);(0,_.useEffect)(()=>(r.start(),()=>r.dispose()),[r]),(0,_.useEffect)(()=>{function e(e){(e.metaKey||e.ctrlKey)&&e.key.toLowerCase()===`k`&&(e.preventDefault(),r.dispatch({type:`SET_FINDER_OPEN`,open:!0}))}return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[r]);let{chart:a,checkData:o,checkError:s,coachmarksSeen:c,entrypointError:l,entrypointOpen:u,error:d,explanation:f,explanationError:p,explanationLoading:m,finderOpen:h,focusedGraph:g,focusedMapData:v,focusedStudiedCount:y,graph:b,hint:x,hoverNodeId:S,languageFocus:C,languageOptions:w,layer:T,legendOpen:E,level:D,litRegionId:O,llmStatus:k,mapError:A,mapTab:ee,mode:te,modeChosen:ne,moduleIndex:re,parseProgress:ie,pendingDawnRegionId:j,picker:M,projectName:ae,projectFailure:oe,region:se,revealedRegionIds:ce,selectedNode:le,showAll:ue,showChart:de,showChecks:fe,sidebarOpen:pe,status:me,studyData:he,studyError:ge}=i;if(d)return(0,$.jsxs)(`main`,{className:`load-state`,role:`alert`,children:[(0,$.jsx)(`h1`,{children:`The graph did not load.`}),(0,$.jsx)(`p`,{children:d}),(0,$.jsx)(`p`,{children:`Your progress is stored on this machine and is not affected.`}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:()=>r.start(),children:`Try again`})]});if(ie)return(0,$.jsx)(Oq,{progress:ie,onCancel:()=>r.dispatch({type:`RESET_PROJECT`})});if(me===`picking`&&M)return(0,$.jsx)(kq,{picker:M,failure:oe,onBrowse:e=>r.dispatch({type:`BROWSE_PICKER`,path:e}),onSelect:e=>r.dispatch({type:`SELECT_PROJECT`,path:e})});if(!b||!g||!se)return(0,$.jsx)(`main`,{className:`load-state`,"aria-busy":`true`,children:(0,$.jsx)(`p`,{children:`Mapping parser evidence…`})});let _e=D===wG.SYSTEM?(0,$.jsxs)(`section`,{className:`orientation-copy orientation-copy--system${T===`map`?` orientation-copy--inline`:``}`,children:[(0,$.jsx)(`p`,{children:g.nodes.some(e=>e.region===se.id&&e.partial)?`${se.node_count} source ${se.node_count===1?`file remains`:`files remain`} visible · ${se.loc} lines. The module is unchartable beyond raw source because it has a syntax error.`:T===`map`?`The ${se.node_count} parser-proven ${se.node_count===1?`structure`:`structures`} inside this module ${se.node_count===1?`is`:`are`} drawn as planets in the Galaxy layer. This map shows how modules connect, not what is inside them.`:`${se.node_count} parser-proven structures · ${se.loc} lines in this system.`}),(0,$.jsx)(`button`,{className:`check-launch`,type:`button`,onClick:()=>r.dispatch({type:`OPEN_CHECKS`}),children:g.nodes.some(e=>e.region===se.id&&e.partial)?`Check availability`:se.understood?`Review understanding`:`Prove understanding`})]}):null;return(0,$.jsxs)(`main`,{className:`app-shell`,"data-level":de?`chart`:D.toLowerCase(),"data-mode":te,children:[(0,$.jsxs)(`header`,{className:`instrument-rail`,children:[(0,$.jsxs)(`div`,{className:`brand-lockup`,children:[(0,$.jsx)(`span`,{className:`brand-mark`,"aria-hidden":`true`}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`strong`,{children:`Codemble`}),(0,$.jsx)(`span`,{children:ae})]})]}),(0,$.jsx)(`nav`,{className:`location`,"aria-label":`Breadcrumb`,"aria-live":`polite`,children:de?(0,$.jsx)(`span`,{"aria-current":`page`,children:`Star chart`}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`button`,{type:`button`,disabled:D===wG.GALAXY,"aria-current":D===wG.GALAXY?`page`:void 0,onClick:()=>r.dispatch({type:`SET_LEVEL_GALAXY`}),children:`Galaxy`}),D===wG.GALAXY?(0,$.jsxs)(`small`,{children:[` · Home `,b.selected_entrypoint?WG(b)?.id??`unresolved`:`unselected`]}):(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`span`,{"aria-hidden":`true`,children:`/`}),(0,$.jsx)(`button`,{type:`button`,disabled:D===wG.SYSTEM,"aria-current":D===wG.SYSTEM?`page`:void 0,onClick:()=>r.dispatch({type:`RETREAT`}),children:se.id})]}),D===wG.STUDY&&le?(0,$.jsxs)($.Fragment,{children:[(0,$.jsx)(`span`,{"aria-hidden":`true`,children:`/`}),(0,$.jsx)(`span`,{"aria-current":`page`,children:le.name})]}):null,C===`all`?null:(0,$.jsxs)(`small`,{children:[` · `,AG(C),` focus`]})]})}),(0,$.jsxs)(`div`,{className:`rail-overflow`,"data-open":t||void 0,onKeyDown:r=>{r.key===`Escape`&&t&&(r.preventDefault(),n(!1),e.current?.focus())},children:[(0,$.jsx)(`button`,{ref:e,className:`mobile-menu-trigger`,type:`button`,"aria-expanded":t,"aria-controls":`rail-overflow-panel`,onClick:()=>n(e=>!e),children:`Menu`}),(0,$.jsxs)(`div`,{className:`rail-overflow__panel`,id:`rail-overflow-panel`,onClickCapture:e=>{e.target.closest(`button`)&&!e.target.closest(`.switch-project`)&&n(!1)},children:[(0,$.jsxs)(`div`,{className:`rail-actions`,children:[(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,"aria-pressed":pe,onClick:()=>r.dispatch({type:`TOGGLE_SIDEBAR`}),children:`Modules`}),(0,$.jsxs)(`button`,{className:`rail-action`,type:`button`,onClick:()=>r.dispatch({type:`SET_FINDER_OPEN`,open:!0}),children:[`Find `,(0,$.jsx)(`kbd`,{children:`⌘K`})]}),de?(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,onClick:()=>r.dispatch({type:`HIDE_CHART`}),children:`Return to galaxy`}):D===wG.GALAXY?(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,onClick:()=>r.dispatch({type:`SHOW_CHART`}),children:`Star chart`}):(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,onClick:()=>r.dispatch({type:`RETREAT`}),children:D===wG.STUDY?`Return to system`:`Return to galaxy`}),b.entrypoint_candidates.length?(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,onClick:()=>r.dispatch({type:`CHANGE_HOME`}),children:`Change Home`}):null,(0,$.jsx)(Lq,{onConfirm:()=>r.dispatch({type:`RESET_PROJECT`})})]}),(0,$.jsxs)(`div`,{className:`rail-controls`,children:[T===`galaxy`?(0,$.jsx)(`button`,{className:`rail-action rail-action--toggle`,type:`button`,"aria-pressed":ue,title:`Draw every module at once, including the ones no route from Home reaches`,onClick:()=>r.dispatch({type:`TOGGLE_SHOW_ALL`}),children:`Show all`}):null,(0,$.jsx)(Fq,{layer:T,mode:te,onChange:e=>r.dispatch({type:`SET_LAYER`,layer:e})}),(0,$.jsx)(Iq,{options:w,value:C,onChange:e=>r.dispatch({type:`SET_LANGUAGE_FOCUS`,language:e})}),(0,$.jsx)(PK,{mode:te,modeChosen:ne,onChoose:e=>r.dispatch({type:`SET_MODE`,mode:e})})]})]})]})]}),de?(0,$.jsxs)(`section`,{className:`chart-stage`,"aria-label":`Language concept progress`,children:[pe?(0,$.jsx)(Pq,{index:re,currentRegionId:null,onGo:e=>r.dispatch({type:`GO_TO_REGION`,regionId:e}),onClose:()=>r.dispatch({type:`TOGGLE_SIDEBAR`})}):null,(0,$.jsx)(Bq,{chart:a,studiedCount:y,projectName:ae,onClearProgress:()=>r.dispatch({type:`CLEAR_PROGRESS`})})]}):(0,$.jsxs)(`section`,{className:`map-stage`,"aria-label":`Parser-proven project map`,children:[pe?(0,$.jsx)(Pq,{index:re,currentRegionId:D===wG.GALAXY?null:se?.id,onGo:e=>r.dispatch({type:`GO_TO_REGION`,regionId:e}),onClose:()=>r.dispatch({type:`TOGGLE_SIDEBAR`})}):null,T===`map`?(0,$.jsx)(OK,{data:v,mapTab:ee,mode:te,selectedRegionId:D===wG.GALAXY?void 0:se?.id,hasEntrypointCandidates:b.entrypoint_candidates.length>0,error:A,onSelectTab:e=>r.dispatch({type:`SET_MAP_TAB`,tab:e}),onSelectRegion:e=>r.dispatch({type:`ADVANCE_REGION`,regionId:e}),onSelectNode:e=>r.dispatch({type:`SELECT_STUDY_NODE`,nodeId:e}),onRetry:()=>r.dispatch({type:`SET_LAYER`,layer:`map`}),children:_e}):(0,$.jsx)(aK,{graph:g,level:D,region:se,selectedNode:le,hoverNodeId:S,pendingDawnRegionId:j,revealedRegionIds:ce,mode:te,onHoverNode:e=>r.dispatch({type:`HOVER_NODE`,nodeId:e}),onAdvance:e=>r.dispatch({type:`ADVANCE`,node:e}),onRetreat:()=>r.dispatch({type:`RETREAT`}),onDawnConsumed:e=>r.dispatch({type:`CONSUME_DAWN`,regionId:e})}),(0,$.jsx)(`button`,{className:`legend-toggle`,type:`button`,"aria-expanded":E,onClick:()=>r.dispatch({type:`TOGGLE_LEGEND`}),children:`Key`}),(0,$.jsxs)(`aside`,{className:`map-legend`,hidden:!E,"aria-label":T===`map`?`Map legend`:`Galaxy legend`,children:[T===`galaxy`?(0,$.jsxs)($.Fragment,{children:[(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-size`}),`Size · `,te===`easy`?`how much code`:`lines of code`]}),(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-brightness`}),`Brighter · `,te===`easy`?`used in more places`:`more distinct callers`]})]}):null,(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-dot legend-dot--dim`}),`Dim · `,te===`easy`?`not proven yet`:`not understood`]}),(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-dot legend-dot--lit`}),`Amber · `,te===`easy`?`you proved you understand it`:`understood`]}),(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-dot legend-dot--partial`}),te===`easy`?`Could not be read`:`Unchartable · syntax error`]}),(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-route`}),te===`easy`?`Certain connection`:`Parser edge · certain`]}),(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:T===`map`?`legend-route legend-route--possible legend-route--dashed`:`legend-route legend-route--possible`}),te===`easy`?`Possible connection`:`Possible relationship`]}),T===`galaxy`&&D===wG.GALAXY||T===`map`&&ee===`architecture`?w.filter(e=>e.id!==`all`).map(e=>(0,$.jsxs)(`span`,{children:[(0,$.jsx)(`i`,{className:`legend-tint legend-tint--${e.id}`}),` `,e.label]},e.id)):null]}),T===`galaxy`&&D===wG.GALAXY?(0,$.jsxs)(`p`,{className:`orientation-bar`,children:[(0,$.jsxs)(`span`,{children:[g.regions.length,` `,C===`all`?g.regions.length===1?`system`:`systems`:`${AG(C)} ${g.regions.length===1?`system`:`systems`}`]}),(0,$.jsx)(`span`,{className:`orientation-bar__charted`,children:ue?`all charted`:`${ce.size} charted`}),g.partial_files.length?(0,$.jsxs)(`span`,{className:`partial-summary`,children:[g.partial_files.length,` unchartable · syntax error`]}):null]}):null,T===`galaxy`?_e:null,D===wG.SYSTEM&&fe?(0,$.jsx)(zq,{suite:o,error:s,mode:te,onClose:()=>r.dispatch({type:`CLOSE_CHECKS`}),onSubmit:(e,t)=>r.dispatch({type:`SUBMIT_CHECK`,checkId:e,selectedIds:t})}):null,u&&D===wG.GALAXY?(0,$.jsx)(Rq,{candidates:b.entrypoint_candidates,nodes:b.nodes,selectedEntrypoint:b.selected_entrypoint,error:l,onSelect:e=>r.dispatch({type:`SELECT_ENTRYPOINT`,nodeId:e}),onContinue:()=>r.dispatch({type:`DISMISS_ENTRYPOINT`})}):null,O?(0,$.jsxs)(`output`,{className:`illumination-pulse`,"aria-live":`polite`,children:[(0,$.jsx)(`span`,{"aria-hidden":`true`,children:`✦`}),(0,$.jsxs)(`strong`,{children:[O,` understood`]})]}):null,D===wG.STUDY&&le?(0,$.jsx)(FK,{node:le,study:he,error:ge,mode:te,explanation:f,explanationLoading:m,explanationError:p,llmStatus:k,onSelectNode:e=>r.dispatch({type:`SELECT_STUDY_NODE`,nodeId:e}),onRetryNarration:()=>r.dispatch({type:`SELECT_STUDY_NODE`,nodeId:le.id})}):null,ne===!0&&!u&&!c?(0,$.jsx)(pK,{layer:T,onDismiss:()=>r.dispatch({type:`DISMISS_COACHMARKS`})}):null]}),h?(0,$.jsx)(Nq,{index:re,onGo:e=>r.dispatch({type:`GO_TO_REGION`,regionId:e}),onClose:()=>r.dispatch({type:`SET_FINDER_OPEN`,open:!1})}):null,de?null:(0,$.jsx)(uK,{hint:x,onStudy:e=>r.dispatch({type:`ADVANCE_REGION`,regionId:e})}),(0,$.jsxs)(`footer`,{className:`status-line`,children:[(0,$.jsx)(`span`,{children:de?`${a.length} concepts detected`:C===`all`?`${b.nodes.length} nodes · ${b.edges.length} edges`:`${g.nodes.length}/${b.nodes.length} nodes · ${g.edges.length} focused edges`}),(0,$.jsx)(`span`,{children:de?`${y} focused structures studied this session`:T===`map`?`Click a box or row to study · Switch tabs to change view`:`Drag to orbit · Scroll to zoom · Click to move closer · Escape to move back`}),(0,$.jsx)(`span`,{children:`Local only`})]})]})}var Eq=Object.fromEntries(rq.map(({id:e,copy:t})=>[e,t])),Dq=rq.map(({id:e})=>e);function Oq({progress:e,onCancel:t}){let{stage:n,detail:r,files_done:i,files_total:a,pollError:o,pollOutage:s,attempts:c,path:l}=e,[u,d]=(0,_.useState)(!1),[f,p]=(0,_.useState)(``),m=(0,_.useRef)(null),h=Dq.indexOf(n);(0,_.useEffect)(()=>{m.current?.focus()},[]);async function g(){d(!0),p(``);try{await t()}catch(e){p(e.message),d(!1)}}return(0,$.jsxs)(`main`,{className:`loading-screen`,children:[(0,$.jsxs)(`header`,{className:`loading-header`,children:[(0,$.jsx)(`p`,{className:`picker-wordmark`,children:`Codemble`}),(0,$.jsxs)(`h1`,{ref:m,tabIndex:-1,children:[`Mapping `,(0,$.jsx)(`span`,{className:`loading-path`,children:l})]}),(0,$.jsx)(`p`,{className:`loading-subtitle`,children:`Parsing runs on your machine. Nothing is sent anywhere.`})]}),(0,$.jsx)(`ol`,{className:`loading-stages`,"aria-label":`Parse stages`,children:Dq.map((e,t)=>{let n=t(0,$.jsx)(`li`,{children:(0,$.jsxs)(`button`,{type:`button`,disabled:u,onClick:()=>r(e.project_root),children:[(0,$.jsx)(`span`,{className:`picker-recent-path`,children:e.project_root}),(0,$.jsxs)(`span`,{className:`picker-recent-lit`,children:[e.understood_count,` `,e.understood_count===1?`system`:`systems`,` lit last visit`]})]})},e.project_root))})]}):null,l?(0,$.jsx)(Aq,{scale:l,busy:u,onBrowse:n}):null,t?(0,$.jsx)(Mq,{failure:t,busy:u,onSelect:r}):c?(0,$.jsx)(`p`,{className:`picker-error`,role:`alert`,children:c}):null,(0,$.jsxs)(`section`,{className:`picker-browser`,"aria-labelledby":`picker-browser-heading`,children:[(0,$.jsx)(`h2`,{id:`picker-browser-heading`,children:`Browse folders`}),(0,$.jsx)(`p`,{className:`picker-path`,children:i}),(0,$.jsxs)(`ul`,{children:[a?(0,$.jsx)(`li`,{children:(0,$.jsx)(`button`,{type:`button`,disabled:u,onClick:()=>n(a),children:`↑ Up`})}):null,o.map(e=>(0,$.jsx)(`li`,{children:(0,$.jsxs)(`button`,{type:`button`,disabled:u,onClick:()=>n(e.path),children:[e.name,`/`]})},e.path))]}),(0,$.jsx)(`button`,{className:`picker-select`,type:`button`,disabled:u,onClick:()=>r(i),children:u?`Mapping…`:`Map this folder`})]})]})}function Aq({scale:e,busy:t,onBrowse:n}){let r=e.suggestions.filter(e=>e.path!==`.`);return(0,$.jsxs)(`section`,{className:`picker-scale`,role:`alert`,"aria-labelledby":`picker-scale-heading`,children:[(0,$.jsx)(`h2`,{id:`picker-scale-heading`,children:`That folder is too big to map at once.`}),(0,$.jsxs)(`p`,{children:[`It has `,e.file_count,` supported source files; Codemble maps up to`,` `,e.scale_cap,`. Choose a smaller scope — busiest first.`]}),r.length?(0,$.jsx)(`ul`,{className:`picker-scale-scopes`,children:r.map(r=>(0,$.jsx)(`li`,{children:(0,$.jsxs)(`button`,{type:`button`,disabled:t,onClick:()=>n(`${e.root}/${r.path}`),children:[(0,$.jsxs)(`span`,{children:[r.path,`/`]}),(0,$.jsxs)(`small`,{children:[r.file_count,` files`]})]})},r.path))}):null,(0,$.jsx)(jq,{busy:t,onBrowse:n})]})}function jq({busy:e,onBrowse:t}){let[n,r]=(0,_.useState)(``);return(0,$.jsxs)(`form`,{className:`picker-path-entry`,onSubmit:e=>{e.preventDefault();let r=n.trim();r&&t(r)},children:[(0,$.jsx)(`label`,{htmlFor:`picker-path-input`,children:`Or type a folder path`}),(0,$.jsx)(`input`,{id:`picker-path-input`,type:`text`,value:n,disabled:e,placeholder:`/Users/you/project/src`,onChange:e=>r(e.target.value)}),(0,$.jsx)(`button`,{type:`submit`,disabled:e||!n.trim(),children:`Go`})]})}function Mq({failure:e,busy:t,onSelect:n}){return(0,$.jsxs)(`section`,{className:`picker-failure`,role:`alert`,children:[(0,$.jsx)(`h2`,{children:`Codemble could not map that folder.`}),(0,$.jsx)(`p`,{children:`Nothing on disk changed, and no project's saved progress was touched. Try it again, or choose a different folder below.`}),(0,$.jsxs)(`p`,{className:`picker-failure__detail`,children:[(0,$.jsx)(`span`,{children:`What the parser reported`}),(0,$.jsx)(`code`,{children:e.detail})]}),(0,$.jsxs)(`button`,{className:`picker-select`,type:`button`,disabled:t,onClick:()=>n(e.path),children:[`Try `,(0,$.jsx)(`span`,{className:`picker-recent-path`,children:e.path}),` again`]})]})}function Nq({index:e,onGo:t,onClose:n}){let[r,i]=(0,_.useState)(``),[a,o]=(0,_.useState)(0),s=(0,_.useRef)(null),c=(0,_.useRef)(null),l=(0,_.useMemo)(()=>{let t=r.trim().toLowerCase();return(t?e.filter(e=>e.label.toLowerCase().includes(t)||e.file.toLowerCase().includes(t)):e).slice(0,60)},[e,r]);(0,_.useLayoutEffect)(()=>{let e=s.current;e&&!e.open&&e.showModal(),c.current?.focus()},[]),(0,_.useEffect)(()=>o(0),[r]);let u=l[Math.min(a,l.length-1)]??null;function d(e){e.key===`ArrowDown`?(e.preventDefault(),o(e=>Math.min(e+1,l.length-1))):e.key===`ArrowUp`?(e.preventDefault(),o(e=>Math.max(e-1,0))):e.key===`Enter`&&u&&(e.preventDefault(),t(u.id))}return(0,$.jsxs)(`dialog`,{ref:s,className:`module-finder`,"aria-label":`Find a module`,onCancel:e=>{e.preventDefault(),n()},onClose:n,children:[(0,$.jsx)(`input`,{ref:c,type:`search`,value:r,placeholder:`Find a module…`,"aria-label":`Find a module by name or path`,onChange:e=>i(e.target.value),onKeyDown:d}),(0,$.jsx)(`ul`,{role:`listbox`,"aria-label":`Matching modules`,children:l.map((e,n)=>(0,$.jsx)(`li`,{children:(0,$.jsxs)(`button`,{type:`button`,role:`option`,"aria-selected":n===a,"data-active":n===a||void 0,onMouseEnter:()=>o(n),onClick:()=>t(e.id),children:[(0,$.jsx)(`strong`,{children:e.label}),(0,$.jsx)(`small`,{children:e.file}),e.home?(0,$.jsx)(`em`,{children:`Home`}):e.understood?(0,$.jsx)(`em`,{children:`lit`}):null]})},e.id))}),l.length?null:(0,$.jsx)(`p`,{className:`module-finder__empty`,children:`No module matches that.`})]})}function Pq({index:e,currentRegionId:t,onGo:n,onClose:r}){let i=(0,_.useMemo)(()=>zG(e),[e]);return(0,$.jsxs)(`aside`,{className:`index-sidebar`,"aria-label":`Project index`,children:[(0,$.jsxs)(`header`,{children:[(0,$.jsx)(`h2`,{children:`Modules`}),(0,$.jsx)(`button`,{type:`button`,onClick:r,"aria-label":`Close the project index`,children:`×`})]}),(0,$.jsx)(`div`,{className:`index-sidebar__scroll`,children:i.map(e=>(0,$.jsxs)(`section`,{children:[(0,$.jsx)(`h3`,{title:e.name,children:e.name}),(0,$.jsx)(`ul`,{children:e.members.map(e=>(0,$.jsx)(`li`,{children:(0,$.jsxs)(`button`,{type:`button`,"aria-current":e.id===t?`true`:void 0,"data-lit":e.understood||void 0,title:e.file,onClick:()=>n(e.id),children:[(0,$.jsx)(`span`,{children:e.display??e.label}),e.home?(0,$.jsx)(`em`,{children:`Home`}):null]})},e.id))})]},e.community))})]})}function Fq({layer:e,mode:t,onChange:n}){return(0,$.jsx)(`nav`,{className:`layer-switcher`,"aria-label":`View layer`,children:[{id:`galaxy`,label:`Galaxy`},{id:`map`,label:t===`easy`?`Diagram`:`Map`}].map(t=>(0,$.jsx)(`button`,{type:`button`,"aria-pressed":e===t.id,onClick:()=>n(t.id),children:t.label},t.id))})}function Iq({options:e,value:t,onChange:n}){return e.length<=2?null:(0,$.jsxs)(`nav`,{className:`language-focus`,"aria-label":`Language focus`,children:[(0,$.jsx)(`span`,{className:`language-focus__label`,children:`Focus`}),(0,$.jsx)(`div`,{children:e.map(e=>(0,$.jsxs)(`button`,{type:`button`,"aria-label":`Focus ${e.label}: ${e.count} ${e.count===1?`system`:`systems`}`,"aria-pressed":t===e.id,title:e.label,onClick:()=>n(e.id),children:[(0,$.jsx)(`span`,{children:e.shortLabel}),(0,$.jsx)(`small`,{children:e.count})]},e.id))})]})}function Lq({onConfirm:e}){let[t,n]=(0,_.useState)(!1),[r,i]=(0,_.useState)(!1),[a,o]=(0,_.useState)(``),s=(0,_.useRef)(null),c=(0,_.useRef)(null),l=(0,_.useRef)(!1);(0,_.useEffect)(()=>{t?c.current?.focus():l.current&&s.current?.focus(),l.current=t},[t]);function u(){n(!1),o(``)}async function d(){i(!0),o(``);try{await e()}catch(e){o(e.message),i(!1)}}return t?(0,$.jsxs)(`div`,{className:`switch-project`,role:`group`,"aria-label":`Switch project`,tabIndex:-1,ref:c,onKeyDown:e=>{e.key===`Escape`&&!r&&u()},children:[(0,$.jsx)(`p`,{children:`Progress is saved per project, so this galaxy comes back lit.`}),a?(0,$.jsx)(`p`,{className:`switch-project__error`,role:`alert`,children:a}):null,(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,disabled:r,onClick:d,children:r?`Releasing…`:`Switch`}),(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,disabled:r,onClick:u,children:`Cancel`})]})]}):(0,$.jsx)(`button`,{className:`rail-action`,type:`button`,ref:s,onClick:()=>n(!0),children:`Switch project`})}function Rq({candidates:e,nodes:t,selectedEntrypoint:n,error:r,onSelect:i,onContinue:a}){let o=new Map(t.map(e=>[e.id,e]));return(0,$.jsxs)(`aside`,{className:`entrypoint-picker`,"aria-labelledby":`entrypoint-heading`,children:[(0,$.jsx)(`p`,{children:`Home calibration`}),(0,$.jsx)(`h1`,{id:`entrypoint-heading`,children:e.length?`Where does your project start?`:`No clear entrypoint found.`}),(0,$.jsx)(`p`,{children:e.length?`The parser found ranked candidates but cannot choose one honestly. Select the structure you run.`:`No file here declares a startup structure the parser recognises, and Codemble will not guess one. Explore the map without Home — every system, check, explanation, and lens note still works.`}),e.length?(0,$.jsx)(`div`,{className:`entrypoint-candidates`,children:e.map(e=>{let t=o.get(e);return(0,$.jsxs)(`button`,{type:`button`,onClick:()=>i(e),children:[(0,$.jsx)(`span`,{children:e}),(0,$.jsxs)(`small`,{children:[t?.file,`:`,t?.lineno,` · parser rank `,t?.entrypoint_rank]})]},e)})}):null,r?(0,$.jsx)(`p`,{className:`entrypoint-error`,role:`alert`,children:r}):null,(0,$.jsx)(`button`,{className:`entrypoint-continue`,type:`button`,onClick:a,children:n?`Keep current Home`:`Explore without Home`})]})}function zq({suite:e,error:t,mode:n,onClose:r,onSubmit:i}){let a=e?.checks.find(e=>!e.passed)??null,o=e?.checks.filter(e=>e.passed).length??0,[s,c]=(0,_.useState)(()=>new Set),[l,u]=(0,_.useState)(null),[d,f]=(0,_.useState)(``),[p,m]=(0,_.useState)(!1),[h,g]=(0,_.useState)(``);(0,_.useEffect)(()=>{c(new Set),u(null),g(``)},[a?.id]);function v(e,t){f(``),c(n=>{if(!t)return new Set([e]);let r=new Set(n);return r.has(e)?r.delete(e):r.add(e),r})}async function y(e){if(e.preventDefault(),!(!a||s.size===0)){m(!0),g(``);try{let e=await i(a.id,[...s]);e.correct?(f(e.message),u(null)):(f(``),u(e))}catch(e){g(e.message)}finally{m(!1)}}}return(0,$.jsxs)(`aside`,{className:`check-panel`,"aria-label":`Graph-derived understanding checks`,children:[(0,$.jsxs)(`header`,{className:`check-panel__header`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`p`,{children:`Active recall · graph only`}),(0,$.jsx)(`h1`,{children:e?.region_id??`Loading checks`})]}),(0,$.jsx)(`button`,{className:`check-close`,type:`button`,onClick:r,children:`Close`})]}),t||h?(0,$.jsxs)(`div`,{className:`check-state`,role:`alert`,children:[(0,$.jsx)(`h2`,{children:`The checks did not load.`}),(0,$.jsxs)(`p`,{children:[t||h,` The galaxy remains available.`]})]}):null,!e&&!t?(0,$.jsx)(`p`,{className:`check-loading`,role:`status`,children:`Deriving answers from parser edges…`}):null,e?.region_understood?(0,$.jsxs)(`div`,{className:`check-complete`,"aria-live":`polite`,children:[(0,$.jsx)(`span`,{className:`check-complete__star`,"aria-hidden":`true`,children:`✦`}),(0,$.jsx)(`h2`,{children:`System lit.`}),(0,$.jsx)(`p`,{children:`This region's source hash matches the checks you passed. Edit its file and only this system will dim again.`}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:r,children:`Return to the system`})]}):null,e&&!e.region_understood&&e.checks.length===0?(0,$.jsxs)(`div`,{className:`check-state`,children:[(0,$.jsx)(`h2`,{children:`No safe check yet.`}),(0,$.jsx)(`p`,{children:`Every question here is answered by the parser graph, and this region has no certain relationship Codemble can build one from. It stays dim rather than lighting on a question that would prove nothing. Import this module somewhere, or call something inside it, and its checks appear.`})]}):null,a&&!e.region_understood?(0,$.jsxs)(`form`,{className:`active-check`,onSubmit:y,children:[(0,$.jsxs)(`div`,{className:`check-progress`,children:[(0,$.jsxs)(`span`,{children:[`Check `,o+1,` of `,e.checks.length]}),(0,$.jsx)(`progress`,{value:o,max:e.checks.length})]}),d?(0,$.jsxs)(`p`,{className:`check-affirmation`,role:`status`,children:[(0,$.jsx)(`span`,{"aria-hidden":`true`,children:`✦`}),` `,d]}):null,(0,$.jsxs)(`fieldset`,{children:[(0,$.jsx)(`legend`,{children:a.prompt_voices[n]}),a.multiple?(0,$.jsx)(`p`,{children:`Select every answer supported by the graph.`}):null,(0,$.jsx)(`div`,{className:`check-options`,children:a.options.map(e=>(0,$.jsxs)(`label`,{children:[(0,$.jsx)(`input`,{type:a.multiple?`checkbox`:`radio`,name:`answer-${a.id}`,value:e.id,checked:s.has(e.id),onChange:()=>v(e.id,a.multiple)}),(0,$.jsx)(`span`,{children:e.label})]},e.id))})]}),l&&!l.correct?(0,$.jsxs)(`div`,{className:`check-feedback`,role:`status`,children:[(0,$.jsx)(`strong`,{children:l.message}),(0,$.jsxs)(`span`,{children:[`Parser answer: `,l.answer_labels.join(`, `)]}),(0,$.jsxs)(`span`,{children:[`Evidence: `,l.evidence.join(`, `)]})]}):null,(0,$.jsx)(`button`,{className:`check-primary`,type:`submit`,disabled:!s.size||p,children:p?`Checking parser evidence…`:`Check answer`})]}):null]})}function Bq({chart:e,studiedCount:t,projectName:n,onClearProgress:r}){let i=e.filter(e=>e.understood_nodes>0).length;return(0,$.jsxs)(`section`,{className:`star-chart-screen`,"aria-labelledby":`star-chart-heading`,children:[(0,$.jsxs)(`header`,{className:`star-chart-intro`,children:[(0,$.jsx)(`p`,{children:`Parser-detected concepts`}),(0,$.jsx)(`h1`,{id:`star-chart-heading`,children:`Your language star chart.`}),(0,$.jsx)(`p`,{children:`Encountered comes from real syntax. Studied tracks this session. Understood lights only after graph-derived checks pass.`}),(0,$.jsxs)(`dl`,{children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Concepts encountered`}),(0,$.jsx)(`dd`,{children:e.length})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Studied this session`}),(0,$.jsx)(`dd`,{children:t})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Concepts understood`}),(0,$.jsx)(`dd`,{children:i})]})]})]}),(0,$.jsx)(`div`,{className:`concept-ledger`,role:`list`,"aria-label":`Language concept progress`,children:e.map(e=>(0,$.jsxs)(`article`,{className:`concept-row`,role:`listitem`,children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`h2`,{children:kG(e.concept)}),(0,$.jsxs)(`span`,{children:[kG(e.language),` · `,e.occurrences,` parser `,e.occurrences===1?`occurrence`:`occurrences`]})]}),(0,$.jsx)(`div`,{className:`concept-meter`,"aria-label":`${e.understood_nodes} of ${e.nodes} structures understood`,children:(0,$.jsx)(`span`,{style:{width:`${e.nodes?e.understood_nodes/e.nodes*100:0}%`}})}),(0,$.jsxs)(`dl`,{children:[(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Studied (session)`}),(0,$.jsxs)(`dd`,{children:[e.studied_nodes,`/`,e.nodes]})]}),(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`dt`,{children:`Understood`}),(0,$.jsxs)(`dd`,{children:[e.understood_nodes,`/`,e.nodes]})]})]})]},`${e.language}:${e.concept}`))}),(0,$.jsx)(Vq,{projectName:n,onConfirm:r})]})}function Vq({projectName:e,onConfirm:t}){let[n,r]=(0,_.useState)(!1),[i,a]=(0,_.useState)(!1),[o,s]=(0,_.useState)(``),c=(0,_.useRef)(null),l=(0,_.useRef)(null),u=(0,_.useRef)(!1);(0,_.useEffect)(()=>{n?l.current?.focus():u.current&&c.current?.focus(),u.current=n},[n]);function d(){r(!1),s(``)}async function f(){a(!0),s(``);try{await t(),r(!1)}catch(e){s(e.message)}finally{a(!1)}}return n?(0,$.jsxs)(`section`,{className:`progress-reset progress-reset--confirming`,role:`group`,"aria-label":`Clear this project's progress`,tabIndex:-1,ref:l,onKeyDown:e=>{e.key===`Escape`&&!i&&d()},children:[(0,$.jsxs)(`p`,{role:`alert`,children:[`This dims every system you lit in `,e,` and cannot be undone. Your other projects keep their progress, and no source file is touched.`]}),o?(0,$.jsx)(`p`,{className:`progress-reset__error`,role:`alert`,children:o}):null,(0,$.jsxs)(`div`,{children:[(0,$.jsx)(`button`,{className:`check-primary progress-reset__confirm`,type:`button`,disabled:i,onClick:f,children:i?`Clearing…`:`Yes, clear ${e}`}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,disabled:i,onClick:d,children:`Keep it`})]})]}):(0,$.jsxs)(`section`,{className:`progress-reset`,children:[(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,ref:c,onClick:()=>r(!0),children:`Clear this project's progress`}),(0,$.jsxs)(`p`,{children:[`Start `,e,` over with every system dim again.`]})]})}var Hq=class extends _.Component{constructor(e){super(e),this.state={message:``}}static getDerivedStateFromError(e){return{message:e instanceof Error?e.message:String(e)}}componentDidCatch(e,t){console.error(`Codemble stopped rendering:`,e,t?.componentStack)}render(){return this.state.message?(0,$.jsxs)(`main`,{className:`load-state`,role:`alert`,children:[(0,$.jsx)(`h1`,{children:`The galaxy stopped rendering.`}),(0,$.jsx)(`p`,{children:this.state.message}),(0,$.jsx)(`p`,{children:`Your progress is saved on this machine; reloading re-reads it.`}),(0,$.jsx)(`button`,{className:`check-primary`,type:`button`,onClick:()=>window.location.reload(),children:`Reload Codemble`})]}):this.props.children}};(0,v.createRoot)(document.getElementById(`root`)).render((0,$.jsx)(_.StrictMode,{children:(0,$.jsx)(Hq,{children:(0,$.jsx)(Tq,{})})})); \ No newline at end of file diff --git a/codemble/web_dist/index.html b/codemble/web_dist/index.html index a7bde98..be0a3ad 100644 --- a/codemble/web_dist/index.html +++ b/codemble/web_dist/index.html @@ -9,7 +9,7 @@ content="Explore the parser-proven structure of your local project with Codemble." /> Codemble · Your code, mapped - + diff --git a/docs-site/package.json b/docs-site/package.json index ee5a05f..e336771 100644 --- a/docs-site/package.json +++ b/docs-site/package.json @@ -1,7 +1,7 @@ { "name": "codemble-docs", "type": "module", - "version": "0.6.1", + "version": "0.6.2", "private": true, "scripts": { "dev": "astro dev", diff --git a/docs/releases/v0.6.2.md b/docs/releases/v0.6.2.md new file mode 100644 index 0000000..42d236d --- /dev/null +++ b/docs/releases/v0.6.2.md @@ -0,0 +1,25 @@ +# Codemble v0.6.2 — visible first-run choice on mobile + +v0.6.2 is an immediate hotfix for the installed v0.6.1 artifact. The final +public-wheel smoke found that a fresh 320 px run opened the audience modal while +the dialog was still contained by the closed compact Menu. The invisible modal +backdrop blocked every control. + +The audience gate now portals to the document top layer. It remains the same +required, keyboard-accessible first decision; after selection, the persistent +Easy/Expert toggle still lives in the compact Menu. No parser, graph, checks, +persistence, provider, or progress behavior changed. + +## Verification + +- Fresh isolated data directory at 320×800: visible audience dialog → choice → + coach marks → compact Menu +- Zero console errors and no horizontal overflow on the installed wheel +- Python tests, Ruff, web contracts/build, Astro check/build, Graphify refresh, + wheel/sdist checksum verification, CI, Pages, GitHub release assets, and + public PyPI `uvx` smoke + +## Known limits + +- The v0.6.1 artifact remains immutable on PyPI; v0.6.2 supersedes it as latest. +- The Phase 1 milestone still requires human tester evidence in issue #13. diff --git a/pyproject.toml b/pyproject.toml index ee10174..3830049 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "codemble" -version = "0.6.1" +version = "0.6.2" description = "A learning game that turns the code AI wrote for you into a galaxy you light up by understanding it." readme = "README.md" license = "Apache-2.0" diff --git a/web/package-lock.json b/web/package-lock.json index ff602c9..44cf121 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,12 +1,12 @@ { "name": "codemble-web", - "version": "0.6.1", + "version": "0.6.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "codemble-web", - "version": "0.6.1", + "version": "0.6.2", "dependencies": { "@fontsource/jetbrains-mono": "5.2.8", "@fontsource/shippori-mincho": "^5.3.0", diff --git a/web/package.json b/web/package.json index a42a663..c785440 100644 --- a/web/package.json +++ b/web/package.json @@ -1,12 +1,12 @@ { "name": "codemble-web", "private": true, - "version": "0.6.1", + "version": "0.6.2", "type": "module", "scripts": { "dev": "vite", "build": "vite build", - "check": "node scripts/check_graph_data.mjs && node scripts/check_name_atlas.mjs && node scripts/check_project_mapping.mjs && node scripts/check_learner_projection.mjs && node scripts/check_learner_session.mjs && node scripts/check_orbit_pointer_guard.mjs && vite build", + "check": "node scripts/check_graph_data.mjs && node scripts/check_name_atlas.mjs && node scripts/check_project_mapping.mjs && node scripts/check_learner_projection.mjs && node scripts/check_learner_session.mjs && node scripts/check_orbit_pointer_guard.mjs && node scripts/check_mode_gate_portal.mjs && vite build", "benchmark:projection": "node scripts/benchmark_learner_projection.mjs" }, "dependencies": { diff --git a/web/scripts/check_mode_gate_portal.mjs b/web/scripts/check_mode_gate_portal.mjs new file mode 100644 index 0000000..c82ca07 --- /dev/null +++ b/web/scripts/check_mode_gate_portal.mjs @@ -0,0 +1,13 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; + +const source = readFileSync(new URL("../src/ModeControl.jsx", import.meta.url), "utf8"); + +assert.match(source, /import \{ createPortal \} from "react-dom";/); +assert.match( + source, + /return createPortal\([\s\S]*? ))} - + , + document.body, ); }