@goodbones/browser 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/build/dts/index.d.ts +12 -0
- package/build/dts/index.d.ts.map +1 -0
- package/build/dts/main.d.ts +3 -0
- package/build/dts/main.d.ts.map +1 -0
- package/build/dts/model/atlas.d.ts +157 -0
- package/build/dts/model/atlas.d.ts.map +1 -0
- package/build/dts/model/campaigns.d.ts +141 -0
- package/build/dts/model/campaigns.d.ts.map +1 -0
- package/build/dts/server/collect.d.ts +16 -0
- package/build/dts/server/collect.d.ts.map +1 -0
- package/build/dts/server/compose.d.ts +13 -0
- package/build/dts/server/compose.d.ts.map +1 -0
- package/build/dts/server/export.d.ts +3 -0
- package/build/dts/server/export.d.ts.map +1 -0
- package/build/dts/server/handler.d.ts +6 -0
- package/build/dts/server/handler.d.ts.map +1 -0
- package/build/dts/server/serve.d.ts +15 -0
- package/build/dts/server/serve.d.ts.map +1 -0
- package/build/dts/server/site.d.ts +2 -0
- package/build/dts/server/site.d.ts.map +1 -0
- package/build/dts/server/source.d.ts +19 -0
- package/build/dts/server/source.d.ts.map +1 -0
- package/build/dts/server/vite-plugin.d.ts +8 -0
- package/build/dts/server/vite-plugin.d.ts.map +1 -0
- package/build/dts/server/watch.d.ts +10 -0
- package/build/dts/server/watch.d.ts.map +1 -0
- package/build/esm/index.js +14 -0
- package/build/esm/index.js.map +1 -0
- package/build/esm/main.js +134 -0
- package/build/esm/main.js.map +1 -0
- package/build/esm/model/atlas.js +431 -0
- package/build/esm/model/atlas.js.map +1 -0
- package/build/esm/model/campaigns.js +181 -0
- package/build/esm/model/campaigns.js.map +1 -0
- package/build/esm/server/collect.js +83 -0
- package/build/esm/server/collect.js.map +1 -0
- package/build/esm/server/compose.js +50 -0
- package/build/esm/server/compose.js.map +1 -0
- package/build/esm/server/export.js +19 -0
- package/build/esm/server/export.js.map +1 -0
- package/build/esm/server/handler.js +67 -0
- package/build/esm/server/handler.js.map +1 -0
- package/build/esm/server/serve.js +80 -0
- package/build/esm/server/serve.js.map +1 -0
- package/build/esm/server/site.js +6 -0
- package/build/esm/server/site.js.map +1 -0
- package/build/esm/server/source.js +67 -0
- package/build/esm/server/source.js.map +1 -0
- package/build/esm/server/vite-plugin.js +21 -0
- package/build/esm/server/vite-plugin.js.map +1 -0
- package/build/esm/server/watch.js +56 -0
- package/build/esm/server/watch.js.map +1 -0
- package/build/site/_astro/Browser.yxldcnQ3.js +3 -0
- package/build/site/_astro/client.Buyw3Q1S.js +9 -0
- package/build/site/_astro/index.DQrWs1cb.css +1 -0
- package/build/site/_astro/react.DJY1zw8Z.js +1 -0
- package/build/site/favicon.svg +1 -0
- package/build/site/index.html +8 -0
- package/package.json +78 -0
- package/src/app/components/Browser.tsx +153 -0
- package/src/app/components/architecture/ArchitectureBrowser.tsx +240 -0
- package/src/app/components/architecture/Detail.tsx +655 -0
- package/src/app/components/architecture/ManifestPane.tsx +178 -0
- package/src/app/components/architecture/Tree.tsx +205 -0
- package/src/app/components/architecture/rows.ts +181 -0
- package/src/app/components/architecture/selection.ts +6 -0
- package/src/app/components/campaigns/CampaignBrowser.tsx +146 -0
- package/src/app/components/campaigns/Detail.tsx +653 -0
- package/src/app/components/campaigns/Ladder.tsx +326 -0
- package/src/app/components/campaigns/pick.ts +7 -0
- package/src/app/components/lib/data.ts +132 -0
- package/src/app/pages/index.astro +34 -0
- package/src/app/public/favicon.svg +1 -0
- package/src/app/styles/theme.css +993 -0
- package/src/index.ts +37 -0
- package/src/main.ts +155 -0
- package/src/model/atlas.ts +751 -0
- package/src/model/campaigns.ts +376 -0
- package/src/server/collect.ts +132 -0
- package/src/server/compose.ts +79 -0
- package/src/server/export.ts +24 -0
- package/src/server/handler.ts +77 -0
- package/src/server/serve.ts +100 -0
- package/src/server/site.ts +6 -0
- package/src/server/source.ts +89 -0
- package/src/server/vite-plugin.ts +32 -0
- package/src/server/watch.ts +65 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-plugin.js","sourceRoot":"","sources":["../../../src/server/vite-plugin.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAYzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAA6B,EAAU,EAAE,CAAC,CAAC;IAC1E,IAAI,EAAE,mBAAmB;IACzB,eAAe,CAAC,MAAM;QACpB,MAAM,MAAM,GAAG,UAAU,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;YACjD,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC;iBACtB,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;gBAChB,IAAI,CAAC,OAAO;oBAAE,IAAI,EAAE,CAAC;YACvB,CAAC,CAAC;iBACD,KAAK,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YACpC,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { watch } from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
// The repository, watched: a change to a source file, a manifest or a ledger
|
|
4
|
+
// is what redraws the browsers. Node's recursive watcher, so no dependency;
|
|
5
|
+
// events are debounced, since an editor's save is several of them.
|
|
6
|
+
const IGNORED = ["node_modules", ".git", "build", "dist", ".nx", ".astro", "coverage"];
|
|
7
|
+
const MANIFEST = /(^|\/)architecture(\.config)?\.(ya?ml|json|mjs)$/;
|
|
8
|
+
export const isRelevant = (file, extensions, ledgerDir) => {
|
|
9
|
+
const segments = file.split("/");
|
|
10
|
+
if (segments.some((segment) => IGNORED.includes(segment)))
|
|
11
|
+
return false;
|
|
12
|
+
if (MANIFEST.test(file))
|
|
13
|
+
return true;
|
|
14
|
+
if (ledgerDir !== "" && (file === ledgerDir || file.startsWith(`${ledgerDir}/`)))
|
|
15
|
+
return true;
|
|
16
|
+
return extensions.includes(path.extname(file));
|
|
17
|
+
};
|
|
18
|
+
export const watchRepository = (options) => {
|
|
19
|
+
const delay = options.debounceMs ?? 150;
|
|
20
|
+
let pending = new Set();
|
|
21
|
+
let timer = null;
|
|
22
|
+
const flush = () => {
|
|
23
|
+
timer = null;
|
|
24
|
+
const files = [...pending].sort();
|
|
25
|
+
pending = new Set();
|
|
26
|
+
if (files.length > 0)
|
|
27
|
+
options.onChange(files);
|
|
28
|
+
};
|
|
29
|
+
let watcher = null;
|
|
30
|
+
try {
|
|
31
|
+
watcher = watch(options.repoRoot, { recursive: true }, (_event, filename) => {
|
|
32
|
+
if (filename === null)
|
|
33
|
+
return;
|
|
34
|
+
const file = String(filename).split(path.sep).join("/");
|
|
35
|
+
if (!isRelevant(file, options.extensions, options.ledgerDir))
|
|
36
|
+
return;
|
|
37
|
+
pending.add(file);
|
|
38
|
+
if (timer !== null)
|
|
39
|
+
clearTimeout(timer);
|
|
40
|
+
timer = setTimeout(flush, delay);
|
|
41
|
+
});
|
|
42
|
+
watcher.on("error", () => {
|
|
43
|
+
// A watcher that dies leaves the page static; the next request still
|
|
44
|
+
// recomputes, so nothing is wrong, only not live.
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
watcher = null;
|
|
49
|
+
}
|
|
50
|
+
return () => {
|
|
51
|
+
if (timer !== null)
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
watcher?.close();
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=watch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../../src/server/watch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,6EAA6E;AAC7E,4EAA4E;AAC5E,mEAAmE;AAEnE,MAAM,OAAO,GAAG,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;AAYvF,MAAM,QAAQ,GAAG,kDAAkD,CAAC;AAEpE,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,IAAY,EACZ,UAAiC,EACjC,SAAiB,EACR,EAAE;IACX,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACxE,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,SAAS,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9F,OAAO,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACjD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAqB,EAAgB,EAAE;IACrE,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,IAAI,GAAG,CAAC;IACxC,IAAI,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,IAAI,KAAK,GAA0B,IAAI,CAAC;IACxC,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,KAAK,GAAG,IAAI,CAAC;QACb,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAClC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QACpB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC,CAAC;IACF,IAAI,OAAO,GAAqB,IAAI,CAAC;IACrC,IAAI,CAAC;QACH,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;YAC1E,IAAI,QAAQ,KAAK,IAAI;gBAAE,OAAO;YAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxD,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,SAAS,CAAC;gBAAE,OAAO;YACrE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAClB,IAAI,KAAK,KAAK,IAAI;gBAAE,YAAY,CAAC,KAAK,CAAC,CAAC;YACxC,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,qEAAqE;YACrE,kDAAkD;QACpD,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,EAAE;QACV,IAAI,KAAK,KAAK,IAAI;YAAE,YAAY,CAAC,KAAK,CAAC,CAAC;QACxC,OAAO,EAAE,KAAK,EAAE,CAAC;IACnB,CAAC,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import{n as e,t}from"./react.DJY1zw8Z.js";var n=e((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})),r=e(((e,t)=>{t.exports=n()})),i=t(),a=r(),o=(e,t)=>e!==null&&t!==null&&e.kind===t.kind&&(e.kind===`node`?e.id===t.id:e.path===t.path),s=({atlas:e,hovered:t,onSelect:n,selected:r})=>{let i=t??r,s=i!==null&&o(i,r);return(0,a.jsx)(`div`,{className:`detail`,children:i===null?(0,a.jsx)(c,{atlas:e,onSelect:n}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(`div`,{className:`pane-head`,children:[(0,a.jsx)(`span`,{className:`eyebrow`,children:i.kind}),s?(0,a.jsx)(`button`,{type:`button`,className:`small`,onClick:()=>{n(null)},children:`unpin`}):(0,a.jsx)(`span`,{className:`hint`,children:`click to pin`})]}),i.kind===`file`?(0,a.jsx)(d,{atlas:e,path:i.path,onSelect:n}):i.kind===`folder`?(0,a.jsx)(f,{atlas:e,path:i.path,onSelect:n}):(0,a.jsx)(m,{atlas:e,id:i.id,onSelect:n})]})})},c=({atlas:e,onSelect:t})=>{let n=e.violations.filter(e=>!e.baselined);return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`div`,{className:`pane-head`,children:(0,a.jsx)(`span`,{className:`eyebrow`,children:`repository`})}),(0,a.jsx)(`h2`,{className:`mono`,children:e.name}),(0,a.jsxs)(`p`,{className:`muted`,children:[e.files.filter(e=>e.walked).length,` files under `,e.roots.join(`, `),`,`,` `,e.edges.length,` edges, `,e.manifest.nodes.length,` nodes in `,e.manifest.path,e.manifest.files.length>1?` and ${String(e.manifest.files.length-1)} included file(s)`:``,`.`]}),(0,a.jsxs)(`dl`,{className:`facts`,children:[(0,a.jsx)(`dt`,{children:`violations`}),(0,a.jsxs)(`dd`,{className:n.length>0?`bad`:`good`,children:[n.length,e.violations.length>n.length?` (+${String(e.violations.length-n.length)} baselined)`:``]}),(0,a.jsx)(`dt`,{children:`unresolved`}),(0,a.jsx)(`dd`,{className:e.unresolved.length>0?`bad`:`good`,children:e.unresolved.length}),(0,a.jsx)(`dt`,{children:`cycles`}),(0,a.jsx)(`dd`,{className:e.cycles>0?`bad`:`good`,children:e.cycles})]}),(0,a.jsx)(`h3`,{children:`How to read it`}),(0,a.jsx)(`p`,{className:`muted`,children:`Hover a file: its imports come forward in the accent, its importers in ink, a refused edge in red, and the node that governs it lights up in the manifest. Hover a line of the manifest: every file that node governs lights up in the tree. Click either to keep it.`}),(0,a.jsx)(`h3`,{children:`Nodes`}),(0,a.jsx)(`ul`,{className:`list`,children:e.manifest.nodes.filter(e=>e.depth===0).map(e=>(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{t({kind:`node`,id:e.id})},children:e.path}),(0,a.jsxs)(`span`,{className:`muted`,children:[` `,e.files===0?``:`${String(e.files)} files`]})]},e.id))}),e.manifest.rules.length>0?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`Repository-wide rules`}),(0,a.jsx)(`ul`,{className:`list`,children:e.manifest.rules.map(e=>(0,a.jsxs)(`li`,{title:e.message,children:[(0,a.jsx)(`span`,{className:`family`,children:e.family}),` `,(0,a.jsx)(`span`,{className:`mono`,children:e.name})]},`${e.family}:${e.name}`))})]}):null,n.length>0?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`Violations`}),(0,a.jsxs)(`ul`,{className:`list`,children:[n.slice(0,40).map(e=>(0,a.jsxs)(`li`,{className:`violation`,children:[(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{t({kind:`file`,path:e.file})},children:e.file}),(0,a.jsx)(`div`,{className:`muted small`,children:e.message})]},e.fingerprint)),n.length>40?(0,a.jsxs)(`li`,{className:`muted`,children:[`… `,n.length-40,` more`]}):null]})]}):null]})},l=e=>e===`allowed`?`allowed`:e===`refused`?`refused`:`no allowlist`,u=({atlas:e,chain:t,onSelect:n})=>(0,a.jsxs)(`div`,{className:`crumbs`,children:[t.map((t,r)=>{let i=e.manifest.nodes.find(e=>e.id===t);return(0,a.jsxs)(`span`,{children:[r>0?(0,a.jsx)(`span`,{className:`muted`,children:` › `}):null,(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{n({kind:`node`,id:t})},title:i?.message??t,children:i?.key??t})]},t)}),t.length===0?(0,a.jsx)(`span`,{className:`muted`,children:`governed by no node`}):null]}),d=({atlas:e,onSelect:t,path:n})=>{let r=e.files.find(e=>e.path===n);if(r===void 0)return null;let i=r.node===null?null:e.manifest.nodes.find(e=>e.id===r.node),o=e.edges.filter(e=>e.from===n),s=e.edges.filter(e=>e.to===n),c=e.violations.filter(e=>e.file===n),d=e.unresolved.filter(e=>e.file===n),f=r.chain.map(t=>e.manifest.nodes.find(e=>e.id===t)).filter(e=>e!==void 0&&e.imports!==null);return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h2`,{className:`mono path`,children:r.path}),r.walked?null:(0,a.jsx)(`p`,{className:`muted`,children:`Outside the walk: reached from it, governed by nothing.`}),(0,a.jsx)(u,{atlas:e,chain:r.chain,onSelect:t}),i?.message!==null&&i?.message!==void 0?(0,a.jsx)(`p`,{className:`message`,children:i.message}):null,(0,a.jsx)(`h3`,{children:`May import`}),f.length===0?(0,a.jsx)(`p`,{className:`muted`,children:`anything — no node above this file states an allowlist`}):f.map(e=>(0,a.jsxs)(`div`,{className:`allowlist`,children:[(0,a.jsxs)(`div`,{className:`muted small`,children:[`from `,(0,a.jsx)(`span`,{className:`mono`,children:e.key}),e.imports?.reset===!0?` (reset)`:``,e.imports?.unrestricted===!0?` (unrestricted)`:``]}),(0,a.jsxs)(`ul`,{className:`chips`,children:[(e.imports?.allowances??[]).map(e=>(0,a.jsx)(`li`,{className:`chip ${e.kind} ${e.used?``:`slack`}`,title:e.used?e.kind===`external`?`a package`:e.expanded:`slack: no import uses this entry`,children:e.entry},`${e.kind}:${e.entry}`)),(e.imports?.deny??[]).map(e=>(0,a.jsxs)(`li`,{className:`chip deny`,title:e.message,children:[`deny `,e.match.join(` | `)]},e.message))]})]},e.id)),(0,a.jsx)(`h3`,{children:`Imports`}),o.length+r.externals.length+r.builtins.length===0?(0,a.jsx)(`p`,{className:`muted`,children:`nothing`}):(0,a.jsxs)(`ul`,{className:`list`,children:[o.map(e=>(0,a.jsxs)(`li`,{className:`edge-row ${e.status}`,children:[(0,a.jsx)(`span`,{className:`verdict ${e.status}`,children:e.status===`refused`?`✗`:`✓`}),(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{t({kind:`file`,path:e.to})},children:e.to}),(0,a.jsx)(`div`,{className:`muted small`,children:e.status===`refused`?e.refusedBy.map(e=>e.message).join(` `):e.admittedBy===null?l(e.status):`admitted by ${e.admittedBy.entry} on ${e.admittedBy.node}${e.admittedBy.fragment===null?``:` (via ${e.admittedBy.fragment})`}`})]},e.to)),r.externals.map(e=>(0,a.jsxs)(`li`,{className:`edge-row ${e.status}`,children:[(0,a.jsx)(`span`,{className:`verdict ${e.status}`,children:e.status===`refused`?`✗`:`✓`}),(0,a.jsx)(`span`,{className:`mono`,children:e.package}),(0,a.jsxs)(`span`,{className:`muted small`,children:[` external · `,e.specifiers.join(`, `)]}),(0,a.jsx)(`div`,{className:`muted small`,children:e.admittedBy===null?l(e.status):`admitted by ${e.admittedBy.entry} on ${e.admittedBy.node}`})]},e.package)),r.builtins.map(e=>(0,a.jsxs)(`li`,{className:`edge-row`,children:[(0,a.jsx)(`span`,{className:`verdict allowed`,children:`·`}),(0,a.jsx)(`span`,{className:`mono`,children:e}),(0,a.jsx)(`span`,{className:`muted small`,children:` builtin`})]},e)),d.map(e=>(0,a.jsxs)(`li`,{className:`edge-row refused`,children:[(0,a.jsx)(`span`,{className:`verdict refused`,children:`?`}),(0,a.jsx)(`span`,{className:`mono`,children:e.specifier}),(0,a.jsxs)(`div`,{className:`muted small`,children:[`unresolved: `,e.detail]})]},e.specifier))]}),(0,a.jsx)(`h3`,{children:`Imported by`}),s.length===0?(0,a.jsx)(`p`,{className:`muted`,children:`nothing in the walk`}):(0,a.jsx)(`ul`,{className:`list`,children:s.map(e=>(0,a.jsxs)(`li`,{className:`edge-row ${e.status}`,children:[(0,a.jsx)(`span`,{className:`verdict ${e.status}`,children:e.status===`refused`?`✗`:`✓`}),(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{t({kind:`file`,path:e.from})},children:e.from})]},e.from))}),r.requires.length>0?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`Owes`}),(0,a.jsx)(`ul`,{className:`list`,children:r.requires.map(e=>(0,a.jsxs)(`li`,{className:e.present?``:`bad`,children:[(0,a.jsx)(`span`,{className:`verdict ${e.present?`allowed`:`refused`}`,children:e.present?`✓`:`✗`}),(0,a.jsx)(`span`,{className:`mono`,children:e.sibling}),(0,a.jsxs)(`span`,{className:`muted small`,children:[` `,e.rule]})]},e.sibling))})]}):null,r.importRules.length>0?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`Import rules selecting it`}),(0,a.jsx)(`ul`,{className:`chips`,children:r.importRules.map(e=>(0,a.jsx)(`li`,{className:`chip rule mono`,children:e},e))})]}):null,(0,a.jsx)(`h3`,{children:`Violations`}),c.length===0?(0,a.jsx)(`p`,{className:`good`,children:`none`}):(0,a.jsx)(`ul`,{className:`list`,children:c.map(e=>(0,a.jsxs)(`li`,{className:`violation ${e.baselined?`baselined`:``}`,children:[(0,a.jsx)(`span`,{className:`family`,children:e.kind}),` `,e.message,e.baselined?(0,a.jsx)(`span`,{className:`muted small`,children:` (baselined)`}):null]},e.fingerprint))})]})},f=({atlas:e,onSelect:t,path:n})=>{let r=e.folders.find(e=>e.path===n);if(r===void 0)return null;let i=e.files.filter(e=>e.path.startsWith(`${n}/`)),o=i[0]?.chain.filter(t=>e.manifest.nodes.find(e=>e.id===t)?.folder===!0)??(r.node===null?[]:[r.node]),s=e.violations.filter(e=>e.file.startsWith(`${n}/`)),c=e.edges.filter(e=>e.from.startsWith(`${n}/`)&&!e.to.startsWith(`${n}/`)),l=e.edges.filter(e=>e.to.startsWith(`${n}/`)&&!e.from.startsWith(`${n}/`)),d=r.declares.map(t=>e.manifest.nodes.find(e=>e.id===t)).filter(e=>e!==void 0);return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(`h2`,{className:`mono path`,children:[r.path,`/`]}),(0,a.jsx)(u,{atlas:e,chain:o,onSelect:t}),d.map(e=>(0,a.jsxs)(`div`,{className:`declared`,children:[(0,a.jsxs)(`div`,{className:`muted small`,children:[`declares node `,(0,a.jsx)(`span`,{className:`mono`,children:e.path}),e.position===null?``:` · ${e.position.file}:${String(e.position.line)}`]}),e.message===null?null:(0,a.jsx)(`p`,{className:`message`,children:e.message})]},e.id)),(0,a.jsxs)(`dl`,{className:`facts`,children:[(0,a.jsx)(`dt`,{children:`files`}),(0,a.jsx)(`dd`,{children:i.length}),(0,a.jsx)(`dt`,{children:`edges out`}),(0,a.jsx)(`dd`,{children:c.length}),(0,a.jsx)(`dt`,{children:`edges in`}),(0,a.jsx)(`dd`,{children:l.length}),(0,a.jsx)(`dt`,{children:`violations`}),(0,a.jsx)(`dd`,{className:s.length>0?`bad`:`good`,children:s.length})]}),(0,a.jsx)(`h3`,{children:`Reaches`}),(0,a.jsxs)(`ul`,{className:`list`,children:[[...new Set(c.map(e=>p(e.to)))].sort().map(e=>(0,a.jsx)(`li`,{children:(0,a.jsxs)(`button`,{type:`button`,className:`link mono`,onClick:()=>{t({kind:`folder`,path:e})},children:[e,`/`]})},e)),c.length===0?(0,a.jsx)(`li`,{className:`muted`,children:`nothing outside itself`}):null]}),(0,a.jsx)(`h3`,{children:`Reached from`}),(0,a.jsxs)(`ul`,{className:`list`,children:[[...new Set(l.map(e=>p(e.from)))].sort().map(e=>(0,a.jsx)(`li`,{children:(0,a.jsxs)(`button`,{type:`button`,className:`link mono`,onClick:()=>{t({kind:`folder`,path:e})},children:[e,`/`]})},e)),l.length===0?(0,a.jsx)(`li`,{className:`muted`,children:`nothing outside itself`}):null]})]})},p=e=>e.slice(0,Math.max(0,e.lastIndexOf(`/`))),m=({atlas:e,id:t,onSelect:n})=>{let r=e.manifest.nodes.find(e=>e.id===t);if(r===void 0)return null;let i=[],o=r;for(;o!==void 0;)i.unshift(o.id),o=o.parent===null?void 0:e.manifest.nodes.find(e=>e.id===o?.parent);let s=e.files.filter(e=>e.chain.includes(t)),c=e.violations.filter(e=>r.rules.includes(e.rule));return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h2`,{className:`mono path`,children:r.path}),(0,a.jsx)(u,{atlas:e,chain:i,onSelect:n}),(0,a.jsxs)(`dl`,{className:`facts`,children:[(0,a.jsx)(`dt`,{children:`id`}),(0,a.jsx)(`dd`,{className:`mono`,children:r.id}),(0,a.jsx)(`dt`,{children:`kind`}),(0,a.jsxs)(`dd`,{children:[r.folder?`folder, layout ${r.layout}`:`file`,r.partial?`, partial`:``]}),(0,a.jsx)(`dt`,{children:`written at`}),(0,a.jsx)(`dd`,{className:`mono`,children:r.position===null?`—`:`${r.position.file}:${String(r.position.line)}`}),(0,a.jsx)(`dt`,{children:`governs`}),(0,a.jsxs)(`dd`,{children:[s.length,` files`]})]}),r.message===null?null:(0,a.jsx)(`p`,{className:`message`,children:r.message}),r.imports===null?null:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`imports`}),r.imports.message===null?null:(0,a.jsx)(`p`,{className:`muted small`,children:r.imports.message}),(0,a.jsxs)(`ul`,{className:`chips`,children:[r.imports.allowances.map(e=>(0,a.jsx)(`li`,{className:`chip ${e.kind} ${e.used?``:`slack`}`,title:e.used?e.expanded:`slack: no import uses this entry`,children:e.entry},`${e.kind}:${e.entry}`)),r.imports.deny.map(e=>(0,a.jsxs)(`li`,{className:`chip deny`,title:e.message,children:[`deny `,e.match.join(` | `)]},e.message))]}),r.imports.reset?(0,a.jsx)(`p`,{className:`muted small`,children:`reset: inherits no allowance`}):null,r.imports.unrestricted?(0,a.jsx)(`p`,{className:`muted small`,children:`unrestricted: no allowlist yet`}):null]}),r.importedBy===null?null:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`importedBy`}),(0,a.jsx)(`p`,{className:`muted small`,children:r.importedBy.message}),(0,a.jsx)(`ul`,{className:`chips`,children:r.importedBy.allow.map(e=>(0,a.jsx)(`li`,{className:`chip allow`,children:e},e))})]}),r.members.length>0?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`members`}),(0,a.jsx)(`ul`,{className:`list`,children:r.members.map((e,t)=>(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`span`,{className:`family`,children:e.subject}),` `,e.message]},t))})]}):null,r.surface.length>0?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`surface`}),(0,a.jsx)(`ul`,{className:`list`,children:r.surface.map((e,t)=>(0,a.jsx)(`li`,{children:e.message},t))})]}):null,r.requires.length>0?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`requires`}),(0,a.jsx)(`ul`,{className:`chips`,children:r.requires.map(e=>(0,a.jsx)(`li`,{className:`chip`,children:e},e))})]}):null,(0,a.jsx)(`h3`,{children:`Rules lowered from it`}),(0,a.jsxs)(`ul`,{className:`chips`,children:[r.rules.map(e=>(0,a.jsx)(`li`,{className:`chip rule mono`,children:e},e)),r.rules.length===0?(0,a.jsx)(`li`,{className:`muted`,children:`none`}):null]}),(0,a.jsx)(`h3`,{children:`Violations of its rules`}),c.length===0?(0,a.jsx)(`p`,{className:`good`,children:`none`}):(0,a.jsx)(`ul`,{className:`list`,children:c.map(e=>(0,a.jsxs)(`li`,{className:`violation`,children:[(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{n({kind:`file`,path:e.file})},children:e.file}),(0,a.jsx)(`div`,{className:`muted small`,children:e.message})]},e.fingerprint))}),s.length>0?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`Files`}),(0,a.jsxs)(`ul`,{className:`list compact`,children:[s.slice(0,60).map(e=>(0,a.jsx)(`li`,{children:(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{n({kind:`file`,path:e.path})},children:e.path})},e.path)),s.length>60?(0,a.jsxs)(`li`,{className:`muted`,children:[`… `,s.length-60,` more`]}):null]})]}):null]})},h=(e,t,n)=>{let r=e.filter(e=>e.position?.file===t).map(e=>({node:e,line:e.position?.line??0})).sort((e,t)=>e.line===t.line?e.node.depth-t.node.depth:e.line-t.line);return r.map((e,t)=>{let i=r.slice(t+1).find(t=>t.line>e.line);return{node:e.node,line:e.line,end:i===void 0?n:i.line-1}})},g=e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),_=({activeNode:e,atlas:t,chain:n,onHoverNode:r,onSelectNode:o,scrollTo:s,selectedNode:c})=>{let l=t.manifest.files,[u,d]=(0,i.useState)(l[0]?.path??``),f=s?.file??null;(0,i.useEffect)(()=>{f!==null&&l.some(e=>e.path===f)&&d(f)},[f,l]),(0,i.useEffect)(()=>{l.some(e=>e.path===u)||d(l[0]?.path??``)},[l,u]);let p=l.find(e=>e.path===u)??l[0],m=(0,i.useMemo)(()=>p===void 0?[]:p.text.split(`
|
|
2
|
+
`),[p]),_=(0,i.useMemo)(()=>p===void 0?[]:h(t.manifest.nodes,p.path,m.length),[p,t,m.length]),v=(0,i.useMemo)(()=>new Map(_.map(e=>[e.line,e])),[_]),y=_.find(t=>t.node.id===e)??null,b=(0,i.useMemo)(()=>new Set(_.filter(e=>n.includes(e.node.id)).map(e=>e.line)),[_,n]),x=(0,i.useMemo)(()=>{let e=new Map;for(let t of _){let n=(t.node.imports?.allowances??[]).filter(e=>!e.used);if(n.length!==0)for(let r=t.line;r<=t.end;r+=1){let t=m[r-1]??``;for(let i of n)RegExp(`(^|[\\s\\[,"'])${g(i.entry)}(["',\\]\\s]|$)`).test(t)&&e.set(r,i.entry)}}return e},[_,m]),S=(0,i.useRef)(null),C=s!==null&&s.file===p?.path?s.line:null;(0,i.useEffect)(()=>{C!==null&&S.current!==null&&S.current.querySelector(`[data-line="${String(C)}"]`)?.scrollIntoView({block:`center`,behavior:`smooth`})},[C,u]);let w=e=>{let t=null;for(let n of _)n.line<=e&&(t===null||n.line>=t.line)&&(t=n);return t?.node??null};return(0,a.jsxs)(`div`,{className:`manifest`,onMouseLeave:()=>{r(null)},children:[(0,a.jsx)(`div`,{className:`pane-head tabs-row`,children:l.map(e=>(0,a.jsx)(`button`,{type:`button`,className:e.path===p?.path?`tab active`:`tab`,onClick:()=>{d(e.path)},title:e.path,children:e.path.split(`/`).slice(-2).join(`/`)},e.path))}),(0,a.jsx)(`ol`,{className:`source`,ref:S,children:m.map((e,t)=>{let n=t+1,i=v.get(n),s=[`line`];i!==void 0&&s.push(`anchor`),y!==null&&n>=y.line&&n<=y.end&&s.push(`own`),b.has(n)&&s.push(`chain`),i?.node.id===c&&s.push(`selected`);let l=x.get(n);return l!==void 0&&s.push(`slack`),(0,a.jsxs)(`li`,{"data-line":n,className:s.join(` `),onMouseEnter:()=>{r(w(n)?.id??null)},onClick:()=>{let e=w(n);o(e===null?null:e.id)},title:l===void 0?i===void 0?void 0:`${i.node.id} — ${String(i.node.files)} file(s) governed`:`No import uses "${l}": this allowance is slack.`,children:[(0,a.jsx)(`span`,{className:`ln`,children:n}),(0,a.jsx)(`span`,{className:`code`,children:e===``?` `:e}),i===void 0?null:(0,a.jsx)(`span`,{className:`node-tag`,children:i.node.id})]},n)})})]})},v=e=>{let t=e.lastIndexOf(`/`);return t===-1?``:e.slice(0,t)},y=e=>{let t=new Map;for(let n of e.folders){let e=n.parent??``,r=t.get(e)??[];r.push(n),t.set(e,r)}let n=new Map,r=new Map,i=new Map;for(let t of e.files){let e=n.get(t.folder)??[];e.push(t),n.set(t.folder,e);let a=t.folder;for(;a!==``;)r.set(a,(r.get(a)??0)+1),i.set(a,(i.get(a)??0)+t.violations),a=v(a)}for(let e of t.values())e.sort((e,t)=>e.name.localeCompare(t.name));for(let e of n.values())e.sort((e,t)=>e.name.localeCompare(t.name));return{folders:t,files:n,filesUnder:r,violationsUnder:i}},b=(e,t)=>{let n=y(e),r=[],i=(e,a)=>{for(let o of n.folders.get(e)??[]){let e=t.has(o.path);r.push({kind:`folder`,path:o.path,name:o.name,depth:a,expanded:e,folder:o,files:n.filesUnder.get(o.path)??0,violations:n.violationsUnder.get(o.path)??0}),e&&i(o.path,a+1)}for(let t of n.files.get(e)??[])r.push({kind:`file`,path:t.path,name:t.name,depth:a,file:t})};return i(``,0),r},x=(e,t)=>{let n=new Map(e.map((e,t)=>[e.path,t]));return e=>{let r=e;for(;r!==``;){let i=n.get(r);if(i!==void 0&&(r===e||!t.has(r)))return i;r=v(r)}return-1}},S=(e,t,n)=>{let r=x(t,n),i=new Map;for(let t of e.edges){let e=r(t.from),n=r(t.to);if(e===-1||n===-1||e===n)continue;let a=`${String(e)}>${String(n)}`,o=i.get(a);o===void 0?i.set(a,{from:e,to:n,edges:[t]}):o.edges.push(t)}return[...i.values()].map(e=>({...e,refused:e.edges.some(e=>e.status===`refused`)}))},C=e=>{let t=e.files.length<=600;return new Set(e.folders.filter(e=>t||e.depth<2).map(e=>e.path))},w=(e,t,n)=>{let r=new Map;if(t===null)return r;let i=e=>n?e.startsWith(`${t}/`):e===t;r.set(t,`focus`);for(let t of e.edges){let e=i(t.from),a=i(t.to);e&&a?n&&(r.set(t.from,`within`),r.set(t.to,`within`)):e&&!r.has(t.to)?r.set(t.to,`dep`):a&&!r.has(t.from)&&r.set(t.from,`importer`)}if(!n){let n=e.files.find(e=>e.path===t);for(let e of n?.requires??[])r.has(e.sibling)||r.set(e.sibling,`sibling`)}return r},T=150,E=(e,t,n)=>{if(t===null)return`dim`;let r=e=>n?e===t||e.startsWith(`${t}/`):e===t,i=!1,a=!1,o=!1;for(let t of e.edges){let e=r(t.from),n=r(t.to);e&&n?o=!0:e?i=!0:n&&(a=!0)}return i?`out`:a?`in`:o?`within`:`dim`},D={dim:0,within:1,in:2,out:3},O=(e,t)=>{let n=e*24+12,r=t*24+12,i=Math.abs(e-t),a=Math.min(138,18+i*5);return`M6 ${String(n)} C ${String(6+a)} ${String(n)}, ${String(6+a)} ${String(r)}, 10 ${String(r)}`},k=(e,t)=>{let n=t.get(e.path);if(n!==void 0)return n;if(e.kind===`folder`&&!e.expanded){let n=null;for(let[r,i]of t)if(r.startsWith(`${e.path}/`)){if(i===`dep`||i===`importer`)return i;n??=i}return n}return null},A=(e,t)=>t!==null&&(e.kind===`file`?e.file.chain.includes(t):e.folder.node===t||e.folder.declares.includes(t)),j=({arcs:e,focus:t,focusIsFolder:n,governedBy:r,onHover:i,onSelect:o,onToggle:s,relations:c,rows:l,selected:u})=>{let d=Math.max(l.length,1)*24,f=e.map(e=>({arc:e,kind:E(e,t,n)})).sort((e,t)=>D[e.kind]-D[t.kind]);return(0,a.jsxs)(`div`,{className:`tree`,onMouseLeave:()=>{i(null)},children:[(0,a.jsx)(`ol`,{className:`rows`,style:{height:d},children:l.map(e=>{let t=k(e,c),n=[`row`,e.kind];t!==null&&n.push(t),A(e,r)&&n.push(`governed`),u===e.path&&n.push(`selected`);let l=e.kind===`file`?e.file.violations:e.violations;return(0,a.jsxs)(`li`,{className:n.join(` `),style:{paddingLeft:8+e.depth*14,height:24},onMouseEnter:()=>{i(e.path)},onClick:()=>{o(e)},title:e.path,children:[e.kind===`folder`?(0,a.jsx)(`button`,{type:`button`,className:`chevron`,"aria-label":e.expanded?`collapse`:`expand`,onClick:t=>{t.stopPropagation(),s(e.path)},children:e.expanded?`▾`:`▸`}):(0,a.jsx)(`span`,{className:`chevron spacer`}),(0,a.jsxs)(`span`,{className:`name ${e.kind===`file`&&!e.file.walked?`outside`:``}`,children:[e.name,e.kind===`folder`?`/`:``]}),e.kind===`folder`&&e.folder.declares.length>0?(0,a.jsx)(`span`,{className:`node-mark`,title:`node: ${e.folder.declares.join(`, `)}`,children:`§`}):null,e.kind===`folder`&&!e.expanded?(0,a.jsx)(`span`,{className:`meta`,children:e.files}):null,l>0?(0,a.jsx)(`span`,{className:`badge refused`,title:`${String(l)} violation(s)`,children:l}):null]},e.path)})}),(0,a.jsxs)(`svg`,{className:`arcs`,width:T,height:d,viewBox:`0 0 ${String(T)} ${String(d)}`,"aria-hidden":`true`,children:[(0,a.jsx)(`defs`,{children:[`dim`,`within`,`in`,`out`,`refused`].map(e=>(0,a.jsx)(`marker`,{id:`head-${e}`,viewBox:`0 0 10 10`,refX:`9`,refY:`5`,markerWidth:`6`,markerHeight:`6`,orient:`auto-start-reverse`,children:(0,a.jsx)(`path`,{d:`M0,0 L10,5 L0,10 z`,className:`head ${e}`})},e))}),f.map(({arc:e,kind:t})=>{let n=e.refused&&t!==`dim`?`refused`:t;return(0,a.jsx)(`path`,{d:O(e.from,e.to),className:`arc ${t} ${e.refused?`refused`:``}`,markerEnd:`url(#head-${n})`,children:(0,a.jsx)(`title`,{children:M(e.edges)})},`${String(e.from)}>${String(e.to)}`)})]})]})},M=e=>e.slice(0,6).map(e=>`${e.from} → ${e.to}${e.status===`refused`?` (refused)`:``}`).join(`
|
|
3
|
+
`)+(e.length>6?`\n… ${String(e.length-6)} more`:``),ee=(e,t)=>t===null?null:t.startsWith(`node:`)?{kind:`node`,id:t.slice(5)}:e.files.some(e=>e.path===t)?{kind:`file`,path:t}:e.folders.some(e=>e.path===t)?{kind:`folder`,path:t}:null,te=e=>e===null?null:e.kind===`node`?`node:${e.id}`:e.path,N=({atlas:e,onSelect:t,selection:n})=>{let[r,o]=(0,i.useState)(()=>C(e)),[c,l]=(0,i.useState)(``),[u,d]=(0,i.useState)(null),[f,p]=(0,i.useState)(null);(0,i.useEffect)(()=>{o(t=>{let n=new Set(t),r=new Set(e.folders.map(e=>e.path));for(let r of C(e))t.has(r)||n.add(r);for(let e of t)r.has(e)||n.delete(e);return n})},[e]);let m=(0,i.useMemo)(()=>ee(e,n),[e,n]),h=(0,i.useMemo)(()=>new Map(e.manifest.nodes.map(e=>[e.id,e])),[e]),g=(0,i.useMemo)(()=>new Map(e.files.map(e=>[e.path,e])),[e]),v=(0,i.useMemo)(()=>new Map(e.folders.map(e=>[e.path,e])),[e]),y=(0,i.useMemo)(()=>{if(c.trim()===``)return null;let t=c.trim().toLowerCase(),n=new Set;for(let r of e.files){if(!r.path.toLowerCase().includes(t))continue;n.add(r.path);let e=r.folder;for(;e!==``;)n.add(e),e=e.slice(0,Math.max(0,e.lastIndexOf(`/`)))}return n},[e,c]),x=(0,i.useMemo)(()=>y===null?r:new Set([...y].filter(e=>v.has(e))),[r,y,v]),T=(0,i.useMemo)(()=>{let t=b(e,x);return y===null?t:t.filter(e=>y.has(e.path))},[e,x,y]),E=(0,i.useMemo)(()=>S(e,T,x),[e,T,x]),D=u??(m!==null&&m.kind!==`node`?m.path:null),O=D!==null&&v.has(D),k=(0,i.useMemo)(()=>w(e,D,O),[e,D,O]),A=(()=>{let e=f??(m?.kind===`node`?m.id:D===null?null:g.get(D)?.node??v.get(D)?.node??null);return e===null?null:h.get(e)??null})(),M=D===null?A===null?[]:P(h,A):g.get(D)?.chain??(A===null?[]:P(h,A)),N=f??(m?.kind===`node`?m.id:null),I=A?.position??null,L=e=>{t(te(e))};return(0,a.jsxs)(`div`,{className:`arch`,children:[(0,a.jsxs)(`section`,{className:`pane tree-pane`,"aria-label":`Repository tree`,children:[(0,a.jsxs)(`div`,{className:`pane-head`,children:[(0,a.jsx)(`input`,{className:`filter`,type:`search`,placeholder:`filter files…`,value:c,onChange:e=>{l(e.target.value)}}),(0,a.jsx)(`button`,{type:`button`,className:`small`,onClick:()=>{o(new Set(e.folders.map(e=>e.path)))},children:`expand`}),(0,a.jsx)(`button`,{type:`button`,className:`small`,onClick:()=>{o(new Set)},children:`collapse`})]}),(0,a.jsx)(j,{rows:T,arcs:E,focus:D,focusIsFolder:O,relations:k,governedBy:N,selected:m!==null&&m.kind!==`node`?m.path:null,onHover:d,onToggle:e=>{o(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},onSelect:e=>{L(e.kind===`folder`?{kind:`folder`,path:e.path}:{kind:`file`,path:e.path})}}),(0,a.jsx)(F,{})]}),(0,a.jsx)(`section`,{className:`pane manifest-pane`,"aria-label":`architecture.yaml`,children:(0,a.jsx)(_,{atlas:e,activeNode:A?.id??null,chain:M,scrollTo:I,selectedNode:m?.kind===`node`?m.id:null,onHoverNode:p,onSelectNode:e=>{L(e===null?null:{kind:`node`,id:e})}})}),(0,a.jsx)(`section`,{className:`pane detail-pane`,"aria-label":`Details`,children:(0,a.jsx)(s,{atlas:e,selected:m,hovered:u===null?f===null?null:{kind:`node`,id:f}:v.has(u)?{kind:`folder`,path:u}:{kind:`file`,path:u},onSelect:L})})]})},P=(e,t)=>{let n=[],r=t;for(;r!==void 0;)n.unshift(r.id),r=r.parent===null?void 0:e.get(r.parent);return n},F=()=>(0,a.jsxs)(`div`,{className:`legend`,children:[(0,a.jsx)(`span`,{className:`key out`,children:`imports`}),(0,a.jsx)(`span`,{className:`key in`,children:`imported by`}),(0,a.jsx)(`span`,{className:`key refused`,children:`refused`}),(0,a.jsx)(`span`,{className:`key sibling`,children:`owed sibling`}),(0,a.jsx)(`span`,{className:`key governed`,children:`governed by node`})]}),I=e=>`${String(Math.round(e*100))}%`,L=e=>{if(e===null)return`—`;let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleDateString()},R=e=>e===null?``:`${e.file}:${String(e.line)}`,ne=({campaign:e,onPick:t,pinned:n,shown:r,view:i})=>(0,a.jsxs)(`div`,{className:`detail`,children:[(0,a.jsxs)(`div`,{className:`pane-head`,children:[(0,a.jsx)(`span`,{className:`eyebrow`,children:r.kind}),n?(0,a.jsx)(`button`,{type:`button`,className:`small`,onClick:()=>{t(null)},children:`unpin`}):r.kind===`campaign`?null:(0,a.jsx)(`span`,{className:`hint`,children:`click to pin`})]}),r.kind===`campaign`?(0,a.jsx)(z,{view:i,campaign:e,onPick:t}):r.kind===`phase`?(0,a.jsx)(re,{campaign:e,id:r.id,onPick:t}):r.kind===`objective`?(0,a.jsx)(ie,{campaign:e,id:r.id,onPick:t}):(0,a.jsx)(ae,{view:i,campaign:e,name:r.name,onPick:t})]}),z=({campaign:e,onPick:t,view:n})=>{let r=n.nudge?.sectors.filter(t=>t.campaign===e.id)??[];return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h2`,{children:e.title??e.id}),(0,a.jsxs)(`p`,{className:`muted small mono`,children:[e.id,e.position===null?``:` · ${R(e.position)}`]}),e.why===null?null:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`Why`}),(0,a.jsx)(`p`,{className:`message`,children:e.why})]}),e.how===null?null:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`How`}),(0,a.jsx)(`p`,{className:`message`,children:e.how})]}),(0,a.jsxs)(`dl`,{className:`facts`,children:[(0,a.jsx)(`dt`,{children:`progress`}),(0,a.jsx)(`dd`,{children:I(e.progress)}),(0,a.jsx)(`dt`,{children:`holdouts left`}),(0,a.jsx)(`dd`,{children:e.count}),(0,a.jsx)(`dt`,{children:`owner`}),(0,a.jsx)(`dd`,{children:e.owner??`—`}),(0,a.jsx)(`dt`,{children:`scope`}),(0,a.jsx)(`dd`,{className:`mono`,children:e.scope.join(`, `)}),(0,a.jsx)(`dt`,{children:`perimeter`}),(0,a.jsx)(`dd`,{children:e.perimeter??`none: the scope is the one sector`}),(0,a.jsx)(`dt`,{children:`stale after`}),(0,a.jsx)(`dd`,{children:e.staleAfterDays===null?`never`:`${String(e.staleAfterDays)} days`}),(0,a.jsx)(`dt`,{children:`on completion`}),(0,a.jsx)(`dd`,{children:e.onComplete}),(0,a.jsx)(`dt`,{children:`ledgers`}),(0,a.jsx)(`dd`,{className:e.ledgered?`good`:`bad`,children:e.ledgered?`every objective, under ${n.ledgerDir}/${e.id}/`:"missing: run `architecture objectives clear`"}),(0,a.jsx)(`dt`,{children:`arithmetic`}),(0,a.jsx)(`dd`,{className:e.arithmetic?`good`:`bad`,children:e.arithmetic?`holds`:`does not hold`}),(0,a.jsx)(`dt`,{children:`legacy`}),(0,a.jsxs)(`dd`,{children:[e.legacy.files,` file`,e.legacy.files===1?``:`s`,` no sector claims`,e.legacy.holdouts>0?`, ${String(e.legacy.holdouts)} holdouts`:``]})]}),e.plan.changed.length+e.plan.unreceipted.length+e.plan.refined.length>0?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`Plan`}),(0,a.jsxs)(`ul`,{className:`list`,children:[e.plan.unreceipted.map(e=>(0,a.jsxs)(`li`,{className:`bad`,children:[`phase `,(0,a.jsx)(`span`,{className:`mono`,children:e}),` changed without a concession`]},`u:${e}`)),e.plan.changed.map(e=>(0,a.jsxs)(`li`,{children:[`phase `,(0,a.jsx)(`span`,{className:`mono`,children:e}),` changed, with its receipt`]},`c:${e}`)),e.plan.refined.map(e=>(0,a.jsxs)(`li`,{children:[`open phase refined into `,(0,a.jsx)(`span`,{className:`mono`,children:e})]},`r:${e}`))]})]}):null,e.drift.length>0?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`Drift`}),(0,a.jsx)(`ul`,{className:`list`,children:e.drift.map(e=>(0,a.jsxs)(`li`,{className:`bad`,children:[(0,a.jsx)(`span`,{className:`mono`,children:e.file}),` is claimed by `,e.sectors.join(` and `)]},e.file))})]}):null,(0,a.jsx)(`h3`,{children:`Objectives`}),(0,a.jsx)(`ul`,{className:`list`,children:e.objectives.map(e=>(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{t({kind:`objective`,id:e.id})},children:e.id}),(0,a.jsxs)(`span`,{className:`muted small`,children:[` `,e.measure===null?`${String(e.count)} left · ${I(e.progress)}`:`${String(e.measure.value??`?`)} ${e.measure.direction===`down`?`↓`:`↑`} ${e.measure.target===null?``:`target ${String(e.measure.target)}`}`,e.phase===null?``:` · ${e.phase}`]})]},e.id))}),(0,a.jsx)(`h3`,{children:`Sectors`}),(0,a.jsx)(`ul`,{className:`list compact`,children:e.sectors.map(e=>(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{t({kind:`sector`,name:e.name})},children:e.name}),(0,a.jsxs)(`span`,{className:`muted small`,children:[` `,e.done?`done`:e.phaseId===null?``:`at ${e.phaseId}`,e.stalled?` · stalled`:``]})]},e.name))}),n.nudge===null?null:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`Working tree`}),n.nudge.touched.length===0?(0,a.jsx)(`p`,{className:`muted`,children:`No uncommitted change touches the scope.`}):r.length===0?(0,a.jsxs)(`p`,{className:`muted`,children:[n.nudge.touched.length,` file(s) changed, none in a sector of this campaign.`]}):(0,a.jsx)(`ul`,{className:`list`,children:r.map(e=>(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{t({kind:`sector`,name:e.sector})},children:e.sector}),` `,(0,a.jsx)(B,{nudge:e})]},e.sector))})]})]})},B=({nudge:e})=>(0,a.jsxs)(`span`,{className:`flag ${e.verdict===`ok`?`good`:e.verdict===`back`?`bad`:`warn`}`,children:[e.verdict,e.ask===`none`?``:` · ${e.ask}`]}),re=({campaign:e,id:t,onPick:n})=>{let r=e.phases.find(e=>e.id===t);if(r===void 0)return null;let i=e.sectors.filter(e=>e.phase===r.index&&!e.done);return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h2`,{className:`mono`,children:r.id}),(0,a.jsxs)(`p`,{className:`muted small`,children:[`phase `,r.index+1,` of `,e.phases.length,r.defined?`, defined`:`, open`,r.attested?`, attested`:``,r.position===null?``:` · ${R(r.position)}`]}),r.intent===null?null:(0,a.jsxs)(`p`,{className:`message`,children:[`“`,r.intent,`”`]}),r.defined?null:(0,a.jsx)(`p`,{className:`muted`,children:`An open phase carries intent only. It is refined into defined phases as sectors reach it and the next step becomes clear.`}),r.concessions>0?(0,a.jsxs)(`p`,{className:`muted small`,children:[r.concessions,` recorded change`,r.concessions===1?``:`s`,` to this phase.`]}):null,(0,a.jsx)(`h3`,{children:`Objectives`}),(0,a.jsxs)(`ul`,{className:`list`,children:[r.objectives.map(t=>{let r=e.objectives.find(e=>e.id===t);return(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{n({kind:`objective`,id:t})},children:t}),r===void 0?null:(0,a.jsxs)(`span`,{className:`muted small`,children:[` `,r.count,` left · `,I(r.progress)]})]},t)}),r.objectives.length===0?(0,a.jsx)(`li`,{className:`muted`,children:`none`}):null]}),(0,a.jsx)(`h3`,{children:`Sectors standing here`}),(0,a.jsxs)(`ul`,{className:`list compact`,children:[i.map(e=>(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{n({kind:`sector`,name:e.name})},children:e.name}),(0,a.jsxs)(`span`,{className:`muted small`,children:[` `,Object.entries(e.residue).filter(([e])=>r.objectives.includes(e)).map(([e,t])=>`${e}: ${String(t)}`).join(`, `)]})]},e.name)),i.length===0?(0,a.jsx)(`li`,{className:`muted`,children:`none`}):null]})]})},ie=({campaign:e,id:t,onPick:n})=>{let r=e.objectives.find(e=>e.id===t);if(r===void 0)return null;let i=r.measure;return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h2`,{className:`mono`,children:r.id}),(0,a.jsxs)(`p`,{className:`muted small`,children:[`holdout: `,r.holdout,r.phase===null?` · in window everywhere`:` · phase ${r.phase}`,r.position===null?``:` · ${R(r.position)}`]}),(0,a.jsx)(`p`,{className:`message`,children:r.why??r.message}),i===null?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`div`,{className:`progress`,title:`${I(r.progress)} of the initial holdouts cleared`,children:(0,a.jsx)(`div`,{className:`progress-bar`,style:{width:I(r.progress)}})}),(0,a.jsxs)(`dl`,{className:`facts`,children:[(0,a.jsx)(`dt`,{children:`left`}),(0,a.jsx)(`dd`,{className:r.count===0?`good`:``,children:r.count}),(0,a.jsx)(`dt`,{children:`initial`}),(0,a.jsxs)(`dd`,{children:[r.initial,r.allowed>0?` +${String(r.allowed)} conceded`:``]}),(0,a.jsx)(`dt`,{children:`cleared`}),(0,a.jsx)(`dd`,{children:r.cleared}),(0,a.jsx)(`dt`,{children:`closed`}),(0,a.jsx)(`dd`,{children:r.closed}),(0,a.jsx)(`dt`,{children:`last cleared`}),(0,a.jsx)(`dd`,{children:L(r.lastCleared)}),(0,a.jsx)(`dt`,{children:`concessions`}),(0,a.jsx)(`dd`,{children:r.concessions}),(0,a.jsx)(`dt`,{children:`ledger`}),(0,a.jsx)(`dd`,{className:r.ledgered?`good`:`bad`,children:r.ledgered?`present`:`missing`})]})]}):(0,a.jsxs)(`dl`,{className:`facts`,children:[(0,a.jsx)(`dt`,{children:`now`}),(0,a.jsx)(`dd`,{children:i.value??`unmeasured`}),(0,a.jsx)(`dt`,{children:`recorded`}),(0,a.jsx)(`dd`,{children:i.recorded??`not yet`}),(0,a.jsx)(`dt`,{children:`target`}),(0,a.jsx)(`dd`,{children:i.target??`standing: only ratchets`}),(0,a.jsx)(`dt`,{children:`direction`}),(0,a.jsx)(`dd`,{children:i.direction===`down`?`lower is better`:`higher is better`}),(0,a.jsx)(`dt`,{children:`tolerance`}),(0,a.jsx)(`dd`,{children:i.tolerance}),(0,a.jsx)(`dt`,{children:`progress`}),(0,a.jsx)(`dd`,{children:I(r.progress)}),(0,a.jsx)(`dt`,{children:`ledger`}),(0,a.jsx)(`dd`,{className:r.ledgered?`good`:`bad`,children:r.ledgered?`present`:`missing`})]}),(0,a.jsx)(`h3`,{children:`By sector`}),r.sectors.length===0?(0,a.jsx)(`p`,{className:`muted`,children:`no sector is in this objective's window`}):null,r.sectors.map(e=>(0,a.jsxs)(`div`,{className:`sector-block`,children:[(0,a.jsxs)(`div`,{className:`sector-row`,children:[(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{n({kind:`sector`,name:e.sector})},children:e.sector}),(0,a.jsxs)(`span`,{className:`muted small`,children:[` `,e.measure===null?`${String(e.count)} left`:`${String(e.measure.value??`?`)} now, ${String(e.measure.recorded??`?`)} recorded, ${e.measure.standing}`,e.unrecorded?` · unrecorded`:``,e.initial===null?``:` · ${String(e.initial)} initially, ${String(e.cleared??0)} cleared`]})]}),e.new.length>0?(0,a.jsx)(`ul`,{className:`list compact`,children:e.new.map(e=>(0,a.jsxs)(`li`,{className:`bad mono small`,children:[`+ `,e,` `,(0,a.jsx)(`span`,{className:`muted`,children:`(not in the ledger)`})]},`new:${e}`))}):null,e.stale.length>0?(0,a.jsx)(`ul`,{className:`list compact`,children:e.stale.map(e=>(0,a.jsxs)(`li`,{className:`good mono small`,children:[`− `,e,` `,(0,a.jsx)(`span`,{className:`muted`,children:"(cleared, run `objectives clear`)"})]},`stale:${e}`))}):null,e.holdouts.length>0?(0,a.jsxs)(`details`,{children:[(0,a.jsxs)(`summary`,{className:`muted small`,children:[e.holdouts.length,` in the ledger`]}),(0,a.jsx)(`ul`,{className:`list compact`,children:e.holdouts.map(e=>(0,a.jsx)(`li`,{className:`mono small`,children:e},e))})]}):null]},e.sector))]})},ae=({campaign:e,name:t,onPick:n,view:r})=>{let i=e.sectors.find(e=>e.name===t);if(i===void 0)return null;let o=r.nudge?.sectors.find(n=>n.campaign===e.id&&n.sector===t);return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(`h2`,{className:`mono`,children:[i.name,i.legacy?(0,a.jsx)(`span`,{className:`flag warn`,children:`legacy`}):null,i.done?(0,a.jsx)(`span`,{className:`flag good`,children:`done`}):null,i.stalled?(0,a.jsx)(`span`,{className:`flag bad`,children:`stalled`}):null]}),i.legacy?(0,a.jsx)(`p`,{className:`muted`,children:`What no sector has claimed. It stands at the first phase.`}):null,(0,a.jsxs)(`dl`,{className:`facts`,children:[(0,a.jsx)(`dt`,{children:`phase`}),(0,a.jsx)(`dd`,{children:i.done?`end state`:i.phaseId??(e.phases.length===0?`standing`:`—`)}),(0,a.jsx)(`dt`,{children:`reached`}),(0,a.jsxs)(`dd`,{children:[i.reached??"not placed by `clear` yet",i.since===null?``:` since ${L(i.since)}`]}),(0,a.jsx)(`dt`,{children:`files`}),(0,a.jsx)(`dd`,{children:i.files.length}),i.marker===null?null:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`dt`,{children:`marker`}),(0,a.jsx)(`dd`,{className:`mono`,children:i.marker})]}),(0,a.jsx)(`dt`,{children:`roots`}),(0,a.jsx)(`dd`,{className:`mono`,children:i.roots.length===0?`—`:i.roots.join(`, `)})]}),(0,a.jsx)(`h3`,{children:`Residue`}),(0,a.jsx)(`ul`,{className:`list`,children:e.objectives.map(e=>{let t=i.residue[e.id]??i.counts[e.id],r=i.values[e.id];return(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`button`,{type:`button`,className:`link mono`,onClick:()=>{n({kind:`objective`,id:e.id})},children:e.id}),(0,a.jsxs)(`span`,{className:`muted small ${(t??0)>0?``:`good`}`,children:[` `,e.measure===null?t===void 0?`not in window`:`${String(t)} left`:r===void 0?`unmeasured`:`${String(r)}${e.measure.target===null?``:` → ${String(e.measure.target)}`}`]})]},e.id)})}),o===void 0?null:(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`Working tree`}),(0,a.jsxs)(`p`,{children:[(0,a.jsx)(B,{nudge:o}),` `,(0,a.jsxs)(`span`,{className:`muted small`,children:[`direction `,o.direction,` · onTouch `,o.onTouch]})]}),o.holdouts.shown.length>0?(0,a.jsxs)(`ul`,{className:`list compact`,children:[o.holdouts.shown.map(e=>(0,a.jsxs)(`li`,{className:`small`,children:[(0,a.jsxs)(`span`,{className:`mono`,children:[e.file,e.line===null?``:`:${String(e.line)}`]}),(0,a.jsx)(`div`,{className:`muted`,children:e.message})]},`${e.file}:${e.subject??``}`)),o.holdouts.total>o.holdouts.shown.length?(0,a.jsxs)(`li`,{className:`muted small`,children:[`… `,o.holdouts.total-o.holdouts.shown.length,` more`]}):null]}):null,o.belongsInSector.length>0?(0,a.jsxs)(`p`,{className:`bad small`,children:[`Added inside the scope, in no sector: `,o.belongsInSector.join(`, `)]}):null]}),i.attested.length>0?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`Attestations`}),(0,a.jsx)(`ul`,{className:`list`,children:i.attested.map(e=>(0,a.jsxs)(`li`,{children:[(0,a.jsx)(`span`,{className:`mono`,children:e.phase}),` — `,e.reason,(0,a.jsxs)(`div`,{className:`muted small`,children:[e.by,`, `,L(e.at),e.evidence===void 0?``:` · ${e.evidence}`]})]},`${e.phase}:${e.at}`))})]}):null,i.notes.length>0?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(`h3`,{children:`Notes`}),(0,a.jsx)(`ul`,{className:`list`,children:i.notes.map(e=>(0,a.jsxs)(`li`,{children:[e.text,(0,a.jsxs)(`div`,{className:`muted small`,children:[e.by,`, `,L(e.at),e.phase===null?``:` · at ${e.phase}`]})]},`${e.at}:${e.by}`))})]}):null,(0,a.jsx)(`h3`,{children:`Holdouts`}),i.hits.length===0?(0,a.jsx)(`p`,{className:`good`,children:`none firing`}):(0,a.jsxs)(`ul`,{className:`list compact`,children:[i.hits.slice(0,80).map(e=>(0,a.jsxs)(`li`,{className:`small`,children:[(0,a.jsxs)(`span`,{className:`mono`,children:[e.file,e.line===null?``:`:${String(e.line)}`]}),(0,a.jsxs)(`span`,{className:`muted`,children:[` `,e.objective,e.subject===null?``:` · ${e.subject}`]})]},`${e.objective}:${e.entry}`)),i.hits.length>80?(0,a.jsxs)(`li`,{className:`muted`,children:[`… `,i.hits.length-80,` more`]}):null]}),(0,a.jsxs)(`details`,{children:[(0,a.jsxs)(`summary`,{className:`muted small`,children:[i.files.length,` files`]}),(0,a.jsx)(`ul`,{className:`list compact`,children:i.files.map(e=>(0,a.jsx)(`li`,{className:`mono small`,children:e},e))})]})]})},V=168,oe=14,H=16,U=14,W=52,G=24,K=28,q=(e,t)=>e!==null&&e.kind===t.kind&&(e.kind===`campaign`||(e.kind===`sector`&&t.kind===`sector`?e.name===t.name:e.id===t.id)),se=e=>[...e.objectives.some(e=>e.phase===null)||e.phases.length===0?[{kind:`standing`}]:[],...e.phases.map((e,t)=>({kind:`phase`,index:t})),{kind:`end`}],ce=(e,t,n)=>{if(n.done)return t.length-1;if(e.phases.length===0)return 0;let r=t.findIndex(e=>e.kind===`phase`&&e.index===n.phase);return r===-1?0:r},J=(e,t)=>e.length<=t?e:`${e.slice(0,t-1)}…`,le=e=>{let t=e.measure;if(t===null)return String(e.count);let n=t.value===null?`?`:String(t.value);return t.target===null?n:`${n}→${String(t.target)}`},ue=({campaign:e,hover:t,nudged:n,onHover:r,onPick:i,selected:o})=>{let s=se(e),c=t??o,l=e=>H+e*182,u=t=>t.kind===`standing`?e.objectives.filter(e=>e.phase===null):t.kind===`phase`?e.objectives.filter(n=>n.phase===e.phases[t.index]?.id):[],d=80+Math.max(1,...s.map(e=>u(e).length))*30+18,f=e.sectors.map(t=>({sector:t,column:ce(e,s,t)})),p=new Map,m=f.map(e=>{let t=p.get(e.column)??0;return p.set(e.column,t+1),{...e,row:t}}),h=Math.max(1,...p.values())*36+12,g=l(s.length)+8,_=d+h+24,v=c?.kind===`objective`?e.objectives.find(e=>e.id===c.id):void 0,y=c?.kind===`phase`?e.phases.findIndex(e=>e.id===c.id):-1,b=c?.kind===`sector`?e.sectors.find(e=>e.name===c.name):void 0,x=e=>v===void 0?y===-1?b!==void 0&&b.name===e.name:e.phase===y&&!e.done:(e.residue[v.id]??e.counts[v.id]??0)>0,S=t=>b===void 0?y===-1?v!==void 0&&v.id===t.id:t.phase===e.phases[y]?.id:(b.residue[t.id]??0)>0,C=t=>b===void 0?v===void 0?y===t:v.phase===e.phases[t]?.id:b.phase===t&&!b.done,w=c!==null&&c.kind!==`campaign`;return(0,a.jsxs)(`svg`,{className:`ladder ${w?`focused`:``}`,width:g,height:_,viewBox:`0 0 ${String(g)} ${String(_)}`,role:`img`,"aria-label":`Campaign ${e.id}: ${String(e.phases.length)} phases, ${String(e.sectors.length)} sectors`,onMouseLeave:()=>{r(null)},children:[(0,a.jsx)(`defs`,{children:(0,a.jsx)(`marker`,{id:`ladder-arrow`,viewBox:`0 0 10 10`,refX:`9`,refY:`5`,markerWidth:`7`,markerHeight:`7`,orient:`auto-start-reverse`,children:(0,a.jsx)(`path`,{d:`M0,0 L10,5 L0,10 z`,className:`arrowhead`})})}),s.map((t,n)=>{let d=l(n),f=u(t);if(t.kind===`end`){let t=e.sectors.filter(e=>e.done).length;return(0,a.jsxs)(`g`,{className:`column end ${e.complete?`lit`:``}`,children:[(0,a.jsx)(`rect`,{x:d,y:U,width:V,height:W,rx:`8`,className:`phase end`}),(0,a.jsx)(`text`,{x:d+12,y:33,className:`eyebrow end-text`,children:`THE END`}),(0,a.jsx)(`text`,{x:d+12,y:52,className:`phase-name end-text`,children:`end state`}),(0,a.jsxs)(`text`,{x:d+12,y:86,className:`small muted`,children:[t,` of `,e.sectors.length,` sectors there`]})]},`end`)}let p=t.kind===`phase`?e.phases[t.index]:void 0,m=t.kind===`phase`?C(t.index):c?.kind===`objective`&&v?.phase===null,h=p===void 0?null:{kind:`phase`,id:p.id};return(0,a.jsxs)(`g`,{className:`column ${m?`lit`:``}`,children:[(0,a.jsxs)(`g`,{className:`phase-box ${p===void 0?`standing`:p.defined?`defined`:`open`} ${h!==null&&q(o,h)?`selected`:``}`,onMouseEnter:()=>{r(h)},onClick:()=>{i(h)},children:[(0,a.jsx)(`rect`,{x:d,y:U,width:V,height:W,rx:`8`,className:`phase`}),(0,a.jsxs)(`text`,{x:d+12,y:33,className:`eyebrow`,children:[p===void 0||t.kind!==`phase`?`STANDING`:p.defined?`PHASE ${String(t.index+1)}`:`OPEN`,p?.attested===!0?` · ATTESTED`:``]}),(0,a.jsx)(`text`,{x:d+12,y:52,className:`phase-name`,children:p===void 0?`in window everywhere`:J(p.id,20)}),p===void 0?null:(0,a.jsx)(`text`,{x:d+V-10,y:52,className:`phase-count`,textAnchor:`end`,children:p.sectors})]}),n<s.length-1?(0,a.jsx)(`line`,{x1:d+V+1,y1:40,x2:d+V+oe-1,y2:40,className:`connector`,markerEnd:`url(#ladder-arrow)`}):null,p!==void 0&&!p.defined&&p.intent!==null?(0,a.jsxs)(`text`,{x:d+12,y:86,className:`intent`,children:[`“`,J(p.intent,26),`”`]}):null,f.map((e,t)=>{let n=80+t*30+(p!==void 0&&!p.defined?14:0),s={kind:`objective`,id:e.id};return(0,a.jsxs)(`g`,{className:`chip-box ${S(e)?`lit`:``} ${e.complete?`complete`:``} ${q(o,s)?`selected`:``} ${e.ledgered?``:`unledgered`}`,onMouseEnter:()=>{r(s)},onClick:()=>{i(s)},children:[(0,a.jsx)(`rect`,{x:d+4,y:n,width:160,height:G,rx:`12`,className:`chip`}),(0,a.jsx)(`text`,{x:d+14,y:n+16,className:`chip-text mono`,children:J(e.id,18)}),(0,a.jsx)(`text`,{x:d+V-14,y:n+16,className:`chip-count`,textAnchor:`end`,children:le(e)}),(0,a.jsxs)(`title`,{children:[e.message,e.measure===null?` — ${String(e.count)} holdout(s), ${String(Math.round(e.progress*100))}% cleared`:` — ${String(e.measure.value??`?`)} now, target ${String(e.measure.target??`none`)}`]})]},e.id)})]},t.kind===`phase`?`phase:${String(t.index)}`:`standing`)}),(0,a.jsx)(`line`,{x1:H,y1:d-8,x2:g-8,y2:d-8,className:`rule`}),(0,a.jsx)(`text`,{x:H,y:d-14,className:`label`,children:`Sectors`}),(0,a.jsx)(`text`,{x:76,y:d-14,className:`small muted`,children:`holdouts left`}),s.map((e,t)=>(0,a.jsx)(`rect`,{x:l(t),y:d,width:V,height:h,rx:`8`,className:`lane`},t)),m.map(({column:e,row:t,sector:s})=>{let c=l(e)+4,u=d+6+t*36,f=Object.entries(s.residue).reduce((e,[,t])=>e+t,0),p={kind:`sector`,name:s.name},m=s.done?`done`:s.legacy?`legacy`:`sector`;return(0,a.jsxs)(`g`,{className:`sector-box ${m} ${x(s)?`lit`:``} ${q(o,p)?`selected`:``} ${n.has(s.name)?`nudged`:``} ${s.stalled?`stalled`:``}`,onMouseEnter:()=>{r(p)},onClick:()=>{i(p)},children:[(0,a.jsx)(`rect`,{x:c,y:u,width:160,height:K,rx:`6`,className:`sector`}),(0,a.jsx)(`text`,{x:c+10,y:u+19,className:`sector-name mono`,children:J(s.name,16)}),(0,a.jsx)(`text`,{x:c+V-18,y:u+19,className:`sector-count`,textAnchor:`end`,children:s.done?`done`:s.stalled?`${String(f)} ⏸`:String(f)}),(0,a.jsxs)(`title`,{children:[s.name,`: `,String(s.files.length),` files`,s.phaseId===null?``:`, at ${s.phaseId}`,s.stalled?`, stalled`:``]})]},s.name)}),e.sectors.length===0?(0,a.jsx)(`text`,{x:28,y:d+24,className:`small muted`,children:`no sectors`}):null]})},de=(e,t)=>{if(t===null)return{campaign:null,pick:null};let n=t.indexOf(`/`),r=n===-1?t:t.slice(0,n);if(!e.campaigns.some(e=>e.id===r))return{campaign:null,pick:null};if(n===-1)return{campaign:r,pick:null};let i=t.slice(n+1),a=i.indexOf(`:`),o=a===-1?i:i.slice(0,a),s=a===-1?``:i.slice(a+1);return{campaign:r,pick:o===`campaign`?{kind:`campaign`}:o===`phase`?{kind:`phase`,id:s}:o===`objective`?{kind:`objective`,id:s}:o===`sector`?{kind:`sector`,name:s}:null}},Y=(e,t)=>t===null?e:`${e}/${t.kind}${t.kind===`campaign`?``:`:${t.kind===`sector`?t.name:t.id}`}`,fe=({onSelect:e,selection:t,view:n})=>{let r=(0,i.useMemo)(()=>de(n,t),[n,t]),o=n.campaigns.find(e=>e.id===r.campaign)??n.campaigns[0],[s,c]=(0,i.useState)(null);if(o===void 0)return(0,a.jsx)(`div`,{className:`placeholder`,children:`This policy declares no campaigns.`});let l=r.campaign===o.id?r.pick:null,u=t=>{e(Y(o.id,t))},d=n.nudge?.sectors.filter(e=>e.campaign===o.id)??[];return(0,a.jsxs)(`div`,{className:`camp`,children:[(0,a.jsxs)(`section`,{className:`pane ladder-pane`,"aria-label":`Campaign ladder`,children:[(0,a.jsx)(`div`,{className:`pane-head tabs-row`,children:n.campaigns.map(t=>(0,a.jsxs)(`button`,{type:`button`,className:t.id===o.id?`tab active`:`tab`,onClick:()=>{e(Y(t.id,null))},title:t.title??t.id,children:[(0,a.jsx)(`span`,{className:`mono`,children:t.id}),(0,a.jsxs)(`span`,{className:`pct ${t.complete?`good`:t.stalled?`bad`:``}`,children:[Math.round(t.progress*100),`%`]})]},t.id))}),(0,a.jsxs)(`div`,{className:`camp-head`,children:[(0,a.jsxs)(`h2`,{children:[o.title??o.id,o.stalled?(0,a.jsx)(`span`,{className:`flag bad`,children:`stalled`}):null,o.complete?(0,a.jsx)(`span`,{className:`flag good`,children:`complete`}):null,o.missingLedger?(0,a.jsx)(`span`,{className:`flag warn`,children:`no ledger`}):null,o.arithmetic?null:(0,a.jsx)(`span`,{className:`flag bad`,children:`ledger arithmetic`})]}),(0,a.jsx)(`div`,{className:`progress`,title:`${String(Math.round(o.progress*100))}% of the initial holdouts cleared`,children:(0,a.jsx)(`div`,{className:`progress-bar`,style:{width:`${String(Math.round(o.progress*100))}%`}})}),(0,a.jsxs)(`div`,{className:`muted small`,children:[o.count,` holdout`,o.count===1?``:`s`,` left`,o.owner===null?``:` · ${o.owner}`,o.staleAfterDays===null?``:` · stale after ${String(o.staleAfterDays)}d`,` · scope `,(0,a.jsx)(`span`,{className:`mono`,children:o.scope.join(`, `)}),o.perimeter===null?``:` · perimeter ${o.perimeter}`]})]}),(0,a.jsx)(`div`,{className:`ladder-scroll`,children:(0,a.jsx)(ue,{campaign:o,nudged:new Set(d.map(e=>e.sector)),hover:s,selected:l,onHover:c,onPick:u})}),(0,a.jsxs)(`div`,{className:`legend`,children:[(0,a.jsx)(`span`,{className:`key defined`,children:`defined phase`}),(0,a.jsx)(`span`,{className:`key open`,children:`open phase`}),(0,a.jsx)(`span`,{className:`key sector`,children:`sector`}),(0,a.jsx)(`span`,{className:`key legacy`,children:`legacy`}),(0,a.jsx)(`span`,{className:`key done`,children:`done`}),(0,a.jsx)(`span`,{className:`key nudged`,children:`touched in the working tree`})]})]}),(0,a.jsx)(`section`,{className:`pane detail-pane`,"aria-label":`Details`,children:(0,a.jsx)(ne,{view:n,campaign:o,shown:s??l??{kind:`campaign`},pinned:s===null&&l!==null,onPick:u})})]})},X=e=>new URL(`__goodbones/${e}`,document.baseURI).href,pe=(e,t)=>typeof e==`object`&&e&&`error`in e?String(e.error):`HTTP ${String(t)}`,Z=(e,t)=>{let[n,r]=(0,i.useState)({state:`loading`,value:null,error:null});return(0,i.useEffect)(()=>{let t=!1;return r(e=>({state:`loading`,value:e.value,error:null})),fetch(X(e),{cache:`no-store`}).then(async e=>{let n=await e.json();if(!t){if(!e.ok){r(t=>({state:`failed`,value:t.value,error:pe(n,e.status)}));return}r({state:`ready`,value:n,error:null})}}).catch(e=>{t||r(t=>({state:`failed`,value:t.value,error:String(e)}))}),()=>{t=!0}},[e,t]),n},me=()=>{let[e,t]=(0,i.useState)({live:!1,version:0,changed:[]});return(0,i.useEffect)(()=>{if(typeof EventSource>`u`)return;let e=new EventSource(X(`events`));return e.addEventListener(`hello`,()=>{t(e=>({...e,live:!0}))}),e.addEventListener(`changed`,e=>{let n=[];try{let t=JSON.parse(e.data);typeof t==`object`&&t&&`files`in t&&Array.isArray(t.files)&&(n=t.files.map(String))}catch{n=[]}t(e=>({live:!0,version:e.version+1,changed:n}))}),e.addEventListener(`error`,()=>{e.readyState===EventSource.CLOSED&&t(e=>({...e,live:!1}))}),()=>{e.close()}},[]),e},Q=e=>{let t=e.replace(/^#/,``),n=t.indexOf(`/`),r=n===-1?t:t.slice(0,n),i=n===-1?null:decodeURIComponent(t.slice(n+1));return{tab:r===`campaigns`?`campaigns`:`architecture`,selection:i}},he=e=>`#${e.tab}${e.selection===null?``:`/${encodeURIComponent(e.selection)}`}`,ge=()=>{let[e,t]=(0,i.useState)(()=>Q(window.location.hash));return(0,i.useEffect)(()=>{let e=()=>{t(Q(window.location.hash))};return window.addEventListener(`hashchange`,e),()=>{window.removeEventListener(`hashchange`,e)}},[]),[e,e=>{let n=he(e);window.location.hash!==n&&window.history.replaceState(null,``,n),t(e)}]},_e=()=>{try{let e=window.localStorage.getItem(`goodbones-theme`);return e===`dark`||e===`light`?e:null}catch{return null}},ve=e=>{let t=new Date(e);return Number.isNaN(t.getTime())?e:t.toLocaleTimeString()},ye=()=>{let[e,t]=ge(),n=me(),r=Z(`atlas.json`,n.version),o=Z(`campaigns.json`,n.version),[s,c]=(0,i.useState)(()=>_e()??`dark`);(0,i.useEffect)(()=>{document.documentElement.dataset.theme=s;try{window.localStorage.setItem(`goodbones-theme`,s)}catch{}},[s]);let l=r.value?.name??o.value?.name??``,u=r.value?.generatedAt??o.value?.generatedAt??null,d=r.error??o.error,f=r.state===`loading`||o.state===`loading`;return(0,a.jsxs)(`div`,{className:`page`,children:[(0,a.jsxs)(`header`,{className:`bar`,children:[(0,a.jsxs)(`div`,{className:`brand`,children:[(0,a.jsx)(`span`,{className:`mark`,"aria-hidden":`true`}),(0,a.jsx)(`span`,{className:`brand-name`,children:`goodbones`}),l===``?null:(0,a.jsx)(`span`,{className:`repo`,children:l})]}),(0,a.jsxs)(`nav`,{className:`tabs`,"aria-label":`Browsers`,children:[(0,a.jsx)(`button`,{type:`button`,className:e.tab===`architecture`?`tab active`:`tab`,onClick:()=>{t({tab:`architecture`,selection:null})},children:`Architecture Browser`}),(0,a.jsxs)(`button`,{type:`button`,className:e.tab===`campaigns`?`tab active`:`tab`,onClick:()=>{t({tab:`campaigns`,selection:null})},children:[`Campaign Browser`,o.value!==null&&o.value.campaigns.length>0?(0,a.jsx)(`span`,{className:`count`,children:o.value.campaigns.length}):null]})]}),(0,a.jsxs)(`div`,{className:`status`,children:[(0,a.jsxs)(`span`,{className:`live ${n.live?`on`:`off`}`,title:n.live?`Live: the page redraws when the repository changes.`:`A snapshot: no feed of changes is reachable.`,children:[(0,a.jsx)(`span`,{className:`dot`,"aria-hidden":`true`}),n.live?`live`:`snapshot`]}),u===null?null:(0,a.jsx)(`span`,{className:`stamp`,title:u,children:f?`redrawing…`:`drawn ${ve(u)}`}),(0,a.jsx)(`button`,{type:`button`,className:`theme`,onClick:()=>{c(s===`dark`?`light`:`dark`)},"aria-label":`Toggle light and dark`,title:`Toggle light and dark`,children:s===`dark`?`☾`:`☀`})]})]}),d===null?null:(0,a.jsxs)(`div`,{className:`banner error`,role:`alert`,children:[(0,a.jsx)(`strong`,{children:`The repository could not be read.`}),` `,d,r.value===null?``:` Showing the last drawing.`]}),n.changed.length>0&&f?(0,a.jsxs)(`div`,{className:`banner`,children:[`Changed: `,n.changed.slice(0,4).join(`, `),n.changed.length>4?` and ${String(n.changed.length-4)} more`:``]}):null,(0,a.jsx)(`main`,{className:`body`,children:e.tab===`architecture`?r.value===null?(0,a.jsx)($,{loading:r.state===`loading`,what:`the architecture`}):(0,a.jsx)(N,{atlas:r.value,selection:e.selection,onSelect:e=>{t({tab:`architecture`,selection:e})}}):o.value===null?(0,a.jsx)($,{loading:o.state===`loading`,what:`the campaigns`}):(0,a.jsx)(fe,{view:o.value,selection:e.selection,onSelect:e=>{t({tab:`campaigns`,selection:e})}})})]})},$=({loading:e,what:t})=>(0,a.jsx)(`div`,{className:`placeholder`,children:e?`Reading ${t}…`:`Nothing to draw for ${t}.`});export{ye as Browser};
|