diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3458e2d..5e70736 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,3 +103,37 @@ jobs: uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0 with: version: v2.12.2 + + web: + name: view frontend + # internal/view/dist/ is the built frontend `scc view` embeds, committed so a + # `go build` needs no node. This job rebuilds it from web/ and fails when the + # result differs from what is committed — the only thing that keeps the two + # from drifting apart. + runs-on: ubuntu-latest + defaults: + run: + working-directory: web + steps: + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 + + - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + with: + node-version: '22' + + - name: install + run: npm ci + + - name: test + run: npm test + + - name: build (typecheck included) + run: npm run build + + - name: dist is current + run: | + if [ -n "$(git status --porcelain -- ../internal/view/dist)" ]; then + echo "::error::internal/view/dist/ is stale — run \`npm run build\` in web/ and commit the result" + git status --porcelain -- ../internal/view/dist + exit 1 + fi diff --git a/.gitignore b/.gitignore index 7e8d206..d43f3d4 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,6 @@ npm/dist/ # CodeGraph's symbol index. Not an scc artifact: it is CodeGraph's schema on # CodeGraph's schedule, rebuilt by `scc launch`, and it is machine-specific. /.codegraph/ + +# The view frontend's packages. Its build output, internal/view/dist/, is committed. +/web/node_modules/ diff --git a/README.md b/README.md index 066aff7..fd7c1b4 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ Installed globally (`npm i -g @protonspy/scc`) the same commands are just `scc i | `validate` | Every applicable validator, one exit code, one JSON document. `--pr` also reads the pull request open on this branch; `--checks` also runs this project's build, format, lint and test commands. | | `check\|check set\|check skip` | The delivery gate: this project's own build, format, lint and test commands, run in that order and judged. A gate the project does not have is skipped once and then stays quiet. | | `hooks install\|check\|remove` | Hooks that run the validators without anybody remembering to — git's (`scc validate` before a commit, the message checked as it is written, `scc validate --pr --checks` before a push) and the harness's own (findings, drift and undelivered work handed back to the agent, and a prompt that names an artifact routed through the map). `init` writes both; anything scc did not write is left alone. | +| `view` | Serves the docs, plans and specs as a read-only web page on `127.0.0.1:7777` (`--port 0` for a free one): wiki, ADRs, codewiki next to the source lines it cites, glossary, stack, notes, and every plan and spec with its progress. Runs until Ctrl+C. | | `rtk` | Wires in [RTK](https://github.com/rtk-ai/rtk) after the fact: installs it if missing, then splices its usage block into the entry file. | | `graph build\|sync\|query\|explore\|scope` | The workspace's symbol graph, via [CodeGraph](https://github.com/colbymchenry/codegraph). `scope` narrows it to certain trees — one graph per directory, since CodeGraph indexes a single root at a time. | | `launch` | Starts the harness with the workspace's symbol graph and RTK block current, **inside a sandbox by default** — ai-jail on Linux/macOS, a dev container on Windows. | diff --git a/docs/adr/0002-narrowed-from-csdd.md b/docs/adr/0002-narrowed-from-csdd.md index 69e753f..8c923e2 100644 --- a/docs/adr/0002-narrowed-from-csdd.md +++ b/docs/adr/0002-narrowed-from-csdd.md @@ -39,3 +39,7 @@ When something from `csdd` is wanted here, the *decision* is ported and not the the three platforms. The reversal does not weaken the other three — it is the editor-free `devcontainer up` / `devcontainer exec` path, not the VS Code flow, so the surface is still arguments in and a process out. +- **A second item was reversed by its own record.** The embedded web dashboard is + now `scc view`, under `adr:0003-local-read-only-viewer`: read-only, + loopback-only, and reading through the same parsers as the CLI. The TUI and the + MCP server stay decided against. diff --git a/docs/adr/0003-local-read-only-viewer.md b/docs/adr/0003-local-read-only-viewer.md new file mode 100644 index 0000000..add67b6 --- /dev/null +++ b/docs/adr/0003-local-read-only-viewer.md @@ -0,0 +1,66 @@ +--- +status: accepted +--- + +# A local, read-only viewer, built with React + +## Context + +`adr:0002-narrowed-from-csdd` decided against an embedded web dashboard, among +other surfaces built for a person rather than for an agent, and said that decision +is reopened by a new record rather than by a pull request. This is that record. + +The addressing commands — `scc map`, `scc notes find`, `scc graph` — exist so an +agent never reads a whole file. A person reading the record end to end is the one +reader they were never built for: the wiki, the ADRs, the codewiki next to the +lines it cites, every plan and spec with its progress. The user asked for that as +`scc view`, a page served by the binary. + +Two questions follow. Whether a web surface may exist at all, given 0002; and how a +React frontend ships inside a binary whose module is stdlib-only +(`adr:0001-stdlib-only-dependencies`). + +## Decision + +**`scc view` exists, and is held to three limits** that keep it inside what 0002 +was protecting: + +- **Read-only.** GET and HEAD only; nothing on disk changes. Every write stays a + command with an exit code, so the agent-facing surface is still the only one that + does anything. +- **Loopback-only.** The listener binds `127.0.0.1`, and a `Host` header that does + not name loopback is refused, which closes DNS rebinding. There is no + authentication because there is no remote access to authenticate. +- **The same parsers.** Every route reads through `internal/artifact`, so the page + shows what `scc map` would say and is not a second reading of the files. + +**The frontend is React, built by Vite from `web/` into `internal/view/dist/`, +which is committed and embedded with `go:embed`.** The Go module stays +stdlib-only: `web/` is build machinery outside the module, as `npm/` already is, +and a `go build` needs no node. CI rebuilds `dist/` and fails on a diff. + +Rejected: React vendored without a build step (no JSX, no TypeScript, hand-managed +updates), and React loaded from a CDN (needs network, and puts a third-party script +in a page that can read the workspace). Rendering Markdown in Go was rejected +because the stdlib has no renderer and `mdscan` is a scanner. + +## Consequences + +- The binary grows by the bundle — about 400 KB, 120 KB gzipped. +- A change to `web/` needs node ≥ 22.12 and a committed rebuild; a change to Go + alone does not. The CI job is what makes a forgotten rebuild loud. +- The frontend's packages are npm dependencies with their own supply chain. They + run in the developer's build and in the browser, never in the Go binary's + process, and `package-lock.json` pins them; `docs/stack.md` lists each. +- Markdown from the repository is untrusted input to the page: raw HTML is shown as + text, and a Content-Security-Policy keeps scripts and connections on the + viewer's own origin, so a hostile page in a cloned repository cannot read + through the source route and send it anywhere. +- The source route can read any text file in the workspace up to 1 MiB whose real + path has no dot-named segment, not only the files a codewiki page cites. The dot + rule is applied after symlinks are followed and Windows short names expanded, so + neither a committed link to `.env` nor `GIT~1` reaches past it. +- There is no authentication: any account on the machine can reach the loopback + port. Accepted, because the readable set is the checkout and the record, not + credentials. If a shared host ever makes that unacceptable, the fix is a per-run + token in the URL, not a wider bind. diff --git a/docs/codewiki/packages.md b/docs/codewiki/packages.md index 931788a..52f46e0 100644 --- a/docs/codewiki/packages.md +++ b/docs/codewiki/packages.md @@ -7,7 +7,7 @@ cmd/scc/main.go os.Exit(cli.Run(os.Args[1:])) | internal/cli the whole command surface | - scaffold · validate · hooks write / check / gate + scaffold · validate · hooks · view write / check / gate / serve | \ assets · manifest ears · mdscan · artifact · notes templates, hashes, grammars | @@ -156,6 +156,25 @@ workspace safe by construction. `Changed` is the only one that reads content, an compares against the *working* tree rather than `HEAD`, because at the end of a turn the agent has usually written code and not yet committed it. +## The viewer is one more reader, not a second parser + +[internal/view/page.go:41-69]() · [internal/view/page.go:98-115]() + +`scc view` serves the record to a person, which `adr:0002-narrowed-from-csdd` +ruled out until `adr:0003-local-read-only-viewer` reopened it on three conditions. +The one visible here: every route reads through `artifact.Load` and +`artifact.Within`, so the page can never disagree with `scc map` about what a file +says or where the workspace ends. `resolve` is the single containment check both +the page and the source route pass through. + +[internal/view/view.go:68-100]() + +The other two conditions are the middleware: GET and HEAD only, and a `Host` +header that names loopback by name. A domain that merely resolves to `127.0.0.1` +is refused on purpose — that is what a DNS-rebinding page does. The React frontend +is built from `web/` into `internal/view/dist/` and embedded, so none of it is in +the Go module. + ## Hooks are events, not scripts [internal/hooks/harness.go:42-60]() · [internal/hooks/harness.go:127-140]() diff --git a/docs/stack.md b/docs/stack.md index ee6bfdd..2fb36cd 100644 --- a/docs/stack.md +++ b/docs/stack.md @@ -69,6 +69,27 @@ nobody recorded a reason, this file says so rather than inventing one. assembles the publish tree. Cost: a node dependency for people who only wanted a Go binary — which is why direct download from the GitHub Release stays supported. +## The view frontend — `web/` + +Build machinery outside the Go module, as `npm/` is: its output, +`internal/view/dist/`, is committed and embedded, so `go build` needs no node. Why a +React page exists at all is `adr:0003-local-read-only-viewer`. Every version is +pinned exactly in `web/package.json` and locked in `web/package-lock.json`. + +- **React 19 and react-dom** — the page `scc view` serves. Chosen by the user over + a build-free alternative; the component model is what keeps three views and a + sidebar small. +- **react-markdown 10 and remark-gfm 4** — render the record's Markdown, tables and + task lists included. Chosen over an HTML-emitting renderer because it escapes + raw HTML by default, and repository Markdown is untrusted input to the page. +- **Vite 8 and @vitejs/plugin-react** — the bundler that writes `dist/`; `npm run + dev` proxies `/api` to a running `scc view` for hot reload. +- **TypeScript 7** — typechecks `web/src` as the first half of `npm run build`. +- **Vitest 5** — runs `web/src/links.test.ts`, the one module with logic worth a + test: where every link in a page goes. +- **Node.js ≥ 22.12** — what Vite 8 and Vitest 5 require; needed only to change + `web/`. CI's `web` job uses it to rebuild `dist/` and fail on a diff. + ## Integrated binaries — driven, never vendored Each is a third-party CLI scc composes a command line for and starts. None is a Go diff --git a/internal/cli/cli.go b/internal/cli/cli.go index 2e9abbb..16ec776 100644 --- a/internal/cli/cli.go +++ b/internal/cli/cli.go @@ -84,6 +84,8 @@ func Run(args []string) int { return runCheck(args[1:]) case "hooks": return runHooks(args[1:]) + case "view": + return runView(args[1:]) default: render.Err(fmt.Sprintf("unknown command %q", args[0])) fmt.Fprintf(os.Stderr, "run `%s help` for the available commands\n", prog()) @@ -132,6 +134,7 @@ Commands: validate Run every applicable validator; exit 2 on findings check The delivery gate — build, format, lint, test: run | set | skip | show hooks Git hooks that run the validators — install | check | remove + view Serve docs, plans and specs as a read-only web page on 127.0.0.1 version Print the version help Show this help @@ -146,5 +149,6 @@ Exit codes: 2 validation findings "%s launch" is the one exception: it returns whatever the agent it started returned. -`, render.Bold(prog()), prog(), prog(), prog()) +"%s view" runs until interrupted, and an interrupt is a 0. +`, render.Bold(prog()), prog(), prog(), prog(), prog()) } diff --git a/internal/cli/view.go b/internal/cli/view.go new file mode 100644 index 0000000..5e2e518 --- /dev/null +++ b/internal/cli/view.go @@ -0,0 +1,95 @@ +package cli + +import ( + "context" + "flag" + "fmt" + "net" + "os" + "os/signal" + "strconv" + + "github.com/protonspy/spec-claude-code/internal/render" + "github.com/protonspy/spec-claude-code/internal/view" +) + +// defaultViewPort is fixed rather than 0 so the URL survives a restart and a tab +// left open reconnects; --port 0 asks the system for a free one instead. +const defaultViewPort = 7777 + +// viewContext is what stops the server: an interrupt, in the real binary. A test +// swaps it for a context it cancels itself, since it cannot signal its own process. +var viewContext = func() (context.Context, context.CancelFunc) { + return signal.NotifyContext(context.Background(), os.Interrupt) +} + +// runView serves the workspace read-only on loopback until interrupted. It is the +// one command that does not return on its own, and an interrupt is its normal end, +// so that exits 0. +func runView(args []string) int { + fs := flag.NewFlagSet("view", flag.ContinueOnError) + fs.SetOutput(os.Stderr) + fs.Usage = viewUsage + root := addRoot(fs) + port := fs.Int("port", defaultViewPort, "port to listen on, on 127.0.0.1 only; 0 picks a free one") + jsonOut := addJSON(fs) + rest, err := parseFlags(fs, helpWord(args)) + if err != nil { + return exitFor(err) + } + if !noPositionals(rest, "view") { + return ExitError + } + if *port < 0 || *port > 65535 { + render.Err(fmt.Sprintf("--port %d is not a port", *port)) + return ExitError + } + target, ok := resolveRoot(*root) + if !ok || !requireWorkspace(target) { + return ExitError + } + + addr := net.JoinHostPort("127.0.0.1", strconv.Itoa(*port)) + ln, err := net.Listen("tcp", addr) + if err != nil { + render.Err(fmt.Sprintf("could not listen on %s: %v", addr, err)) + render.Detail(" another process holds the port — pass --port , or --port 0 for a free one") + return ExitError + } + url := "http://" + ln.Addr().String() + "/" + + ctx, stop := viewContext() + defer stop() + if *jsonOut { + if code := emitJSON(struct { + URL string `json:"url"` + Root string `json:"root"` + }{url, target}); code != ExitOK { + _ = ln.Close() + return code + } + } else { + render.OK("serving " + target) + render.Info(url) + render.Detail(" read-only, loopback only — Ctrl+C to stop") + } + if err := view.Serve(ctx, ln, target); err != nil { + render.Err(fmt.Sprintf("server stopped: %v", err)) + return ExitError + } + return ExitOK +} + +func viewUsage() { + fmt.Fprintf(os.Stderr, `Usage: %s view [--port N] [--root DIR] [--json] + +Serve the workspace's docs, plans and specs as a read-only web page on +127.0.0.1, until interrupted: the wiki, ADRs, codewiki with the source lines it +cites, glossary, stack, notes, every plan and every spec. + +Flags: + --port N port to listen on (default %d; 0 picks a free one) + --root DIR %s + --json print {"url", "root"} on stdout once listening +`, prog(), defaultViewPort, rootFlagHelp) +} diff --git a/internal/cli/view_test.go b/internal/cli/view_test.go new file mode 100644 index 0000000..bba5275 --- /dev/null +++ b/internal/cli/view_test.go @@ -0,0 +1,76 @@ +package cli + +import ( + "context" + "net" + "strconv" + "strings" + "testing" +) + +// stopAtOnce swaps the interrupt for a context that is already cancelled, so +// runView binds, prints its URL, and returns the way an interrupt makes it return. +func stopAtOnce(t *testing.T) { + t.Helper() + orig := viewContext + viewContext = func() (context.Context, context.CancelFunc) { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + return ctx, cancel + } + t.Cleanup(func() { viewContext = orig }) +} + +func TestViewPrintsALoopbackURLAndExitsZeroOnInterrupt(t *testing.T) { + stopAtOnce(t) + root := initWorkspace(t) + stdout, stderr, code := run(t, "view", "--port", "0", "--root", root, "--json") + if code != ExitOK { + t.Fatalf("exit = %d, want 0 (stderr: %s)", code, stderr) + } + var got struct{ URL, Root string } + decode(t, stdout, &got) + if !strings.HasPrefix(got.URL, "http://127.0.0.1:") || strings.HasSuffix(got.URL, ":0/") { + t.Errorf("url = %q, want a bound 127.0.0.1 port", got.URL) + } +} + +func TestViewRefusesOutsideAWorkspace(t *testing.T) { + stopAtOnce(t) + _, stderr, code := run(t, "view", "--port", "0", "--root", t.TempDir()) + if code != ExitError || !strings.Contains(stderr, "not an scc workspace") { + t.Errorf("exit = %d, stderr %q; want 1 naming the missing workspace", code, stderr) + } +} + +func TestViewReportsAPortInUse(t *testing.T) { + stopAtOnce(t) + root := initWorkspace(t) + ln, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + defer func() { _ = ln.Close() }() + port := strconv.Itoa(ln.Addr().(*net.TCPAddr).Port) + + _, stderr, code := run(t, "view", "--port", port, "--root", root) + if code != ExitError || !strings.Contains(stderr, "127.0.0.1:"+port) { + t.Errorf("exit = %d, stderr %q; want 1 naming 127.0.0.1:%s", code, stderr, port) + } +} + +func TestViewRejectsABadPort(t *testing.T) { + for _, p := range []string{"-1", "65536"} { + if _, _, code := run(t, "view", "--port", p); code != ExitError { + t.Errorf("--port %s exit = %d, want 1", p, code) + } + } +} + +func TestViewHelpIsZero(t *testing.T) { + for _, args := range [][]string{{"view", "--help"}, {"view", "help"}} { + if _, stderr, code := run(t, args...); code != ExitOK || !strings.Contains(stderr, "view [--port N]") { + t.Errorf("%v exit = %d, stderr %q", args, code, stderr) + } + } +} diff --git a/internal/view/dist/assets/index-BcFXmEw6.js b/internal/view/dist/assets/index-BcFXmEw6.js new file mode 100644 index 0000000..0798df0 --- /dev/null +++ b/internal/view/dist/assets/index-BcFXmEw6.js @@ -0,0 +1,39 @@ +var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),s=(e,n)=>{let r={};for(var i in e)t(r,i,{get:e[i],enumerable:!0});return n||t(r,Symbol.toStringTag,{value:`Module`}),r},c=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;li[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},l=(n,r,o)=>(o=n==null?{}:e(i(n)),c(r||!n||!n.__esModule||!a.call(n,`default`)?t(o,`default`,{value:n,enumerable:!0}):o,n));(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var u=o((e=>{var t=Symbol.for(`react.transitional.element`),n=Symbol.for(`react.portal`),r=Symbol.for(`react.fragment`),i=Symbol.for(`react.strict_mode`),a=Symbol.for(`react.profiler`),o=Symbol.for(`react.consumer`),s=Symbol.for(`react.context`),c=Symbol.for(`react.forward_ref`),l=Symbol.for(`react.suspense`),u=Symbol.for(`react.memo`),d=Symbol.for(`react.lazy`),f=Symbol.for(`react.activity`),p=Symbol.for(`react.view_transition`),m=Symbol.iterator;function h(e){return typeof e!=`object`||!e?null:(e=m&&e[m]||e[`@@iterator`],typeof e==`function`?e:null)}var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},_=Object.assign,v={};function y(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||g}y.prototype.isReactComponent={},y.prototype.setState=function(e,t){if(typeof e!=`object`&&typeof e!=`function`&&e!=null)throw Error(`takes an object of state variables to update or a function which returns an object of state variables.`);this.updater.enqueueSetState(this,e,t,`setState`)},y.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,`forceUpdate`)};function b(){}b.prototype=y.prototype;function x(e,t,n){this.props=e,this.context=t,this.refs=v,this.updater=n||g}var ee=x.prototype=new b;ee.constructor=x,_(ee,y.prototype),ee.isPureReactComponent=!0;var te=Array.isArray;function ne(){}var S={H:null,A:null,T:null,S:null},C=Object.prototype.hasOwnProperty;function w(e,n,r){var i=r.ref;return{$$typeof:t,type:e,key:n,ref:i===void 0?null:i,props:r}}function T(e,t){return w(e.type,t,e.props)}function E(e){return typeof e==`object`&&!!e&&e.$$typeof===t}function re(e){var t={"=":`=0`,":":`=2`};return`$`+e.replace(/[=:]/g,function(e){return t[e]})}var ie=/\/+/g;function ae(e,t){return typeof e==`object`&&e&&e.key!=null?re(``+e.key):t.toString(36)}function oe(e){switch(e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason;default:switch(typeof e.status==`string`?e.then(ne,ne):(e.status=`pending`,e.then(function(t){e.status===`pending`&&(e.status=`fulfilled`,e.value=t)},function(t){e.status===`pending`&&(e.status=`rejected`,e.reason=t)})),e.status){case`fulfilled`:return e.value;case`rejected`:throw e.reason}}throw e}function se(e,r,i,a,o){var s=typeof e;(s===`undefined`||s===`boolean`)&&(e=null);var c=!1;if(e===null)c=!0;else switch(s){case`bigint`:case`string`:case`number`:c=!0;break;case`object`:switch(e.$$typeof){case t:case n:c=!0;break;case d:return c=e._init,se(c(e._payload),r,i,a,o)}}if(c)return o=o(e),c=a===``?`.`+ae(e,0):a,te(o)?(i=``,c!=null&&(i=c.replace(ie,`$&/`)+`/`),se(o,r,i,``,function(e){return e})):o!=null&&(E(o)&&(o=T(o,i+(o.key==null||e&&e.key===o.key?``:(``+o.key).replace(ie,`$&/`)+`/`)+c)),r.push(o)),1;c=0;var l=a===``?`.`:a+`:`;if(te(e))for(var u=0;u{t.exports=u()})),f=o((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m){if(n(c)!==null)m=!0,ee||(ee=!0,T());else{var t=n(l);t!==null&&ie(x,t.startTime-e)}}}var ee=!1,te=-1,ne=5,S=-1;function C(){return g?!0:!(e.unstable_now()-St&&C());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&ie(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?T():ee=!1}}}var T;if(typeof y==`function`)T=function(){y(w)};else if(typeof MessageChannel<`u`){var E=new MessageChannel,re=E.port2;E.port1.onmessage=w,T=function(){re.postMessage(null)}}else T=function(){_(w,0)};function ie(t,n){te=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(te),te=-1):h=!0,ie(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,ee||(ee=!0,T()))),r},e.unstable_shouldYield=C,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),p=o(((e,t)=>{t.exports=f()})),m=o((e=>{var t=d();function n(e){var t=`https://react.dev/errors/`+e;if(1{function n(){if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<`u`&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE==`function`)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=m()})),g=o((e=>{var t=p(),n=d(),r=h();function i(e){var t=`https://react.dev/errors/`+e;if(1Te||(e.current=we[Te],we[Te]=null,Te--)}function A(e,t){Te++,we[Te]=e.current,e.current=t}var j=Ee(null),Oe=Ee(null),M=Ee(null),N=Ee(null);function ke(e,t){switch(A(M,t),A(Oe,e),A(j,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?up(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=up(t),e=dp(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}De(j),A(j,e)}function Ae(){De(j),De(Oe),De(M)}function je(e){var t=e.memoizedState;t!==null&&(sh._currentValue=t.memoizedState,A(N,e)),t=j.current;var n=dp(t,e.type);t!==n&&(A(Oe,e),A(j,n))}function Me(e){Oe.current===e&&(De(j),De(Oe)),N.current===e&&(De(N),sh._currentValue=Ce)}var Ne,Pe;function Fe(e){if(Ne===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);Ne=t&&t[1]||``,Pe=-1)`:-1i||c[r]!==l[i]){var u=` +`+c[r].replace(` at new `,` at `);return e.displayName&&u.includes(``)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{Ie=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?Fe(n):``}function Re(e,t){switch(e.tag){case 26:case 27:case 5:return Fe(e.type);case 16:return Fe(`Lazy`);case 13:return e.child!==t&&t!==null?Fe(`Suspense Fallback`):Fe(`Suspense`);case 19:return Fe(`SuspenseList`);case 0:case 15:return Le(e.type,!1);case 11:return Le(e.type.render,!1);case 1:return Le(e.type,!0);case 31:return Fe(`Activity`);case 30:return Fe(`ViewTransition`);default:return``}}function ze(e){try{var t=``,n=null;do t+=Re(e,n),n=e,e=e.return;while(e);return t}catch(e){return` +Error generating stack: `+e.message+` +`+e.stack}}var Be=Object.prototype.hasOwnProperty,Ve=t.unstable_scheduleCallback,He=t.unstable_cancelCallback,Ue=t.unstable_shouldYield,We=t.unstable_requestPaint,Ge=t.unstable_now,Ke=t.unstable_getCurrentPriorityLevel,qe=t.unstable_ImmediatePriority,Je=t.unstable_UserBlockingPriority,Ye=t.unstable_NormalPriority,Xe=t.unstable_LowPriority,Ze=t.unstable_IdlePriority,Qe=t.log,$e=t.unstable_setDisableYieldValue,et=null,tt=null;function nt(e){if(typeof Qe==`function`&&$e(e),tt&&typeof tt.setStrictMode==`function`)try{tt.setStrictMode(et,e)}catch{}}var rt=Math.clz32?Math.clz32:ot,it=Math.log,at=Math.LN2;function ot(e){return e>>>=0,e===0?32:31-(it(e)/at|0)|0}var st=256,ct=262144,lt=4194304;function ut(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&-e;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function dt(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=ut(n))):i=ut(o):i=ut(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=ut(n))):i=ut(o)):i=ut(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function ft(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function pt(e,t){t&8&&(t|=t&32);var n=e.entangledLanes;if(n!==0)for(e=e.entanglements,n&=t;0n;n++)t.push(e);return t}function _t(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function vt(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0=pr),gr=` `,_r=!1;function vr(e,t){switch(e){case`keyup`:return dr.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function yr(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var br=!1;function xr(e,t){switch(e){case`compositionend`:return yr(t);case`keypress`:return t.which===32?(_r=!0,gr):null;case`textInput`:return e=t.data,e===gr&&_r?null:e;default:return null}}function Sr(e,t){if(br)return e===`compositionend`||!fr&&vr(e,t)?(e=Pn(),Nn=Mn=jn=null,br=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=Gr(n)}}function qr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?qr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Jr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Wr(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Wr(e.document)}return t}function Yr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var Xr=On&&`documentMode`in document&&11>=document.documentMode,Zr=null,Qr=null,$r=null,ei=!1;function ti(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;ei||Zr==null||Zr!==Wr(r)||(r=Zr,`selectionStart`in r&&Yr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),$r&&Ur($r,r)||($r=r,r=Jf(Qr,`onSelect`),0>=o,i-=o,Zi=1<<32-rt(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),B&&$i(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(a,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(a,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(a,h),B&&$i(a,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(a,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return B&&$i(a,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,a,g,v.value,l),v!==null&&(e&&(_=v.alternate,_!==null&&h.delete(_.key===null?g:_.key)),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(a,e)}),B&&$i(a,g),u}function _(e,r,o,c){if(typeof o==`object`&&o&&o.type===ie&&o.key===null&&o.props.ref===void 0&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case E:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===ie){if(r.tag===7){n(e,r.sibling),c=a(r,o.props.children),so(c,o),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===D&&eo(l)===r.type){n(e,r.sibling),c=a(r,o.props),so(c,o),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}o.type===ie?(c=Ri(o.props.children,e.mode,c,o.key),so(c,o),c.return=e,e=c):(c=Li(o.type,o.key,o.props,null,e.mode,c),so(c,o),c.return=e,e=c)}return s(e);case re:a:{for(l=o.key;r!==null;){if(r.key===l){if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=a(r,o.children||[]),c.return=e,e=c;break a}n(e,r);break}t(e,r),r=r.sibling}c=Vi(o,e.mode,c),c.return=e,e=c}return s(e);case D:return o=eo(o),_(e,r,o,c)}if(Se(o))return h(e,r,o,c);if(ye(o)){if(l=ye(o),typeof l!=`function`)throw Error(i(150));return o=l.call(o),g(e,r,o,c)}if(typeof o.then==`function`)return _(e,r,oo(o),c);if(o.$$typeof===ce)return _(e,r,Ea(e,o),c);co(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=a(r,o),c.return=e,e=c):(n(e,r),c=zi(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{ao=0;var i=_(e,t,n,r);return io=null,i}catch(t){if(t===Ja||t===Xa)throw t;var a=Ni(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var uo=lo(!0),fo=lo(!1),po=!1;function mo(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function ho(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function go(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function _o(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,K&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=Ai(e),ki(e,null,n),t}return Ei(e,r,t,n),Ai(e)}function vo(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,bt(e,n)}}function yo(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var bo=!1;function xo(){if(bo){var e=za;if(e!==null)throw e}}function So(e,t,n,r){bo=!1;var i=e.updateQueue;po=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,p=f!==s.lane;if(p?(Y&f)===f:(r&f)===f){f!==0&&f===Ra&&(bo=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var m=e,h=s;f=t;var g=n;switch(h.tag){case 1:if(m=h.payload,typeof m==`function`){d=m.call(g,d,f);break a}d=m;break a;case 3:m.flags=m.flags&-65537|128;case 0:if(m=h.payload,f=typeof m==`function`?m.call(g,d,f):m,f==null)break a;d=w({},d,f);break a;case 2:po=!0}}f=s.callback,f!==null&&(e.flags|=64,p&&(e.flags|=8192),p=i.callbacks,p===null?i.callbacks=[f]:p.push(f))}else p={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=p,c=d):u=u.next=p,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;p=s,s=p.next,p.next=null,i.lastBaseUpdate=p,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),od|=o,e.lanes=o,e.memoizedState=d}}function Co(e,t){if(typeof e!=`function`)throw Error(i(191,e));e.call(t)}function wo(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=O.T,s={};s.types=o===null?null:o.types,O.T=s,uc(e,!1,t,n);try{var c=i(),l=O.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?lc(e,t,Ha(c,r),jd(e)):lc(e,t,r,jd(e))}catch(n){lc(e,t,{then:function(){},status:`rejected`,reason:n},jd())}finally{k.p=a,o!==null&&s.types!==null&&(o.types=s.types),O.T=o}}function $s(){}function ec(e,t,n,r){if(e.tag!==5)throw Error(i(476));var a=tc(e).queue;Qs(e,a,t,Ce,n===null?$s:function(){return nc(e),n(r)})}function tc(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:Ce,baseState:Ce,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:ds,lastRenderedState:Ce},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:ds,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function nc(e){var t=tc(e);t.next===null&&(t=e.alternate.memoizedState),lc(e,t.next.queue,{},jd())}function rc(){return Ta(sh)}function ic(){return os().memoizedState}function ac(){return os().memoizedState}function oc(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=jd();e=go(n);var r=_o(t,e,n);r!==null&&(Pd(r,t,n),vo(r,t,n)),t={cache:ja()},e.payload=t;return}t=t.return}}function sc(e,t,n){var r=jd();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},dc(e)?fc(t,n):(n=Di(e,t,n,r),n!==null&&(Pd(n,e,r),pc(n,t,r)))}function cc(e,t,n){lc(e,t,n,jd())}function lc(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(dc(e))fc(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,Hr(s,o))return Ei(e,t,i,0),q===null&&Ti(),!1}catch{}if(n=Di(e,t,i,r),n!==null)return Pd(n,e,r),pc(n,t,r),!0}return!1}function uc(e,t,n,r){if(r={lane:2,revertLane:Pf(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},dc(e)){if(t)throw Error(i(479))}else t=Di(e,n,r,2),t!==null&&Pd(t,e,2)}function dc(e){var t=e.alternate;return e===H||t!==null&&t===H}function fc(e,t){Wo=Uo=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function pc(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,bt(e,n)}}var mc={readContext:Ta,use:ls,useCallback:Xo,useContext:Xo,useEffect:Xo,useImperativeHandle:Xo,useLayoutEffect:Xo,useInsertionEffect:Xo,useMemo:Xo,useReducer:Xo,useRef:Xo,useState:Xo,useDebugValue:Xo,useDeferredValue:Xo,useTransition:Xo,useSyncExternalStore:Xo,useId:Xo,useHostTransitionStatus:Xo,useFormState:Xo,useActionState:Xo,useOptimistic:Xo,useMemoCache:Xo,useCacheRefresh:Xo,useEffectEvent:Xo},hc={readContext:Ta,use:ls,useCallback:function(e,t){return as().memoizedState=[e,t===void 0?null:t],e},useContext:Ta,useEffect:zs,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),Ls(4194308,4,Gs.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Ls(4194308,4,e,t)},useInsertionEffect:function(e,t){Ls(4,2,e,t)},useMemo:function(e,t){var n=as();t=t===void 0?null:t;var r=e();if(Go){nt(!0);try{e()}finally{nt(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=as();if(n!==void 0){var i=n(t);if(Go){nt(!0);try{n(t)}finally{nt(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=sc.bind(null,H,e),[r.memoizedState,e]},useRef:function(e){var t=as();return e={current:e},t.memoizedState=e},useState:function(e){e=xs(e);var t=e.queue,n=cc.bind(null,H,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:qs,useDeferredValue:function(e,t){return Xs(as(),e,t)},useTransition:function(){var e=xs(!1);return e=Qs.bind(null,H,e.queue,!0,!1),as().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=H,a=as();if(B){if(n===void 0)throw Error(i(407));n=n()}else{if(n=t(),q===null)throw Error(i(349));Y&127||gs(r,t,n)}a.memoizedState=n;var o={value:n,getSnapshot:t};return a.queue=o,zs(vs.bind(null,r,o,e),[e]),r.flags|=2048,Fs(9,{destroy:void 0},_s.bind(null,r,o,n,t),null),n},useId:function(){var e=as(),t=q.identifierPrefix;if(B){var n=Qi,r=Zi;n=(r&~(1<<32-rt(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=Ko++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(a,{is:r.is}):s.createElement(a)}}o[Dt]=t,o[Ot]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(np(o,a,r),a){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&pl(t)}}return W(t),t.subtreeFlags&=-33554433,ml(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&pl(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(i(166));if(e=M.current,da(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,a=ia,a!==null)switch(a.tag){case 27:case 5:r=a.memoizedProps}e[Dt]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||ep(e.nodeValue,n)),e||ca(t,!0)}else e=lp(e).createTextNode(r),e[Dt]=t,t.stateNode=e}return W(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=da(t),n!==null){if(e===null){if(!r)throw Error(i(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(i(557));e[Dt]=t}else fa(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;W(t),e=!1}else n=pa(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(Io(t),t):(Io(t),null);if(t.flags&128)throw Error(i(558))}return W(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(a=da(t),r!==null&&r.dehydrated!==null){if(e===null){if(!a)throw Error(i(318));if(a=t.memoizedState,a=a===null?null:a.dehydrated,!a)throw Error(i(317));a[Dt]=t}else fa(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;W(t),a=!1}else a=pa(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(Io(t),t):(Io(t),null)}return Io(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,a=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(a=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==a&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),gl(t,t.updateQueue),W(t),null);case 4:return Ae(),e===null&&Wf(t.stateNode.containerInfo),t.flags|=67108864,W(t),null;case 10:return ya(t.type),W(t),null;case 19:if(zo(t),r=t.memoizedState,r===null)return W(t),null;if(a=!!(t.flags&128),o=r.rendering,o===null){if(a)_l(r,!1);else{if(ad!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=Bo(e),o!==null){for(t.flags|=128,_l(r,!1),e=o.updateQueue,t.updateQueue=e,gl(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)Ii(n,e),n=n.sibling;return Ro(t,Lo.current&1|2),B&&$i(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&Ge()>gd&&(t.flags|=128,a=!0,_l(r,!1),t.lanes=4194304)}}else{if(!a){if(e=Bo(o),e!==null){if(t.flags|=128,a=!0,e=e.updateQueue,t.updateQueue=e,gl(t,e),_l(r,!0),r.tail===null&&r.tailMode!==`collapsed`&&r.tailMode!==`visible`&&!o.alternate&&!B)return W(t),null}else 2*Ge()-r.renderingStartTime>gd&&n!==536870912&&(t.flags|=128,a=!0,_l(r,!1),t.lanes=4194304)}r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}if(r.tail!==null){e=r.tail;a:{for(n=e;n!==null;){if(n.alternate!==null){n=!1;break a}n=n.sibling}n=!0}return r.rendering=e,r.tail=e.sibling,r.renderingStartTime=Ge(),e.sibling=null,o=Lo.current,o=a?o&1|2:o&1,r.tailMode===`visible`||r.tailMode===`collapsed`||!n||B?Ro(t,o):(n=o,A(Ao,t),A(Lo,n),jo===null&&(jo=t)),B&&$i(t,r.treeForkCount),e}return W(t),null;case 22:case 23:return Io(t),ko(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(W(t),t.subtreeFlags&6&&(t.flags|=8192)):W(t),n=t.updateQueue,n!==null&&gl(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&De(Wa),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),ya(V),W(t),null;case 25:return null;case 30:return t.flags|=33554432,W(t),null}throw Error(i(156,t.tag))}function yl(e,t){switch(na(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return ya(V),Ae(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return Me(t),null;case 31:if(t.memoizedState!==null){if(Io(t),t.alternate===null)throw Error(i(340));fa()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(Io(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(i(340));fa()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return zo(t),e=t.flags,e&65536?(t.flags=e&-65537|128,e=t.memoizedState,e!==null&&(e.rendering=null,e.tail=null),t.flags|=4,t):null;case 4:return Ae(),null;case 10:return ya(t.type),null;case 22:case 23:return Io(t),ko(),e!==null&&De(Wa),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return ya(V),null;case 25:return null;default:return null}}function bl(e,t){switch(na(t),t.tag){case 3:ya(V),Ae();break;case 26:case 27:case 5:Me(t);break;case 4:Ae();break;case 31:t.memoizedState!==null&&Io(t);break;case 13:Io(t);break;case 19:zo(t);break;case 10:ya(t.type);break;case 22:case 23:Io(t),ko(),e!==null&&De(Wa);break;case 24:ya(V)}}function xl(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Z(t,t.return,e)}}function Sl(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Z(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Z(t,t.return,e)}}function Cl(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{wo(t,n)}catch(t){Z(e,e.return,t)}}}function wl(e,t,n){n.props=Sc(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Z(e,t,n)}}function Tl(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:var i=e.stateNode,a=vi(e.memoizedProps,i);(i.ref===null||i.ref.name!==a)&&(i.ref=Pp(a)),r=i.ref;break;case 7:if(e.stateNode===null){var o=new Fp(e);m(e.child,!1,Qp,o,void 0,void 0),e.stateNode=o}r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Z(e,t,n)}}function El(e,t){var n=e.ref,r=e.refCleanup;if(n!==null){if(typeof r==`function`)try{r()}catch(n){Z(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Z(e,t,n)}else n.current=null}}function Dl(e,t){if((e.tag===5||e.tag===27||e.tag===6)&&e.alternate===null&&t!==null)for(var n=0;n title`))),np(r,t,n),r[Dt]=e,Vt(r),t=r;break a;case`link`:if(o=Gm(`link`,`href`,a).get(t+(n.href||``))){for(s=0;sg&&(o=g,g=h,h=o);var _=Kr(s,h),v=Kr(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,O.T=null,n=wd,wd=null;var o=bd,s=Sd;if(yd=0,xd=bd=null,Sd=0,K&6)throw Error(i(331));var c=K;if(K|=4,Yu(o.current),Vu(o,o.current,s,n),K=c,Df(0,!1),tt&&typeof tt.onPostCommitFiberRoot==`function`)try{tt.onPostCommitFiberRoot(et,o)}catch{}return!0}finally{k.p=a,O.T=r,uf(e,t)}}function pf(e,t,n){t=Ui(n,t),t=Oc(e.stateNode,t,2),e=_o(e,t,2),e!==null&&(_t(e,2),Ef(e))}function Z(e,t,n){if(e.tag===3)pf(e,e,n);else for(;t!==null;){if(t.tag===3){pf(t,e,n);break}if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(vd===null||!vd.has(r))){e=Ui(n,e),n=kc(2),r=_o(t,n,2),r!==null&&(Ac(n,r,t,e),_t(r,2),Ef(r));break}}t=t.return}}function mf(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new $u;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(rd=!0,i.add(n),e=hf.bind(null,e,t,n),t.then(e,e))}function hf(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,q===e&&(Y&n)===n&&(ad===4||ad===3&&(Y&62914560)===Y&&300>Ge()-md?K&2?cd|=n:Vd(e,0):cd|=n,ud===Y&&(ud=0)),Ef(e)}function gf(e,t){t===0&&(t=ht()),e=Oi(e,t),e!==null&&(_t(e,t),Ef(e))}function _f(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),gf(e,n)}function vf(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,a=e.memoizedState;a!==null&&(n=a.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(i(314))}r!==null&&r.delete(t),gf(e,n)}function yf(e,t){return Ve(e,t)}var bf=null,xf=null,Sf=!1,Cf=!1,wf=!1,Tf=0;function Ef(e){e!==xf&&e.next===null&&(xf===null?bf=xf=e:xf=xf.next=e),Cf=!0,Sf||(Sf=!0,Nf())}function Df(e,t){if(!wf&&Cf){wf=!0;do for(var n=!1,r=bf;r!==null;){if(!t){if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-rt(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,Mf(r,a))}else a=Y,a=dt(r,r===q?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||ft(r,a)||(n=!0,Mf(r,a))}r=r.next}while(n);wf=!1}}function Of(){kf()}function kf(){Cf=Sf=!1;var e=0;Tf!==0&&hp()&&(e=Tf);for(var t=Ge(),n=null,r=bf;r!==null;){var i=r.next,a=Af(r,t);a===0?(r.next=null,n===null?bf=i:n.next=i,i===null&&(xf=n)):(n=r,(e!==0||a&3)&&(Cf=!0)),r=i}yd!==0&&yd!==5||Df(e,!1),Tf!==0&&(Tf=0)}function Af(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&ap(d)&&(c=c.responseEnd,o+=u*(c$m){s.length=o;break}f=new Promise(jp.bind(f)),s.push(f)}}}if(0`u`?null:document;function Tm(e,t,n){var r=wm;if(r&&typeof t==`string`&&t){var i=cn(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),ym.has(i)||(ym.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),np(t,`link`,e),Vt(t),r.head.appendChild(t)))}}function Em(e){xm.D(e),Tm(`dns-prefetch`,e,null)}function Dm(e,t){xm.C(e,t),Tm(`preconnect`,e,t)}function Om(e,t,n){xm.L(e,t,n);var r=wm;if(r&&e&&t){var i=`link[rel="preload"][as="`+cn(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+cn(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+cn(n.imageSizes)+`"]`)):i+=`[href="`+cn(e)+`"]`;var a=i;switch(t){case`style`:a=Pm(e);break;case`script`:a=Rm(e)}if(!(vm.has(a)||(e=w({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),vm.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(Fm(a))||t===`script`&&r.querySelector(zm(a))))){var o=r.createElement(`link`);np(o,`link`,e),t===`style`&&(o[Ft]=!0,o.onload=o.onerror=function(){Ht(o)}),Vt(o),r.head.appendChild(o)}}}function km(e,t){xm.m(e,t);var n=wm;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+cn(r)+`"][href="`+cn(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Rm(e)}if(!vm.has(a)&&(e=w({rel:`modulepreload`,href:e},t),vm.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(zm(a)))return}r=n.createElement(`link`),np(r,`link`,e),Vt(r),n.head.appendChild(r)}}}function Am(e,t,n){xm.S(e,t,n);var r=wm;if(r&&e){var i=Bt(r).hoistableStyles,a=Pm(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(Fm(a)))s.loading=5;else{e=w({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=vm.get(a))&&Hm(e,n);var c=o=r.createElement(`link`);Vt(c),np(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Vm(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function jm(e,t){xm.X(e,t);var n=wm;if(n&&e){var r=Bt(n).hoistableScripts,i=Rm(e),a=r.get(i);a||(a=n.querySelector(zm(i)),a||(e=w({src:e,async:!0},t),(t=vm.get(i))&&Um(e,t),a=n.createElement(`script`),Vt(a),np(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Mm(e,t){xm.M(e,t);var n=wm;if(n&&e){var r=Bt(n).hoistableScripts,i=Rm(e),a=r.get(i);a||(a=n.querySelector(zm(i)),a||(e=w({src:e,async:!0,type:`module`},t),(t=vm.get(i))&&Um(e,t),a=n.createElement(`script`),Vt(a),np(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Nm(e,t,n,r){var a=(a=M.current)?bm(a):null;if(!a)throw Error(i(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(n=Pm(n.href),t=Bt(a).hoistableStyles,r=t.get(n),r||(r={type:`style`,instance:null,count:0,state:null},t.set(n,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Pm(n.href);var o=Bt(a).hoistableStyles,s=o.get(e);if(s||(a=a.ownerDocument||a,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=a.querySelector(Fm(e)))?o._p||(s.instance=o,s.state.loading=5):(o=vm.get(e),o||(o={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},vm.set(e,o)),Lm(a,e,o,s.state))),t&&r===null)throw Error(i(528,``));return s}if(t&&r!==null)throw Error(i(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(n=Rm(n),t=Bt(a).hoistableScripts,r=t.get(n),r||(r={type:`script`,instance:null,count:0,state:null},t.set(n,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(i(444,e))}}function Pm(e){return`href="`+cn(e)+`"`}function Fm(e){return`link[rel="stylesheet"][`+e+`]`}function Im(e){return w({},e,{"data-precedence":e.precedence,precedence:null})}function Lm(e,t,n,r){if(t=e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)){if(!0!==t[Ft]){r.loading=1;return}}else t=e.createElement(`link`),t[Ft]=!0,t.onload=t.onerror=Ht.bind(null,t),np(t,`link`,n),Vt(t),e.head.appendChild(t);r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2})}function Rm(e){return`[src="`+cn(e)+`"]`}function zm(e){return`script[async]`+e}function Bm(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+cn(n.href)+`"]`);if(r)return t.instance=r,Vt(r),r;var a=w({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),Vt(r),np(r,`style`,a),Vm(r,n.precedence,e),t.instance=r;case`stylesheet`:a=Pm(n.href);var o=e.querySelector(Fm(a));if(o)return t.state.loading|=4,t.instance=o,Vt(o),o;r=Im(n),(a=vm.get(a))&&Hm(r,a),o=(e.ownerDocument||e).createElement(`link`),Vt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),np(o,`link`,r),t.state.loading|=4,Vm(o,n.precedence,e),t.instance=o;case`script`:return o=Rm(n.src),(a=e.querySelector(zm(o)))?(t.instance=a,Vt(a),a):(r=n,(a=vm.get(o))&&(r=w({},n),Um(r,a)),e=e.ownerDocument||e,a=e.createElement(`script`),Vt(a),np(a,`link`,r),e.head.appendChild(a),t.instance=a);case`void`:return null;default:throw Error(i(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Vm(r,n.precedence,e));return t.instance}function Vm(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function qm(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Jm(e,t){return e===`img`&&t.src!=null&&t.src!==``&&t.onLoad==null&&t.loading!==`lazy`}function Ym(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Xm(e){return(e.width||100)*(e.height||100)*(typeof devicePixelRatio==`number`?devicePixelRatio:1)*.25}function Zm(e,t){typeof t.decode==`function`&&(e.imgCount++,t.complete||(e.imgBytes+=Xm(t),e.suspenseyImages.push(t)),e=rh.bind(e),t.decode().then(e,e))}function Qm(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Pm(r.href),a=t.querySelector(Fm(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=nh.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,Vt(a);return}a=t.ownerDocument||t,r=Im(r),(i=vm.get(i))&&Hm(r,i),a=a.createElement(`link`),Vt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),np(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=nh.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var $m=0;function eh(e,t){return e.stylesheets&&e.count===0&&ah(e,e.stylesheets),0$m?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function th(e){if(e.count===0&&(e.imgCount===0||!e.waitingForImages)){if(e.stylesheets)ah(e,e.stylesheets);else if(e.unsuspend){var t=e.unsuspend;e.unsuspend=null,t()}}}function nh(){this.count--,th(this)}function rh(){this.imgCount--,th(this)}var ih=null;function ah(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,ih=new Map,t.forEach(oh,e),ih=null,nh.call(e))}function oh(e,t){if(!(t.state.loading&4)){var n=ih.get(e);if(n)var r=n.get(null);else{n=new Map,ih.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<`u`&&typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE==`function`)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=g()})),v=d(),y=_();async function b(e){let t=await fetch(e,{cache:`no-store`});if(!t.ok)throw Error(t.status===404?`Not found, or not readable from the viewer.`:`HTTP ${t.status}`);return await t.json()}var x=()=>b(`/api/tree`),ee=e=>b(`/api/page?path=`+encodeURIComponent(e)),te=e=>b(`/api/source?path=`+encodeURIComponent(e));function ne(e){let t=``;for(let n of e.toLowerCase())n===` `?t+=`-`:/[\p{L}\p{N}_-]/u.test(n)&&(t+=n);return t}var S=/\[\[([^[\]]+)\]\]/g,C=/\badr:(\d{4}-[a-z0-9][a-z0-9-]*)\b/g,w=/^[ \t]{0,3}(`{3,}|~{3,})/,T=/^(.+?):(\d+)(?:-(\d+))?$/;function E(e,t){return`#/page/`+encodeURI(e)+(t?`?h=`+encodeURIComponent(t):``)}function re(e,t,n){let r=`#/source/`+encodeURI(e);return t!==void 0&&(r+=`:`+t+(n!==void 0&&n!==t?`-`+n:``)),r}function ie(e){let t=null;return e.split(` +`).map(e=>{let n=w.exec(e);return t===null?n?(t=n[1],e):e.split(/(`+[^`]*`+)/).map((e,t)=>t%2==1?ae(e):oe(e)).join(``):(n&&n[1][0]===t[0]&&n[1].length>=t.length&&(t=null),e)}).join(` +`)}function ae(e){let t=/^`+\s*adr:(\d{4}-[a-z0-9][a-z0-9-]*)\s*`+$/.exec(e);return t?`[${e}](${E(`docs/adr/${t[1]}.md`)})`:e}function oe(e){return e.replace(S,(e,t)=>{let[n,r]=t.split(`|`,2).map(e=>e.trim());return`[${r||n}](${E(`docs/wiki/pages/${n}.md`)})`}).replace(C,(e,t)=>`[${e}](${E(`docs/adr/${t}.md`)})`)}function se(e,t,n){if(e===``){let e=T.exec(t.trim());if(!e)return null;let n=le(e[1]);return n===null?null:{internal:re(n,Number(e[2]),e[3]?Number(e[3]):void 0)}}if(e.startsWith(`#/`))return{internal:e};if(e.startsWith(`#`))return{internal:E(n,e.slice(1))};if(/^[a-z][a-z0-9+.-]*:/i.test(e)||e.startsWith(`//`))return/^(https?|mailto):/i.test(e)?{external:e}:null;let[r,i]=ue(e,`#`),a=n.includes(`/`)?n.slice(0,n.lastIndexOf(`/`)+1):``,o=le(r.startsWith(`/`)?r.slice(1):a+de(r));return o===null?null:o.endsWith(`.md`)?{internal:E(o,i||void 0)}:{internal:re(o)}}function ce(e){let t=e.replace(/^#/,``);if(t.startsWith(`/page/`)){let[e,n]=ue(t.slice(6),`?`),r=new URLSearchParams(n).get(`h`)??void 0;return{kind:`page`,path:de(e),heading:r}}if(t.startsWith(`/source/`)){let e=de(t.slice(8)),n=/^(.*?):(\d+)(?:-(\d+))?$/.exec(e);if(!n)return{kind:`source`,path:e};let r=Number(n[2]);return{kind:`source`,path:n[1],from:r,to:n[3]?Number(n[3]):r}}return{kind:`home`}}function le(e){let t=[];for(let n of e.split(`/`))if(n!==``&&n!==`.`){if(n===`..`){if(t.length===0)return null;t.pop()}else t.push(n)}return t.length?t.join(`/`):null}function ue(e,t){let n=e.indexOf(t);return n<0?[e,``]:[e.slice(0,n),e.slice(n+1)]}function de(e){try{return decodeURI(e)}catch{return e}}var fe=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})),D=o(((e,t)=>{t.exports=fe()}))();function pe({done:e,total:t}){if(t===0)return(0,D.jsx)(`span`,{className:`muted small`,children:`no tasks`});let n=Math.round(e/t*100);return(0,D.jsxs)(`span`,{className:`progress`,title:`${e} of ${t} tasks done`,children:[(0,D.jsx)(`span`,{className:`bar`,role:`progressbar`,"aria-valuemin":0,"aria-valuemax":t,"aria-valuenow":e,children:(0,D.jsx)(`span`,{className:`fill`,style:{width:`${n}%`}})}),(0,D.jsxs)(`span`,{className:`small`,children:[e,`/`,t]})]})}function me({tree:e}){if(!e)return(0,D.jsx)(`p`,{className:`muted`,children:`Loading…`});let t=t=>e.groups.find(e=>e.id===t)?.items??[],n=t(`plans`),r=t(`specs`).filter(e=>e.kind===`tasks`),i=t(`wiki`).find(e=>e.path===`docs/wiki/index.md`);return(0,D.jsxs)(`article`,{className:`home`,children:[(0,D.jsxs)(`header`,{className:`page-head`,children:[(0,D.jsx)(`h1`,{children:e.workspace}),(0,D.jsx)(`p`,{className:`muted`,children:`The workspace's record: what was decided, what is being built, and how far along it is.`})]}),(0,D.jsx)(`div`,{className:`cards`,children:e.groups.map(e=>(0,D.jsxs)(`a`,{className:`card`,href:e.items[0]?E(he(e.id,e.items)):void 0,children:[(0,D.jsx)(`span`,{className:`card-n`,children:e.id===`specs`?new Set(e.items.map(e=>e.path.split(`/`)[1])).size:e.items.length}),(0,D.jsx)(`span`,{className:`card-t`,children:e.title})]},e.id))}),(n.length>0||r.length>0)&&(0,D.jsxs)(`section`,{children:[(0,D.jsx)(`h2`,{children:`Progress`}),(0,D.jsx)(`ul`,{className:`progress-list`,children:[...n,...r].map(e=>(0,D.jsxs)(`li`,{children:[(0,D.jsx)(`a`,{href:E(e.path),children:e.kind===`tasks`?e.path.split(`/`)[1]:e.title}),(0,D.jsx)(`span`,{className:`muted small`,children:e.kind===`plan`?`plan`:`spec`}),(0,D.jsx)(pe,{done:e.done,total:e.total})]},e.path))})]}),i&&(0,D.jsxs)(`p`,{children:[`Start with the `,(0,D.jsx)(`a`,{href:E(i.path),children:`wiki index`}),`.`]})]})}function he(e,t){return e===`wiki`?t.find(e=>e.path===`docs/wiki/index.md`)?.path??t[0].path:t[0].path}function ge(e,t){let n=t||{};return(e[e.length-1]===``?[...e,``]:e).join((n.padRight?` `:``)+`,`+(n.padLeft===!1?``:` `)).trim()}var _e=/^[$_\p{ID_Start}][$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,ve=/^[$_\p{ID_Start}][-$_\u{200C}\u{200D}\p{ID_Continue}]*$/u,ye={};function be(e,t){return((t||ye).jsx?ve:_e).test(e)}var xe=/[ \t\n\f\r]/g;function Se(e){return typeof e==`object`?e.type===`text`&&O(e.value):O(e)}function O(e){return e.replace(xe,``)===``}var k=class{constructor(e,t,n){this.normal=t,this.property=e,n&&(this.space=n)}};k.prototype.normal={},k.prototype.property={},k.prototype.space=void 0;function Ce(e,t){let n={},r={};for(let t of e)Object.assign(n,t.property),Object.assign(r,t.normal);return new k(n,r,t)}function we(e){return e.toLowerCase()}var Te=class{constructor(e,t){this.attribute=t,this.property=e}};Te.prototype.attribute=``,Te.prototype.booleanish=!1,Te.prototype.boolean=!1,Te.prototype.commaOrSpaceSeparated=!1,Te.prototype.commaSeparated=!1,Te.prototype.defined=!1,Te.prototype.mustUseProperty=!1,Te.prototype.number=!1,Te.prototype.overloadedBoolean=!1,Te.prototype.property=``,Te.prototype.spaceSeparated=!1,Te.prototype.space=void 0;var Ee=s({boolean:()=>A,booleanish:()=>j,commaOrSpaceSeparated:()=>Ae,commaSeparated:()=>ke,number:()=>M,overloadedBoolean:()=>Oe,spaceSeparated:()=>N}),De=0,A=je(),j=je(),Oe=je(),M=je(),N=je(),ke=je(),Ae=je();function je(){return 2**++De}var Me=Object.keys(Ee),Ne=class extends Te{constructor(e,t,n,r){let i=-1;if(super(e,t),Pe(this,`space`,r),typeof n==`number`)for(;++i4&&n.slice(0,4)===`data`&&qe.test(t)){if(t.charAt(4)===`-`){let e=t.slice(5).replace(Ke,Xe);r=`data`+e.charAt(0).toUpperCase()+e.slice(1)}else{let e=t.slice(4);if(!Ke.test(e)){let n=e.replace(Ge,Ye);n.charAt(0)!==`-`&&(n=`-`+n),t=`data`+n}}i=Ne}return new i(r,t)}function Ye(e){return`-`+e.toLowerCase()}function Xe(e){return e.charAt(1).toUpperCase()}var Ze=Ce([Ie,ze,Ve,He,Ue],`html`),Qe=Ce([Ie,Be,Ve,He,Ue],`svg`);function $e(e){return e.join(` `).trim()}var et=o(((e,t)=>{var n=/\/\*[^*]*\*+([^/*][^*]*\*+)*\//g,r=/\n/g,i=/^\s*/,a=/^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/,o=/^:\s*/,s=/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/,c=/^[;\s]*/,l=/^\s+|\s+$/g;function u(e,t){if(typeof e!=`string`)throw TypeError(`First argument must be a string`);if(!e)return[];t||={};var l=1,u=1;function f(e){var t=e.match(r);t&&(l+=t.length);var n=e.lastIndexOf(` +`);u=~n?e.length-n:u+e.length}function p(){var e={line:l,column:u};return function(t){return t.position=new m(e),_(),t}}function m(e){this.start=e,this.end={line:l,column:u},this.source=t.source}m.prototype.content=e;function h(n){var r=Error(t.source+`:`+l+`:`+u+`: `+n);if(r.reason=n,r.filename=t.source,r.line=l,r.column=u,r.source=e,!t.silent)throw r}function g(t){var n=t.exec(e);if(n){var r=n[0];return f(r),e=e.slice(r.length),n}}function _(){g(i)}function v(e){var t;for(e||=[];t=y();)t!==!1&&e.push(t);return e}function y(){var t=p();if(e.charAt(0)==`/`&&e.charAt(1)==`*`){for(var n=2;e.charAt(n)!=``&&(e.charAt(n)!=`*`||e.charAt(n+1)!=`/`);)++n;if(n+=2,e.charAt(n-1)===``)return h(`End of comment missing`);var r=e.slice(2,n-2);return u+=2,f(r),e=e.slice(n),u+=2,t({type:`comment`,comment:r})}}function b(){var e=p(),t=g(a);if(t){if(y(),!g(o))return h(`property missing ':'`);var r=g(s),i=e({type:`declaration`,property:d(t[0].replace(n,``)),value:r?d(r[0].replace(n,``)):``});return g(c),i}}function x(){var e=[];v(e);for(var t;t=b();)t!==!1&&(e.push(t),v(e));return e}return _(),x()}function d(e){return e?e.replace(l,``):``}t.exports=u})),tt=o((e=>{var t=e&&e.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.default=r;var n=t(et());function r(e,t){let r=null;if(!e||typeof e!=`string`)return r;let i=(0,n.default)(e),a=typeof t==`function`;return i.forEach(e=>{if(e.type!==`declaration`)return;let{property:n,value:i}=e;a?t(n,i,e):i&&(r||={},r[n]=i)}),r}})),nt=o((e=>{Object.defineProperty(e,"__esModule",{value:!0}),e.camelCase=void 0;var t=/^--[a-zA-Z0-9_-]+$/,n=/-([a-z])/g,r=/^[^-]+$/,i=/^-(webkit|moz|ms|o|khtml)-/,a=/^-(ms)-/,o=function(e){return!e||r.test(e)||t.test(e)},s=function(e,t){return t.toUpperCase()},c=function(e,t){return`${t}-`};e.camelCase=function(e,t){return t===void 0&&(t={}),o(e)?e:(e=e.toLowerCase(),e=t.reactCompat?e.replace(a,c):e.replace(i,c),e.replace(n,s))}})),rt=o(((e,t)=>{var n=(e&&e.__importDefault||function(e){return e&&e.__esModule?e:{default:e}})(tt()),r=nt();function i(e,t){var i={};return!e||typeof e!=`string`||(0,n.default)(e,function(e,n){e&&n&&(i[(0,r.camelCase)(e,t)]=n)}),i}i.default=i,t.exports=i})),it=ot(`end`),at=ot(`start`);function ot(e){return t;function t(t){let n=t&&t.position&&t.position[e]||{};if(typeof n.line==`number`&&n.line>0&&typeof n.column==`number`&&n.column>0)return{line:n.line,column:n.column,offset:typeof n.offset==`number`&&n.offset>-1?n.offset:void 0}}}function st(e){let t=at(e),n=it(e);if(t&&n)return{start:t,end:n}}function ct(e){return!e||typeof e!=`object`?``:`position`in e||`type`in e?ut(e.position):`start`in e||`end`in e?ut(e):`line`in e||`column`in e?lt(e):``}function lt(e){return dt(e&&e.line)+`:`+dt(e&&e.column)}function ut(e){return lt(e&&e.start)+`-`+lt(e&&e.end)}function dt(e){return e&&typeof e==`number`?e:1}var ft=class extends Error{constructor(e,t,n){super(),typeof t==`string`&&(n=t,t=void 0);let r=``,i={},a=!1;if(t&&(i=`line`in t&&`column`in t||`start`in t&&`end`in t?{place:t}:`type`in t?{ancestors:[t],place:t.position}:{...t}),typeof e==`string`?r=e:!i.cause&&e&&(a=!0,r=e.message,i.cause=e),!i.ruleId&&!i.source&&typeof n==`string`){let e=n.indexOf(`:`);e===-1?i.ruleId=n:(i.source=n.slice(0,e),i.ruleId=n.slice(e+1))}if(!i.place&&i.ancestors&&i.ancestors){let e=i.ancestors[i.ancestors.length-1];e&&(i.place=e.position)}let o=i.place&&`start`in i.place?i.place.start:i.place;this.ancestors=i.ancestors||void 0,this.cause=i.cause||void 0,this.column=o?o.column:void 0,this.fatal=void 0,this.file=``,this.message=r,this.line=o?o.line:void 0,this.name=ct(i.place)||`1:1`,this.place=i.place||void 0,this.reason=this.message,this.ruleId=i.ruleId||void 0,this.source=i.source||void 0,this.stack=a&&i.cause&&typeof i.cause.stack==`string`?i.cause.stack:``,this.actual=void 0,this.expected=void 0,this.note=void 0,this.url=void 0}};ft.prototype.file=``,ft.prototype.name=``,ft.prototype.reason=``,ft.prototype.message=``,ft.prototype.stack=``,ft.prototype.column=void 0,ft.prototype.line=void 0,ft.prototype.ancestors=void 0,ft.prototype.cause=void 0,ft.prototype.fatal=void 0,ft.prototype.place=void 0,ft.prototype.ruleId=void 0,ft.prototype.source=void 0;var pt=l(rt(),1),mt={}.hasOwnProperty,ht=new Map,gt=/[A-Z]/g,_t=new Set([`table`,`tbody`,`thead`,`tfoot`,`tr`]),vt=new Set([`td`,`th`]),yt=`https://github.com/syntax-tree/hast-util-to-jsx-runtime`;function bt(e,t){if(!t||t.Fragment===void 0)throw TypeError("Expected `Fragment` in options");let n=t.filePath||void 0,r;if(t.development){if(typeof t.jsxDEV!=`function`)throw TypeError("Expected `jsxDEV` in options when `development: true`");r=jt(n,t.jsxDEV)}else{if(typeof t.jsx!=`function`)throw TypeError("Expected `jsx` in production options");if(typeof t.jsxs!=`function`)throw TypeError("Expected `jsxs` in production options");r=At(n,t.jsx,t.jsxs)}let i={Fragment:t.Fragment,ancestors:[],components:t.components||{},create:r,elementAttributeNameCase:t.elementAttributeNameCase||`react`,evaluater:t.createEvaluater?t.createEvaluater():void 0,filePath:n,ignoreInvalidStyle:t.ignoreInvalidStyle||!1,passKeys:t.passKeys!==!1,passNode:t.passNode||!1,schema:t.space===`svg`?Qe:Ze,stylePropertyNameCase:t.stylePropertyNameCase||`dom`,tableCellAlignToStyle:t.tableCellAlignToStyle!==!1},a=xt(i,e,void 0);return a&&typeof a!=`string`?a:i.create(e,i.Fragment,{children:a||void 0},void 0)}function xt(e,t,n){if(t.type===`element`)return St(e,t,n);if(t.type===`mdxFlowExpression`||t.type===`mdxTextExpression`)return Ct(e,t);if(t.type===`mdxJsxFlowElement`||t.type===`mdxJsxTextElement`)return Tt(e,t,n);if(t.type===`mdxjsEsm`)return wt(e,t);if(t.type===`root`)return Et(e,t,n);if(t.type===`text`)return Dt(e,t)}function St(e,t,n){let r=e.schema,i=r;t.tagName.toLowerCase()===`svg`&&r.space===`html`&&(i=Qe,e.schema=i),e.ancestors.push(t);let a=Lt(e,t.tagName,!1),o=Mt(e,t),s=Pt(e,t);return _t.has(t.tagName)&&(s=s.filter(function(e){return typeof e!=`string`||!Se(e)})),Ot(e,o,a,t),kt(o,s),e.ancestors.pop(),e.schema=r,e.create(t,a,o,n)}function Ct(e,t){if(t.data&&t.data.estree&&e.evaluater){let n=t.data.estree.body[0];return n.type,e.evaluater.evaluateExpression(n.expression)}Rt(e,t.position)}function wt(e,t){if(t.data&&t.data.estree&&e.evaluater)return e.evaluater.evaluateProgram(t.data.estree);Rt(e,t.position)}function Tt(e,t,n){let r=e.schema,i=r;t.name===`svg`&&r.space===`html`&&(i=Qe,e.schema=i),e.ancestors.push(t);let a=t.name===null?e.Fragment:Lt(e,t.name,!0),o=Nt(e,t),s=Pt(e,t);return Ot(e,o,a,t),kt(o,s),e.ancestors.pop(),e.schema=r,e.create(t,a,o,n)}function Et(e,t,n){let r={};return kt(r,Pt(e,t)),e.create(t,e.Fragment,r,n)}function Dt(e,t){return t.value}function Ot(e,t,n,r){typeof n!=`string`&&n!==e.Fragment&&e.passNode&&(t.node=r)}function kt(e,t){if(t.length>0){let n=t.length>1?t:t[0];n&&(e.children=n)}}function At(e,t,n){return r;function r(e,r,i,a){let o=Array.isArray(i.children)?n:t;return a?o(r,i,a):o(r,i)}}function jt(e,t){return n;function n(n,r,i,a){let o=Array.isArray(i.children),s=at(n);return t(r,i,a,o,{columnNumber:s?s.column-1:void 0,fileName:e,lineNumber:s?s.line:void 0},void 0)}}function Mt(e,t){let n={},r,i;for(i in t.properties)if(i!==`children`&&mt.call(t.properties,i)){let a=Ft(e,i,t.properties[i]);if(a){let[i,o]=a;e.tableCellAlignToStyle&&i===`align`&&typeof o==`string`&&vt.has(t.tagName)?r=o:n[i]=o}}if(r){let t=n.style||={};t[e.stylePropertyNameCase===`css`?`text-align`:`textAlign`]=r}return n}function Nt(e,t){let n={};for(let r of t.attributes)if(r.type===`mdxJsxExpressionAttribute`){if(r.data&&r.data.estree&&e.evaluater){let t=r.data.estree.body[0];t.type;let i=t.expression;i.type;let a=i.properties[0];a.type,Object.assign(n,e.evaluater.evaluateExpression(a.argument))}else Rt(e,t.position)}else{let i=r.name,a;if(r.value&&typeof r.value==`object`){if(r.value.data&&r.value.data.estree&&e.evaluater){let t=r.value.data.estree.body[0];t.type,a=e.evaluater.evaluateExpression(t.expression)}else Rt(e,t.position)}else a=r.value===null||r.value;n[i]=a}return n}function Pt(e,t){let n=[],r=-1,i=e.passKeys?new Map:ht;for(;++ri?0:i+t:t>i?i:t,n=n>0?n:0,r.length<1e4)o=Array.from(r),o.unshift(t,n),e.splice(...o);else for(n&&e.splice(t,n);a0?(Xt(e,e.length,0,t),e):t}var Zt={}.hasOwnProperty;function Qt(e){let t={},n=-1;for(;++n13&&n<32||n>126&&n<160||n>55295&&n<57344||n>64975&&n<65008||(n&65535)==65535||(n&65535)==65534||n>1114111?`�`:String.fromCodePoint(n)}function nn(e){return e.replace(/[\t\n\r ]+/g,` `).replace(/^ | $/g,``).toLowerCase().toUpperCase()}var rn=pn(/[A-Za-z]/),an=pn(/[\dA-Za-z]/),on=pn(/[#-'*+\--9=?A-Z^-~]/);function sn(e){return e!==null&&(e<32||e===127)}var cn=pn(/\d/),ln=pn(/[\dA-Fa-f]/),un=pn(/[!-/:-@[-`{-~]/);function F(e){return e!==null&&e<-2}function I(e){return e!==null&&(e<0||e===32)}function L(e){return e===-2||e===-1||e===32}var dn=pn(/\p{P}|\p{S}/u),fn=pn(/\s/);function pn(e){return t;function t(t){return t!==null&&t>-1&&e.test(String.fromCharCode(t))}}function mn(e){let t=[],n=-1,r=0,i=0;for(;++n55295&&a<57344){let t=e.charCodeAt(n+1);a<56320&&t>56319&&t<57344?(o=String.fromCharCode(a,t),i=1):o=`�`}else o=String.fromCharCode(a);o&&=(t.push(e.slice(r,n),encodeURIComponent(o)),r=n+i+1,``),i&&=(n+=i,0)}return t.join(``)+e.slice(r)}function R(e,t,n,r){let i=r?r-1:1/0,a=0;return o;function o(r){return L(r)?(e.enter(n),s(r)):t(r)}function s(r){return L(r)&&a++0&&L(t)?(e.enter(r),c(t)):l(t)}function c(t){return L(t)&&o=i?t(e):n(e)}}var gn={tokenize:_n};function _n(e){let t=e.attempt(this.parser.constructs.contentInitial,r,i),n;return t;function r(n){if(n===null){e.consume(n);return}return e.enter(`lineEnding`),e.consume(n),e.exit(`lineEnding`),R(e,t,`linePrefix`)}function i(t){return e.enter(`paragraph`),a(t)}function a(t){let r=e.enter(`chunkText`,{contentType:`text`,previous:n});return n&&(n.next=r),n=r,o(t)}function o(t){if(t===null){e.exit(`chunkText`),e.exit(`paragraph`),e.consume(t);return}return F(t)?(e.consume(t),e.exit(`chunkText`),a):(e.consume(t),o)}}var vn=class{constructor(){this.index=new Map,this.map=[]}add(e,t,n){yn(this,e,t,n,!1)}addBefore(e,t,n){yn(this,e,t,n,!0)}consume(e){if(this.map.sort(function(e,t){return e[0]-t[0]}),this.map.length===0)return;let t=this.map.length,n=[];for(;t>0;)--t,n.push(e.slice(this.map[t][0]+this.map[t][1]),this.map[t][2]),e.length=this.map[t][0];n.push(e.slice()),e.length=0;let r=n.pop();for(;r;){for(let t of r)e.push(t);r=n.pop()}this.map.length=0,this.index.clear()}};function yn(e,t,n,r,i){if(n===0&&r.length===0)return;let a=e.index.get(t);if(a){a[1]+=n,i?(r.push(...a[2]),a[2]=r):a[2].push(...r);return}let o=[t,n,r];e.map.push(o),e.index.set(t,o)}var bn={tokenize:Sn},xn={tokenize:Cn};function Sn(e){let t=this,n=[],r=0,i,a,o;return s;function s(i){if(ro))return;let n=t.events.length,a=n,s,c;for(;a--;)if(t.events[a][0]===`exit`&&t.events[a][1].type===`chunkFlow`){if(s){c=t.events[a][1].end;break}s=!0}for(_(r),e=n;er;){let r=n[i];t.containerState=r[1],r[0].exit.call(t,e)}n.length=r}function v(){i.write([null]),a=void 0,i=void 0,t.containerState._closeFlow=void 0}}function Cn(e,t,n){return R(e,e.attempt(this.parser.constructs.document,t,n),`linePrefix`,this.parser.constructs.disable.null.includes(`codeIndented`)?void 0:4)}function wn(e){if(e===null||I(e)||fn(e))return 1;if(dn(e))return 2}function Tn(e,t,n){let r=[],i=-1;for(;++i1&&e[n][1].end.offset-e[n][1].start.offset>1?2:1,o={...e[i][1].end},s={...e[n][1].start};kn(o,-a),kn(s,a);let c={type:a>1?`strongSequence`:`emphasisSequence`,start:o,end:{...e[i][1].end}},l={type:a>1?`strongSequence`:`emphasisSequence`,start:{...e[n][1].start},end:s},u={type:a>1?`strongText`:`emphasisText`,start:{...e[i][1].end},end:{...e[n][1].start}},d={type:a>1?`strong`:`emphasis`,start:{...c.start},end:{...l.end}};e[i][1].end={...c.start},e[n][1].start={...l.end},r=[],e[i][1].end.offset-e[i][1].start.offset&&(r=P(r,[[`enter`,e[i][1],t],[`exit`,e[i][1],t]])),r=P(r,[[`enter`,d,t],[`enter`,c,t],[`exit`,c,t],[`enter`,u,t]]),r=P(r,Tn(t.parser.constructs.insideSpan.null,e.slice(i+1,n),t)),r=P(r,[[`exit`,u,t],[`enter`,l,t],[`exit`,l,t],[`exit`,d,t]]);let f=0;e[n][1].end.offset-e[n][1].start.offset&&(f=2,r=P(r,[[`enter`,e[n][1],t],[`exit`,e[n][1],t]])),Xt(e,i-1,n-i+3,r),n=i+r.length-f-2;break}}for(n=-1;++n0&&L(t)?R(e,v,`linePrefix`,a+1)(t):v(t)}function v(t){return t===null||F(t)?e.check(Hn,h,b)(t):(e.enter(`codeFlowValue`),y(t))}function y(t){return t===null||F(t)?(e.exit(`codeFlowValue`),v(t)):(e.consume(t),y)}function b(n){return e.exit(`codeFenced`),t(n)}function x(e,t,n){let i=0;return a;function a(t){return e.enter(`lineEnding`),e.consume(t),e.exit(`lineEnding`),c}function c(t){return e.enter(`codeFencedFence`),L(t)?R(e,l,`linePrefix`,r.parser.constructs.disable.null.includes(`codeIndented`)?void 0:4)(t):l(t)}function l(t){return t===s?(e.enter(`codeFencedFenceSequence`),u(t)):n(t)}function u(t){return t===s?(i++,e.consume(t),u):i>=o?(e.exit(`codeFencedFenceSequence`),L(t)?R(e,d,`whitespace`)(t):d(t)):n(t)}function d(r){return r===null||F(r)?(e.exit(`codeFencedFence`),t(r)):n(r)}}}var Kn={name:`codeIndented`,tokenize:Jn},qn={partial:!0,tokenize:Yn};function Jn(e,t,n){return r;function r(t){return e.enter(`codeIndented`),hn(e,i,n,`linePrefix`,4,4)(t)}function i(t){return t===null?o(t):F(t)?e.attempt(qn,i,o)(t):(e.enter(`codeFlowValue`),a(t))}function a(t){return t===null||F(t)?(e.exit(`codeFlowValue`),i(t)):(e.consume(t),a)}function o(n){return e.exit(`codeIndented`),t(n)}}function Yn(e,t,n){let r=this;return i;function i(o){return r.parser.lazy[r.now().line]?n(o):F(o)?(e.enter(`lineEnding`),e.consume(o),e.exit(`lineEnding`),i):hn(e,t,a,`linePrefix`,4,4)(o)}function a(e){return F(e)?i(e):n(e)}}var Xn={name:`codeText`,previous:Qn,resolve:Zn,tokenize:$n};function Zn(e){let t=e.length-4,n=3,r,i;if((e[n][1].type===`lineEnding`||e[n][1].type===`space`)&&(e[t][1].type===`lineEnding`||e[t][1].type===`space`)){for(r=n;++r=this.left.length+this.right.length)throw RangeError("Cannot access index `"+e+"` in a splice buffer of size `"+(this.left.length+this.right.length)+"`");return ethis.left.length?this.right.slice(this.right.length-n+this.left.length,this.right.length-e+this.left.length).reverse():this.left.slice(e).concat(this.right.slice(this.right.length-n+this.left.length).reverse())}splice(e,t,n){let r=t||0;this.setCursor(Math.trunc(e));let i=this.right.splice(this.right.length-r,1/0);return n&&tr(this.left,n),i.reverse()}pop(){return this.setCursor(1/0),this.left.pop()}push(e){this.setCursor(1/0),this.left.push(e)}pushMany(e){this.setCursor(1/0),tr(this.left,e)}unshift(e){this.setCursor(0),this.right.push(e)}unshiftMany(e){this.setCursor(0),tr(this.right,e.reverse())}setCursor(e){if(!(e===this.left.length||e>this.left.length&&this.right.length===0||e<0&&this.left.length===0)){if(e=4?t(i):e.interrupt(r.parser.constructs.flow,n,t)(i)}}function lr(e,t,n,r,i,a,o,s,c){let l=c||1/0,u=0;return d;function d(t){return t===60?(e.enter(r),e.enter(i),e.enter(a),e.consume(t),e.exit(a),f):t===null||t===32||t===41||sn(t)?n(t):(e.enter(r),e.enter(o),e.enter(s),e.enter(`chunkString`,{contentType:`string`}),h(t))}function f(n){return n===62?(e.enter(a),e.consume(n),e.exit(a),e.exit(i),e.exit(r),t):(e.enter(s),e.enter(`chunkString`,{contentType:`string`}),p(n))}function p(t){return t===62?(e.exit(`chunkString`),e.exit(s),f(t)):t===null||t===60||F(t)?n(t):(e.consume(t),t===92?m:p)}function m(t){return t===60||t===62||t===92?(e.consume(t),p):p(t)}function h(i){return!u&&(i===null||i===41||I(i))?(e.exit(`chunkString`),e.exit(s),e.exit(o),e.exit(r),t(i)):u999||l===null||l===91||l===93&&!c||l===94&&!s&&`_hiddenFootnoteSupport`in o.parser.constructs?n(l):l===93?(e.exit(a),e.enter(i),e.consume(l),e.exit(i),e.exit(r),t):F(l)?(e.enter(`lineEnding`),e.consume(l),e.exit(`lineEnding`),u):(e.enter(`chunkString`,{contentType:`string`}),d(l))}function d(t){return t===null||t===91||t===93||F(t)||s++>999?(e.exit(`chunkString`),u(t)):(e.consume(t),c||=!L(t),t===92?f:d)}function f(t){return t===91||t===92||t===93?(e.consume(t),s++,d):d(t)}}function dr(e,t,n,r,i,a){let o;return s;function s(t){return t===34||t===39||t===40?(e.enter(r),e.enter(i),e.consume(t),e.exit(i),o=t===40?41:t,c):n(t)}function c(n){return n===o?(e.enter(i),e.consume(n),e.exit(i),e.exit(r),t):(e.enter(a),l(n))}function l(t){return t===o?(e.exit(a),c(o)):t===null?n(t):F(t)?(e.enter(`lineEnding`),e.consume(t),e.exit(`lineEnding`),R(e,l,`linePrefix`)):(e.enter(`chunkString`,{contentType:`string`}),u(t))}function u(t){return t===o||t===null||F(t)?(e.exit(`chunkString`),l(t)):(e.consume(t),t===92?d:u)}function d(t){return t===o||t===92?(e.consume(t),u):u(t)}}function fr(e,t){let n;return r;function r(i){return F(i)?(e.enter(`lineEnding`),e.consume(i),e.exit(`lineEnding`),n=!0,r):L(i)?R(e,r,n?`linePrefix`:`lineSuffix`)(i):t(i)}}var pr={name:`definition`,tokenize:hr},mr={partial:!0,tokenize:gr};function hr(e,t,n){let r=this,i;return a;function a(t){return e.enter(`definition`),o(t)}function o(t){return ur.call(r,e,s,n,`definitionLabel`,`definitionLabelMarker`,`definitionLabelString`)(t)}function s(t){return i=nn(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)),t===58?(e.enter(`definitionMarker`),e.consume(t),e.exit(`definitionMarker`),c):n(t)}function c(t){return I(t)?fr(e,l)(t):l(t)}function l(t){return lr(e,u,n,`definitionDestination`,`definitionDestinationLiteral`,`definitionDestinationLiteralMarker`,`definitionDestinationRaw`,`definitionDestinationString`)(t)}function u(t){return e.attempt(mr,d,d)(t)}function d(t){return L(t)?R(e,f,`whitespace`)(t):f(t)}function f(a){return a===null||F(a)?(e.exit(`definition`),r.parser.defined.push(i),t(a)):n(a)}}function gr(e,t,n){return r;function r(t){return I(t)?fr(e,i)(t):n(t)}function i(t){return dr(e,a,n,`definitionTitle`,`definitionTitleMarker`,`definitionTitleString`)(t)}function a(t){return L(t)?R(e,o,`whitespace`)(t):o(t)}function o(e){return e===null||F(e)?t(e):n(e)}}var _r={name:`hardBreakEscape`,tokenize:vr};function vr(e,t,n){return r;function r(t){return e.enter(`hardBreakEscape`),e.consume(t),i}function i(r){return F(r)?(e.exit(`hardBreakEscape`),t(r)):n(r)}}var yr={name:`headingAtx`,resolve:br,tokenize:xr};function br(e,t){let n=e.length-2,r=3;if(e[r][1].type===`whitespace`&&(r+=2),n-2>r&&e[n][1].type===`whitespace`&&(n-=2),e[n][1].type===`atxHeadingSequence`&&(r===n-1||n-4>r&&e[n-2][1].type===`whitespace`)&&(n-=r+1===n?2:4),n>r){let i={type:`atxHeadingText`,start:e[r][1].start,end:e[n][1].end},a={type:`chunkText`,start:e[r][1].start,end:e[n][1].end,contentType:`text`};Xt(e,r,n-r+1,[[`enter`,i,t],[`enter`,a,t],[`exit`,a,t],[`exit`,i,t]])}return e}function xr(e,t,n){let r=0;return i;function i(t){return e.enter(`atxHeading`),a(t)}function a(t){return e.enter(`atxHeadingSequence`),o(t)}function o(t){return t===35&&r++<6?(e.consume(t),o):t===null||I(t)?(e.exit(`atxHeadingSequence`),s(t)):n(t)}function s(n){return n===35?(e.enter(`atxHeadingSequence`),c(n)):n===null||F(n)?(e.exit(`atxHeading`),t(n)):L(n)?R(e,s,`whitespace`)(n):(e.enter(`atxHeadingText`),l(n))}function c(t){return t===35?(e.consume(t),c):(e.exit(`atxHeadingSequence`),s(t))}function l(t){return t===null||t===35||I(t)?(e.exit(`atxHeadingText`),s(t)):(e.consume(t),l)}}var Sr=`address.article.aside.base.basefont.blockquote.body.caption.center.col.colgroup.dd.details.dialog.dir.div.dl.dt.fieldset.figcaption.figure.footer.form.frame.frameset.h1.h2.h3.h4.h5.h6.head.header.hr.html.iframe.legend.li.link.main.menu.menuitem.nav.noframes.ol.optgroup.option.p.param.search.section.summary.table.tbody.td.tfoot.th.thead.title.tr.track.ul`.split(`.`),Cr=[`pre`,`script`,`style`,`textarea`],wr={concrete:!0,name:`htmlFlow`,resolveTo:Er,tokenize:Dr},Tr={partial:!0,tokenize:Or};function Er(e){let t=e.length;for(;t--&&(e[t][0]!==`enter`||e[t][1].type!==`htmlFlow`););return t>1&&e[t-2][1].type===`linePrefix`&&(e[t][1].start=e[t-2][1].start,e[t+1][1].start=e[t-2][1].start,e.splice(t-2,2)),e}function Dr(e,t,n){let r=this,i,a,o,s,c;return l;function l(e){return u(e)}function u(t){return e.enter(`htmlFlow`),e.enter(`htmlFlowData`),e.consume(t),d}function d(s){return s===33?(e.consume(s),f):s===47?(e.consume(s),a=!0,h):s===63?(e.consume(s),i=3,r.interrupt?t:le):rn(s)?(e.consume(s),o=String.fromCharCode(s),g):n(s)}function f(a){return a===45?(e.consume(a),i=2,p):a===91?(e.consume(a),i=5,s=0,m):rn(a)?(e.consume(a),i=4,r.interrupt?t:le):n(a)}function p(i){return i===45?(e.consume(i),r.interrupt?t:le):n(i)}function m(i){return i===`CDATA[`.charCodeAt(s++)?(e.consume(i),s===6?r.interrupt?t:T:m):n(i)}function h(t){return rn(t)?(e.consume(t),o=String.fromCharCode(t),g):n(t)}function g(s){if(s===null||s===47||s===62||I(s)){let c=s===47,l=o.toLowerCase();return!c&&!a&&Cr.includes(l)?(i=1,r.interrupt?t(s):T(s)):Sr.includes(o.toLowerCase())?(i=6,c?(e.consume(s),_):r.interrupt?t(s):T(s)):(i=7,r.interrupt&&!r.parser.lazy[r.now().line]?n(s):a?v(s):y(s))}return s===45||an(s)?(e.consume(s),o+=String.fromCharCode(s),g):n(s)}function _(i){return i===62?(e.consume(i),r.interrupt?t:T):n(i)}function v(t){return L(t)?(e.consume(t),v):C(t)}function y(t){return t===47?(e.consume(t),C):t===58||t===95||rn(t)?(e.consume(t),b):L(t)?(e.consume(t),y):C(t)}function b(t){return t===45||t===46||t===58||t===95||an(t)?(e.consume(t),b):x(t)}function x(t){return t===61?(e.consume(t),ee):L(t)?(e.consume(t),x):y(t)}function ee(t){return t===null||t===60||t===61||t===62||t===96?n(t):t===34||t===39?(e.consume(t),c=t,te):L(t)?(e.consume(t),ee):ne(t)}function te(t){return t===c?(e.consume(t),c=null,S):t===null||F(t)?n(t):(e.consume(t),te)}function ne(t){return t===null||t===34||t===39||t===47||t===60||t===61||t===62||t===96||I(t)?x(t):(e.consume(t),ne)}function S(e){return e===47||e===62||L(e)?y(e):n(e)}function C(t){return t===62?(e.consume(t),w):n(t)}function w(t){return t===null||F(t)?T(t):L(t)?(e.consume(t),w):n(t)}function T(t){return t===45&&i===2?(e.consume(t),ae):t===60&&i===1?(e.consume(t),oe):t===62&&i===4?(e.consume(t),ue):t===63&&i===3?(e.consume(t),le):t===93&&i===5?(e.consume(t),ce):F(t)&&(i===6||i===7)?(e.exit(`htmlFlowData`),e.check(Tr,de,E)(t)):t===null||F(t)?(e.exit(`htmlFlowData`),E(t)):(e.consume(t),T)}function E(t){return e.check(Hn,re,de)(t)}function re(t){return e.enter(`lineEnding`),e.consume(t),e.exit(`lineEnding`),ie}function ie(t){return t===null||F(t)?E(t):(e.enter(`htmlFlowData`),T(t))}function ae(t){return t===45?(e.consume(t),le):T(t)}function oe(t){return t===47?(e.consume(t),o=``,se):T(t)}function se(t){if(t===62){let n=o.toLowerCase();return Cr.includes(n)?(e.consume(t),ue):T(t)}return rn(t)&&o.length<8?(e.consume(t),o+=String.fromCharCode(t),se):T(t)}function ce(t){return t===93?(e.consume(t),le):T(t)}function le(t){return t===62?(e.consume(t),ue):t===45&&i===2?(e.consume(t),le):T(t)}function ue(t){return t===null||F(t)?(e.exit(`htmlFlowData`),de(t)):(e.consume(t),ue)}function de(n){return e.exit(`htmlFlow`),t(n)}}function Or(e,t,n){return r;function r(r){return e.enter(`lineEnding`),e.consume(r),e.exit(`lineEnding`),e.attempt(Mn,t,n)}}var kr={name:`htmlText`,tokenize:Ar};function Ar(e,t,n){let r=this,i,a,o;return s;function s(t){return e.enter(`htmlText`),e.enter(`htmlTextData`),e.consume(t),c}function c(t){return t===33?(e.consume(t),l):t===47?(e.consume(t),x):t===63?(e.consume(t),y):rn(t)?(e.consume(t),ne):n(t)}function l(t){return t===45?(e.consume(t),u):t===91?(e.consume(t),a=0,m):rn(t)?(e.consume(t),v):n(t)}function u(t){return t===45?(e.consume(t),p):n(t)}function d(t){return t===null?n(t):t===45?(e.consume(t),f):F(t)?(o=d,oe(t)):(e.consume(t),d)}function f(t){return t===45?(e.consume(t),p):d(t)}function p(e){return e===62?ae(e):e===45?f(e):d(e)}function m(t){return t===`CDATA[`.charCodeAt(a++)?(e.consume(t),a===6?h:m):n(t)}function h(t){return t===null?n(t):t===93?(e.consume(t),g):F(t)?(o=h,oe(t)):(e.consume(t),h)}function g(t){return t===93?(e.consume(t),_):h(t)}function _(t){return t===62?ae(t):t===93?(e.consume(t),_):h(t)}function v(t){return t===null||t===62?ae(t):F(t)?(o=v,oe(t)):(e.consume(t),v)}function y(t){return t===null?n(t):t===63?(e.consume(t),b):F(t)?(o=y,oe(t)):(e.consume(t),y)}function b(e){return e===62?ae(e):y(e)}function x(t){return rn(t)?(e.consume(t),ee):n(t)}function ee(t){return t===45||an(t)?(e.consume(t),ee):te(t)}function te(t){return F(t)?(o=te,oe(t)):L(t)?(e.consume(t),te):ae(t)}function ne(t){return t===45||an(t)?(e.consume(t),ne):t===47||t===62||I(t)?S(t):n(t)}function S(t){return t===47?(e.consume(t),ae):t===58||t===95||rn(t)?(e.consume(t),C):F(t)?(o=S,oe(t)):L(t)?(e.consume(t),S):ae(t)}function C(t){return t===45||t===46||t===58||t===95||an(t)?(e.consume(t),C):w(t)}function w(t){return t===61?(e.consume(t),T):F(t)?(o=w,oe(t)):L(t)?(e.consume(t),w):S(t)}function T(t){return t===null||t===60||t===61||t===62||t===96?n(t):t===34||t===39?(e.consume(t),i=t,E):F(t)?(o=T,oe(t)):L(t)?(e.consume(t),T):(e.consume(t),re)}function E(t){return t===i?(e.consume(t),i=void 0,ie):t===null?n(t):F(t)?(o=E,oe(t)):(e.consume(t),E)}function re(t){return t===null||t===34||t===39||t===60||t===61||t===96?n(t):t===47||t===62||I(t)?S(t):(e.consume(t),re)}function ie(e){return e===47||e===62||I(e)?S(e):n(e)}function ae(r){return r===62?(e.consume(r),e.exit(`htmlTextData`),e.exit(`htmlText`),t):n(r)}function oe(t){return e.exit(`htmlTextData`),e.enter(`lineEnding`),e.consume(t),e.exit(`lineEnding`),se}function se(t){return L(t)?R(e,ce,`linePrefix`,r.parser.constructs.disable.null.includes(`codeIndented`)?void 0:4)(t):ce(t)}function ce(t){return e.enter(`htmlTextData`),o(t)}}var jr={name:`labelEnd`,resolveAll:Fr,resolveTo:Ir,tokenize:Lr},Mr={tokenize:Rr},Nr={tokenize:zr},Pr={tokenize:Br};function Fr(e){let t=-1,n=[];for(;++t0&&i[i.length-1]._balanced;)i.pop();a=i[i.length-1]}return s;function s(t){return a?a._inactive?d(t):(o=r.parser.defined.includes(nn(r.sliceSerialize({start:a.end,end:r.now()}))),e.enter(`labelEnd`),e.enter(`labelMarker`),e.consume(t),e.exit(`labelMarker`),e.exit(`labelEnd`),c):n(t)}function c(t){return t===40?e.attempt(Mr,u,o?u:d)(t):t===91?e.attempt(Nr,u,o?l:d)(t):o?u(t):d(t)}function l(t){return e.attempt(Pr,u,d)(t)}function u(e){return i.pop(),t(e)}function d(e){return a._balanced=!0,n(e)}}function Rr(e,t,n){return r;function r(t){return e.enter(`resource`),e.enter(`resourceMarker`),e.consume(t),e.exit(`resourceMarker`),i}function i(t){return I(t)?fr(e,a)(t):a(t)}function a(t){return t===41?u(t):lr(e,o,s,`resourceDestination`,`resourceDestinationLiteral`,`resourceDestinationLiteralMarker`,`resourceDestinationRaw`,`resourceDestinationString`,32)(t)}function o(t){return I(t)?fr(e,c)(t):u(t)}function s(e){return n(e)}function c(t){return t===34||t===39||t===40?dr(e,l,n,`resourceTitle`,`resourceTitleMarker`,`resourceTitleString`)(t):u(t)}function l(t){return I(t)?fr(e,u)(t):u(t)}function u(r){return r===41?(e.enter(`resourceMarker`),e.consume(r),e.exit(`resourceMarker`),e.exit(`resource`),t):n(r)}}function zr(e,t,n){let r=this;return i;function i(t){return ur.call(r,e,a,o,`reference`,`referenceMarker`,`referenceString`)(t)}function a(e){return r.parser.defined.includes(nn(r.sliceSerialize(r.events[r.events.length-1][1]).slice(1,-1)))?t(e):n(e)}function o(e){return n(e)}}function Br(e,t,n){return r;function r(t){return e.enter(`reference`),e.enter(`referenceMarker`),e.consume(t),e.exit(`referenceMarker`),i}function i(r){return r===93?(e.enter(`referenceMarker`),e.consume(r),e.exit(`referenceMarker`),e.exit(`reference`),t):n(r)}}var Vr={name:`labelStartImage`,resolveAll:jr.resolveAll,tokenize:Hr};function Hr(e,t,n){let r=this,i;return a;function a(t){return e.enter(`labelImage`),e.enter(`labelImageMarker`),e.consume(t),e.exit(`labelImageMarker`),o}function o(t){return t===91?(e.enter(`labelMarker`),e.consume(t),e.exit(`labelMarker`),i=e.exit(`labelImage`),s):n(t)}function s(e){return e===94&&`_hiddenFootnoteSupport`in r.parser.constructs?n(e):(r._labelStarts=r._labelStarts||[],r._labelStarts.push(i),t(e))}}var Ur={name:`labelStartLink`,resolveAll:jr.resolveAll,tokenize:Wr};function Wr(e,t,n){let r=this,i;return a;function a(t){return e.enter(`labelLink`),e.enter(`labelMarker`),e.consume(t),e.exit(`labelMarker`),i=e.exit(`labelLink`),o}function o(e){return e===94&&`_hiddenFootnoteSupport`in r.parser.constructs?n(e):(r._labelStarts=r._labelStarts||[],r._labelStarts.push(i),t(e))}}var Gr={name:`lineEnding`,tokenize:Kr};function Kr(e,t){return n;function n(n){return e.enter(`lineEnding`),e.consume(n),e.exit(`lineEnding`),R(e,t,`linePrefix`)}}var qr={name:`thematicBreak`,tokenize:Jr};function Jr(e,t,n){let r=0,i;return a;function a(t){return e.enter(`thematicBreak`),o(t)}function o(e){return i=e,s(e)}function s(a){return a===i?(e.enter(`thematicBreakSequence`),c(a)):r>=3&&(a===null||F(a))?(e.exit(`thematicBreak`),t(a)):n(a)}function c(t){return t===i?(e.consume(t),r++,c):(e.exit(`thematicBreakSequence`),L(t)?R(e,s,`whitespace`)(t):s(t))}}var Yr={continuation:{tokenize:$r},exit:ti,name:`list`,tokenize:Qr},Xr={partial:!0,tokenize:ni},Zr={partial:!0,tokenize:ei};function Qr(e,t,n){let r=this,i=r.events[r.events.length-1],a=i&&i[1].type===`linePrefix`?i[2].sliceSerialize(i[1],!0).length:0,o=0;return s;function s(t){let i=r.containerState.type||(t===42||t===43||t===45?`listUnordered`:`listOrdered`);if(i===`listUnordered`?!r.containerState.marker||t===r.containerState.marker:cn(t)){if(r.containerState.type||(r.containerState.type=i,e.enter(i,{_container:!0})),i===`listUnordered`)return e.enter(`listItemPrefix`),t===42||t===45?e.check(qr,n,l)(t):l(t);if(!r.interrupt||t===49)return e.enter(`listItemPrefix`),e.enter(`listItemValue`),c(t)}return n(t)}function c(t){return cn(t)&&++o<10?(e.consume(t),c):(!r.interrupt||o<2)&&(r.containerState.marker?t===r.containerState.marker:t===41||t===46)?(e.exit(`listItemValue`),l(t)):n(t)}function l(t){return e.enter(`listItemMarker`),e.consume(t),e.exit(`listItemMarker`),r.containerState.marker=r.containerState.marker||t,e.check(Mn,r.interrupt?n:u,e.attempt(Xr,f,d))}function u(e){return r.containerState.initialBlankLine=!0,a++,f(e)}function d(t){return L(t)?(e.enter(`listItemPrefixWhitespace`),e.consume(t),e.exit(`listItemPrefixWhitespace`),f):n(t)}function f(n){return r.containerState.size=a+r.sliceSerialize(e.exit(`listItemPrefix`),!0).length,t(n)}}function $r(e,t,n){let r=this;return r.containerState._closeFlow=void 0,e.check(Mn,i,a);function i(n){return r.containerState.furtherBlankLines=r.containerState.furtherBlankLines||r.containerState.initialBlankLine,R(e,t,`listItemIndent`,r.containerState.size+1)(n)}function a(n){return r.containerState.furtherBlankLines||!L(n)?(r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,o(n)):(r.containerState.furtherBlankLines=void 0,r.containerState.initialBlankLine=void 0,e.attempt(Zr,t,o)(n))}function o(i){return r.containerState._closeFlow=!0,r.interrupt=void 0,R(e,e.attempt(Yr,t,n),`linePrefix`,r.parser.constructs.disable.null.includes(`codeIndented`)?void 0:4)(i)}}function ei(e,t,n){let r=this;return R(e,i,`listItemIndent`,r.containerState.size+1);function i(e){let i=r.events[r.events.length-1];return i&&i[1].type===`listItemIndent`&&i[2].sliceSerialize(i[1],!0).length===r.containerState.size?t(e):n(e)}}function ti(e){e.exit(this.containerState.type)}function ni(e,t,n){let r=this;return R(e,i,`listItemPrefixWhitespace`,r.parser.constructs.disable.null.includes(`codeIndented`)?void 0:5);function i(e){let i=r.events[r.events.length-1];return!L(e)&&i&&i[1].type===`listItemPrefixWhitespace`?t(e):n(e)}}var ri={name:`setextUnderline`,resolveTo:ii,tokenize:ai};function ii(e,t){let n=new vn,r=e.length,i,a,o;for(;r--;)if(e[r][0]===`enter`){if(e[r][1].type===`content`){i=r;break}e[r][1].type===`paragraph`&&(a=r)}else e[r][1].type===`content`&&n.add(r,1,[]),!o&&e[r][1].type===`definition`&&(o=r);let s={type:`setextHeading`,start:{...e[i][1].start},end:{...e[e.length-1][1].end}};return e[a][1].type=`setextHeadingText`,o?(n.add(a,0,[[`enter`,s,t]]),n.add(o+1,0,[[`exit`,e[i][1],t]]),e[i][1].end={...e[o][1].end}):e[i][1]=s,n.add(e.length,0,[[`exit`,s,t]]),n.consume(e),e}function ai(e,t,n){let r=this,i;return a;function a(t){let a=r.events.length,s;for(;a--;)if(r.events[a][1].type!==`lineEnding`&&r.events[a][1].type!==`linePrefix`&&r.events[a][1].type!==`content`){s=r.events[a][1].type===`paragraph`;break}return!r.parser.lazy[r.now().line]&&(r.interrupt||s)?(e.enter(`setextHeadingLine`),i=t,o(t)):n(t)}function o(t){return e.enter(`setextHeadingLineSequence`),s(t)}function s(t){return t===i?(e.consume(t),s):(e.exit(`setextHeadingLineSequence`),L(t)?R(e,c,`lineSuffix`)(t):c(t))}function c(r){return r===null||F(r)?(e.exit(`setextHeadingLine`),t(r)):n(r)}}var oi={tokenize:si};function si(e){let t=this,n=e.attempt(Mn,r,e.attempt(this.parser.constructs.flowInitial,i,R(e,e.attempt(this.parser.constructs.flow,i,e.attempt(ir,i)),`linePrefix`)));return n;function r(r){if(r===null){e.consume(r);return}return e.enter(`lineEndingBlank`),e.consume(r),e.exit(`lineEndingBlank`),t.currentConstruct=void 0,n}function i(r){if(r===null){e.consume(r);return}return e.enter(`lineEnding`),e.consume(r),e.exit(`lineEnding`),t.currentConstruct=void 0,n}}var ci={resolveAll:fi()},li=di(`string`),ui=di(`text`);function di(e){return{resolveAll:fi(e===`text`?pi:void 0),tokenize:t};function t(t){let n=this,r=this.parser.constructs[e],i=t.attempt(r,a,o);return a;function a(e){return c(e)?i(e):o(e)}function o(e){if(e===null){t.consume(e);return}return t.enter(`data`),t.consume(e),s}function s(e){return c(e)?(t.exit(`data`),i(e)):(t.consume(e),s)}function c(e){if(e===null)return!0;let t=r[e],i=-1;if(t)for(;++iSi,contentInitial:()=>gi,disable:()=>Ci,document:()=>hi,flow:()=>vi,flowInitial:()=>_i,insideSpan:()=>xi,string:()=>yi,text:()=>bi}),hi={42:Yr,43:Yr,45:Yr,48:Yr,49:Yr,50:Yr,51:Yr,52:Yr,53:Yr,54:Yr,55:Yr,56:Yr,57:Yr,62:Pn},gi={91:pr},_i={[-2]:Kn,[-1]:Kn,32:Kn},vi={35:yr,42:qr,45:[ri,qr],60:wr,61:ri,95:qr,96:Wn,126:Wn},yi={38:Bn,92:Rn},bi={[-5]:Gr,[-4]:Gr,[-3]:Gr,33:Vr,38:Bn,42:En,60:[An,kr],91:Ur,92:[_r,Rn],93:jr,95:En,96:Xn},xi={null:[En,ci]},Si={null:[42,95]},Ci={null:[]};function wi(e,t,n){let r={_bufferIndex:-1,_index:0,line:n&&n.line||1,column:n&&n.column||1,offset:n&&n.offset||0},i={},a=[],o=[],s=[],c={attempt:te(x),check:te(ee),consume:v,enter:y,exit:b,interrupt:te(ee,{interrupt:!0})},l={code:null,containerState:{},defineSkip:h,events:[],now:m,parser:e,previous:null,sliceSerialize:f,sliceStream:p,write:d},u=t.tokenize.call(l,c);return t.resolveAll&&a.push(t),l;function d(e){return o=P(o,e),g(),o[o.length-1]===null?(ne(t,0),l.events=Tn(a,l.events,l),l.events):[]}function f(e,t){return Ei(p(e),t)}function p(e){return Ti(o,e)}function m(){let{_bufferIndex:e,_index:t,line:n,column:i,offset:a}=r;return{_bufferIndex:e,_index:t,line:n,column:i,offset:a}}function h(e){i[e.line]=e.column,C()}function g(){for(;r._index-1){let e=o[0];typeof e==`string`?o[0]=e.slice(r):o.shift()}a>0&&o.push(e[i].slice(0,a))}return o}function Ei(e,t){let n=-1,r=[],i;for(;++n0&&i(t.beforeEnter,{...o,sliceSerialize:e[p][2].sliceSerialize},e[p][1]),Pi.call(n,e[p][1].type)&&n[e[p][1].type].call({...o,sliceSerialize:e[p][2].sliceSerialize},e[p][1]),e[p][0]===`exit`&&t.afterExit.length>0&&i(t.afterExit,{...o,sliceSerialize:e[p][2].sliceSerialize},e[p][1])}if(o.tokenStack.length>0){let e=o.tokenStack[o.tokenStack.length-1];(e[1]||Bi).call(o,void 0,e[0])}for(r.position={start:Li(e.length>0?e[0][1].start:{line:1,column:1,offset:0}),end:Li(e.length>0?e[e.length-2][1].end:{line:1,column:1,offset:0})},p=-1;++p0&&(r.className=[`language-`+i[0]]);let a={type:`element`,tagName:`code`,properties:r,children:[{type:`text`,value:n}]};return t.meta&&(a.data={meta:t.meta}),e.patch(t,a),a=e.applyData(t,a),a={type:`element`,tagName:`pre`,properties:{},children:[a]},e.patch(t,a),a}function Gi(e,t){let n={type:`element`,tagName:`del`,properties:{},children:e.all(t)};return e.patch(t,n),e.applyData(t,n)}function Ki(e,t){let n={type:`element`,tagName:`em`,properties:{},children:e.all(t)};return e.patch(t,n),e.applyData(t,n)}function qi(e,t){let n=typeof e.options.clobberPrefix==`string`?e.options.clobberPrefix:`user-content-`,r=String(t.identifier).toUpperCase(),i=mn(r.toLowerCase()),a=e.footnoteOrder.indexOf(r),o,s=e.footnoteCounts.get(r);s===void 0?(s=0,e.footnoteOrder.push(r),o=e.footnoteOrder.length):o=a+1,s+=1,e.footnoteCounts.set(r,s);let c={type:`element`,tagName:`a`,properties:{href:`#`+n+`fn-`+i,id:n+`fnref-`+i+(s>1?`-`+s:``),dataFootnoteRef:!0,ariaDescribedBy:[`footnote-label`]},children:[{type:`text`,value:String(o)}]};e.patch(t,c);let l={type:`element`,tagName:`sup`,properties:{},children:[c]};return e.patch(t,l),e.applyData(t,l)}function Ji(e,t){let n={type:`element`,tagName:`h`+t.depth,properties:{},children:e.all(t)};return e.patch(t,n),e.applyData(t,n)}function Yi(e,t){if(e.options.allowDangerousHtml){let n={type:`raw`,value:t.value};return e.patch(t,n),e.applyData(t,n)}}function Xi(e,t){let n=t.referenceType,r=`]`;if(n===`collapsed`?r+=`[]`:n===`full`&&(r+=`[`+(t.label||t.identifier)+`]`),t.type===`imageReference`)return[{type:`text`,value:`![`+t.alt+r}];let i=e.all(t),a=i[0];a&&a.type===`text`?a.value=`[`+a.value:i.unshift({type:`text`,value:`[`});let o=i[i.length-1];return o&&o.type===`text`?o.value+=r:i.push({type:`text`,value:r}),i}function Zi(e,t){let n=String(t.identifier).toUpperCase(),r=e.definitionById.get(n);if(!r)return Xi(e,t);let i={src:mn(r.url||``),alt:t.alt};r.title!==null&&r.title!==void 0&&(i.title=r.title);let a={type:`element`,tagName:`img`,properties:i,children:[]};return e.patch(t,a),e.applyData(t,a)}function Qi(e,t){let n={src:mn(t.url)};t.alt!==null&&t.alt!==void 0&&(n.alt=t.alt),t.title!==null&&t.title!==void 0&&(n.title=t.title);let r={type:`element`,tagName:`img`,properties:n,children:[]};return e.patch(t,r),e.applyData(t,r)}function $i(e,t){let n={type:`text`,value:t.value.replace(/\r?\n|\r/g,` `)};e.patch(t,n);let r={type:`element`,tagName:`code`,properties:{},children:[n]};return e.patch(t,r),e.applyData(t,r)}function ea(e,t){let n=String(t.identifier).toUpperCase(),r=e.definitionById.get(n);if(!r)return Xi(e,t);let i={href:mn(r.url||``)};r.title!==null&&r.title!==void 0&&(i.title=r.title);let a={type:`element`,tagName:`a`,properties:i,children:e.all(t)};return e.patch(t,a),e.applyData(t,a)}function ta(e,t){let n={href:mn(t.url)};t.title!==null&&t.title!==void 0&&(n.title=t.title);let r={type:`element`,tagName:`a`,properties:n,children:e.all(t)};return e.patch(t,r),e.applyData(t,r)}function na(e,t,n){let r=e.all(t),i=n?ra(n):ia(t),a={},o=[];if(typeof t.checked==`boolean`){let e=r[0],n;e&&e.type===`element`&&e.tagName===`p`?n=e:(n={type:`element`,tagName:`p`,properties:{},children:[]},r.unshift(n)),n.children.length>0&&n.children.unshift({type:`text`,value:` `}),n.children.unshift({type:`element`,tagName:`input`,properties:{type:`checkbox`,checked:t.checked,disabled:!0},children:[]}),a.className=[`task-list-item`]}let s=-1;for(;++s1}function z(e,t){let n={},r=e.all(t),i=-1;for(typeof t.start==`number`&&t.start!==1&&(n.start=t.start);++i0){let r={type:`element`,tagName:`tbody`,properties:{},children:e.wrap(n,!0)},a=at(t.children[1]),o=it(t.children[t.children.length-1]);a&&o&&(r.position={start:a,end:o}),i.push(r)}let a={type:`element`,tagName:`table`,properties:{},children:e.wrap(i,!0)};return e.patch(t,a),e.applyData(t,a)}function ca(e,t,n){let r=n?n.children:void 0,i=(r?r.indexOf(t):1)===0?`th`:`td`,a=n&&n.type===`table`?n.align:void 0,o=a?a.length:t.children.length,s=-1,c=[];for(;++s0,!0),r[0]),i=r.index+r[0].length,r=n.exec(t);return a.push(pa(t.slice(i),i>0,!1)),a.join(``)}function pa(e,t,n){let r=0,i=e.length;if(t){let t=e.codePointAt(r);for(;t===ua||t===da;)r++,t=e.codePointAt(r)}if(n){let t=e.codePointAt(i-1);for(;t===ua||t===da;)i--,t=e.codePointAt(i-1)}return i>r?e.slice(r,i):``}function ma(e,t){let n={type:`text`,value:fa(String(t.value))};return e.patch(t,n),e.applyData(t,n)}function ha(e,t){let n={type:`element`,tagName:`hr`,properties:{},children:[]};return e.patch(t,n),e.applyData(t,n)}var ga={blockquote:Hi,break:Ui,code:Wi,delete:Gi,emphasis:Ki,footnoteReference:qi,heading:Ji,html:Yi,imageReference:Zi,image:Qi,inlineCode:$i,linkReference:ea,link:ta,listItem:na,list:z,paragraph:B,root:aa,strong:oa,table:sa,tableCell:la,tableRow:ca,text:ma,thematicBreak:ha,toml:_a,yaml:_a,definition:_a,footnoteDefinition:_a};function _a(){}var{defineProperty:va}=Object,ya=typeof self==`object`?self:globalThis,ba=(e,t)=>{switch(e){case`Function`:case`SharedWorker`:case`Worker`:case`eval`:case`setInterval`:case`setTimeout`:throw TypeError(`unable to deserialize `+e)}return new ya[e](t)},xa=(e,t)=>{let n=(t,n)=>(e.set(n,t),t),r=i=>{if(e.has(i))return e.get(i);let[a,o]=t[i];switch(a){case 0:case-1:return n(o,i);case 1:{let e=n([],i);for(let t of o)e.push(r(t));return e}case 2:{let e=n({},i);for(let[t,n]of o){let i=r(t),a=r(n);i===`__proto__`?va(e,i,{value:a,configurable:!0,enumerable:!0,writable:!0}):e[i]=a}return e}case 3:return n(new Date(o),i);case 4:{let{source:e,flags:t}=o;return n(new RegExp(e,t),i)}case 5:{let e=n(new Map,i);for(let[t,n]of o)e.set(r(t),r(n));return e}case 6:{let e=n(new Set,i);for(let t of o)e.add(r(t));return e}case 7:{let{name:e,message:t}=o;return n(typeof ya[e]==`function`?ba(e,t):Error(t),i)}case 8:return n(BigInt(o),i);case`BigInt`:return n(Object(BigInt(o)),i);case`ArrayBuffer`:return n(new Uint8Array(o).buffer,o);case`DataView`:{let{buffer:e}=new Uint8Array(o);return n(new DataView(e),o)}case`-0`:return-0}return n(ba(a,o),i)};return r},Sa=e=>xa(new Map,e)(0),Ca=``,{toString:wa}={},{keys:Ta,is:Ea}=Object,Da=e=>{let t=typeof e;if(t!==`object`||!e)return[0,t];let n=wa.call(e).slice(8,-1);switch(n){case`Array`:return[1,Ca];case`Object`:return[2,Ca];case`Date`:return[3,Ca];case`RegExp`:return[4,Ca];case`Map`:return[5,Ca];case`Set`:return[6,Ca];case`DataView`:return[1,n]}return n.includes(`Array`)?[1,n]:e instanceof Error?[7,e.name||`Error`]:[2,n]},Oa=([e,t])=>e===0&&(t===`function`||t===`symbol`),ka=(e,t,n,r)=>{let i=(e,t)=>{let i=r.push(e)-1;return n.set(t,i),i},a=o=>{if(n.has(o))return n.get(o);let[s,c]=Da(o);switch(s){case 0:{let t=o;switch(c){case`bigint`:s=8,t=o.toString();break;case`number`:if(!o&&Ea(o,-0))return r.push([`-0`])-1;break;case`function`:case`symbol`:if(e)throw TypeError(`unable to serialize `+c);t=null;break;case`undefined`:return i([-1],o)}return i([s,t],o)}case 1:{if(c){let e=o;return c===`DataView`?e=new Uint8Array(o.buffer):c===`ArrayBuffer`&&(e=new Uint8Array(o)),i([c,[...e]],o)}let e=[],t=i([s,e],o);for(let t of o)e.push(a(t));return t}case 2:{if(c)switch(c){case`BigInt`:return i([c,o.toString()],o);case`Boolean`:case`Number`:case`String`:return i([c,o.valueOf()],o)}if(t&&`toJSON`in o)return a(o.toJSON());let n=[],r=i([s,n],o);for(let t of Ta(o))(e||!Oa(Da(o[t])))&&n.push([a(t),a(o[t])]);return r}case 3:return i([s,isNaN(o.getTime())?Ca:o.toISOString()],o);case 4:{let{source:e,flags:t}=o;return i([s,{source:e,flags:t}],o)}case 5:{let t=[],n=i([s,t],o);for(let[n,r]of o)(e||!(Oa(Da(n))||Oa(Da(r))))&&t.push([a(n),a(r)]);return n}case 6:{let t=[],n=i([s,t],o);for(let n of o)(e||!Oa(Da(n)))&&t.push(a(n));return n}}let{message:l}=o;return i([s,{name:c,message:l}],o)};return a},Aa=(e,{json:t,lossy:n}={})=>{let r=[];return ka(!(t||n),!!t,new Map,r)(e),r},V=typeof structuredClone==`function`?(e,t)=>t&&(`json`in t||`lossy`in t)?Sa(Aa(e,t)):structuredClone(e):(e,t)=>Sa(Aa(e,t));function ja(e,t){let n=[{type:`text`,value:`↩`}];return t>1&&n.push({type:`element`,tagName:`sup`,properties:{},children:[{type:`text`,value:String(t)}]}),n}function Ma(e,t){return`Back to reference `+(e+1)+(t>1?`-`+t:``)}function Na(e){let t=typeof e.options.clobberPrefix==`string`?e.options.clobberPrefix:`user-content-`,n=e.options.footnoteBackContent||ja,r=e.options.footnoteBackLabel||Ma,i=e.options.footnoteLabel||`Footnotes`,a=e.options.footnoteLabelTagName||`h2`,o=e.options.footnoteLabelProperties||{className:[`sr-only`]},s=[],c=-1;for(;++c0&&d.push({type:`text`,value:` `});let e=typeof n==`string`?n:n(c,u);typeof e==`string`&&(e={type:`text`,value:e}),d.push({type:`element`,tagName:`a`,properties:{href:`#`+t+`fnref-`+l+(u>1?`-`+u:``),dataFootnoteBackref:``,ariaLabel:typeof r==`string`?r:r(c,u),className:[`data-footnote-backref`]},children:Array.isArray(e)?e:[e]})}let p=a[a.length-1];if(p&&p.type===`element`&&p.tagName===`p`){let e=p.children[p.children.length-1];e&&e.type===`text`?e.value+=` `:p.children.push({type:`text`,value:` `}),p.children.push(...d)}else a.push(...d);let m={type:`element`,tagName:`li`,properties:{id:t+`fn-`+l},children:e.wrap(a,!0)};e.patch(i,m),s.push(m)}if(s.length!==0)return{type:`element`,tagName:`section`,properties:{dataFootnotes:!0,className:[`footnotes`]},children:[{type:`element`,tagName:a,properties:{...V(o),id:`footnote-label`},children:[{type:`text`,value:i}]},{type:`text`,value:` +`},{type:`element`,tagName:`ol`,properties:{},children:e.wrap(s,!0)},{type:`text`,value:` +`}]}}var Pa=(function(e){if(e==null)return za;if(typeof e==`function`)return Ra(e);if(typeof e==`object`)return Array.isArray(e)?Fa(e):Ia(e);if(typeof e==`string`)return La(e);throw Error(`Expected function, string, or object as test`)});function Fa(e){let t=[],n=-1;for(;++n`:``))+`)`})}return u;function u(){let l=Ha,u,d,f;if((!t||a(e,i,c[c.length-1]||void 0))&&(l=Wa(n(e,c)),l[0]===!1))return l;if(`children`in e&&e.children){let t=e;if(t.children&&l[0]!==`skip`)for(d=(r?t.children.length:-1)+o,f=c.concat(t);d>-1&&d0&&n.push({type:`text`,value:` +`}),n}function $a(e){let t=0,n=e.charCodeAt(t);for(;n===9||n===32;)t++,n=e.charCodeAt(t);return e.slice(t)}function eo(e,t){let n=Ja(e,t),r=n.one(e,void 0),i=Na(n),a=Array.isArray(r)?{type:`root`,children:r}:r||{type:`root`,children:[]};return i&&(`children`in a,a.children.push({type:`text`,value:` +`},i)),a}function to(e,t){return e&&`run`in e?async function(n,r){let i=eo(n,{file:r,...t});await e.run(i,r)}:function(n,r){return eo(n,{file:r,...e||t})}}function no(e){if(e)throw e}var ro=o(((e,t)=>{var n=Object.prototype.hasOwnProperty,r=Object.prototype.toString,i=Object.defineProperty,a=Object.getOwnPropertyDescriptor,o=function(e){return typeof Array.isArray==`function`?Array.isArray(e):r.call(e)===`[object Array]`},s=function(e){if(!e||r.call(e)!==`[object Object]`)return!1;var t=n.call(e,`constructor`),i=e.constructor&&e.constructor.prototype&&n.call(e.constructor.prototype,`isPrototypeOf`);if(e.constructor&&!t&&!i)return!1;for(var a in e);return a===void 0||n.call(e,a)},c=function(e,t){i&&t.name===`__proto__`?i(e,t.name,{enumerable:!0,configurable:!0,value:t.newValue,writable:!0}):e[t.name]=t.newValue},l=function(e,t){if(t===`__proto__`){if(!n.call(e,t))return;if(a)return a(e,t).value}return e[t]};t.exports=function e(){var t,n,r,i,a,u,d=arguments[0],f=1,p=arguments.length,m=!1;for(typeof d==`boolean`&&(m=d,d=arguments[1]||{},f=2),(d==null||typeof d!=`object`&&typeof d!=`function`)&&(d={});ft.length,o;r&&t.push(i);try{o=e.apply(this,t)}catch(e){let t=e;if(r&&n)throw t;return i(t)}r||(o&&o.then&&typeof o.then==`function`?o.then(a,i):o instanceof Error?i(o):a(o))}function i(e,...r){n||(n=!0,t(e,...r))}function a(e){i(null,e)}}var so={basename:co,dirname:lo,extname:uo,join:fo,sep:`/`};function co(e,t){if(t!==void 0&&typeof t!=`string`)throw TypeError(`"ext" argument must be a string`);ho(e);let n=0,r=-1,i=e.length,a;if(t===void 0||t.length===0||t.length>e.length){for(;i--;)if(e.codePointAt(i)===47){if(a){n=i+1;break}}else r<0&&(a=!0,r=i+1);return r<0?``:e.slice(n,r)}if(t===e)return``;let o=-1,s=t.length-1;for(;i--;)if(e.codePointAt(i)===47){if(a){n=i+1;break}}else o<0&&(a=!0,o=i+1),s>-1&&(e.codePointAt(i)===t.codePointAt(s--)?s<0&&(r=i):(s=-1,r=o));return n===r?r=o:r<0&&(r=e.length),e.slice(n,r)}function lo(e){if(ho(e),e.length===0)return`.`;let t=-1,n=e.length,r;for(;--n;)if(e.codePointAt(n)===47){if(r){t=n;break}}else r||=!0;return t<0?e.codePointAt(0)===47?`/`:`.`:t===1&&e.codePointAt(0)===47?`//`:e.slice(0,t)}function uo(e){ho(e);let t=e.length,n=-1,r=0,i=-1,a=0,o;for(;t--;){let s=e.codePointAt(t);if(s===47){if(o){r=t+1;break}continue}n<0&&(o=!0,n=t+1),s===46?i<0?i=t:a!==1&&(a=1):i>-1&&(a=-1)}return i<0||n<0||a===0||a===1&&i===n-1&&i===r+1?``:e.slice(i,n)}function fo(...e){let t=-1,n;for(;++t0&&e.codePointAt(e.length-1)===47&&(n+=`/`),t?`/`+n:n}function mo(e,t){let n=``,r=0,i=-1,a=0,o=-1,s,c;for(;++o<=e.length;){if(o2){if(c=n.lastIndexOf(`/`),c!==n.length-1){c<0?(n=``,r=0):(n=n.slice(0,c),r=n.length-1-n.lastIndexOf(`/`)),i=o,a=0;continue}}else if(n.length>0){n=``,r=0,i=o,a=0;continue}}t&&(n=n.length>0?n+`/..`:`..`,r=2)}else n.length>0?n+=`/`+e.slice(i+1,o):n=e.slice(i+1,o),r=o-i-1}i=o,a=0}else s===46&&a>-1?a++:a=-1}return n}function ho(e){if(typeof e!=`string`)throw TypeError(`Path must be a string. Received `+JSON.stringify(e))}var go={cwd:_o};function _o(){return`/`}function vo(e){return!!(typeof e==`object`&&e&&`href`in e&&e.href&&`protocol`in e&&e.protocol&&e.auth===void 0)}function yo(e){if(typeof e==`string`)e=new URL(e);else if(!vo(e)){let t=TypeError('The "path" argument must be of type string or an instance of URL. Received `'+e+"`");throw t.code=`ERR_INVALID_ARG_TYPE`,t}if(e.protocol!==`file:`){let e=TypeError(`The URL must be of scheme file`);throw e.code=`ERR_INVALID_URL_SCHEME`,e}return bo(e)}function bo(e){if(e.hostname!==``){let e=TypeError(`File URL host must be "localhost" or empty on darwin`);throw e.code=`ERR_INVALID_FILE_URL_HOST`,e}let t=e.pathname,n=-1;for(;++n0){let[r,...a]=t,o=n[i][1];io(o)&&io(r)&&(r=(0,Oo.default)(!0,o,r)),n[i]=[e,r,...a]}}}}().freeze();function jo(e,t){if(typeof t!=`function`)throw TypeError("Cannot `"+e+"` without `parser`")}function Mo(e,t){if(typeof t!=`function`)throw TypeError("Cannot `"+e+"` without `compiler`")}function No(e,t){if(t)throw Error("Cannot call `"+e+"` on a frozen processor.\nCreate a new processor first, by calling it: use `processor()` instead of `processor`.")}function Po(e){if(!io(e)||typeof e.type!=`string`)throw TypeError("Expected node, got `"+e+"`")}function Fo(e,t,n){if(!n)throw Error("`"+e+"` finished async. Use `"+t+"` instead")}function Io(e){return Lo(e)?e:new So(e)}function Lo(e){return!!(e&&typeof e==`object`&&`message`in e&&`messages`in e)}function Ro(e){return typeof e==`string`||zo(e)}function zo(e){return!!(e&&typeof e==`object`&&`byteLength`in e&&`byteOffset`in e)}var Bo=[],Vo={allowDangerousHtml:!0},H=/^(https?|ircs?|mailto|xmpp)$/i,U=[{from:`astPlugins`,id:`remove-buggy-html-in-markdown-parser`},{from:`allowDangerousHtml`,id:`remove-buggy-html-in-markdown-parser`},{from:`allowNode`,id:`replace-allownode-allowedtypes-and-disallowedtypes`,to:`allowElement`},{from:`allowedTypes`,id:`replace-allownode-allowedtypes-and-disallowedtypes`,to:`allowedElements`},{from:`className`,id:`remove-classname`},{from:`disallowedTypes`,id:`replace-allownode-allowedtypes-and-disallowedtypes`,to:`disallowedElements`},{from:`escapeHtml`,id:`remove-buggy-html-in-markdown-parser`},{from:`includeElementIndex`,id:`#remove-includeelementindex`},{from:`includeNodeIndex`,id:`change-includenodeindex-to-includeelementindex`},{from:`linkTarget`,id:`remove-linktarget`},{from:`plugins`,id:`change-plugins-to-remarkplugins`,to:`remarkPlugins`},{from:`rawSourcePos`,id:`#remove-rawsourcepos`},{from:`renderers`,id:`change-renderers-to-components`,to:`components`},{from:`source`,id:`change-source-to-children`,to:`children`},{from:`sourcePos`,id:`#remove-sourcepos`},{from:`transformImageUri`,id:`#add-urltransform`,to:`urlTransform`},{from:`transformLinkUri`,id:`#add-urltransform`,to:`urlTransform`}];function Ho(e){let t=Uo(e),n=Wo(e);return Go(t.runSync(t.parse(n),n),e)}function Uo(e){let t=e.rehypePlugins||Bo,n=e.remarkPlugins||Bo,r=e.remarkRehypeOptions?{...e.remarkRehypeOptions,...Vo}:Vo;return Ao().use(Vi).use(n).use(to,r).use(t)}function Wo(e){let t=e.children||``,n=new So;return typeof t==`string`?n.value=t:``+t,n}function Go(e,t){let n=t.allowedElements,r=t.allowElement,i=t.components,a=t.disallowedElements,o=t.skipHtml,s=t.unwrapDisallowed,c=t.urlTransform||Ko;for(let e of U)Object.hasOwn(t,e.from)&&``+e.from+(e.to?"use `"+e.to+"` instead":`remove it`)+e.id;return Ga(e,l),bt(e,{Fragment:D.Fragment,components:i,ignoreInvalidStyle:!0,jsx:D.jsx,jsxs:D.jsxs,passKeys:!0,passNode:!0});function l(e,t,i){if(e.type===`raw`&&i&&typeof t==`number`)return o?i.children.splice(t,1):i.children[t]={type:`text`,value:e.value},t;if(e.type===`element`){let t;for(t in Ht)if(Object.hasOwn(Ht,t)&&Object.hasOwn(e.properties,t)){let n=e.properties[t],r=Ht[t];(r===null||r.includes(e.tagName))&&(e.properties[t]=c(String(n||``),t,e))}}if(e.type===`element`){let o=n?!n.includes(e.tagName):a?a.includes(e.tagName):!1;if(!o&&r&&typeof t==`number`&&(o=!r(e,t,i)),o&&i&&typeof t==`number`)return s&&e.children?i.children.splice(t,1,...e.children):i.children.splice(t,1),t}}}function Ko(e){let t=e.indexOf(`:`),n=e.indexOf(`?`),r=e.indexOf(`#`),i=e.indexOf(`/`);return t===-1||i!==-1&&t>i||n!==-1&&t>n||r!==-1&&t>r||H.test(e.slice(0,t))?e:``}function qo(e,t){let n=String(e);if(typeof t!=`string`)throw TypeError(`Expected character`);let r=0,i=n.indexOf(t);for(;i!==-1;)r++,i=n.indexOf(t,i+t.length);return r}function Jo(e){if(typeof e!=`string`)throw TypeError(`Expected a string`);return e.replace(/[|\\{}()[\]^$+*?.]/g,`\\$&`).replace(/-/g,`\\x2d`)}function Yo(e,t,n){let r=Pa((n||{}).ignore||[]),i=Xo(t),a=-1;for(;++a0?{type:`text`,value:a}:void 0),a===!1)r.lastIndex=n+1;else{if(s!==n&&f({type:`text`,value:e.value.slice(s,n)}),Array.isArray(a))for(let e of a)f(e);else a&&f(a);s=n+d[0].length,l=!0}if(!r.global)break;d=r.exec(e.value)}return l?(s?\]}]+$/.exec(e);if(!t)return[e,void 0];e=e.slice(0,t.index);let n=t[0],r=n.indexOf(`)`),i=qo(e,`(`),a=qo(e,`)`);for(;r!==-1&&i>a;)e+=n.slice(0,r+1),n=n.slice(r+1),r=n.indexOf(`)`),a++;return[e,n]}function ms(e,t){let n=e.input.charCodeAt(e.index-1);return(e.index===0||fn(n)||dn(n))&&(!t||n!==47)}ws.peek=Cs;function hs(){this.buffer()}function gs(e){this.enter({type:`footnoteReference`,identifier:``,label:``},e)}function _s(){this.buffer()}function vs(e){this.enter({type:`footnoteDefinition`,identifier:``,label:``,children:[]},e)}function ys(e){let t=this.resume(),n=this.stack[this.stack.length-1];n.type,n.identifier=nn(this.sliceSerialize(e)).toLowerCase(),n.label=t}function bs(e){this.exit(e)}function xs(e){let t=this.resume(),n=this.stack[this.stack.length-1];n.type,n.identifier=nn(this.sliceSerialize(e)).toLowerCase(),n.label=t}function Ss(e){this.exit(e)}function Cs(){return`[`}function ws(e,t,n,r){let i=n.createTracker(r),a=i.move(`[^`),o=n.enter(`footnoteReference`),s=n.enter(`reference`);return a+=i.move(n.safe(n.associationId(e),{after:`]`,before:a})),s(),o(),a+=i.move(`]`),a}function Ts(){return{enter:{gfmFootnoteCallString:hs,gfmFootnoteCall:gs,gfmFootnoteDefinitionLabelString:_s,gfmFootnoteDefinition:vs},exit:{gfmFootnoteCallString:ys,gfmFootnoteCall:bs,gfmFootnoteDefinitionLabelString:xs,gfmFootnoteDefinition:Ss}}}function Es(e){let t=!1;return e&&e.firstLineBlank&&(t=!0),{handlers:{footnoteDefinition:n,footnoteReference:ws},unsafe:[{character:`[`,inConstruct:[`label`,`phrasing`,`reference`]}]};function n(e,n,r,i){let a=r.createTracker(i),o=a.move(`[^`),s=r.enter(`footnoteDefinition`),c=r.enter(`label`);return o+=a.move(r.safe(r.associationId(e),{before:o,after:`]`})),c(),o+=a.move(`]:`),e.children&&e.children.length>0&&(a.shift(4),o+=a.move((t?` +`:` `)+r.indentLines(r.containerFlow(e,a.current()),t?Os:Ds))),s(),o}}function Ds(e,t,n){return t===0?e:Os(e,t,n)}function Os(e,t,n){return(n?``:` `)+e}var ks=[`autolink`,`destinationLiteral`,`destinationRaw`,`reference`,`titleQuote`,`titleApostrophe`];Ps.attention=Fs,Ps.peek=Is;function As(){return{canContainEols:[`delete`],enter:{strikethrough:Ms},exit:{strikethrough:Ns}}}function js(){return{handlers:{delete:Ps},unsafe:[{character:`~`,inConstruct:`phrasing`,notInConstruct:ks}]}}function Ms(e){this.enter({type:`delete`,children:[],position:void 0},e)}function Ns(e){this.exit(e)}function Ps(e,t,n,r){let i=n.createTracker(r),a=n.stack.includes(`strikethrough`)?`~`:`~~`,o=n.enter(`strikethrough`),s=i.move(a);return s+=n.containerPhrasing(e,{...i.current(),before:s,after:`~`}),s+=i.move(a),o(),s}function Fs(){return{construct:`strikethrough`,markers:[`~`],sizes:[2,1]}}function Is(){return`~`}function Ls(e){return e.length}function Rs(e,t){let n=t||{},r=(n.align||[]).concat(),i=n.stringLength||Ls,a=[],o=[],s=[],c=[],l=0,u=-1;for(;++ul&&(l=e[u].length);++ac[a])&&(c[a]=e)}t.push(o)}o[u]=t,s[u]=r}let d=-1;if(typeof r==`object`&&`length`in r)for(;++dc[d]&&(c[d]=i),p[d]=i),f[d]=o}o.splice(1,0,f),s.splice(1,0,p),u=-1;let m=[];for(;++u `),a.shift(2);let o=n.indentLines(n.containerFlow(e,a.current()),Us);return i(),o}function Us(e,t,n){return`>`+(n?``:` `)+e}function Ws(e,t){return Gs(e,t.inConstruct,!0)&&!Gs(e,t.notInConstruct,!1)}function Gs(e,t,n){if(typeof t==`string`&&(t=[t]),!t||t.length===0)return n;let r=-1;for(;++ro&&(o=a):a=1,i=r+t.length,r=n.indexOf(t,i);return o}function Js(e,t){return!(t.options.fences!==!1||!e.value||e.lang||!/[^\n\r ]/.test(e.value)||/^[\t ]*(?:[\n\r]|$)|(?:^|[\n\r])[\t ]*$/.test(e.value))}function Ys(e){let t=e.options.fence||"`";if(t!=="`"&&t!==`~`)throw Error("Cannot serialize code with `"+t+"` for `options.fence`, expected `` ` `` or `~`");return t}function Xs(e,t,n,r){let i=Ys(n),a=e.value||``;if(Js(e,n)){let e=n.enter(`codeIndented`),t=n.indentLines(a,Zs);return e(),t}let o=n.createTracker(r),s=i.repeat(Math.max(qs(a,i)+1,3)),c=n.enter(`codeFenced`),l=i==="`"?`GraveAccent`:`Tilde`,u=o.move(s);if(e.lang){let t=n.enter(`codeFencedLang${l}`);u+=o.move(n.safe(e.lang,{before:u,after:` `,encode:["`"],...o.current()})),t()}if(e.lang&&e.meta){let t=n.enter(`codeFencedMeta${l}`);u+=o.move(` `),u+=o.move(n.safe(e.meta,{before:u,after:` +`,encode:["`"],...o.current()})),t()}return u+=o.move(` +`),a&&(u+=o.move(a+` +`)),u+=o.move(s),c(),u}function Zs(e,t,n){return(n?``:` `)+e}function Qs(e){let t=e.options.quote||`"`;if(t!==`"`&&t!==`'`)throw Error("Cannot serialize title with `"+t+"` for `options.quote`, expected `\"`, or `'`");return t}function $s(e,t,n,r){let i=Qs(n),a=i===`"`?`Quote`:`Apostrophe`,o=n.enter(`definition`),s=n.enter(`label`),c=n.createTracker(r),l=c.move(`[`);return l+=c.move(n.safe(n.associationId(e),{before:l,after:`]`,...c.current()})),l+=c.move(`]: `),s(),!e.url||/[\0- \u007F]/.test(e.url)?(s=n.enter(`destinationLiteral`),l+=c.move(`<`),l+=c.move(n.safe(e.url,{before:l,after:`>`,...c.current()})),l+=c.move(`>`)):(s=n.enter(`destinationRaw`),l+=c.move(n.safe(e.url,{before:l,after:e.title?` `:` +`,...c.current()}))),s(),e.title&&(s=n.enter(`title${a}`),l+=c.move(` `+i),l+=c.move(n.safe(e.title,{before:l,after:i,...c.current()})),l+=c.move(i),s()),o(),l}function ec(e){let t=e.options.emphasis||`*`;if(t!==`*`&&t!==`_`)throw Error("Cannot serialize emphasis with `"+t+"` for `options.emphasis`, expected `*`, or `_`");return t}tc.attention=nc,tc.peek=rc;function tc(e,t,n,r){let i=n.enter(`phrasing`),a=n.containerPhrasing({type:`root`,children:[e]},r);return i(),a}function nc(e,t){return{construct:`emphasis`,markers:ec(t)===`*`?[`*`,`_`]:[`_`,`*`],sizes:[1]}}function rc(e,t,n){return n.options.emphasis||`*`}function ic(e){return`&#x`+e.toString(16).toUpperCase()+`;`}function ac(e,t){let n=!1;return Ga(e,function(e){if(`value`in e&&/\r?\n|\r/.test(e.value)||e.type===`break`)return n=!0,!1}),!!((!e.depth||e.depth<3)&&Wt(e)&&(t.options.setext||n))}function oc(e,t,n,r){let i=Math.max(Math.min(6,e.depth||1),1),a=n.createTracker(r);if(ac(e,n)){let t=n.enter(`headingSetext`),r=n.enter(`phrasing`),o=n.containerPhrasing(e,{...a.current(),before:` +`,after:` +`});return r(),t(),o+` +`+(i===1?`=`:`-`).repeat(o.length-(Math.max(o.lastIndexOf(`\r`),o.lastIndexOf(` +`))+1))}let o=`#`.repeat(i),s=n.enter(`headingAtx`),c=n.enter(`phrasing`);a.move(o+` `);let l=n.containerPhrasing(e,{before:`# `,after:` +`,...a.current()}),u=l.charCodeAt(0);return(u===9||u===32)&&(l=ic(u)+l.slice(1)),l=l?o+` `+l:o,n.options.closeAtx&&(l+=` `+o),c(),s(),l}sc.peek=cc;function sc(e){return e.value||``}function cc(){return`<`}lc.peek=uc;function lc(e,t,n,r){let i=Qs(n),a=i===`"`?`Quote`:`Apostrophe`,o=n.enter(`image`),s=n.enter(`label`),c=n.createTracker(r),l=c.move(`![`);return l+=c.move(n.safe(e.alt,{before:l,after:`]`,...c.current()})),l+=c.move(`](`),s(),!e.url&&e.title||/[\0- \u007F]/.test(e.url)?(s=n.enter(`destinationLiteral`),l+=c.move(`<`),l+=c.move(n.safe(e.url,{before:l,after:`>`,...c.current()})),l+=c.move(`>`)):(s=n.enter(`destinationRaw`),l+=c.move(n.safe(e.url,{before:l,after:e.title?` `:`)`,...c.current()}))),s(),e.title&&(s=n.enter(`title${a}`),l+=c.move(` `+i),l+=c.move(n.safe(e.title,{before:l,after:i,...c.current()})),l+=c.move(i),s()),l+=c.move(`)`),o(),l}function uc(){return`!`}dc.peek=fc;function dc(e,t,n,r){let i=e.referenceType,a=n.enter(`imageReference`),o=n.enter(`label`),s=n.createTracker(r),c=s.move(`![`),l=n.safe(e.alt,{before:c,after:`]`,...s.current()});c+=s.move(l+`][`),o();let u=n.stack;n.stack=u.filter(function(e){return e!==`phrasing`}),o=n.enter(`reference`);let d=n.safe(n.associationId(e),{before:c,after:`]`,...s.current()});return o(),n.stack=u,a(),i===`full`||!l||l!==d?c+=s.move(d+`]`):i===`shortcut`?c=c.slice(0,-1):c+=s.move(`]`),c}function fc(){return`!`}pc.peek=mc;function pc(e,t,n){let r=e.value||``,i="`",a=-1;for(;RegExp("(^|[^`])"+i+"([^`]|$)").test(r);)i+="`";for(/[^\n\r ]/.test(r)&&(/^[\n\r ]/.test(r)&&/[\n\r ]$/.test(r)||/^`|`$/.test(r))&&(r=` `+r+` `);++a\u007F]/.test(e.url))}gc.peek=_c;function gc(e,t,n,r){let i=Qs(n),a=i===`"`?`Quote`:`Apostrophe`,o=n.createTracker(r);if(hc(e,n)){let t=n.stack;n.stack=t.filter(function(e){return e!==`phrasing`});let r=n.enter(`autolink`),i=o.move(`<`);return i+=o.move(n.containerPhrasing(e,{before:i,after:`>`,...o.current()})),i+=o.move(`>`),r(),n.stack=t,i}let s=n.enter(`link`),c=n.enter(`label`),l=o.move(`[`);return l+=o.move(n.containerPhrasing(e,{before:l,after:`](`,...o.current()})),l+=o.move(`](`),c(),!e.url&&e.title||/[\0- \u007F]/.test(e.url)?(c=n.enter(`destinationLiteral`),l+=o.move(`<`),l+=o.move(n.safe(e.url,{before:l,after:`>`,...o.current()})),l+=o.move(`>`)):(c=n.enter(`destinationRaw`),l+=o.move(n.safe(e.url,{before:l,after:e.title?` `:`)`,...o.current()}))),c(),e.title&&(c=n.enter(`title${a}`),l+=o.move(` `+i),l+=o.move(n.safe(e.title,{before:l,after:i,...o.current()})),l+=o.move(i),c()),l+=o.move(`)`),s(),l}function _c(e,t,n){return hc(e,n)?`<`:`[`}vc.peek=yc;function vc(e,t,n,r){let i=e.referenceType,a=n.enter(`linkReference`),o=n.enter(`label`),s=n.createTracker(r),c=s.move(`[`),l=n.containerPhrasing(e,{before:c,after:`]`,...s.current()});c+=s.move(l+`][`),o();let u=n.stack;n.stack=u.filter(function(e){return e!==`phrasing`}),o=n.enter(`reference`);let d=n.safe(n.associationId(e),{before:c,after:`]`,...s.current()});return o(),n.stack=u,a(),i===`full`||!l||l!==d?c+=s.move(d+`]`):i===`shortcut`?c=c.slice(0,-1):c+=s.move(`]`),c}function yc(){return`[`}function bc(e){let t=e.options.bullet||`*`;if(t!==`*`&&t!==`+`&&t!==`-`)throw Error("Cannot serialize items with `"+t+"` for `options.bullet`, expected `*`, `+`, or `-`");return t}function xc(e){let t=bc(e),n=e.options.bulletOther;if(!n)return t===`*`?`-`:`*`;if(n!==`*`&&n!==`+`&&n!==`-`)throw Error("Cannot serialize items with `"+n+"` for `options.bulletOther`, expected `*`, `+`, or `-`");if(n===t)throw Error("Expected `bullet` (`"+t+"`) and `bulletOther` (`"+n+"`) to be different");return n}function Sc(e){let t=e.options.bulletOrdered||`.`;if(t!==`.`&&t!==`)`)throw Error("Cannot serialize items with `"+t+"` for `options.bulletOrdered`, expected `.` or `)`");return t}function Cc(e){let t=e.options.rule||`*`;if(t!==`*`&&t!==`-`&&t!==`_`)throw Error("Cannot serialize rules with `"+t+"` for `options.rule`, expected `*`, `-`, or `_`");return t}function wc(e,t,n,r){let i=n.enter(`list`),a=n.bulletCurrent,o=e.ordered?Sc(n):bc(n),s=e.ordered?o===`.`?`)`:`.`:xc(n),c=t&&n.bulletLastUsed?o===n.bulletLastUsed:!1;if(!e.ordered){let t=e.children?e.children[0]:void 0;if((o===`*`||o===`-`)&&t&&(!t.children||!t.children[0])&&n.stack[n.stack.length-1]===`list`&&n.stack[n.stack.length-2]===`listItem`&&n.stack[n.stack.length-3]===`list`&&n.stack[n.stack.length-4]===`listItem`&&n.indexStack[n.indexStack.length-1]===0&&n.indexStack[n.indexStack.length-2]===0&&n.indexStack[n.indexStack.length-3]===0&&(c=!0),Cc(n)===o&&t){let t=-1;for(;++t-1?t.start:1)+(n.options.incrementListMarker===!1?0:t.children.indexOf(e))+a);let o=a.length+1;(i===`tab`||i===`mixed`&&(t&&t.type===`list`&&t.spread||e.spread))&&(o=Math.ceil(o/4)*4);let s=n.createTracker(r);s.move(a+` `.repeat(o-a.length)),s.shift(o);let c=n.enter(`listItem`),l=n.indentLines(n.containerFlow(e,s.current()),u);return c(),l;function u(e,t,n){return t?(n?``:` `.repeat(o))+e:(n?a:a+` `.repeat(o-a.length))+e}}function Dc(e,t,n,r){let i=n.enter(`paragraph`),a=n.enter(`phrasing`),o=n.containerPhrasing(e,r);return a(),i(),o}function Oc(e,t,n,r){if(!e.children.some(function(e){return Vs(e)}))return n.containerFlow(e,r);let i=n.enter(`phrasing`),a=n.containerPhrasing(e,r);return i(),a}function kc(e){let t=e.options.strong||`*`;if(t!==`*`&&t!==`_`)throw Error("Cannot serialize strong with `"+t+"` for `options.strong`, expected `*`, or `_`");return t}Ac.attention=jc,Ac.peek=Mc;function Ac(e,t,n,r){let i=n.enter(`phrasing`),a=n.containerPhrasing({type:`root`,children:[e]},r);return i(),a}function jc(e,t){return{construct:`strong`,markers:kc(t)===`*`?[`*`,`_`]:[`_`,`*`],sizes:[2]}}function Mc(e,t,n){return n.options.strong||`*`}function Nc(e,t,n,r){let i=t?t.children:[],a=i.indexOf(e);return n.safe(e.value,{...r,afterNode:i[a+1],beforeNode:i[a-1]})}function Pc(e){let t=e.options.ruleRepetition||3;if(t<3)throw Error("Cannot serialize rules with repetition `"+t+"` for `options.ruleRepetition`, expected `3` or more");return t}function Fc(e,t,n){let r=(Cc(n)+(n.options.ruleSpaces?` `:``)).repeat(Pc(n));return n.options.ruleSpaces?r.slice(0,-1):r}var Ic={blockquote:Hs,break:Ks,code:Xs,definition:$s,emphasis:tc,hardBreak:Ks,heading:oc,html:sc,image:lc,imageReference:dc,inlineCode:pc,link:gc,linkReference:vc,list:wc,listItem:Ec,paragraph:Dc,root:Oc,strong:Ac,text:Nc,thematicBreak:Fc};function Lc(){return{enter:{table:Rc,tableData:Hc,tableHeader:Hc,tableRow:Bc},exit:{codeText:Uc,table:zc,tableData:Vc,tableHeader:Vc,tableRow:Vc}}}function Rc(e){let t=e._align;this.enter({type:`table`,align:t.map(function(e){return e===`none`?null:e}),children:[]},e),this.data.inTable=!0}function zc(e){this.exit(e),this.data.inTable=void 0}function Bc(e){this.enter({type:`tableRow`,children:[]},e)}function Vc(e){this.exit(e)}function Hc(e){this.enter({type:`tableCell`,children:[]},e)}function Uc(e){let t=this.resume();this.data.inTable&&(t=t.replace(/\\([\\|])/g,Wc));let n=this.stack[this.stack.length-1];n.type,n.value=t,this.exit(e)}function Wc(e,t){return t===`|`?t:e}function Gc(e){let t=e||{},n=t.tableCellPadding,r=t.tablePipeAlign,i=t.stringLength,a=n?` `:`|`;return{unsafe:[{character:`\r`,inConstruct:`tableCell`},{character:` +`,inConstruct:`tableCell`},{atBreak:!0,character:`|`,after:`[ :-]`},{character:`|`,inConstruct:`tableCell`},{atBreak:!0,character:`:`,after:`-`},{atBreak:!0,character:`-`,after:`[:|-]`}],handlers:{inlineCode:f,table:o,tableCell:c,tableRow:s}};function o(e,t,n,r){return l(u(e,n,r),e.align)}function s(e,t,n,r){let i=l([d(e,n,r)]);return i.slice(0,i.indexOf(` +`))}function c(e,t,n,r){let i=n.enter(`tableCell`),o=n.enter(`phrasing`),s=n.containerPhrasing(e,{...r,before:a,after:a});return o(),i(),s}function l(e,t){return Rs(e,{align:t,alignDelimiters:r,padding:n,stringLength:i})}function u(e,t,n){let r=e.children,i=-1,a=[],o=t.enter(`table`);for(;++i0&&!n&&(e[e.length-1][1]._gfmAutolinkLiteralWalkedInto=!0),n}var Sl={tokenize:Al,partial:!0};function Cl(){return{document:{91:{name:`gfmFootnoteDefinition`,tokenize:Dl,continuation:{tokenize:Ol},exit:kl}},text:{91:{name:`gfmFootnoteCall`,tokenize:El},93:{name:`gfmPotentialFootnoteCall`,add:`after`,tokenize:wl,resolveTo:Tl}}}}function wl(e,t,n){let r=this,i=r.events.length,a=r.parser.gfmFootnotes||(r.parser.gfmFootnotes=[]),o;for(;i--;){let e=r.events[i][1];if(e.type===`labelImage`){o=e;break}if(e.type===`gfmFootnoteCall`||e.type===`labelLink`||e.type===`label`||e.type===`image`||e.type===`link`)break}return s;function s(i){if(!o||!o._balanced)return n(i);let s=nn(r.sliceSerialize({start:o.end,end:r.now()}));return s.codePointAt(0)!==94||!a.includes(s.slice(1))?n(i):(e.enter(`gfmFootnoteCallLabelMarker`),e.consume(i),e.exit(`gfmFootnoteCallLabelMarker`),t(i))}}function Tl(e,t){let n=e.length;for(;n--;)if(e[n][1].type===`labelImage`&&e[n][0]===`enter`){e[n][1];break}e[n+1][1].type=`data`,e[n+3][1].type=`gfmFootnoteCallLabelMarker`;let r={type:`gfmFootnoteCall`,start:Object.assign({},e[n+3][1].start),end:Object.assign({},e[e.length-1][1].end)},i={type:`gfmFootnoteCallMarker`,start:Object.assign({},e[n+3][1].end),end:Object.assign({},e[n+3][1].end)};i.end.column++,i.end.offset++,i.end._bufferIndex++;let a={type:`gfmFootnoteCallString`,start:Object.assign({},i.end),end:Object.assign({},e[e.length-1][1].start)},o={type:`chunkString`,contentType:`string`,start:Object.assign({},a.start),end:Object.assign({},a.end)},s=[e[n+1],e[n+2],[`enter`,r,t],e[n+3],e[n+4],[`enter`,i,t],[`exit`,i,t],[`enter`,a,t],[`enter`,o,t],[`exit`,o,t],[`exit`,a,t],e[e.length-2],e[e.length-1],[`exit`,r,t]];return e.splice(n,e.length-n+1,...s),e}function El(e,t,n){let r=this,i=r.parser.gfmFootnotes||(r.parser.gfmFootnotes=[]),a=0,o;return s;function s(t){return e.enter(`gfmFootnoteCall`),e.enter(`gfmFootnoteCallLabelMarker`),e.consume(t),e.exit(`gfmFootnoteCallLabelMarker`),c}function c(t){return t===94?(e.enter(`gfmFootnoteCallMarker`),e.consume(t),e.exit(`gfmFootnoteCallMarker`),e.enter(`gfmFootnoteCallString`),e.enter(`chunkString`).contentType=`string`,l):n(t)}function l(s){if(a>999||s===93&&!o||s===null||s===91||I(s))return n(s);if(s===93){e.exit(`chunkString`);let a=e.exit(`gfmFootnoteCallString`);return i.includes(nn(r.sliceSerialize(a)))?(e.enter(`gfmFootnoteCallLabelMarker`),e.consume(s),e.exit(`gfmFootnoteCallLabelMarker`),e.exit(`gfmFootnoteCall`),t):n(s)}return I(s)||(o=!0),a++,e.consume(s),s===92?u:l}function u(t){return t===91||t===92||t===93?(e.consume(t),a++,l):l(t)}}function Dl(e,t,n){let r=this,i=r.parser.gfmFootnotes||(r.parser.gfmFootnotes=[]),a,o=0,s;return c;function c(t){return e.enter(`gfmFootnoteDefinition`)._container=!0,e.enter(`gfmFootnoteDefinitionLabel`),e.enter(`gfmFootnoteDefinitionLabelMarker`),e.consume(t),e.exit(`gfmFootnoteDefinitionLabelMarker`),l}function l(t){return t===94?(e.enter(`gfmFootnoteDefinitionMarker`),e.consume(t),e.exit(`gfmFootnoteDefinitionMarker`),e.enter(`gfmFootnoteDefinitionLabelString`),e.enter(`chunkString`).contentType=`string`,u):n(t)}function u(t){if(o>999||t===93&&!s||t===null||t===91||I(t))return n(t);if(t===93){e.exit(`chunkString`);let n=e.exit(`gfmFootnoteDefinitionLabelString`);return a=nn(r.sliceSerialize(n)),e.enter(`gfmFootnoteDefinitionLabelMarker`),e.consume(t),e.exit(`gfmFootnoteDefinitionLabelMarker`),e.exit(`gfmFootnoteDefinitionLabel`),f}return I(t)||(s=!0),o++,e.consume(t),t===92?d:u}function d(t){return t===91||t===92||t===93?(e.consume(t),o++,u):u(t)}function f(t){return t===58?(e.enter(`definitionMarker`),e.consume(t),e.exit(`definitionMarker`),i.includes(a)||i.push(a),R(e,p,`gfmFootnoteDefinitionWhitespace`)):n(t)}function p(e){return t(e)}}function Ol(e,t,n){return e.check(Mn,t,e.attempt(Sl,t,n))}function kl(e){e.exit(`gfmFootnoteDefinition`)}function Al(e,t,n){let r=this;return R(e,i,`gfmFootnoteDefinitionIndent`,5);function i(e){let i=r.events[r.events.length-1];return i&&i[1].type===`gfmFootnoteDefinitionIndent`&&i[2].sliceSerialize(i[1],!0).length===4?t(e):n(e)}}function jl(e){let t=(e||{}).singleTilde,n={name:`strikethrough`,tokenize:i,resolveAll:r};return t??=!0,{text:{126:n},insideSpan:{null:[n]},attentionMarkers:{null:[126]}};function r(e,t){let n=-1;for(;++n1?r(a):(e.consume(a),o++,c);if(o<2&&!t)return r(a);let l=e.exit(`strikethroughSequenceTemporary`),u=wn(a);return l._open=!u||u===2&&!!s,l._close=!s||s===2&&!!u,n(a)}}}var Ml=class{constructor(){this.map=[],this.index=new Map}add(e,t,n){Nl(this,e,t,n)}consume(e){if(this.map.sort(function(e,t){return e[0]-t[0]}),this.map.length===0)return;let t=this.map.length,n=[];for(;t>0;)--t,n.push(e.slice(this.map[t][0]+this.map[t][1]),this.map[t][2]),e.length=this.map[t][0];n.push(e.slice()),e.length=0;let r=n.pop();for(;r;){for(let t of r)e.push(t);r=n.pop()}this.map.length=0,this.index.clear()}};function Nl(e,t,n,r){if(n===0&&r.length===0)return;let i=e.index.get(t);if(i){i[1]+=n,i[2].push(...r);return}let a=[t,n,r];e.map.push(a),e.index.set(t,a)}function Pl(e,t){let n=!1,r=[];for(;t-1;){let{type:e}=r.events[t][1];if(e===`lineEnding`||e===`linePrefix`)t--;else break}let i=t>-1?r.events[t][1].type:null,a=i===`tableHead`||i===`tableRow`?ee:c;return a===ee&&r.parser.lazy[r.now().line]?n(e):a(e)}function c(t){return e.enter(`tableHead`),e.enter(`tableRow`),l(t)}function l(e){return e===124?u(e):(o=!0,a+=1,u(e))}function u(t){return t===null?n(t):F(t)?a>1?(a=0,r.interrupt=!0,e.exit(`tableRow`),e.enter(`lineEnding`),e.consume(t),e.exit(`lineEnding`),p):n(t):L(t)?R(e,u,`whitespace`)(t):(a+=1,o&&(o=!1,i+=1),t===124?(e.enter(`tableCellDivider`),e.consume(t),e.exit(`tableCellDivider`),o=!0,u):(e.enter(`data`),d(t)))}function d(t){return t===null||t===124||I(t)?(e.exit(`data`),u(t)):(e.consume(t),t===92?f:d)}function f(t){return t===92||t===124?(e.consume(t),d):d(t)}function p(t){return r.interrupt=!1,r.parser.lazy[r.now().line]?n(t):(e.enter(`tableDelimiterRow`),o=!1,L(t)?R(e,m,`linePrefix`,r.parser.constructs.disable.null.includes(`codeIndented`)?void 0:4)(t):m(t))}function m(t){return t===45||t===58?g(t):t===124?(o=!0,e.enter(`tableCellDivider`),e.consume(t),e.exit(`tableCellDivider`),h):x(t)}function h(t){return L(t)?R(e,g,`whitespace`)(t):g(t)}function g(t){return t===58?(a+=1,o=!0,e.enter(`tableDelimiterMarker`),e.consume(t),e.exit(`tableDelimiterMarker`),_):t===45?(a+=1,_(t)):t===null||F(t)?b(t):x(t)}function _(t){return t===45?(e.enter(`tableDelimiterFiller`),v(t)):x(t)}function v(t){return t===45?(e.consume(t),v):t===58?(o=!0,e.exit(`tableDelimiterFiller`),e.enter(`tableDelimiterMarker`),e.consume(t),e.exit(`tableDelimiterMarker`),y):(e.exit(`tableDelimiterFiller`),y(t))}function y(t){return L(t)?R(e,b,`whitespace`)(t):b(t)}function b(n){return n===124?m(n):n===null||F(n)?!o||i!==a?x(n):(e.exit(`tableDelimiterRow`),e.exit(`tableHead`),t(n)):x(n)}function x(e){return n(e)}function ee(t){return e.enter(`tableRow`),te(t)}function te(n){return n===124?(e.enter(`tableCellDivider`),e.consume(n),e.exit(`tableCellDivider`),te):n===null||F(n)?(e.exit(`tableRow`),t(n)):L(n)?R(e,te,`whitespace`)(n):(e.enter(`data`),ne(n))}function ne(t){return t===null||t===124||I(t)?(e.exit(`data`),te(t)):(e.consume(t),t===92?S:ne)}function S(t){return t===92||t===124?(e.consume(t),ne):ne(t)}}function Ll(e,t){let n=-1,r=!0,i=0,a=[0,0,0,0],o=[0,0,0,0],s=!1,c=0,l,u,d,f=new Ml;for(;++nn[2]+1){let t=n[2]+1,r=n[3]-n[2]-1;e.add(t,r,[])}}e.add(n[3]+1,0,[[`exit`,o,t]])}return i!==void 0&&(a.end=Object.assign({},Bl(t.events,i)),e.add(i,0,[[`exit`,a,t]]),a=void 0),a}function zl(e,t,n,r,i){let a=[],o=Bl(t.events,n);i&&(i.end=Object.assign({},o),a.push([`exit`,i,t])),r.end=Object.assign({},o),a.push([`exit`,r,t]),e.add(n+1,0,a)}function Bl(e,t){let n=e[t],r=n[0]===`enter`?`start`:`end`;return n[1][r]}var Vl={name:`tasklistCheck`,tokenize:Ul};function Hl(){return{text:{91:Vl}}}function Ul(e,t,n){let r=this;return i;function i(t){return r.previous!==null||!r._gfmTasklistFirstContentOfListItem?n(t):(e.enter(`taskListCheck`),e.enter(`taskListCheckMarker`),e.consume(t),e.exit(`taskListCheckMarker`),a)}function a(t){return I(t)?(e.enter(`taskListCheckValueUnchecked`),e.consume(t),e.exit(`taskListCheckValueUnchecked`),o):t===88||t===120?(e.enter(`taskListCheckValueChecked`),e.consume(t),e.exit(`taskListCheckValueChecked`),o):n(t)}function o(t){return t===93?(e.enter(`taskListCheckMarker`),e.consume(t),e.exit(`taskListCheckMarker`),e.exit(`taskListCheck`),s):n(t)}function s(r){return F(r)?t(r):L(r)?e.check({tokenize:Wl},t,n)(r):n(r)}}function Wl(e,t,n){return R(e,r,`whitespace`);function r(e){return e===null?n(e):t(e)}}function Gl(e){return Qt([cl(),Cl(),jl(e),Fl(),Hl()])}var Kl={};function ql(e){let t=this,n=e||Kl,r=t.data(),i=r.micromarkExtensions||=[],a=r.fromMarkdownExtensions||=[],o=r.toMarkdownExtensions||=[];i.push(Gl(n)),a.push(Zc()),o.push(Qc(n))}function Jl({path:e,heading:t}){let[n,r]=(0,v.useState)(null),[i,a]=(0,v.useState)(null);(0,v.useEffect)(()=>{ee(e).then(r,e=>a(e.message))},[e]),(0,v.useEffect)(()=>{n&&(t?document.getElementById(t)?.scrollIntoView():window.scrollTo(0,0))},[n,t]);let o=(0,v.useMemo)(()=>Yl(e),[e]),s=(0,v.useMemo)(()=>n?ie(n.body):``,[n]);if(i)return(0,D.jsxs)(`p`,{className:`error`,children:[e,`: `,i]});if(!n)return(0,D.jsx)(`p`,{className:`muted`,children:`Loading…`});let c=n.sections.filter(e=>e.level>=2&&e.level<=3),l=Object.entries(n.frontmatter);return(0,D.jsxs)(`div`,{className:`page`,children:[(0,D.jsxs)(`article`,{className:`doc`,children:[(0,D.jsxs)(`header`,{className:`page-head`,children:[(0,D.jsxs)(`div`,{className:`crumb`,children:[(0,D.jsx)(`code`,{children:n.path}),(0,D.jsx)(`span`,{className:`kind`,children:n.kind})]}),l.length>0&&(0,D.jsx)(`dl`,{className:`frontmatter`,children:l.map(([e,t])=>(0,D.jsxs)(`div`,{children:[(0,D.jsx)(`dt`,{children:e}),(0,D.jsx)(`dd`,{children:t})]},e))}),n.total>0&&(0,D.jsx)(pe,{done:n.done,total:n.total})]}),(0,D.jsx)(`div`,{className:`markdown`,children:(0,D.jsx)(Ho,{remarkPlugins:[ql],components:o,children:s})})]}),c.length>1&&(0,D.jsxs)(`aside`,{className:`toc`,"aria-label":`On this page`,children:[(0,D.jsx)(`h2`,{children:`On this page`}),(0,D.jsx)(`ul`,{children:c.map(t=>(0,D.jsx)(`li`,{className:`l${t.level}`,children:(0,D.jsx)(`a`,{href:E(e,t.slug),children:t.title})},t.slug+t.line))})]})]})}function Yl(e){let t=e=>({children:t})=>(0,D.jsx)(e,{id:ne(Xl(t)),children:t});return{h1:t(`h1`),h2:t(`h2`),h3:t(`h3`),h4:t(`h4`),h5:t(`h5`),h6:t(`h6`),a:({href:t,children:n})=>{let r=se(t??``,Xl(n),e);return r===null?(0,D.jsx)(`span`,{className:`dead-link`,children:n}):`external`in r?(0,D.jsx)(`a`,{href:r.external,target:`_blank`,rel:`noreferrer noopener`,children:n}):(0,D.jsx)(`a`,{href:r.internal,className:r.internal.startsWith(`#/source/`)?`cite`:void 0,children:n})}}}function Xl(e){let t=``;return v.Children.forEach(e,e=>{typeof e==`string`||typeof e==`number`?t+=e:(0,v.isValidElement)(e)&&(t+=Xl(e.props.children))}),t}var Zl={requirements:`Requirements`,design:`Design`,tasks:`Tasks`};function Ql({tree:e,current:t}){return(0,D.jsxs)(`nav`,{className:`sidebar`,"aria-label":`Workspace`,children:[(0,D.jsxs)(`a`,{className:`brand`,href:`#/`,children:[(0,D.jsx)(`span`,{className:`brand-mark`,children:`scc`}),(0,D.jsx)(`span`,{className:`brand-name`,children:e?.workspace??`…`})]}),e?.groups.map(e=>e.items.length===0?null:(0,D.jsxs)(`section`,{className:`group`,children:[(0,D.jsxs)(`h2`,{children:[e.title,` `,(0,D.jsx)(`span`,{className:`count`,children:e.id===`specs`?ru(e):e.items.length})]}),e.id===`specs`?(0,D.jsx)(eu,{items:e.items,current:t}):(0,D.jsx)($l,{items:e.items,current:t})]},e.id))]})}function $l({items:e,current:t}){return(0,D.jsx)(`ul`,{children:e.map(e=>(0,D.jsx)(`li`,{children:(0,D.jsx)(tu,{item:e,current:t,label:nu(e)})},e.path))})}function eu({items:e,current:t}){let n=new Map;for(let t of e){let e=t.path.split(`/`)[1];n.set(e,[...n.get(e)??[],t])}return(0,D.jsx)(`ul`,{children:[...n].map(([e,n])=>(0,D.jsxs)(`li`,{className:`feature`,children:[(0,D.jsx)(`span`,{className:`feature-name`,children:e}),(0,D.jsx)(`ul`,{children:n.map(e=>(0,D.jsx)(`li`,{children:(0,D.jsx)(tu,{item:e,current:t,label:Zl[e.kind]??e.title})},e.path))})]},e))})}function tu({item:e,current:t,label:n}){let r=e.path===t;return(0,D.jsxs)(`a`,{href:E(e.path),className:r?`active`:void 0,"aria-current":r?`page`:void 0,children:[(0,D.jsx)(`span`,{className:`label`,children:n}),e.total>0&&(0,D.jsxs)(`span`,{className:e.done===e.total?`tally done`:`tally`,children:[e.done,`/`,e.total]})]})}function nu(e){let t=/\/(\d{4})-[^/]+\.md$/.exec(e.path);return t&&e.path.startsWith(`docs/adr/`)?`${t[1]} · ${e.title}`:e.title}function ru(e){return new Set(e.items.map(e=>e.path.split(`/`)[1])).size}function iu({path:e,from:t,to:n}){let[r,i]=(0,v.useState)(null),[a,o]=(0,v.useState)(null),s=(0,v.useRef)(null);if((0,v.useEffect)(()=>{te(e).then(i,e=>o(e.message))},[e]),(0,v.useEffect)(()=>{r&&s.current?s.current.scrollIntoView({block:`center`}):r&&window.scrollTo(0,0)},[r,t]),a)return(0,D.jsxs)(`p`,{className:`error`,children:[e,`: `,a]});if(!r)return(0,D.jsx)(`p`,{className:`muted`,children:`Loading…`});let c=t??0,l=n??t??0,u=t!==void 0&&t>r.lines.length;return(0,D.jsxs)(`article`,{className:`source`,children:[(0,D.jsxs)(`header`,{className:`page-head`,children:[(0,D.jsxs)(`div`,{className:`crumb`,children:[(0,D.jsx)(`code`,{children:r.path}),t!==void 0&&(0,D.jsx)(`span`,{className:`kind`,children:t===l?`line ${t}`:`lines ${t}–${l}`})]}),(0,D.jsx)(`button`,{className:`back`,onClick:()=>history.back(),children:`← Back`})]}),u&&(0,D.jsxs)(`p`,{className:`error`,children:[`The citation points past the end of the file (`,r.lines.length,` lines) — the codewiki page has drifted.`]}),(0,D.jsx)(`div`,{className:`code`,children:(0,D.jsx)(`table`,{children:(0,D.jsx)(`tbody`,{children:r.lines.map((e,t)=>{let n=t+1,r=n>=c&&n<=l;return(0,D.jsxs)(`tr`,{id:`L${n}`,className:r?`hit`:void 0,ref:n===c?s:void 0,children:[(0,D.jsx)(`td`,{className:`ln`,children:n}),(0,D.jsx)(`td`,{className:`tx`,children:e||` `})]},n)})})})})]})}function G(){let[e,t]=(0,v.useState)(()=>ce(location.hash));return(0,v.useEffect)(()=>{let e=()=>t(ce(location.hash));return addEventListener(`hashchange`,e),()=>removeEventListener(`hashchange`,e)},[]),e}function au(){let e=G(),[t,n]=(0,v.useState)(null),[r,i]=(0,v.useState)(null);(0,v.useEffect)(()=>{x().then(e=>{n(e),i(null),document.title=`${e.workspace} · scc view`}).catch(e=>i(e.message))},[e]);let a=e.kind===`home`?``:e.path;return(0,D.jsxs)(`div`,{className:`shell`,children:[(0,D.jsx)(Ql,{tree:t,current:a}),(0,D.jsxs)(`main`,{className:`main`,children:[r&&(0,D.jsxs)(`p`,{className:`error`,children:[`Could not read the workspace: `,r]}),e.kind===`home`&&(0,D.jsx)(me,{tree:t}),e.kind===`page`&&(0,D.jsx)(Jl,{path:e.path,heading:e.heading},e.path),e.kind===`source`&&(0,D.jsx)(iu,{path:e.path,from:e.from,to:e.to},e.path)]})]})}(0,y.createRoot)(document.getElementById(`root`)).render((0,D.jsx)(v.StrictMode,{children:(0,D.jsx)(au,{})})); \ No newline at end of file diff --git a/internal/view/dist/assets/index-KyEs33b0.css b/internal/view/dist/assets/index-KyEs33b0.css new file mode 100644 index 0000000..bccd205 --- /dev/null +++ b/internal/view/dist/assets/index-KyEs33b0.css @@ -0,0 +1 @@ +:root{--bg:#fbfbfa;--panel:#f3f2ef;--text:#1f2328;--muted:#656d76;--line:#e2e0db;--accent:#2f6f5e;--accent-soft:#e2efe9;--hit:#fff4c2;--code-bg:#f1efeb;--error:#b42318;--mono:ui-monospace, "Cascadia Code", "SF Mono", Menlo, Consolas, monospace;--sans:system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}@media (prefers-color-scheme:dark){:root{--bg:#15171a;--panel:#1c1f23;--text:#e6e6e3;--muted:#9198a1;--line:#2e3238;--accent:#6cc4a8;--accent-soft:#1f3530;--hit:#3b3415;--code-bg:#22262b;--error:#ff8a80;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}}*{box-sizing:border-box}body{background:var(--bg);color:var(--text);font:15px/1.6 var(--sans);margin:0}a{color:var(--accent);text-decoration:none}a:hover{text-decoration:underline}code,pre{font-family:var(--mono);font-size:.88em}.shell{grid-template-columns:280px minmax(0,1fr);min-height:100vh;display:grid}.sidebar{background:var(--panel);border-right:1px solid var(--line);height:100vh;padding:16px 12px 32px;font-size:14px;position:sticky;top:0;overflow-y:auto}.brand{color:var(--text);align-items:center;gap:8px;padding:4px 8px 16px;display:flex}.brand:hover{text-decoration:none}.brand-mark{font:600 12px var(--mono);background:var(--accent);color:var(--bg);border-radius:4px;padding:2px 6px}.brand-name{text-overflow:ellipsis;white-space:nowrap;font-weight:600;overflow:hidden}.group h2{text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin:16px 8px 4px;font-size:11px}.count{font-weight:400}.sidebar ul{margin:0;padding:0;list-style:none}.sidebar a{color:var(--text);border-radius:6px;justify-content:space-between;gap:8px;padding:3px 8px;display:flex}.sidebar a:hover{background:var(--line);text-decoration:none}.sidebar a.active{background:var(--accent-soft);color:var(--accent);font-weight:600}.sidebar .label{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.feature-name{font-family:var(--mono);color:var(--muted);padding:4px 8px 0;font-size:13px;display:block}.feature ul a{padding-left:20px}.tally{font:12px var(--mono);color:var(--muted);flex:none}.tally.done{color:var(--accent)}.main{min-width:0;padding:32px 40px 80px}.page{grid-template-columns:minmax(0,780px) 220px;gap:40px;display:grid}.page-head{margin-bottom:16px}.crumb{color:var(--muted);align-items:center;gap:8px;font-size:13px;display:flex}.kind{text-transform:uppercase;letter-spacing:.05em;border:1px solid var(--line);border-radius:999px;padding:0 8px;font-size:11px}.frontmatter{flex-wrap:wrap;gap:6px;margin:10px 0;display:flex}.frontmatter div{border:1px solid var(--line);border-radius:6px;font-size:12px;display:flex;overflow:hidden}.frontmatter dt{background:var(--panel);color:var(--muted);padding:1px 8px}.frontmatter dd{font-family:var(--mono);margin:0;padding:1px 8px}.progress{align-items:center;gap:8px;display:inline-flex}.bar{background:var(--line);border-radius:3px;width:120px;height:6px;display:inline-block;overflow:hidden}.fill{background:var(--accent);height:100%;display:block}.markdown h1{margin:0 0 16px;font-size:1.9em;line-height:1.25}.markdown h2{border-bottom:1px solid var(--line);margin:32px 0 8px;padding-bottom:4px;font-size:1.35em}.markdown h3{margin:24px 0 8px;font-size:1.1em}.markdown :is(h1,h2,h3,h4){scroll-margin-top:16px}.markdown :not(pre)>code{background:var(--code-bg);border-radius:4px;padding:1px 5px}.markdown pre{tab-size:4;background:var(--code-bg);border-radius:8px;padding:12px 14px;line-height:1.45;overflow-x:auto}.markdown table{border-collapse:collapse;margin:12px 0;display:block;overflow-x:auto}.markdown th,.markdown td{border:1px solid var(--line);text-align:left;vertical-align:top;padding:5px 10px}.markdown th{background:var(--panel)}.markdown blockquote{border-left:3px solid var(--accent);color:var(--muted);margin:12px 0;padding:2px 14px}.markdown li.task-list-item{list-style:none}.markdown ul.contains-task-list{padding-left:1.2em}.markdown .cite{font-family:var(--mono);background:var(--accent-soft);border-radius:4px;padding:1px 6px;font-size:.88em}.dead-link{color:var(--muted);-webkit-text-decoration:underline dotted;text-decoration:underline dotted}.toc{align-self:start;max-height:calc(100vh - 64px);font-size:13px;position:sticky;top:32px;overflow-y:auto}.toc h2{text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin:0 0 8px;font-size:11px}.toc ul{border-left:1px solid var(--line);margin:0;padding:0 0 0 10px;list-style:none}.toc li{padding:2px 0}.toc li.l3{padding-left:12px}.toc a{color:var(--muted)}.toc a:hover{color:var(--accent)}.source .page-head{justify-content:space-between;align-items:center;display:flex}.back{font:inherit;color:var(--accent);border:1px solid var(--line);cursor:pointer;background:0 0;border-radius:6px;padding:2px 10px;font-size:13px}.code{border:1px solid var(--line);background:var(--code-bg);border-radius:8px;overflow-x:auto}.code table{border-collapse:collapse;font:13px/1.5 var(--mono);width:100%}.code .ln{text-align:right;width:1%;color:var(--muted);-webkit-user-select:none;user-select:none;border-right:1px solid var(--line);padding:0 12px}.code .tx{white-space:pre;tab-size:4;padding:0 14px}.code tr.hit{background:var(--hit)}.code tr.hit .ln{color:var(--text);font-weight:600}.cards{grid-template-columns:repeat(auto-fill,minmax(130px,1fr));gap:12px;margin:16px 0 32px;display:grid}.card{border:1px solid var(--line);background:var(--panel);color:var(--text);border-radius:10px;flex-direction:column;padding:14px 16px;display:flex}.card:hover{border-color:var(--accent);text-decoration:none}.card-n{font-size:26px;font-weight:600;line-height:1.2}.card-t{color:var(--muted);font-size:13px}.progress-list{padding:0;list-style:none}.progress-list li{border-bottom:1px solid var(--line);grid-template-columns:minmax(0,1fr) 50px auto;align-items:center;gap:12px;padding:6px 0;display:grid}.muted{color:var(--muted)}.small{font-size:12px}.error{color:var(--error)}@media (width<=1100px){.page{grid-template-columns:minmax(0,1fr)}.toc{display:none}}@media (width<=760px){.shell{grid-template-columns:1fr}.sidebar{border-right:0;border-bottom:1px solid var(--line);height:auto;max-height:40vh;position:static}.main{padding:20px 16px 60px}} diff --git a/internal/view/dist/index.html b/internal/view/dist/index.html new file mode 100644 index 0000000..3156799 --- /dev/null +++ b/internal/view/dist/index.html @@ -0,0 +1,13 @@ + + + + + + scc view + + + + +
+ + diff --git a/internal/view/page.go b/internal/view/page.go new file mode 100644 index 0000000..50d082f --- /dev/null +++ b/internal/view/page.go @@ -0,0 +1,143 @@ +package view + +import ( + "bytes" + "os" + "path" + "path/filepath" + "strings" + + "github.com/protonspy/spec-claude-code/internal/artifact" + "github.com/protonspy/spec-claude-code/internal/paths" +) + +// Page is one Markdown file, answered by GET /api/page. Body is the Markdown +// after the frontmatter block, which is shown separately as Frontmatter. +type Page struct { + Path string `json:"path"` + Kind string `json:"kind"` + Title string `json:"title"` + Frontmatter map[string]string `json:"frontmatter"` + Sections []artifact.Section `json:"sections"` + Tasks []artifact.Task `json:"tasks"` + Done int `json:"done"` + Total int `json:"total"` + Body string `json:"body"` +} + +// Source is one file a codewiki page cites, answered by GET /api/source. +type Source struct { + Path string `json:"path"` + Lines []string `json:"lines"` +} + +// maxFile caps what either route reads, and what the tree parses; a page or a +// cited file larger than this is not narrated code, and a hostile repository's +// multi-gigabyte .md should not be read into memory to find that out. +const maxFile = 1 << 20 + +// LoadPage resolves rel to a Markdown file under docs/, plans/ or specs/ and +// parses it. false covers every refusal alike, so a caller cannot tell a file that +// is not there from one it may not read. +func LoadPage(root, rel string) (Page, bool) { + abs, ok := resolve(root, rel) + if !ok || !strings.HasSuffix(rel, ".md") { + return Page{}, false + } + switch strings.SplitN(rel, "/", 2)[0] { + case paths.DocsSeg, paths.PlansSeg, paths.SpecsSeg: + default: + return Page{}, false + } + a, err := artifact.Load(root, abs) + if err != nil { + return Page{}, false + } + done, total := a.Done() + body := a.Lines + if n := a.Doc().Frontmatter.Lines; n > 0 && n <= len(body) { + body = body[n:] + } + fm := a.Frontmatter + if fm == nil { + fm = map[string]string{} + } + return Page{ + Path: a.Path, Kind: string(a.Kind), Title: a.Title, Frontmatter: fm, + Sections: orEmpty(a.Sections), Tasks: orEmpty(a.Tasks), + Done: done, Total: total, Body: strings.Join(body, "\n"), + }, true +} + +// LoadSource resolves rel to a text file anywhere in the workspace and returns its +// lines. +func LoadSource(root, rel string) (Source, bool) { + abs, ok := resolve(root, rel) + if !ok { + return Source{}, false + } + data, err := os.ReadFile(abs) + if err != nil || len(data) > maxFile { + return Source{}, false + } + if bytes.IndexByte(data[:min(len(data), 8192)], 0) >= 0 { + return Source{}, false + } + text := strings.ReplaceAll(string(data), "\r\n", "\n") + return Source{Path: rel, Lines: strings.Split(strings.TrimSuffix(text, "\n"), "\n")}, true +} + +// resolve is the containment check both routes share: rel must already be a +// clean, relative, slash-separated path naming a regular file that stays inside +// the workspace once symlinks are followed. No segment may be dot-named — .git, +// .env, the harness directory, and `..` with them — which is also what the tree +// skips, so no route serves a file the sidebar would never list. +// +// The dot rule runs twice: on the request, and on the real path after symlinks +// are followed. The second is the one that holds — a committed symlink to +// ../.env, or a Windows short name like GIT~1, both pass the first check, and +// EvalSymlinks expands either back to the dot-named path it stands for. +func resolve(root, rel string) (string, bool) { + if rel == "" || strings.ContainsAny(rel, "\\:\x00") || path.IsAbs(rel) || path.Clean(rel) != rel || dotted(rel) { + return "", false + } + abs := filepath.Join(root, filepath.FromSlash(rel)) + if !artifact.Within(root, abs) { + return "", false + } + realRoot, err := filepath.EvalSymlinks(root) + if err != nil { + return "", false + } + realAbs, err := filepath.EvalSymlinks(abs) + if err != nil { + return "", false + } + realRel, err := filepath.Rel(realRoot, realAbs) + if err != nil || dotted(filepath.ToSlash(realRel)) { + return "", false + } + st, err := os.Stat(realAbs) + if err != nil || !st.Mode().IsRegular() || st.Size() > maxFile { + return "", false + } + return abs, true +} + +// dotted reports whether any segment of a slash-separated path is dot-named, +// `..` included. +func dotted(rel string) bool { + for _, seg := range strings.Split(rel, "/") { + if strings.HasPrefix(seg, ".") { + return true + } + } + return false +} + +func orEmpty[T any](s []T) []T { + if s == nil { + return []T{} + } + return s +} diff --git a/internal/view/tree.go b/internal/view/tree.go new file mode 100644 index 0000000..744e3ef --- /dev/null +++ b/internal/view/tree.go @@ -0,0 +1,165 @@ +package view + +import ( + "io/fs" + "path/filepath" + "sort" + "strings" + + "github.com/protonspy/spec-claude-code/internal/artifact" + "github.com/protonspy/spec-claude-code/internal/paths" +) + +// Item is one page in the sidebar: enough to label it and show its progress. +type Item struct { + Path string `json:"path"` + Title string `json:"title"` + Kind string `json:"kind"` + Done int `json:"done"` + Total int `json:"total"` +} + +// Group is one section of the sidebar. The ids are the contract the frontend +// switches on; the titles are what a person reads. +type Group struct { + ID string `json:"id"` + Title string `json:"title"` + Items []Item `json:"items"` +} + +// Tree is the whole sidebar, answered by GET /api/tree. +type Tree struct { + Workspace string `json:"workspace"` + Groups []Group `json:"groups"` +} + +// groupOrder is the order the sidebar shows, and every id it can carry. All six +// are always present, empty or not, so the frontend never has to ask whether one +// exists. +var groupOrder = []struct{ id, title string }{ + {"wiki", "Wiki"}, + {"adr", "ADRs"}, + {"codewiki", "Codewiki"}, + {"docs", "Docs"}, + {"plans", "Plans"}, + {"specs", "Specs"}, +} + +// BuildTree reads the workspace from disk: every Markdown file under docs/, then +// every plan and spec through artifact.Scan, so the viewer and `scc map` agree on +// what is a plan and what is a spec. +func BuildTree(root string) (Tree, error) { + items := map[string][]Item{} + docs, err := docPages(root) + if err != nil { + return Tree{}, err + } + for _, rel := range docs { + a, err := artifact.Load(root, filepath.Join(root, filepath.FromSlash(rel))) + if err != nil { + return Tree{}, err + } + g := docGroup(rel) + items[g] = append(items[g], itemOf(a)) + } + arts, err := artifact.Scan(root) + if err != nil { + return Tree{}, err + } + for _, a := range arts { + g := "specs" + if a.Kind == artifact.KindPlan { + g = "plans" + } + items[g] = append(items[g], itemOf(a)) + } + + t := Tree{Workspace: filepath.Base(root)} + for _, g := range groupOrder { + list := items[g.id] + if list == nil { + list = []Item{} + } + t.Groups = append(t.Groups, Group{ID: g.id, Title: g.title, Items: list}) + } + return t, nil +} + +func itemOf(a *artifact.Artifact) Item { + done, total := a.Done() + return Item{Path: a.Path, Title: a.Title, Kind: string(a.Kind), Done: done, Total: total} +} + +// docPages lists docs/**/*.md, slash-separated and workspace-relative. A directory +// whose name starts with a dot is skipped, the same rule the source route applies. +// A file over maxFile is left out, as the page route would refuse it. +// A directory's own files come before its subdirectories', and its index.md first +// among them, because that is the entry point every wiki page is reachable from. +func docPages(root string) ([]string, error) { + base := paths.Docs(root) + var out []string + err := filepath.WalkDir(base, func(p string, d fs.DirEntry, err error) error { + if err != nil { + if p == base { + return fs.SkipAll + } + return err + } + if d.IsDir() { + if p != base && strings.HasPrefix(d.Name(), ".") { + return fs.SkipDir + } + return nil + } + if d.Type().IsRegular() && strings.HasSuffix(d.Name(), ".md") { + if info, err := d.Info(); err != nil || info.Size() > maxFile { + return nil + } + rel, err := filepath.Rel(root, p) + if err != nil { + return err + } + out = append(out, filepath.ToSlash(rel)) + } + return nil + }) + if err != nil { + return nil, err + } + sort.Slice(out, func(i, j int) bool { + di, dj := pathDir(out[i]), pathDir(out[j]) + if di != dj { + return di < dj + } + if ii, ij := isIndex(out[i]), isIndex(out[j]); ii != ij { + return ii + } + return out[i] < out[j] + }) + return out, nil +} + +func pathDir(rel string) string { + if i := strings.LastIndex(rel, "/"); i >= 0 { + return rel[:i] + } + return "" +} + +func isIndex(rel string) bool { return strings.HasSuffix(rel, "/index.md") } + +// docGroup sorts a docs/ page by the directory directly under docs/. +func docGroup(rel string) string { + parts := strings.Split(rel, "/") + if len(parts) > 2 { + switch parts[1] { + case paths.WikiSeg: + return "wiki" + case paths.ADRSeg: + return "adr" + case paths.CodewikiSeg: + return "codewiki" + } + } + return "docs" +} diff --git a/internal/view/view.go b/internal/view/view.go new file mode 100644 index 0000000..f2cb51a --- /dev/null +++ b/internal/view/view.go @@ -0,0 +1,149 @@ +// Package view serves the workspace's knowledge base, plans and specs as a local, +// read-only web page — `scc view`. +// +// Everything a person reads arrives through three JSON routes, and every route +// reads the disk on each request through the same parsers the rest of scc uses, +// so the page cannot disagree with `scc map` about what a file says. The frontend +// is built from web/ into dist/ and embedded, which keeps `go build` free of node. +// +// The boundary is loopback: the listener binds 127.0.0.1, and the middleware +// refuses a Host header that does not name loopback, which is what stops a page on +// the open web from reaching this server through DNS rebinding. +package view + +import ( + "context" + "embed" + "encoding/json" + "errors" + "io/fs" + "net" + "net/http" + "path" + "strings" + "time" +) + +//go:embed all:dist +var dist embed.FS + +// csp keeps scripts, styles and connections on this origin. 'unsafe-inline' is for +// styles only — React sets style attributes — and never for scripts, so injected +// Markdown that slipped past the renderer still could not run or phone home. +const csp = "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; " + + "object-src 'none'; base-uri 'none'; frame-ancestors 'none'" + +// Handler is the whole server: the three API routes, then the embedded app. +func Handler(root string) http.Handler { + mux := http.NewServeMux() + mux.HandleFunc("/api/tree", func(w http.ResponseWriter, r *http.Request) { + t, err := BuildTree(root) + if err != nil { + http.Error(w, "could not read the workspace", http.StatusInternalServerError) + return + } + writeJSON(w, t) + }) + mux.HandleFunc("/api/page", func(w http.ResponseWriter, r *http.Request) { + p, ok := LoadPage(root, r.URL.Query().Get("path")) + if !ok { + http.NotFound(w, r) + return + } + writeJSON(w, p) + }) + mux.HandleFunc("/api/source", func(w http.ResponseWriter, r *http.Request) { + s, ok := LoadSource(root, r.URL.Query().Get("path")) + if !ok { + http.NotFound(w, r) + return + } + writeJSON(w, s) + }) + mux.HandleFunc("/api/", http.NotFound) + mux.Handle("/", app()) + return guard(mux) +} + +// guard is the middleware every request passes before any route sees it. +func guard(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + h := w.Header() + h.Set("Content-Security-Policy", csp) + h.Set("X-Content-Type-Options", "nosniff") + h.Set("Referrer-Policy", "no-referrer") + if !loopbackHost(r.Host) { + http.Error(w, "forbidden", http.StatusForbidden) + return + } + if r.Method != http.MethodGet && r.Method != http.MethodHead { + h.Set("Allow", "GET, HEAD") + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + return + } + next.ServeHTTP(w, r) + }) +} + +// loopbackHost reports whether a Host header names this machine, with or without +// a port. A name that merely resolves to 127.0.0.1 is refused on purpose: that is +// exactly what a rebinding attacker's domain does. +func loopbackHost(host string) bool { + if h, _, err := net.SplitHostPort(host); err == nil { + host = h + } + host = strings.TrimSuffix(strings.TrimPrefix(host, "["), "]") + switch strings.ToLower(host) { + case "localhost", "127.0.0.1", "::1": + return true + } + return false +} + +// app serves the embedded frontend. A missing path with no extension gets +// index.html, so a reload on a client-side route still lands on the app; a missing +// file — a stale tab asking for an old bundle — gets a real 404, not HTML. +func app() http.Handler { + sub, err := fs.Sub(dist, "dist") + if err != nil { + panic(err) // the embed directive guarantees dist/ exists at build time + } + files := http.FileServer(http.FS(sub)) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + name := strings.TrimPrefix(r.URL.Path, "/") + if name != "" { + if st, err := fs.Stat(sub, name); err != nil || st.IsDir() { + if path.Ext(name) != "" { + http.NotFound(w, r) + return + } + r = r.Clone(r.Context()) + r.URL.Path = "/" + } + } + files.ServeHTTP(w, r) + }) +} + +func writeJSON(w http.ResponseWriter, v any) { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.Header().Set("Cache-Control", "no-store") + _ = json.NewEncoder(w).Encode(v) +} + +// Serve runs the server on ln until ctx is cancelled, then shuts it down. A +// cancelled context is the normal way out and returns nil. +func Serve(ctx context.Context, ln net.Listener, root string) error { + srv := &http.Server{Handler: Handler(root), ReadHeaderTimeout: 10 * time.Second} + done := make(chan error, 1) + go func() { + <-ctx.Done() + sctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + done <- srv.Shutdown(sctx) + }() + if err := srv.Serve(ln); !errors.Is(err, http.ErrServerClosed) { + return err + } + return <-done +} diff --git a/internal/view/view_test.go b/internal/view/view_test.go new file mode 100644 index 0000000..6cd0c47 --- /dev/null +++ b/internal/view/view_test.go @@ -0,0 +1,350 @@ +package view + +import ( + "context" + "encoding/json" + "net" + "net/http" + "net/http/httptest" + "os" + "path/filepath" + "runtime" + "strings" + "testing" + "time" +) + +// fixture lays out a workspace's readable tree: one page in each docs group, a +// plan with tasks, a spec, and source files the codewiki could cite. The manifest +// is not needed — the server is handed a root, it never looks for one. +func fixture(t *testing.T) string { + t.Helper() + root := t.TempDir() + files := map[string]string{ + "docs/wiki/index.md": "# Wiki\n\n- [[alpha]]\n", + "docs/wiki/changelog.md": "# Changelog\n", + "docs/wiki/pages/alpha.md": "# Alpha\n\nSee adr:0001-first.\n", + "docs/adr/0001-first.md": "---\nstatus: accepted\n---\n\n# First\n\n## Context\n\nWhy.\n", + "docs/codewiki/packages.md": "# Packages\n\n## Main\n\n[cmd/main.go:1-2]()\n", + "docs/glossary.md": "# Glossary\n", + "docs/raw/.hidden/secret.md": "# Hidden\n", + "plans/ship.md": "---\nautonomy: auto\n---\n\n# Ship\n\n## Tasks\n\n- [x] 1.1 (Unit) One\n- [ ] 1.2 (Unit) Two\n", + "specs/feat/requirements.md": "# Feat — requirements\n\n- **R1.1** The system shall work.\n", + "specs/feat/design.md": "# Feat — design\n", + "specs/feat/tasks.md": "# Feat — tasks\n\n- [x] 1.1 (Unit) Do — R1.1\n", + "cmd/main.go": "package main\r\n\r\nfunc main() {}\r\n", + ".env": "SECRET=1\n", + "internal/.cache/x.go": "package x\n", + "bin/blob": "ab\x00cd", + "notes.txt": "outside docs\n", + } + for rel, body := range files { + p := filepath.Join(root, filepath.FromSlash(rel)) + if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(p, []byte(body), 0o644); err != nil { + t.Fatal(err) + } + } + return root +} + +func get(t *testing.T, h http.Handler, target string) *httptest.ResponseRecorder { + t.Helper() + r := httptest.NewRequest(http.MethodGet, target, nil) + r.Host = "127.0.0.1:7777" + w := httptest.NewRecorder() + h.ServeHTTP(w, r) + return w +} + +func decodeBody(t *testing.T, w *httptest.ResponseRecorder, v any) { + t.Helper() + if w.Code != http.StatusOK { + t.Fatalf("status = %d, body %q", w.Code, w.Body.String()) + } + if err := json.Unmarshal(w.Body.Bytes(), v); err != nil { + t.Fatalf("decode: %v (%s)", err, w.Body.String()) + } +} + +func TestTreeGroupsEveryPageByKind(t *testing.T) { + var tree Tree + decodeBody(t, get(t, Handler(fixture(t)), "/api/tree"), &tree) + + byID := map[string][]Item{} + var ids []string + for _, g := range tree.Groups { + ids = append(ids, g.ID) + byID[g.ID] = g.Items + } + if got := strings.Join(ids, ","); got != "wiki,adr,codewiki,docs,plans,specs" { + t.Fatalf("groups = %s", got) + } + paths := func(id string) string { + var out []string + for _, it := range byID[id] { + out = append(out, it.Path) + } + return strings.Join(out, ",") + } + want := map[string]string{ + "wiki": "docs/wiki/index.md,docs/wiki/changelog.md,docs/wiki/pages/alpha.md", + "adr": "docs/adr/0001-first.md", + "codewiki": "docs/codewiki/packages.md", + "docs": "docs/glossary.md", + "plans": "plans/ship.md", + "specs": "specs/feat/requirements.md,specs/feat/design.md,specs/feat/tasks.md", + } + for id, w := range want { + if got := paths(id); got != w { + t.Errorf("%s = %s, want %s", id, got, w) + } + } + plan := byID["plans"][0] + if plan.Title != "Ship" || plan.Done != 1 || plan.Total != 2 { + t.Errorf("plan item = %+v, want Ship 1/2", plan) + } +} + +func TestTreeReadsTheDiskOnEveryRequest(t *testing.T) { + root := fixture(t) + h := Handler(root) + get(t, h, "/api/tree") + if err := os.WriteFile(filepath.Join(root, "plans", "later.md"), []byte("# Later\n"), 0o644); err != nil { + t.Fatal(err) + } + var tree Tree + decodeBody(t, get(t, h, "/api/tree"), &tree) + for _, g := range tree.Groups { + if g.ID == "plans" && len(g.Items) == 2 { + return + } + } + t.Fatal("a plan written after the first request is missing from the second") +} + +func TestTreeKeepsEmptyGroups(t *testing.T) { + var tree Tree + decodeBody(t, get(t, Handler(t.TempDir()), "/api/tree"), &tree) + if len(tree.Groups) != 6 { + t.Fatalf("groups = %d, want 6 even with nothing on disk", len(tree.Groups)) + } + for _, g := range tree.Groups { + if g.Items == nil { + t.Errorf("%s items is null, want []", g.ID) + } + } +} + +func TestPageSplitsFrontmatterFromBody(t *testing.T) { + var p Page + decodeBody(t, get(t, Handler(fixture(t)), "/api/page?path=docs/adr/0001-first.md"), &p) + if p.Frontmatter["status"] != "accepted" { + t.Errorf("frontmatter = %v", p.Frontmatter) + } + if strings.Contains(p.Body, "status:") || !strings.HasPrefix(strings.TrimSpace(p.Body), "# First") { + t.Errorf("body = %q, want the Markdown after the frontmatter", p.Body) + } + if p.Title != "First" || len(p.Sections) == 0 { + t.Errorf("title %q, sections %v", p.Title, p.Sections) + } +} + +func TestPageCarriesTaskProgress(t *testing.T) { + var p Page + decodeBody(t, get(t, Handler(fixture(t)), "/api/page?path=plans/ship.md"), &p) + if p.Done != 1 || p.Total != 2 || len(p.Tasks) != 2 || !p.Tasks[0].Checked { + t.Errorf("progress %d/%d, tasks %+v", p.Done, p.Total, p.Tasks) + } +} + +func TestPageRefusesAnythingButMarkdownInTheThreeTrees(t *testing.T) { + h := Handler(fixture(t)) + for _, rel := range []string{ + "", + "notes.txt", + "cmd/main.go", + "docs/../plans/ship.md", + "../outside.md", + "/etc/passwd", + "docs\\glossary.md", + "C:/Windows/win.ini", + "docs/missing.md", + "docs/wiki", + "docs/raw/.hidden/secret.md", + } { + if w := get(t, h, "/api/page?path="+rel); w.Code != http.StatusNotFound { + t.Errorf("page %q = %d, want 404", rel, w.Code) + } + } +} + +func TestPageRefusesASymlinkOutOfTheWorkspace(t *testing.T) { + root := fixture(t) + outside := filepath.Join(t.TempDir(), "x.md") + if err := os.WriteFile(outside, []byte("# Outside\n"), 0o644); err != nil { + t.Fatal(err) + } + if err := os.Symlink(outside, filepath.Join(root, "docs", "link.md")); err != nil { + t.Skipf("symlinks unavailable here: %v", err) + } + if w := get(t, Handler(root), "/api/page?path=docs/link.md"); w.Code != http.StatusNotFound { + t.Errorf("symlink out of the workspace = %d, want 404", w.Code) + } +} + +// A symlink committed inside the workspace passes the containment check, so the +// dot rule has to hold on where it points, not only on what was asked for. +func TestSourceRefusesASymlinkToADotPath(t *testing.T) { + root := fixture(t) + if err := os.Symlink(filepath.Join(root, ".env"), filepath.Join(root, "cmd", "env.txt")); err != nil { + t.Skipf("symlinks unavailable here: %v", err) + } + if w := get(t, Handler(root), "/api/source?path=cmd/env.txt"); w.Code != http.StatusNotFound { + t.Errorf("symlink to .env = %d, want 404", w.Code) + } +} + +// On Windows a dot-named directory usually has an 8.3 alias — .git is GIT~1 — +// which carries no dot, and reaches the same file. +func TestSourceRefusesAShortNameForADotPath(t *testing.T) { + if runtime.GOOS != "windows" { + t.Skip("8.3 short names are a Windows filesystem feature") + } + root := fixture(t) + if _, err := os.Stat(filepath.Join(root, "internal", "CACHE~1", "x.go")); err != nil { + t.Skipf("no 8.3 alias on this volume: %v", err) + } + if w := get(t, Handler(root), "/api/source?path=internal/CACHE~1/x.go"); w.Code != http.StatusNotFound { + t.Errorf("short name for internal/.cache = %d, want 404", w.Code) + } +} + +func TestTreeLeavesOutAnOversizedPage(t *testing.T) { + root := fixture(t) + big := "# Big\n" + strings.Repeat("a", maxFile) + if err := os.WriteFile(filepath.Join(root, "docs", "big.md"), []byte(big), 0o644); err != nil { + t.Fatal(err) + } + h := Handler(root) + if w := get(t, h, "/api/page?path=docs/big.md"); w.Code != http.StatusNotFound { + t.Errorf("oversized page = %d, want 404", w.Code) + } + if strings.Contains(get(t, h, "/api/tree").Body.String(), "docs/big.md") { + t.Error("oversized page is listed in the tree") + } +} + +func TestSourceReturnsLines(t *testing.T) { + var s Source + decodeBody(t, get(t, Handler(fixture(t)), "/api/source?path=cmd/main.go"), &s) + if len(s.Lines) != 3 || s.Lines[0] != "package main" || s.Lines[2] != "func main() {}" { + t.Errorf("lines = %q", s.Lines) + } +} + +func TestSourceRefusesDotSegmentsBinariesAndEscapes(t *testing.T) { + root := fixture(t) + big := filepath.Join(root, "big.txt") + if err := os.WriteFile(big, []byte(strings.Repeat("a", maxFile+1)), 0o644); err != nil { + t.Fatal(err) + } + h := Handler(root) + for _, rel := range []string{".env", "internal/.cache/x.go", "bin/blob", "big.txt", "../x", "cmd/../.env", "cmd"} { + if w := get(t, h, "/api/source?path="+rel); w.Code != http.StatusNotFound { + t.Errorf("source %q = %d, want 404", rel, w.Code) + } + } +} + +func TestGuardRefusesForeignHosts(t *testing.T) { + h := Handler(fixture(t)) + for host, want := range map[string]int{ + "127.0.0.1:7777": http.StatusOK, + "localhost:7777": http.StatusOK, + "[::1]:7777": http.StatusOK, + "LOCALHOST": http.StatusOK, + "evil.example:7777": http.StatusForbidden, + "127.0.0.1.nip.io": http.StatusForbidden, + "": http.StatusForbidden, + } { + r := httptest.NewRequest(http.MethodGet, "/api/tree", nil) + r.Host = host + w := httptest.NewRecorder() + h.ServeHTTP(w, r) + if w.Code != want { + t.Errorf("Host %q = %d, want %d", host, w.Code, want) + } + } +} + +func TestGuardRefusesWrites(t *testing.T) { + h := Handler(fixture(t)) + for _, m := range []string{http.MethodPost, http.MethodPut, http.MethodDelete, http.MethodPatch} { + r := httptest.NewRequest(m, "/api/tree", nil) + r.Host = "localhost" + w := httptest.NewRecorder() + h.ServeHTTP(w, r) + if w.Code != http.StatusMethodNotAllowed { + t.Errorf("%s = %d, want 405", m, w.Code) + } + } +} + +func TestEveryResponseCarriesTheContentSecurityPolicy(t *testing.T) { + h := Handler(fixture(t)) + for _, target := range []string{"/", "/api/tree", "/api/page?path=nope.md"} { + got := get(t, h, target).Header().Get("Content-Security-Policy") + if !strings.Contains(got, "default-src 'self'") || strings.Contains(got, "script-src 'unsafe-inline'") { + t.Errorf("%s CSP = %q", target, got) + } + } +} + +func TestAppFallsBackToIndex(t *testing.T) { + h := Handler(fixture(t)) + for _, target := range []string{"/", "/some/client/route"} { + w := get(t, h, target) + if w.Code != http.StatusOK || !strings.Contains(w.Body.String(), "") { + t.Errorf("%s = %d %q, want index.html", target, w.Code, w.Body.String()) + } + } + if w := get(t, h, "/assets/gone-1234.js"); w.Code != http.StatusNotFound { + t.Errorf("missing asset = %d, want 404 rather than the app", w.Code) + } + if w := get(t, h, "/api/unknown"); w.Code != http.StatusNotFound { + t.Errorf("/api/unknown = %d, want 404 rather than the app", w.Code) + } +} + +func TestServeStopsWhenTheContextIsCancelled(t *testing.T) { + ln, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + ctx, cancel := context.WithCancel(context.Background()) + done := make(chan error, 1) + root := fixture(t) + go func() { done <- Serve(ctx, ln, root) }() + + resp, err := http.Get("http://" + ln.Addr().String() + "/api/tree") + if err != nil { + t.Fatal(err) + } + _ = resp.Body.Close() + if resp.StatusCode != http.StatusOK { + t.Fatalf("live server answered %d", resp.StatusCode) + } + + cancel() + select { + case err := <-done: + if err != nil { + t.Fatalf("Serve returned %v on cancel, want nil", err) + } + case <-time.After(5 * time.Second): + t.Fatal("Serve did not return after cancel") + } +} diff --git a/specs/view/design.md b/specs/view/design.md new file mode 100644 index 0000000..110a469 --- /dev/null +++ b/specs/view/design.md @@ -0,0 +1,75 @@ +# View — design + +## What changes + +Serves R1.1, R1.2, R1.3, R1.4, R1.5, R2.1, R2.2, R2.3, R2.4, R2.5, R2.6, R3.1, R3.2, R3.3, R3.4, R3.5, R3.6. + +A new command, `scc view [--root] [--port N]`, and a new package, `internal/view`, +holding the HTTP server and the built frontend it embeds. `internal/cli/view.go` is +the thin handler every other resource has: flags, the workspace guard, then +`view.Serve`. + +The server is `net/http` from the standard library; the module stays stdlib-only +(`adr:0001-stdlib-only-dependencies`). Reading goes through the parsers the rest of +scc already uses — `artifact.Load` for a page's frontmatter, sections and tasks, +`artifact.Within` for the containment check — so the viewer cannot disagree with +`scc map` about what a file says. + +The frontend is React, built by Vite from `web/` into `internal/view/dist/`, which is +committed and embedded with `go:embed`. A `go build` therefore needs no node; only a +change to `web/` does. Reversing the "no embedded web dashboard" line of +`adr:0002-narrowed-from-csdd` is recorded in `adr:0003-local-read-only-viewer`. + +## Boundaries and contracts + +Bound to `127.0.0.1` only. Three JSON routes, GET only, everything else is the +embedded single-page app (unknown paths fall back to `index.html`): + +| Route | Answers | +|---|---| +| `GET /api/tree` | `{workspace, groups: [{id, title, items: [{path, title, kind, done, total}]}]}` — group ids `wiki`, `adr`, `codewiki`, `docs`, `plans`, `specs` | +| `GET /api/page?path=` | `{path, kind, title, frontmatter, sections, tasks, done, total, body}` — `body` is the Markdown after the frontmatter block | +| `GET /api/source?path=` | `{path, lines}` — the frontend highlights the cited range | + +Every request passes one middleware first: `Host` must be `localhost`, `127.0.0.1` +or `[::1]` with any port (DNS rebinding, R3.4), the method must be GET or HEAD +(R3.5), and every response carries +`Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:` +plus `X-Content-Type-Options: nosniff` (R3.6). + +Both routes share one check: the path must be workspace-relative, slash-separated +and already clean, carry no `.`-prefixed segment (`.git`, `.env`, the harness +directory — the same rule the tree walk skips by), name a regular file, and pass +`artifact.Within`. A page must also end in `.md` and start with `docs/`, `plans/` or +`specs/`; a source file must be at most 1 MiB with no NUL byte in its first 8 KiB. +A missing asset under the app is a 404; only an extensionless path falls back to +`index.html`. A refusal is 404 either way, so the answer does not say whether the file +exists. + +Frontend routing is hash-based — `#/page/`, `#/source/:-` — so +the server needs no route table beyond the three above. Link rewriting lives in one +module, `web/src/links.ts`: `[[slug]]` to `docs/wiki/pages/.md`, `adr:` +to `docs/adr/.md`, a relative `*.md` link resolved against the page's +directory, and an empty-target link whose text is `:[-]` to the +source view. Heading anchors use the same slug rule as `mdscan.Slug`, so the table +of contents built from the server's `sections` lands on the rendered headings. + +Markdown is rendered with `react-markdown` and `remark-gfm`, which escape raw HTML +by default (R3.6) — no `rehype-raw`, no `dangerouslySetInnerHTML`. + +## Alternatives considered + +- **Vendored React without a build step**, or **React from a CDN** — the first gives + up JSX and TypeScript, the second needs network and loads a third-party script + into a page that can read the workspace. The Vite build with a committed `dist/` + keeps `go build` node-free while keeping the frontend normal React. +- **Rendering Markdown to HTML in Go** — needs a Markdown-to-HTML renderer the + stdlib does not have; `mdscan` is a scanner, not a renderer, and writing one is + far more code than the page it serves. + +## Risks + +- `internal/view/dist/` can drift from `web/`. CI rebuilds it and fails on a diff. +- Serving source widens what the viewer exposes beyond `docs/`. The dot-segment rule + and loopback-only binding are the boundary; a repository file without a dot in + its path is readable by anybody who can already reach the user's loopback. diff --git a/specs/view/requirements.md b/specs/view/requirements.md new file mode 100644 index 0000000..d43eb76 --- /dev/null +++ b/specs/view/requirements.md @@ -0,0 +1,49 @@ +--- +autonomy: auto +ci: wait +branch: feat/view +delivery: in-review +pr: 56 +--- + +# View — requirements + +## Purpose + +`scc view` serves the workspace's knowledge base, plans and specs as a local, +read-only web page: the wiki, the ADRs, the codewiki with the source lines it cites, +the glossary, the stack, the note log, every plan and every spec. It is for a person +reading the record end to end — the one reader the addressing commands are not built +for — and it changes nothing on disk. + +## R1 · Serving + +- **R1.1** When `scc view` runs in a workspace, the viewer shall serve the web interface on the loopback interface and print its URL. +- **R1.2** Where `--port` is given, the viewer shall listen on that port, and on a free port the system picks when it is `0`. +- **R1.3** If the port cannot be bound, then the viewer shall exit 1 with a message naming the address. +- **R1.4** If the root is not an scc workspace, then the viewer shall exit 1 without starting a server. +- **R1.5** When the process receives an interrupt, the viewer shall shut the server down and exit 0. + +## R2 · Content + +- **R2.1** The viewer shall list every Markdown file under `docs/`, every plan and every spec, grouped as wiki, ADR, codewiki, other docs, plans and specs. +- **R2.2** When a page is opened, the viewer shall render its Markdown body, its frontmatter and a table of contents built from its headings. +- **R2.3** When a plan or a spec's `tasks.md` is opened, the viewer shall show its task progress as done over total. +- **R2.4** The viewer shall render `[[slug]]` wikilinks, `adr:` citations and relative links to Markdown files as links to those pages inside the viewer. +- **R2.5** When a codewiki citation `[:-]()` is followed, the viewer shall show that source file with the cited lines highlighted. +- **R2.6** The viewer shall read the workspace from disk on every request. + +## R3 · Safety + +- **R3.1** If a requested path resolves outside the workspace, then the viewer shall answer 404 without reading the file. +- **R3.2** If a requested page is not a Markdown file under `docs/`, `plans/` or `specs/`, then the viewer shall answer 404. +- **R3.3** If a requested path has a segment starting with `.`, or a requested source file is larger than 1 MiB or is not text, then the viewer shall answer 404. +- **R3.4** If a request's `Host` header does not name a loopback host, then the viewer shall answer 403. +- **R3.5** If a request uses a method other than GET or HEAD, then the viewer shall answer 405. +- **R3.6** The viewer shall render raw HTML inside Markdown as text and send a Content-Security-Policy limiting scripts and connections to its own origin. + +## Out of scope + +Editing anything, search, the symbol graph, live reload pushed from the server, +access from another machine, and authentication — loopback-only is the access +control. diff --git a/specs/view/tasks.md b/specs/view/tasks.md new file mode 100644 index 0000000..b04e03a --- /dev/null +++ b/specs/view/tasks.md @@ -0,0 +1,21 @@ +# View — tasks + +## 1 · Server + +- [x] 1.1 (Unit) Build the tree of docs, plans and specs into groups for `/api/tree` — R2.1, R2.3, R2.6 +- [x] 1.2 (Unit) Serve `/api/page` through the page-path guard and `artifact.Load` — R2.2, R2.3, R2.6, R3.1, R3.2 +- [x] 1.3 (Unit) Serve `/api/source` through the source-path guard — R2.5, R3.1, R3.3 +- [x] 1.4 (Unit) Wrap every route in the host, method and header middleware, and serve the embedded app with an `index.html` fallback — R3.4, R3.5, R3.6 +- [x] 1.5 (Unit) Add `scc view` with `--root` and `--port`, the workspace guard, loopback listen and interrupt shutdown — R1.1, R1.2, R1.3, R1.4, R1.5 + _Depends 1.1, 1.2, 1.3, 1.4_ + +## 2 · Frontend + +- [x] 2.1 (Unit) Scaffold `web/` with Vite, React and TypeScript, and write the link-rewriting and slug module with its tests — R2.4, R2.5 +- [x] 2.2 (Unit) Build the sidebar, page view with frontmatter, table of contents and task progress, and the source view, into `internal/view/dist/` — R2.1, R2.2, R2.3, R2.4, R2.5, R3.6 + _Depends 1.5, 2.1_ + +## 3 · Record + +- [x] 3.1 (Unit) Write `adr:0003-local-read-only-viewer`, the `stack.md` entries, the CI job that rebuilds `dist/` and fails on a diff, and the help text — R1.1, R3.6 + _Depends 2.2_ diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..27c0e73 --- /dev/null +++ b/web/index.html @@ -0,0 +1,12 @@ + + + + + + scc view + + +
+ + + diff --git a/web/package-lock.json b/web/package-lock.json new file mode 100644 index 0000000..359d38a --- /dev/null +++ b/web/package-lock.json @@ -0,0 +1,3091 @@ +{ + "name": "scc-view", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "scc-view", + "dependencies": { + "react": "19.3.0", + "react-dom": "19.3.0", + "react-markdown": "10.1.0", + "remark-gfm": "4.0.1" + }, + "devDependencies": { + "@types/react": "19.3.0", + "@types/react-dom": "19.3.0", + "@vitejs/plugin-react": "6.1.2", + "typescript": "7.0.2", + "vite": "8.3.2", + "vitest": "5.0.3" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@oxc-project/types": { + "version": "0.152.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.152.0.tgz", + "integrity": "sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.12.tgz", + "integrity": "sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.12.tgz", + "integrity": "sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.12.tgz", + "integrity": "sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.12.tgz", + "integrity": "sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.12.tgz", + "integrity": "sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.12.tgz", + "integrity": "sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.12.tgz", + "integrity": "sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.12.tgz", + "integrity": "sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.12.tgz", + "integrity": "sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.12.tgz", + "integrity": "sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.12.tgz", + "integrity": "sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.12.tgz", + "integrity": "sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.12.tgz", + "integrity": "sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.12.tgz", + "integrity": "sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.12.tgz", + "integrity": "sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz", + "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.3.0.tgz", + "integrity": "sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==", + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.3.0" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, + "node_modules/@typescript/typescript-aix-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-aix-ppc64/-/typescript-aix-ppc64-7.0.2.tgz", + "integrity": "sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-arm64/-/typescript-darwin-arm64-7.0.2.tgz", + "integrity": "sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-darwin-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-darwin-x64/-/typescript-darwin-x64-7.0.2.tgz", + "integrity": "sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-arm64/-/typescript-freebsd-arm64-7.0.2.tgz", + "integrity": "sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-freebsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-freebsd-x64/-/typescript-freebsd-x64-7.0.2.tgz", + "integrity": "sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm/-/typescript-linux-arm-7.0.2.tgz", + "integrity": "sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-arm64/-/typescript-linux-arm64-7.0.2.tgz", + "integrity": "sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-loong64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-loong64/-/typescript-linux-loong64-7.0.2.tgz", + "integrity": "sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-mips64el": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-mips64el/-/typescript-linux-mips64el-7.0.2.tgz", + "integrity": "sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-ppc64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-ppc64/-/typescript-linux-ppc64-7.0.2.tgz", + "integrity": "sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-riscv64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-riscv64/-/typescript-linux-riscv64-7.0.2.tgz", + "integrity": "sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-s390x": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-s390x/-/typescript-linux-s390x-7.0.2.tgz", + "integrity": "sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-linux-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-linux-x64/-/typescript-linux-x64-7.0.2.tgz", + "integrity": "sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-arm64/-/typescript-netbsd-arm64-7.0.2.tgz", + "integrity": "sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-netbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-netbsd-x64/-/typescript-netbsd-x64-7.0.2.tgz", + "integrity": "sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-arm64/-/typescript-openbsd-arm64-7.0.2.tgz", + "integrity": "sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-openbsd-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-openbsd-x64/-/typescript-openbsd-x64-7.0.2.tgz", + "integrity": "sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-sunos-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-sunos-x64/-/typescript-sunos-x64-7.0.2.tgz", + "integrity": "sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-arm64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-arm64/-/typescript-win32-arm64-7.0.2.tgz", + "integrity": "sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@typescript/typescript-win32-x64": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@typescript/typescript-win32-x64/-/typescript-win32-x64-7.0.2.tgz", + "integrity": "sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.4.0.tgz", + "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==", + "license": "ISC" + }, + "node_modules/@vitejs/plugin-react": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.1.2.tgz", + "integrity": "sha512-fhJNGUdscQa4HkI0xFxwonWyhnVReCPDbXI7FH7jmzpnVCrFQI7PRrhWecO263610vOrs9tr2Y4xcf8uAdFxbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rolldown/pluginutils": "^1.0.1" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@rolldown/plugin-babel": "^0.1.7 || ^0.2.0", + "babel-plugin-react-compiler": "^1.0.0", + "oxc-transform-react": "^0.152.0", + "vite": "^8.0.0" + }, + "peerDependenciesMeta": { + "@rolldown/plugin-babel": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "oxc-transform-react": { + "optional": true + } + } + }, + "node_modules/@vitest/mocker": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.3.tgz", + "integrity": "sha512-T8sWAIbkSyAjkwTcaEc3Iu0o9A27X1/kdXrizhZkGuSKScRQtRzclfAMpOTcGdXCsqxeWlpGy3XjqaW8CpLORg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.31", + "@vitest/spy": "5.0.3", + "estree-walker": "^3.0.3", + "magic-string": "^1.2.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/spy": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-5.0.3.tgz", + "integrity": "sha512-XhFysQTB8AZ+P4gMi+Lpo99vg2AZi0qKpaB9yXQl37+CaMEAPO3iH/wGVnSyL5MPERiLezpqTVtrR6UZH5GCXg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chai": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.3.0.tgz", + "integrity": "sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/html-url-attributes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", + "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/magic-string": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.4.3.tgz", + "integrity": "sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.6.0" + } + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.3.tgz", + "integrity": "sha512-xPgpDNl0/OXHsI7TlaIs22lWnH3KlpvZdXG1ET/m/YT2Hhdkx8lJV4kLphE6l9simyM4KPDFBwas08BgEob6Jw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.1.0.tgz", + "integrity": "sha512-KRLgmPaP2H1ul2bpoJkOS+9pAcDAAj9Nu1mqLnh8NLeJG5tlvj42TH80PIGBpROWlRXLk0lDrWNuZCFy/tsB4A==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.1.tgz", + "integrity": "sha512-OuJHqvr455pwu2OaOrir7dbzqs4jlWKOtlu9L6GjcIjjQwNyw02VntQsr/Ek6/A13vgnXfUhBekWRUP1OkNivw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.2.0.tgz", + "integrity": "sha512-2Jn/ADrHFFyyniBMi0bncTbJqU78K3/TEYvzvwrWWzD9MYPUa/Gm4r3nOeKFQg/PDM5BsbDYdc8ackW4NTY6NA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.3.tgz", + "integrity": "sha512-oGYfQzHSG5dOMovQcJ3fyTmZlWAWpi0XA0sJwJs+i6OT88o1+Jtw/8z0CmdowSLxGhhFK89rQ/oXph/wN02PNw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-edit-map": "^1.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.4.tgz", + "integrity": "sha512-wxEeE8v8XVvOrxn1TZj74qYhAtTQsSqufHVS3uNVyT1MupXxhyaHk8/9xDNPh9BmL77QNDgWTkZ3RsYHB2ry7w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.1.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-edit-map": "^1.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.3" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.2.tgz", + "integrity": "sha512-pRzm4kDTu0MjlmBkxmS9yYhw60nncfcEwu9NNdPFSQEFXS95ZKyIIyTSHu/o3ReBUrLKYEq+7YaXCRn/bPB4MA==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.1.0.tgz", + "integrity": "sha512-fS8hnLIjnjvdQIj39Geug8wWsR0HrYZ43KShKxNfwT7t2LOHo/LbWZEzEaSOjwtjdCsjoE6syHhonEzW0zv0+Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-edit-map": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/micromark-util-edit-map/-/micromark-util-edit-map-1.0.0.tgz", + "integrity": "sha512-Pa2ljlsEL6sVwFaYeyrOLSYbQt73JvGbPOYFq+9AElXiSnfI5Q4465RRZ1sHv7lDjDOnGRDDaqPXqClqWK/q1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.3.tgz", + "integrity": "sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/obug": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.2.1.tgz", + "integrity": "sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.29.tgz", + "integrity": "sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.19", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/property-information": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz", + "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.3.0.tgz", + "integrity": "sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.28.0" + }, + "peerDependencies": { + "react": "^19.3.0" + } + }, + "node_modules/react-markdown": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", + "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "html-url-attributes": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=18", + "react": ">=18" + } + }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rolldown": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.12.tgz", + "integrity": "sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.152.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm-eabi": "1.2.12", + "@rolldown/binding-android-arm64": "1.2.12", + "@rolldown/binding-darwin-arm64": "1.2.12", + "@rolldown/binding-darwin-x64": "1.2.12", + "@rolldown/binding-freebsd-x64": "1.2.12", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.12", + "@rolldown/binding-linux-arm64-gnu": "1.2.12", + "@rolldown/binding-linux-arm64-musl": "1.2.12", + "@rolldown/binding-linux-ppc64-gnu": "1.2.12", + "@rolldown/binding-linux-s390x-gnu": "1.2.12", + "@rolldown/binding-linux-x64-gnu": "1.2.12", + "@rolldown/binding-linux-x64-musl": "1.2.12", + "@rolldown/binding-openharmony-arm64": "1.2.12", + "@rolldown/binding-win32-arm64-msvc": "1.2.12", + "@rolldown/binding-win32-x64-msvc": "1.2.12" + } + }, + "node_modules/scheduler": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", + "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", + "license": "MIT" + }, + "node_modules/source-map-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/std-env": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.3.0.tgz", + "integrity": "sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==", + "dev": true, + "license": "MIT" + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, + "node_modules/tinybench": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-6.2.0.tgz", + "integrity": "sha512-78U2TlB2CnVenajOFzf3BKSm0J6oz5L0NV7g32LCPccvYc0lbWvys4d3uUUCS2B1N8PAf2+aekR8i1KbC3HO7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/tinyexec": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/typescript": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-7.0.2.tgz", + "integrity": "sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc" + }, + "engines": { + "node": ">=16.20.0" + }, + "optionalDependencies": { + "@typescript/typescript-aix-ppc64": "7.0.2", + "@typescript/typescript-darwin-arm64": "7.0.2", + "@typescript/typescript-darwin-x64": "7.0.2", + "@typescript/typescript-freebsd-arm64": "7.0.2", + "@typescript/typescript-freebsd-x64": "7.0.2", + "@typescript/typescript-linux-arm": "7.0.2", + "@typescript/typescript-linux-arm64": "7.0.2", + "@typescript/typescript-linux-loong64": "7.0.2", + "@typescript/typescript-linux-mips64el": "7.0.2", + "@typescript/typescript-linux-ppc64": "7.0.2", + "@typescript/typescript-linux-riscv64": "7.0.2", + "@typescript/typescript-linux-s390x": "7.0.2", + "@typescript/typescript-linux-x64": "7.0.2", + "@typescript/typescript-netbsd-arm64": "7.0.2", + "@typescript/typescript-netbsd-x64": "7.0.2", + "@typescript/typescript-openbsd-arm64": "7.0.2", + "@typescript/typescript-openbsd-x64": "7.0.2", + "@typescript/typescript-sunos-x64": "7.0.2", + "@typescript/typescript-win32-arm64": "7.0.2", + "@typescript/typescript-win32-x64": "7.0.2" + } + }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vite": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.2.tgz", + "integrity": "sha512-SQr1x6W5vVSbROg7vsyXIaxK9b0G7zsT68acdWWRmnBUsgDieLCRG+Rep9WdZgcposvv/GSnr4GUUBqB3vXq6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.7", + "postcss": "^8.5.28", + "rolldown": "~1.2.11", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.7.1", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-5.0.3.tgz", + "integrity": "sha512-xMw97S3rjdtj5dkVat7jCsqWBpvchs3RlpQctUqwJD0KkERk40vz2fJ77lDwW/Vzh/pk18eItYAzkodhSes3jQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/mocker": "5.0.3", + "chai": "^6.2.2", + "es-module-lexer": "^2.3.2", + "expect-type": "^1.4.0", + "magic-string": "^1.2.3", + "obug": "^2.1.4", + "picomatch": "^4.0.7", + "std-env": "^4.2.0", + "tinybench": "^6.1.4", + "tinyexec": "^1.3.0", + "tinyglobby": "^0.2.17", + "why-is-node-running": "3.2.1" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^22.12.0 || ^24.0.0 || >=26.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "5.0.3", + "@vitest/browser-preview": "5.0.3", + "@vitest/browser-webdriverio": "^5.0.0-beta.5 || >=5.0.0", + "@vitest/coverage-istanbul": "5.0.3", + "@vitest/coverage-v8": "5.0.3", + "@vitest/ui": "5.0.3", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.4.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, + "node_modules/why-is-node-running": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-3.2.1.tgz", + "integrity": "sha512-Tb2FUhB4vUsGQlfSquQLYkApkuPAFQXGFzxWKHHumVz2dK+X1RUm/HnID4+TfIGYJ1kTcwOaCk/buYCEJr6YjQ==", + "dev": true, + "license": "MIT", + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=20.11" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/web/package.json b/web/package.json new file mode 100644 index 0000000..8a9642e --- /dev/null +++ b/web/package.json @@ -0,0 +1,29 @@ +{ + "name": "scc-view", + "private": true, + "type": "module", + "engines": { + "node": "^22.12.0 || >=24.0.0" + }, + "description": "The frontend `scc view` embeds. Built into ../internal/view/dist, which is committed.", + "scripts": { + "dev": "vite", + "build": "tsc --noEmit && vite build", + "typecheck": "tsc --noEmit", + "test": "vitest run" + }, + "dependencies": { + "react": "19.3.0", + "react-dom": "19.3.0", + "react-markdown": "10.1.0", + "remark-gfm": "4.0.1" + }, + "devDependencies": { + "@types/react": "19.3.0", + "@types/react-dom": "19.3.0", + "@vitejs/plugin-react": "6.1.2", + "typescript": "7.0.2", + "vite": "8.3.2", + "vitest": "5.0.3" + } +} diff --git a/web/src/App.tsx b/web/src/App.tsx new file mode 100644 index 0000000..7cba101 --- /dev/null +++ b/web/src/App.tsx @@ -0,0 +1,50 @@ +import { useEffect, useState } from "react"; +import { fetchTree, type Tree } from "./api"; +import { parseRoute, type Route } from "./links"; +import { Home } from "./Home"; +import { PageView } from "./PageView"; +import { Sidebar } from "./Sidebar"; +import { SourceView } from "./SourceView"; + +function useRoute(): Route { + const [route, setRoute] = useState(() => parseRoute(location.hash)); + useEffect(() => { + const on = () => setRoute(parseRoute(location.hash)); + addEventListener("hashchange", on); + return () => removeEventListener("hashchange", on); + }, []); + return route; +} + +export function App() { + const route = useRoute(); + const [tree, setTree] = useState(null); + const [error, setError] = useState(null); + + // The tree is fetched again on every navigation: the server reads the disk on + // each request, so a page written since the last click shows up on the next. + useEffect(() => { + fetchTree() + .then((t) => { + setTree(t); + setError(null); + document.title = `${t.workspace} · scc view`; + }) + .catch((e: Error) => setError(e.message)); + }, [route]); + + const current = route.kind === "home" ? "" : route.path; + return ( +
+ +
+ {error &&

Could not read the workspace: {error}

} + {route.kind === "home" && } + {route.kind === "page" && } + {route.kind === "source" && ( + + )} +
+
+ ); +} diff --git a/web/src/Home.tsx b/web/src/Home.tsx new file mode 100644 index 0000000..1c40164 --- /dev/null +++ b/web/src/Home.tsx @@ -0,0 +1,55 @@ +import type { Item, Tree } from "./api"; +import { pageHref } from "./links"; +import { Progress } from "./Progress"; + +export function Home({ tree }: { tree: Tree | null }) { + if (!tree) return

Loading…

; + const group = (id: string) => tree.groups.find((g) => g.id === id)?.items ?? []; + const plans = group("plans"); + const tasks = group("specs").filter((it) => it.kind === "tasks"); + const index = group("wiki").find((it) => it.path === "docs/wiki/index.md"); + + return ( +
+
+

{tree.workspace}

+

The workspace's record: what was decided, what is being built, and how far along it is.

+
+ + + + {(plans.length > 0 || tasks.length > 0) && ( +
+

Progress

+ +
+ )} + + {index && ( +

+ Start with the wiki index. +

+ )} +
+ ); +} + +function first(id: string, items: Item[]): string { + if (id === "wiki") return items.find((i) => i.path === "docs/wiki/index.md")?.path ?? items[0].path; + return items[0].path; +} diff --git a/web/src/PageView.tsx b/web/src/PageView.tsx new file mode 100644 index 0000000..4614870 --- /dev/null +++ b/web/src/PageView.tsx @@ -0,0 +1,111 @@ +import { Children, isValidElement, useEffect, useMemo, useState, type ReactNode } from "react"; +import Markdown, { type Components } from "react-markdown"; +import remarkGfm from "remark-gfm"; +import { fetchPage, type Page } from "./api"; +import { linkify, pageHref, resolveLink, slug } from "./links"; +import { Progress } from "./Progress"; + +export function PageView({ path, heading }: { path: string; heading?: string }) { + const [page, setPage] = useState(null); + const [error, setError] = useState(null); + + useEffect(() => { + fetchPage(path).then(setPage, (e: Error) => setError(e.message)); + }, [path]); + + useEffect(() => { + if (!page) return; + if (heading) document.getElementById(heading)?.scrollIntoView(); + else window.scrollTo(0, 0); + }, [page, heading]); + + const components = useMemo(() => markdownComponents(path), [path]); + const body = useMemo(() => (page ? linkify(page.body) : ""), [page]); + + if (error) return

{path}: {error}

; + if (!page) return

Loading…

; + + const toc = page.sections.filter((s) => s.level >= 2 && s.level <= 3); + const fm = Object.entries(page.frontmatter); + return ( +
+
+
+
+ {page.path} + {page.kind} +
+ {fm.length > 0 && ( +
+ {fm.map(([k, v]) => ( +
+
{k}
+
{v}
+
+ ))} +
+ )} + {page.total > 0 && } +
+
+ + {body} + +
+
+ {toc.length > 1 && ( + + )} +
+ ); +} + +function markdownComponents(from: string): Components { + const heading = + (Tag: "h1" | "h2" | "h3" | "h4" | "h5" | "h6") => + ({ children }: { children?: ReactNode }) => {children}; + return { + h1: heading("h1"), + h2: heading("h2"), + h3: heading("h3"), + h4: heading("h4"), + h5: heading("h5"), + h6: heading("h6"), + a: ({ href, children }) => { + const target = resolveLink(href ?? "", textOf(children), from); + if (target === null) return {children}; + if ("external" in target) { + return ( + + {children} + + ); + } + return ( + + {children} + + ); + }, + }; +} + +// textOf flattens rendered children back to the text they came from, which is +// what a heading's slug and a citation's path are computed from. +function textOf(node: ReactNode): string { + let out = ""; + Children.forEach(node, (child) => { + if (typeof child === "string" || typeof child === "number") out += child; + else if (isValidElement<{ children?: ReactNode }>(child)) out += textOf(child.props.children); + }); + return out; +} diff --git a/web/src/Progress.tsx b/web/src/Progress.tsx new file mode 100644 index 0000000..8416d25 --- /dev/null +++ b/web/src/Progress.tsx @@ -0,0 +1,14 @@ +export function Progress({ done, total }: { done: number; total: number }) { + if (total === 0) return no tasks; + const pct = Math.round((done / total) * 100); + return ( + + + + + + {done}/{total} + + + ); +} diff --git a/web/src/Sidebar.tsx b/web/src/Sidebar.tsx new file mode 100644 index 0000000..b2c5ab1 --- /dev/null +++ b/web/src/Sidebar.tsx @@ -0,0 +1,91 @@ +import type { Group, Item, Tree } from "./api"; +import { pageHref } from "./links"; + +const specFile: Record = { + requirements: "Requirements", + design: "Design", + tasks: "Tasks", +}; + +export function Sidebar({ tree, current }: { tree: Tree | null; current: string }) { + return ( + + ); +} + +function Items({ items, current }: { items: Item[]; current: string }) { + return ( +
    + {items.map((it) => ( +
  • + +
  • + ))} +
+ ); +} + +// A spec is three files under one feature name, so the sidebar shows the feature +// once with its files beneath it rather than three near-identical titles. +function Specs({ items, current }: { items: Item[]; current: string }) { + const byFeature = new Map(); + for (const it of items) { + const feature = it.path.split("/")[1]; + byFeature.set(feature, [...(byFeature.get(feature) ?? []), it]); + } + return ( +
    + {[...byFeature].map(([feature, files]) => ( +
  • + {feature} +
      + {files.map((it) => ( +
    • + +
    • + ))} +
    +
  • + ))} +
+ ); +} + +function Link({ item, current, label }: { item: Item; current: string; label: string }) { + const active = item.path === current; + return ( + + {label} + {item.total > 0 && ( + + {item.done}/{item.total} + + )} + + ); +} + +// An ADR's filename carries its number, which the title does not. +function label(it: Item): string { + const m = /\/(\d{4})-[^/]+\.md$/.exec(it.path); + return m && it.path.startsWith("docs/adr/") ? `${m[1]} · ${it.title}` : it.title; +} + +function specCount(g: Group): number { + return new Set(g.items.map((it) => it.path.split("/")[1])).size; +} diff --git a/web/src/SourceView.tsx b/web/src/SourceView.tsx new file mode 100644 index 0000000..3db4900 --- /dev/null +++ b/web/src/SourceView.tsx @@ -0,0 +1,58 @@ +import { useEffect, useRef, useState } from "react"; +import { fetchSource, type Source } from "./api"; + +export function SourceView({ path, from, to }: { path: string; from?: number; to?: number }) { + const [src, setSrc] = useState(null); + const [error, setError] = useState(null); + const first = useRef(null); + + useEffect(() => { + fetchSource(path).then(setSrc, (e: Error) => setError(e.message)); + }, [path]); + + useEffect(() => { + if (src && first.current) first.current.scrollIntoView({ block: "center" }); + else if (src) window.scrollTo(0, 0); + }, [src, from]); + + if (error) return

{path}: {error}

; + if (!src) return

Loading…

; + + const lo = from ?? 0; + const hi = to ?? from ?? 0; + const outOfRange = from !== undefined && from > src.lines.length; + return ( +
+
+
+ {src.path} + {from !== undefined && {from === hi ? `line ${from}` : `lines ${from}–${hi}`}} +
+ +
+ {outOfRange && ( +

+ The citation points past the end of the file ({src.lines.length} lines) — the codewiki page has drifted. +

+ )} +
+ + + {src.lines.map((line, i) => { + const n = i + 1; + const hit = n >= lo && n <= hi; + return ( + + + + + ); + })} + +
{n}{line || " "}
+
+
+ ); +} diff --git a/web/src/api.ts b/web/src/api.ts new file mode 100644 index 0000000..7b6607f --- /dev/null +++ b/web/src/api.ts @@ -0,0 +1,64 @@ +// The three routes `scc view` answers; the shapes mirror internal/view. + +export interface Item { + path: string; + title: string; + kind: string; + done: number; + total: number; +} + +export interface Group { + id: "wiki" | "adr" | "codewiki" | "docs" | "plans" | "specs"; + title: string; + items: Item[]; +} + +export interface Tree { + workspace: string; + groups: Group[]; +} + +export interface Section { + slug: string; + level: number; + title: string; + line: number; +} + +export interface Task { + number: string; + checked: boolean; + methodology?: string; + text: string; + requirements?: string[]; + status?: string; + blocked: boolean; +} + +export interface Page { + path: string; + kind: string; + title: string; + frontmatter: Record; + sections: Section[]; + tasks: Task[]; + done: number; + total: number; + body: string; +} + +export interface Source { + path: string; + lines: string[]; +} + +async function get(url: string): Promise { + const res = await fetch(url, { cache: "no-store" }); + if (!res.ok) throw new Error(res.status === 404 ? "Not found, or not readable from the viewer." : `HTTP ${res.status}`); + return (await res.json()) as T; +} + +export const fetchTree = () => get("/api/tree"); +export const fetchPage = (path: string) => get("/api/page?path=" + encodeURIComponent(path)); +export const fetchSource = (path: string) => get("/api/source?path=" + encodeURIComponent(path)); diff --git a/web/src/links.test.ts b/web/src/links.test.ts new file mode 100644 index 0000000..11589a6 --- /dev/null +++ b/web/src/links.test.ts @@ -0,0 +1,109 @@ +import { describe, expect, it } from "vitest"; +import { linkify, normalize, parseRoute, resolveLink, slug } from "./links"; + +describe("slug", () => { + it("matches mdscan.Slug", () => { + expect(slug("How the dispatcher routes")).toBe("how-the-dispatcher-routes"); + expect(slug("R1 · Serving")).toBe("r1--serving"); + expect(slug("Out of scope")).toBe("out-of-scope"); + expect(slug("Ação_1-b")).toBe("ação_1-b"); + expect(slug("`code` & (parens)")).toBe("code--parens"); + }); +}); + +describe("linkify", () => { + it("turns wikilinks into page links", () => { + expect(linkify("see [[context-budget]] and [[note-log|notes]]")).toBe( + "see [context-budget](#/page/docs/wiki/pages/context-budget.md) and [notes](#/page/docs/wiki/pages/note-log.md)", + ); + }); + + it("turns adr citations into page links", () => { + expect(linkify("per adr:0001-stdlib-only-dependencies.")).toBe( + "per [adr:0001-stdlib-only-dependencies](#/page/docs/adr/0001-stdlib-only-dependencies.md).", + ); + }); + + it("links a code span that is exactly an adr citation", () => { + expect(linkify("see `adr:0001-a`.")).toBe("see [`adr:0001-a`](#/page/docs/adr/0001-a.md)."); + expect(linkify("`run adr:0001-a`")).toBe("`run adr:0001-a`"); + }); + + it("leaves code spans and fenced blocks alone", () => { + const md = "`[[x]]` and [[y]]\n```\n[[z]] adr:0001-a\n```\n~~~~\n[[w]]\n~~~~\n[[v]]"; + const out = linkify(md); + expect(out).toContain("`[[x]]`"); + expect(out).toContain("[y](#/page/docs/wiki/pages/y.md)"); + expect(out).toContain("\n[[z]] adr:0001-a\n"); + expect(out).toContain("\n[[w]]\n"); + expect(out).toContain("[v](#/page/docs/wiki/pages/v.md)"); + }); +}); + +describe("resolveLink", () => { + const from = "docs/codewiki/packages.md"; + + it("sends a codewiki citation to the source view with its range", () => { + expect(resolveLink("", "internal/cli/cli.go:48-64", from)).toEqual({ + internal: "#/source/internal/cli/cli.go:48-64", + }); + expect(resolveLink("", "internal/cli/cli.go:7", from)).toEqual({ + internal: "#/source/internal/cli/cli.go:7", + }); + }); + + it("goes nowhere for an empty link that is not a citation", () => { + expect(resolveLink("", "just text", from)).toBeNull(); + expect(resolveLink("", "../../etc/passwd:1", from)).toBeNull(); + }); + + it("resolves relative Markdown links against the page directory", () => { + expect(resolveLink("../wiki/index.md", "", from)).toEqual({ internal: "#/page/docs/wiki/index.md" }); + expect(resolveLink("other.md#risks", "", from)).toEqual({ + internal: "#/page/docs/codewiki/other.md?h=risks", + }); + }); + + it("sends a relative link to a non-Markdown file to the source view", () => { + expect(resolveLink("../../internal/x.go", "", from)).toEqual({ internal: "#/source/internal/x.go" }); + }); + + it("refuses a link that climbs out of the workspace", () => { + expect(resolveLink("../../../secret.md", "", from)).toBeNull(); + }); + + it("keeps a same-page anchor on the page", () => { + expect(resolveLink("#risks", "", from)).toEqual({ internal: "#/page/docs/codewiki/packages.md?h=risks" }); + }); + + it("opens web links outside and drops other schemes", () => { + expect(resolveLink("https://example.com", "", from)).toEqual({ external: "https://example.com" }); + expect(resolveLink("javascript:alert(1)", "", from)).toBeNull(); + expect(resolveLink("file:///etc/passwd", "", from)).toBeNull(); + }); +}); + +describe("parseRoute", () => { + it("reads pages, headings and sources back", () => { + expect(parseRoute("")).toEqual({ kind: "home" }); + expect(parseRoute("#/page/docs/wiki/index.md?h=start-here")).toEqual({ + kind: "page", + path: "docs/wiki/index.md", + heading: "start-here", + }); + expect(parseRoute("#/source/internal/cli/cli.go:48-64")).toEqual({ + kind: "source", + path: "internal/cli/cli.go", + from: 48, + to: 64, + }); + expect(parseRoute("#/source/go.mod")).toEqual({ kind: "source", path: "go.mod" }); + }); +}); + +describe("normalize", () => { + it("resolves dots and refuses escapes", () => { + expect(normalize("a/./b/../c")).toBe("a/c"); + expect(normalize("../a")).toBeNull(); + }); +}); diff --git a/web/src/links.ts b/web/src/links.ts new file mode 100644 index 0000000..9a4ddcd --- /dev/null +++ b/web/src/links.ts @@ -0,0 +1,159 @@ +// Everything the viewer decides about where a link goes lives here, so the +// rendering components never parse a path themselves. + +/** A place in the viewer, addressed by the URL hash. */ +export type Route = + | { kind: "home" } + | { kind: "page"; path: string; heading?: string } + | { kind: "source"; path: string; from?: number; to?: number }; + +/** + * slug renders heading text as an anchor exactly as `mdscan.Slug` does in Go: + * lowercased, spaces to hyphens, everything that is not a letter, digit, hyphen + * or underscore dropped. The table of contents comes from the server's sections + * and the headings are rendered here, so the two must agree to the byte. + */ +export function slug(text: string): string { + let out = ""; + for (const ch of text.toLowerCase()) { + if (ch === " ") out += "-"; + else if (/[\p{L}\p{N}_-]/u.test(ch)) out += ch; + } + return out; +} + +const wikilinkRe = /\[\[([^[\]]+)\]\]/g; +const adrRe = /\badr:(\d{4}-[a-z0-9][a-z0-9-]*)\b/g; +const fenceRe = /^[ \t]{0,3}(`{3,}|~{3,})/; +const citationRe = /^(.+?):(\d+)(?:-(\d+))?$/; + +/** pageHref is the hash for a page, with an optional heading to scroll to. */ +export function pageHref(path: string, heading?: string): string { + return "#/page/" + encodeURI(path) + (heading ? "?h=" + encodeURIComponent(heading) : ""); +} + +/** sourceHref is the hash for a source file, with an optional cited range. */ +export function sourceHref(path: string, from?: number, to?: number): string { + let h = "#/source/" + encodeURI(path); + if (from !== undefined) h += ":" + from + (to !== undefined && to !== from ? "-" + to : ""); + return h; +} + +/** + * linkify turns the two link forms Markdown does not know — `[[slug]]` wikilinks + * and `adr:` citations — into ordinary Markdown links to viewer routes. + * Fenced blocks and inline code are left alone, the same masking the validators + * apply, so an example in a code block is not turned into a link — except a code + * span that is exactly one ADR citation. + */ +export function linkify(markdown: string): string { + let fence: string | null = null; + return markdown + .split("\n") + .map((line) => { + const m = fenceRe.exec(line); + if (fence !== null) { + if (m && m[1][0] === fence[0] && m[1].length >= fence.length) fence = null; + return line; + } + if (m) { + fence = m[1]; + return line; + } + return line + .split(/(`+[^`]*`+)/) + .map((part, i) => (i % 2 === 1 ? linkifyCode(part) : linkifyProse(part))) + .join(""); + }) + .join("\n"); +} + +// A code span holding nothing but an ADR citation is how this workspace usually +// writes one, so that span becomes a link; any other code span stays as it is. +function linkifyCode(span: string): string { + const m = /^`+\s*adr:(\d{4}-[a-z0-9][a-z0-9-]*)\s*`+$/.exec(span); + return m ? `[${span}](${pageHref(`docs/adr/${m[1]}.md`)})` : span; +} + +function linkifyProse(text: string): string { + return text + .replace(wikilinkRe, (_, inner: string) => { + const [target, label] = inner.split("|", 2).map((s) => s.trim()); + return `[${label || target}](${pageHref(`docs/wiki/pages/${target}.md`)})`; + }) + .replace(adrRe, (whole, name: string) => `[${whole}](${pageHref(`docs/adr/${name}.md`)})`); +} + +/** What a rendered link does: navigate inside the viewer, leave it, or nothing. */ +export type Target = { internal: string } | { external: string } | null; + +/** + * resolveLink decides where a link in the page at `from` goes. A codewiki + * citation is a link with an empty destination whose text is + * `:[-]`; a relative link is resolved against the page's own + * directory, and one that climbs out of the workspace goes nowhere. + */ +export function resolveLink(href: string, text: string, from: string): Target { + if (href === "") { + const m = citationRe.exec(text.trim()); + if (!m) return null; + const path = normalize(m[1]); + if (path === null) return null; + return { internal: sourceHref(path, Number(m[2]), m[3] ? Number(m[3]) : undefined) }; + } + if (href.startsWith("#/")) return { internal: href }; + if (href.startsWith("#")) return { internal: pageHref(from, href.slice(1)) }; + if (/^[a-z][a-z0-9+.-]*:/i.test(href) || href.startsWith("//")) { + return /^(https?|mailto):/i.test(href) ? { external: href } : null; + } + const [rawPath, anchor] = splitOnce(href, "#"); + const base = from.includes("/") ? from.slice(0, from.lastIndexOf("/") + 1) : ""; + const path = normalize(rawPath.startsWith("/") ? rawPath.slice(1) : base + decodeSafe(rawPath)); + if (path === null) return null; + if (path.endsWith(".md")) return { internal: pageHref(path, anchor || undefined) }; + return { internal: sourceHref(path) }; +} + +/** parseRoute reads the URL hash back into a route. */ +export function parseRoute(hash: string): Route { + const h = hash.replace(/^#/, ""); + if (h.startsWith("/page/")) { + const [path, query] = splitOnce(h.slice("/page/".length), "?"); + const heading = new URLSearchParams(query).get("h") ?? undefined; + return { kind: "page", path: decodeSafe(path), heading }; + } + if (h.startsWith("/source/")) { + const rest = decodeSafe(h.slice("/source/".length)); + const m = /^(.*?):(\d+)(?:-(\d+))?$/.exec(rest); + if (!m) return { kind: "source", path: rest }; + const from = Number(m[2]); + return { kind: "source", path: m[1], from, to: m[3] ? Number(m[3]) : from }; + } + return { kind: "home" }; +} + +/** normalize resolves `.` and `..` segments, and refuses a path that escapes. */ +export function normalize(path: string): string | null { + const out: string[] = []; + for (const seg of path.split("/")) { + if (seg === "" || seg === ".") continue; + if (seg === "..") { + if (out.length === 0) return null; + out.pop(); + } else out.push(seg); + } + return out.length ? out.join("/") : null; +} + +function splitOnce(s: string, sep: string): [string, string] { + const i = s.indexOf(sep); + return i < 0 ? [s, ""] : [s.slice(0, i), s.slice(i + 1)]; +} + +function decodeSafe(s: string): string { + try { + return decodeURI(s); + } catch { + return s; + } +} diff --git a/web/src/main.tsx b/web/src/main.tsx new file mode 100644 index 0000000..663a43d --- /dev/null +++ b/web/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import { App } from "./App"; +import "./style.css"; + +createRoot(document.getElementById("root")!).render( + + + , +); diff --git a/web/src/style.css b/web/src/style.css new file mode 100644 index 0000000..04c0348 --- /dev/null +++ b/web/src/style.css @@ -0,0 +1,454 @@ +:root { + --bg: #fbfbfa; + --panel: #f3f2ef; + --text: #1f2328; + --muted: #656d76; + --line: #e2e0db; + --accent: #2f6f5e; + --accent-soft: #e2efe9; + --hit: #fff4c2; + --code-bg: #f1efeb; + --error: #b42318; + --mono: ui-monospace, "Cascadia Code", "SF Mono", Menlo, Consolas, monospace; + --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; + color-scheme: light; +} + +@media (prefers-color-scheme: dark) { + :root { + --bg: #15171a; + --panel: #1c1f23; + --text: #e6e6e3; + --muted: #9198a1; + --line: #2e3238; + --accent: #6cc4a8; + --accent-soft: #1f3530; + --hit: #3b3415; + --code-bg: #22262b; + --error: #ff8a80; + color-scheme: dark; + } +} + +* { + box-sizing: border-box; +} + +body { + margin: 0; + background: var(--bg); + color: var(--text); + font: 15px/1.6 var(--sans); +} + +a { + color: var(--accent); + text-decoration: none; +} +a:hover { + text-decoration: underline; +} + +code, +pre { + font-family: var(--mono); + font-size: 0.88em; +} + +.shell { + display: grid; + grid-template-columns: 280px minmax(0, 1fr); + min-height: 100vh; +} + +/* Sidebar */ +.sidebar { + position: sticky; + top: 0; + height: 100vh; + overflow-y: auto; + background: var(--panel); + border-right: 1px solid var(--line); + padding: 16px 12px 32px; + font-size: 14px; +} +.brand { + display: flex; + align-items: center; + gap: 8px; + padding: 4px 8px 16px; + color: var(--text); +} +.brand:hover { + text-decoration: none; +} +.brand-mark { + font: 600 12px var(--mono); + background: var(--accent); + color: var(--bg); + border-radius: 4px; + padding: 2px 6px; +} +.brand-name { + font-weight: 600; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.group h2 { + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--muted); + margin: 16px 8px 4px; +} +.count { + font-weight: 400; +} +.sidebar ul { + list-style: none; + margin: 0; + padding: 0; +} +.sidebar a { + display: flex; + justify-content: space-between; + gap: 8px; + padding: 3px 8px; + border-radius: 6px; + color: var(--text); +} +.sidebar a:hover { + background: var(--line); + text-decoration: none; +} +.sidebar a.active { + background: var(--accent-soft); + color: var(--accent); + font-weight: 600; +} +.sidebar .label { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.feature-name { + display: block; + padding: 4px 8px 0; + font-family: var(--mono); + font-size: 13px; + color: var(--muted); +} +.feature ul a { + padding-left: 20px; +} +.tally { + flex: none; + font: 12px var(--mono); + color: var(--muted); +} +.tally.done { + color: var(--accent); +} + +/* Main */ +.main { + padding: 32px 40px 80px; + min-width: 0; +} +.page { + display: grid; + grid-template-columns: minmax(0, 780px) 220px; + gap: 40px; +} +.page-head { + margin-bottom: 16px; +} +.crumb { + display: flex; + align-items: center; + gap: 8px; + color: var(--muted); + font-size: 13px; +} +.kind { + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.05em; + border: 1px solid var(--line); + border-radius: 999px; + padding: 0 8px; +} +.frontmatter { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin: 10px 0; +} +.frontmatter div { + display: flex; + border: 1px solid var(--line); + border-radius: 6px; + overflow: hidden; + font-size: 12px; +} +.frontmatter dt { + background: var(--panel); + color: var(--muted); + padding: 1px 8px; +} +.frontmatter dd { + margin: 0; + padding: 1px 8px; + font-family: var(--mono); +} + +.progress { + display: inline-flex; + align-items: center; + gap: 8px; +} +.bar { + display: inline-block; + width: 120px; + height: 6px; + border-radius: 3px; + background: var(--line); + overflow: hidden; +} +.fill { + display: block; + height: 100%; + background: var(--accent); +} + +/* Markdown */ +.markdown h1 { + font-size: 1.9em; + line-height: 1.25; + margin: 0 0 16px; +} +.markdown h2 { + font-size: 1.35em; + margin: 32px 0 8px; + padding-bottom: 4px; + border-bottom: 1px solid var(--line); +} +.markdown h3 { + font-size: 1.1em; + margin: 24px 0 8px; +} +.markdown :is(h1, h2, h3, h4) { + scroll-margin-top: 16px; +} +.markdown :not(pre) > code { + background: var(--code-bg); + padding: 1px 5px; + border-radius: 4px; +} +.markdown pre { + tab-size: 4; + background: var(--code-bg); + padding: 12px 14px; + border-radius: 8px; + overflow-x: auto; + line-height: 1.45; +} +.markdown table { + border-collapse: collapse; + display: block; + overflow-x: auto; + margin: 12px 0; +} +.markdown th, +.markdown td { + border: 1px solid var(--line); + padding: 5px 10px; + text-align: left; + vertical-align: top; +} +.markdown th { + background: var(--panel); +} +.markdown blockquote { + margin: 12px 0; + padding: 2px 14px; + border-left: 3px solid var(--accent); + color: var(--muted); +} +.markdown li.task-list-item { + list-style: none; +} +.markdown ul.contains-task-list { + padding-left: 1.2em; +} +.markdown .cite { + font-family: var(--mono); + font-size: 0.88em; + background: var(--accent-soft); + padding: 1px 6px; + border-radius: 4px; +} +.dead-link { + text-decoration: underline dotted; + color: var(--muted); +} + +/* Table of contents */ +.toc { + position: sticky; + top: 32px; + align-self: start; + max-height: calc(100vh - 64px); + overflow-y: auto; + font-size: 13px; +} +.toc h2 { + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.06em; + color: var(--muted); + margin: 0 0 8px; +} +.toc ul { + list-style: none; + margin: 0; + padding: 0 0 0 10px; + border-left: 1px solid var(--line); +} +.toc li { + padding: 2px 0; +} +.toc li.l3 { + padding-left: 12px; +} +.toc a { + color: var(--muted); +} +.toc a:hover { + color: var(--accent); +} + +/* Source */ +.source .page-head { + display: flex; + justify-content: space-between; + align-items: center; +} +.back { + font: inherit; + font-size: 13px; + color: var(--accent); + background: none; + border: 1px solid var(--line); + border-radius: 6px; + padding: 2px 10px; + cursor: pointer; +} +.code { + border: 1px solid var(--line); + border-radius: 8px; + overflow-x: auto; + background: var(--code-bg); +} +.code table { + border-collapse: collapse; + font: 13px/1.5 var(--mono); + width: 100%; +} +.code .ln { + width: 1%; + padding: 0 12px; + text-align: right; + color: var(--muted); + user-select: none; + border-right: 1px solid var(--line); +} +.code .tx { + padding: 0 14px; + white-space: pre; + tab-size: 4; +} +.code tr.hit { + background: var(--hit); +} +.code tr.hit .ln { + color: var(--text); + font-weight: 600; +} + +/* Home */ +.cards { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); + gap: 12px; + margin: 16px 0 32px; +} +.card { + display: flex; + flex-direction: column; + padding: 14px 16px; + border: 1px solid var(--line); + border-radius: 10px; + background: var(--panel); + color: var(--text); +} +.card:hover { + border-color: var(--accent); + text-decoration: none; +} +.card-n { + font-size: 26px; + font-weight: 600; + line-height: 1.2; +} +.card-t { + color: var(--muted); + font-size: 13px; +} +.progress-list { + list-style: none; + padding: 0; +} +.progress-list li { + display: grid; + grid-template-columns: minmax(0, 1fr) 50px auto; + align-items: center; + gap: 12px; + padding: 6px 0; + border-bottom: 1px solid var(--line); +} + +.muted { + color: var(--muted); +} +.small { + font-size: 12px; +} +.error { + color: var(--error); +} + +@media (max-width: 1100px) { + .page { + grid-template-columns: minmax(0, 1fr); + } + .toc { + display: none; + } +} +@media (max-width: 760px) { + .shell { + grid-template-columns: 1fr; + } + .sidebar { + position: static; + height: auto; + max-height: 40vh; + border-right: 0; + border-bottom: 1px solid var(--line); + } + .main { + padding: 20px 16px 60px; + } +} diff --git a/web/tsconfig.json b/web/tsconfig.json new file mode 100644 index 0000000..b0f5411 --- /dev/null +++ b/web/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "module": "ESNext", + "moduleResolution": "bundler", + "jsx": "react-jsx", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "isolatedModules": true, + "skipLibCheck": true, + "noEmit": true, + "types": ["vite/client"] + }, + "include": ["src", "vite.config.ts"] +} diff --git a/web/vite.config.ts b/web/vite.config.ts new file mode 100644 index 0000000..8db26db --- /dev/null +++ b/web/vite.config.ts @@ -0,0 +1,17 @@ +import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; + +// The build lands in the Go package that embeds it. `npm run dev` proxies the API +// to a running `scc view`, so the frontend can be worked on with hot reload. +export default defineConfig({ + plugins: [react()], + base: "./", + build: { + outDir: "../internal/view/dist", + emptyOutDir: true, + sourcemap: false, + }, + server: { + proxy: { "/api": { target: "http://127.0.0.1:7777", changeOrigin: true } }, + }, +});