From 7d7133d6cc22d78b4271c916b05b614fd2a90f7c Mon Sep 17 00:00:00 2001 From: Shaun Campbell Date: Wed, 16 Sep 2026 13:47:07 -0400 Subject: [PATCH] feat: ship Barkstack UI plugin --- .dockerignore | 3 + .gitignore | 1 + Dockerfile | 11 +- README.md | 12 +- cmd/pawsql/main.go | 87 +- internal/adminui/dist/assets/entry.js | 3203 +++++++++++++++++++++++++ internal/adminui/handler.go | 118 + internal/adminui/handler_test.go | 62 + ui/bun.lock | 350 +++ ui/package.json | 20 + ui/src/PawSQL.svelte | 113 + ui/src/entry.ts | 1 + ui/src/events.test.ts | 22 + ui/src/events.ts | 15 + ui/tsconfig.json | 17 + ui/vite.config.ts | 18 + 16 files changed, 4034 insertions(+), 19 deletions(-) create mode 100644 .dockerignore create mode 100644 internal/adminui/dist/assets/entry.js create mode 100644 internal/adminui/handler.go create mode 100644 internal/adminui/handler_test.go create mode 100644 ui/bun.lock create mode 100644 ui/package.json create mode 100644 ui/src/PawSQL.svelte create mode 100644 ui/src/entry.ts create mode 100644 ui/src/events.test.ts create mode 100644 ui/src/events.ts create mode 100644 ui/tsconfig.json create mode 100644 ui/vite.config.ts diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..636bab8 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +.git +pawsql +ui/node_modules diff --git a/.gitignore b/.gitignore index 2cc413a..428de16 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /Barkfile /pawsql +/ui/node_modules diff --git a/Dockerfile b/Dockerfile index b47c5c8..a066af2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,11 @@ # syntax=docker/dockerfile:1.7 +FROM oven/bun:1.4.0-alpine AS ui +WORKDIR /src/ui +COPY ui/package.json ui/bun.lock ./ +RUN bun install --frozen-lockfile +COPY ui ./ +RUN bun run build + FROM golang:1.24-alpine AS build WORKDIR /src RUN apk add --no-cache git @@ -6,10 +13,12 @@ COPY go.mod go.sum ./ RUN go mod download COPY cmd ./cmd COPY internal ./internal +COPY --from=ui /src/internal/adminui/dist ./internal/adminui/dist RUN CGO_ENABLED=0 go build -trimpath -ldflags='-s -w' -o /pawsql ./cmd/pawsql FROM alpine:3.21 RUN apk add --no-cache ca-certificates docker-cli COPY --from=build /pawsql /usr/local/bin/pawsql +EXPOSE 5432 ENTRYPOINT ["/usr/local/bin/pawsql"] -CMD ["--config", "/etc/pawsql/Barkfile"] +CMD ["--config", "/etc/pawsql/Barkfile", "--admin-listen", ":9090"] diff --git a/README.md b/README.md index 2bb8994..0792870 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,13 @@ PawSQL is a TLS-terminating PostgreSQL router. It accepts PostgreSQL clients on ## Build, configure, and run -Build a native binary: +Build the independently owned Svelte plugin, then the native binary: ```sh +cd ui +bun install +bun run build +cd .. go build -o pawsql ./cmd/pawsql ``` @@ -21,10 +25,10 @@ Create a `Barkfile` and validate it before starting: ```sh ./pawsql validate --config Barkfile -./pawsql --config Barkfile +./pawsql --config Barkfile --admin-listen :9090 ``` -`--config` defaults to `Barkfile`. The listener, TLS material, and at least one database route are required. +`--config` defaults to `Barkfile`. The PostgreSQL listener, TLS material, and at least one database route are required. `--admin-listen` defaults to `:9090` and serves PawSQL's embedded Barkstack plugin at `/barkstack/ui/`; pass an empty value to disable it. The admin port is intended for Barkstack over localhost or a private overlay network, not direct publication. To build and run the PawSQL container image for routes reachable from that container: @@ -37,7 +41,7 @@ docker run --rm --publish 5432:5432 \ pawsql ``` -The supplied image includes the Docker CLI so managed `postgres` routes can create, start, and stop their containers through the mounted Docker socket. The socket grants PawSQL root-equivalent control of the Docker host; mount it only for trusted Barkfiles and trusted administrators. +The supplied image includes the compiled PawSQL Svelte plugin and Docker CLI; production does not run Node or Bun. The Docker CLI lets managed `postgres` routes create, start, and stop containers through the mounted Docker socket. The socket grants PawSQL root-equivalent control of the Docker host; mount it only for trusted Barkfiles and trusted administrators. Publish PostgreSQL port 5432 as needed, but leave admin port 9090 unpublished and let Barkstack proxy the UI. ## Barkfile diff --git a/cmd/pawsql/main.go b/cmd/pawsql/main.go index 82f45a5..0ab3708 100644 --- a/cmd/pawsql/main.go +++ b/cmd/pawsql/main.go @@ -1,17 +1,21 @@ package main import ( + "context" "crypto/tls" "errors" "flag" "fmt" "log/slog" "net" + "net/http" "os" "os/signal" "syscall" + "time" config "cloud.campbellwireless.net/git/barkstack/barkfile-parser" + "github.com/barkstack/pawsql/internal/adminui" "github.com/barkstack/pawsql/internal/postgres" "github.com/barkstack/pawsql/internal/router" "github.com/barkstack/pawsql/internal/server" @@ -26,7 +30,7 @@ func main() { } func run(args []string, logger *slog.Logger) error { - validateOnly, configPath, err := parseArguments(args) + validateOnly, configPath, adminListen, err := parseArguments(args) if err != nil { return err } @@ -67,30 +71,83 @@ func run(args []string, logger *slog.Logger) error { } logger.Info("pawsql listening", "address", listener.Addr().String()) + type serveResult struct { + name string + err error + } + serveErrors := make(chan serveResult, 2) + serverCount := 1 + go func() { serveErrors <- serveResult{name: "PostgreSQL", err: routingServer.Serve(listener)} }() + + var adminServer *http.Server + if adminListen != "" { + routes := make([]adminui.RouteSummary, 0, len(cfg.Databases)) + for _, database := range cfg.Databases { + routes = append(routes, adminui.RouteSummary{Name: database.Name, Hostname: database.Hostname, Managed: database.Postgres != nil}) + } + adminListener, err := net.Listen("tcp", adminListen) + if err != nil { + _ = routingServer.Shutdown() + return fmt.Errorf("listen for admin HTTP on %s: %w", adminListen, err) + } + adminServer = &http.Server{ + Handler: adminui.Handler(routes), + ReadHeaderTimeout: 10 * time.Second, + IdleTimeout: 60 * time.Second, + } + serverCount++ + logger.Info("pawsql admin UI listening", "address", adminListener.Addr().String()) + go func() { + err := adminServer.Serve(adminListener) + if errors.Is(err, http.ErrServerClosed) { + err = nil + } + serveErrors <- serveResult{name: "admin HTTP", err: err} + }() + } + + shutdown := func() error { + if err := routingServer.Shutdown(); err != nil && !errors.Is(err, net.ErrClosed) { + return fmt.Errorf("stop PostgreSQL listener: %w", err) + } + if adminServer != nil { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + if err := adminServer.Shutdown(ctx); err != nil { + return fmt.Errorf("stop admin HTTP listener: %w", err) + } + } + return nil + } + signals := make(chan os.Signal, 1) signal.Notify(signals, os.Interrupt, syscall.SIGTERM) defer signal.Stop(signals) - serveErrors := make(chan error, 1) - go func() { serveErrors <- routingServer.Serve(listener) }() - select { case received := <-signals: logger.Info("shutdown signal received", "signal", received.String()) - if err := routingServer.Shutdown(); err != nil && !errors.Is(err, net.ErrClosed) { - return fmt.Errorf("stop listener: %w", err) - } - if err := <-serveErrors; err != nil { + if err := shutdown(); err != nil { return err } + for range serverCount { + result := <-serveErrors + if result.err != nil { + return fmt.Errorf("%s server: %w", result.name, result.err) + } + } routingServer.Wait() logger.Info("pawsql shutdown complete") return nil - case err := <-serveErrors: - return err + case result := <-serveErrors: + _ = shutdown() + if result.err == nil { + return fmt.Errorf("%s server stopped unexpectedly", result.name) + } + return fmt.Errorf("%s server: %w", result.name, result.err) } } -func parseArguments(args []string) (validateOnly bool, configPath string, err error) { +func parseArguments(args []string) (validateOnly bool, configPath, adminListen string, err error) { if len(args) > 0 && args[0] == "validate" { validateOnly = true args = args[1:] @@ -98,12 +155,14 @@ func parseArguments(args []string) (validateOnly bool, configPath string, err er flags := flag.NewFlagSet("pawsql", flag.ContinueOnError) flags.SetOutput(os.Stderr) configPath = "Barkfile" + adminListen = ":9090" flags.StringVar(&configPath, "config", configPath, "path to Barkfile") + flags.StringVar(&adminListen, "admin-listen", adminListen, "admin HTTP listen address (empty disables)") if err := flags.Parse(args); err != nil { - return false, "", err + return false, "", "", err } if flags.NArg() != 0 { - return false, "", fmt.Errorf("unexpected arguments: %v", flags.Args()) + return false, "", "", fmt.Errorf("unexpected arguments: %v", flags.Args()) } - return validateOnly, configPath, nil + return validateOnly, configPath, adminListen, nil } diff --git a/internal/adminui/dist/assets/entry.js b/internal/adminui/dist/assets/entry.js new file mode 100644 index 0000000..368feb3 --- /dev/null +++ b/internal/adminui/dist/assets/entry.js @@ -0,0 +1,3203 @@ +typeof window < "u" && ((window.__svelte ??= {}).v ??= /* @__PURE__ */ new Set()).add("5"); +const jn = 1, zn = 2, Hn = 16, qn = 1, Bn = 2, Rr = "[", Kt = "[!", mr = "[?", Jt = "]", qe = {}, A = /* @__PURE__ */ Symbol("uninitialized"), Nr = !1; +var Or = Array.isArray, Vn = Array.prototype.indexOf, _t = Array.prototype.includes, xt = Array.from, gt = Object.keys, rt = Object.defineProperty, ze = Object.getOwnPropertyDescriptor, Yn = Object.prototype, Un = Array.prototype, Qn = Object.getPrototypeOf, br = Object.isExtensible; +const Gn = () => { +}; +function Wn(e) { + for (var t = 0; t < e.length; t++) + e[t](); +} +function Mr() { + var e, t, r = new Promise((n, s) => { + e = n, t = s; + }); + return { promise: r, resolve: e, reject: t }; +} +const N = 2, Be = 4, St = 8, Pr = 1 << 24, X = 16, W = 32, fe = 64, Ht = 128, Xt = 256, G = 512, C = 1024, S = 2048, te = 4096, F = 8192, H = 16384, Pe = 32768, mt = 1 << 25, Ve = 65536, bt = 1 << 17, Kn = 1 << 18, De = 1 << 19, Jn = 1 << 20, pe = 1 << 25, Ne = 65536, kt = 1 << 21, He = 1 << 22, Ee = 1 << 23, ct = /* @__PURE__ */ Symbol("$state"), Dr = /* @__PURE__ */ Symbol("component"), Xn = /* @__PURE__ */ Symbol("legacy props"), Zn = /* @__PURE__ */ Symbol("attributes"), qt = /* @__PURE__ */ Symbol("class"), es = /* @__PURE__ */ Symbol("style"), Bt = /* @__PURE__ */ Symbol("text"), st = new class extends Error { + name = "StaleReactionError"; + message = "The reaction that called `getAbortSignal()` was re-run or destroyed"; +}(), Tt = 3, it = 8; +function ts() { + console.warn("https://svelte.dev/e/derived_inert"); +} +function At(e) { + console.warn("https://svelte.dev/e/hydration_mismatch"); +} +function rs() { + console.warn("https://svelte.dev/e/svelte_boundary_reset_noop"); +} +let $ = !1; +function _e(e) { + $ = e; +} +let k; +function V(e) { + if (e === null) + throw At(), qe; + return k = e; +} +function Ct() { + return V(/* @__PURE__ */ ve(k)); +} +function D(e) { + if ($) { + if (/* @__PURE__ */ ve(k) !== null) + throw At(), qe; + k = e; + } +} +function We(e = 1) { + if ($) { + for (var t = e, r = k; t--; ) + r = /** @type {TemplateNode} */ + /* @__PURE__ */ ve(r); + k = r; + } +} +function wt(e = !0) { + for (var t = 0, r = k; ; ) { + if (r.nodeType === it) { + var n = ( + /** @type {Comment} */ + r.data + ); + if (n === Jt) { + if (t === 0) return r; + t -= 1; + } else (n === Rr || n === Kt || // "[1", "[2", etc. for if blocks + n[0] === "[" && !isNaN(Number(n.slice(1)))) && (t += 1); + } + var s = ( + /** @type {TemplateNode} */ + /* @__PURE__ */ ve(r) + ); + e && r.remove(), r = s; + } +} +function Lr(e) { + if (!e || e.nodeType !== it) + throw At(), qe; + return ( + /** @type {Comment} */ + e.data + ); +} +function Fr(e) { + return e === this.v; +} +function ns(e, t) { + return e != e ? t == t : e !== t || e !== null && typeof e == "object" || typeof e == "function"; +} +function Ir(e) { + return !ns(e, this.v); +} +function ss(e) { + throw new Error("https://svelte.dev/e/lifecycle_outside_component"); +} +function is() { + throw new Error("https://svelte.dev/e/async_derived_orphan"); +} +function ls(e, t, r) { + throw new Error("https://svelte.dev/e/each_key_duplicate"); +} +function as(e) { + throw new Error("https://svelte.dev/e/effect_in_teardown"); +} +function os() { + throw new Error("https://svelte.dev/e/effect_in_unowned_derived"); +} +function fs(e) { + throw new Error("https://svelte.dev/e/effect_orphan"); +} +function us() { + throw new Error("https://svelte.dev/e/effect_update_depth_exceeded"); +} +function cs() { + throw new Error("https://svelte.dev/e/hydration_failed"); +} +function vs() { + throw new Error("https://svelte.dev/e/state_descriptors_fixed"); +} +function ds() { + throw new Error("https://svelte.dev/e/state_prototype_fixed"); +} +function hs() { + throw new Error("https://svelte.dev/e/state_unsafe_mutation"); +} +function ps() { + throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror"); +} +let _s = !1, P = null; +function Ye(e) { + P = e; +} +function jr(e, t = !1, r) { + P = { + p: P, + i: !1, + c: null, + e: null, + s: e, + x: null, + r: ( + /** @type {Effect} */ + _ + ), + l: null + }; +} +function zr(e) { + var t = ( + /** @type {ComponentContext} */ + P + ), r = t.e; + if (r !== null) { + t.e = null; + for (var n of r) + an(n); + } + return e !== void 0 && (t.x = e), t.i = !0, P = t.p, Zt(e); +} +function Zt(e = {}) { + return rt(e, Dr, { value: !0 }), e; +} +function Hr() { + return !0; +} +let Se = []; +function qr() { + var e = Se; + Se = [], Wn(e); +} +function Te(e) { + if (Se.length === 0 && !et) { + var t = Se; + queueMicrotask(() => { + t === Se && qr(); + }); + } + Se.push(e); +} +function gs() { + for (; Se.length > 0; ) + qr(); +} +const ms = -7169; +function x(e, t) { + e.f = e.f & ms | t; +} +function er(e) { + (e.f & G) !== 0 || e.deps === null ? x(e, C) : x(e, te); +} +function Br(e) { + if (e !== null) + for (const t of e) + (t.f & N) === 0 || (t.f & Ne) === 0 || (t.f ^= Ne, Br( + /** @type {Derived} */ + t.deps + )); +} +function Vr(e, t, r) { + (e.f & S) !== 0 ? t.add(e) : (e.f & te) !== 0 && r.add(e), Br(e.deps), x(e, C); +} +function Rt(e) { + var t = g, r = _; + K(null), ce(null); + try { + return e(); + } finally { + K(t), ce(r); + } +} +function bs(e, t, r, n) { + const s = tr; + var i = e.filter((h) => !h.settled), l = t.map(s); + if (r.length === 0 && i.length === 0) { + n(l); + return; + } + var a = ( + /** @type {Effect} */ + _ + ), o = ks(), f = i.length === 1 ? i[0].promise : i.length > 1 ? Promise.all(i.map((h) => h.promise)) : null; + function c(h) { + if ((a.f & H) === 0) { + o(); + try { + n([...l, ...h]); + } catch (u) { + le(u, a); + } + yt(); + } + } + var v = Yr(); + if (r.length === 0) { + f.then(() => c([])).finally(v); + return; + } + function d() { + Promise.all(r.map((h) => /* @__PURE__ */ ws(h))).then(c).catch((h) => le(h, a)).finally(v); + } + f ? f.then(() => { + o(), d(), yt(); + }) : d(); +} +function ks() { + var e = ( + /** @type {Effect} */ + _ + ), t = g, r = P, n = ( + /** @type {Batch} */ + m + ); + return function(i = !0) { + ce(e), K(t), Ye(r), i && (e.f & H) === 0 && (n?.activate(), n?.apply()); + }; +} +function yt(e = !0) { + ce(null), K(null), Ye(null), e && m?.deactivate(); +} +function Yr() { + var e = ( + /** @type {Effect} */ + _ + ), t = e.b, r = ( + /** @type {Batch} */ + m + ), n = !!t?.is_rendered(); + return t?.update_pending_count(1, r), r.increment(n, e), () => { + t?.update_pending_count(-1, r), r.decrement(n, e); + }; +} +// @__NO_SIDE_EFFECTS__ +function tr(e) { + var t = N | S; + return _ !== null && (_.f |= De), { + ctx: P, + deps: null, + effects: null, + equals: Fr, + f: t, + fn: e, + reactions: null, + rv: 0, + v: ( + /** @type {V} */ + A + ), + wv: 0, + parent: _, + ac: null + }; +} +const Ke = /* @__PURE__ */ Symbol("obsolete"); +// @__NO_SIDE_EFFECTS__ +function ws(e, t, r) { + let n = ( + /** @type {Effect | null} */ + _ + ); + n === null && is(); + var s = ( + /** @type {Promise} */ + /** @type {unknown} */ + void 0 + ), i = Oe( + /** @type {V} */ + A + ), l = !g, a = /* @__PURE__ */ new Set(); + return Ls(() => { + var o = ( + /** @type {Effect} */ + _ + ), f = Mr(); + s = f.promise; + try { + Promise.resolve(e()).then(f.resolve, (h) => { + h !== st && f.reject(h); + }).finally(yt); + } catch (h) { + f.reject(h), yt(); + } + var c = ( + /** @type {Batch} */ + m + ); + if (l) { + if ((o.f & Pe) !== 0) + var v = Yr(); + if ( + // boundary can be null if the async derived is inside an $effect.root not connected to the component render tree + n.b?.is_rendered() + ) + c.async_deriveds.get(o)?.reject(Ke); + else + for (const h of a.values()) + h.reject(Ke); + a.add(f), c.async_deriveds.set(o, f); + } + const d = (h, u = void 0) => { + v?.(), a.delete(f), u !== Ke && (c.activate(), u ? (i.f |= Ee, Ue(i, u)) : ((i.f & Ee) !== 0 && (i.f ^= Ee), Ue(i, h)), c.deactivate()); + }; + f.promise.then(d, (h) => d(null, h || "unknown")); + }), Os(() => { + for (const o of a) + o.reject(Ke); + }), new Promise((o) => { + function f(c) { + function v() { + c === s ? o(i) : f(s); + } + c.then(v, v); + } + f(s); + }); +} +// @__NO_SIDE_EFFECTS__ +function ys(e) { + const t = /* @__PURE__ */ tr(e); + return t.equals = Ir, t; +} +function $s(e) { + var t = e.effects; + if (t !== null) { + e.effects = null; + for (var r = 0; r < t.length; r += 1) + I( + /** @type {Effect} */ + t[r] + ); + } +} +function rr(e) { + var t, r = _, n = e.parent; + if (!me && n !== null && e.v !== A && // if it was never evaluated before, it's guaranteed to fail downstream, so we try to execute instead + (n.f & (H | F)) !== 0) + return ts(), e.v; + ce(n); + try { + e.f &= ~Ne, $s(e), t = _n(e); + } finally { + ce(r); + } + return t; +} +function Ur(e) { + var t = rr(e); + if (!e.equals(t) && (e.wv = hn(), (!m?.is_fork || e.deps === null) && (m !== null ? (m.capture(e, t, !0), Vt?.capture(e, t, !0)) : e.v = t, e.deps === null))) { + x(e, C); + return; + } + me || (Z !== null ? (ar() || m?.is_fork) && Z.set(e, t) : er(e)); +} +function Es(e) { + if (e.effects !== null) + for (const t of e.effects) + (t.teardown || t.ac) && (t.teardown?.(), t.ac !== null && Rt(() => { + t.ac.abort(st), t.ac = null; + }), t.fn !== null && (t.teardown = Gn), nt(t, 0), ur(t)); +} +function Qr(e) { + if (e.effects !== null) + for (const t of e.effects) + t.teardown && t.fn !== null && Qe(t); +} +let Lt = null, Ie = null, m = null, Vt = null, Z = null, Yt = null, et = !1, Ft = !1, je = null, vt = null; +var kr = 0; +let xs = 1; +class ge { + id = xs++; + /** True as soon as `#process` was called */ + #e = !1; + linked = !0; + /** @type {Batch | null} */ + #t = null; + /** @type {Batch | null} */ + #r = null; + /** @type {Map>>} */ + async_deriveds = /* @__PURE__ */ new Map(); + /** + * The current values of any signals that are updated in this batch. + * Tuple format: [value, is_derived] (note: is_derived is false for deriveds, too, if they were overridden via assignment) + * They keys of this map are identical to `this.#previous` + * @type {Map} + */ + current = /* @__PURE__ */ new Map(); + /** + * The values of any signals (sources and deriveds) that are updated in this batch _before_ those updates took place. + * They keys of this map are identical to `this.#current` + * @type {Map} + */ + previous = /* @__PURE__ */ new Map(); + /** + * When the batch is committed (and the DOM is updated), we need to remove old branches + * and append new ones by calling the functions added inside (if/each/key/etc) blocks + * @type {Set<(batch: Batch) => void>} + */ + #o = /* @__PURE__ */ new Set(); + /** + * If a fork is discarded, we need to destroy any effects that are no longer needed + * @type {Set<(batch: Batch) => void>} + */ + #s = /* @__PURE__ */ new Set(); + /** + * The number of async effects that are currently in flight + */ + #l = 0; + /** + * Async effects that are currently in flight, _not_ inside a pending boundary + * @type {Map} + */ + #n = /* @__PURE__ */ new Map(); + /** + * A deferred that resolves when the batch is committed, used with `settled()` + * TODO replace with Promise.withResolvers once supported widely enough + * @type {{ promise: Promise, resolve: (value?: any) => void, reject: (reason: unknown) => void } | null} + */ + #a = null; + /** + * The root effects that need to be flushed + * @type {Effect[]} + */ + #i = []; + /** + * Effects created while this batch was active. + * @type {Effect[]} + */ + #p = []; + /** + * Deferred effects (which run after async work has completed) that are DIRTY + * @type {Set} + */ + #f = /* @__PURE__ */ new Set(); + /** + * Deferred effects that are MAYBE_DIRTY + * @type {Set} + */ + #u = /* @__PURE__ */ new Set(); + /** + * A map of branches that still exist, but will be destroyed when this batch + * is committed — we skip over these during `process`. + * The value contains child effects that were dirty/maybe_dirty before being reset, + * so they can be rescheduled if the branch survives. + * @type {Map} + */ + #v = /* @__PURE__ */ new Map(); + /** + * Inverse of #skipped_branches which we need to tell prior batches to unskip them when committing + * @type {Set} + */ + #_ = /* @__PURE__ */ new Set(); + is_fork = !1; + #c = !1; + constructor() { + Ie === null ? Lt = Ie = this : (Ie.#r = this, this.#t = Ie), Ie = this; + } + #b() { + if (this.is_fork) return !0; + for (const n of this.#n.keys()) { + for (var t = n, r = !1; t.parent !== null; ) { + if (this.#v.has(t)) { + r = !0; + break; + } + t = t.parent; + } + if (!r) + return !0; + } + return !1; + } + /** + * Add an effect to the #skipped_branches map and reset its children + * @param {Effect} effect + */ + skip_effect(t) { + this.#v.has(t) || this.#v.set(t, { d: [], m: [] }), this.#_.delete(t); + } + /** + * Remove an effect from the #skipped_branches map and reschedule + * any tracked dirty/maybe_dirty child effects + * @param {Effect} effect + * @param {(e: Effect) => void} callback + */ + unskip_effect(t, r = (n) => this.schedule(n)) { + var n = this.#v.get(t); + if (n) { + this.#v.delete(t); + for (var s of n.d) + x(s, S), r(s); + for (s of n.m) + x(s, te), r(s); + } + this.#_.add(t); + } + #g() { + this.#e = !0, kr++ > 1e3 && (this.#h(), Ss()); + for (const o of this.#f) + this.#u.delete(o), x(o, S), this.schedule(o); + for (const o of this.#u) + x(o, te), this.schedule(o); + const t = this.#i; + this.#i = [], this.apply(); + var r = je = [], n = [], s = vt = []; + for (const o of t) + try { + this.#k(o, r, n); + } catch (f) { + throw Jr(o), this.#b() || this.discard(), f; + } + if (m = null, s.length > 0) { + var i = ge.ensure(); + for (const o of s) + i.schedule(o); + } + if (je = null, vt = null, this.#b()) { + this.#d(n), this.#d(r); + for (const [o, f] of this.#v) + Kr(o, f); + s.length > 0 && /** @type {unknown} */ + m.#g(); + return; + } + const l = this.#w(); + if (l) { + this.#d(n), this.#d(r), l.#y(this); + return; + } + this.#f.clear(), this.#u.clear(); + for (const o of this.#o) o(this); + this.#o.clear(), Vt = this, wr(n), wr(r), Vt = null, this.#a?.resolve(); + var a = ( + /** @type {Batch | null} */ + /** @type {unknown} */ + m + ); + if (this.#l === 0 && (this.#i.length === 0 || a !== null) && this.#h(), this.#i.length > 0) + if (a !== null) { + const o = a; + o.#i.push(...this.#i.filter((f) => !o.#i.includes(f))); + } else + a = this; + a !== null && (ae.clear(), a.#g()); + } + /** + * Traverse the effect tree, executing effects or stashing + * them for later execution as appropriate + * @param {Effect} root + * @param {Effect[]} effects + * @param {Effect[]} render_effects + */ + #k(t, r, n) { + t.f ^= C; + for (var s = t.first; s !== null; ) { + var i = s.f, l = (i & (W | fe)) !== 0, a = l && (i & C) !== 0, o = a || (i & F) !== 0 || this.#v.has(s); + if (!o && s.fn !== null) { + l ? s.f ^= C : (i & Be) !== 0 ? r.push(s) : lt(s) && ((i & X) !== 0 && this.#u.add(s), Qe(s)); + var f = s.first; + if (f !== null) { + s = f; + continue; + } + } + for (; s !== null; ) { + var c = s.next; + if (c !== null) { + s = c; + break; + } + s = s.parent; + } + } + } + #w() { + for (var t = this.#t; t !== null; ) { + if (!t.is_fork) { + for (const [r, [, n]] of this.current) + if (t.current.has(r) && !n) + return t; + } + t = t.#t; + } + return null; + } + /** + * @param {Batch} batch + */ + #y(t) { + for (const [n, s] of t.current) + !this.previous.has(n) && t.previous.has(n) && this.previous.set(n, t.previous.get(n)), this.current.set(n, s); + for (const [n, s] of t.async_deriveds) { + const i = this.async_deriveds.get(n); + i && s.promise.then(i.resolve).catch(i.reject); + } + t.async_deriveds.clear(), this.transfer_effects(t.#f, t.#u); + const r = (n) => { + var s = n.reactions; + if (s !== null && !((n.f & N) !== 0 && (n.f & (S | te)) === 0)) + for (const a of s) { + var i = a.f; + if ((i & N) !== 0) + r( + /** @type {Derived} */ + a + ); + else { + var l = ( + /** @type {Effect} */ + a + ); + i & (He | X) && !this.async_deriveds.has(l) && (this.#u.delete(l), x(l, S), this.schedule(l)); + } + } + }; + for (const n of this.current.keys()) + r(n); + this.oncommit(() => t.discard()), t.#h(), m = this, this.#g(); + } + /** + * @param {Effect[]} effects + */ + #d(t) { + for (var r = 0; r < t.length; r += 1) + Vr(t[r], this.#f, this.#u); + } + /** + * Associate a change to a given source with the current + * batch, noting its previous and current values + * @param {Value} source + * @param {any} value + * @param {boolean} [is_derived] + */ + capture(t, r, n = !1) { + t.v !== A && !this.previous.has(t) && this.previous.set(t, t.v), (t.f & Ee) === 0 && (this.current.set(t, [r, n]), Z?.set(t, r)), this.is_fork || (t.v = r); + } + activate() { + m = this; + } + deactivate() { + m = null, Z = null; + } + flush() { + try { + Ft = !0, m = this, this.#g(); + } finally { + kr = 0, Yt = null, je = null, vt = null, Ft = !1, m = null, Z = null, ae.clear(); + } + } + discard() { + for (const t of this.#s) t(this); + this.#s.clear(); + for (const t of this.async_deriveds.values()) + t.reject(Ke); + this.#h(), this.#a?.resolve(); + } + /** + * @param {Effect} effect + */ + register_created_effect(t) { + this.#p.push(t); + } + #m() { + for (let v = Lt; v !== null; v = v.#r) { + var t = v.id < this.id, r = []; + for (const [d, [h, u]] of this.current) { + if (v.current.has(d)) { + var n = ( + /** @type {[any, boolean]} */ + v.current.get(d)[0] + ); + if (t && h !== n) + v.current.set(d, [h, u]); + else + continue; + } + r.push(d); + } + if (t) + for (const [d, h] of this.async_deriveds) { + const u = v.async_deriveds.get(d); + u && h.promise.then(u.resolve).catch(u.reject); + } + var s = [...v.current.keys()].filter( + (d) => !/** @type {[any, boolean]} */ + v.current.get(d)[1] + ); + if (!(!v.#e || s.length === 0)) { + var i = s.filter((d) => !this.current.has(d)); + if (i.length === 0) + t && v.discard(); + else if (r.length > 0) { + if (t) + for (const d of this.#_) + v.unskip_effect(d, (h) => { + (h.f & (X | He)) !== 0 ? v.schedule(h) : v.#d([h]); + }); + v.activate(); + var l = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Map(); + for (var o of r) + Wr(o, i, l, a); + a = /* @__PURE__ */ new Map(); + var f = [...v.current].filter(([d, h]) => { + const u = this.current.get(d); + return u ? u[0] !== h[0] || u[1] !== h[1] : !0; + }).map(([d]) => d); + if (f.length > 0) + for (const d of this.#p) + (d.f & (H | F | bt)) === 0 && nr(d, f, a) && ((d.f & (He | X)) !== 0 ? (x(d, S), v.schedule(d)) : v.#f.add(d)); + if (v.#i.length > 0 && !v.#c) { + v.apply(); + for (var c of v.#i) + v.#k(c, [], []); + v.#i = []; + } + v.deactivate(); + } + } + } + } + /** + * @param {boolean} blocking + * @param {Effect} effect + */ + increment(t, r) { + if (this.#l += 1, t) { + let n = this.#n.get(r) ?? 0; + this.#n.set(r, n + 1); + } + } + /** + * @param {boolean} blocking + * @param {Effect} effect + */ + decrement(t, r) { + if (this.#l -= 1, t) { + let n = this.#n.get(r) ?? 0; + n === 1 ? this.#n.delete(r) : this.#n.set(r, n - 1); + } + this.#c || (this.#c = !0, Te(() => { + this.#c = !1, this.linked && this.flush(); + })); + } + /** + * @param {Set} dirty_effects + * @param {Set} maybe_dirty_effects + */ + transfer_effects(t, r) { + for (const n of t) + this.#f.add(n); + for (const n of r) + this.#u.add(n); + t.clear(), r.clear(); + } + /** @param {(batch: Batch) => void} fn */ + oncommit(t) { + this.#o.add(t); + } + /** @param {(batch: Batch) => void} fn */ + ondiscard(t) { + this.#s.add(t); + } + settled() { + return (this.#a ??= Mr()).promise; + } + static ensure() { + if (m === null) { + const t = m = new ge(); + !Ft && !et && Te(() => { + t.#e || t.flush(); + }); + } + return m; + } + apply() { + { + Z = null; + return; + } + } + /** + * + * @param {Effect} effect + */ + schedule(t) { + if (Yt = t, t.b?.is_pending && (t.f & (Be | St | Pr)) !== 0 && (t.f & Pe) === 0) { + t.b.defer_effect(t); + return; + } + for (var r = t; r.parent !== null; ) { + r = r.parent; + var n = r.f; + if (je !== null && r === _ && (g === null || (g.f & N) === 0)) + return; + if ((n & (fe | W)) !== 0) { + if ((n & C) === 0) + return; + r.f ^= C; + } + } + this.#i.push(r); + } + #h() { + if (this.linked) { + var t = this.#t, r = this.#r; + t === null ? Lt = r : t.#r = r, r === null ? Ie = t : r.#t = t, this.linked = !1; + } + } +} +function Gr(e) { + var t = et; + et = !0; + try { + for (var r; ; ) { + if (gs(), m === null) + return ( + /** @type {T} */ + r + ); + m.flush(); + } + } finally { + et = t; + } +} +function Ss() { + try { + us(); + } catch (e) { + le(e, Yt); + } +} +let he = null; +function wr(e) { + var t = e.length; + if (t !== 0) { + for (var r = 0; r < t; ) { + var n = e[r++]; + if ((n.f & (H | F)) === 0 && lt(n) && (he = /* @__PURE__ */ new Set(), Qe(n), n.deps === null && n.first === null && n.nodes === null && n.teardown === null && n.ac === null && un(n), he?.size > 0)) { + ae.clear(); + for (const s of he) { + if ((s.f & (H | F)) !== 0) continue; + const i = [s]; + let l = s.parent; + for (; l !== null; ) + he.has(l) && (he.delete(l), i.push(l)), l = l.parent; + for (let a = i.length - 1; a >= 0; a--) { + const o = i[a]; + (o.f & (H | F)) === 0 && Qe(o); + } + } + he.clear(); + } + } + he = null; + } +} +function Wr(e, t, r, n) { + if (!r.has(e) && (r.add(e), e.reactions !== null)) + for (const s of e.reactions) { + const i = s.f; + (i & N) !== 0 ? Wr( + /** @type {Derived} */ + s, + t, + r, + n + ) : (i & (He | X)) !== 0 && (i & S) === 0 && nr(s, t, n) && (x(s, S), sr( + /** @type {Effect} */ + s + )); + } +} +function nr(e, t, r) { + const n = r.get(e); + if (n !== void 0) return n; + if (e.deps !== null) + for (const s of e.deps) { + if (_t.call(t, s)) + return !0; + if ((s.f & N) !== 0 && nr( + /** @type {Derived} */ + s, + t, + r + )) + return r.set( + /** @type {Derived} */ + s, + !0 + ), !0; + } + return r.set(e, !1), !1; +} +function sr(e) { + m.schedule(e); +} +function Kr(e, t) { + if (!((e.f & W) !== 0 && (e.f & C) !== 0)) { + (e.f & S) !== 0 ? t.d.push(e) : (e.f & te) !== 0 && t.m.push(e), x(e, C); + for (var r = e.first; r !== null; ) + Kr(r, t), r = r.next; + } +} +function Jr(e) { + x(e, C); + for (var t = e.first; t !== null; ) + Jr(t), t = t.next; +} +let $t = /* @__PURE__ */ new Set(); +const ae = /* @__PURE__ */ new Map(); +let Xr = !1; +function Oe(e, t) { + var r = { + f: 0, + // TODO ideally we could skip this altogether, but it causes type errors + v: e, + reactions: null, + equals: Fr, + rv: 0, + wv: 0 + }; + return r; +} +// @__NO_SIDE_EFFECTS__ +function J(e, t) { + const r = Oe(e); + return js(r), r; +} +// @__NO_SIDE_EFFECTS__ +function Zr(e, t = !1, r = !0) { + const n = Oe(e); + return t || (n.equals = Ir), n; +} +function j(e, t, r = !1) { + g !== null && // since we are untracking the function inside `$inspect.with` we need to add this check + // to ensure we error if state is set inside an inspect effect + (!ee || (g.f & bt) !== 0) && Hr() && (g.f & (N | X | He | bt)) !== 0 && (oe === null || !oe.has(e)) && hs(); + let n = r ? Je(t) : t; + return Ue(e, n, vt); +} +function Ue(e, t, r = null) { + if (!e.equals(t)) { + me ? ae.set(e, t) : ae.has(e) || ae.set(e, e.v); + var n = ge.ensure(); + if (n.capture(e, t), (e.f & N) !== 0) { + const s = ( + /** @type {Derived} */ + e + ); + (e.f & S) !== 0 && rr(s), Z === null && er(s); + } + e.wv = hn(), en(e, S, r), _ !== null && (_.f & C) !== 0 && (_.f & (W | fe)) === 0 && (U === null ? zs([e]) : U.push(e)), !n.is_fork && $t.size > 0 && !Xr && Ts(); + } + return t; +} +function Ts() { + Xr = !1; + for (const e of $t) { + (e.f & C) !== 0 && x(e, te); + let t; + try { + t = lt(e); + } catch { + t = !0; + } + t && Qe(e); + } + $t.clear(); +} +function tt(e) { + j(e, e.v + 1); +} +function en(e, t, r) { + var n = e.reactions; + if (n !== null) + for (var s = n.length, i = 0; i < s; i++) { + var l = n[i], a = l.f, o = (a & S) === 0; + if (o && x(l, t), (a & bt) !== 0) + $t.add( + /** @type {Effect} */ + l + ); + else if ((a & N) !== 0) { + var f = ( + /** @type {Derived} */ + l + ); + Z?.delete(f), (a & Ne) === 0 && (a & G && (_ === null || (_.f & kt) === 0) && (l.f |= Ne), en(f, te, r)); + } else if (o) { + var c = ( + /** @type {Effect} */ + l + ); + (a & X) !== 0 && he !== null && he.add(c), r !== null ? r.push(c) : sr(c); + } + } +} +function Je(e) { + if (typeof e != "object" || e === null || ct in e || Dr in e) + return e; + const t = Qn(e); + if (t !== Yn && t !== Un) + return e; + var r = /* @__PURE__ */ new Map(), n = Or(e), s = /* @__PURE__ */ J(0), i = Re, l = (a) => { + if (Re === i) + return a(); + var o = g, f = Re; + K(null), Er(i); + var c = a(); + return K(o), Er(f), c; + }; + return n && r.set("length", /* @__PURE__ */ J( + /** @type {any[]} */ + e.length + )), new Proxy( + /** @type {any} */ + e, + { + defineProperty(a, o, f) { + (!("value" in f) || f.configurable === !1 || f.enumerable === !1 || f.writable === !1) && vs(); + var c = r.get(o); + return c === void 0 ? l(() => { + var v = /* @__PURE__ */ J(f.value); + return r.set(o, v), v; + }) : j(c, f.value, !0), !0; + }, + deleteProperty(a, o) { + var f = r.get(o); + if (f === void 0) { + if (o in a) { + const c = l(() => /* @__PURE__ */ J(A)); + r.set(o, c), tt(s); + } + } else + j(f, A), tt(s); + return !0; + }, + get(a, o, f) { + if (o === ct) + return e; + var c = r.get(o), v = o in a; + if (c === void 0 && (!v || ze(a, o)?.writable) && (c = l(() => { + var h = Je(v ? a[o] : A), u = /* @__PURE__ */ J(h); + return u; + }), r.set(o, c)), c !== void 0) { + var d = y(c); + return d === A ? void 0 : d; + } + return Reflect.get(a, o, f); + }, + getOwnPropertyDescriptor(a, o) { + var f = Reflect.getOwnPropertyDescriptor(a, o); + if (f && "value" in f) { + var c = r.get(o); + c && (f.value = y(c)); + } else if (f === void 0) { + var v = r.get(o), d = v?.v; + if (v !== void 0 && d !== A) + return { + enumerable: !0, + configurable: !0, + value: d, + writable: !0 + }; + } + return f; + }, + has(a, o) { + if (o === ct) + return !0; + var f = r.get(o), c = f !== void 0 && f.v !== A || Reflect.has(a, o); + if (f !== void 0 || _ !== null && (!c || ze(a, o)?.writable)) { + f === void 0 && (f = l(() => { + var d = c ? Je(a[o]) : A, h = /* @__PURE__ */ J(d); + return h; + }), r.set(o, f)); + var v = y(f); + if (v === A) + return !1; + } + return c; + }, + set(a, o, f, c) { + var v = r.get(o), d = o in a; + if (n && o === "length") + for (var h = f; h < /** @type {Source} */ + v.v; h += 1) { + var u = r.get(h + ""); + u !== void 0 ? j(u, A) : h in a && (u = l(() => /* @__PURE__ */ J(A)), r.set(h + "", u)); + } + if (v === void 0) + (!d || ze(a, o)?.writable) && (v = l(() => /* @__PURE__ */ J(void 0)), j(v, Je(f)), r.set(o, v)); + else { + d = v.v !== A; + var w = l(() => Je(f)); + j(v, w); + } + var T = Reflect.getOwnPropertyDescriptor(a, o); + if (T?.set && T.set.call(c, f), !d) { + if (n && typeof o == "string") { + var b = ( + /** @type {Source} */ + r.get("length") + ), E = Number(o); + Number.isInteger(E) && E >= b.v && j(b, E + 1); + } + tt(s); + } + return !0; + }, + ownKeys(a) { + y(s); + var o = Reflect.ownKeys(a).filter((v) => { + var d = r.get(v); + return d === void 0 || d.v !== A; + }); + for (var [f, c] of r) + c.v !== A && !(f in a) && o.push(f); + return o; + }, + setPrototypeOf() { + ds(); + } + } + ); +} +var yr, tn, rn, nn; +function Ut() { + if (yr === void 0) { + yr = window, tn = /Firefox/.test(navigator.userAgent); + var e = Element.prototype, t = Node.prototype, r = Text.prototype; + rn = ze(t, "firstChild").get, nn = ze(t, "nextSibling").get, br(e) && (e[qt] = void 0, e[Zn] = null, e[es] = void 0, e.__e = void 0), br(r) && (r[Bt] = void 0); + } +} +function ue(e = "") { + return document.createTextNode(e); +} +// @__NO_SIDE_EFFECTS__ +function Me(e) { + return ( + /** @type {TemplateNode | null} */ + rn.call(e) + ); +} +// @__NO_SIDE_EFFECTS__ +function ve(e) { + return ( + /** @type {TemplateNode | null} */ + nn.call(e) + ); +} +function L(e, t) { + if (!$) + return /* @__PURE__ */ Me(e); + var r = /* @__PURE__ */ Me(k); + if (r === null) + r = k.appendChild(ue()); + else if (t && r.nodeType !== Tt) { + var n = ue(); + return r?.before(n), V(n), n; + } + return t && lr( + /** @type {Text} */ + r + ), V(r), r; +} +function As(e, t = !1) { + if (!$) { + var r = /* @__PURE__ */ Me(e); + return r instanceof Comment && r.data === "" ? /* @__PURE__ */ ve(r) : r; + } + if (t) { + if (k?.nodeType !== Tt) { + var n = ue(); + return k?.before(n), V(n), n; + } + lr( + /** @type {Text} */ + k + ); + } + return k; +} +function we(e, t = !1) { + if (!$) + return /* @__PURE__ */ Me(e); + var r = L(e, t); + return D(e), r; +} +function R(e, t = 1, r = !1) { + let n = $ ? k : e; + for (var s; t--; ) + s = n, n = /** @type {TemplateNode} */ + /* @__PURE__ */ ve(n); + if (!$) + return n; + if (r) { + if (n?.nodeType !== Tt) { + var i = ue(); + return n === null ? s?.after(i) : n.before(i), V(i), i; + } + lr( + /** @type {Text} */ + n + ); + } + return V(n), n; +} +function sn(e) { + e.textContent = ""; +} +function ln() { + return !1; +} +function ir(e, t, r) { + return ( + /** @type {T extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[T] : Element} */ + document.createElement(e) + ); +} +function lr(e) { + if ( + /** @type {string} */ + e.nodeValue.length < 65536 + ) + return; + let t = e.nextSibling; + for (; t !== null && t.nodeType === Tt; ) + t.remove(), e.nodeValue += /** @type {string} */ + t.nodeValue, t = e.nextSibling; +} +function Cs(e) { + var t = _; + if (t === null) + return g.f |= Ee, e; + if ((t.f & Pe) === 0 && (t.f & Be) === 0) + throw e; + le(e, t); +} +function le(e, t) { + if (!(t !== null && (t.f & H) !== 0)) { + for (; t !== null; ) { + if ((t.f & Ht) !== 0 && (t.f & (H | mt)) === 0) { + if ((t.f & Pe) === 0) + throw e; + try { + t.b.error(e); + return; + } catch (r) { + e = r; + } + } + t = t.parent; + } + throw e; + } +} +function Rs(e) { + _ === null && (g === null && fs(), os()), me && as(); +} +function Ns(e, t) { + var r = t.last; + r === null ? t.last = t.first = e : (r.next = e, e.prev = r, t.last = e); +} +function de(e, t) { + var r = _; + r !== null && (r.f & F) !== 0 && (e |= F); + var n = { + ctx: P, + deps: null, + nodes: null, + f: e | S | G, + first: null, + fn: t, + last: null, + next: null, + parent: r, + b: r && r.b, + prev: null, + teardown: null, + wv: 0, + ac: null + }; + m?.register_created_effect(n); + var s = n; + if ((e & Be) !== 0) + je !== null ? je.push(n) : ge.ensure().schedule(n); + else if (t !== null) { + try { + Qe(n); + } catch (l) { + throw I(n), l; + } + s.deps === null && s.teardown === null && s.nodes === null && s.first === s.last && // either `null`, or a singular child + (s.f & De) === 0 && (s = s.first, (e & X) !== 0 && (e & Ve) !== 0 && s !== null && (s.f |= Ve)); + } + if (s !== null && (s.parent = r, r !== null && Ns(s, r), g !== null && (g.f & N) !== 0 && (e & fe) === 0)) { + var i = ( + /** @type {Derived} */ + g + ); + (i.effects ??= []).push(s); + } + return n; +} +function ar() { + return g !== null && !ee; +} +function Os(e) { + const t = de(St, null); + return x(t, C), t.teardown = e, t; +} +function Ms(e) { + Rs(); + var t = ( + /** @type {Effect} */ + _.f + ), r = !g && (t & W) !== 0 && P !== null && !P.i; + if (r) { + var n = ( + /** @type {ComponentContext} */ + P + ); + (n.e ??= []).push(e); + } else + return an(e); +} +function an(e) { + return de(Be | Jn, e); +} +function Ps(e) { + ge.ensure(); + const t = de(fe | De, e); + return () => { + I(t); + }; +} +function Ds(e) { + ge.ensure(); + const t = de(fe | De, e); + return (r = {}) => new Promise((n) => { + r.outro ? Ce(t, () => { + I(t), n(void 0); + }) : (I(t), n(void 0)); + }); +} +function on(e) { + return de(Be, e); +} +function Ls(e) { + return de(He | De, e); +} +function or(e, t = 0) { + return de(St | t, e); +} +function at(e, t = [], r = [], n = []) { + bs(n, t, r, (s) => { + de(St, () => { + e(...s.map(y)); + }); + }); +} +function fr(e, t = 0) { + var r = de(X | t, e); + return r; +} +function Q(e) { + return de(W | De, e); +} +function fn(e) { + var t = e.teardown; + if (t !== null) { + const r = me, n = g; + $r(!0), K(null); + try { + t.call(null); + } catch (s) { + le(s, e.parent); + } finally { + $r(r), K(n); + } + } +} +function ur(e, t = !1) { + var r = e.first; + for (e.first = e.last = null; r !== null; ) { + const s = r.ac; + s !== null && Rt(() => { + s.abort(st); + }); + var n = r.next; + (r.f & fe) !== 0 ? r.parent = null : I(r, t), r = n; + } +} +function Fs(e) { + for (var t = e.first; t !== null; ) { + var r = t.next; + (t.f & W) === 0 && I(t), t = r; + } +} +function I(e, t = !0) { + var r = !1; + (t || (e.f & Kn) !== 0) && e.nodes !== null && e.nodes.end !== null && (Is( + e.nodes.start, + /** @type {TemplateNode} */ + e.nodes.end + ), r = !0), e.f |= mt, ur(e, t && !r), nt(e, 0); + var n = e.nodes && e.nodes.t; + if (n !== null) + for (const i of n) + i.stop(); + fn(e), e.f ^= mt, e.f |= H; + var s = e.parent; + s !== null && s.first !== null && un(e), e.next = e.prev = e.teardown = e.ctx = e.deps = e.fn = e.nodes = e.ac = e.b = null; +} +function Is(e, t) { + for (; e !== null; ) { + var r = e === t ? null : /* @__PURE__ */ ve(e); + e.remove(), e = r; + } +} +function un(e) { + var t = e.parent, r = e.prev, n = e.next; + r !== null && (r.next = n), n !== null && (n.prev = r), t !== null && (t.first === e && (t.first = n), t.last === e && (t.last = r)); +} +function Ce(e, t, r = !0) { + var n = []; + e.f |= Xt, cn(e, n, !0); + var s = () => { + r && I(e), t && t(); + }, i = n.length; + if (i > 0) { + var l = () => --i || s(); + for (var a of n) + a.out(l); + } else + s(); +} +function cn(e, t, r) { + if ((e.f & F) === 0) { + e.f ^= F; + var n = e.nodes && e.nodes.t; + if (n !== null) + for (const a of n) + (a.is_global || r) && t.push(a); + for (var s = e.first; s !== null; ) { + var i = s.next; + if ((s.f & fe) === 0) { + var l = (s.f & Ve) !== 0 || // If this is a branch effect without a block effect parent, + // it means the parent block effect was pruned. In that case, + // transparency information was transferred to the branch effect. + (s.f & W) !== 0 && (e.f & X) !== 0; + cn(s, t, l ? r : !1); + } + s = i; + } + } +} +function Et(e) { + e.f &= ~Xt, vn(e, !0); +} +function vn(e, t) { + if ((e.f & Xt) === 0 && (e.f & F) !== 0) { + e.f ^= F, (e.f & C) === 0 && (x(e, S), ge.ensure().schedule(e)); + for (var r = e.first; r !== null; ) { + var n = r.next, s = (r.f & Ve) !== 0 || (r.f & W) !== 0; + vn(r, s ? t : !1), r = n; + } + var i = e.nodes && e.nodes.t; + if (i !== null) + for (const l of i) + (l.is_global || t) && l.in(); + } +} +function cr(e, t) { + if (e.nodes) + for (var r = e.nodes.start, n = e.nodes.end; r !== null; ) { + var s = r === n ? null : /* @__PURE__ */ ve(r); + t.append(r), r = s; + } +} +let dt = !1, me = !1; +function $r(e) { + me = e; +} +let g = null, ee = !1; +function K(e) { + g = e; +} +let _ = null; +function ce(e) { + _ = e; +} +let oe = null; +function js(e) { + g !== null && (oe ??= /* @__PURE__ */ new Set()).add(e); +} +let z = null, B = 0, U = null; +function zs(e) { + U = e; +} +let dn = 1, Ae = 0, Re = Ae; +function Er(e) { + Re = e; +} +function hn() { + return ++dn; +} +function lt(e) { + var t = e.f; + if ((t & S) !== 0) + return !0; + if (t & N && (e.f &= ~Ne), (t & te) !== 0) { + for (var r = ( + /** @type {Value[]} */ + e.deps + ), n = r.length, s = 0; s < n; s++) { + var i = r[s]; + if (lt( + /** @type {Derived} */ + i + ) && Ur( + /** @type {Derived} */ + i + ), i.wv > e.wv) + return !0; + } + (t & G) !== 0 && // During time traveling we don't want to reset the status so that + // traversal of the graph in the other batches still happens + Z === null && x(e, C); + } + return !1; +} +function pn(e, t, r = !0) { + var n = e.reactions; + if (n !== null && !(oe !== null && oe.has(e))) + for (var s = 0; s < n.length; s++) { + var i = n[s]; + (i.f & N) !== 0 ? pn( + /** @type {Derived} */ + i, + t, + !1 + ) : t === i && (r ? x(i, S) : (i.f & C) !== 0 && x(i, te), sr( + /** @type {Effect} */ + i + )); + } +} +function _n(e) { + var t = z, r = B, n = U, s = g, i = oe, l = P, a = ee, o = Re, f = e.f; + z = /** @type {null | Value[]} */ + null, B = 0, U = null, g = (f & (W | fe)) === 0 ? e : null, oe = null, Ye(e.ctx), ee = !1, Re = ++Ae, e.ac !== null && (Rt(() => { + e.ac.abort(st); + }), e.ac = null); + try { + e.f |= kt; + var c = ( + /** @type {Function} */ + e.fn + ), v = c(); + e.f |= Pe; + var d = xr(e); + if (Hr() && U !== null && !ee && d !== null && (e.f & (N | te | S)) === 0) + for (var h = 0; h < /** @type {Source[]} */ + U.length; h++) + pn( + U[h], + /** @type {Effect} */ + e + ); + if (s !== null && s !== e) { + if (Ae++, s.deps !== null) + for (let u = 0; u < r; u += 1) + s.deps[u].rv = Ae; + if (t !== null) + for (const u of t) + u.rv = Ae; + U !== null && (n === null ? n = U : n.push(.../** @type {Source[]} */ + U)); + } + return (e.f & Ee) !== 0 && (e.f ^= Ee), v; + } catch (u) { + return xr(e), Cs(u); + } finally { + e.f ^= kt, z = t, B = r, U = n, g = s, oe = i, Ye(l), ee = a, Re = o; + } +} +function xr(e) { + var t = e.deps, r = m?.is_fork; + if (z !== null) { + var n; + if (r || nt(e, B), t !== null && B > 0) + for (t.length = B + z.length, n = 0; n < z.length; n++) + t[B + n] = z[n]; + else + e.deps = t = z; + if (ar() && (e.f & G) !== 0) + for (n = B; n < t.length; n++) + (t[n].reactions ??= []).push(e); + } else !r && t !== null && B < t.length && (nt(e, B), t.length = B); + return t; +} +function Hs(e, t) { + let r = t.reactions; + if (r !== null) { + var n = Vn.call(r, e); + if (n !== -1) { + var s = r.length - 1; + s === 0 ? r = t.reactions = null : (r[n] = r[s], r.pop()); + } + } + if (r === null && (t.f & N) !== 0 && // Destroying a child effect while updating a parent effect can cause a dependency to appear + // to be unused, when in fact it is used by the currently-updating parent. Checking `new_deps` + // allows us to skip the expensive work of disconnecting and immediately reconnecting it + (z === null || !_t.call(z, t))) { + var i = ( + /** @type {Derived} */ + t + ); + (i.f & G) !== 0 && (i.f ^= G, i.f &= ~Ne), i.v !== A && er(i), i.ac !== null && Rt(() => { + i.ac.abort(st), i.ac = null, x(i, S); + }), Es(i), nt(i, 0); + } +} +function nt(e, t) { + var r = e.deps; + if (r !== null) + for (var n = t; n < r.length; n++) + Hs(e, r[n]); +} +function Qe(e) { + var t = e.f; + if ((t & H) === 0) { + x(e, C); + var r = _, n = dt; + _ = e, dt = (t & (W | fe)) === 0; + try { + (t & (X | Pr)) !== 0 ? Fs(e) : ur(e), fn(e); + var s = _n(e); + e.teardown = typeof s == "function" ? s : null, e.wv = dn; + var i; + Nr && _s && (e.f & S) !== 0 && e.deps; + } finally { + dt = n, _ = r; + } + } +} +function y(e) { + var t = e.f, r = (t & N) !== 0; + if (g !== null && !ee) { + var n = _ !== null && (_.f & H) !== 0; + if (!n && (oe === null || !oe.has(e))) { + var s = g.deps; + if ((g.f & kt) !== 0) + e.rv < Ae && (e.rv = Ae, z === null && s !== null && s[B] === e ? B++ : z === null ? z = [e] : z.push(e)); + else { + g.deps ??= [], _t.call(g.deps, e) || g.deps.push(e); + var i = e.reactions; + i === null ? e.reactions = [g] : _t.call(i, g) || i.push(g); + } + } + } + if (me && ae.has(e)) + return ae.get(e); + if (r) { + var l = ( + /** @type {Derived} */ + e + ); + if (me) { + var a = l.v; + return ((l.f & C) === 0 && l.reactions !== null || mn(l)) && (a = rr(l)), ae.set(l, a), a; + } + var o = (l.f & G) === 0 && !ee && g !== null && (dt || (g.f & G) !== 0), f = (l.f & Pe) === 0; + lt(l) && (o && (l.f |= G), Ur(l)), o && !f && (Qr(l), gn(l)); + } + if (Z?.has(e)) + return Z.get(e); + if ((e.f & Ee) !== 0) + throw e.v; + return e.v; +} +function gn(e) { + if (e.f |= G, e.deps !== null) + for (const t of e.deps) + (t.reactions ??= []).push(e), (t.f & N) !== 0 && (t.f & G) === 0 && (Qr( + /** @type {Derived} */ + t + ), gn( + /** @type {Derived} */ + t + )); +} +function mn(e) { + if (e.v === A) return !0; + if (e.deps === null) return !1; + for (const t of e.deps) + if (ae.has(t) || (t.f & N) !== 0 && mn( + /** @type {Derived} */ + t + )) + return !0; + return !1; +} +function vr(e) { + var t = ee; + try { + return ee = !0, e(); + } finally { + ee = t; + } +} +const Xe = /* @__PURE__ */ Symbol("events"), bn = /* @__PURE__ */ new Set(), Qt = /* @__PURE__ */ new Set(); +function ot(e, t, r) { + (t[Xe] ??= {})[e] = r; +} +function qs(e) { + for (var t = 0; t < e.length; t++) + bn.add(e[t]); + for (var r of Qt) + r(e); +} +let It = null, jt = !1; +function Sr(e) { + var t = this, r = ( + /** @type {Node} */ + t.ownerDocument + ), n = e.type, s = e.composedPath?.() || [], i = ( + /** @type {null | Element} */ + s[0] || e.target + ); + It = e, jt || (jt = !0, setTimeout(() => { + jt = !1, It = null; + })); + var l = 0, a = It === e && e[Xe]; + if (a) { + var o = s.indexOf(a); + if (o !== -1 && (t === document || t === /** @type {any} */ + window)) { + e[Xe] = t; + return; + } + var f = s.indexOf(t); + if (f === -1) + return; + o <= f && (l = o); + } + if (i = /** @type {Element} */ + s[l] || e.target, i !== t) { + rt(e, "currentTarget", { + configurable: !0, + get() { + return i || r; + } + }); + var c = g, v = _; + K(null), ce(null); + try { + for (var d, h = []; i !== null && i !== t; ) { + try { + var u = i[Xe]?.[n]; + u != null && (!/** @type {any} */ + i.disabled || // DOM could've been updated already by the time this is reached, so we check this as well + // -> the target could not have been disabled because it emits the event in the first place + e.target === i) && u.call(i, e); + } catch (w) { + d ? h.push(w) : d = w; + } + if (e.cancelBubble) break; + l++, i = l < s.length ? ( + /** @type {Element} */ + s[l] + ) : null; + } + if (d) { + for (let w of h) + queueMicrotask(() => { + throw w; + }); + throw d; + } + } finally { + e[Xe] = t, delete e.currentTarget, K(c), ce(v); + } + } +} +const Bs = ( + // We gotta write it like this because after downleveling the pure comment may end up in the wrong location + globalThis?.window?.trustedTypes && /* @__PURE__ */ globalThis.window.trustedTypes.createPolicy("svelte-trusted-html", { + /** @param {string} html */ + createHTML: (e) => e + }) +); +function Vs(e) { + return ( + /** @type {string} */ + Bs?.createHTML(e) ?? e + ); +} +function Ys(e) { + var t = ir("template"); + return t.innerHTML = Vs(e.replaceAll("", "")), t.content; +} +function ht(e, t) { + var r = ( + /** @type {Effect} */ + _ + ); + r.nodes === null && (r.nodes = { start: e, end: t, a: null, t: null }); +} +// @__NO_SIDE_EFFECTS__ +function be(e, t) { + var r = (t & qn) !== 0, n = (t & Bn) !== 0, s, i = !e.startsWith(""); + return () => { + if ($) + return ht(k, null), k; + s === void 0 && (s = Ys(i ? e : "" + e), r || (s = /** @type {TemplateNode} */ + /* @__PURE__ */ Me(s))); + var l = ( + /** @type {TemplateNode} */ + n || tn ? document.importNode(s, !0) : s.cloneNode(!0) + ); + if (r) { + var a = ( + /** @type {TemplateNode} */ + /* @__PURE__ */ Me(l) + ), o = ( + /** @type {TemplateNode} */ + l.lastChild + ); + ht(a, o); + } else + ht(l, l); + return l; + }; +} +function ie(e, t) { + if ($) { + var r = ( + /** @type {Effect & { nodes: EffectNodes }} */ + _ + ); + ((r.f & Pe) === 0 || r.nodes.end === null) && (r.nodes.end = k), Ct(); + return; + } + e !== null && e.before( + /** @type {Node} */ + t + ); +} +const Us = ["touchstart", "touchmove"]; +function Qs(e) { + return Us.includes(e); +} +function Gs(e) { + let t = 0, r = Oe(0), n; + return () => { + ar() && (y(r), or(() => (t === 0 && (n = vr(() => e(() => tt(r)))), t += 1, () => { + Te(() => { + t -= 1, t === 0 && (n?.(), n = void 0, tt(r)); + }); + }))); + }; +} +var Ws = Ve | De; +function Ks(e, t, r, n) { + new Js(e, t, r, n); +} +class Js { + /** @type {Boundary | null} */ + parent; + is_pending = !1; + /** + * API-level transformError transform function. Transforms errors before they reach the `failed` snippet. + * Inherited from parent boundary, or defaults to identity. + * @type {(error: unknown) => unknown} + */ + transform_error; + /** @type {TemplateNode} */ + #e; + /** @type {TemplateNode | null} */ + #t = $ ? k : null; + /** @type {BoundaryProps} */ + #r; + /** @type {((anchor: Node) => void)} */ + #o; + /** @type {Effect} */ + #s; + /** @type {Effect | null} */ + #l = null; + /** @type {Effect | null} */ + #n = null; + /** @type {Effect | null} */ + #a = null; + /** @type {DocumentFragment | null} */ + #i = null; + #p = 0; + #f = 0; + #u = !1; + /** @type {Set} */ + #v = /* @__PURE__ */ new Set(); + /** @type {Set} */ + #_ = /* @__PURE__ */ new Set(); + /** + * A source containing the number of pending async deriveds/expressions. + * Only created if `$effect.pending()` is used inside the boundary, + * otherwise updating the source results in needless `Batch.ensure()` + * calls followed by no-op flushes + * @type {Source | null} + */ + #c = null; + #b = Gs(() => (this.#c = Oe(this.#p), () => { + this.#c = null; + })); + /** + * @param {TemplateNode} node + * @param {BoundaryProps} props + * @param {((anchor: Node) => void)} children + * @param {((error: unknown) => unknown) | undefined} [transform_error] + */ + constructor(t, r, n, s) { + this.#e = t, this.#r = r, this.#o = (i) => { + var l = ( + /** @type {Effect} */ + _ + ); + l.b = this, l.f |= Ht, n(i); + }, this.parent = /** @type {Effect} */ + _.b, this.transform_error = s ?? this.parent?.transform_error ?? ((i) => i), this.#s = fr(() => { + if ($) { + const i = ( + /** @type {Comment} */ + this.#t + ); + Ct(); + const l = i.data === Kt; + if (i.data.startsWith(mr)) { + const o = JSON.parse(i.data.slice(mr.length)); + this.#k(o); + } else l ? this.#y() : this.#g(); + } else + this.#d(); + }, Ws), $ && (this.#e = k); + } + #g() { + try { + this.#l = Q(() => this.#o(this.#e)); + } catch (t) { + this.error(t); + } + } + /** + * @param {unknown} error The deserialized error from the server's hydration comment + */ + #k(t) { + const r = this.#r.failed, { reset: n, invoke_onerror: s } = this.#w(t); + Te(s), r && (this.#a = Q(() => { + r( + this.#e, + () => t, + () => n + ); + })); + } + /** + * Creates the `reset` function for a failed boundary, along with a function + * that invokes `onerror` with it (if provided) + * @param {unknown} error + * @returns {{ reset: () => void, invoke_onerror: () => void }} + */ + #w(t) { + var r = !1, n = !1; + const s = () => { + if (r) { + rs(); + return; + } + r = !0, n && ps(), this.#a !== null && Ce(this.#a, () => { + this.#a = null; + }), this.#h(() => { + this.#d(); + }); + }; + return { reset: s, invoke_onerror: () => { + try { + n = !0, this.#r.onerror?.(t, s), n = !1; + } catch (l) { + le(l, this.#s && this.#s.parent); + } + } }; + } + #y() { + const t = this.#r.pending; + t && (this.is_pending = !0, this.#n = Q(() => t(this.#e)), Te(() => { + var r = this.#i = document.createDocumentFragment(), n = ue(), s = !1; + if (r.append(n), this.#l = this.#h(() => { + try { + return Q(() => this.#o(n)); + } catch (i) { + try { + this.error(i), s = !0; + } catch (l) { + le(l, this.#s.parent); + } + return null; + } + }), this.#l === null) { + this.#i = null, s && this.#m( + /** @type {Batch} */ + m + ); + return; + } + this.#f === 0 && (this.#e.before(r), this.#i = null, Ce( + /** @type {Effect} */ + this.#n, + () => { + this.#n = null; + } + ), this.#m( + /** @type {Batch} */ + m + )); + })); + } + #d() { + try { + if (this.is_pending = this.has_pending_snippet(), this.#f = 0, this.#p = 0, this.#l = Q(() => { + this.#o(this.#e); + }), this.#f > 0) { + var t = this.#i = document.createDocumentFragment(); + cr(this.#l, t); + const r = ( + /** @type {(anchor: Node) => void} */ + this.#r.pending + ); + this.#n = Q(() => r(this.#e)); + } else + this.#m( + /** @type {Batch} */ + m + ); + } catch (r) { + this.error(r); + } + } + /** + * @param {Batch} batch + */ + #m(t) { + this.is_pending = !1, t.transfer_effects(this.#v, this.#_); + } + /** + * Defer an effect inside a pending boundary until the boundary resolves + * @param {Effect} effect + */ + defer_effect(t) { + Vr(t, this.#v, this.#_); + } + /** + * Returns `false` if the effect exists inside a boundary whose pending snippet is shown + * @returns {boolean} + */ + is_rendered() { + return !this.is_pending && (!this.parent || this.parent.is_rendered()); + } + has_pending_snippet() { + return !!this.#r.pending; + } + /** + * @template T + * @param {() => T} fn + */ + #h(t) { + var r = _, n = g, s = P; + ce(this.#s), K(this.#s), Ye(this.#s.ctx); + try { + return ge.ensure(), t(); + } finally { + ce(r), K(n), Ye(s); + } + } + /** + * Updates the pending count associated with the currently visible pending snippet, + * if any, such that we can replace the snippet with content once work is done + * @param {1 | -1} d + * @param {Batch} batch + */ + #$(t, r) { + if (!this.has_pending_snippet()) { + this.parent && this.parent.#$(t, r); + return; + } + this.#f += t, this.#f === 0 && (this.#m(r), this.#n && Ce(this.#n, () => { + this.#n = null; + }), this.#i && (this.#e.before(this.#i), this.#i = null)); + } + /** + * Update the source that powers `$effect.pending()` inside this boundary, + * and controls when the current `pending` snippet (if any) is removed. + * Do not call from inside the class + * @param {1 | -1} d + * @param {Batch} batch + */ + update_pending_count(t, r) { + this.#$(t, r), this.#p += t, !(!this.#c || this.#u) && (this.#u = !0, Te(() => { + this.#u = !1, this.#c && Ue(this.#c, this.#p); + })); + } + get_effect_pending() { + return this.#b(), y( + /** @type {Source} */ + this.#c + ); + } + /** @param {unknown} error */ + error(t) { + if (!this.#r.onerror && !this.#r.failed) + throw t; + m?.is_fork ? (this.#l && m.skip_effect(this.#l), this.#n && m.skip_effect(this.#n), this.#a && m.skip_effect(this.#a), m.oncommit(() => { + this.#E(t); + })) : this.#E(t); + } + /** + * @param {unknown} error + */ + #E(t) { + this.#l && (I(this.#l), this.#l = null), this.#n && (I(this.#n), this.#n = null), this.#a && (I(this.#a), this.#a = null), $ && (V( + /** @type {TemplateNode} */ + this.#t + ), We(), V(wt())); + let r = this.#r.failed; + const n = (s) => { + const { reset: i, invoke_onerror: l } = this.#w(s); + l(), r && (this.#a = this.#h(() => { + try { + return Q(() => { + var a = ( + /** @type {Effect} */ + _ + ); + a.b = this, a.f |= Ht, r( + this.#e, + () => s, + () => i + ); + }); + } catch (a) { + return le( + a, + /** @type {Effect} */ + this.#s.parent + ), null; + } + })); + }; + Te(() => { + var s; + try { + s = this.transform_error(t); + } catch (i) { + le(i, this.#s && this.#s.parent); + return; + } + s !== null && typeof s == "object" && typeof /** @type {any} */ + s.then == "function" ? s.then( + n, + /** @param {unknown} e */ + (i) => le(i, this.#s && this.#s.parent) + ) : n(s); + }); + } +} +function ye(e, t) { + var r = t == null ? "" : typeof t == "object" ? `${t}` : t; + r !== /** @type {any} */ + (e[Bt] ??= e.nodeValue) && (e[Bt] = r, e.nodeValue = `${r}`); +} +function kn(e, t) { + return wn(e, t); +} +function Xs(e, t) { + Ut(), t.intro = t.intro ?? !1; + const r = t.target, n = $, s = k; + try { + for (var i = /* @__PURE__ */ Me(r); i && (i.nodeType !== it || /** @type {Comment} */ + i.data !== Rr); ) + i = /* @__PURE__ */ ve(i); + if (!i) + throw qe; + _e(!0), V( + /** @type {Comment} */ + i + ); + const l = wn(e, { ...t, anchor: i }); + return _e(!1), /** @type {Exports} */ + l; + } catch (l) { + if (l instanceof Error && l.message.split(` +`).some((a) => a.startsWith("https://svelte.dev/e/"))) + throw l; + return l !== qe && console.warn("Failed to hydrate: ", l), t.recover === !1 && cs(), Ut(), sn(r), _e(!1), kn(e, t); + } finally { + _e(n), V(s); + } +} +const ft = /* @__PURE__ */ new Map(); +function wn(e, { target: t, anchor: r, props: n = {}, events: s, context: i, intro: l = !0, transformError: a }) { + Ut(); + var o = void 0, f = Ds(() => { + var c = r ?? t.appendChild(ue()); + Ks( + /** @type {TemplateNode} */ + c, + { + pending: () => { + } + }, + (h) => { + jr({}); + var u = ( + /** @type {ComponentContext} */ + P + ); + if (i && (u.c = i), s && (n.$$events = s), $ && ht( + /** @type {TemplateNode} */ + h, + null + ), o = e(h, n) || Zt(), $ && (_.nodes.end = k, k === null || k.nodeType !== it || /** @type {Comment} */ + k.data !== Jt)) + throw At(), qe; + zr(); + }, + a + ); + var v = /* @__PURE__ */ new Set(), d = (h) => { + for (var u = 0; u < h.length; u++) { + var w = h[u]; + if (!v.has(w)) { + v.add(w); + var T = Qs(w); + for (const re of [t, document]) { + var b = ft.get(re); + b === void 0 && (b = /* @__PURE__ */ new Map(), ft.set(re, b)); + var E = b.get(w); + E === void 0 ? (re.addEventListener(w, Sr, { passive: T }), b.set(w, 1)) : b.set(w, E + 1); + } + } + } + }; + return d(xt(bn)), Qt.add(d), () => { + for (var h of v) + for (const T of [t, document]) { + var u = ( + /** @type {Map} */ + ft.get(T) + ), w = ( + /** @type {number} */ + u.get(h) + ); + --w == 0 ? (T.removeEventListener(h, Sr), u.delete(h), u.size === 0 && ft.delete(T)) : u.set(h, w); + } + Qt.delete(d), c !== r && c.parentNode?.removeChild(c); + }; + }); + return Gt.set(o, f), o; +} +let Gt = /* @__PURE__ */ new WeakMap(); +function Zs(e, t) { + const r = Gt.get(e); + return r ? (Gt.delete(e), r(t)) : Promise.resolve(); +} +class ei { + /** @type {TemplateNode} */ + anchor; + /** @type {Map} */ + #e = /* @__PURE__ */ new Map(); + /** + * Map of keys to effects that are currently rendered in the DOM. + * These effects are visible and actively part of the document tree. + * Example: + * ``` + * {#if condition} + * foo + * {:else} + * bar + * {/if} + * ``` + * Can result in the entries `true->Effect` and `false->Effect` + * @type {Map} + */ + #t = /* @__PURE__ */ new Map(); + /** + * Similar to #onscreen with respect to the keys, but contains branches that are not yet + * in the DOM, because their insertion is deferred. + * @type {Map} + */ + #r = /* @__PURE__ */ new Map(); + /** + * Keys of effects that are currently outroing + * @type {Set} + */ + #o = /* @__PURE__ */ new Set(); + /** + * Whether to pause (i.e. outro) on change, or destroy immediately. + * This is necessary for `` + */ + #s = !0; + /** + * @param {TemplateNode} anchor + * @param {boolean} transition + */ + constructor(t, r = !0) { + this.anchor = t, this.#s = r; + } + /** + * @param {Batch} batch + */ + #l = (t) => { + if (this.#e.has(t)) { + var r = ( + /** @type {Key} */ + this.#e.get(t) + ), n = this.#t.get(r); + if (n) + Et(n), this.#o.delete(r); + else { + var s = this.#r.get(r); + s && (Et(s.effect), this.#t.set(r, s.effect), this.#r.delete(r), s.fragment.lastChild.remove(), this.anchor.before(s.fragment), n = s.effect); + } + for (const [i, l] of this.#e) { + if (this.#e.delete(i), i === t) + break; + const a = this.#r.get(l); + a && (I(a.effect), this.#r.delete(l)); + } + for (const [i, l] of this.#t) { + if (i === r || this.#o.has(i)) continue; + const a = () => { + if (Array.from(this.#e.values()).includes(i)) { + var f = document.createDocumentFragment(); + cr(l, f), f.append(ue()), this.#r.set(i, { effect: l, fragment: f }); + } else + I(l); + this.#o.delete(i), this.#t.delete(i); + }; + this.#s || !n ? (this.#o.add(i), Ce(l, a, !1)) : a(); + } + } + }; + /** + * @param {Batch} batch + */ + #n = (t) => { + this.#e.delete(t); + const r = Array.from(this.#e.values()); + for (const [n, s] of this.#r) + r.includes(n) || (I(s.effect), this.#r.delete(n)); + }; + /** + * + * @param {any} key + * @param {null | ((target: TemplateNode) => void)} fn + */ + ensure(t, r) { + var n = ( + /** @type {Batch} */ + m + ), s = ln(); + if (r && !this.#t.has(t) && !this.#r.has(t)) + if (s) { + var i = document.createDocumentFragment(), l = ue(); + i.append(l), this.#r.set(t, { + effect: Q(() => r(l)), + fragment: i + }); + } else + this.#t.set( + t, + Q(() => r(this.anchor)) + ); + if (this.#e.set(n, t), s) { + for (const [a, o] of this.#t) + a === t ? n.unskip_effect(o) : n.skip_effect(o); + for (const [a, o] of this.#r) + a === t ? n.unskip_effect(o.effect) : n.skip_effect(o.effect); + n.oncommit(this.#l), n.ondiscard(this.#n); + } else + $ && (this.anchor = k), this.#l(n); + } +} +function ti(e) { + P === null && ss(), Ms(() => { + const t = vr(e); + if (typeof t == "function") return ( + /** @type {() => void} */ + t + ); + }); +} +function ut(e, t, r = !1) { + var n; + $ && (n = k, Ct()); + var s = new ei(e), i = r ? Ve : 0; + function l(a, o) { + if ($) { + var f = Lr( + /** @type {TemplateNode} */ + n + ); + if (a !== parseInt(f.substring(1))) { + var c = wt(); + V(c), s.anchor = c, _e(!1), s.ensure(a, o), _e(!0); + return; + } + } + s.ensure(a, o); + } + fr(() => { + var a = !1; + t((o, f = 0) => { + a = !0, l(f, o); + }), a || l(-1, null); + }, i); +} +function ri(e, t, r) { + for (var n = [], s = t.length, i, l = t.length, a = 0; a < s; a++) { + let v = t[a]; + Ce( + v, + () => { + if (i) { + if (i.pending.delete(v), i.done.add(v), i.pending.size === 0) { + var d = ( + /** @type {Set} */ + e.outrogroups + ); + Wt(e, xt(i.done)), d.delete(i), d.size === 0 && (e.outrogroups = null); + } + } else + l -= 1; + }, + !1 + ); + } + if (l === 0) { + var o = n.length === 0 && r !== null && e.pending.size === 0; + if (o) { + var f = ( + /** @type {Element} */ + r + ), c = ( + /** @type {Element} */ + f.parentNode + ); + sn(c), c.append(f), e.items.clear(); + } + Wt(e, t, !o); + } else + i = { + pending: new Set(t), + done: /* @__PURE__ */ new Set() + }, (e.outrogroups ??= /* @__PURE__ */ new Set()).add(i); +} +function Wt(e, t, r = !0) { + var n; + if (e.pending.size > 0) { + n = /* @__PURE__ */ new Set(); + for (const l of e.pending.values()) + for (const a of l) + n.add( + /** @type {EachItem} */ + e.items.get(a).e + ); + } + for (var s = 0; s < t.length; s++) { + var i = t[s]; + if (n?.has(i)) { + i.f |= pe; + const l = document.createDocumentFragment(); + cr(i, l); + } else + I(t[s], r); + } +} +var Tr; +function ni(e, t, r, n, s, i = null) { + var l = e, a = /* @__PURE__ */ new Map(); + $ && Ct(); + var o = null, f = /* @__PURE__ */ ys(() => { + var b = r(); + return ( + /** @type {V[]} */ + Or(b) ? b : b == null ? [] : xt(b) + ); + }), c, v = /* @__PURE__ */ new Map(), d = !0; + function h(b) { + (T.effect.f & H) === 0 && (T.pending.delete(b), T.fallback = o, si(T, c, l, t, n), o !== null && (c.length === 0 ? (o.f & pe) === 0 ? Et(o) : (o.f ^= pe, Ze(o, null, l)) : Ce(o, () => { + o = null; + }))); + } + function u(b) { + T.pending.delete(b); + } + var w = fr(() => { + c = /** @type {V[]} */ + y(f); + var b = c.length; + let E = !1; + if ($) { + var re = Lr(l) === Kt; + re !== (b === 0) && (l = wt(), V(l), _e(!1), E = !0); + } + for (var ne = /* @__PURE__ */ new Set(), q = ( + /** @type {Batch} */ + m + ), Le = ln(), se = 0; se < b; se += 1) { + $ && k.nodeType === it && /** @type {Comment} */ + k.data === Jt && (l = /** @type {Comment} */ + k, E = !0, _e(!1)); + var p = c[se], O = n(p, se), M = d ? null : a.get(O); + M ? (M.v && Ue(M.v, p), M.i && Ue(M.i, se), Le && q.unskip_effect(M.e)) : (M = ii( + a, + d ? l : Tr ??= ue(), + p, + O, + se, + s, + t, + r + ), d || (M.e.f |= pe), a.set(O, M)), ne.add(O); + } + if (b === 0 && i && !o && (d ? o = Q(() => i(l)) : (o = Q(() => i(Tr ??= ue())), o.f |= pe)), b > ne.size && ls(), $ && b > 0 && V(wt()), !d) + if (v.set(q, ne), Le) { + for (const [xe, Fe] of a) + ne.has(xe) || q.skip_effect(Fe.e); + q.oncommit(h), q.ondiscard(u); + } else + h(q); + E && _e(!0), y(f); + }), T = { effect: w, items: a, pending: v, outrogroups: null, fallback: o }; + d = !1, $ && (l = k); +} +function Ge(e) { + for (; e !== null && (e.f & W) === 0; ) + e = e.next; + return e; +} +function si(e, t, r, n, s) { + var i = t.length, l = e.items, a = Ge(e.effect.first), o, f = null, c = [], v = [], d, h, u, w; + for (w = 0; w < i; w += 1) { + if (d = t[w], h = s(d, w), u = /** @type {EachItem} */ + l.get(h).e, e.outrogroups !== null) + for (const p of e.outrogroups) + p.pending.delete(u), p.done.delete(u); + if ((u.f & F) !== 0 && Et(u), (u.f & pe) !== 0) + if (u.f ^= pe, u === a) + Ze(u, null, r); + else { + var T = f ? f.next : a; + u === e.effect.last && (e.effect.last = u.prev), u.prev && (u.prev.next = u.next), u.next && (u.next.prev = u.prev), $e(e, f, u), $e(e, u, T), Ze(u, T, r), f = u, c = [], v = [], a = Ge(f.next); + continue; + } + if (u !== a) { + if (o !== void 0 && o.has(u)) { + if (c.length < v.length) { + var b = v[0], E; + f = b.prev; + var re = c[0], ne = c[c.length - 1]; + for (E = 0; E < c.length; E += 1) + Ze(c[E], b, r); + for (E = 0; E < v.length; E += 1) + o.delete(v[E]); + $e(e, re.prev, ne.next), $e(e, f, re), $e(e, ne, b), a = b, f = ne, w -= 1, c = [], v = []; + } else + o.delete(u), Ze(u, a, r), $e(e, u.prev, u.next), $e(e, u, f === null ? e.effect.first : f.next), $e(e, f, u), f = u; + continue; + } + for (c = [], v = []; a !== null && a !== u; ) + (o ??= /* @__PURE__ */ new Set()).add(a), v.push(a), a = Ge(a.next); + if (a === null) + continue; + } + (u.f & pe) === 0 && c.push(u), f = u, a = Ge(u.next); + } + if (e.outrogroups !== null) { + for (const p of e.outrogroups) + p.pending.size === 0 && (Wt(e, xt(p.done)), e.outrogroups?.delete(p)); + e.outrogroups.size === 0 && (e.outrogroups = null); + } + if (a !== null || o !== void 0) { + var q = []; + if (o !== void 0) + for (u of o) + (u.f & F) === 0 && q.push(u); + for (; a !== null; ) + (a.f & F) === 0 && a !== e.fallback && q.push(a), a = Ge(a.next); + var Le = q.length; + if (Le > 0) { + var se = null; + ri(e, q, se); + } + } +} +function ii(e, t, r, n, s, i, l, a) { + var o = (l & jn) !== 0 ? (l & Hn) === 0 ? /* @__PURE__ */ Zr(r, !1, !1) : Oe(r) : null, f = (l & zn) !== 0 ? Oe(s) : null; + return { + v: o, + i: f, + e: Q(() => (i(t, o ?? r, f ?? s, a), () => { + e.delete(n); + })) + }; +} +function Ze(e, t, r) { + if (e.nodes) + for (var n = e.nodes.start, s = e.nodes.end, i = t && (t.f & pe) === 0 ? ( + /** @type {EffectNodes} */ + t.nodes.start + ) : r; n !== null; ) { + var l = ( + /** @type {TemplateNode} */ + /* @__PURE__ */ ve(n) + ); + if (i.before(n), n === s) + return; + n = l; + } +} +function $e(e, t, r) { + t === null ? e.effect.first = r : t.next = r, r === null ? e.effect.last = t : r.prev = t; +} +function li(e, t) { + on(() => { + e = _?.parent?.nodes?.start ?? e; + var r = e.getRootNode(), n = ( + /** @type {ShadowRoot} */ + r.host ? ( + /** @type {ShadowRoot} */ + r + ) : ( + /** @type {Document} */ + r.head ?? /** @type {Document} */ + r.ownerDocument.head + ) + ); + if (!n.querySelector("#" + t.hash)) { + const s = ir("style"); + s.id = t.hash, s.textContent = t.code, n.appendChild(s); + } + }); +} +const Ar = [...` +\r\f \v\uFEFF`]; +function ai(e, t, r) { + var n = "" + e; + if (r) { + for (var s of Object.keys(r)) + if (r[s]) + n = n ? n + " " + s : s; + else if (n.length) + for (var i = s.length, l = 0; (l = n.indexOf(s, l)) >= 0; ) { + var a = l + i; + (l === 0 || Ar.includes(n[l - 1])) && (a === n.length || Ar.includes(n[a])) ? n = (l === 0 ? "" : n.substring(0, l)) + n.substring(a + 1) : l = a; + } + } + return n === "" ? null : n; +} +function oi(e, t, r, n, s, i) { + var l = ( + /** @type {any} */ + e[qt] + ); + if ($ || l !== r || l === void 0) { + var a = ai(r, n, i); + (!$ || a !== e.getAttribute("class")) && (a == null ? e.removeAttribute("class") : e.className = a), e[qt] = r; + } else if (i && s !== i) + for (var o in i) { + var f = !!i[o]; + (s == null || f !== !!s[o]) && e.classList.toggle(o, f); + } + return i; +} +function zt(e, t) { + return e === t || e?.[ct] === t; +} +function fi(e = Zt(), t, r, n) { + var s = ( + /** @type {ComponentContext} */ + P.r + ), i = ( + /** @type {Effect} */ + _ + ); + return on(() => { + var l, a; + return or(() => { + l = a, a = [], vr(() => { + zt(r(...a), e) || (t(e, ...a), l && zt(r(...l), e) && t(null, ...l)); + }); + }), () => { + let o = i; + for (; o !== s && o.parent !== null && o.parent.f & mt; ) + o = o.parent; + const f = () => { + a && zt(r(...a), e) && t(null, ...a); + }, c = o.teardown; + o.teardown = () => { + f(), c?.(); + }; + }; + }), e; +} +function ui(e, t, r, n) { + var s = ( + /** @type {V} */ + n + ), i = !0, l = () => (i && (i = !1, s = /** @type {V} */ + n), s), a; + a = /** @type {V} */ + e[t], a === void 0 && n !== void 0 && (a = l()); + var o; + o = () => { + var d = ( + /** @type {V} */ + e[t] + ); + return d === void 0 ? l() : (i = !0, d); + }; + var f = !1, c = /* @__PURE__ */ tr(() => (f = !1, o())), v = ( + /** @type {Effect} */ + _ + ); + return ( + /** @type {() => V} */ + (function(d, h) { + if (arguments.length > 0) { + const u = h ? y(c) : d; + return j(c, u), f = !0, s !== void 0 && (s = u), d; + } + return me && f || (v.f & H) !== 0 ? c.v : y(c); + }) + ); +} +function ci(e) { + return new vi(e); +} +class vi { + /** @type {any} */ + #e; + /** @type {Record} */ + #t; + /** + * @param {ComponentConstructorOptions & { + * component: any; + * }} options + */ + constructor(t) { + var r = /* @__PURE__ */ new Map(), n = (i, l) => { + var a = /* @__PURE__ */ Zr(l, !1, !1); + return r.set(i, a), a; + }; + const s = new Proxy( + { ...t.props || {}, $$events: {} }, + { + get(i, l) { + return y(r.get(l) ?? n(l, Reflect.get(i, l))); + }, + has(i, l) { + return l === Xn ? !0 : (y(r.get(l) ?? n(l, Reflect.get(i, l))), Reflect.has(i, l)); + }, + set(i, l, a) { + return j(r.get(l) ?? n(l, a), a), Reflect.set(i, l, a); + } + } + ); + this.#t = (t.hydrate ? Xs : kn)(t.component, { + target: t.target, + anchor: t.anchor, + props: s, + context: t.context, + intro: t.intro ?? !1, + recover: t.recover, + transformError: t.transformError + }), (!t?.props?.$$host || t.sync === !1) && Gr(), this.#e = s.$$events; + for (const i of Object.keys(this.#t)) + i === "$set" || i === "$destroy" || i === "$on" || rt(this, i, { + get() { + return this.#t[i]; + }, + /** @param {any} value */ + set(l) { + this.#t[i] = l; + }, + enumerable: !0 + }); + this.#t.$set = /** @param {Record} next */ + (i) => { + Object.assign(s, i); + }, this.#t.$destroy = () => { + Zs(this.#t); + }; + } + /** @param {Record} props */ + $set(t) { + this.#t.$set(t); + } + /** + * @param {string} event + * @param {(...args: any[]) => any} callback + * @returns {any} + */ + $on(t, r) { + this.#e[t] = this.#e[t] || []; + const n = (...s) => r.call(this, ...s); + return this.#e[t].push(n), () => { + this.#e[t] = this.#e[t].filter( + /** @param {any} fn */ + (s) => s !== n + ); + }; + } + $destroy() { + this.#t.$destroy(); + } +} +let yn; +typeof HTMLElement == "function" && (yn = class extends HTMLElement { + /** The Svelte component constructor */ + $$ctor; + /** Slots */ + $$s; + /** @type {any} The Svelte component instance */ + $$c; + /** Whether or not the custom element is connected */ + $$cn = !1; + /** @type {Record} Component props data */ + $$d = {}; + /** `true` if currently in the process of reflecting component props back to attributes */ + $$r = !1; + /** @type {Record} Props definition (name, reflected, type etc) */ + $$p_d = {}; + /** @type {Record} Event listeners */ + $$l = {}; + /** @type {Map} Event listener unsubscribe functions */ + $$l_u = /* @__PURE__ */ new Map(); + /** @type {any} The managed render effect for reflecting attributes */ + $$me; + /** @type {ShadowRoot | null} The ShadowRoot of the custom element */ + $$shadowRoot = null; + /** + * @param {*} $$componentCtor + * @param {*} $$slots + * @param {ShadowRootInit | undefined} shadow_root_init + */ + constructor(e, t, r) { + super(), this.$$ctor = e, this.$$s = t, r && (this.$$shadowRoot = this.attachShadow(r)); + } + /** + * @param {string} type + * @param {EventListenerOrEventListenerObject} listener + * @param {boolean | AddEventListenerOptions} [options] + */ + addEventListener(e, t, r) { + if (this.$$l[e] = this.$$l[e] || [], this.$$l[e].push(t), this.$$c) { + const n = this.$$c.$on(e, t); + this.$$l_u.set(t, n); + } + super.addEventListener(e, t, r); + } + /** + * @param {string} type + * @param {EventListenerOrEventListenerObject} listener + * @param {boolean | AddEventListenerOptions} [options] + */ + removeEventListener(e, t, r) { + if (super.removeEventListener(e, t, r), this.$$c) { + const n = this.$$l_u.get(t); + n && (n(), this.$$l_u.delete(t)); + } + } + async connectedCallback() { + if (this.$$cn = !0, !this.$$c) { + let t = function(s) { + return (i) => { + const l = ir("slot"); + s !== "default" && (l.name = s), ie(i, l); + }; + }; + var e = t; + if (await Promise.resolve(), !this.$$cn || this.$$c) + return; + const r = {}, n = di(this); + for (const s of this.$$s) + s in n && (s === "default" && !this.$$d.children ? (this.$$d.children = t(s), r.default = !0) : r[s] = t(s)); + for (const s of this.attributes) { + const i = this.$$g_p(s.name); + i in this.$$d || (this.$$d[i] = pt(i, s.value, this.$$p_d, "toProp")); + } + for (const s in this.$$p_d) + !(s in this.$$d) && this[s] !== void 0 && (this.$$d[s] = this[s], delete this[s]); + this.$$c = ci({ + component: this.$$ctor, + target: this.$$shadowRoot || this, + props: { + ...this.$$d, + $$slots: r, + $$host: this + } + }), this.$$me = Ps(() => { + or(() => { + this.$$r = !0; + for (const s of gt(this.$$c)) { + if (!this.$$p_d[s]?.reflect) continue; + this.$$d[s] = this.$$c[s]; + const i = pt( + s, + this.$$d[s], + this.$$p_d, + "toAttribute" + ); + i == null ? this.removeAttribute(this.$$p_d[s].attribute || s) : this.setAttribute(this.$$p_d[s].attribute || s, i); + } + this.$$r = !1; + }); + }); + for (const s in this.$$l) + for (const i of this.$$l[s]) { + const l = this.$$c.$on(s, i); + this.$$l_u.set(i, l); + } + this.$$l = {}; + } + } + // We don't need this when working within Svelte code, but for compatibility of people using this outside of Svelte + // and setting attributes through setAttribute etc, this is helpful + /** + * @param {string} attr + * @param {string} _oldValue + * @param {string} newValue + */ + attributeChangedCallback(e, t, r) { + this.$$r || (e = this.$$g_p(e), this.$$d[e] = pt(e, r, this.$$p_d, "toProp"), this.$$c?.$set({ [e]: this.$$d[e] })); + } + disconnectedCallback() { + this.$$cn = !1, Promise.resolve().then(() => { + !this.$$cn && this.$$c && (this.$$c.$destroy(), this.$$me(), this.$$c = void 0); + }); + } + /** + * @param {string} attribute_name + */ + $$g_p(e) { + return gt(this.$$p_d).find( + (t) => this.$$p_d[t].attribute === e || !this.$$p_d[t].attribute && t.toLowerCase() === e + ) || e; + } +}); +function pt(e, t, r, n) { + const s = r[e]?.type; + if (t = s === "Boolean" && typeof t != "boolean" ? t != null : t, !n || !r[e]) + return t; + if (n === "toAttribute") + switch (s) { + case "Object": + case "Array": + return t == null ? null : JSON.stringify(t); + case "Boolean": + return t ? "" : null; + case "Number": + return t ?? null; + default: + return t; + } + else + switch (s) { + case "Object": + case "Array": + return t && JSON.parse(t); + case "Boolean": + return t; + // conversion already handled above + case "Number": + return t != null ? +t : t; + default: + return t; + } +} +function di(e) { + const t = {}; + return e.childNodes.forEach((r) => { + t[ + /** @type {Element} node */ + r.slot || "default" + ] = !0; + }), t; +} +function hi(e, t, r, n, s, i) { + let l = class extends yn { + constructor() { + super(e, r, s), this.$$p_d = t; + } + static get observedAttributes() { + return gt(t).map( + (a) => (t[a].attribute || a).toLowerCase() + ); + } + }; + return gt(t).forEach((a) => { + rt(l.prototype, a, { + get() { + return this.$$c && a in this.$$c ? this.$$c[a] : this.$$d[a]; + }, + set(o) { + o = pt(a, o, t), this.$$d[a] = o; + var f = this.$$c; + if (f) { + var c = ze(f, a)?.get; + c ? f[a] = o : f.$set({ [a]: o }); + } + } + }); + }), n.forEach((a) => { + rt(l.prototype, a, { + get() { + return this.$$c?.[a]; + } + }); + }), e.element = /** @type {any} */ + l, l; +} +function pi(e, t) { + e.dispatchEvent(new CustomEvent("barkstack:navigate", { + bubbles: !0, + composed: !0, + detail: { path: t } + })); +} +function Cr(e, t, r) { + e.dispatchEvent(new CustomEvent("barkstack:notify", { + bubbles: !0, + composed: !0, + detail: { level: t, message: r } + })); +} +var _i = /* @__PURE__ */ be(''), gi = /* @__PURE__ */ be('
'), mi = /* @__PURE__ */ be(''), bi = /* @__PURE__ */ be(''), ki = /* @__PURE__ */ be('
No database routes are configured.
'), wi = /* @__PURE__ */ be('
Ready
'), yi = /* @__PURE__ */ be('
DatabaseHostnameBackendStatus
'), $i = /* @__PURE__ */ be('
Connection endpoint

Use a configured database hostname or database name to select a route.

Configured routes

Routes loaded from this PawSQL release configuration.

Router stateRunning

PostgreSQL listener and management UI are online.

Routing table

', 1), Ei = /* @__PURE__ */ be('
PostgreSQL routing

PawSQL

Secure, service-aware PostgreSQL routing for Barkstack workloads.

Status
'); +const xi = { + hash: "svelte-809kv3", + code: `:host {display:block;color:var(--bark-text, #edf3fb);font-family:var(--bark-font-sans, system-ui, sans-serif);}.svelte-809kv3 {box-sizing:border-box;}section.svelte-809kv3 {display:grid;gap:var(--bark-space-5, 1.5rem);}.intro.svelte-809kv3 {display:flex;justify-content:space-between;align-items:flex-start;gap:var(--bark-space-5, 1.5rem);}.eyebrow.svelte-809kv3, .label.svelte-809kv3 {color:var(--bark-primary, #6ee7b7);font-size:.69rem;font-weight:800;letter-spacing:.12em;text-transform:uppercase;}h2.svelte-809kv3 {margin:.55rem 0 .35rem;font-size:2.25rem;letter-spacing:-.05em;}h3.svelte-809kv3 {margin:.4rem 0 0;font-size:1.15rem;}p.svelte-809kv3 {margin:0;color:var(--bark-text-muted, #91a1b7);line-height:1.6;}.service-status.svelte-809kv3 {display:flex;align-items:center;gap:.65rem;padding:.65rem .9rem;border:1px solid var(--bark-border, #27354a);border-radius:var(--bark-radius-md, .75rem);background:var(--bark-surface, #101827);}.service-status.svelte-809kv3 > span:where(.svelte-809kv3) {width:.55rem;height:.55rem;border-radius:50%;background:var(--bark-success, #4ade80);box-shadow:0 0 0 5px color-mix(in srgb, var(--bark-success, #4ade80) 12%, transparent);}.service-status.offline.svelte-809kv3 > span:where(.svelte-809kv3) {background:var(--bark-danger, #fb7185);}.service-status.svelte-809kv3 small:where(.svelte-809kv3), .service-status.svelte-809kv3 strong:where(.svelte-809kv3) {display:block;}.service-status.svelte-809kv3 small:where(.svelte-809kv3) {color:var(--bark-text-muted, #91a1b7);font-size:.66rem;text-transform:uppercase;letter-spacing:.08em;}.service-status.svelte-809kv3 strong:where(.svelte-809kv3) {margin-top:.15rem;font-size:.82rem;}.back.svelte-809kv3 {justify-self:start;border:0;background:none;color:var(--bark-text-muted, #91a1b7);cursor:pointer;padding:0;}.back.svelte-809kv3:hover {color:var(--bark-text, #edf3fb);}.grid.svelte-809kv3 {display:grid;grid-template-columns:1.5fr .75fr .75fr;gap:var(--bark-space-4, 1rem);}.grid.svelte-809kv3 article:where(.svelte-809kv3) {min-height:10rem;padding:var(--bark-space-5, 1.5rem);border:1px solid var(--bark-border, #27354a);border-radius:var(--bark-radius-lg, 1rem);background:var(--bark-surface, #101827);}.grid.svelte-809kv3 article:where(.svelte-809kv3) p:where(.svelte-809kv3) {margin-top:.8rem;font-size:.82rem;}.metric.svelte-809kv3 {display:block;margin-top:.9rem;font-size:1.65rem;letter-spacing:-.04em;}.metric.healthy.svelte-809kv3 {color:var(--bark-success, #4ade80);}.endpoint.svelte-809kv3 {display:flex;align-items:center;gap:.7rem;margin-top:1rem;}.endpoint.svelte-809kv3 code:where(.svelte-809kv3) {flex:1;overflow:hidden;color:var(--bark-text, #edf3fb);font-family:var(--bark-font-mono, monospace);font-size:.86rem;text-overflow:ellipsis;}.endpoint.svelte-809kv3 button:where(.svelte-809kv3), .panel-heading.svelte-809kv3 button:where(.svelte-809kv3), .error.svelte-809kv3 button:where(.svelte-809kv3) {padding:.45rem .7rem;border:1px solid var(--bark-border, #27354a);border-radius:var(--bark-radius-sm, .45rem);background:var(--bark-surface-raised, #172235);color:var(--bark-text, #edf3fb);cursor:pointer;}.routes-panel.svelte-809kv3 {border:1px solid var(--bark-border, #27354a);border-radius:var(--bark-radius-lg, 1rem);background:var(--bark-surface, #101827);overflow:hidden;}.panel-heading.svelte-809kv3 {display:flex;align-items:center;justify-content:space-between;padding:var(--bark-space-5, 1.5rem);border-bottom:1px solid var(--bark-border, #27354a);}.panel-heading.svelte-809kv3 button:where(.svelte-809kv3) {border:0;background:transparent;color:var(--bark-primary, #6ee7b7);}.row.svelte-809kv3 {display:grid;grid-template-columns:1fr 1.5fr 1.25fr .6fr;gap:1rem;align-items:center;min-height:3.7rem;padding:.75rem var(--bark-space-5, 1.5rem);border-bottom:1px solid var(--bark-border, #27354a);font-size:.82rem;}.row.svelte-809kv3:last-child {border-bottom:0;}.row.header.svelte-809kv3 {min-height:2.8rem;color:var(--bark-text-muted, #91a1b7);background:var(--bark-surface-raised, #172235);font-size:.68rem;font-weight:700;letter-spacing:.07em;text-transform:uppercase;}.row.svelte-809kv3 code:where(.svelte-809kv3) {color:var(--bark-text-muted, #91a1b7);font-family:var(--bark-font-mono, monospace);}.ready.svelte-809kv3 {color:var(--bark-success, #4ade80);}.ready.svelte-809kv3 i:where(.svelte-809kv3) {display:inline-block;width:.4rem;height:.4rem;margin-right:.4rem;border-radius:50%;background:currentColor;}.empty.svelte-809kv3, .error.svelte-809kv3 {padding:3rem;text-align:center;color:var(--bark-text-muted, #91a1b7);}.error.svelte-809kv3 {border:1px solid color-mix(in srgb, var(--bark-danger, #fb7185) 30%, var(--bark-border, #27354a));border-radius:var(--bark-radius-lg, 1rem);background:var(--bark-surface, #101827);}.error.svelte-809kv3 strong:where(.svelte-809kv3) {color:var(--bark-text, #edf3fb);}.error.svelte-809kv3 p:where(.svelte-809kv3) {margin:.5rem 0 1rem;}.loading.svelte-809kv3 {display:grid;gap:.8rem;padding:2rem;border:1px solid var(--bark-border, #27354a);border-radius:var(--bark-radius-lg, 1rem);background:var(--bark-surface, #101827);}.loading.svelte-809kv3 span:where(.svelte-809kv3) {height:1rem;border-radius:.3rem;background:var(--bark-surface-raised, #172235); animation: svelte-809kv3-pulse 1.4s infinite;}.loading.svelte-809kv3 span:where(.svelte-809kv3):nth-child(2) {width:65%;}.loading.svelte-809kv3 span:where(.svelte-809kv3):nth-child(3) {width:40%;} @keyframes svelte-809kv3-pulse { 50% { opacity: .4; } } + @media (max-width: 850px) {.intro.svelte-809kv3 {flex-direction:column;}.grid.svelte-809kv3 {grid-template-columns:1fr;}.row.svelte-809kv3 {grid-template-columns:1fr;gap:.35rem;padding:1rem;}.row.header.svelte-809kv3 {display:none;}.endpoint.svelte-809kv3 {align-items:stretch;flex-direction:column;} }` +}; +function Si(e, t) { + jr(t, !0), li(e, xi); + let r = ui(t, "route", 7, "/"), n, s = /* @__PURE__ */ J(void 0), i = /* @__PURE__ */ J(!0), l = /* @__PURE__ */ J(""); + async function a() { + j(i, !0); + try { + const p = await fetch("/plugins/pawsql/ui/status.json", { headers: { Accept: "application/json" }, cache: "no-store" }); + if (!p.ok) throw new Error(`Status returned ${p.status}`); + j(s, await p.json(), !0), j(l, ""); + } catch (p) { + j(l, p instanceof Error ? p.message : "Status is unavailable", !0); + } finally { + j(i, !1); + } + } + function o(p) { + pi(n, p); + } + async function f() { + const p = y(s)?.endpoint ?? "*.pawsql.barkstack.dev:5432"; + try { + await navigator.clipboard.writeText(p), Cr(n, "success", "Connection endpoint copied"); + } catch { + Cr(n, "info", p); + } + } + ti(a); + var c = { + get route() { + return r(); + }, + set route(p = "/") { + r(p), Gr(); + } + }, v = Ei(), d = L(v), h = R(L(d), 2); + let u; + var w = R(L(h)), T = R(L(w)), b = we(T, !0); + D(w), D(h), D(d); + var E = R(d, 2); + { + var re = (p) => { + var O = _i(); + ot("click", O, () => o("/pawsql")), ie(p, O); + }; + ut(E, (p) => { + r() !== "/" && p(re); + }); + } + var ne = R(E, 2); + { + var q = (p) => { + var O = gi(); + ie(p, O); + }, Le = (p) => { + var O = mi(), M = R(L(O)), xe = we(M, !0), Fe = R(M); + D(O), at(() => ye(xe, y(l))), ot("click", Fe, a), ie(p, O); + }, se = (p) => { + var O = $i(), M = As(O), xe = L(M), Fe = R(L(xe), 2), dr = L(Fe), $n = we(dr, !0), En = R(dr); + D(Fe), We(2), D(xe); + var hr = R(xe, 2), xn = R(L(hr)), Sn = we(xn, !0); + We(), D(hr), We(2), D(M); + var pr = R(M, 2), Nt = L(pr), Ot = L(Nt), Tn = R(L(Ot)), An = we(Tn, !0); + D(Ot); + var Cn = R(Ot); + { + var Rn = (Y) => { + var ke = bi(); + ot("click", ke, () => o("/pawsql/routes")), ie(Y, ke); + }; + ut(Cn, (Y) => { + r() === "/" && Y(Rn); + }); + } + D(Nt); + var Nn = R(Nt, 2); + { + var On = (Y) => { + var ke = ki(); + ie(Y, ke); + }, Mn = (Y) => { + var ke = yi(), Pn = R(L(ke), 2); + ni(Pn, 17, () => y(s).routes, (Mt) => Mt.name, (Mt, Pt) => { + var Dt = wi(), _r = L(Dt), Dn = we(_r, !0), gr = R(_r), Ln = we(gr, !0), Fn = R(gr), In = we(Fn, !0); + We(), D(Dt), at(() => { + ye(Dn, y(Pt).name), ye(Ln, y(Pt).hostname || "Database name"), ye(In, y(Pt).managed ? "Managed PostgreSQL" : "External upstream"); + }), ie(Mt, Dt); + }), D(ke), ie(Y, ke); + }; + ut(Nn, (Y) => { + y(s)?.routes.length ? Y(Mn, -1) : Y(On); + }); + } + D(pr), at( + (Y) => { + ye($n, y(s)?.endpoint), ye(Sn, y(s)?.routes.length ?? 0), ye(An, Y); + }, + [ + () => r().startsWith("/routes") ? "All configured routes" : "Active configuration" + ] + ), ot("click", En, f), ie(p, O); + }; + ut(ne, (p) => { + y(i) ? p(q) : y(l) ? p(Le, 1) : p(se, -1); + }); + } + return D(v), fi(v, (p) => n = p, () => n), at(() => { + u = oi(h, 1, "service-status svelte-809kv3", null, u, { offline: !!y(l) }), ye(b, y(l) ? "Degraded" : y(s)?.status ?? "Connecting"); + }), ie(e, v), zr(c); +} +qs(["click"]); +customElements.define("barkstack-pawsql", hi(Si, { route: { reflect: !0, type: "String" } }, [], [], { mode: "open" })); diff --git a/internal/adminui/handler.go b/internal/adminui/handler.go new file mode 100644 index 0000000..fea1b29 --- /dev/null +++ b/internal/adminui/handler.go @@ -0,0 +1,118 @@ +// Package adminui serves PawSQL's Barkstack UI plugin and small read-only status API. +package adminui + +import ( + "embed" + "encoding/json" + "io/fs" + "mime" + "net/http" + "path" + "strings" +) + +//go:embed dist +var embeddedUI embed.FS + +const entryPath = "/barkstack/ui/assets/entry.js" + +type manifest struct { + APIVersion string `json:"apiVersion"` + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Icon string `json:"icon"` + Mount string `json:"mount"` + Entry string `json:"entry"` + Element string `json:"element"` + Navigation []navigationItem `json:"navigation"` +} + +type navigationItem struct { + Label string `json:"label"` + Path string `json:"path"` + Icon string `json:"icon"` +} + +type RouteSummary struct { + Name string `json:"name"` + Hostname string `json:"hostname,omitempty"` + Managed bool `json:"managed"` +} + +type statusResponse struct { + Status string `json:"status"` + Routes []RouteSummary `json:"routes"` + Endpoint string `json:"endpoint"` +} + +type handler struct { + assets fs.FS + routes []RouteSummary +} + +func Handler(routes []RouteSummary) http.Handler { + assets, err := fs.Sub(embeddedUI, "dist") + if err != nil { + panic(err) + } + copyRoutes := append([]RouteSummary(nil), routes...) + return &handler{assets: assets, routes: copyRoutes} +} + +func (h *handler) ServeHTTP(response http.ResponseWriter, request *http.Request) { + if request.Method != http.MethodGet && request.Method != http.MethodHead { + response.Header().Set("Allow", "GET, HEAD") + http.Error(response, "method not allowed", http.StatusMethodNotAllowed) + return + } + switch request.URL.Path { + case "/barkstack/ui/manifest.json": + h.serveJSON(response, request, manifest{ + APIVersion: "barkstack.dev/ui/v1", ID: "pawsql", Name: "PawSQL", + Description: "PostgreSQL routing for Barkstack", Icon: "database", Mount: "/pawsql", + Entry: entryPath, Element: "barkstack-pawsql", + Navigation: []navigationItem{{Label: "PawSQL", Path: "/pawsql", Icon: "database"}}, + }) + case "/barkstack/ui/status.json": + h.serveJSON(response, request, statusResponse{Status: "running", Routes: h.routes, Endpoint: "*.pawsql.barkstack.dev:5432"}) + default: + h.serveAsset(response, request) + } +} + +func (h *handler) serveJSON(response http.ResponseWriter, request *http.Request, value any) { + response.Header().Set("Content-Type", "application/json") + response.Header().Set("Cache-Control", "no-store") + if request.Method == http.MethodHead { + return + } + _ = json.NewEncoder(response).Encode(value) +} + +func (h *handler) serveAsset(response http.ResponseWriter, request *http.Request) { + const prefix = "/barkstack/ui/assets/" + if !strings.HasPrefix(request.URL.Path, prefix) { + http.NotFound(response, request) + return + } + assetName := strings.TrimPrefix(request.URL.Path, "/barkstack/ui/") + if assetName == "" || !fs.ValidPath(assetName) || path.Clean(assetName) != assetName || strings.Contains(assetName, "\\") { + http.NotFound(response, request) + return + } + contents, err := fs.ReadFile(h.assets, assetName) + if err != nil { + http.NotFound(response, request) + return + } + if contentType := mime.TypeByExtension(path.Ext(assetName)); contentType != "" { + response.Header().Set("Content-Type", contentType) + } + response.Header().Set("Cache-Control", "public, max-age=31536000, immutable") + response.Header().Set("X-Content-Type-Options", "nosniff") + if request.Method == http.MethodHead { + return + } + _, _ = response.Write(contents) +} diff --git a/internal/adminui/handler_test.go b/internal/adminui/handler_test.go new file mode 100644 index 0000000..ba06e31 --- /dev/null +++ b/internal/adminui/handler_test.go @@ -0,0 +1,62 @@ +package adminui + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestManifestEndpointDescribesPawSQLPlugin(t *testing.T) { + response := httptest.NewRecorder() + Handler(nil).ServeHTTP(response, httptest.NewRequest(http.MethodGet, "/barkstack/ui/manifest.json", nil)) + if response.Code != http.StatusOK { + t.Fatalf("status = %d", response.Code) + } + if got := response.Header().Get("Content-Type"); got != "application/json" { + t.Fatalf("content type = %q", got) + } + var got manifest + if err := json.Unmarshal(response.Body.Bytes(), &got); err != nil { + t.Fatal(err) + } + if got.APIVersion != "barkstack.dev/ui/v1" || got.ID != "pawsql" || got.Entry != entryPath || got.Element != "barkstack-pawsql" { + t.Fatalf("manifest = %+v", got) + } +} + +func TestEmbeddedEntryAssetIsServedWithJavaScriptContentType(t *testing.T) { + response := httptest.NewRecorder() + Handler(nil).ServeHTTP(response, httptest.NewRequest(http.MethodGet, entryPath, nil)) + if response.Code != http.StatusOK { + t.Fatalf("status = %d", response.Code) + } + if got := response.Header().Get("Content-Type"); !strings.Contains(got, "javascript") { + t.Fatalf("content type = %q", got) + } + if response.Body.Len() == 0 { + t.Fatal("embedded entry asset is empty") + } +} + +func TestStatusEndpointReportsConfiguredRoutes(t *testing.T) { + routes := []RouteSummary{{Name: "reporting", Hostname: "reports.example.com", Managed: true}} + response := httptest.NewRecorder() + Handler(routes).ServeHTTP(response, httptest.NewRequest(http.MethodGet, "/barkstack/ui/status.json", nil)) + var got statusResponse + if err := json.Unmarshal(response.Body.Bytes(), &got); err != nil { + t.Fatal(err) + } + if got.Status != "running" || len(got.Routes) != 1 || got.Routes[0] != routes[0] { + t.Fatalf("status response = %+v", got) + } +} + +func TestUnknownAssetReturnsNotFound(t *testing.T) { + response := httptest.NewRecorder() + Handler(nil).ServeHTTP(response, httptest.NewRequest(http.MethodGet, "/barkstack/ui/assets/missing.js", nil)) + if response.Code != http.StatusNotFound { + t.Fatalf("status = %d, want 404", response.Code) + } +} diff --git a/ui/bun.lock b/ui/bun.lock new file mode 100644 index 0000000..5c27fd7 --- /dev/null +++ b/ui/bun.lock @@ -0,0 +1,350 @@ +{ + "lockfileVersion": 2, + "configVersion": 1, + "workspaces": { + "": { + "name": "@barkstack/pawsql-ui", + "dependencies": { + "svelte": "^5.38.10", + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^6.2.0", + "jsdom": "^27.0.0", + "typescript": "^5.9.2", + "vite": "^7.1.5", + "vitest": "^3.2.4", + }, + }, + }, + "packages": { + "@acemir/cssom": ["@acemir/cssom@0.9.31", "", {}, "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA=="], + + "@asamuzakjp/css-color": ["@asamuzakjp/css-color@4.1.2", "", { "dependencies": { "@csstools/css-calc": "^3.0.0", "@csstools/css-color-parser": "^4.0.1", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", "lru-cache": "^11.2.5" } }, "sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg=="], + + "@asamuzakjp/dom-selector": ["@asamuzakjp/dom-selector@6.8.1", "", { "dependencies": { "@asamuzakjp/nwsapi": "^2.3.9", "bidi-js": "^1.0.3", "css-tree": "^3.1.0", "is-potential-custom-element-name": "^1.0.1", "lru-cache": "^11.2.6" } }, "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ=="], + + "@asamuzakjp/nwsapi": ["@asamuzakjp/nwsapi@2.3.9", "", {}, "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q=="], + + "@csstools/color-helpers": ["@csstools/color-helpers@6.1.1", "", {}, "sha512-gLNsunvwf3mCi5u5o46/Z/JcJMnhbHSaZ69rkgPzNM3J4s8hWwpPUQB6/tt0EDFyCiWzxANlx+2LJwpYj4zS1w=="], + + "@csstools/css-calc": ["@csstools/css-calc@3.4.0", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-XQKj5B7QiZcHiegCOCAzcAOJdhGgWOHbbu62h5e5mkHnn8lWcfiJhllkqWmxu5zWR9jucPHuo1iTB56P033hcg=="], + + "@csstools/css-color-parser": ["@csstools/css-color-parser@4.2.3", "", { "dependencies": { "@csstools/color-helpers": "^6.1.1", "@csstools/css-calc": "^3.4.0" }, "peerDependencies": { "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-y4LpL+lmpuyKDiEFq2PnZUVFdAjsoB/qQJod79yLNokXyW7jewi+/WJ69EfItj8A2unWtxXnGjw6LYXgXu5ZjA=="], + + "@csstools/css-parser-algorithms": ["@csstools/css-parser-algorithms@4.0.0", "", { "peerDependencies": { "@csstools/css-tokenizer": "^4.0.0" } }, "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w=="], + + "@csstools/css-syntax-patches-for-csstree": ["@csstools/css-syntax-patches-for-csstree@1.1.14", "", { "peerDependencies": { "css-tree": "^3.2.1" }, "optionalPeers": ["css-tree"] }, "sha512-HpbVXyrofRXpHpgkNIjU/3EWR4WJvOkO3emNK/L6X/mTJU7bGUI3AkkpoTNXznQLp0KRjLHELTGeKI5dIkI9JQ=="], + + "@csstools/css-tokenizer": ["@csstools/css-tokenizer@4.0.0", "", {}, "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.28.2", "", { "os": "android", "cpu": "arm" }, "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.2", "", { "os": "android", "cpu": "arm64" }, "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.28.2", "", { "os": "android", "cpu": "x64" }, "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.2", "", { "os": "linux", "cpu": "arm" }, "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.2", "", { "os": "linux", "cpu": "none" }, "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.2", "", { "os": "linux", "cpu": "x64" }, "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ=="], + + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.2", "", { "os": "none", "cpu": "arm64" }, "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.2", "", { "os": "none", "cpu": "x64" }, "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw=="], + + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.2", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw=="], + + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.2", "", { "os": "none", "cpu": "arm64" }, "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g=="], + + "@exodus/bytes": ["@exodus/bytes@1.15.1", "", { "peerDependencies": { "@noble/hashes": "^1.8.0 || ^2.0.0" }, "optionalPeers": ["@noble/hashes"] }, "sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q=="], + + "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], + + "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="], + + "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.6.0", "", {}, "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw=="], + + "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], + + "@napi-rs/lzma-linux-x64-gnu": ["@napi-rs/lzma-linux-x64-gnu@1.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.63.3", "", { "os": "android", "cpu": "arm" }, "sha512-w3Jnvi1ocaVm/c7yVPpfB98XeSRBMyzp6njL5MVVbGyXjpmUkN+s6Hp4t0PqhGCCaI1ZHMKXt/w0lA1RCaLVcw=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.63.3", "", { "os": "android", "cpu": "arm64" }, "sha512-uI/ESiaIbbRYAEhzy8PCUWDp1hB0bjAqM06mW9flOoNO4Q8DQpeoREhBR5Hegfl+wpXiguyJv6XSPzEN7OxyHQ=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.63.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-oxhrd1jmXLwWZ83eQYDXxuqRdkqkzrjR3JobKeuUyfdNZo11FuQIvqEOZhyIT7OBHxXoGslDDjN0cQcM6T0TqQ=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.63.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-7/YiIMghVE8DrxKvNdorAaJVdriOFgOIpdStnPx8ppx5zfTwC3jBCSEAIzB7JD5404m65THl6H93UTTVUvypmg=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.63.3", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-GXFZRRoMAytaI5z6N3Zhfw0WL18Q0M8r95D5hlC4GqE/lGk8pbSJNUBoOWDfbm6dTciqHj2nU87tI5f6XhQiOg=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.63.3", "", { "os": "freebsd", "cpu": "x64" }, "sha512-77W+8X3ddYgPxUpB8nZFQs2Mq+wc4HVlcSRtApXLjYBcnPMkttrSnU8VwKQjeWYhMsITHFs5cWBQ8vz1Q+5RHQ=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.63.3", "", { "os": "linux", "cpu": "arm" }, "sha512-FVkwK+iUC+mq+GipVK46rRVticfAPtvPUNlqlGXUDxdVk/UGjQiiiUVPUrEXdSpU2ufU0XxLGyTqDtBidDOVmg=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.63.3", "", { "os": "linux", "cpu": "arm" }, "sha512-+aGU1t3398yQOVj1Bz8o3e+KtswxAPvO+mtxtNdfXYMkXIHu7XhhkCD7/DEH9q8tF8uhDnMWvfpUKI8y1sZJsg=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.63.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-cR0kjpRXR2KJ2oQK8E2KTPtphs+b9hZ8IhTZubNryt/RsqgdOZBQ2Zq0q5UedtiIi0rs3jVhJh55RE1ZHUVGUA=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.63.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-y1RYi4Q3/9ByVWSSt9kX2ustE0B7kFYbJ6zZdVZVyqopZs3yhCTwRfrjIX4vezUJInma/Gs6BOFDJg7yZmJ0IQ=="], + + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.63.3", "", { "os": "linux", "cpu": "none" }, "sha512-DNhEA5viIj3Z5bZLE4z4oV8N5ozWqDwyt7T6KG7VdLDJ0nW+rNOYlphBl4/3HQkK75qipPLsVOfStHHOwN9WSg=="], + + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.63.3", "", { "os": "linux", "cpu": "none" }, "sha512-17gQCqrIpXBX2Cmi9/TygnVOqGbzsba/iaqcYSL8FY7lNugg+7AiYNs5c5nKWD+NRQha36Sa0CqkJqH4XVHwnQ=="], + + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.63.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-6LwVnZRIyINpdku/yOcI8Tm9YqLmhHK5emmlOOnW9tO0SYEm1FmKPcsSAGp0NBlqR2P04xaND4jvN6sTHqhq8A=="], + + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.63.3", "", { "os": "linux", "cpu": "ppc64" }, "sha512-xMUqkTXlEUtI/p5AAukMwBRr1enU3efsTeF+bskeFfk8t1C9rcC8sLREcZXmTfAXEbvRdJVSonVJez3TMlbR3w=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.63.3", "", { "os": "linux", "cpu": "none" }, "sha512-S3E94co9F9WRRqEaUoQZ38K1gCz6KiM+nL7/3ijq7fDGF3OznjS5TasgYITlvl27GQKtu4lOAOsr5MFwkijvOA=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.63.3", "", { "os": "linux", "cpu": "none" }, "sha512-1QtRDwG42x5BJI3s9mxu5rEjDnfbSnk20HQ9/ylTAYnSwYwxMVb+Vgu34wzzTQ7ogqBybebgQNUDAvZVQ38DbA=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.63.3", "", { "os": "linux", "cpu": "s390x" }, "sha512-BQhejF6ZXOpxbngiNTP12GCGQeaDVL2QXGeBVViKIYzFHM5RKxTxwUMB1fr1BeNFphFMpnRqC5QSXFSa4z6UQw=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.63.3", "", { "os": "linux", "cpu": "x64" }, "sha512-SXagRwnI2Wlwlitllu59UK/nGVbD1CKPcNqDplHwIC4BqJcpXFjD32d1R/RbuISa95HdQrZM3/7v4bKiowFaLA=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.63.3", "", { "os": "linux", "cpu": "x64" }, "sha512-2IPozoEALRCziGqE8O9KMK60PMu5TS1huv4fwoeCexj+WjmcwFtX9CTOVbfXCUqcELAubEwRFPYlzb/WvwY2HQ=="], + + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.63.3", "", { "os": "openbsd", "cpu": "x64" }, "sha512-AoxqosUHT9IX54hFn2TiN6A7d6ZKTtE6pd2bqWtqkkNJ6HJGaU6FRouGX8L1O7R/ZwsnCnpQrHzb4pDEx+UHRQ=="], + + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.63.3", "", { "os": "none", "cpu": "arm64" }, "sha512-d+CaftKgmkFBzCwezMqqy1d0QNNYugqLCMcYVQWBy5SS2YfeMP8Q8ripkgx9O8IyBXXLHrJ+aaCV4U96usv6Yg=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.63.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-xXlDF6nR1eOuXbdDy5Hl5fmtY7teUDevF/k0O7IPoZe4Tpmdv+lgdE5JRsnhQtt37ql9P0VF2kAN9a0OCZdo+Q=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.63.3", "", { "os": "win32", "cpu": "ia32" }, "sha512-YtXAgLN+JP7Ay6qG3eWhc7IHMQPzLc8r3uvhAvlJIoCz/4Q32+Bl9Fmnywidh8v1GOIMmymjovfqY9ETAtysvA=="], + + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.63.3", "", { "os": "win32", "cpu": "x64" }, "sha512-WuWtSJRNo549vzcfZyEgfqb6zeSgn1F+UE5kQ+BCjzz0W4MGCjntUHkZVc1VRuAM7+ULaSyhiPxD1spyewFvkQ=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.63.3", "", { "os": "win32", "cpu": "x64" }, "sha512-+lIKX7O0+IGe7WuhATaAMMeT7B76vfhXH/l9wLQL+nvyhbw2ohYCKIdWL56JfDu75CWt5oKRP4QFH/jkMtBquA=="], + + "@sveltejs/acorn-typescript": ["@sveltejs/acorn-typescript@1.0.13", "", { "peerDependencies": { "acorn": "^8.9.0" } }, "sha512-wgKggnhZVL9Bfx1OaKKTrYY9BFRk6C8UAkQNUcIv1+llzYrIqy+RZm5HPKzn0NpEBvTVhTqB4kQyllZywsRBRQ=="], + + "@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@6.2.4", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", "deepmerge": "^4.3.1", "magic-string": "^0.30.21", "obug": "^2.1.0", "vitefu": "^1.1.1" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-ou/d51QSdTyN26D7h6dSpusAKaZkAiGM55/AKYi+9AGZw7q85hElbjK3kEyzXHhLSnRISHOYzVge6x0jRZ7DXA=="], + + "@sveltejs/vite-plugin-svelte-inspector": ["@sveltejs/vite-plugin-svelte-inspector@5.0.2", "", { "dependencies": { "obug": "^2.1.0" }, "peerDependencies": { "@sveltejs/vite-plugin-svelte": "^6.0.0-next.0", "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-TZzRTcEtZffICSAoZGkPSl6Etsj2torOVrx6Uw0KpXxrec9Gg6jFWQ60Q3+LmNGfZSxHRCZL7vXVZIWmuV50Ig=="], + + "@types/chai": ["@types/chai@5.2.3", "", { "dependencies": { "@types/deep-eql": "*", "assertion-error": "^2.0.1" } }, "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA=="], + + "@types/deep-eql": ["@types/deep-eql@4.0.2", "", {}, "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw=="], + + "@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="], + + "@vitest/expect": ["@vitest/expect@3.2.7", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.7", "@vitest/utils": "3.2.7", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w=="], + + "@vitest/mocker": ["@vitest/mocker@3.2.7", "", { "dependencies": { "@vitest/spy": "3.2.7", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA=="], + + "@vitest/pretty-format": ["@vitest/pretty-format@3.2.7", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA=="], + + "@vitest/runner": ["@vitest/runner@3.2.7", "", { "dependencies": { "@vitest/utils": "3.2.7", "pathe": "^2.0.3", "strip-literal": "^3.0.0" } }, "sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA=="], + + "@vitest/snapshot": ["@vitest/snapshot@3.2.7", "", { "dependencies": { "@vitest/pretty-format": "3.2.7", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g=="], + + "@vitest/spy": ["@vitest/spy@3.2.7", "", { "dependencies": { "tinyspy": "^4.0.3" } }, "sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ=="], + + "@vitest/utils": ["@vitest/utils@3.2.7", "", { "dependencies": { "@vitest/pretty-format": "3.2.7", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw=="], + + "acorn": ["acorn@8.18.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ=="], + + "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + + "aria-query": ["aria-query@5.3.1", "", {}, "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g=="], + + "assertion-error": ["assertion-error@2.0.1", "", {}, "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA=="], + + "axobject-query": ["axobject-query@4.1.0", "", {}, "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="], + + "bidi-js": ["bidi-js@1.1.0", "", { "dependencies": { "require-from-string": "^2.0.2" } }, "sha512-fX1Onk0tdVPC7obPWB5EbJ1z7NVhLq4m2xZLq2YXBkxzMXIGRpNMU88n0EPgWseKl12J7zXs7qrDxPK4sRs2fg=="], + + "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], + + "chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="], + + "check-error": ["check-error@2.1.3", "", {}, "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA=="], + + "clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="], + + "css-tree": ["css-tree@3.2.1", "", { "dependencies": { "mdn-data": "2.27.1", "source-map-js": "^1.2.1" } }, "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA=="], + + "cssstyle": ["cssstyle@5.3.7", "", { "dependencies": { "@asamuzakjp/css-color": "^4.1.1", "@csstools/css-syntax-patches-for-csstree": "^1.0.21", "css-tree": "^3.1.0", "lru-cache": "^11.2.4" } }, "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ=="], + + "data-urls": ["data-urls@6.0.1", "", { "dependencies": { "whatwg-mimetype": "^5.0.0", "whatwg-url": "^15.1.0" } }, "sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ=="], + + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + + "decimal.js": ["decimal.js@10.6.0", "", {}, "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="], + + "deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="], + + "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], + + "devalue": ["devalue@5.9.2", "", {}, "sha512-po4PAY5c53tw5XMocSnf8A/5OHhbbUftpr93aEN6BBoAdntUmK7vu7wOATqvt7cXO7m1Cl4gMVn6p7n6n4mj0w=="], + + "entities": ["entities@8.1.0", "", {}, "sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA=="], + + "es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="], + + "esbuild": ["esbuild@0.28.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.2", "@esbuild/android-arm": "0.28.2", "@esbuild/android-arm64": "0.28.2", "@esbuild/android-x64": "0.28.2", "@esbuild/darwin-arm64": "0.28.2", "@esbuild/darwin-x64": "0.28.2", "@esbuild/freebsd-arm64": "0.28.2", "@esbuild/freebsd-x64": "0.28.2", "@esbuild/linux-arm": "0.28.2", "@esbuild/linux-arm64": "0.28.2", "@esbuild/linux-ia32": "0.28.2", "@esbuild/linux-loong64": "0.28.2", "@esbuild/linux-mips64el": "0.28.2", "@esbuild/linux-ppc64": "0.28.2", "@esbuild/linux-riscv64": "0.28.2", "@esbuild/linux-s390x": "0.28.2", "@esbuild/linux-x64": "0.28.2", "@esbuild/netbsd-arm64": "0.28.2", "@esbuild/netbsd-x64": "0.28.2", "@esbuild/openbsd-arm64": "0.28.2", "@esbuild/openbsd-x64": "0.28.2", "@esbuild/openharmony-arm64": "0.28.2", "@esbuild/sunos-x64": "0.28.2", "@esbuild/win32-arm64": "0.28.2", "@esbuild/win32-ia32": "0.28.2", "@esbuild/win32-x64": "0.28.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA=="], + + "esm-env": ["esm-env@1.2.2", "", {}, "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA=="], + + "esrap": ["esrap@2.3.7", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, "peerDependencies": { "@typescript-eslint/types": "^8.2.0" }, "optionalPeers": ["@typescript-eslint/types"] }, "sha512-n2nf7fZR3c9yXf0BPEuHuXqT+KW0SJVj4cN5FMEkpCZ3scLjOQWpiccyCxVzCC2q1wubTghuEGzngJY/7Ah0Ow=="], + + "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + + "expect-type": ["expect-type@1.4.0", "", {}, "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA=="], + + "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "html-encoding-sniffer": ["html-encoding-sniffer@6.0.0", "", { "dependencies": { "@exodus/bytes": "^1.6.0" } }, "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg=="], + + "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], + + "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + + "is-potential-custom-element-name": ["is-potential-custom-element-name@1.0.1", "", {}, "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="], + + "is-reference": ["is-reference@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.6" } }, "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw=="], + + "js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="], + + "jsdom": ["jsdom@27.4.0", "", { "dependencies": { "@acemir/cssom": "^0.9.28", "@asamuzakjp/dom-selector": "^6.7.6", "@exodus/bytes": "^1.6.0", "cssstyle": "^5.3.4", "data-urls": "^6.0.0", "decimal.js": "^10.6.0", "html-encoding-sniffer": "^6.0.0", "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.6", "is-potential-custom-element-name": "^1.0.1", "parse5": "^8.0.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", "tough-cookie": "^6.0.0", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^8.0.0", "whatwg-mimetype": "^4.0.0", "whatwg-url": "^15.1.0", "ws": "^8.18.3", "xml-name-validator": "^5.0.0" }, "peerDependencies": { "canvas": "^3.0.0" }, "optionalPeers": ["canvas"] }, "sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ=="], + + "locate-character": ["locate-character@3.0.0", "", {}, "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="], + + "loupe": ["loupe@3.2.1", "", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="], + + "lru-cache": ["lru-cache@11.5.2", "", {}, "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g=="], + + "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + + "mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "nanoid": ["nanoid@3.3.19", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug=="], + + "obug": ["obug@2.2.1", "", {}, "sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q=="], + + "parse5": ["parse5@8.0.1", "", { "dependencies": { "entities": "^8.0.0" } }, "sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw=="], + + "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + + "pathval": ["pathval@2.0.1", "", {}, "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@4.0.7", "", {}, "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA=="], + + "postcss": ["postcss@8.5.28", "", { "dependencies": { "nanoid": "^3.3.18", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A=="], + + "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], + + "rollup": ["rollup@4.63.3", "", { "dependencies": { "@types/estree": "1.0.9" }, "optionalDependencies": { "@napi-rs/lzma-linux-x64-gnu": "1.5.1", "@rollup/rollup-android-arm-eabi": "4.63.3", "@rollup/rollup-android-arm64": "4.63.3", "@rollup/rollup-darwin-arm64": "4.63.3", "@rollup/rollup-darwin-x64": "4.63.3", "@rollup/rollup-freebsd-arm64": "4.63.3", "@rollup/rollup-freebsd-x64": "4.63.3", "@rollup/rollup-linux-arm-gnueabihf": "4.63.3", "@rollup/rollup-linux-arm-musleabihf": "4.63.3", "@rollup/rollup-linux-arm64-gnu": "4.63.3", "@rollup/rollup-linux-arm64-musl": "4.63.3", "@rollup/rollup-linux-loong64-gnu": "4.63.3", "@rollup/rollup-linux-loong64-musl": "4.63.3", "@rollup/rollup-linux-ppc64-gnu": "4.63.3", "@rollup/rollup-linux-ppc64-musl": "4.63.3", "@rollup/rollup-linux-riscv64-gnu": "4.63.3", "@rollup/rollup-linux-riscv64-musl": "4.63.3", "@rollup/rollup-linux-s390x-gnu": "4.63.3", "@rollup/rollup-linux-x64-gnu": "4.63.3", "@rollup/rollup-linux-x64-musl": "4.63.3", "@rollup/rollup-openbsd-x64": "4.63.3", "@rollup/rollup-openharmony-arm64": "4.63.3", "@rollup/rollup-win32-arm64-msvc": "4.63.3", "@rollup/rollup-win32-ia32-msvc": "4.63.3", "@rollup/rollup-win32-x64-gnu": "4.63.3", "@rollup/rollup-win32-x64-msvc": "4.63.3", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-1i2XreiAoMMXuPGD6Msj2xWrMMkHojNRKivInxGQcg7/1KuPuYlfUutLyh4drnOxUTHX9cHI4wFoat8D/NKaBw=="], + + "saxes": ["saxes@6.0.0", "", { "dependencies": { "xmlchars": "^2.2.0" } }, "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA=="], + + "siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], + + "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="], + + "strip-literal": ["strip-literal@3.1.0", "", { "dependencies": { "js-tokens": "^9.0.1" } }, "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg=="], + + "svelte": ["svelte@5.57.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.10", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "devalue": "^5.8.1", "esm-env": "^1.2.1", "esrap": "^2.2.12", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-NdbDn7fl4be1ViUG0oq/lvG6OZy3oENolV2ONjiqqsfVoeAfzaQAKUcEX3MrQod/Bebv1PgwET9rfXhgn9s4Kg=="], + + "symbol-tree": ["symbol-tree@3.2.4", "", {}, "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="], + + "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], + + "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], + + "tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="], + + "tinypool": ["tinypool@1.1.1", "", {}, "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg=="], + + "tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="], + + "tinyspy": ["tinyspy@4.0.6", "", {}, "sha512-u8KszXvGfU68hVcZpRHKG28T0krMuv2G5nDhiHaMLen/gIuFEgIJhaJuO69qjnXg5paSrbPMFfx3brNuN8eVSg=="], + + "tldts": ["tldts@7.4.13", "", { "dependencies": { "tldts-core": "^7.4.13" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-iHtaIWWIbMDkCeJdTBzZFGgbluE5J+oHlb2g7+oAz1S1gpuVpabRZdQyd471Vl8UUkcz2vXSL8xZH2kyCe8tfA=="], + + "tldts-core": ["tldts-core@7.4.13", "", {}, "sha512-mbYsrih5FRtGxs3Usvl/PqwJsNpp+jsmrdFviiK02teHDG0/HebBG/pqCylje3kzgXYzuLoHJF/0mz9W53t8Xg=="], + + "tough-cookie": ["tough-cookie@6.0.2", "", { "dependencies": { "tldts": "^7.0.5" } }, "sha512-exgYmnmL/sJpR3upZfXG5PoatXQii55xAiXGXzY+sROLZ/Y+SLcp9PgJNI9Vz37HpQ74WvDcLT8eqm+kV3FzrA=="], + + "tr46": ["tr46@6.0.0", "", { "dependencies": { "punycode": "^2.3.1" } }, "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "vite": ["vite@7.3.6", "", { "dependencies": { "esbuild": "^0.27.0 || ^0.28.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.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" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg=="], + + "vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="], + + "vitefu": ["vitefu@1.1.3", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" }, "optionalPeers": ["vite"] }, "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg=="], + + "vitest": ["vitest@3.2.7", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.7", "@vitest/mocker": "3.2.7", "@vitest/pretty-format": "^3.2.7", "@vitest/runner": "3.2.7", "@vitest/snapshot": "3.2.7", "@vitest/spy": "3.2.7", "@vitest/utils": "3.2.7", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.2.7", "@vitest/ui": "3.2.7", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "./vitest.mjs" } }, "sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg=="], + + "w3c-xmlserializer": ["w3c-xmlserializer@5.0.0", "", { "dependencies": { "xml-name-validator": "^5.0.0" } }, "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA=="], + + "webidl-conversions": ["webidl-conversions@8.0.1", "", {}, "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ=="], + + "whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="], + + "whatwg-url": ["whatwg-url@15.1.0", "", { "dependencies": { "tr46": "^6.0.0", "webidl-conversions": "^8.0.0" } }, "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g=="], + + "why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="], + + "ws": ["ws@8.21.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw=="], + + "xml-name-validator": ["xml-name-validator@5.0.0", "", {}, "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg=="], + + "xmlchars": ["xmlchars@2.2.0", "", {}, "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="], + + "zimmerframe": ["zimmerframe@1.1.5", "", {}, "sha512-msJxIvYDYcoNL+PJsu+7qmpDWsYmAxTY+2TNYXXF0hzBzBk0BMecOqDOG/EckUoKCuKwObfbugIl8QpqHDXeFA=="], + + "data-urls/whatwg-mimetype": ["whatwg-mimetype@5.0.0", "", {}, "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw=="], + } +} diff --git a/ui/package.json b/ui/package.json new file mode 100644 index 0000000..661e719 --- /dev/null +++ b/ui/package.json @@ -0,0 +1,20 @@ +{ + "name": "@barkstack/pawsql-ui", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "test": "vitest run" + }, + "dependencies": { + "svelte": "^5.38.10" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^6.2.0", + "jsdom": "^27.0.0", + "typescript": "^5.9.2", + "vite": "^7.1.5", + "vitest": "^3.2.4" + } +} diff --git a/ui/src/PawSQL.svelte b/ui/src/PawSQL.svelte new file mode 100644 index 0000000..7c7f66f --- /dev/null +++ b/ui/src/PawSQL.svelte @@ -0,0 +1,113 @@ + + + + +
+
+
+ PostgreSQL routing +

PawSQL

+

Secure, service-aware PostgreSQL routing for Barkstack workloads.

+
+
+
Status{error ? 'Degraded' : (status?.status ?? 'Connecting')}
+
+
+ + {#if route !== '/'} + + {/if} + + {#if loading} +
+ {:else if error} + + {:else} +
+
+ Connection endpoint +
{status?.endpoint}
+

Use a configured database hostname or database name to select a route.

+
+
+ Configured routes{status?.routes.length ?? 0}

Routes loaded from this PawSQL release configuration.

+
+
+ Router stateRunning

PostgreSQL listener and management UI are online.

+
+
+ +
+
Routing table

{route.startsWith('/routes') ? 'All configured routes' : 'Active configuration'}

{#if route === '/'}{/if}
+ {#if !status?.routes.length} +
No database routes are configured.
+ {:else} +
+
DatabaseHostnameBackendStatus
+ {#each status.routes as configuredRoute (configuredRoute.name)} +
{configuredRoute.name}{configuredRoute.hostname || 'Database name'}{configuredRoute.managed ? 'Managed PostgreSQL' : 'External upstream'}Ready
+ {/each} +
+ {/if} +
+ {/if} +
+ + diff --git a/ui/src/entry.ts b/ui/src/entry.ts new file mode 100644 index 0000000..5a3fa94 --- /dev/null +++ b/ui/src/entry.ts @@ -0,0 +1 @@ +import './PawSQL.svelte'; diff --git a/ui/src/events.test.ts b/ui/src/events.test.ts new file mode 100644 index 0000000..54b138c --- /dev/null +++ b/ui/src/events.test.ts @@ -0,0 +1,22 @@ +import { describe, expect, it, vi } from 'vitest'; +import { dispatchNavigate, dispatchNotify } from './events'; + +describe('Barkstack host events', () => { + it('requests host-owned navigation with a composed custom event', () => { + const target = new EventTarget(); + const listener = vi.fn(); + target.addEventListener('barkstack:navigate', listener); + dispatchNavigate(target, '/pawsql/routes'); + const event = listener.mock.calls[0][0] as CustomEvent; + expect(event.detail).toEqual({ path: '/pawsql/routes' }); + expect(event.composed).toBe(true); + }); + + it('requests a global notification', () => { + const target = new EventTarget(); + let detail: unknown; + target.addEventListener('barkstack:notify', (event) => { detail = (event as CustomEvent).detail; }); + dispatchNotify(target, 'success', 'Endpoint copied'); + expect(detail).toEqual({ level: 'success', message: 'Endpoint copied' }); + }); +}); diff --git a/ui/src/events.ts b/ui/src/events.ts new file mode 100644 index 0000000..c3f203f --- /dev/null +++ b/ui/src/events.ts @@ -0,0 +1,15 @@ +export function dispatchNavigate(target: EventTarget, path: string): void { + target.dispatchEvent(new CustomEvent('barkstack:navigate', { + bubbles: true, + composed: true, + detail: { path } + })); +} + +export function dispatchNotify(target: EventTarget, level: 'success' | 'info' | 'warning' | 'error', message: string): void { + target.dispatchEvent(new CustomEvent('barkstack:notify', { + bubbles: true, + composed: true, + detail: { level, message } + })); +} diff --git a/ui/tsconfig.json b/ui/tsconfig.json new file mode 100644 index 0000000..5df25e9 --- /dev/null +++ b/ui/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "allowJs": true, + "checkJs": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true, + "module": "ESNext", + "moduleResolution": "Bundler", + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strict": true, + "target": "ES2022" + }, + "include": ["src/**/*.ts", "src/**/*.svelte", "vite.config.ts"] +} diff --git a/ui/vite.config.ts b/ui/vite.config.ts new file mode 100644 index 0000000..5f362ff --- /dev/null +++ b/ui/vite.config.ts @@ -0,0 +1,18 @@ +import { svelte } from '@sveltejs/vite-plugin-svelte'; +import { defineConfig } from 'vite'; +import { resolve } from 'node:path'; + +export default defineConfig({ + plugins: [svelte({ compilerOptions: { customElement: true } })], + build: { + lib: { + entry: resolve(__dirname, 'src/entry.ts'), + formats: ['es'], + fileName: () => 'assets/entry.js' + }, + outDir: '../internal/adminui/dist', + emptyOutDir: true, + target: 'es2022' + }, + test: { environment: 'jsdom' } +});