From 4ae2a4ac53e267c9ce91aa6a1c5865400261e4f4 Mon Sep 17 00:00:00 2001 From: Josh Siviour Date: Mon, 18 May 2026 15:48:04 +1000 Subject: [PATCH] feat(elbv2): QEMU microvm direct-boot for LB system instances (#228) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(vm): direct-boot foundations + config/input extensions + image build pipeline vm package (mulga-siv-62): - Add KernelImage, Initrd, KernelCmdline, FwCfg/FwCfgEntry to vm.Config - Emit -kernel/-initrd/-append/-fw_cfg args when fields set - Relax drive invariant: accept kernel image in place of drives - Add devices.go: IsMMIO predicate, NetDevice/BlkDevice/RngDevice helpers - Refactor lifecycle.go + network_helpers.go call sites to use helpers - shutdown.go: os.Remove fw_cfg tmpfiles after QEMU exits - Add devices_test.go, microvm_test.go; extend vm_test.go config/input extensions (mulga-siv-63): - Add MicrovmConfig{ELBv2Enabled, ImagePath} to DaemonConfig - ImagePath falls back to /usr/share/spinifex/microvm when empty - Add commented [microvm] section to spinifex.toml template - Add DirectBoot bool + NICs []NICConfig to SystemInstanceInput image build pipeline (mulga-siv-64): - scripts/build-microvm-image.sh: Alpine chroot build producing vmlinuz + initramfs.cpio.gz - build/microvm/init.sh: fw_cfg-driven PID 1 init (mounts, modprobe, NIC config, lb-agent-env, ca-cert) - build/microvm/inittab: BusyBox init with lb-agent respawn - make build-microvm-image target - setup.sh: install microvm/* to /usr/share/spinifex/microvm/ - .gitignore: exclude built vmlinuz + initramfs.cpio.gz artifacts * feat(daemon): direct-boot launch path for microvm system instances When SystemInstanceInput.DirectBoot=true: - Skip GetAMIConfig and GenerateVolumes - Build vm.Config directly (no buildBaseVMConfig, no PCIe root ports) - MachineType=microvm,x-option-roms=off,pic=off,pit=off,rtc=on,acpi=on,isa-serial=on - Resolve kernel/initrd from Microvm.ImagePath config field - Serialise NICs to three fw_cfg tmpfiles (netcfg, lb-agent-env, ca-cert) - Validate exactly one NICConfig.IsDefault=true before writing netcfg blob - Shutdown path cleans up tmpfiles via existing Config.FwCfg iteration PC-machine path (DirectBoot=false) unchanged. Closes mulga-siv-65 * feat(elbv2): wire microvm.elbv2_enabled flag into ELBv2 service When ELBv2Enabled=true: - Drop lbVMUserData cloud-config; emit KEY=value LBAgentEnv blob instead - Set SystemInstanceInput.DirectBoot=true; omit ImageID - Populate NICs []NICConfig (index 0=primary ENI IsDefault, 1=mgmt, 2+=extra ENIs) - Validate exactly one IsDefault NIC at service layer When ELBv2Enabled=false: existing PC-machine path unchanged. Adds buildLBAgentEnv, buildMicrovmNICs, subnetCIDRForIP, subnetGatewayIP helpers. Tests in arn_test.go cover both flag-on and flag-off paths. Closes mulga-siv-66 * test(daemon,vm): add unit tests for direct-boot helpers to meet diff coverage threshold * feat(daemon): Phase 1 perf instrumentation + e2e runner microvm flag - Log t1→t2 boot timing via slog on the direct-boot path - measureQEMURSSMiB helper reads /proc//status (tested) - Gate constants: phase1BootGateMs=500, phase1RSSGateMiB=25 - run-lb-e2e.sh: --microvm flag, dual-path CI annotation, density test note Closes mulga-siv-67 * fix(build): remove busybox-initscripts — not in Alpine 3.20, not needed * fix(microvm): end-to-end fixes for direct-boot LB path Serial output was silent (x-option-roms=off suppresses BIOS serial init); fixed by removing it from the machine string and using -serial chardev:console0 to attach to the machine-created ISA serial device instead of adding a duplicate isa-serial device (which would create ttyS1 while kernel uses ttyS0). virtio-net interfaces were invisible to the kernel because QEMU's auto-kernel-cmdline does not append virtio_mmio.device= params when -append is used. Fixed by generating explicit virtio_mmio.device=0x200@0xfebNNNNN:N params for each NIC in KernelCmdline, and modprobing virtio_mmio + virtio_net in init.sh. sys.micro bumped to 512 MiB — 128 MiB caused kernel OOM during initramfs decompression (~68 MiB uncompressed). BusyBox init ::respawn: entries do not source or export env files; fixed inittab to use set -a; . /etc/conf.d/lb-agent; set +a before exec. wireLBAgentConfig was documented as reading the CA cert but never set elbv2Service.CACert; lb-agent TLS handshakes to AWSGW failed with x509: certificate signed by unknown authority. Fixed by reading d.config.NATS.CACert (same local CA that signs the AWSGW server cert) and assigning to elbv2Service.CACert so writeFwCfgBlobs writes a non-empty cacert blob into fw_cfg. Adds vm_test TestExecute_MicrovmFileChardev and updates lifecycle_test to assert SerialSocket is intentionally empty on direct-boot VMs. * fix(build): auto-detect docker/podman when apk unavailable for microvm image build * fix(build): create /dev/console and /dev/null as proper device nodes in initramfs tar extraction without root silently demotes device files to 0-byte regular files (mknod requires CAP_MKNOD). The kernel opens /dev/console when wiring init's stdio to the serial console; a regular file there causes all init output to be silently discarded to RAM — the VM appears stuck at 'Run /init as init process' with no subsequent console output and lb-agent never heartbeats. Fix: after rootfs population, wipe /dev and recreate console (c 5 1) and null (c 1 3) via sudo mknod. devtmpfs provides all other devices at runtime once init.sh mounts it. * fix(microvm): fix mgmt NIC routing for all LB schemes Two bugs prevented lb-agent from reaching the AWSGW via the mgmt interface: 1. RouteDst/RouteVia swapped — resolveMgmtRoute returns (gateway, target) but buildMicrovmNICs assigned them as (Dst=gateway, Via=target), producing 'ip route add 10.15.8.1 via 192.168.1.33' instead of the correct 'ip route add 192.168.1.33 via 10.15.8.1'. 2. NIC[1] MAC and CIDR never filled — the daemon allocates mgmt IP/MAC after buildMicrovmNICs returns, but didn't inject them into input.NICs[1] before calling writeFwCfgBlobs, leaving NIC1_MAC= empty in the netcfg blob and skipping interface setup in init.sh entirely. Also extends mgmt routing to internet-facing scheme in the microvm path: VPC SNAT is not reliable across all VPC topologies for control-plane heartbeats; mgmt is always a direct L2 path to the host. * feat(microvm): Phase 2 kernel stripping + boot optimisation - cpu: switch to host,-pmu (disable PMU — not needed in microvm guest) - machine type: make isa-serial configurable via microvm.isa_serial config field; default true (on) preserves console log path - build: strip unused kernel modules (USB, IDE, ATA, GPU, media, input, HID, bluetooth, staging, sound, wireless) from initramfs before cpio - build: add Phase 2 artifact size gate — fail if vmlinuz + initramfs.cpio.gz exceeds MICROVM_ARTIFACT_MAX_MiB (default 50 MiB); override via env var during development - perf: add phase2BootGateMs=300 and phase2ArtifactGateMiB=50 constants with canary tests to catch unintentional gate changes - tests: cover buildMicrovmNICs nil-VPC and extra-ENI paths - tests: cover microvmMachineType nil/true/false branches * fix(build): use find-based virtio+fw_cfg module keep-list in initramfs strip The directory-only keep-list (drivers/virtio, drivers/firmware) missed virtio_net.ko which lives in drivers/net/, virtio_blk in drivers/block/, and virtio-rng in drivers/char/hw_random/. Switch to find-based approach: collect all virtio*.ko* and *fw_cfg*.ko* regardless of subdirectory, then restore them into their original relative paths under kernel/. Artifacts now: 42 MiB (vmlinuz 11 MiB + initramfs 31 MiB), gate passes. * fix(build): keep failover modules in initramfs strip virtio_net depends on net_failover/failover for live-migration support. Stripping them left virtio_net with unresolved symbols (net_failover_create/destroy), so the module failed to load and the guest came up with only lo. init.sh then skipped every NIC ("no interface found for MAC ..."), leaving lb-agent with no network path to AWSGW and the LB stuck in provisioning. Add *failover*.ko* to the keep-list. Image size unchanged at 42 MiB (under the 50 MiB Phase 2 gate). ELBv2 e2e now reaches active and 2/2 targets healthy for both ALB and NLB internal LBs. * fix(daemon): restore slog default after viperblock.New mutates it viperblock.New unconditionally calls vb.SetDebug, which calls slog.SetDefault with a TextHandler at LevelError — globally silencing every slog.Info and slog.Warn in the caller process for the rest of its life. Discovered while validating microvm Phase 2 (mulga-siv-68): the daemon stopped emitting Info logs the moment the first customer VM with volumes launched, hiding direct-boot timing, LaunchSystemInstance completed, and CreateLoadBalancer completed lines that we need for boot-time tuning. Workaround in newViperblock: re-install an Info-level TextHandler on os.Stderr after each viperblock.New call. Also drop the three explicit vb.SetDebug(false) calls in prepareRootVolume / prepareEFIVolume / prepareCloudInitVolume — they were no-ops (viperblock.New already runs SetDebug internally) and each one re-triggered the global mutation we are trying to undo. Proper fix is in viperblock itself — tracked as mulga-siv-70: SetDebug should not call slog.SetDefault. Until then, this restore call is the shortest path to getting the daemon's observability back so we can measure t1_to_t2_ms and tune Phase 2. Preflight note: golangci-lint not available on this dev host, so the project preflight target cannot run end-to-end. Verified with go vet ./spinifex/handlers/ec2/instance/... (clean) and go test ./spinifex/handlers/ec2/instance/... (pass). * perf(microvm): hit Phase 2 boot/memory gates t1→t2 hypervisor: 3224 ms → 264 ms (12×). 128 MiB guest now boots cleanly without OOM, reverting the temporary 512 MiB bump. Root causes: 1. build-microvm-image.sh staged the entire chroot into the cpio without dropping /boot, embedding a duplicate vmlinuz, Alpine's stock initramfs-virt, System.map, and a "boot → ." symlink loop (~25 MiB). Decompression peak exceeded 128 MiB. Strip /boot after the kernel is copied out, before the cpio. Initramfs drops from 31 MiB → 11 MiB (53 MiB → 28 MiB uncompressed); total artifact 42 MiB → 22 MiB. 2. vm/lifecycle.go burned 3 s of fixed sleep on every direct-boot launch: 2 s nbdkit pre-exec wait (no nbdkit on direct-boot) and 1 s post-fork settle (QEMU binds QMP within ~10 ms when there is no firmware, ROM, or block layer). Both extracted to directBoot-aware helpers — nbdkitPreExecWait collapses to 0, and qemuStartSettleWait to 50 ms. 3. KernelCmdline only carried `console=ttyS0 virtio_mmio.device=…`. Added boot-time perf flags: quiet loglevel=3 (silence printk over 115200-baud isa-serial), mitigations=off (KVM guest on trusted host, single-tenant LB workload), tsc=reliable, no_timer_check, reboot=t, i8042.{nopnp,noaux,nokbd} (microvm has no PS/2). 4. init.sh dropped modprobe virtio_mmio (built-in: CONFIG_VIRTIO_MMIO=y) and tightened polling: fw_cfg/iface waits go from 10 × 200 ms (up to 2 s) to 5 × 20 ms (up to 100 ms). Phase 2 gates: - t1→t2 ≤ 300 ms ✅ 264 ms / 281 ms - artifact ≤ 50 MiB ✅ 22 MiB (gate already in build script) - ELBv2 e2e green ✅ 32/33 (pre-existing client-VM failure, unrelated to microvm path) * build(microvm): wire build into deploy + distro + release pipeline Adds install-microvm Makefile target (with grouped-target staleness detection on vmlinuz/initramfs.cpio.gz), wires it into dev-install.sh and reset-dev-env.sh, makes 'make deploy' reinstall artifacts when present, and makes 'make distro-amd64' stage build/microvm/* into the release tarball staging dir. arm64 distro stays unchanged (no aarch64 microvm artifact yet — Phase 4). Release workflow gains a setup-go step and a 'make build-microvm-image' step before 'make distro-amd64' on the amd64 runner so the resulting tarball includes the kernel + initramfs without a manual copy. Precursor for the Phase 3 PC-machine LB removal (mulga-siv-69). Closes mulga-siv-71. * build(ansible): include microvm artifacts in build role tarball Adds a build-microvm-image task to the ansible build role and stages build/microvm/* into the role's release tarball so the install role's setup.sh run picks them up via INSTALL_SPINIFEX_TARBALL. Skipped gracefully when the build script is absent (older branches without direct-boot LB wiring). * feat(config): enable microvm direct-boot LB path by default Uncomments the [nodes..daemon.microvm] section in the generated spinifex.toml template and sets elbv2_enabled = true so all new clusters bring up ELBv2 LBs via the direct-boot microvm path. Operators can opt back to the legacy PC-machine path by flipping the flag to false in the rendered config. Required for end-to-end CI on this branch to exercise the direct-boot path. Existing clusters' configs are unchanged (the template only affects fresh 'spx admin init' renders). * fix(microvm): bootstrap apk.static when no host rootfs tool exists Self-hosted CI runners and the GitHub-hosted ubuntu-24.04 image often have none of apk, docker, or podman installed. apk-tools is not in the Debian 13 (trixie) repositories. Without one of these the rootfs build fails up front with 'no rootfs build tool available'. When all three are absent, fetch apk-tools-static from the configured Alpine mirror, extract it to a tempdir, and prepend it to PATH so the existing native-apk strategy below picks it up transparently. Requires only curl + tar, both of which are present on every CI runner that can already check out source. No-op when apk, docker, or podman is already present. Unblocks https://github.com/mulgadc/spinifex/actions/runs/25988830244 * revert: drop apk.static bootstrap in build-microvm-image Reverts 0bd76b7. Self-hosted runners will get docker.io installed out of band; existing Strategy 2 (docker run alpine:3.20) handles the rootfs build without host sudo or unsigned package install. * docs(workbook): drop lb-alpine import for microvm direct-boot LB LBs now launch via direct-boot QEMU microvm using kernel + initramfs bundled at /usr/share/spinifex/microvm/, so the legacy lb-alpine system AMI import is no longer required. * fix(daemon): own tap devices by daemon user so QEMU can attach without CAP_NET_ADMIN When the daemon runs non-root (production: User=spinifex-daemon), child QEMU processes inherit that uid but lack CAP_NET_ADMIN. The kernel's tun attach check then requires the tap owner uid to match the caller's euid. Without the `user` flag, `ip tuntap add` defaults to root:root and qemu's TUNSETIFF fails with EPERM ("could not configure /dev/net/tun: Operation not permitted"). Surfaced by the e2e-nightly cell-17 microvm LB launch on the ci-pseudo runner where the kernel enforces strictly; legacy EC2 launches on ci-single runners happened to attach successfully despite the same code path. Adding `user $current group $gid` to `ip tuntap add` ensures the tap is owned by whatever uid the daemon (and its qemu children) run as. Root daemons skip the flag — they have CAP_NET_ADMIN ambient. * fix(e2e): redirect lb probe chatter to stderr so stalls are visible test_http_from / test_tcp_from echoed progress to stdout, which the callers captured into *_OK vars via $(...). Result: 6+ minute retry loops ran silently in CI, and the "$ok" comparison never matched "true" because the captured value contained the full multi-line chatter. Reachability pass/fail counters were also lost in the subshell. Redirect helper output to stderr, leave only the true/false flag on stdout, and move pass/fail to the caller so they actually count. * fix(microvm): don't /32 AdvertiseIP via mgmt for internet-facing single-node buildMicrovmNICs overrode resolveMgmtRoute's deliberate empty return for the single-node internet-facing case by falling back to (MgmtBridgeIP, AdvertiseIP). That installed a /32 route to AdvertiseIP via the mgmt NIC inside the LB microvm. On single-node where the AWSGW host IP equals the WAN client IP, the /32 also catches reply traffic for inbound HTTP/TCP to the LB's floating IP — replies leave via the mgmt NIC with src=data-NIC IP, the host kernel drops the asymmetric flow, and same-chassis ingress hangs. resolveMgmtRoute already encodes the correct policy: - multi-node any scheme → explicit MgmtRoute{Gateway,Target} - single-node internal → fallback to (MgmtBridgeIP, AdvertiseIP) - single-node internet-facing → empty (reach AWSGW via VPC SNAT) Honor it. Matches the legacy lbVMUserData path, whose own comment flagged the stolen-WAN-return-path symptom this introduced. Test covers all three branches. * feat(ansible): dev-deploy playbook for in-place artifact swap Fills the gap between ansible-dev-install (skips when already installed) and ansible-dev-reset (full teardown + reinstall + smoketest). Mirrors Makefile `deploy` target: rebuild + replace binaries and microvm artifacts on a running node, restart spinifex.target, wait for awsgw. Skips setup.sh (no user/dir/systemd-unit changes) and smoketest so iteration is fast. Use ansible-dev-reset when changing systemd units, helper scripts, logrotate, or setup.sh itself. Adds: - roles/deploy/tasks/main.yml — install spx + nbdkit plugin + microvm artifacts, with plugindir auto-detection via `nbdkit --dump-config`. - playbooks/dev-deploy.yml — chains build + deploy roles. - Makefile ansible-dev-deploy target. - README playbook table + "when to use which" guidance. * chore(microvm): remove legacy LB Alpine image build pipeline Phase 3 microvm removal — strip the PC-machine LB image build artifacts that direct-boot no longer needs. The microvm initramfs already carries lb-agent + HAProxy via build-microvm-image, so the lb.conf manifest, lb-setup.sh chroot script, build-lb-image target, dev-install / reset-dev-env import steps, and ansible LB-image tasks all become dead. build-system-image stays — other manifests (e.g. GPU images) still use it. * refactor(microvm): remove legacy PC-machine LB boot path Phase 3 — direct-boot becomes the only ELBv2 LB launch path. - Drop SystemInstanceInput.DirectBoot / ImageID / UserData (every LB caller set DirectBoot=true; legacy cloud-init userdata is gone). - Drop ELBv2ServiceImpl.lbVMUserData, systemAMI* fields, SetSystemAMIFunc, getSystemAMI, and the lazy-AMI wiring in daemon.startCluster. - Collapse CreateLoadBalancer to a single direct-boot launch input. - Collapse daemon.LaunchSystemInstance: drop AMI validation, ImageID on RunInstancesInput, UserData base64 encode, GenerateVolumes branch. buildDirectBootConfig hardcodes /usr/share/spinifex/microvm and isa-serial=on (microvmMachineType no longer takes a flag). - Drop MicrovmConfig from config.DaemonConfig and the [daemon.microvm] section from the spinifex.toml template. - Prune dead tests (lbVMUserData_*, PCMachine_Unchanged, AMI resolver paths) and refresh stale comments that still mentioned lbVMUserData. ARM hosts have no LB launch path until Phase 4 adds direct-boot on virt — CreateLoadBalancer on aarch64 fails naturally at QEMU exec. * docs: drop lb-alpine catalog entry from cluster setup guide LB system instances no longer use an AMI — direct-boot microvm artifacts ship in the spinifex package. * feat(ui): remove LB image import banner + LB-AMI gating Direct-boot microvm artifacts ship in the spinifex package, so the LB system AMI no longer exists — the "Load balancer image not imported" banner and the Create-button disable on the LB list / wizard pages can never fire. Strip: - lb-image-missing-banner.tsx component - hasLbImage / isLbImage / LB_IMAGE_NAME / LB_MANAGED_BY_VALUE from system-managed.ts (isSystemManagedImage stays — still used by the EC2 Images pages to hide system AMIs) - Banner gating + ec2ImagesQueryOptions imports from the LB list and wizard pages - The corresponding tests that asserted the banner appears * revert: restore lb.conf + lb-setup.sh for mulga install pipeline Phase 3 microvm removal (commit 6313d74) deleted these too early — the mulga install/iso artifact builders (scripts/tofu-cluster/build-install -artifacts.sh, scripts/tofu-iso/build-iso-artifacts.sh) still invoke scripts/build-system-image.sh scripts/images/lb.conf, breaking e2e with "ERROR: Manifest not found: scripts/images/lb.conf". Restore both files verbatim so the legacy pipeline keeps building until the mulga-side migration to microvm-only artifacts lands post-merge. --- .github/workflows/release.yml | 8 + .gitignore | 2 + Makefile | 47 ++- build/microvm/init.sh | 56 +++ build/microvm/inittab | 4 + .../setting-up-your-cluster/README.md | 1 - docs/terraform-workbooks/nginx-alb/README.md | 14 +- scripts/ansible/README.md | 11 +- scripts/ansible/playbooks/dev-deploy.yml | 14 + scripts/ansible/roles/build/tasks/main.yml | 20 +- scripts/ansible/roles/deploy/tasks/main.yml | 148 ++++++++ scripts/ansible/roles/init/tasks/main.yml | 14 - scripts/ansible/vars/defaults.yml | 4 - scripts/build-microvm-image.sh | 261 ++++++++++++++ scripts/dev-install.sh | 5 +- scripts/reset-dev-env.sh | 7 +- scripts/setup.sh | 7 + spinifex/daemon/daemon.go | 51 ++- spinifex/daemon/daemon_system_instance.go | 274 +++++++++++++-- .../daemon/daemon_system_instance_test.go | 243 +++++++++++++ spinifex/daemon/network.go | 16 +- spinifex/daemon/perf_bench_test.go | 62 ++++ spinifex/daemon/perf_helpers.go | 39 +++ .../handlers/ec2/instance/helpers_test.go | 4 +- .../handlers/ec2/instance/service_impl.go | 25 +- spinifex/handlers/elbv2/arn_test.go | 325 ++++++++++++------ spinifex/handlers/elbv2/launcher.go | 34 +- spinifex/handlers/elbv2/service_impl.go | 220 +++++++----- spinifex/handlers/elbv2/service_impl_test.go | 118 +------ .../handlers/elbv2/service_impl_vpc_test.go | 48 --- .../spinifexui/frontend/dist/assets/_id.js | 2 +- .../dist/assets/create-load-balancer.js | 2 +- .../dist/assets/create-placement-group.js | 4 +- .../dist/assets/create-target-group.js | 22 +- .../frontend/dist/assets/describe-images.js | 2 +- .../dist/assets/describe-load-balancers.js | 2 +- .../spinifexui/frontend/dist/assets/ec23.js | 2 +- .../spinifexui/frontend/dist/assets/iam3.js | 2 +- .../spinifexui/frontend/dist/assets/index.js | 4 +- .../dist/assets/lb-image-missing-banner.js | 1 - .../frontend/dist/assets/system-managed.js | 2 +- .../frontend/dist/assets/upload-button.js | 2 +- .../elbv2/lb-image-missing-banner.tsx | 19 - .../frontend/src/lib/system-managed.test.ts | 54 +-- .../frontend/src/lib/system-managed.ts | 24 +- .../-components/create-load-balancer-page.tsx | 17 - .../describe-load-balancers-page.tsx | 8 - .../create-load-balancer.test.tsx | 32 +- .../describe-load-balancers/index.test.tsx | 49 --- spinifex/vm/devices.go | 60 ++++ spinifex/vm/devices_test.go | 86 +++++ spinifex/vm/lifecycle.go | 202 +++++++---- spinifex/vm/lifecycle_test.go | 175 +++++++++- spinifex/vm/microvm_test.go | 47 +++ spinifex/vm/network_helpers.go | 4 +- spinifex/vm/shutdown.go | 7 + spinifex/vm/vm.go | 50 ++- spinifex/vm/vm_test.go | 72 +++- tests/e2e/run-lb-e2e.sh | 42 ++- 59 files changed, 2271 insertions(+), 806 deletions(-) create mode 100755 build/microvm/init.sh create mode 100644 build/microvm/inittab create mode 100644 scripts/ansible/playbooks/dev-deploy.yml create mode 100644 scripts/ansible/roles/deploy/tasks/main.yml create mode 100755 scripts/build-microvm-image.sh create mode 100644 spinifex/daemon/perf_bench_test.go create mode 100644 spinifex/daemon/perf_helpers.go delete mode 100644 spinifex/services/spinifexui/frontend/dist/assets/lb-image-missing-banner.js delete mode 100644 spinifex/services/spinifexui/frontend/src/components/elbv2/lb-image-missing-banner.tsx create mode 100644 spinifex/vm/devices.go create mode 100644 spinifex/vm/devices_test.go create mode 100644 spinifex/vm/microvm_test.go diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 788f83460..4655253d5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,6 +31,14 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.26.3' + + - name: Build microVM artifacts (lb-agent + kernel + initramfs) + run: cd spinifex && make build-microvm-image + - name: Build amd64 Tarball env: VERSION: ${{ github.ref_name }} diff --git a/.gitignore b/.gitignore index 730ec55f5..543f7417d 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,8 @@ go.work.sum # Build outputs bin/ dist/ +build/microvm/vmlinuz +build/microvm/initramfs.cpio.gz !spinifex/services/spinifexui/frontend/dist/ tmp/ *.test diff --git a/Makefile b/Makefile index 5e9cd6577..b21c3c053 100644 --- a/Makefile +++ b/Makefile @@ -79,8 +79,25 @@ ifndef IMAGE endif ./scripts/build-system-image.sh scripts/images/$(IMAGE).conf -build-lb-image: ## Build LB Alpine image - $(MAKE) build-system-image IMAGE=lb +MICROVM_OUT_DIR := build/microvm +MICROVM_ARTIFACTS := $(MICROVM_OUT_DIR)/vmlinuz $(MICROVM_OUT_DIR)/initramfs.cpio.gz +MICROVM_INPUTS := scripts/build-microvm-image.sh $(MICROVM_OUT_DIR)/init.sh $(MICROVM_OUT_DIR)/inittab bin/lb-agent + +# Grouped target — script writes both files in one run. +$(MICROVM_ARTIFACTS) &: $(MICROVM_INPUTS) + ./scripts/build-microvm-image.sh + +# Only triggers when bin/lb-agent is missing; preserves the artifact's mtime so +# build-microvm-image stays correctly stale-aware. +bin/lb-agent: + $(MAKE) build-lb-agent + +build-microvm-image: $(MICROVM_ARTIFACTS) ## Build microVM kernel + initramfs (incremental — skips when up to date) + +install-microvm: $(MICROVM_ARTIFACTS) ## Install microVM artifacts to /usr/share/spinifex/microvm/ + sudo install -d /usr/share/spinifex/microvm + sudo install -m 0644 $(MICROVM_OUT_DIR)/vmlinuz /usr/share/spinifex/microvm/vmlinuz + sudo install -m 0644 $(MICROVM_OUT_DIR)/initramfs.cpio.gz /usr/share/spinifex/microvm/initramfs.cpio.gz go_run: @echo -e "\n....Running $(GO_PROJECT_NAME)...." @@ -122,9 +139,18 @@ run: $(MAKE) go_build $(MAKE) go_run -# Fast iteration: build + install binary + restart all services +# Fast iteration: build + install binary + restart all services. +# Microvm artifacts are reinstalled when they already exist on disk — the rule's +# input timestamps drive a rebuild only if anything actually changed. On a fresh +# checkout (no build/microvm/vmlinuz yet) the install step is skipped; run +# `make install-microvm` explicitly the first time. deploy: build sudo install -m 755 bin/spx /usr/local/bin/spx + @if [ -f $(MICROVM_OUT_DIR)/vmlinuz ]; then \ + $(MAKE) install-microvm; \ + else \ + echo "[deploy] microvm artifacts absent — run 'make install-microvm' for first-time setup"; \ + fi sudo systemctl daemon-reload sudo systemctl restart spinifex.target @@ -206,6 +232,14 @@ distro-amd64: -f build/Dockerfile.distro \ --output type=local,dest=dist/amd64/ \ ../ + @if [ -f $(MICROVM_OUT_DIR)/vmlinuz ] && [ -f $(MICROVM_OUT_DIR)/initramfs.cpio.gz ]; then \ + echo "[distro-amd64] staging microvm artifacts into tarball"; \ + mkdir -p dist/amd64/microvm; \ + cp $(MICROVM_OUT_DIR)/vmlinuz $(MICROVM_OUT_DIR)/initramfs.cpio.gz dist/amd64/microvm/; \ + else \ + echo "[distro-amd64] WARNING: microvm artifacts missing — tarball will not include them"; \ + echo "[distro-amd64] run 'make build-microvm-image' before 'make distro-amd64'"; \ + fi tar -czf dist/spinifex-$(VERSION)-linux-amd64.tar.gz -C dist/amd64 . sha256sum dist/spinifex-$(VERSION)-linux-amd64.tar.gz > dist/spinifex-$(VERSION)-linux-amd64.tar.gz.sha256 @@ -238,9 +272,12 @@ ansible-dev-install: ansible-dev-reset: cd scripts/ansible && ansible-playbook playbooks/dev-reset.yml -.PHONY: build build-ui build-installer build-lb-agent build-system-image build-lb-image go_build go_run preflight test test-cover test-race diff-coverage bench run \ +ansible-dev-deploy: + cd scripts/ansible && ansible-playbook playbooks/dev-deploy.yml + +.PHONY: build build-ui build-installer build-lb-agent build-system-image build-microvm-image install-microvm go_build go_run preflight test test-cover test-race diff-coverage bench run \ deploy reinstall clean \ install-system install-go install-aws quickinstall \ lint fix govulncheck \ distro distro-amd64 distro-arm64 distro-clean \ - ansible-dev-preflight ansible-dev-teardown ansible-dev-install ansible-dev-reset + ansible-dev-preflight ansible-dev-teardown ansible-dev-install ansible-dev-reset ansible-dev-deploy diff --git a/build/microvm/init.sh b/build/microvm/init.sh new file mode 100755 index 000000000..869fb59fe --- /dev/null +++ b/build/microvm/init.sh @@ -0,0 +1,56 @@ +#!/bin/sh +mount -t proc proc /proc +mount -t sysfs sys /sys +mount -t devtmpfs dev /dev + +# virtio_mmio is built-in (CONFIG_VIRTIO_MMIO=y) so virtio-net devices are +# already enumerated by the time PID 1 runs — no modprobe needed. +# qemu_fw_cfg and virtio_net are =m in stock Alpine linux-virt, so load them. +modprobe qemu_fw_cfg 2>/dev/null || modprobe fw_cfg_sysfs 2>/dev/null || true +modprobe virtio_net 2>/dev/null || true + +for i in 1 2 3 4 5; do + [ -f /sys/firmware/qemu_fw_cfg/by_name/opt/spinifex/netcfg/raw ] && break + sleep 0.02 +done + +if [ ! -f /sys/firmware/qemu_fw_cfg/by_name/opt/spinifex/netcfg/raw ]; then + echo "[init] FATAL: fw_cfg netcfg not available" >&2 + exit 1 +fi + +. /sys/firmware/qemu_fw_cfg/by_name/opt/spinifex/netcfg/raw + +for n in 0 1 2 3 4 5; do + eval mac=\$NIC${n}_MAC + [ -z "$mac" ] && continue + + iface="" + for attempt in 1 2 3 4 5; do + iface=$(ip -o link | awk -v m="$mac" 'tolower($0) ~ tolower(m) {print $2}' | tr -d :) + [ -n "$iface" ] && break + sleep 0.02 + done + + if [ -z "$iface" ]; then + echo "[init] WARNING: no interface found for MAC $mac (NIC$n), skipping" >&2 + continue + fi + + eval cidr=\$NIC${n}_CIDR + eval gw=\$NIC${n}_GW + eval default=\$NIC${n}_DEFAULT + eval rdst=\$NIC${n}_ROUTE_DST + eval rvia=\$NIC${n}_ROUTE_VIA + + ip link set "$iface" up + [ -n "$cidr" ] && ip addr add "$cidr" dev "$iface" + [ "$default" = "1" ] && [ -n "$gw" ] && ip route add default via "$gw" dev "$iface" + [ -n "$rdst" ] && [ -n "$rvia" ] && ip route add "$rdst" via "$rvia" dev "$iface" +done + +cp /sys/firmware/qemu_fw_cfg/by_name/opt/spinifex/lb-agent-env/raw /etc/conf.d/lb-agent +mkdir -p /etc/ssl/certs +cp /sys/firmware/qemu_fw_cfg/by_name/opt/spinifex/ca-cert/raw /etc/ssl/certs/ca-certificates.crt + +exec /sbin/init diff --git a/build/microvm/inittab b/build/microvm/inittab new file mode 100644 index 000000000..092709fe3 --- /dev/null +++ b/build/microvm/inittab @@ -0,0 +1,4 @@ +::sysinit:/etc/rc.local +::respawn:/bin/sh -c 'set -a; . /etc/conf.d/lb-agent; set +a; exec /usr/local/bin/lb-agent' +::ctrlaltdel:/sbin/reboot +::shutdown:/bin/umount -a -r diff --git a/docs/getting-started/setting-up-your-cluster/README.md b/docs/getting-started/setting-up-your-cluster/README.md index 62eba5bd9..7c899e2aa 100644 --- a/docs/getting-started/setting-up-your-cluster/README.md +++ b/docs/getting-started/setting-up-your-cluster/README.md @@ -60,7 +60,6 @@ spx admin images list NAME | DISTRO | VERSION | ARCH | BOOT debian-13-arm64 | debian | 13 | arm64 | bios debian-13-x86_64 | debian | 13 | x86_64 | bios -lb-alpine-3.21.6-x86_64 | alpine | 3.21.6 | x86_64 | bios ubuntu-26.04-arm64 | ubuntu | 26.04 | arm64 | bios ubuntu-26.04-x86_64 | ubuntu | 26.04 | x86_64 | bios ``` diff --git a/docs/terraform-workbooks/nginx-alb/README.md b/docs/terraform-workbooks/nginx-alb/README.md index 185dadb89..0eea9db55 100644 --- a/docs/terraform-workbooks/nginx-alb/README.md +++ b/docs/terraform-workbooks/nginx-alb/README.md @@ -86,22 +86,16 @@ Or create a `main.tf` file and paste the full configuration below. -### Step 2. Install Load Balancer AMI +### Step 2. Install Debian AMI -Next install the load balancer AMI images, which is used as the AMI disk image for launching the load-balancer and a requirement. - -```bash -spx admin images import --name lb-alpine-3.21.6-x86_64 -``` - -### Step 2.1 Install Debian AMI - -Next, install the Debian 13 AMI which is used in the example to host the `nginx` webservers as an EC2 instance. +Install the Debian 13 AMI which is used in the example to host the `nginx` webservers as an EC2 instance. ```bash spx admin images import --name debian-13-x86_64 ``` +> **Note:** The load balancer itself runs as a direct-boot QEMU microvm using the kernel + initramfs bundled with the Spinifex distribution (`/usr/share/spinifex/microvm/`), so no separate LB AMI import is required. + ### Step 3. Deploy ```bash diff --git a/scripts/ansible/README.md b/scripts/ansible/README.md index 41ba6e1a5..7e3ae7c86 100644 --- a/scripts/ansible/README.md +++ b/scripts/ansible/README.md @@ -31,6 +31,7 @@ inventory and roles relative to CWD. | `playbooks/dev-teardown.yml` | Wipe state only (no reinstall) | `reset-dev-env.sh` §teardown | | `playbooks/dev-install.yml` | Build + install + init + smoketest on clean box | `dev-install.sh` | | `playbooks/dev-reset.yml` | Capture settings → teardown → build → install → init → smoketest | `reset-dev-env.sh` (full) | +| `playbooks/dev-deploy.yml` | Rebuild + swap binaries/microvm artifacts + restart (no setup.sh, no smoketest) | `make deploy` | Upcoming (not yet implemented): @@ -44,6 +45,7 @@ ansible-playbook playbooks/dev-preflight.yml ansible-playbook playbooks/dev-teardown.yml ansible-playbook playbooks/dev-install.yml ansible-playbook playbooks/dev-reset.yml +ansible-playbook playbooks/dev-deploy.yml ``` Or via `make` (from `spinifex/`): @@ -53,8 +55,16 @@ make ansible-dev-preflight make ansible-dev-teardown make ansible-dev-install make ansible-dev-reset +make ansible-dev-deploy ``` +### When to use which + +- First-time / clean box → `ansible-dev-install` +- Iterate on Go code, microvm initramfs, lb-agent → `ansible-dev-deploy` (fast) +- Changed systemd units, helper scripts, logrotate, setup.sh → `ansible-dev-reset` (slow, full rebuild) +- Need a clean slate without reinstall → `ansible-dev-teardown` + ## Variable overrides Defaults in `vars/defaults.yml`. Override per run with `-e`: @@ -74,7 +84,6 @@ Useful overrides: | `spinifex_region` | `ap-southeast-2` | Region passed to `spx admin init` | | `spinifex_az` | `{{ region }}a` | AZ passed to `spx admin init` | | `spinifex_external_mode` | `pool` | `pool` \| `nat` external networking | -| `spinifex_build_lb_image` | `true` | Build + import LB system image after init | `dev-reset.yml` automatically captures `region`, `az`, `external_mode`, pool range, gateway, prefix-len, nat gateway_ip from the existing diff --git a/scripts/ansible/playbooks/dev-deploy.yml b/scripts/ansible/playbooks/dev-deploy.yml new file mode 100644 index 000000000..123f46b29 --- /dev/null +++ b/scripts/ansible/playbooks/dev-deploy.yml @@ -0,0 +1,14 @@ +--- +# In-place artifact swap: rebuilds + replaces binaries/microvm artifacts on +# an already-installed node, then restarts spinifex.target. Use when iterating +# on code without altering systemd units, users, dirs, or running the full +# smoketest. For first-time or unit/script changes use dev-install / dev-reset. +- name: Dev deploy — build + swap binaries + restart (no setup.sh, no smoketest) + hosts: localhost + gather_facts: true + vars_files: + - ../vars/defaults.yml + + roles: + - build + - deploy diff --git a/scripts/ansible/roles/build/tasks/main.yml b/scripts/ansible/roles/build/tasks/main.yml index 961fb8b56..9096c62c0 100644 --- a/scripts/ansible/roles/build/tasks/main.yml +++ b/scripts/ansible/roles/build/tasks/main.yml @@ -11,6 +11,18 @@ chdir: "{{ mulga_root }}/viperblock" changed_when: true +- name: build — detect microVM build script (present only on direct-boot branches) + ansible.builtin.stat: + path: "{{ spinifex_root }}/scripts/build-microvm-image.sh" + register: build_microvm_script + +- name: build — microVM kernel + initramfs (direct-boot LBs) + ansible.builtin.command: + cmd: make build-microvm-image + chdir: "{{ spinifex_root }}" + changed_when: true + when: build_microvm_script.stat.exists + - name: build — verify build artifacts present ansible.builtin.stat: path: "{{ item }}" @@ -40,9 +52,15 @@ mkdir -p "$STAGING/scripts" cp "{{ spinifex_root }}/build/scripts/"* "$STAGING/scripts/" cp "{{ spinifex_root }}/build/logrotate/spinifex" "$STAGING/logrotate-spinifex" + # microVM artifacts ship only when the branch built them. + if [ -f "{{ spinifex_root }}/build/microvm/vmlinuz" ] && [ -f "{{ spinifex_root }}/build/microvm/initramfs.cpio.gz" ]; then + mkdir -p "$STAGING/microvm" + cp "{{ spinifex_root }}/build/microvm/vmlinuz" "$STAGING/microvm/" + cp "{{ spinifex_root }}/build/microvm/initramfs.cpio.gz" "$STAGING/microvm/" + fi tar czf "{{ build_tarball_path }}" -C "$STAGING" . changed_when: true - name: build — summary ansible.builtin.debug: - msg: "Built spx + nbdkit plugin, tarball at {{ build_tarball_path }}" + msg: "Built spx + nbdkit plugin{{ ' + microvm artifacts' if build_microvm_script.stat.exists else '' }}, tarball at {{ build_tarball_path }}" diff --git a/scripts/ansible/roles/deploy/tasks/main.yml b/scripts/ansible/roles/deploy/tasks/main.yml new file mode 100644 index 000000000..3c24d890d --- /dev/null +++ b/scripts/ansible/roles/deploy/tasks/main.yml @@ -0,0 +1,148 @@ +--- +# In-place artifact swap for an already-installed spinifex node. Mirrors +# `make deploy`: replace binaries + microvm artifacts, restart services. +# Does NOT run setup.sh (no user/dir/systemd-unit changes) or smoketest. + +- name: deploy — fail fast if spinifex isn't already installed + ansible.builtin.stat: + path: "{{ spinifex_config_file }}" + register: deploy_installed_stat + failed_when: not deploy_installed_stat.stat.exists + +- name: deploy — assert config present + ansible.builtin.assert: + that: deploy_installed_stat.stat.exists + fail_msg: | + {{ spinifex_config_file }} missing — this playbook only updates an + existing install. Run ansible-dev-install or ansible-dev-reset first. + +- name: deploy — verify build artifacts present + ansible.builtin.stat: + path: "{{ item }}" + register: deploy_artifacts + loop: + - "{{ spinifex_root }}/bin/spx" + - "{{ mulga_root }}/viperblock/lib/nbdkit-viperblock-plugin.so" + +- name: deploy — assert artifacts exist after build role + ansible.builtin.assert: + that: item.stat.exists + fail_msg: "Build artifact missing: {{ item.item }} — build role should have produced it" + loop: "{{ deploy_artifacts.results }}" + loop_control: + label: "{{ item.item }}" + +- name: deploy — detect microvm artifacts (direct-boot branches only) + ansible.builtin.stat: + path: "{{ spinifex_root }}/build/microvm/{{ item }}" + register: deploy_microvm_stat + loop: + - vmlinuz + - initramfs.cpio.gz + +- name: deploy — set microvm presence fact + ansible.builtin.set_fact: + deploy_microvm_present: "{{ deploy_microvm_stat.results | map(attribute='stat.exists') | min }}" + +- name: deploy — detect nbdkit plugin directory + ansible.builtin.shell: | + set -e + nbdkit --dump-config | awk -F= '/^plugindir=/{print $2; exit}' + register: deploy_plugindir_cmd + changed_when: false + +- name: deploy — set plugin path fact + ansible.builtin.set_fact: + deploy_plugindir: "{{ deploy_plugindir_cmd.stdout | trim }}" + +- name: deploy — assert plugindir resolved + ansible.builtin.assert: + that: deploy_plugindir | length > 0 + fail_msg: "Could not detect nbdkit plugin directory via `nbdkit --dump-config`" + +- name: deploy — stop spinifex.target before binary swap + become: true + ansible.builtin.systemd: + name: spinifex.target + state: stopped + failed_when: false + +- name: deploy — install spx binary + become: true + ansible.builtin.copy: + src: "{{ spinifex_root }}/bin/spx" + dest: /usr/local/bin/spx + mode: "0755" + owner: root + group: root + +- name: deploy — install viperblock nbdkit plugin + become: true + ansible.builtin.copy: + src: "{{ mulga_root }}/viperblock/lib/nbdkit-viperblock-plugin.so" + dest: "{{ deploy_plugindir }}/nbdkit-viperblock-plugin.so" + mode: "0755" + owner: root + group: root + +- name: deploy — ensure microvm dir + become: true + ansible.builtin.file: + path: /usr/share/spinifex/microvm + state: directory + mode: "0755" + owner: root + group: root + when: deploy_microvm_present + +- name: deploy — install microvm kernel + become: true + ansible.builtin.copy: + src: "{{ spinifex_root }}/build/microvm/vmlinuz" + dest: /usr/share/spinifex/microvm/vmlinuz + mode: "0644" + owner: root + group: root + when: deploy_microvm_present + +- name: deploy — install microvm initramfs + become: true + ansible.builtin.copy: + src: "{{ spinifex_root }}/build/microvm/initramfs.cpio.gz" + dest: /usr/share/spinifex/microvm/initramfs.cpio.gz + mode: "0644" + owner: root + group: root + when: deploy_microvm_present + +- name: deploy — daemon-reload (covers any unit changes shipped via setup.sh later) + become: true + ansible.builtin.systemd: + daemon_reload: true + +- name: deploy — start spinifex.target + become: true + ansible.builtin.systemd: + name: spinifex.target + state: started + +- name: deploy — wait for awsgw to respond + become: true + become_user: "{{ spinifex_invoking_user }}" + environment: + AWS_PROFILE: spinifex + ansible.builtin.command: aws ec2 describe-regions + register: deploy_awsgw + retries: 15 + delay: 2 + until: deploy_awsgw.rc == 0 + changed_when: false + +- name: deploy — summary + ansible.builtin.debug: + msg: | + Deployed: + spx → /usr/local/bin/spx + nbdkit plugin → {{ deploy_plugindir }}/nbdkit-viperblock-plugin.so + microvm → {{ '/usr/share/spinifex/microvm/{vmlinuz,initramfs.cpio.gz}' if deploy_microvm_present else 'skipped (not built on this branch)' }} + spinifex.target restarted; awsgw responding. diff --git a/scripts/ansible/roles/init/tasks/main.yml b/scripts/ansible/roles/init/tasks/main.yml index f6dd988ce..6e2b91311 100644 --- a/scripts/ansible/roles/init/tasks/main.yml +++ b/scripts/ansible/roles/init/tasks/main.yml @@ -74,19 +74,6 @@ delay: 2 changed_when: false -- name: init — build LB agent - ansible.builtin.command: - cmd: make build-lb-agent - chdir: "{{ spinifex_root }}" - changed_when: true - when: spinifex_build_lb_image | bool - -- name: init — import LB system image - ansible.builtin.command: - cmd: "{{ spinifex_root }}/scripts/build-system-image.sh {{ spinifex_lb_image_conf }} --import --quiet" - changed_when: true - when: spinifex_build_lb_image | bool - - name: init — summary ansible.builtin.debug: msg: | @@ -95,4 +82,3 @@ external_mode={{ spinifex_external_mode }} spinifex.target: started CA: {{ spinifex_ca_trust_path }} - LB image: {{ 'imported' if spinifex_build_lb_image else 'skipped' }} diff --git a/scripts/ansible/vars/defaults.yml b/scripts/ansible/vars/defaults.yml index 1b2341cb3..8d275dae9 100644 --- a/scripts/ansible/vars/defaults.yml +++ b/scripts/ansible/vars/defaults.yml @@ -79,10 +79,6 @@ mulga_root: "{{ lookup('pipe', 'readlink -f ' ~ playbook_dir ~ '/../../../..') } # Build output. build_tarball_path: /tmp/spinifex-local.tar.gz -# LB system image (built + imported at end of init). -spinifex_build_lb_image: true -spinifex_lb_image_conf: "{{ spinifex_root }}/scripts/images/lb.conf" - # Smoketest image — parameterised so tofu examples can share the same base. spinifex_smoketest_distro: debian spinifex_smoketest_version: "13" diff --git a/scripts/build-microvm-image.sh b/scripts/build-microvm-image.sh new file mode 100755 index 000000000..5b44b0244 --- /dev/null +++ b/scripts/build-microvm-image.sh @@ -0,0 +1,261 @@ +#!/bin/bash +# build-microvm-image.sh — build a minimal Alpine-based microVM kernel + initramfs +# for use with QEMU microvm machine type and Spinifex lb-agent. +# +# Outputs: +# $REPO_ROOT/build/microvm/vmlinuz +# $REPO_ROOT/build/microvm/initramfs.cpio.gz +# +# Rootfs strategy (first match wins): +# 1. apk available on host → install directly into a temp chroot (Alpine CI/CD) +# 2. docker available → run alpine container, export filesystem +# 3. podman available → same via podman +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +BUILD_DIR="$REPO_ROOT/build/microvm" +INIT_SH="$BUILD_DIR/init.sh" +INITTAB="$BUILD_DIR/inittab" + +ALPINE_VERSION="${ALPINE_VERSION:-3.20}" +ALPINE_MIRROR="${ALPINE_MIRROR:-https://dl-cdn.alpinelinux.org/alpine}" +ALPINE_PACKAGES="busybox linux-virt haproxy iproute2 ca-certificates" + +echo "[build-microvm-image] repo root: $REPO_ROOT" +echo "[build-microvm-image] build dir: $BUILD_DIR" +mkdir -p "$BUILD_DIR" + +# --- Verify non-negotiable tools --- +for tool in cpio gzip find; do + if ! command -v "$tool" >/dev/null 2>&1; then + echo "ERROR: required tool not found: $tool" >&2 + exit 1 + fi +done + +# --- Create chroot --- +CHROOT_DIR=$(mktemp -d) +cleanup() { + echo "[build-microvm-image] cleaning up chroot: $CHROOT_DIR" + rm -rf "$CHROOT_DIR" +} +trap cleanup EXIT + +# --- Populate rootfs --- +# Strategy 1: native apk (Alpine hosts, CI) +if command -v apk >/dev/null 2>&1; then + echo "[build-microvm-image] rootfs: native apk" + mkdir -p \ + "$CHROOT_DIR/etc/apk" \ + "$CHROOT_DIR/lib/apk/db" \ + "$CHROOT_DIR/var/cache/apk" + cat > "$CHROOT_DIR/etc/apk/repositories" </dev/null 2>&1 && docker info >/dev/null 2>&1; then + CONTAINER_TOOL=docker + elif command -v podman >/dev/null 2>&1; then + CONTAINER_TOOL=podman + else + echo "ERROR: no rootfs build tool available." >&2 + echo " Install one of: apk (Alpine), docker, podman" >&2 + exit 1 + fi + + echo "[build-microvm-image] rootfs: $CONTAINER_TOOL export (alpine:${ALPINE_VERSION})" + cid=$($CONTAINER_TOOL run -d \ + "alpine:${ALPINE_VERSION}" \ + sh -c "apk add --no-cache ${ALPINE_PACKAGES}") + + exit_code=$($CONTAINER_TOOL wait "$cid") + if [ "$exit_code" != "0" ]; then + echo "ERROR: package installation failed in container (exit $exit_code)" >&2 + $CONTAINER_TOOL rm "$cid" >/dev/null 2>&1 || true + exit 1 + fi + + $CONTAINER_TOOL export "$cid" | tar -x -C "$CHROOT_DIR" + $CONTAINER_TOOL rm "$cid" >/dev/null 2>&1 +fi + +# --- Fix /dev device nodes --- +# tar extraction without root silently creates 0-byte regular files for device +# nodes (mknod requires CAP_MKNOD). The kernel opens /dev/console to wire +# init's stdio to the serial console; a regular file there causes all init +# output to be silently discarded. Recreate the two nodes needed before +# devtmpfs mounts (which provides the rest at runtime). +rm -rf "$CHROOT_DIR/dev" +mkdir "$CHROOT_DIR/dev" +sudo mknod -m 600 "$CHROOT_DIR/dev/console" c 5 1 +sudo mknod -m 666 "$CHROOT_DIR/dev/null" c 1 3 + +# --- Place init script --- +echo "[build-microvm-image] installing init.sh as /init..." +if [ ! -f "$INIT_SH" ]; then + echo "ERROR: $INIT_SH not found — cannot build initramfs" >&2 + exit 1 +fi +install -m 0755 "$INIT_SH" "$CHROOT_DIR/init" + +# --- Place inittab --- +if [ -f "$INITTAB" ]; then + echo "[build-microvm-image] installing inittab..." + install -m 0644 "$INITTAB" "$CHROOT_DIR/etc/inittab" +fi + +# --- Copy lb-agent binary --- +LB_AGENT_BIN="$REPO_ROOT/bin/lb-agent" +if [ -f "$LB_AGENT_BIN" ]; then + echo "[build-microvm-image] copying lb-agent binary..." + mkdir -p "$CHROOT_DIR/usr/local/bin" + install -m 0755 "$LB_AGENT_BIN" "$CHROOT_DIR/usr/local/bin/lb-agent" +else + echo "[build-microvm-image] WARNING: $LB_AGENT_BIN not found — lb-agent will be absent from initramfs" >&2 +fi + +# --- Create required directories for init --- +mkdir -p \ + "$CHROOT_DIR/proc" \ + "$CHROOT_DIR/sys" \ + "$CHROOT_DIR/dev" \ + "$CHROOT_DIR/etc/ssl/certs" \ + "$CHROOT_DIR/etc/conf.d" + +# --- Locate kernel --- +KERNEL_IMG=$(find "$CHROOT_DIR/boot" -name "vmlinuz*" | sort | tail -1) +if [ -z "$KERNEL_IMG" ]; then + echo "ERROR: no vmlinuz found in $CHROOT_DIR/boot" >&2 + exit 1 +fi +echo "[build-microvm-image] kernel image: $KERNEL_IMG" + +KERNEL_VER=$(basename "$KERNEL_IMG" | sed 's/vmlinuz-//') +KERNEL_CONFIG="$CHROOT_DIR/boot/config-${KERNEL_VER}" + +# --- Assert fw_cfg module --- +if ! find "$CHROOT_DIR/lib/modules" \ + -name "qemu_fw_cfg.ko*" \ + -o -name "fw_cfg_sysfs.ko*" \ + | grep -q .; then + if ! grep -q "CONFIG_FW_CFG_SYSFS=y" "$KERNEL_CONFIG" 2>/dev/null; then + echo "ERROR: qemu_fw_cfg module missing from initramfs — fw_cfg reads will fail at boot" >&2 + exit 1 + fi + echo "[build-microvm-image] fw_cfg: built-in (CONFIG_FW_CFG_SYSFS=y)" +else + echo "[build-microvm-image] fw_cfg: module found in lib/modules" +fi + +# --- Strip kernel modules (Phase 2 keep-list approach) --- +# Only modules needed by a virtio-mmio microvm guest are kept: +# virtio*.ko* — virtio bus, net, blk, rng, console, and helpers +# *fw_cfg*.ko* — QEMU fw_cfg sysfs driver (delivers boot blobs) +# *failover*.ko* — net_failover + failover (virtio_net deps for live migration) +# All other loadable modules are removed. Drivers compiled into the kernel +# (CONFIG_VIRTIO_MMIO=y etc.) are unaffected — they live in vmlinuz, not here. +echo "[build-microvm-image] stripping kernel modules to virtio+fw_cfg only..." +for kver_dir in "$CHROOT_DIR/lib/modules"/*/; do + kver="$(basename "$kver_dir")" + kernel_dir="$kver_dir/kernel" + [ -d "$kernel_dir" ] || continue + + # Collect keeper modules and their relative paths from the kernel/ tree. + tmp_keep=$(mktemp -d) + find "$kernel_dir" -name "virtio*.ko.gz" -o -name "virtio*.ko" \ + -o -name "*fw_cfg*.ko.gz" -o -name "*fw_cfg*.ko" \ + -o -name "*failover*.ko.gz" -o -name "*failover*.ko" \ + 2>/dev/null | while read -r mod; do + rel="${mod#"$kernel_dir/"}" + dest_dir="$tmp_keep/$(dirname "$rel")" + mkdir -p "$dest_dir" + cp "$mod" "$dest_dir/" + done + + # Replace kernel module tree with the keeper set. + rm -rf "$kernel_dir" + mkdir -p "$kernel_dir" + # Restore each kept file into the same relative path. + (cd "$tmp_keep" && find . -name "*.ko*" | while read -r f; do + dest_dir="$kernel_dir/$(dirname "${f#./}")" + mkdir -p "$dest_dir" + cp "$f" "$dest_dir/" + done) + rm -rf "$tmp_keep" + + # Regenerate module dependency map from the surviving modules. + depmod -b "$CHROOT_DIR" "$kver" 2>/dev/null || true +done + +# --- Strip package-manager artifacts (not needed at runtime) --- +echo "[build-microvm-image] stripping package manager artifacts..." +rm -rf \ + "$CHROOT_DIR/lib/apk" \ + "$CHROOT_DIR/var/cache/apk" \ + "$CHROOT_DIR/etc/apk" \ + "$CHROOT_DIR/usr/share/man" \ + "$CHROOT_DIR/usr/share/doc" \ + "$CHROOT_DIR/usr/share/apk" \ + "$CHROOT_DIR/usr/include" \ + "$CHROOT_DIR/usr/lib/pkgconfig" + +# --- Strip debug symbols from binaries --- +echo "[build-microvm-image] stripping debug symbols from binaries..." +find "$CHROOT_DIR/usr/sbin" "$CHROOT_DIR/usr/bin" \ + "$CHROOT_DIR/sbin" "$CHROOT_DIR/bin" \ + "$CHROOT_DIR/usr/local/bin" \ + -type f 2>/dev/null | while read -r bin; do + strip --strip-all "$bin" 2>/dev/null || true +done + +# --- Copy vmlinuz out before stripping /boot from chroot --- +VMLINUZ_OUT="$BUILD_DIR/vmlinuz" +echo "[build-microvm-image] copying kernel: $VMLINUZ_OUT" +cp "$KERNEL_IMG" "$VMLINUZ_OUT" + +# Drop /boot from the chroot — vmlinuz, Alpine's stock initramfs-virt, System.map +# and kernel config all live here (~25 MiB). None are needed at runtime: the +# guest already has the kernel loaded by QEMU's -kernel, and Alpine's initramfs +# is unused because we replace it with our own /init. Leaving /boot in the cpio +# nearly doubles uncompressed initramfs size and forces a 512 MiB guest just to +# survive decompression. +rm -rf "$CHROOT_DIR/boot" + +# --- Build initramfs --- +INITRAMFS_OUT="$BUILD_DIR/initramfs.cpio.gz" +echo "[build-microvm-image] building initramfs: $INITRAMFS_OUT" +( + cd "$CHROOT_DIR" + find . | cpio --quiet -o -H newc | gzip -9 > "$INITRAMFS_OUT" +) + +# --- Log artifact sizes --- +echo "" +echo "[build-microvm-image] artifacts:" +ls -lh "$VMLINUZ_OUT" "$INITRAMFS_OUT" +echo "" + +# --- Phase 2 artifact size gate (50 MiB total) --- +ARTIFACT_MAX_MiB="${MICROVM_ARTIFACT_MAX_MiB:-50}" +total_bytes=$(( $(stat -c %s "$VMLINUZ_OUT") + $(stat -c %s "$INITRAMFS_OUT") )) +max_bytes=$(( ARTIFACT_MAX_MiB * 1024 * 1024 )) +total_mib=$(( (total_bytes + 1048575) / 1048576 )) +if [ "$total_bytes" -gt "$max_bytes" ]; then + echo "ERROR: artifact size ${total_mib} MiB exceeds ${ARTIFACT_MAX_MiB} MiB gate" >&2 + echo " Set MICROVM_ARTIFACT_MAX_MiB=N to override during development." >&2 + exit 1 +fi +echo "[build-microvm-image] artifact size gate: PASS (${total_mib} MiB / ${ARTIFACT_MAX_MiB} MiB)" +echo "" +echo "[build-microvm-image] done." diff --git a/scripts/dev-install.sh b/scripts/dev-install.sh index 5bd6ad862..f9ee66ea0 100755 --- a/scripts/dev-install.sh +++ b/scripts/dev-install.sh @@ -91,9 +91,8 @@ if ! id -Gn 2>/dev/null | grep -qw spinifex; then newgrp spinifex fi -echo "=== Building and importing LB image ===" -cd "$PROJECT_ROOT" && make build-lb-agent -"$PROJECT_ROOT/scripts/build-system-image.sh" "$PROJECT_ROOT/scripts/images/lb.conf" --import --quiet +echo "=== Building and installing microVM artifacts ===" +cd "$PROJECT_ROOT" && make build-lb-agent install-microvm echo "=== Done ===" echo "Services: sudo systemctl status spinifex.target" diff --git a/scripts/reset-dev-env.sh b/scripts/reset-dev-env.sh index 05db3609e..a8b5a0ac3 100755 --- a/scripts/reset-dev-env.sh +++ b/scripts/reset-dev-env.sh @@ -268,10 +268,9 @@ sudo systemctl start spinifex.target # Wait for services to start sleep 5 -# --- Build + import LB image (needs services running) --- -echo "==> Building and importing LB image" -cd "$PROJECT_ROOT" && make build-lb-agent -"$PROJECT_ROOT/scripts/build-system-image.sh" "$PROJECT_ROOT/scripts/images/lb.conf" --import --quiet +# --- Build + install microVM artifacts (kernel + initramfs for direct-boot LBs) --- +echo "==> Building and installing microVM artifacts" +cd "$PROJECT_ROOT" && make build-lb-agent install-microvm # --- Smoke test --- sudo -u "$INVOKING_USER" "$SCRIPT_DIR/smoke-test.sh" diff --git a/scripts/setup.sh b/scripts/setup.sh index a0e9af0bf..e734b7a28 100755 --- a/scripts/setup.sh +++ b/scripts/setup.sh @@ -346,6 +346,13 @@ install_files() { $SUDO install -m 0755 "$EXTRACT_DIR/setup.sh" /usr/local/share/spinifex/setup.sh info " /usr/local/share/spinifex/setup.sh" fi + + # microVM kernel + initramfs + $SUDO install -d /usr/share/spinifex/microvm + if [ -d "$EXTRACT_DIR/microvm" ]; then + $SUDO cp "$EXTRACT_DIR/microvm/"* /usr/share/spinifex/microvm/ + info " /usr/share/spinifex/microvm/*" + fi } # --- Create directories --- diff --git a/spinifex/daemon/daemon.go b/spinifex/daemon/daemon.go index b77933ffb..71a4249df 100644 --- a/spinifex/daemon/daemon.go +++ b/spinifex/daemon/daemon.go @@ -49,7 +49,6 @@ import ( handlers_elbv2 "github.com/mulgadc/spinifex/spinifex/handlers/elbv2" "github.com/mulgadc/spinifex/spinifex/instancetypes" "github.com/mulgadc/spinifex/spinifex/objectstore" - "github.com/mulgadc/spinifex/spinifex/tags" "github.com/mulgadc/spinifex/spinifex/types" "github.com/mulgadc/spinifex/spinifex/utils" "github.com/mulgadc/spinifex/spinifex/vm" @@ -1186,29 +1185,6 @@ func (d *Daemon) startCluster() error { // Wire system credentials + gateway URL for LB agent SigV4 auth. d.wireLBAgentConfig() - // Set up lazy system AMI discovery for LB VMs. The image may not exist - // at daemon startup (imported later), so we resolve it at request time. - if d.imageService != nil { - imgSvc := d.imageService - d.elbv2Service.SetSystemAMIFunc(func() (string, error) { - imagesOut, imgErr := imgSvc.DescribeImages(&ec2.DescribeImagesInput{ - Filters: []*ec2.Filter{{ - Name: aws.String("tag:" + tags.ManagedByKey), - Values: []*string{aws.String(tags.ManagedByELBv2)}, - }}, - }, utils.GlobalAccountID) - if imgErr != nil { - return "", fmt.Errorf("describe LB system images: %w", imgErr) - } - if len(imagesOut.Images) == 0 { - return "", errors.New("LB system image not imported; run: spx admin images import --name lb-alpine-3.21.6-x86_64") - } - amiID := aws.StringValue(imagesOut.Images[0].ImageId) - slog.Info("System AMI resolved for LB VMs", "amiId", amiID, "name", aws.StringValue(imagesOut.Images[0].Name)) - return amiID, nil - }) - } - // System VMs (LB, NAT GW) use the dedicated sys.micro instance type. d.elbv2Service.SetSystemInstanceTypeFunc(func() string { return "sys.micro" @@ -2129,21 +2105,34 @@ func (d *Daemon) wireLBAgentConfig() { "awsgwBindIP", awsgwBindIP, "mgmtBridgeIP", d.mgmtBridgeIP, "advertiseIP", advertiseIP) } - // Pass mgmt route info so lbVMUserData can add a bootcmd route for + // Pass mgmt route info so buildMicrovmNICs can add a host route for // internal LBs that reach the AWSGW via the management NIC. if d.mgmtRouteVia != "" { d.elbv2Service.MgmtRouteGateway = d.mgmtBridgeIP d.elbv2Service.MgmtRouteTarget = d.mgmtRouteVia } - // Always expose mgmtBridgeIP and advertiseIP so lbVMUserData can synthesize - // a mgmt-NIC fallback route for internal-scheme LBs on single-node setups - // (where MgmtRoute{Gateway,Target} stay empty because internet-facing LBs - // reach AWSGW via VPC + EIP SNAT). Internal LBs have no EIP, so without - // this fallback the agent has no return path and the LB stays in - // provisioning forever. + // Always expose mgmtBridgeIP and advertiseIP so buildMicrovmNICs can + // synthesize a mgmt-NIC fallback route for internal-scheme LBs on + // single-node setups (where MgmtRoute{Gateway,Target} stay empty because + // internet-facing LBs reach AWSGW via VPC + EIP SNAT). Internal LBs have + // no EIP, so without this fallback the agent has no return path and the + // LB stays in provisioning forever. d.elbv2Service.MgmtBridgeIP = d.mgmtBridgeIP d.elbv2Service.AdvertiseIP = advertiseIP + + // Read CA cert so direct-boot microvm guests can verify AWSGW TLS. + // The NATS CA cert signs the AWSGW server cert (same local CA). + if d.config.NATS.CACert != "" { + if caBytes, err := os.ReadFile(d.config.NATS.CACert); err == nil { + d.elbv2Service.CACert = string(caBytes) + slog.Info("CA cert loaded for LB agent TLS", "path", d.config.NATS.CACert) + } else { + slog.Warn("Failed to read CA cert for LB agent TLS", "path", d.config.NATS.CACert, "err", err) + } + } else { + slog.Warn("NATS CACert not configured — direct-boot LB VMs will not verify AWSGW TLS") + } } // resolveGPUModel maps a discovered GPU to an instance type model. diff --git a/spinifex/daemon/daemon_system_instance.go b/spinifex/daemon/daemon_system_instance.go index 68b041949..854391dec 100644 --- a/spinifex/daemon/daemon_system_instance.go +++ b/spinifex/daemon/daemon_system_instance.go @@ -1,9 +1,11 @@ package daemon import ( - "encoding/base64" "fmt" "log/slog" + "os" + "path/filepath" + "strings" "time" "github.com/aws/aws-sdk-go/aws" @@ -17,13 +19,11 @@ import ( // Compile-time check that Daemon implements SystemInstanceLauncher. var _ handlers_elbv2.SystemInstanceLauncher = (*Daemon)(nil) -// LaunchSystemInstance creates and starts a system-managed VM. The VM is owned -// by the system account (GlobalAccountID) and is not visible to customer -// DescribeInstances calls. -// -// This is the internal equivalent of RunInstances — it reuses the same -// instance service, resource manager, volume preparation, and QEMU launch -// path, but skips the NATS request/response envelope and key pair validation. +// LaunchSystemInstance creates and starts a system-managed VM (ELBv2 LB). +// The VM is owned by the system account (GlobalAccountID), is not visible to +// customer DescribeInstances calls, and always boots via direct kernel boot +// (bundled vmlinuz+initramfs, fw_cfg-delivered config). There is no AMI, +// volume, or cloud-init path. func (d *Daemon) LaunchSystemInstance(input *handlers_elbv2.SystemInstanceInput) (*handlers_elbv2.SystemInstanceOutput, error) { accountID := utils.GlobalAccountID // ENI account may differ from system account — the ENI is created under @@ -39,14 +39,6 @@ func (d *Daemon) LaunchSystemInstance(input *handlers_elbv2.SystemInstanceInput) return nil, fmt.Errorf("unknown instance type: %s", input.InstanceType) } - // Validate AMI - if d.imageService == nil { - return nil, fmt.Errorf("image service not initialized") - } - if _, err := d.imageService.GetAMIConfig(input.ImageID); err != nil { - return nil, fmt.Errorf("AMI %s not found: %w", input.ImageID, err) - } - // Allocate resources if err := d.resourceMgr.allocate(instanceType); err != nil { return nil, fmt.Errorf("insufficient capacity for %s: %w", input.InstanceType, err) @@ -57,7 +49,6 @@ func (d *Daemon) LaunchSystemInstance(input *handlers_elbv2.SystemInstanceInput) // customer-facing listings (Nodes page). runInput := &ec2.RunInstancesInput{ InstanceType: aws.String(input.InstanceType), - ImageId: aws.String(input.ImageID), MinCount: aws.Int64(1), MaxCount: aws.Int64(1), TagSpecifications: []*ec2.TagSpecification{ @@ -72,10 +63,6 @@ func (d *Daemon) LaunchSystemInstance(input *handlers_elbv2.SystemInstanceInput) if input.SubnetID != "" { runInput.SubnetId = aws.String(input.SubnetID) } - if input.UserData != "" { - encoded := base64.StdEncoding.EncodeToString([]byte(input.UserData)) - runInput.UserData = aws.String(encoded) - } // Create VM via instance service instance, ec2Instance, err := d.instanceService.RunInstance(runInput) @@ -276,6 +263,14 @@ func (d *Daemon) LaunchSystemInstance(input *handlers_elbv2.SystemInstanceInput) instance.MgmtMAC = generateMgmtMAC(instance.ID) instance.MgmtIP = mgmtIP + // Inject the allocated MAC and CIDR into NIC[1] so writeFwCfgBlobs + // carries real values — the ELBv2 service leaves them blank because + // MAC/IP are only known after daemon allocation. + if len(input.NICs) > 1 && input.NICs[1].MAC == "" { + input.NICs[1].MAC = instance.MgmtMAC + input.NICs[1].CIDR = instance.MgmtIP + "/24" + } + tapName := vm.MgmtTapName(instance.ID) tapErr := d.networkPlumber.SetupTap(vm.TapSpec{Name: tapName, Bridge: mgmtBridge}) if tapErr != nil { @@ -302,30 +297,25 @@ func (d *Daemon) LaunchSystemInstance(input *handlers_elbv2.SystemInstanceInput) } } - // Prepare volumes (root volume clone from AMI, cloud-init ISO, etc.) - volumeInfos, err := d.instanceService.GenerateVolumes(runInput, instance) + // Direct-boot (microvm) path: build the vm.Config directly with microvm + // machine settings and fw_cfg blobs for network, lb-agent env, and CA cert. + cfg, err := d.buildDirectBootConfig(instance.ID, input) if err != nil { d.cleanupFailedSystemInstance(instance, instanceType) - return nil, fmt.Errorf("generate volumes: %w", err) - } - - instance.Instance.BlockDeviceMappings = make([]*ec2.InstanceBlockDeviceMapping, 0, len(volumeInfos)) - for _, vi := range volumeInfos { - mapping := &ec2.InstanceBlockDeviceMapping{} - mapping.SetDeviceName(vi.DeviceName) - mapping.Ebs = &ec2.EbsInstanceBlockDevice{} - mapping.Ebs.SetVolumeId(vi.VolumeId) - mapping.Ebs.SetAttachTime(vi.AttachTime) - mapping.Ebs.SetDeleteOnTermination(vi.DeleteOnTermination) - mapping.Ebs.SetStatus("attached") - instance.Instance.BlockDeviceMappings = append(instance.Instance.BlockDeviceMappings, mapping) + return nil, fmt.Errorf("build direct-boot config: %w", err) } + instance.Config = cfg + instance.DirectBoot = true // Launch QEMU VM + t1 := time.Now() if err := d.vmMgr.Run(instance); err != nil { d.cleanupFailedSystemInstance(instance, instanceType) return nil, fmt.Errorf("launch instance: %w", err) } + slog.Info("direct-boot timing", + "instanceId", instance.ID, + "t1_to_t2_ms", time.Since(t1).Milliseconds()) slog.Info("LaunchSystemInstance completed", "instanceId", instance.ID, @@ -418,3 +408,215 @@ func (d *Daemon) WaitForSystemInstance(instanceID string, timeout time.Duration) } return fmt.Errorf("instance %s did not reach running state within %s", instanceID, timeout) } + +// buildDirectBootConfig constructs a vm.Config for a direct-boot microVM +// launch. It does not call buildBaseVMConfig — the microvm machine type +// requires no PCIe root ports, no UEFI/BIOS, and no drives. Runtime paths +// (PID file, console log, serial socket) are filled in later by startQEMU. +// +// Network topology from input.NICs is serialised to three fw_cfg tmpfiles +// (netcfg, lb-agent-env, ca-cert) under utils.RuntimeDir(). +func (d *Daemon) buildDirectBootConfig(instanceID string, input *handlers_elbv2.SystemInstanceInput) (vm.Config, error) { + it := d.resourceMgr.instanceTypes[input.InstanceType] + architecture := "x86_64" + if it != nil && it.ProcessorInfo != nil && len(it.ProcessorInfo.SupportedArchitectures) > 0 && it.ProcessorInfo.SupportedArchitectures[0] != nil { + architecture = *it.ProcessorInfo.SupportedArchitectures[0] + } + vcpus := 1 + memMiB := 128 + if it != nil { + vcpus = int(instanceTypeVCPUs(it)) + memMiB = int(instanceTypeMemoryMiB(it)) + } + + const imagePath = "/usr/share/spinifex/microvm" + + fwCfg, err := d.writeFwCfgBlobs(instanceID, input) + if err != nil { + return vm.Config{}, fmt.Errorf("write fw_cfg blobs: %w", err) + } + + // Build kernel cmdline. + // + // QEMU microvm maps virtio-mmio slots at 0xfeb00000 + n*0x200 with IRQ 5+n. + // Without virtio_mmio.device params the kernel never discovers the devices + // (auto-kernel-cmdline does not append when -append is specified). + // + // Boot-time perf flags (Phase 2): + // quiet loglevel=3 — suppress printk to ttyS0 (115200 baud serial + // writes dominate boot time; warnings+errors only) + // mitigations=off — skip spectre/meltdown microcode patching at + // boot. Safe here: KVM guest on trusted host CPU, + // single-tenant LB workload, no untrusted code in + // the VM. Saves ~200-500ms. + // tsc=reliable — skip TSC calibration loop on KVM (host already + // vouched for invariant TSC) + // no_timer_check — skip APIC/PIT cross-check; microvm has no PIT + // reboot=t — triple-fault reboot; skip ACPI/keyboard probes + // i8042.no{pnp,aux,kbd} — microvm has no PS/2; skip i8042 probe timeouts + var sb strings.Builder + sb.WriteString("console=ttyS0 quiet loglevel=3 mitigations=off tsc=reliable no_timer_check reboot=t i8042.nopnp i8042.noaux i8042.nokbd") + for i := range input.NICs { + fmt.Fprintf(&sb, " virtio_mmio.device=0x200@0x%x:%d", + 0xfeb00000+i*0x200, 5+i) + } + cmdline := sb.String() + + machineType := microvmMachineType() + + cfg := vm.Config{ + Name: instanceID, + EnableKVM: true, + NoGraphic: true, + Architecture: architecture, + CPUType: "host,-pmu", + CPUCount: vcpus, + Memory: memMiB, + MachineType: machineType, + KernelImage: filepath.Join(imagePath, "vmlinuz"), + Initrd: filepath.Join(imagePath, "initramfs.cpio.gz"), + KernelCmdline: cmdline, + FwCfg: fwCfg, + } + + // Wire netdevs and devices for each NIC in declaration order. + // Tap device creation happens later in startQEMU (host-side only here). + allNICs := buildNICNetdevs(instanceID, input, machineType) + cfg.NetDevs = append(cfg.NetDevs, allNICs.netdevs...) + cfg.Devices = append(cfg.Devices, allNICs.devices...) + + return cfg, nil +} + +// nicNetdevResult holds the QEMU netdev and device entries for all NICs. +type nicNetdevResult struct { + netdevs []vm.NetDev + devices []vm.Device +} + +// microvmMachineType returns the QEMU -M string for the microvm machine. +// isa-serial is kept on permanently for per-VM console log access — the +// boot-time saving from turning it off is not worth losing console output. +func microvmMachineType() string { + return "microvm,pic=off,pit=off,rtc=on,acpi=on,isa-serial=on" +} + +// buildNICNetdevs produces QEMU -netdev and -device entries for each NIC in +// input. The NIC order determines the netdev IDs: net0 = primary ENI, +// net1 = mgmt (if present), net2+ = extra ENIs. Extra ENIs beyond the primary +// are only included when corresponding ExtraENIs entries exist. +func buildNICNetdevs(instanceID string, input *handlers_elbv2.SystemInstanceInput, machineType string) nicNetdevResult { + var res nicNetdevResult + + for i, nic := range input.NICs { + netID := fmt.Sprintf("net%d", i) + // Resolve the tap name from the corresponding ENI. + tapName := tapNameForNIC(i, nic, instanceID, input) + res.netdevs = append(res.netdevs, vm.NetDev{ + Value: fmt.Sprintf("tap,id=%s,ifname=%s,script=no,downscript=no", netID, tapName), + }) + res.devices = append(res.devices, vm.NetDevice(machineType, netID, nic.MAC)) + } + + return res +} + +// tapNameForNIC returns the Linux tap device name for a NIC at the given index. +// Index 0 → primary ENI tap, index 1 → mgmt tap, index 2+ → extra ENI taps. +func tapNameForNIC(idx int, _ handlers_elbv2.NICConfig, instanceID string, input *handlers_elbv2.SystemInstanceInput) string { + switch idx { + case 0: + return vm.TapDeviceName(input.ENIID) + case 1: + return vm.MgmtTapName(instanceID) + default: + extraIdx := idx - 2 + if extraIdx < len(input.ExtraENIs) { + return vm.TapDeviceName(input.ExtraENIs[extraIdx].ENIID) + } + return fmt.Sprintf("tap-unknown-%d", idx) + } +} + +// writeFwCfgBlobs serialises NIC configuration, lb-agent env, and CA cert to +// per-VM tmpfiles under utils.RuntimeDir(). Returns the fw_cfg entries for the +// three blobs and an error if any write fails or the NIC default invariant is +// violated. +func (d *Daemon) writeFwCfgBlobs(instanceID string, input *handlers_elbv2.SystemInstanceInput) ([]vm.FwCfgEntry, error) { + runtimeDir := utils.RuntimeDir() + + netcfgPath := filepath.Join(runtimeDir, fmt.Sprintf("fwcfg-%s-netcfg.tmp", instanceID)) + lbenvPath := filepath.Join(runtimeDir, fmt.Sprintf("fwcfg-%s-lbenv.tmp", instanceID)) + cacertPath := filepath.Join(runtimeDir, fmt.Sprintf("fwcfg-%s-cacert.tmp", instanceID)) + + netcfg, err := buildNetcfgBlob(input.NICs) + if err != nil { + return nil, err + } + if err := os.WriteFile(netcfgPath, []byte(netcfg), 0600); err != nil { + return nil, fmt.Errorf("write netcfg blob: %w", err) + } + + if err := os.WriteFile(lbenvPath, []byte(input.LBAgentEnv), 0600); err != nil { + _ = os.Remove(netcfgPath) + return nil, fmt.Errorf("write lb-agent-env blob: %w", err) + } + + if err := os.WriteFile(cacertPath, []byte(input.CACert), 0600); err != nil { + _ = os.Remove(netcfgPath) + _ = os.Remove(lbenvPath) + return nil, fmt.Errorf("write ca-cert blob: %w", err) + } + + slog.Debug("wrote fw_cfg blobs", + "instanceId", instanceID, + "netcfg", netcfgPath, + "lbenv", lbenvPath, + "cacert", cacertPath, + ) + + return []vm.FwCfgEntry{ + {Name: "opt/spinifex/netcfg", File: netcfgPath}, + {Name: "opt/spinifex/lb-agent-env", File: lbenvPath}, + {Name: "opt/spinifex/ca-cert", File: cacertPath}, + }, nil +} + +// buildNetcfgBlob serialises a slice of NICConfig entries to the shell KEY=value +// format consumed by the initramfs init script. Exactly one NIC must have +// IsDefault=true; returns an error otherwise. +func buildNetcfgBlob(nics []handlers_elbv2.NICConfig) (string, error) { + defaultCount := 0 + for _, n := range nics { + if n.IsDefault { + defaultCount++ + } + } + if defaultCount != 1 { + return "", fmt.Errorf("netcfg: exactly one NIC must have IsDefault=true, got %d", defaultCount) + } + + var sb strings.Builder + for i, n := range nics { + prefix := fmt.Sprintf("NIC%d", i) + fmt.Fprintf(&sb, "%s_MAC=%s\n", prefix, n.MAC) + if n.CIDR != "" { + fmt.Fprintf(&sb, "%s_CIDR=%s\n", prefix, n.CIDR) + } + if n.Gateway != "" { + fmt.Fprintf(&sb, "%s_GW=%s\n", prefix, n.Gateway) + } + if n.IsDefault { + fmt.Fprintf(&sb, "%s_DEFAULT=1\n", prefix) + } else { + fmt.Fprintf(&sb, "%s_DEFAULT=0\n", prefix) + } + if n.RouteDst != "" { + fmt.Fprintf(&sb, "%s_ROUTE_DST=%s\n", prefix, n.RouteDst) + } + if n.RouteVia != "" { + fmt.Fprintf(&sb, "%s_ROUTE_VIA=%s\n", prefix, n.RouteVia) + } + } + return sb.String(), nil +} diff --git a/spinifex/daemon/daemon_system_instance_test.go b/spinifex/daemon/daemon_system_instance_test.go index 18ddc9db6..982cd2eab 100644 --- a/spinifex/daemon/daemon_system_instance_test.go +++ b/spinifex/daemon/daemon_system_instance_test.go @@ -1,10 +1,16 @@ package daemon import ( + "fmt" + "os" + "strings" "testing" "time" + "github.com/mulgadc/spinifex/spinifex/handlers/elbv2" "github.com/mulgadc/spinifex/spinifex/vm" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func newDaemonWithVMs(vms ...*vm.VM) *Daemon { @@ -66,3 +72,240 @@ func TestWaitForSystemInstance_Timeout(t *testing.T) { t.Fatal("expected timeout error") } } + +// --------------------------------------------------------------------------- +// buildNetcfgBlob +// --------------------------------------------------------------------------- + +func TestBuildNetcfgBlob_NoDefault(t *testing.T) { + nics := []handlers_elbv2.NICConfig{ + {MAC: "02:aa:bb:cc:dd:01", CIDR: "10.0.1.5/24", IsDefault: false}, + } + _, err := buildNetcfgBlob(nics) + require.Error(t, err) + assert.Contains(t, err.Error(), "exactly one NIC must have IsDefault=true") +} + +func TestBuildNetcfgBlob_TwoDefaults(t *testing.T) { + nics := []handlers_elbv2.NICConfig{ + {MAC: "02:aa:bb:cc:dd:01", IsDefault: true}, + {MAC: "02:aa:bb:cc:dd:02", IsDefault: true}, + } + _, err := buildNetcfgBlob(nics) + require.Error(t, err) + assert.Contains(t, err.Error(), "exactly one NIC must have IsDefault=true, got 2") +} + +func TestBuildNetcfgBlob_SingleNICMinimal(t *testing.T) { + nics := []handlers_elbv2.NICConfig{ + {MAC: "02:aa:bb:cc:dd:01", IsDefault: true}, + } + got, err := buildNetcfgBlob(nics) + require.NoError(t, err) + assert.Contains(t, got, "NIC0_MAC=02:aa:bb:cc:dd:01\n") + assert.Contains(t, got, "NIC0_DEFAULT=1\n") + // Optional fields absent when empty. + assert.NotContains(t, got, "NIC0_CIDR=") + assert.NotContains(t, got, "NIC0_GW=") +} + +func TestBuildNetcfgBlob_FullNIC(t *testing.T) { + nics := []handlers_elbv2.NICConfig{ + { + MAC: "02:aa:bb:cc:dd:01", + CIDR: "10.0.1.5/24", + Gateway: "10.0.1.1", + IsDefault: true, + RouteDst: "10.20.0.5/32", + RouteVia: "10.0.1.254", + }, + } + got, err := buildNetcfgBlob(nics) + require.NoError(t, err) + assert.Contains(t, got, "NIC0_MAC=02:aa:bb:cc:dd:01\n") + assert.Contains(t, got, "NIC0_CIDR=10.0.1.5/24\n") + assert.Contains(t, got, "NIC0_GW=10.0.1.1\n") + assert.Contains(t, got, "NIC0_DEFAULT=1\n") + assert.Contains(t, got, "NIC0_ROUTE_DST=10.20.0.5/32\n") + assert.Contains(t, got, "NIC0_ROUTE_VIA=10.0.1.254\n") +} + +func TestBuildNetcfgBlob_MultiNIC_DefaultFlags(t *testing.T) { + nics := []handlers_elbv2.NICConfig{ + {MAC: "02:aa:bb:cc:dd:01", CIDR: "10.0.1.5/24", Gateway: "10.0.1.1", IsDefault: true}, + {MAC: "02:aa:bb:cc:dd:02", CIDR: "192.168.100.5/24", IsDefault: false}, + } + got, err := buildNetcfgBlob(nics) + require.NoError(t, err) + assert.Contains(t, got, "NIC0_DEFAULT=1\n") + assert.Contains(t, got, "NIC1_DEFAULT=0\n") + assert.Contains(t, got, "NIC1_MAC=02:aa:bb:cc:dd:02\n") +} + +// --------------------------------------------------------------------------- +// tapNameForNIC +// --------------------------------------------------------------------------- + +func TestTapNameForNIC_PrimaryENI(t *testing.T) { + input := &handlers_elbv2.SystemInstanceInput{ + ENIID: "eni-0123456789abcdef0", + } + got := tapNameForNIC(0, handlers_elbv2.NICConfig{}, "i-abc123", input) + // TapDeviceName strips "eni-" prefix → "tap0123456789abcde" (15 chars max) + assert.True(t, strings.HasPrefix(got, "tap"), "expected tap prefix, got %q", got) + assert.LessOrEqual(t, len(got), 15) +} + +func TestTapNameForNIC_MgmtNIC(t *testing.T) { + input := &handlers_elbv2.SystemInstanceInput{ENIID: "eni-aaa"} + got := tapNameForNIC(1, handlers_elbv2.NICConfig{}, "i-deadbeef", input) + // MgmtTapName strips "i-" prefix → "mgdeadbeef" (10 chars) + assert.True(t, strings.HasPrefix(got, "mg"), "expected mg prefix, got %q", got) + assert.LessOrEqual(t, len(got), 15) +} + +func TestTapNameForNIC_ExtraENI(t *testing.T) { + input := &handlers_elbv2.SystemInstanceInput{ + ENIID: "eni-primary", + ExtraENIs: []handlers_elbv2.ExtraENIInput{ + {ENIID: "eni-extra0"}, + {ENIID: "eni-extra1"}, + }, + } + got := tapNameForNIC(2, handlers_elbv2.NICConfig{}, "i-inst", input) + assert.True(t, strings.HasPrefix(got, "tap"), "expected tap prefix for extra ENI, got %q", got) +} + +func TestTapNameForNIC_ExtraENI_OutOfRange(t *testing.T) { + input := &handlers_elbv2.SystemInstanceInput{ + ENIID: "eni-primary", + ExtraENIs: []handlers_elbv2.ExtraENIInput{}, + } + // idx=2 → extraIdx=0 but no ExtraENIs → fallback name + got := tapNameForNIC(2, handlers_elbv2.NICConfig{}, "i-inst", input) + assert.Equal(t, fmt.Sprintf("tap-unknown-%d", 2), got) +} + +// --------------------------------------------------------------------------- +// buildNICNetdevs +// --------------------------------------------------------------------------- + +func TestBuildNICNetdevs_SingleNIC(t *testing.T) { + input := &handlers_elbv2.SystemInstanceInput{ + ENIID: "eni-000000000000000a", + NICs: []handlers_elbv2.NICConfig{ + {MAC: "02:aa:bb:cc:dd:01", IsDefault: true}, + }, + } + res := buildNICNetdevs("i-test", input, microvmMachineType()) + require.Len(t, res.netdevs, 1) + require.Len(t, res.devices, 1) + assert.Contains(t, res.netdevs[0].Value, "tap,id=net0,") + // microvm machine type → virtio-net-device transport + assert.Contains(t, res.devices[0].Value, "virtio-net-device,netdev=net0") + assert.Contains(t, res.devices[0].Value, "02:aa:bb:cc:dd:01") +} + +func TestBuildNICNetdevs_TwoNICs(t *testing.T) { + input := &handlers_elbv2.SystemInstanceInput{ + ENIID: "eni-000000000000000b", + NICs: []handlers_elbv2.NICConfig{ + {MAC: "02:aa:bb:cc:dd:01", IsDefault: true}, + {MAC: "02:aa:bb:cc:dd:02", IsDefault: false}, + }, + } + res := buildNICNetdevs("i-test2", input, microvmMachineType()) + require.Len(t, res.netdevs, 2) + require.Len(t, res.devices, 2) + assert.Contains(t, res.netdevs[0].Value, "id=net0,") + assert.Contains(t, res.netdevs[1].Value, "id=net1,") + assert.Contains(t, res.devices[0].Value, "netdev=net0") + assert.Contains(t, res.devices[1].Value, "netdev=net1") +} + +func TestBuildNICNetdevs_EmptyNICs(t *testing.T) { + input := &handlers_elbv2.SystemInstanceInput{ENIID: "eni-empty"} + res := buildNICNetdevs("i-empty", input, microvmMachineType()) + assert.Empty(t, res.netdevs) + assert.Empty(t, res.devices) +} + +// --------------------------------------------------------------------------- +// microvmMachineType +// --------------------------------------------------------------------------- + +func TestMicrovmMachineType(t *testing.T) { + mt := microvmMachineType() + assert.Contains(t, mt, "microvm,") + assert.Contains(t, mt, "isa-serial=on") +} + +// --------------------------------------------------------------------------- +// writeFwCfgBlobs +// --------------------------------------------------------------------------- + +func TestWriteFwCfgBlobs_HappyPath(t *testing.T) { + // Use a temp dir as runtime dir so files land somewhere writable. + tmpDir := t.TempDir() + t.Setenv("XDG_RUNTIME_DIR", tmpDir) + + d := &Daemon{} + instanceID := "i-fwcfg-test" + input := &handlers_elbv2.SystemInstanceInput{ + NICs: []handlers_elbv2.NICConfig{ + {MAC: "02:aa:bb:cc:dd:01", CIDR: "10.0.1.5/24", Gateway: "10.0.1.1", IsDefault: true}, + }, + LBAgentEnv: "LB_BACKEND=10.0.1.10:8080\n", + CACert: "-----BEGIN CERTIFICATE-----\nfake\n-----END CERTIFICATE-----\n", + } + + entries, err := d.writeFwCfgBlobs(instanceID, input) + require.NoError(t, err) + require.Len(t, entries, 3) + + // Check names are as expected. + assert.Equal(t, "opt/spinifex/netcfg", entries[0].Name) + assert.Equal(t, "opt/spinifex/lb-agent-env", entries[1].Name) + assert.Equal(t, "opt/spinifex/ca-cert", entries[2].Name) + + // Verify files were written and contain expected content. + netcfgData, err := os.ReadFile(entries[0].File) + require.NoError(t, err) + assert.Contains(t, string(netcfgData), "NIC0_MAC=02:aa:bb:cc:dd:01") + + lbenvData, err := os.ReadFile(entries[1].File) + require.NoError(t, err) + assert.Equal(t, "LB_BACKEND=10.0.1.10:8080\n", string(lbenvData)) + + cacertData, err := os.ReadFile(entries[2].File) + require.NoError(t, err) + assert.Contains(t, string(cacertData), "BEGIN CERTIFICATE") + + // Cleanup: remove the tmpfiles (proves they are real filesystem files). + for _, e := range entries { + assert.NoError(t, os.Remove(e.File)) + } +} + +func TestWriteFwCfgBlobs_InvalidNICs_NoDefault(t *testing.T) { + tmpDir := t.TempDir() + t.Setenv("XDG_RUNTIME_DIR", tmpDir) + + d := &Daemon{} + input := &handlers_elbv2.SystemInstanceInput{ + NICs: []handlers_elbv2.NICConfig{ + {MAC: "02:aa:bb:cc:dd:01", IsDefault: false}, + }, + } + + _, err := d.writeFwCfgBlobs("i-bad-nics", input) + require.Error(t, err) + assert.Contains(t, err.Error(), "IsDefault") + + // No tmpfiles must be left behind. + entries, _ := os.ReadDir(tmpDir) + for _, e := range entries { + assert.False(t, strings.HasPrefix(e.Name(), "fwcfg-i-bad-nics"), + "unexpected tmpfile left behind: %s", e.Name()) + } +} diff --git a/spinifex/daemon/network.go b/spinifex/daemon/network.go index c92887fd2..92acca76d 100644 --- a/spinifex/daemon/network.go +++ b/spinifex/daemon/network.go @@ -6,6 +6,7 @@ import ( "net" "os" "os/exec" + "os/user" "sort" "strings" @@ -48,7 +49,20 @@ func (p *OVSNetworkPlumber) SetupTap(spec vm.TapSpec) error { } } - if out, err := sudoCommand("ip", "tuntap", "add", "dev", spec.Name, "mode", "tap").CombinedOutput(); err != nil { + // When the daemon runs non-root (production: User=spinifex-daemon), child + // QEMU processes inherit that uid without CAP_NET_ADMIN. The kernel's tun + // attach check then requires the tap to be owned by the calling euid + // (drivers/net/tun.c: tun_chr_open + TUNSETIFF perm check). Without the + // `user` flag the tap defaults to root:root and qemu's TUNSETIFF fails + // with EPERM ("could not configure /dev/net/tun: Operation not permitted"). + // Root daemons skip this — they have CAP_NET_ADMIN ambient. + addArgs := []string{"tuntap", "add", "dev", spec.Name, "mode", "tap"} + if os.Geteuid() != 0 { + if u, err := user.Current(); err == nil { + addArgs = append(addArgs, "user", u.Username, "group", u.Gid) + } + } + if out, err := sudoCommand("ip", addArgs...).CombinedOutput(); err != nil { return fmt.Errorf("create tap %s: %s: %w", spec.Name, strings.TrimSpace(string(out)), err) } diff --git a/spinifex/daemon/perf_bench_test.go b/spinifex/daemon/perf_bench_test.go new file mode 100644 index 000000000..eca758e4d --- /dev/null +++ b/spinifex/daemon/perf_bench_test.go @@ -0,0 +1,62 @@ +package daemon + +import ( + "os" + "testing" +) + +// Phase gate constants — changing these is a deliberate decision. +const ( + phase1BootGateMs = 500 + phase1RSSGateMiB = 25 + + phase2BootGateMs = 300 + phase2ArtifactGateMiB = 50 +) + +func TestBootGate_Phase1(t *testing.T) { + if phase1BootGateMs != 500 { + t.Errorf("Phase 1 boot gate changed: got %d, want 500", phase1BootGateMs) + } + if phase1RSSGateMiB != 25 { + t.Errorf("Phase 1 RSS gate changed: got %d, want 25", phase1RSSGateMiB) + } +} + +func TestBootGate_Phase2(t *testing.T) { + if phase2BootGateMs != 300 { + t.Errorf("Phase 2 boot gate changed: got %d, want 300", phase2BootGateMs) + } + if phase2ArtifactGateMiB != 50 { + t.Errorf("Phase 2 artifact gate changed: got %d, want 50", phase2ArtifactGateMiB) + } +} + +func TestMeasureQEMURSSMiB_Self(t *testing.T) { + rss, err := measureQEMURSSMiB(os.Getpid()) + if err != nil { + t.Fatalf("measureQEMURSSMiB self: %v", err) + } + if rss <= 0 { + t.Errorf("expected RSS > 0, got %f", rss) + } + if rss > 1024 { + t.Errorf("RSS %f MiB seems unreasonably high for a test process", rss) + } +} + +func TestMeasureQEMURSSMiB_InvalidPID(t *testing.T) { + for _, pid := range []int{0, -1, -999} { + _, err := measureQEMURSSMiB(pid) + if err == nil { + t.Errorf("expected error for pid=%d, got nil", pid) + } + } +} + +func TestMeasureQEMURSSMiB_NonExistentPID(t *testing.T) { + _, err := measureQEMURSSMiB(999999999) + if err == nil { + t.Error("expected error for non-existent pid, got nil") + } +} diff --git a/spinifex/daemon/perf_helpers.go b/spinifex/daemon/perf_helpers.go new file mode 100644 index 000000000..b7f04cff3 --- /dev/null +++ b/spinifex/daemon/perf_helpers.go @@ -0,0 +1,39 @@ +package daemon + +import ( + "bufio" + "fmt" + "os" + "strconv" + "strings" +) + +// measureQEMURSSMiB reads /proc//status and returns RSS in MiB. +func measureQEMURSSMiB(pid int) (float64, error) { + if pid <= 0 { + return 0, fmt.Errorf("invalid pid: %d", pid) + } + f, err := os.Open(fmt.Sprintf("/proc/%d/status", pid)) + if err != nil { + return 0, fmt.Errorf("open /proc/%d/status: %w", pid, err) + } + defer f.Close() + + scanner := bufio.NewScanner(f) + for scanner.Scan() { + line := scanner.Text() + if !strings.HasPrefix(line, "VmRSS:") { + continue + } + fields := strings.Fields(line) + if len(fields) < 2 { + return 0, fmt.Errorf("unexpected VmRSS format: %q", line) + } + kb, err := strconv.ParseFloat(fields[1], 64) + if err != nil { + return 0, fmt.Errorf("parse VmRSS kB: %w", err) + } + return kb / 1024, nil + } + return 0, fmt.Errorf("VmRSS not found in /proc/%d/status", pid) +} diff --git a/spinifex/handlers/ec2/instance/helpers_test.go b/spinifex/handlers/ec2/instance/helpers_test.go index aaec500e2..5f690b912 100644 --- a/spinifex/handlers/ec2/instance/helpers_test.go +++ b/spinifex/handlers/ec2/instance/helpers_test.go @@ -67,5 +67,5 @@ func TestGenerateNetworkConfig_MgmtIPWithoutMAC(t *testing.T) { assert.NotContains(t, cfg, "mgmt0:", "mgmt NIC should not appear without MAC") } -// Route for multi-node is handled via bootcmd in lbVMUserData, not -// in the network-config (Alpine cloud-init doesn't support v2 routes). +// Route for multi-node LB mgmt traffic is handled via the fw_cfg netcfg +// blob delivered to the LB microVM, not in the network-config. diff --git a/spinifex/handlers/ec2/instance/service_impl.go b/spinifex/handlers/ec2/instance/service_impl.go index 93d106ba6..6a9d8761b 100644 --- a/spinifex/handlers/ec2/instance/service_impl.go +++ b/spinifex/handlers/ec2/instance/service_impl.go @@ -149,8 +149,8 @@ func generateNetworkConfig(eniMAC, devMAC, mgmtMAC, mgmtIP string, extraENIMACs addresses: - "%s/24" `, mgmtMAC, mgmtIP) - // Route for multi-node is added via bootcmd in lbVMUserData (Alpine - // cloud-init does not support v2 routes under ethernets). + // Route for multi-node LB mgmt traffic is delivered to the LB microVM + // via the fw_cfg netcfg blob, not here. } return cfg @@ -877,7 +877,20 @@ func (s *InstanceServiceImpl) newViperblock(volumeName string, size int, volumeC VolumeConfig: volumeConfig, } - return viperblock.New(&vbconfig, "s3", cfg) + vb, err := viperblock.New(&vbconfig, "s3", cfg) + restoreSlogDefault() + return vb, err +} + +// restoreSlogDefault re-installs the daemon's Info-level slog handler after +// viperblock.New mutates the global slog default via its SetDebug method +// (see viperblock.go SetDebug — it calls slog.SetDefault with LevelError, +// silencing every Info/Warn in the entire process). Tracked for proper fix +// in viperblock as mulga-siv-70. +func restoreSlogDefault() { + slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{ + Level: slog.LevelInfo, + }))) } // prepareRootVolume handles creation/cloning of the root volume @@ -888,8 +901,6 @@ func (s *InstanceServiceImpl) prepareRootVolume(input *ec2.RunInstancesInput, im return errors.New(awserrors.ErrorServerInternal) } - vb.SetDebug(false) - // Initialize the backend err = vb.Backend.Init() if err != nil { @@ -996,8 +1007,6 @@ func (s *InstanceServiceImpl) prepareEFIVolume(imageId string, volumeConfig vipe return errors.New(awserrors.ErrorServerInternal) } - efiVb.SetDebug(false) - // Initialize the backend slog.Debug("Initializing EFI Viperblock store backend") err = efiVb.Backend.Init() @@ -1083,8 +1092,6 @@ func (s *InstanceServiceImpl) prepareCloudInitVolume(input *ec2.RunInstancesInpu return errors.New(awserrors.ErrorServerInternal) } - cloudInitVb.SetDebug(false) - // Initialize the backend slog.Debug("Initializing cloud-init Viperblock store backend") err = cloudInitVb.Backend.Init() diff --git a/spinifex/handlers/elbv2/arn_test.go b/spinifex/handlers/elbv2/arn_test.go index 06dca3024..cea5ca05a 100644 --- a/spinifex/handlers/elbv2/arn_test.go +++ b/spinifex/handlers/elbv2/arn_test.go @@ -4,63 +4,16 @@ import ( "strings" "testing" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/ec2" + "github.com/aws/aws-sdk-go/service/elbv2" + "github.com/mulgadc/spinifex/spinifex/config" + handlers_ec2_vpc "github.com/mulgadc/spinifex/spinifex/handlers/ec2/vpc" + "github.com/mulgadc/spinifex/spinifex/testutil" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -// extractAgentEnv parses the cloud-config user-data into the env-var map that -// cloud-init will write to /etc/conf.d/lb-agent. We don't pull in a YAML -// dependency just for tests — the format is stable enough that line-based -// parsing catches the things substring matching misses (misplaced keys, -// broken indentation, content that escaped the agent-conf block). -// -// Returns the parsed env map plus the `runcmd:` section's body (raw lines) -// so callers can assert on the launch command shape. -func extractAgentEnv(t *testing.T, ud string) (envs map[string]string, runcmd []string) { - t.Helper() - require.True(t, strings.HasPrefix(ud, "#cloud-config\n"), - "user-data must start with #cloud-config directive") - - envs = map[string]string{} - const agentPathMarker = " - path: /etc/conf.d/lb-agent" - const contentMarker = " content: |" - const envIndent = " " // 6 spaces under `content: |` - - lines := strings.Split(ud, "\n") - inAgentEnv := false - inRuncmd := false - for i := 0; i < len(lines); i++ { - line := lines[i] - switch { - case line == agentPathMarker: - require.Less(t, i+1, len(lines), "agent path entry truncated") - require.Equal(t, contentMarker, lines[i+1], - "agent path must be followed by `content: |` block") - inAgentEnv = true - i++ // skip the content marker - case inAgentEnv: - if !strings.HasPrefix(line, envIndent) { - inAgentEnv = false - i-- // re-process this line in case it starts another section - continue - } - kv := strings.TrimPrefix(line, envIndent) - k, v, ok := strings.Cut(kv, "=") - require.True(t, ok, "agent env line missing '=': %q", line) - envs[k] = v - case line == "runcmd:": - inRuncmd = true - case inRuncmd: - if !strings.HasPrefix(line, " ") { - inRuncmd = false - continue - } - runcmd = append(runcmd, line) - } - } - return envs, runcmd -} - func TestBuildLBArn(t *testing.T) { arn := buildLBArn("us-east-1", "123456789012", "my-alb", "50dc6c495c0c9188", LoadBalancerTypeApplication) assert.Equal(t, "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/my-alb/50dc6c495c0c9188", arn) @@ -86,70 +39,234 @@ func TestBuildListenerArn_NLB(t *testing.T) { assert.Equal(t, "arn:aws:elasticloadbalancing:eu-west-1:999888777666:listener/net/my-nlb/lbid123/listener456", arn) } -// TestLbVMUserData_Structural parses the generated cloud-config and asserts -// the structure: agent env vars land in /etc/conf.d/lb-agent, runcmd starts -// lb-agent via OpenRC (not the bare binary), the CA cert section — owned by -// the instance service's cloud-init template — is absent, and no bootcmd is -// emitted in the single-node default. -func TestLbVMUserData_Structural(t *testing.T) { +// TestBuildLBAgentEnv verifies that buildLBAgentEnv produces a KEY=value blob +// containing all five env vars with the correct values. +func TestBuildLBAgentEnv(t *testing.T) { svc := &ELBv2ServiceImpl{ - GatewayURL: "https://192.168.1.33:9999", + GatewayURL: "https://10.0.0.1:9999", SystemAccessKey: "AKIAIOSFODNN7EXAMPLE", SystemSecretKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", region: "ap-southeast-2", } - ud, err := svc.lbVMUserData("lb-abc123", SchemeInternetFacing) + env := svc.buildLBAgentEnv("lb-abc123") + + lines := strings.Split(strings.TrimRight(env, "\n"), "\n") + kvs := make(map[string]string, len(lines)) + for _, l := range lines { + k, v, ok := strings.Cut(l, "=") + require.True(t, ok, "env line missing '=': %q", l) + kvs[k] = v + } + + assert.Equal(t, "lb-abc123", kvs["LB_LB_ID"]) + assert.Equal(t, "https://10.0.0.1:9999", kvs["LB_GATEWAY_URL"]) + assert.Equal(t, "AKIAIOSFODNN7EXAMPLE", kvs["LB_ACCESS_KEY"]) + assert.Equal(t, "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", kvs["LB_SECRET_KEY"]) + assert.Equal(t, "ap-southeast-2", kvs["LB_REGION"]) +} + +// TestSubnetCIDRForIP and TestSubnetGatewayIP cover the CIDR helpers. +func TestSubnetCIDRForIP(t *testing.T) { + assert.Equal(t, "10.0.1.5/24", subnetCIDRForIP("10.0.1.5", "10.0.1.0/24")) + assert.Equal(t, "172.16.2.10/20", subnetCIDRForIP("172.16.2.10", "172.16.0.0/20")) + assert.Equal(t, "", subnetCIDRForIP("10.0.1.5", "bad-cidr")) +} + +func TestSubnetGatewayIP(t *testing.T) { + assert.Equal(t, "10.0.1.1", subnetGatewayIP("10.0.1.0/24")) + assert.Equal(t, "172.16.0.1", subnetGatewayIP("172.16.0.0/20")) + assert.Equal(t, "", subnetGatewayIP("not-a-cidr")) +} + +// setupMicrovmTestService creates an ELBv2 service wired to a real VPC +// service. The VPC has one subnet (10.0.1.0/24) pre-created. +func setupMicrovmTestService(t *testing.T) (*ELBv2ServiceImpl, *handlers_ec2_vpc.VPCServiceImpl, string) { + t.Helper() + _, nc, _ := testutil.StartTestJetStream(t) + testutil.StubVpcdSGResponder(t, nc) + + vpcSvc, err := handlers_ec2_vpc.NewVPCServiceImplWithNATS(nil, nc) require.NoError(t, err) - envs, runcmd := extractAgentEnv(t, ud) - assert.Equal(t, map[string]string{ - "LB_LB_ID": "lb-abc123", - "LB_GATEWAY_URL": "https://192.168.1.33:9999", - "LB_ACCESS_KEY": "AKIAIOSFODNN7EXAMPLE", - "LB_SECRET_KEY": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY", - "LB_REGION": "ap-southeast-2", - }, envs) - for k := range envs { - assert.NotContains(t, k, "NATS", "NATS URL must not leak into agent config") + cfg := &config.Config{ + Daemon: config.DaemonConfig{ + DevNetworking: true, + }, } + elbv2Svc, err := NewELBv2ServiceImplWithNATS(cfg, nc) + require.NoError(t, err) + elbv2Svc.VPCService = vpcSvc + elbv2Svc.GatewayURL = "https://10.20.0.5:9999" + elbv2Svc.SystemAccessKey = "AKID" + elbv2Svc.SystemSecretKey = "SECRET" + elbv2Svc.region = "us-east-1" + elbv2Svc.CACert = "-----BEGIN CERTIFICATE-----\nMOCK\n-----END CERTIFICATE-----\n" - // Agent is launched via OpenRC, never as a bare binary path. - require.Len(t, runcmd, 1) - assert.Contains(t, runcmd[0], `[ "rc-service", "lb-agent", "start" ]`) - assert.NotContains(t, ud, "/usr/local/bin/lb-agent") + vpcOut, err := vpcSvc.CreateVpc(&ec2.CreateVpcInput{ + CidrBlock: aws.String("10.0.0.0/16"), + }, testAccountID) + require.NoError(t, err) + vpcID := *vpcOut.Vpc.VpcId - // CA cert is injected upstream by the instance service's template. - assert.NotContains(t, ud, "ca_certs:") + subnetOut, err := vpcSvc.CreateSubnet(&ec2.CreateSubnetInput{ + VpcId: aws.String(vpcID), + CidrBlock: aws.String("10.0.1.0/24"), + AvailabilityZone: aws.String("us-east-1a"), + }, testAccountID) + require.NoError(t, err) + subnetID := *subnetOut.Subnet.SubnetId - // Single-node default: no MgmtRoute set means no bootcmd. - assert.NotContains(t, ud, "bootcmd:") + return elbv2Svc, vpcSvc, subnetID } -// TestLbVMUserData_MissingCredentials covers the three required-field error -// paths (gateway URL, access key, secret key) in one table-driven test. -func TestLbVMUserData_MissingCredentials(t *testing.T) { - tests := []struct { - name string - svc *ELBv2ServiceImpl - }{ - { - name: "missing GatewayURL", - svc: &ELBv2ServiceImpl{SystemAccessKey: "AKID", SystemSecretKey: "SECRET"}, - }, - { - name: "missing SystemAccessKey", - svc: &ELBv2ServiceImpl{GatewayURL: "https://10.0.0.1:9999", SystemSecretKey: "SECRET"}, - }, - { - name: "missing SystemSecretKey", - svc: &ELBv2ServiceImpl{GatewayURL: "https://10.0.0.1:9999", SystemAccessKey: "AKID"}, +// TestCreateLoadBalancer_DeliversCACert asserts the CACert plumbed into the +// service is forwarded to the launcher for fw_cfg delivery. +func TestCreateLoadBalancer_DeliversCACert(t *testing.T) { + svc, _, subnetID := setupMicrovmTestService(t) + + mock := &mockSystemInstanceLauncher{ + launchResult: &SystemInstanceOutput{ + InstanceID: "i-microvm-test", + PrivateIP: "10.0.1.5", }, } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - _, err := tt.svc.lbVMUserData("lb-test", SchemeInternetFacing) - require.Error(t, err) - assert.Contains(t, err.Error(), "missing system credentials") - }) - } + svc.InstanceLauncher = mock + + _, err := svc.CreateLoadBalancer(&elbv2.CreateLoadBalancerInput{ + Name: aws.String("mv-alb"), + Subnets: []*string{aws.String(subnetID)}, + }, testAccountID) + require.NoError(t, err) + + require.Len(t, mock.launchCalls, 1) + assert.Equal(t, "-----BEGIN CERTIFICATE-----\nMOCK\n-----END CERTIFICATE-----\n", + mock.launchCalls[0].CACert) +} + +// TestCreateLoadBalancer_Microvm_LBAgentEnv asserts all five lb-agent env vars +// appear in LBAgentEnv with correct values. +func TestCreateLoadBalancer_Microvm_LBAgentEnv(t *testing.T) { + svc, _, subnetID := setupMicrovmTestService(t) + + mock := &mockSystemInstanceLauncher{ + launchResult: &SystemInstanceOutput{InstanceID: "i-env-test", PrivateIP: "10.0.1.6"}, + } + svc.InstanceLauncher = mock + + _, err := svc.CreateLoadBalancer(&elbv2.CreateLoadBalancerInput{ + Name: aws.String("env-alb"), + Subnets: []*string{aws.String(subnetID)}, + }, testAccountID) + require.NoError(t, err) + require.Len(t, mock.launchCalls, 1) + + envBlob := mock.launchCalls[0].LBAgentEnv + kvs := parseEnvBlob(t, envBlob) + + assert.NotEmpty(t, kvs["LB_LB_ID"]) + assert.Equal(t, "https://10.20.0.5:9999", kvs["LB_GATEWAY_URL"]) + assert.Equal(t, "AKID", kvs["LB_ACCESS_KEY"]) + assert.Equal(t, "SECRET", kvs["LB_SECRET_KEY"]) + assert.Equal(t, "us-east-1", kvs["LB_REGION"]) +} + +// TestCreateLoadBalancer_Microvm_NICs asserts NIC[0].IsDefault=true and +// NIC[1].IsDefault=false, and that CIDR/Gateway are derived from the subnet. +func TestCreateLoadBalancer_Microvm_NICs(t *testing.T) { + svc, _, subnetID := setupMicrovmTestService(t) + + mock := &mockSystemInstanceLauncher{ + launchResult: &SystemInstanceOutput{InstanceID: "i-nic-test", PrivateIP: "10.0.1.7"}, + } + svc.InstanceLauncher = mock + + _, err := svc.CreateLoadBalancer(&elbv2.CreateLoadBalancerInput{ + Name: aws.String("nic-alb"), + Subnets: []*string{aws.String(subnetID)}, + }, testAccountID) + require.NoError(t, err) + require.Len(t, mock.launchCalls, 1) + + nics := mock.launchCalls[0].NICs + require.GreaterOrEqual(t, len(nics), 2, "must have at least primary ENI NIC and mgmt NIC") + + // NIC[0]: primary VPC ENI — must be the default route owner. + assert.True(t, nics[0].IsDefault, "NIC[0] must have IsDefault=true") + assert.NotEmpty(t, nics[0].MAC, "NIC[0] MAC must be populated from ENI") + assert.Contains(t, nics[0].CIDR, "/24", "NIC[0] CIDR must include prefix from subnet") + assert.Equal(t, "10.0.1.1", nics[0].Gateway, "NIC[0] gateway must be subnet .1 address") + + // NIC[1]: management NIC — daemon allocates IP/MAC. + assert.False(t, nics[1].IsDefault, "NIC[1] must have IsDefault=false") +} + +// parseEnvBlob parses a KEY=value newline-separated blob into a map. +func parseEnvBlob(t *testing.T, blob string) map[string]string { + t.Helper() + kvs := make(map[string]string) + for line := range strings.SplitSeq(strings.TrimRight(blob, "\n"), "\n") { + if line == "" { + continue + } + k, v, ok := strings.Cut(line, "=") + require.True(t, ok, "env blob line missing '=': %q", line) + kvs[k] = v + } + return kvs +} + +// TestBuildMicrovmNICs_NilVPC verifies buildMicrovmNICs works when VPCService +// is nil — CIDR and gateway remain empty, NIC structure is still correct. +func TestBuildMicrovmNICs_NilVPC(t *testing.T) { + svc := &ELBv2ServiceImpl{VPCService: nil} + nics := svc.buildMicrovmNICs("10.0.1.5", "02:aa:bb:cc:dd:01", "subnet-abc", "eni-abc", SchemeInternal, nil, testAccountID) + require.Len(t, nics, 2, "primary ENI NIC + mgmt NIC") + assert.True(t, nics[0].IsDefault) + assert.Equal(t, "02:aa:bb:cc:dd:01", nics[0].MAC) + assert.Empty(t, nics[0].CIDR, "CIDR unknown when VPC service unavailable") + assert.False(t, nics[1].IsDefault) +} + +// TestBuildMicrovmNICs_ExtraENIs verifies NIC[2+] are appended for multi-subnet ALBs. +func TestBuildMicrovmNICs_ExtraENIs(t *testing.T) { + svc := &ELBv2ServiceImpl{VPCService: nil} + extras := []ExtraENIInput{ + {ENIID: "eni-extra1", ENIMac: "02:aa:bb:cc:dd:02", ENIIP: "10.0.2.5", SubnetID: "subnet-extra1"}, + } + nics := svc.buildMicrovmNICs("10.0.1.5", "02:aa:bb:cc:dd:01", "subnet-abc", "eni-abc", SchemeInternal, extras, testAccountID) + require.Len(t, nics, 3, "primary ENI + mgmt + 1 extra") + assert.Equal(t, "02:aa:bb:cc:dd:02", nics[2].MAC) + assert.False(t, nics[2].IsDefault) +} + +// TestBuildMicrovmNICs_MgmtRoute covers the same single-node/multi-node matrix +// as TestLBVMUserData_InternalSingleNodeFallback: internet-facing single-node +// must NOT emit a /32 via mgmt to AdvertiseIP because that steals the host's +// WAN return path for reply traffic, breaking same-chassis ingress. +func TestBuildMicrovmNICs_MgmtRoute(t *testing.T) { + mk := func() *ELBv2ServiceImpl { + return &ELBv2ServiceImpl{ + VPCService: nil, + MgmtBridgeIP: "10.15.8.1", + AdvertiseIP: "192.168.1.33", + } + } + + internal := mk().buildMicrovmNICs("10.0.1.5", "02:aa:bb:cc:dd:01", "subnet-abc", "eni-abc", SchemeInternal, nil, testAccountID) + require.Len(t, internal, 2) + assert.Equal(t, "192.168.1.33", internal[1].RouteDst, "internal single-node forces /32 via mgmt") + assert.Equal(t, "10.15.8.1", internal[1].RouteVia) + + inet := mk().buildMicrovmNICs("10.0.1.5", "02:aa:bb:cc:dd:01", "subnet-abc", "eni-abc", SchemeInternetFacing, nil, testAccountID) + require.Len(t, inet, 2) + assert.Empty(t, inet[1].RouteDst, "internet-facing single-node must not /32 AdvertiseIP via mgmt") + assert.Empty(t, inet[1].RouteVia) + + multi := mk() + multi.MgmtRouteGateway = "10.15.8.1" + multi.MgmtRouteTarget = "10.15.8.100" + nics := multi.buildMicrovmNICs("10.0.1.5", "02:aa:bb:cc:dd:01", "subnet-abc", "eni-abc", SchemeInternetFacing, nil, testAccountID) + require.Len(t, nics, 2) + assert.Equal(t, "10.15.8.100", nics[1].RouteDst, "multi-node uses explicit MgmtRouteTarget") + assert.Equal(t, "10.15.8.1", nics[1].RouteVia) } diff --git a/spinifex/handlers/elbv2/launcher.go b/spinifex/handlers/elbv2/launcher.go index 7ee0be60f..ad1dd8570 100644 --- a/spinifex/handlers/elbv2/launcher.go +++ b/spinifex/handlers/elbv2/launcher.go @@ -19,15 +19,15 @@ type SystemInstanceLauncher interface { TerminateSystemInstance(instanceID string) error } -// SystemInstanceInput describes the VM to launch. +// SystemInstanceInput describes the direct-boot microVM to launch for an +// ELBv2 load balancer. There is no AMI or cloud-init path — kernel and +// initrd come from the bundled spinifex package and per-VM config is +// delivered via QEMU fw_cfg blobs. type SystemInstanceInput struct { - InstanceType string // e.g. "t3.nano" - ImageID string // AMI ID + InstanceType string // e.g. "sys.micro" SubnetID string // VPC subnet for networking - UserData string // Cloud-init user data (plain text, will be base64-encoded) - // ENI fields — if ENIID is set, the VM uses this pre-created ENI instead - // of auto-creating one. Used for ALB VMs that reuse the ALB's ENI. + // ENI fields — the VM always uses a pre-created ENI (the ALB's primary ENI). ENIID string ENIMac string ENIIP string @@ -49,6 +49,17 @@ type SystemInstanceInput struct { // via the QEMU user-mode dev NIC (dev_networking mode only). // Each entry is a guest port (e.g. 80, 443). The host port is auto-assigned. HostfwdPorts []int + + // NICs defines the network interfaces for the microVM. + // Index 0 is the primary VPC ENI, index 1 is the management NIC, index 2+ are extra ENIs. + NICs []NICConfig + + // LBAgentEnv is a KEY=value blob written to /etc/conf.d/lb-agent inside + // the guest via fw_cfg. + LBAgentEnv string + + // CACert holds PEM-encoded CA certificate bytes delivered to the guest via fw_cfg. + CACert string } // ExtraENIInput describes an additional pre-created ENI to attach to a @@ -60,6 +71,17 @@ type ExtraENIInput struct { SubnetID string } +// NICConfig describes a single network interface for a microVM direct-boot launch. +// Index 0 is the primary VPC ENI, index 1 is the management NIC, index 2+ are extra ENIs. +type NICConfig struct { + MAC string // e.g. "02:0a:01:23:45:67" + CIDR string // e.g. "10.0.1.5/24" + Gateway string // e.g. "10.0.1.1"; empty for mgmt NIC + IsDefault bool // true for exactly one NIC (primary VPC ENI) + RouteDst string // specific host route dst, e.g. "10.20.0.5/32" + RouteVia string // next-hop for RouteDst +} + // SystemInstanceOutput contains the result of a successful launch. type SystemInstanceOutput struct { InstanceID string // e.g. "i-xxxxx" diff --git a/spinifex/handlers/elbv2/service_impl.go b/spinifex/handlers/elbv2/service_impl.go index 641e063f2..284d85d57 100644 --- a/spinifex/handlers/elbv2/service_impl.go +++ b/spinifex/handlers/elbv2/service_impl.go @@ -7,6 +7,7 @@ import ( "fmt" "log/slog" "maps" + "net" "regexp" "slices" "strings" @@ -64,45 +65,10 @@ func validateHealthCheckMatcher(m string) error { return nil } -// lbVMUserData generates cloud-config user data for a load balancer VM. -// Uses write_files to populate /etc/conf.d/lb-agent with the lb-id, gateway -// URL, and system credentials for SigV4 auth. The CA cert is already injected -// by the instance service's cloud-init template (same as regular EC2 VMs). -// Cloud-init guarantees write_files runs before runcmd. The service is NOT -// enabled at boot in the image — cloud-init is the sole trigger so the env -// vars are always present before the agent starts. -func (s *ELBv2ServiceImpl) lbVMUserData(lbID, scheme string) (string, error) { - if s.GatewayURL == "" || s.SystemAccessKey == "" || s.SystemSecretKey == "" { - return "", fmt.Errorf("missing system credentials: gatewayURL=%q accessKey=%q secretKey-set=%t", - s.GatewayURL, s.SystemAccessKey, s.SystemSecretKey != "") - } - - cfg := fmt.Sprintf(`#cloud-config -write_files: - - path: /etc/conf.d/lb-agent - content: | - LB_LB_ID=%s - LB_GATEWAY_URL=%s - LB_ACCESS_KEY=%s - LB_SECRET_KEY=%s - LB_REGION=%s -`, lbID, s.GatewayURL, s.SystemAccessKey, s.SystemSecretKey, s.region) - - mgmtGW, mgmtTarget := s.resolveMgmtRoute(scheme) - if mgmtGW != "" && mgmtTarget != "" { - cfg += fmt.Sprintf(`bootcmd: - - [ "ip", "route", "add", "%s/32", "via", "%s" ] -`, mgmtTarget, mgmtGW) - } - - cfg += `runcmd: - - [ "rc-service", "lb-agent", "start" ] -` - return cfg, nil -} - -// resolveMgmtRoute returns the (gateway, target) pair for the bootcmd host -// route the lb-agent uses to reach AWSGW, or empty strings to skip the route. +// resolveMgmtRoute returns the (gateway, target) pair for the host route the +// lb-agent uses to reach AWSGW from inside the LB microVM, or empty strings +// to skip the route. Consumed by buildMicrovmNICs to populate NIC[1]'s +// RouteDst/RouteVia for the netcfg fw_cfg blob. // // Multi-node (AWSGW on dedicated mgmt IP): MgmtRoute{Gateway,Target} are set // by the daemon for both schemes — return them. @@ -141,16 +107,13 @@ type ELBv2ServiceImpl struct { MgmtRouteTarget string // AWSGW bind IP to route via mgmt NIC MgmtBridgeIP string // br-mgmt IP, populated whenever br-mgmt exists (single + multi node) for the internal-scheme fallback route AdvertiseIP string // AdvertiseIP / WAN gateway, populated whenever set; used as the internal-scheme fallback route target on single-node + CACert string // PEM-encoded CA certificate delivered to microvm guests via fw_cfg nodeID string region string - systemAMI string // AMI ID for system VMs (ALB VMs); resolved lazily via systemAMIFunc - systemAMIFunc func() (string, error) // returns the current system AMI ID (queries image store) - systemAMIMu sync.Mutex // guards lazy resolution of systemAMI - systemAMIResolved bool // true once systemAMI has been resolved to a non-empty value - systemInstanceType string // instance type for system VMs; resolved lazily via systemInstanceTypeFunc - systemInstanceTypeFunc func() string // returns the smallest available instance type - systemInstanceTypeMu sync.Mutex // guards lazy resolution of systemInstanceType - systemInstanceTypeResolved bool // true once systemInstanceType has been resolved to a non-empty value + systemInstanceType string // instance type for system VMs; resolved lazily via systemInstanceTypeFunc + systemInstanceTypeFunc func() string // returns the smallest available instance type + systemInstanceTypeMu sync.Mutex // guards lazy resolution of systemInstanceType + systemInstanceTypeResolved bool // true once systemInstanceType has been resolved to a non-empty value ctx context.Context cancel context.CancelFunc hc *healthChecker @@ -194,39 +157,6 @@ func (s *ELBv2ServiceImpl) Close() { } } -// SetSystemAMIFunc sets a function that resolves the current system AMI ID. -// This is called at request time so the AMI is discovered even if imported -// after the daemon starts. -func (s *ELBv2ServiceImpl) SetSystemAMIFunc(fn func() (string, error)) { - s.systemAMIMu.Lock() - defer s.systemAMIMu.Unlock() - s.systemAMIFunc = fn - s.systemAMI = "" - s.systemAMIResolved = false -} - -// getSystemAMI returns the system AMI ID, resolving it lazily if needed. -// Caches only successful resolutions so the resolver retries after errors. -func (s *ELBv2ServiceImpl) getSystemAMI() (string, error) { - s.systemAMIMu.Lock() - defer s.systemAMIMu.Unlock() - if s.systemAMIResolved { - return s.systemAMI, nil - } - if s.systemAMIFunc == nil { - return "", nil - } - ami, err := s.systemAMIFunc() - if err != nil { - return "", err - } - if ami != "" { - s.systemAMI = ami - s.systemAMIResolved = true - } - return ami, nil -} - // SetSystemInstanceTypeFunc sets a function that resolves the smallest available // instance type. Called at request time so it adapts to node capacity. func (s *ELBv2ServiceImpl) SetSystemInstanceTypeFunc(fn func() string) { @@ -255,6 +185,111 @@ func (s *ELBv2ServiceImpl) getSystemInstanceType() string { return s.systemInstanceType } +// buildLBAgentEnv returns the KEY=value blob written to /etc/conf.d/lb-agent +// via fw_cfg on the direct-boot path. +func (s *ELBv2ServiceImpl) buildLBAgentEnv(lbID string) string { + return fmt.Sprintf("LB_LB_ID=%s\nLB_GATEWAY_URL=%s\nLB_ACCESS_KEY=%s\nLB_SECRET_KEY=%s\nLB_REGION=%s\n", + lbID, s.GatewayURL, s.SystemAccessKey, s.SystemSecretKey, s.region) +} + +// subnetCIDRForIP computes "ip/prefixlen" given a host IP and the subnet's +// CIDR block (e.g. "10.0.1.0/24" → "10.0.1.5/24"). Returns empty string on +// parse failure so the caller can log and continue without panicking. +func subnetCIDRForIP(hostIP, subnetCIDR string) string { + _, ipNet, err := net.ParseCIDR(subnetCIDR) + if err != nil { + return "" + } + ones, _ := ipNet.Mask.Size() + return fmt.Sprintf("%s/%d", hostIP, ones) +} + +// subnetGatewayIP derives the gateway IP (network address +1) from a subnet +// CIDR block. Returns empty string on parse failure. +func subnetGatewayIP(subnetCIDR string) string { + _, ipNet, err := net.ParseCIDR(subnetCIDR) + if err != nil { + return "" + } + gw := ipNet.IP.To4() + if gw == nil { + return "" + } + gwCopy := make(net.IP, len(gw)) + copy(gwCopy, gw) + gwCopy[3]++ + return gwCopy.String() +} + +// buildMicrovmNICs constructs the NIC slice for a direct-boot microvm launch. +// +// NIC[0] is the primary VPC ENI (IsDefault=true): MAC/IP from the ENI record, +// CIDR from ip+subnet prefix, gateway = subnet network address +1. +// +// NIC[1] is the management NIC (IsDefault=false): MAC and CIDR are left empty +// here — the daemon injects them after allocating the per-instance mgmt IP. +// RouteDst/RouteVia encode the host route the lb-agent needs to reach AWSGW +// via the management interface (same logic as resolveMgmtRoute). +// +// NIC[2+] are extra VPC ENIs for multi-subnet ALBs. +func (s *ELBv2ServiceImpl) buildMicrovmNICs(primaryIP, primaryMAC, primarySubnetID, _, scheme string, extraENIs []ExtraENIInput, accountID string) []NICConfig { + // Resolve primary subnet CIDR for NIC[0] prefix and gateway. + primaryCIDR := "" + primaryGateway := "" + if s.VPCService != nil && primarySubnetID != "" { + if subnet, err := s.VPCService.GetSubnet(accountID, primarySubnetID); err == nil && subnet != nil { + primaryCIDR = subnetCIDRForIP(primaryIP, subnet.CidrBlock) + primaryGateway = subnetGatewayIP(subnet.CidrBlock) + } else { + slog.Warn("buildMicrovmNICs: could not look up primary subnet", "subnetId", primarySubnetID, "err", err) + } + } + + nics := []NICConfig{ + // NIC[0]: primary VPC ENI — default route owner. + { + MAC: primaryMAC, + CIDR: primaryCIDR, + Gateway: primaryGateway, + IsDefault: true, + }, + } + + // NIC[1]: management NIC — daemon fills MAC/CIDR after IP allocation. + // RouteDst = AWSGW IP (destination), RouteVia = br-mgmt IP (next-hop). + // Honor resolveMgmtRoute's deliberate empty return for single-node + // internet-facing: adding a /32 to AdvertiseIP via mgmt steals the host's + // WAN return path for reply traffic, breaking same-chassis ingress. + mgmtRouteGW, mgmtRouteTarget := s.resolveMgmtRoute(scheme) + nics = append(nics, NICConfig{ + IsDefault: false, + RouteDst: mgmtRouteTarget, // AWSGW IP — destination to reach + RouteVia: mgmtRouteGW, // br-mgmt IP — next-hop + }) + + // NIC[2+]: extra ENIs for multi-subnet ALBs. + for _, extra := range extraENIs { + extraCIDR := "" + extraGateway := "" + if s.VPCService != nil && extra.SubnetID != "" { + if subnet, err := s.VPCService.GetSubnet(accountID, extra.SubnetID); err == nil && subnet != nil { + extraCIDR = subnetCIDRForIP(extra.ENIIP, subnet.CidrBlock) + extraGateway = subnetGatewayIP(subnet.CidrBlock) + } else { + slog.Warn("buildMicrovmNICs: could not look up extra subnet", "subnetId", extra.SubnetID, "err", err) + } + } + nics = append(nics, NICConfig{ + MAC: extra.ENIMac, + CIDR: extraCIDR, + Gateway: extraGateway, + IsDefault: false, + }) + } + + return nics +} + // resolveENIBindAddr looks up the private IP of the first ENI belonging to the ALB. // Returns empty string if VPC service is unavailable or no ENIs exist. func (s *ELBv2ServiceImpl) resolveENIBindAddr(lb *LoadBalancerRecord) string { @@ -671,15 +706,6 @@ func (s *ELBv2ServiceImpl) CreateLoadBalancer(input *elbv2.CreateLoadBalancerInp var hostPorts map[int]int var launchFailed bool if s.InstanceLauncher != nil && len(eniIDs) > 0 && len(subnets) > 0 { - systemAMI, amiErr := s.getSystemAMI() - if amiErr != nil { - slog.Error("CreateLoadBalancer: cannot resolve LB system AMI", "lbId", lbID, "err", amiErr) - return nil, errors.New(awserrors.ErrorServerInternal) - } - if systemAMI == "" { - slog.Error("CreateLoadBalancer: LB system AMI not resolved", "lbId", lbID) - return nil, errors.New(awserrors.ErrorServerInternal) - } // Resolve MAC/IP for every ENI in one describe call. eniDetails := make(map[string]*ec2.NetworkInterface, len(eniIDs)) if s.VPCService != nil { @@ -721,23 +747,27 @@ func (s *ELBv2ServiceImpl) CreateLoadBalancer(input *elbv2.CreateLoadBalancerInp }) } - userData, udErr := s.lbVMUserData(lbID, scheme) - if udErr != nil { - slog.Error("CreateLoadBalancer: system credentials not configured — cannot launch ALB VM", "lbId", lbID, "err", udErr) + var launchInput *SystemInstanceInput + if s.GatewayURL == "" || s.SystemAccessKey == "" || s.SystemSecretKey == "" { + slog.Error("CreateLoadBalancer: system credentials not configured — cannot launch ALB VM", "lbId", lbID) launchFailed = true } else { - launchInput := &SystemInstanceInput{ + nics := s.buildMicrovmNICs(primaryIP, primaryMAC, subnets[0], eniIDs[0], scheme, extraENIInputs, accountID) + launchInput = &SystemInstanceInput{ InstanceType: s.getSystemInstanceType(), - ImageID: systemAMI, SubnetID: subnets[0], - UserData: userData, ENIID: eniIDs[0], ENIMac: primaryMAC, ENIIP: primaryIP, ExtraENIs: extraENIInputs, Scheme: scheme, AccountID: accountID, + NICs: nics, + LBAgentEnv: s.buildLBAgentEnv(lbID), + CACert: s.CACert, } + } + if !launchFailed && launchInput != nil { // Dev-mode only: forward HTTP/HTTPS ports from host for local testing. // In production (VPC networking), traffic reaches the ALB VM's VPC IP directly. if s.config != nil && s.config.Daemon.DevNetworking { diff --git a/spinifex/handlers/elbv2/service_impl_test.go b/spinifex/handlers/elbv2/service_impl_test.go index 27a510326..bea368ac6 100644 --- a/spinifex/handlers/elbv2/service_impl_test.go +++ b/spinifex/handlers/elbv2/service_impl_test.go @@ -1,7 +1,6 @@ package handlers_elbv2 import ( - "errors" "sort" "strings" "sync" @@ -1526,26 +1525,8 @@ func TestUpdateStoredConfig_SkipsWhenNoInstance(t *testing.T) { // --- Service lifecycle and setter tests --- -// TestGetSystemAMI_ColdStart and TestGetSystemInstanceType_ColdStart pin the -// no-resolver-wired path. TestGet*_RetryOn{Error,Empty} only exercise paths -// after a resolver is set, so they don't cover the boot-time race where a -// caller asks for the system AMI/instance type before LB-image import has -// installed the resolver. Cold-start must return empty + no error rather -// than panic on a nil func. - -func TestGetSystemAMI_ColdStart(t *testing.T) { - svc := setupTestService(t) - - ami, err := svc.getSystemAMI() - require.NoError(t, err) - assert.Empty(t, ami) - - svc.SetSystemAMIFunc(func() (string, error) { return "ami-system-001", nil }) - ami, err = svc.getSystemAMI() - require.NoError(t, err) - assert.Equal(t, "ami-system-001", ami) -} - +// TestGetSystemInstanceType_ColdStart pins the no-resolver-wired path — +// cold-start must return empty rather than panic on a nil func. func TestGetSystemInstanceType_ColdStart(t *testing.T) { svc := setupTestService(t) @@ -1555,38 +1536,6 @@ func TestGetSystemInstanceType_ColdStart(t *testing.T) { assert.Equal(t, "t3.micro", svc.getSystemInstanceType()) } -func TestGetSystemAMI_RetryOnError(t *testing.T) { - svc := setupTestService(t) - - calls := 0 - svc.SetSystemAMIFunc(func() (string, error) { - calls++ - if calls < 3 { - return "", errors.New("LB system image not imported") - } - return "ami-system-001", nil - }) - - // First two calls error — must NOT be cached - _, err := svc.getSystemAMI() - require.Error(t, err) - _, err = svc.getSystemAMI() - require.Error(t, err) - assert.Equal(t, 2, calls) - - // Third call succeeds — cached from now on - ami, err := svc.getSystemAMI() - require.NoError(t, err) - assert.Equal(t, "ami-system-001", ami) - assert.Equal(t, 3, calls) - - // Subsequent calls return cached value without re-invoking - ami, err = svc.getSystemAMI() - require.NoError(t, err) - assert.Equal(t, "ami-system-001", ami) - assert.Equal(t, 3, calls) -} - func TestGetSystemInstanceType_RetryOnEmpty(t *testing.T) { svc := setupTestService(t) @@ -1610,21 +1559,6 @@ func TestGetSystemInstanceType_RetryOnEmpty(t *testing.T) { assert.Equal(t, 2, calls) } -func TestGetSystemAMI_Concurrent(t *testing.T) { - svc := setupTestService(t) - svc.SetSystemAMIFunc(func() (string, error) { return "ami-system-001", nil }) - - var wg sync.WaitGroup - for range 50 { - wg.Go(func() { - got, err := svc.getSystemAMI() - assert.NoError(t, err) - assert.Equal(t, "ami-system-001", got) - }) - } - wg.Wait() -} - func TestGetSystemInstanceType_Concurrent(t *testing.T) { svc := setupTestService(t) svc.SetSystemInstanceTypeFunc(func() string { return "t3.micro" }) @@ -1639,54 +1573,6 @@ func TestGetSystemInstanceType_Concurrent(t *testing.T) { wg.Wait() } -func TestLBVMUserData_MgmtRoute(t *testing.T) { - svc := setupTestService(t) - svc.MgmtRouteGateway = "10.15.8.1" - svc.MgmtRouteTarget = "10.15.8.100" - svc.GatewayURL = "https://10.15.8.100:9999" - svc.SystemAccessKey = "AK" - svc.SystemSecretKey = "SK" - - data, err := svc.lbVMUserData("lb-test1", SchemeInternetFacing) - require.NoError(t, err) - assert.Contains(t, data, "bootcmd:") - assert.Contains(t, data, `"10.15.8.100/32"`) - assert.Contains(t, data, `"10.15.8.1"`) -} - -// TestLBVMUserData_InternalSingleNodeFallback covers the single-node case -// where MgmtRoute{Gateway,Target} are empty (AWSGW reachable on advertiseIP -// via VPC for internet-facing LBs) but an internal LB has no EIP and so -// needs a forced mgmt-NIC route to AWSGW. Internet-facing in the same setup -// must still get no bootcmd (would steal the host's WAN return path). -func TestLBVMUserData_InternalSingleNodeFallback(t *testing.T) { - mkSvc := func() *ELBv2ServiceImpl { - svc := setupTestService(t) - svc.GatewayURL = "https://192.168.1.33:9999" - svc.SystemAccessKey = "AK" - svc.SystemSecretKey = "SK" - svc.MgmtBridgeIP = "10.15.8.1" - svc.AdvertiseIP = "192.168.1.33" - return svc - } - - internal, err := mkSvc().lbVMUserData("lb-int", SchemeInternal) - require.NoError(t, err) - assert.Contains(t, internal, "bootcmd:") - assert.Contains(t, internal, `"192.168.1.33/32"`) - assert.Contains(t, internal, `"10.15.8.1"`) - - inetFacing, err := mkSvc().lbVMUserData("lb-inet", SchemeInternetFacing) - require.NoError(t, err) - assert.NotContains(t, inetFacing, "bootcmd:", "internet-facing single-node must not get a /32 mgmt route") - - noBridge := mkSvc() - noBridge.MgmtBridgeIP = "" - out, err := noBridge.lbVMUserData("lb-int", SchemeInternal) - require.NoError(t, err) - assert.NotContains(t, out, "bootcmd:", "no fallback when br-mgmt is absent") -} - func TestIsCompatibleProtocol_UnknownListenerProtocol(t *testing.T) { assert.False(t, isCompatibleProtocol("SCTP", ProtocolTCP)) assert.False(t, isCompatibleProtocol("", ProtocolHTTP)) diff --git a/spinifex/handlers/elbv2/service_impl_vpc_test.go b/spinifex/handlers/elbv2/service_impl_vpc_test.go index 97026a6e5..82511eaed 100644 --- a/spinifex/handlers/elbv2/service_impl_vpc_test.go +++ b/spinifex/handlers/elbv2/service_impl_vpc_test.go @@ -1,13 +1,11 @@ package handlers_elbv2 import ( - "errors" "testing" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/service/ec2" "github.com/aws/aws-sdk-go/service/elbv2" - "github.com/mulgadc/spinifex/spinifex/awserrors" "github.com/mulgadc/spinifex/spinifex/config" handlers_ec2_vpc "github.com/mulgadc/spinifex/spinifex/handlers/ec2/vpc" "github.com/mulgadc/spinifex/spinifex/testutil" @@ -160,7 +158,6 @@ func TestCreateLoadBalancer_MultiSubnet_AllENIsPassedToLauncher(t *testing.T) { }, } svc.InstanceLauncher = mock - svc.SetSystemAMIFunc(func() (string, error) { return "ami-alb-test", nil }) svc.GatewayURL = "https://10.0.0.1:9999" svc.SystemAccessKey = "AKID" svc.SystemSecretKey = "SECRET" @@ -281,7 +278,6 @@ func TestCreateLoadBalancer_InternetFacing_AllocatesPublicIP(t *testing.T) { }, } svc.InstanceLauncher = mock - svc.SetSystemAMIFunc(func() (string, error) { return "ami-alb-test", nil }) svc.GatewayURL = "https://10.0.0.1:9999" svc.SystemAccessKey = "AKID" svc.SystemSecretKey = "SECRET" @@ -330,7 +326,6 @@ func TestCreateLoadBalancer_Internal_NoPublicIP(t *testing.T) { }, } svc.InstanceLauncher = mock - svc.SetSystemAMIFunc(func() (string, error) { return "ami-alb-test", nil }) svc.GatewayURL = "https://10.0.0.1:9999" svc.SystemAccessKey = "AKID" svc.SystemSecretKey = "SECRET" @@ -371,7 +366,6 @@ func TestCreateLoadBalancer_NLB_Internal_NoPublicIP(t *testing.T) { }, } svc.InstanceLauncher = mock - svc.SetSystemAMIFunc(func() (string, error) { return "ami-nlb-test", nil }) svc.GatewayURL = "https://10.0.0.1:9999" svc.SystemAccessKey = "AKID" svc.SystemSecretKey = "SECRET" @@ -420,7 +414,6 @@ func TestDeleteLoadBalancer_TerminatesVM_WithPublicIP(t *testing.T) { terminateDone: make(chan struct{}), } svc.InstanceLauncher = mock - svc.SetSystemAMIFunc(func() (string, error) { return "ami-alb-test", nil }) svc.GatewayURL = "https://10.0.0.1:9999" svc.SystemAccessKey = "AKID" svc.SystemSecretKey = "SECRET" @@ -468,7 +461,6 @@ func TestDescribeLoadBalancers_InternetFacing_IncludesPublicIP(t *testing.T) { }, } svc.InstanceLauncher = mock - svc.SetSystemAMIFunc(func() (string, error) { return "ami-alb-test", nil }) svc.GatewayURL = "https://10.0.0.1:9999" svc.SystemAccessKey = "AKID" svc.SystemSecretKey = "SECRET" @@ -518,7 +510,6 @@ func TestDescribeLoadBalancers_Internal_NoPublicIP(t *testing.T) { }, } svc.InstanceLauncher = mock - svc.SetSystemAMIFunc(func() (string, error) { return "ami-alb-test", nil }) svc.GatewayURL = "https://10.0.0.1:9999" svc.SystemAccessKey = "AKID" svc.SystemSecretKey = "SECRET" @@ -557,7 +548,6 @@ func TestCreateLoadBalancer_LaunchFailure_SetsStateFailed(t *testing.T) { launchErr: assert.AnError, } svc.InstanceLauncher = mock - svc.SetSystemAMIFunc(func() (string, error) { return "ami-alb-test", nil }) svc.GatewayURL = "https://10.0.0.1:9999" svc.SystemAccessKey = "AKID" svc.SystemSecretKey = "SECRET" @@ -586,7 +576,6 @@ func TestCreateLoadBalancer_MissingCredentials_SetsStateFailed(t *testing.T) { }, } svc.InstanceLauncher = mock - svc.SetSystemAMIFunc(func() (string, error) { return "ami-alb-test", nil }) // Deliberately NOT setting credentials out, err := svc.CreateLoadBalancer(&elbv2.CreateLoadBalancerInput{ @@ -643,43 +632,6 @@ func TestENI_RequesterManagedFlag(t *testing.T) { } } -// TestCreateLoadBalancer_AMIResolverError_ReturnsServerInternal verifies that -// when the launch path would fire (launcher + networking present) but the LB -// system AMI cannot be resolved, CreateLoadBalancer returns ServerInternal and -// does not persist a record or invoke the launcher. -func TestCreateLoadBalancer_AMIResolverError_ReturnsServerInternal(t *testing.T) { - svc, vpcSvc := setupTestServiceWithVPC(t) - - subnets, err := vpcSvc.DescribeSubnets(&ec2.DescribeSubnetsInput{}, testAccountID) - require.NoError(t, err) - subnetID := *subnets.Subnets[0].SubnetId - - mock := &mockSystemInstanceLauncher{ - launchResult: &SystemInstanceOutput{InstanceID: "i-should-not-launch"}, - } - svc.InstanceLauncher = mock - svc.SetSystemAMIFunc(func() (string, error) { - return "", errors.New("LB system image not imported") - }) - svc.GatewayURL = "https://10.0.0.1:9999" - svc.SystemAccessKey = "AKID" - svc.SystemSecretKey = "SECRET" - - out, err := svc.CreateLoadBalancer(&elbv2.CreateLoadBalancerInput{ - Name: aws.String("ami-err-alb"), - Subnets: []*string{aws.String(subnetID)}, - }, testAccountID) - - require.Error(t, err) - assert.Equal(t, awserrors.ErrorServerInternal, err.Error()) - assert.Nil(t, out) - assert.Empty(t, mock.launchCalls, "launcher must not be invoked when AMI resolver errors") - - lbs, err := svc.store.ListLoadBalancers() - require.NoError(t, err) - assert.Empty(t, lbs, "no LB record should be persisted when AMI resolver errors") -} - // TestCreateLoadBalancer_AttachesSpecifiedSecurityGroupsToENI verifies that // when the caller supplies SecurityGroups on the LB input, the underlying ALB // ENI is created with those SGs (not the VPC default SG). Without this the diff --git a/spinifex/services/spinifexui/frontend/dist/assets/_id.js b/spinifex/services/spinifexui/frontend/dist/assets/_id.js index 18ead60ee..93cdf0394 100644 --- a/spinifex/services/spinifexui/frontend/dist/assets/_id.js +++ b/spinifex/services/spinifexui/frontend/dist/assets/_id.js @@ -1 +1 @@ -import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./back-link.js";import{n as i}from"./ec22.js";import{t as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./state-badge.js";import{r as c}from"./system-managed.js";import{t as l}from"./ami-details.js";var u=t(),d=e();function f(){let e=(0,u.c)(14),{id:t}=a.useParams(),f;e[0]===t?f=e[1]:(f=i(t),e[0]=t,e[1]=f);let{data:p}=n(f),m=p?.Images?.[0];if(!m?.ImageId||c(m)){let t;return e[2]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(r,{to:`/ec2/describe-images`,children:`Back to images`}),(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`Image not found.`})]}),e[2]=t):t=e[2],t}let h;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(h=(0,d.jsx)(r,{to:`/ec2/describe-images`,children:`Back to images`}),e[3]=h):h=e[3];let g;e[4]===m.State?g=e[5]:(g=(0,d.jsx)(s,{state:m.State}),e[4]=m.State,e[5]=g);let _;e[6]!==m.ImageId||e[7]!==g?(_=(0,d.jsx)(o,{actions:g,subtitle:`EC2 Image Details`,title:m.ImageId}),e[6]=m.ImageId,e[7]=g,e[8]=_):_=e[8];let v;e[9]===m?v=e[10]:(v=(0,d.jsx)(l,{image:m,showExtendedDetails:!0}),e[9]=m,e[10]=v);let y;return e[11]!==_||e[12]!==v?(y=(0,d.jsxs)(d.Fragment,{children:[h,(0,d.jsxs)(`div`,{className:`space-y-6`,children:[_,v]})]}),e[11]=_,e[12]=v,e[13]=y):y=e[13],y}export{f as component}; \ No newline at end of file +import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./back-link.js";import{n as i}from"./ec22.js";import{t as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./state-badge.js";import{t as c}from"./system-managed.js";import{t as l}from"./ami-details.js";var u=t(),d=e();function f(){let e=(0,u.c)(14),{id:t}=a.useParams(),f;e[0]===t?f=e[1]:(f=i(t),e[0]=t,e[1]=f);let{data:p}=n(f),m=p?.Images?.[0];if(!m?.ImageId||c(m)){let t;return e[2]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(r,{to:`/ec2/describe-images`,children:`Back to images`}),(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`Image not found.`})]}),e[2]=t):t=e[2],t}let h;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(h=(0,d.jsx)(r,{to:`/ec2/describe-images`,children:`Back to images`}),e[3]=h):h=e[3];let g;e[4]===m.State?g=e[5]:(g=(0,d.jsx)(s,{state:m.State}),e[4]=m.State,e[5]=g);let _;e[6]!==m.ImageId||e[7]!==g?(_=(0,d.jsx)(o,{actions:g,subtitle:`EC2 Image Details`,title:m.ImageId}),e[6]=m.ImageId,e[7]=g,e[8]=_):_=e[8];let v;e[9]===m?v=e[10]:(v=(0,d.jsx)(l,{image:m,showExtendedDetails:!0}),e[9]=m,e[10]=v);let y;return e[11]!==_||e[12]!==v?(y=(0,d.jsxs)(d.Fragment,{children:[h,(0,d.jsxs)(`div`,{className:`space-y-6`,children:[_,v]})]}),e[11]=_,e[12]=v,e[13]=y):y=e[13],y}export{f as component}; \ No newline at end of file diff --git a/spinifex/services/spinifexui/frontend/dist/assets/create-load-balancer.js b/spinifex/services/spinifexui/frontend/dist/assets/create-load-balancer.js index 6dd6dd904..4bd822f14 100644 --- a/spinifex/services/spinifexui/frontend/dist/assets/create-load-balancer.js +++ b/spinifex/services/spinifexui/frontend/dist/assets/create-load-balancer.js @@ -1,4 +1,4 @@ -import{a as e,n as t,r as n}from"./compiler-runtime.js";import{t as r}from"./error-banner.js";import{t as i}from"./useSuspenseQuery.js";import{t as a}from"./useNavigate.js";import{V as o}from"./SignatureV4.js";import{t as s}from"./back-link.js";import{a as c,i as l,n as u,r as d,t as f}from"./select.js";import{t as p}from"./plus.js";import{t as m}from"./cli-command-panel.js";import{t as h}from"./trash-2.js";import{t as g}from"./button.js";import{_,p as ee,r as te,x as ne}from"./ec22.js";import{n as re}from"./elbv2.js";import{c as ie}from"./elbv22.js";import{L as v}from"./index.js";import{t as y}from"./page-heading.js";import{n as b}from"./system-managed.js";import{a as x,r as S,t as C}from"./field.js";import{n as w,r as T,t as E}from"./zod.js";import{t as ae}from"./form-actions.js";import{t as oe}from"./lb-image-missing-banner.js";import{t as se}from"./target-group-form.js";import{n as ce,r as D}from"./elbv23.js";var le=e(n(),1),O=t();function ue(e){let t=o(e.Tags);return t?`${e.VpcId} (${t})`:`${e.VpcId} (${e.CidrBlock})`}function k(e){let t=o(e.Tags);return`${t?`${e.SubnetId} (${t})`:e.SubnetId} · ${e.CidrBlock}`}function A(e){let t=new Map;for(let n of e){let e=n.AvailabilityZone??`unknown`,r=t.get(e)??[];r.push(n),t.set(e,r)}return[...t.entries()].toSorted((e,t)=>e[0].localeCompare(t[0])).map(([e,t])=>({az:e,subnets:t}))}function j(){let e=a(),{data:t}=i(ne),{data:n}=i(_),{data:o}=i(ee),{data:j}=i(ie),{data:M}=i(te),N=re(),fe=b(M.Images??[]),[P,F]=(0,le.useState)(null),I=t.Vpcs??[],L=n.Subnets??[],R=o.SecurityGroups??[],z=j.TargetGroups??[],B=T({resolver:E(ce),defaultValues:{name:``,scheme:`internet-facing`,vpcId:I[0]?.VpcId??``,subnetIds:[],securityGroupIds:[],tags:[],listener:{protocol:`HTTP`,port:80,targetGroupMode:`new`,existingTargetGroupArn:``}}}),V=T({resolver:E(D),defaultValues:{name:``,protocol:`HTTP`,port:80,vpcId:I[0]?.VpcId??``,healthCheck:{protocol:`HTTP`,path:`/`,port:`traffic-port`,intervalSeconds:30,timeoutSeconds:5,healthyThresholdCount:5,unhealthyThresholdCount:2,matcher:`200`},tags:[]}}),{handleSubmit:H,register:U,watch:W,control:G,setValue:K,getValues:q,formState:{errors:J,isSubmitting:pe}}=B,Y=W(`vpcId`),me=W(`subnetIds`),he=W(`securityGroupIds`),X=W(`listener.targetGroupMode`),ge=W(`tags`),_e=L.filter(e=>e.VpcId===Y),Z=R.filter(e=>e.VpcId===Y),Q=z.filter(e=>e.VpcId===Y),ve=(e=``)=>{let t=e??``;K(`vpcId`,t,{shouldValidate:!0}),K(`subnetIds`,[],{shouldValidate:!0}),K(`securityGroupIds`,[]),K(`listener.existingTargetGroupArn`,``),V.setValue(`vpcId`,t)},ye=e=>{let t=q(`subnetIds`);K(`subnetIds`,t.includes(e)?t.filter(t=>t!==e):[...t,e],{shouldValidate:!0})},be=e=>{let t=q(`securityGroupIds`);K(`securityGroupIds`,t.includes(e)?t.filter(t=>t!==e):[...t,e])},xe=async t=>{F(null);let n;if(t.listener.targetGroupMode===`new`){if(!await V.trigger())return;n=V.getValues()}let r=await N.mutateAsync({lb:{name:t.name,scheme:t.scheme,vpcId:t.vpcId,subnetIds:t.subnetIds,securityGroupIds:t.securityGroupIds,tags:t.tags},listener:{protocol:t.listener.protocol,port:t.listener.port,targetGroupMode:t.listener.targetGroupMode,existingTargetGroupArn:t.listener.existingTargetGroupArn,newTargetGroup:n}});F(r),!r.error&&r.loadBalancerArn&&e({to:`/ec2/describe-load-balancers/$id`,params:{id:encodeURIComponent(r.loadBalancerArn)}})},$=A(_e);return fe?(0,O.jsxs)(O.Fragment,{children:[(0,O.jsx)(s,{to:`/ec2/describe-load-balancers`,children:`Back to load balancers`}),(0,O.jsx)(y,{title:`Create load balancer`}),N.error&&(0,O.jsx)(r,{error:N.error,msg:`Failed to create load balancer`}),P?.error&&(0,O.jsxs)(`div`,{className:`mb-6 max-w-4xl rounded-md border border-destructive bg-destructive/10 p-4`,children:[(0,O.jsxs)(`h2`,{className:`text-sm font-medium text-destructive`,children:[`Wizard failed: `,P.failedStep]}),(0,O.jsx)(`p`,{className:`mt-1 text-sm text-destructive`,children:P.error.message}),P.created.length>0&&(0,O.jsxs)(`div`,{className:`mt-3`,children:[(0,O.jsx)(`p`,{className:`text-xs font-medium text-destructive`,children:`Successfully created resources (clean up manually if needed):`}),(0,O.jsx)(`ul`,{className:`mt-1 list-inside list-disc text-xs text-destructive`,children:P.created.map((e,t)=>(0,O.jsxs)(`li`,{children:[e.type,`: `,e.id??`(created)`]},t))})]})]}),(0,O.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:H(xe),children:[(0,O.jsxs)(C,{children:[(0,O.jsx)(x,{children:(0,O.jsx)(`label`,{htmlFor:`lb-name`,children:`Name`})}),(0,O.jsx)(v,{"aria-invalid":!!J.name,id:`lb-name`,placeholder:`my-load-balancer`,...U(`name`)}),(0,O.jsx)(S,{errors:[J.name]})]}),(0,O.jsxs)(C,{children:[(0,O.jsx)(x,{children:`Scheme`}),(0,O.jsx)(w,{control:G,name:`scheme`,render:({field:e})=>(0,O.jsxs)(`div`,{className:`flex gap-4`,children:[(0,O.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,O.jsx)(`input`,{checked:e.value===`internet-facing`,name:`scheme`,onChange:()=>e.onChange(`internet-facing`),type:`radio`}),`Internet-facing`]}),(0,O.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,O.jsx)(`input`,{checked:e.value===`internal`,name:`scheme`,onChange:()=>e.onChange(`internal`),type:`radio`}),`Internal`]})]})})]}),(0,O.jsxs)(C,{children:[(0,O.jsx)(x,{children:(0,O.jsx)(`label`,{htmlFor:`lb-vpc`,children:`VPC`})}),(0,O.jsx)(w,{control:G,name:`vpcId`,render:({field:e})=>(0,O.jsxs)(f,{onValueChange:e=>ve(e),value:e.value??``,children:[(0,O.jsx)(l,{"aria-invalid":!!J.vpcId,className:`w-full`,id:`lb-vpc`,children:(0,O.jsx)(c,{placeholder:`Select VPC`})}),(0,O.jsx)(u,{children:I.map(e=>(0,O.jsx)(d,{value:e.VpcId??``,children:ue(e)},e.VpcId))})]})}),(0,O.jsx)(S,{errors:[J.vpcId]})]}),(0,O.jsxs)(C,{children:[(0,O.jsx)(x,{children:`Subnets (select at least 2)`}),$.length===0?(0,O.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`No subnets in the selected VPC.`}):(0,O.jsx)(`div`,{className:`space-y-3`,children:$.map(e=>(0,O.jsxs)(`div`,{children:[(0,O.jsx)(`p`,{className:`mb-1 text-xs font-medium text-muted-foreground`,children:e.az}),(0,O.jsx)(`div`,{className:`space-y-1`,children:e.subnets.map(e=>(0,O.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,O.jsx)(`input`,{checked:me.includes(e.SubnetId??``),onChange:()=>ye(e.SubnetId??``),type:`checkbox`}),(0,O.jsx)(`span`,{className:`font-mono`,children:k(e)})]},e.SubnetId))})]},e.az))}),(0,O.jsx)(S,{errors:[J.subnetIds]})]}),(0,O.jsxs)(C,{children:[(0,O.jsx)(x,{children:`Security groups`}),Z.length===0?(0,O.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`No security groups in the selected VPC.`}):(0,O.jsx)(`div`,{className:`space-y-1`,children:Z.map(e=>(0,O.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,O.jsx)(`input`,{checked:he.includes(e.GroupId??``),onChange:()=>be(e.GroupId??``),type:`checkbox`}),(0,O.jsxs)(`span`,{className:`font-mono`,children:[e.GroupId,` (`,e.GroupName,`)`]})]},e.GroupId))})]}),(0,O.jsxs)(C,{children:[(0,O.jsx)(x,{children:`Tags`}),(0,O.jsxs)(`div`,{className:`space-y-2`,children:[ge.map((e,t)=>(0,O.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,O.jsx)(v,{placeholder:`Key`,...U(`tags.${t}.key`)}),(0,O.jsx)(v,{placeholder:`Value`,...U(`tags.${t}.value`)}),(0,O.jsx)(g,{onClick:()=>K(`tags`,q(`tags`).filter((e,n)=>n!==t)),size:`icon`,type:`button`,variant:`ghost`,children:(0,O.jsx)(h,{className:`size-3.5`})})]},t)),(0,O.jsxs)(g,{onClick:()=>K(`tags`,[...q(`tags`),{key:``,value:``}]),size:`sm`,type:`button`,variant:`outline`,children:[(0,O.jsx)(p,{className:`size-3.5`}),`Add tag`]})]})]}),(0,O.jsxs)(`div`,{className:`space-y-4 rounded-md border bg-card p-4`,children:[(0,O.jsx)(`h2`,{className:`text-sm font-semibold`,children:`First listener & default target group`}),(0,O.jsxs)(C,{children:[(0,O.jsx)(x,{children:(0,O.jsx)(`label`,{htmlFor:`listener-protocol`,children:`Protocol`})}),(0,O.jsx)(w,{control:G,name:`listener.protocol`,render:({field:e})=>(0,O.jsxs)(f,{onValueChange:e.onChange,value:e.value,children:[(0,O.jsx)(l,{className:`w-full`,id:`listener-protocol`,children:(0,O.jsx)(c,{})}),(0,O.jsx)(u,{children:(0,O.jsx)(d,{value:`HTTP`,children:`HTTP`})})]})})]}),(0,O.jsxs)(C,{children:[(0,O.jsx)(x,{children:(0,O.jsx)(`label`,{htmlFor:`listener-port`,children:`Port`})}),(0,O.jsx)(v,{"aria-invalid":!!J.listener?.port,id:`listener-port`,inputMode:`numeric`,type:`number`,...U(`listener.port`,{valueAsNumber:!0})}),(0,O.jsx)(S,{errors:[J.listener?.port]})]}),(0,O.jsxs)(C,{children:[(0,O.jsx)(x,{children:`Default target group`}),(0,O.jsx)(w,{control:G,name:`listener.targetGroupMode`,render:({field:e})=>(0,O.jsxs)(`div`,{className:`flex gap-4`,children:[(0,O.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,O.jsx)(`input`,{checked:e.value===`new`,name:`tg-mode`,onChange:()=>e.onChange(`new`),type:`radio`}),`Create new`]}),(0,O.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,O.jsx)(`input`,{checked:e.value===`existing`,name:`tg-mode`,onChange:()=>e.onChange(`existing`),type:`radio`}),`Use existing`]})]})})]}),X===`existing`&&(0,O.jsxs)(C,{children:[(0,O.jsx)(x,{children:(0,O.jsx)(`label`,{htmlFor:`tg-existing`,children:`Target group`})}),(0,O.jsx)(w,{control:G,name:`listener.existingTargetGroupArn`,render:({field:e})=>(0,O.jsxs)(f,{onValueChange:e.onChange,value:e.value??``,children:[(0,O.jsx)(l,{"aria-invalid":!!J.listener?.existingTargetGroupArn,className:`w-full`,id:`tg-existing`,children:(0,O.jsx)(c,{placeholder:`Select target group`})}),(0,O.jsx)(u,{children:Q.map(e=>(0,O.jsxs)(d,{value:e.TargetGroupArn??``,children:[e.TargetGroupName,` · `,e.Protocol,`:`,e.Port]},e.TargetGroupArn))})]})}),(0,O.jsx)(S,{errors:[J.listener?.existingTargetGroupArn]}),Q.length===0&&(0,O.jsx)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:`No target groups in this VPC. Choose “Create new” instead.`})]}),X===`new`&&(0,O.jsx)(`div`,{className:`space-y-4 border-l-2 border-muted pl-4`,children:(0,O.jsx)(se,{form:V,vpcs:I})})]}),(0,O.jsx)(m,{commands:de(W,V.watch)}),(0,O.jsx)(ae,{isPending:N.isPending,isSubmitting:pe,onCancel:async()=>await e({to:`/ec2/describe-load-balancers`}),pendingLabel:`Creating…`,submitLabel:`Create load balancer`})]})]}):(0,O.jsxs)(O.Fragment,{children:[(0,O.jsx)(s,{to:`/ec2/describe-load-balancers`,children:`Back to load balancers`}),(0,O.jsx)(y,{title:`Create load balancer`}),(0,O.jsx)(oe,{})]})}function de(e,t){let n=t=>{let n=e(t);return typeof n==`string`?n:``},r=t=>{let n=e(t);return Array.isArray(n)?n.filter(e=>typeof e==`string`):[]},i=t=>{let n=e(t);return typeof n==`number`&&Number.isFinite(n)?n:void 0},a=n(`name`)||``,o=n(`scheme`)||`internet-facing`,s=r(`subnetIds`),c=r(`securityGroupIds`),l=n(`listener.protocol`)||`HTTP`,u=i(`listener.port`)??80,d=n(`listener.targetGroupMode`),f=n(`listener.existingTargetGroupArn`),p=[],m={type:`comment`,value:`# Create ALB with listener and default target group +import{a as e,n as t,r as n}from"./compiler-runtime.js";import{t as r}from"./error-banner.js";import{t as i}from"./useSuspenseQuery.js";import{t as a}from"./useNavigate.js";import{V as o}from"./SignatureV4.js";import{t as s}from"./back-link.js";import{a as c,i as l,n as u,r as d,t as f}from"./select.js";import{t as p}from"./plus.js";import{t as m}from"./cli-command-panel.js";import{t as h}from"./trash-2.js";import{t as g}from"./button.js";import{_,p as ee,x as te}from"./ec22.js";import{n as ne}from"./elbv2.js";import{c as re}from"./elbv22.js";import{L as v}from"./index.js";import{t as ie}from"./page-heading.js";import{a as y,r as b,t as x}from"./field.js";import{n as S,r as C,t as w}from"./zod.js";import{t as T}from"./form-actions.js";import{t as E}from"./target-group-form.js";import{n as D,r as O}from"./elbv23.js";var k=e(n(),1),A=t();function ae(e){let t=o(e.Tags);return t?`${e.VpcId} (${t})`:`${e.VpcId} (${e.CidrBlock})`}function oe(e){let t=o(e.Tags);return`${t?`${e.SubnetId} (${t})`:e.SubnetId} · ${e.CidrBlock}`}function se(e){let t=new Map;for(let n of e){let e=n.AvailabilityZone??`unknown`,r=t.get(e)??[];r.push(n),t.set(e,r)}return[...t.entries()].toSorted((e,t)=>e[0].localeCompare(t[0])).map(([e,t])=>({az:e,subnets:t}))}function j(){let e=a(),{data:t}=i(te),{data:n}=i(_),{data:o}=i(ee),{data:j}=i(re),M=ne(),[N,P]=(0,k.useState)(null),F=t.Vpcs??[],I=n.Subnets??[],L=o.SecurityGroups??[],R=j.TargetGroups??[],z=C({resolver:w(D),defaultValues:{name:``,scheme:`internet-facing`,vpcId:F[0]?.VpcId??``,subnetIds:[],securityGroupIds:[],tags:[],listener:{protocol:`HTTP`,port:80,targetGroupMode:`new`,existingTargetGroupArn:``}}}),B=C({resolver:w(O),defaultValues:{name:``,protocol:`HTTP`,port:80,vpcId:F[0]?.VpcId??``,healthCheck:{protocol:`HTTP`,path:`/`,port:`traffic-port`,intervalSeconds:30,timeoutSeconds:5,healthyThresholdCount:5,unhealthyThresholdCount:2,matcher:`200`},tags:[]}}),{handleSubmit:V,register:H,watch:U,control:W,setValue:G,getValues:K,formState:{errors:q,isSubmitting:le}}=z,J=U(`vpcId`),ue=U(`subnetIds`),de=U(`securityGroupIds`),Y=U(`listener.targetGroupMode`),fe=U(`tags`),X=I.filter(e=>e.VpcId===J),Z=L.filter(e=>e.VpcId===J),Q=R.filter(e=>e.VpcId===J),pe=(e=``)=>{let t=e??``;G(`vpcId`,t,{shouldValidate:!0}),G(`subnetIds`,[],{shouldValidate:!0}),G(`securityGroupIds`,[]),G(`listener.existingTargetGroupArn`,``),B.setValue(`vpcId`,t)},me=e=>{let t=K(`subnetIds`);G(`subnetIds`,t.includes(e)?t.filter(t=>t!==e):[...t,e],{shouldValidate:!0})},he=e=>{let t=K(`securityGroupIds`);G(`securityGroupIds`,t.includes(e)?t.filter(t=>t!==e):[...t,e])},ge=async t=>{P(null);let n;if(t.listener.targetGroupMode===`new`){if(!await B.trigger())return;n=B.getValues()}let r=await M.mutateAsync({lb:{name:t.name,scheme:t.scheme,vpcId:t.vpcId,subnetIds:t.subnetIds,securityGroupIds:t.securityGroupIds,tags:t.tags},listener:{protocol:t.listener.protocol,port:t.listener.port,targetGroupMode:t.listener.targetGroupMode,existingTargetGroupArn:t.listener.existingTargetGroupArn,newTargetGroup:n}});P(r),!r.error&&r.loadBalancerArn&&e({to:`/ec2/describe-load-balancers/$id`,params:{id:encodeURIComponent(r.loadBalancerArn)}})},$=se(X);return(0,A.jsxs)(A.Fragment,{children:[(0,A.jsx)(s,{to:`/ec2/describe-load-balancers`,children:`Back to load balancers`}),(0,A.jsx)(ie,{title:`Create load balancer`}),M.error&&(0,A.jsx)(r,{error:M.error,msg:`Failed to create load balancer`}),N?.error&&(0,A.jsxs)(`div`,{className:`mb-6 max-w-4xl rounded-md border border-destructive bg-destructive/10 p-4`,children:[(0,A.jsxs)(`h2`,{className:`text-sm font-medium text-destructive`,children:[`Wizard failed: `,N.failedStep]}),(0,A.jsx)(`p`,{className:`mt-1 text-sm text-destructive`,children:N.error.message}),N.created.length>0&&(0,A.jsxs)(`div`,{className:`mt-3`,children:[(0,A.jsx)(`p`,{className:`text-xs font-medium text-destructive`,children:`Successfully created resources (clean up manually if needed):`}),(0,A.jsx)(`ul`,{className:`mt-1 list-inside list-disc text-xs text-destructive`,children:N.created.map((e,t)=>(0,A.jsxs)(`li`,{children:[e.type,`: `,e.id??`(created)`]},t))})]})]}),(0,A.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:V(ge),children:[(0,A.jsxs)(x,{children:[(0,A.jsx)(y,{children:(0,A.jsx)(`label`,{htmlFor:`lb-name`,children:`Name`})}),(0,A.jsx)(v,{"aria-invalid":!!q.name,id:`lb-name`,placeholder:`my-load-balancer`,...H(`name`)}),(0,A.jsx)(b,{errors:[q.name]})]}),(0,A.jsxs)(x,{children:[(0,A.jsx)(y,{children:`Scheme`}),(0,A.jsx)(S,{control:W,name:`scheme`,render:({field:e})=>(0,A.jsxs)(`div`,{className:`flex gap-4`,children:[(0,A.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,A.jsx)(`input`,{checked:e.value===`internet-facing`,name:`scheme`,onChange:()=>e.onChange(`internet-facing`),type:`radio`}),`Internet-facing`]}),(0,A.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,A.jsx)(`input`,{checked:e.value===`internal`,name:`scheme`,onChange:()=>e.onChange(`internal`),type:`radio`}),`Internal`]})]})})]}),(0,A.jsxs)(x,{children:[(0,A.jsx)(y,{children:(0,A.jsx)(`label`,{htmlFor:`lb-vpc`,children:`VPC`})}),(0,A.jsx)(S,{control:W,name:`vpcId`,render:({field:e})=>(0,A.jsxs)(f,{onValueChange:e=>pe(e),value:e.value??``,children:[(0,A.jsx)(l,{"aria-invalid":!!q.vpcId,className:`w-full`,id:`lb-vpc`,children:(0,A.jsx)(c,{placeholder:`Select VPC`})}),(0,A.jsx)(u,{children:F.map(e=>(0,A.jsx)(d,{value:e.VpcId??``,children:ae(e)},e.VpcId))})]})}),(0,A.jsx)(b,{errors:[q.vpcId]})]}),(0,A.jsxs)(x,{children:[(0,A.jsx)(y,{children:`Subnets (select at least 2)`}),$.length===0?(0,A.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`No subnets in the selected VPC.`}):(0,A.jsx)(`div`,{className:`space-y-3`,children:$.map(e=>(0,A.jsxs)(`div`,{children:[(0,A.jsx)(`p`,{className:`mb-1 text-xs font-medium text-muted-foreground`,children:e.az}),(0,A.jsx)(`div`,{className:`space-y-1`,children:e.subnets.map(e=>(0,A.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,A.jsx)(`input`,{checked:ue.includes(e.SubnetId??``),onChange:()=>me(e.SubnetId??``),type:`checkbox`}),(0,A.jsx)(`span`,{className:`font-mono`,children:oe(e)})]},e.SubnetId))})]},e.az))}),(0,A.jsx)(b,{errors:[q.subnetIds]})]}),(0,A.jsxs)(x,{children:[(0,A.jsx)(y,{children:`Security groups`}),Z.length===0?(0,A.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`No security groups in the selected VPC.`}):(0,A.jsx)(`div`,{className:`space-y-1`,children:Z.map(e=>(0,A.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,A.jsx)(`input`,{checked:de.includes(e.GroupId??``),onChange:()=>he(e.GroupId??``),type:`checkbox`}),(0,A.jsxs)(`span`,{className:`font-mono`,children:[e.GroupId,` (`,e.GroupName,`)`]})]},e.GroupId))})]}),(0,A.jsxs)(x,{children:[(0,A.jsx)(y,{children:`Tags`}),(0,A.jsxs)(`div`,{className:`space-y-2`,children:[fe.map((e,t)=>(0,A.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,A.jsx)(v,{placeholder:`Key`,...H(`tags.${t}.key`)}),(0,A.jsx)(v,{placeholder:`Value`,...H(`tags.${t}.value`)}),(0,A.jsx)(g,{onClick:()=>G(`tags`,K(`tags`).filter((e,n)=>n!==t)),size:`icon`,type:`button`,variant:`ghost`,children:(0,A.jsx)(h,{className:`size-3.5`})})]},t)),(0,A.jsxs)(g,{onClick:()=>G(`tags`,[...K(`tags`),{key:``,value:``}]),size:`sm`,type:`button`,variant:`outline`,children:[(0,A.jsx)(p,{className:`size-3.5`}),`Add tag`]})]})]}),(0,A.jsxs)(`div`,{className:`space-y-4 rounded-md border bg-card p-4`,children:[(0,A.jsx)(`h2`,{className:`text-sm font-semibold`,children:`First listener & default target group`}),(0,A.jsxs)(x,{children:[(0,A.jsx)(y,{children:(0,A.jsx)(`label`,{htmlFor:`listener-protocol`,children:`Protocol`})}),(0,A.jsx)(S,{control:W,name:`listener.protocol`,render:({field:e})=>(0,A.jsxs)(f,{onValueChange:e.onChange,value:e.value,children:[(0,A.jsx)(l,{className:`w-full`,id:`listener-protocol`,children:(0,A.jsx)(c,{})}),(0,A.jsx)(u,{children:(0,A.jsx)(d,{value:`HTTP`,children:`HTTP`})})]})})]}),(0,A.jsxs)(x,{children:[(0,A.jsx)(y,{children:(0,A.jsx)(`label`,{htmlFor:`listener-port`,children:`Port`})}),(0,A.jsx)(v,{"aria-invalid":!!q.listener?.port,id:`listener-port`,inputMode:`numeric`,type:`number`,...H(`listener.port`,{valueAsNumber:!0})}),(0,A.jsx)(b,{errors:[q.listener?.port]})]}),(0,A.jsxs)(x,{children:[(0,A.jsx)(y,{children:`Default target group`}),(0,A.jsx)(S,{control:W,name:`listener.targetGroupMode`,render:({field:e})=>(0,A.jsxs)(`div`,{className:`flex gap-4`,children:[(0,A.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,A.jsx)(`input`,{checked:e.value===`new`,name:`tg-mode`,onChange:()=>e.onChange(`new`),type:`radio`}),`Create new`]}),(0,A.jsxs)(`label`,{className:`flex items-center gap-2 text-xs`,children:[(0,A.jsx)(`input`,{checked:e.value===`existing`,name:`tg-mode`,onChange:()=>e.onChange(`existing`),type:`radio`}),`Use existing`]})]})})]}),Y===`existing`&&(0,A.jsxs)(x,{children:[(0,A.jsx)(y,{children:(0,A.jsx)(`label`,{htmlFor:`tg-existing`,children:`Target group`})}),(0,A.jsx)(S,{control:W,name:`listener.existingTargetGroupArn`,render:({field:e})=>(0,A.jsxs)(f,{onValueChange:e.onChange,value:e.value??``,children:[(0,A.jsx)(l,{"aria-invalid":!!q.listener?.existingTargetGroupArn,className:`w-full`,id:`tg-existing`,children:(0,A.jsx)(c,{placeholder:`Select target group`})}),(0,A.jsx)(u,{children:Q.map(e=>(0,A.jsxs)(d,{value:e.TargetGroupArn??``,children:[e.TargetGroupName,` · `,e.Protocol,`:`,e.Port]},e.TargetGroupArn))})]})}),(0,A.jsx)(b,{errors:[q.listener?.existingTargetGroupArn]}),Q.length===0&&(0,A.jsx)(`p`,{className:`mt-1 text-xs text-muted-foreground`,children:`No target groups in this VPC. Choose “Create new” instead.`})]}),Y===`new`&&(0,A.jsx)(`div`,{className:`space-y-4 border-l-2 border-muted pl-4`,children:(0,A.jsx)(E,{form:B,vpcs:F})})]}),(0,A.jsx)(m,{commands:ce(U,B.watch)}),(0,A.jsx)(T,{isPending:M.isPending,isSubmitting:le,onCancel:async()=>await e({to:`/ec2/describe-load-balancers`}),pendingLabel:`Creating…`,submitLabel:`Create load balancer`})]})]})}function ce(e,t){let n=t=>{let n=e(t);return typeof n==`string`?n:``},r=t=>{let n=e(t);return Array.isArray(n)?n.filter(e=>typeof e==`string`):[]},i=t=>{let n=e(t);return typeof n==`number`&&Number.isFinite(n)?n:void 0},a=n(`name`)||``,o=n(`scheme`)||`internet-facing`,s=r(`subnetIds`),c=r(`securityGroupIds`),l=n(`listener.protocol`)||`HTTP`,u=i(`listener.port`)??80,d=n(`listener.targetGroupMode`),f=n(`listener.existingTargetGroupArn`),p=[],m={type:`comment`,value:`# Create ALB with listener and default target group `},h=e=>{let n=t(e);return typeof n==`string`?n:``},g=e=>{let n=t(e);return typeof n==`number`&&Number.isFinite(n)?n:void 0};if(d===`new`){let e=h(`name`)||``,t=g(`port`)??80,n=h(`vpcId`);p.push({label:`Create Target Group`,parts:[m,{type:`variable`,value:`TG_ARN=`},{type:`bin`,value:`$(AWS_PROFILE=spinifex aws elbv2 create-target-group`},{type:`flag`,value:` \\ --name`},{type:`value`,value:` ${e}`},{type:`flag`,value:` \\ diff --git a/spinifex/services/spinifexui/frontend/dist/assets/create-placement-group.js b/spinifex/services/spinifexui/frontend/dist/assets/create-placement-group.js index afb9c4dcc..d7ab8188e 100644 --- a/spinifex/services/spinifexui/frontend/dist/assets/create-placement-group.js +++ b/spinifex/services/spinifexui/frontend/dist/assets/create-placement-group.js @@ -1,3 +1,3 @@ -import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./error-banner.js";import{t as r}from"./useNavigate.js";import{t as i}from"./back-link.js";import{a as ee,i as a,n as o,r as s,t as c}from"./select.js";import{t as l}from"./cli-command-panel.js";import{c as u}from"./ec2.js";import{L as d}from"./index.js";import{t as f}from"./page-heading.js";import{a as p,r as m,t as h}from"./field.js";import{n as g,r as _,t as v}from"./zod.js";import{i as y}from"./ec23.js";import{t as b}from"./form-actions.js";var te=t(),x=e();function S(){let e=(0,te.c)(52),t=r(),S=u(),C;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(C={resolver:v(y),defaultValues:{groupName:``,strategy:`spread`}},e[0]=C):C=e[0];let{control:w,handleSubmit:T,register:E,watch:D,formState:O}=_(C),{errors:k,isSubmitting:A}=O,j;e[1]!==S||e[2]!==t?(j=async e=>{t({to:`/ec2/describe-placement-groups/$id`,params:{id:(await S.mutateAsync(e)).PlacementGroup?.GroupId??``}})},e[1]=S,e[2]=t,e[3]=j):j=e[3];let M=j,N,P;e[4]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,x.jsx)(i,{to:`/ec2/describe-placement-groups`,children:`Back to placement groups`}),P=(0,x.jsx)(f,{title:`Create Placement Group`}),e[4]=N,e[5]=P):(N=e[4],P=e[5]);let F;e[6]===S.error?F=e[7]:(F=S.error&&(0,x.jsx)(n,{error:S.error,msg:`Failed to create placement group`}),e[6]=S.error,e[7]=F);let I;e[8]!==T||e[9]!==M?(I=T(M),e[8]=T,e[9]=M,e[10]=I):I=e[10];let L;e[11]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,x.jsx)(p,{children:(0,x.jsx)(`label`,{htmlFor:`groupName`,children:`Group Name`})}),e[11]=L):L=e[11];let R=!!k.groupName,z;e[12]===E?z=e[13]:(z=E(`groupName`),e[12]=E,e[13]=z);let B;e[14]!==R||e[15]!==z?(B=(0,x.jsx)(d,{"aria-invalid":R,id:`groupName`,placeholder:`my-placement-group`,...z}),e[14]=R,e[15]=z,e[16]=B):B=e[16];let V;e[17]===k.groupName?V=e[18]:(V=(0,x.jsx)(m,{errors:[k.groupName]}),e[17]=k.groupName,e[18]=V);let H;e[19]!==B||e[20]!==V?(H=(0,x.jsxs)(h,{children:[L,B,V]}),e[19]=B,e[20]=V,e[21]=H):H=e[21];let U;e[22]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,x.jsx)(p,{children:(0,x.jsx)(`label`,{htmlFor:`strategy`,children:`Strategy`})}),e[22]=U):U=e[22];let W;e[23]===k.strategy?W=e[24]:(W=e=>{let{field:t}=e;return(0,x.jsxs)(c,{onValueChange:e=>t.onChange(e),value:t.value??``,children:[(0,x.jsx)(a,{"aria-invalid":!!k.strategy,className:`w-full`,id:`strategy`,children:(0,x.jsx)(ee,{})}),(0,x.jsxs)(o,{children:[(0,x.jsx)(s,{value:`spread`,children:`spread`}),(0,x.jsx)(s,{value:`cluster`,children:`cluster`})]})]})},e[23]=k.strategy,e[24]=W);let G;e[25]!==w||e[26]!==W?(G=(0,x.jsx)(g,{control:w,name:`strategy`,render:W}),e[25]=w,e[26]=W,e[27]=G):G=e[27];let K;e[28]===k.strategy?K=e[29]:(K=(0,x.jsx)(m,{errors:[k.strategy]}),e[28]=k.strategy,e[29]=K);let q;e[30]!==G||e[31]!==K?(q=(0,x.jsxs)(h,{children:[U,G,K]}),e[30]=G,e[31]=K,e[32]=q):q=e[32];let J;e[33]===D?J=e[34]:(J=ne(D),e[33]=D,e[34]=J);let Y;e[35]===J?Y=e[36]:(Y=(0,x.jsx)(l,{commands:J}),e[35]=J,e[36]=Y);let X;e[37]===t?X=e[38]:(X=async()=>await t({to:`/ec2/describe-placement-groups`}),e[37]=t,e[38]=X);let Z;e[39]!==S.isPending||e[40]!==A||e[41]!==X?(Z=(0,x.jsx)(b,{isPending:S.isPending,isSubmitting:A,onCancel:X,pendingLabel:`Creating…`,submitLabel:`Create Placement Group`}),e[39]=S.isPending,e[40]=A,e[41]=X,e[42]=Z):Z=e[42];let Q;e[43]!==H||e[44]!==q||e[45]!==Y||e[46]!==Z||e[47]!==I?(Q=(0,x.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:I,children:[H,q,Y,Z]}),e[43]=H,e[44]=q,e[45]=Y,e[46]=Z,e[47]=I,e[48]=Q):Q=e[48];let $;return e[49]!==Q||e[50]!==F?($=(0,x.jsxs)(x.Fragment,{children:[N,P,F,Q]}),e[49]=Q,e[50]=F,e[51]=$):$=e[51],$}function ne(e){let t=e(`groupName`),n=typeof t==`string`?t:``,r=e(`strategy`),i=typeof r==`string`?r:``;return[{label:`Create Placement Group`,parts:[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 create-placement-group`},{type:`flag`,value:` \\ - --group-name`},{type:`value`,value:` ${n||``}`},{type:`flag`,value:` \\ +import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./error-banner.js";import{t as r}from"./useNavigate.js";import{t as i}from"./back-link.js";import{a as ee,i as a,n as o,r as s,t as c}from"./select.js";import{t as l}from"./cli-command-panel.js";import{c as u}from"./ec2.js";import{L as d}from"./index.js";import{t as f}from"./page-heading.js";import{a as p,r as m,t as h}from"./field.js";import{n as g,r as _,t as v}from"./zod.js";import{i as y}from"./ec23.js";import{t as b}from"./form-actions.js";var te=t(),x=e();function S(){let e=(0,te.c)(52),t=r(),S=u(),C;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(C={resolver:v(y),defaultValues:{groupName:``,strategy:`spread`}},e[0]=C):C=e[0];let{control:w,handleSubmit:T,register:E,watch:D,formState:O}=_(C),{errors:k,isSubmitting:A}=O,j;e[1]!==S||e[2]!==t?(j=async e=>{t({to:`/ec2/describe-placement-groups/$id`,params:{id:(await S.mutateAsync(e)).PlacementGroup?.GroupId??``}})},e[1]=S,e[2]=t,e[3]=j):j=e[3];let M=j,N,P;e[4]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,x.jsx)(i,{to:`/ec2/describe-placement-groups`,children:`Back to placement groups`}),P=(0,x.jsx)(f,{title:`Create Placement Group`}),e[4]=N,e[5]=P):(N=e[4],P=e[5]);let F;e[6]===S.error?F=e[7]:(F=S.error&&(0,x.jsx)(n,{error:S.error,msg:`Failed to create placement group`}),e[6]=S.error,e[7]=F);let I;e[8]!==T||e[9]!==M?(I=T(M),e[8]=T,e[9]=M,e[10]=I):I=e[10];let L;e[11]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,x.jsx)(p,{children:(0,x.jsx)(`label`,{htmlFor:`groupName`,children:`Group Name`})}),e[11]=L):L=e[11];let R=!!k.groupName,z;e[12]===E?z=e[13]:(z=E(`groupName`),e[12]=E,e[13]=z);let B;e[14]!==R||e[15]!==z?(B=(0,x.jsx)(d,{"aria-invalid":R,id:`groupName`,placeholder:`my-placement-group`,...z}),e[14]=R,e[15]=z,e[16]=B):B=e[16];let V;e[17]===k.groupName?V=e[18]:(V=(0,x.jsx)(m,{errors:[k.groupName]}),e[17]=k.groupName,e[18]=V);let H;e[19]!==B||e[20]!==V?(H=(0,x.jsxs)(h,{children:[L,B,V]}),e[19]=B,e[20]=V,e[21]=H):H=e[21];let U;e[22]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,x.jsx)(p,{children:(0,x.jsx)(`label`,{htmlFor:`strategy`,children:`Strategy`})}),e[22]=U):U=e[22];let W;e[23]===k.strategy?W=e[24]:(W=e=>{let{field:t}=e;return(0,x.jsxs)(c,{onValueChange:e=>t.onChange(e),value:t.value??``,children:[(0,x.jsx)(a,{"aria-invalid":!!k.strategy,className:`w-full`,id:`strategy`,children:(0,x.jsx)(ee,{})}),(0,x.jsxs)(o,{children:[(0,x.jsx)(s,{value:`spread`,children:`spread`}),(0,x.jsx)(s,{value:`cluster`,children:`cluster`})]})]})},e[23]=k.strategy,e[24]=W);let G;e[25]!==w||e[26]!==W?(G=(0,x.jsx)(g,{control:w,name:`strategy`,render:W}),e[25]=w,e[26]=W,e[27]=G):G=e[27];let K;e[28]===k.strategy?K=e[29]:(K=(0,x.jsx)(m,{errors:[k.strategy]}),e[28]=k.strategy,e[29]=K);let q;e[30]!==G||e[31]!==K?(q=(0,x.jsxs)(h,{children:[U,G,K]}),e[30]=G,e[31]=K,e[32]=q):q=e[32];let J;e[33]===D?J=e[34]:(J=ne(D),e[33]=D,e[34]=J);let Y;e[35]===J?Y=e[36]:(Y=(0,x.jsx)(l,{commands:J}),e[35]=J,e[36]=Y);let X;e[37]===t?X=e[38]:(X=async()=>await t({to:`/ec2/describe-placement-groups`}),e[37]=t,e[38]=X);let Z;e[39]!==S.isPending||e[40]!==A||e[41]!==X?(Z=(0,x.jsx)(b,{isPending:S.isPending,isSubmitting:A,onCancel:X,pendingLabel:`Creating…`,submitLabel:`Create Placement Group`}),e[39]=S.isPending,e[40]=A,e[41]=X,e[42]=Z):Z=e[42];let Q;e[43]!==H||e[44]!==q||e[45]!==Y||e[46]!==Z||e[47]!==I?(Q=(0,x.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:I,children:[H,q,Y,Z]}),e[43]=H,e[44]=q,e[45]=Y,e[46]=Z,e[47]=I,e[48]=Q):Q=e[48];let $;return e[49]!==Q||e[50]!==F?($=(0,x.jsxs)(x.Fragment,{children:[N,P,F,Q]}),e[49]=Q,e[50]=F,e[51]=$):$=e[51],$}function C(e){return`'${e.replaceAll(`'`,`'"'"'`)}'`}function ne(e){let t=e(`groupName`),n=typeof t==`string`?t:``,r=e(`strategy`),i=typeof r==`string`?r:``;return[{label:`Create Placement Group`,parts:[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 create-placement-group`},{type:`flag`,value:` \\ + --group-name`},{type:`value`,value:` ${n?C(n):``}`},{type:`flag`,value:` \\ --strategy`},{type:`value`,value:` ${i||`spread`}`}]}]}export{S as component}; \ No newline at end of file diff --git a/spinifex/services/spinifexui/frontend/dist/assets/create-target-group.js b/spinifex/services/spinifexui/frontend/dist/assets/create-target-group.js index d7219dd6a..f85bcab76 100644 --- a/spinifex/services/spinifexui/frontend/dist/assets/create-target-group.js +++ b/spinifex/services/spinifexui/frontend/dist/assets/create-target-group.js @@ -1,14 +1,14 @@ -import{n as e}from"./compiler-runtime.js";import{t}from"./error-banner.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./useNavigate.js";import{t as i}from"./back-link.js";import{t as a}from"./cli-command-panel.js";import{x as o}from"./ec22.js";import{r as s}from"./elbv2.js";import{t as c}from"./page-heading.js";import{r as l,t as u}from"./zod.js";import{t as d}from"./form-actions.js";import{t as f}from"./target-group-form.js";import{r as p}from"./elbv23.js";var m=e();function h(){let e=r(),{data:h}=n(o),_=s(),v=h.Vpcs??[],y=l({resolver:u(p),defaultValues:{name:``,protocol:`HTTP`,port:80,vpcId:v[0]?.VpcId??``,healthCheck:{protocol:`HTTP`,path:`/`,port:`traffic-port`,intervalSeconds:30,timeoutSeconds:5,healthyThresholdCount:5,unhealthyThresholdCount:2,matcher:`200`},tags:[]}}),{handleSubmit:b,watch:x,formState:{isSubmitting:S}}=y;return(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(i,{to:`/ec2/describe-target-groups`,children:`Back to target groups`}),(0,m.jsx)(c,{title:`Create target group`}),_.error&&(0,m.jsx)(t,{error:_.error,msg:`Failed to create target group`}),(0,m.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:b(async t=>{try{let n=(await _.mutateAsync(t)).TargetGroups?.[0]?.TargetGroupArn;e(n?{to:`/ec2/describe-target-groups/$id`,params:{id:encodeURIComponent(n)}}:{to:`/ec2/describe-target-groups`})}catch{}}),children:[(0,m.jsx)(f,{form:y,vpcs:v}),(0,m.jsx)(a,{commands:g(x)}),(0,m.jsx)(d,{isPending:_.isPending,isSubmitting:S,onCancel:async()=>await e({to:`/ec2/describe-target-groups`}),pendingLabel:`Creating…`,submitLabel:`Create target group`})]})]})}function g(e){let t=t=>{let n=e(t);return typeof n==`string`?n:``},n=t=>{let n=e(t);return typeof n==`number`&&Number.isFinite(n)?n:void 0},r=t(`name`),i=t(`protocol`)||`HTTP`,a=n(`port`),o=t(`vpcId`),s=t(`healthCheck.path`)||`/`,c=t(`healthCheck.port`)||`traffic-port`,l=n(`healthCheck.intervalSeconds`),u=n(`healthCheck.timeoutSeconds`),d=n(`healthCheck.healthyThresholdCount`),f=n(`healthCheck.unhealthyThresholdCount`),p=t(`healthCheck.matcher`)||`200`,m=[{type:`bin`,value:`AWS_PROFILE=spinifex aws elbv2 create-target-group`},{type:`flag`,value:` \\ +import{n as e}from"./compiler-runtime.js";import{t}from"./error-banner.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./useNavigate.js";import{t as i}from"./back-link.js";import{t as a}from"./cli-command-panel.js";import{x as o}from"./ec22.js";import{r as s}from"./elbv2.js";import{t as c}from"./page-heading.js";import{r as l,t as u}from"./zod.js";import{t as d}from"./form-actions.js";import{t as f}from"./target-group-form.js";import{r as p}from"./elbv23.js";var m=e();function h(){let e=r(),{data:h}=n(o),_=s(),v=h.Vpcs??[],y=l({resolver:u(p),defaultValues:{name:``,protocol:`HTTP`,port:80,vpcId:v[0]?.VpcId??``,healthCheck:{protocol:`HTTP`,path:`/`,port:`traffic-port`,intervalSeconds:30,timeoutSeconds:5,healthyThresholdCount:5,unhealthyThresholdCount:2,matcher:`200`},tags:[]}}),{handleSubmit:b,watch:x,formState:{isSubmitting:S}}=y;return(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(i,{to:`/ec2/describe-target-groups`,children:`Back to target groups`}),(0,m.jsx)(c,{title:`Create target group`}),_.error&&(0,m.jsx)(t,{error:_.error,msg:`Failed to create target group`}),(0,m.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:b(async t=>{try{let n=(await _.mutateAsync(t)).TargetGroups?.[0]?.TargetGroupArn;e(n?{to:`/ec2/describe-target-groups/$id`,params:{id:encodeURIComponent(n)}}:{to:`/ec2/describe-target-groups`})}catch{}}),children:[(0,m.jsx)(f,{form:y,vpcs:v}),(0,m.jsx)(a,{commands:g(x)}),(0,m.jsx)(d,{isPending:_.isPending,isSubmitting:S,onCancel:async()=>await e({to:`/ec2/describe-target-groups`}),pendingLabel:`Creating…`,submitLabel:`Create target group`})]})]})}function g(e){let t=t=>{let n=e(t);return typeof n==`string`?n:``},n=t=>{let n=e(t);return typeof n==`number`&&Number.isFinite(n)?n:void 0},r=t(`name`),i=t(`protocol`)||`HTTP`,a=n(`port`),o=t(`vpcId`),s=t(`healthCheck.protocol`)||`HTTP`,c=t(`healthCheck.path`)||`/`,l=t(`healthCheck.port`)||`traffic-port`,u=n(`healthCheck.intervalSeconds`),d=n(`healthCheck.timeoutSeconds`),f=n(`healthCheck.healthyThresholdCount`),p=n(`healthCheck.unhealthyThresholdCount`),m=t(`healthCheck.matcher`)||`200`,h=[{type:`bin`,value:`AWS_PROFILE=spinifex aws elbv2 create-target-group`},{type:`flag`,value:` \\ --name`},{type:`value`,value:` ${r||``}`},{type:`flag`,value:` \\ --protocol`},{type:`value`,value:` ${i}`},{type:`flag`,value:` \\ --port`},{type:`value`,value:` ${a??80}`},{type:`flag`,value:` \\ - --target-type`},{type:`value`,value:` instance`}];return o&&m.push({type:`flag`,value:` \\ - --vpc-id`},{type:`value`,value:` ${o}`}),m.push({type:`flag`,value:` \\ - --health-check-protocol`},{type:`value`,value:` HTTP`},{type:`flag`,value:` \\ - --health-check-path`},{type:`value`,value:` ${s}`},{type:`flag`,value:` \\ - --health-check-port`},{type:`value`,value:` ${c}`},{type:`flag`,value:` \\ - --health-check-interval-seconds`},{type:`value`,value:` ${l??30}`},{type:`flag`,value:` \\ - --health-check-timeout-seconds`},{type:`value`,value:` ${u??5}`},{type:`flag`,value:` \\ - --healthy-threshold-count`},{type:`value`,value:` ${d??5}`},{type:`flag`,value:` \\ - --unhealthy-threshold-count`},{type:`value`,value:` ${f??2}`},{type:`flag`,value:` \\ - --matcher`},{type:`value`,value:` HttpCode=${p}`}),[{label:`Create Target Group`,parts:m}]}var _=h;export{_ as component}; \ No newline at end of file + --target-type`},{type:`value`,value:` instance`}];return o&&h.push({type:`flag`,value:` \\ + --vpc-id`},{type:`value`,value:` ${o}`}),h.push({type:`flag`,value:` \\ + --health-check-protocol`},{type:`value`,value:` ${s}`},{type:`flag`,value:` \\ + --health-check-path`},{type:`value`,value:` ${c}`},{type:`flag`,value:` \\ + --health-check-port`},{type:`value`,value:` ${l}`},{type:`flag`,value:` \\ + --health-check-interval-seconds`},{type:`value`,value:` ${u??30}`},{type:`flag`,value:` \\ + --health-check-timeout-seconds`},{type:`value`,value:` ${d??5}`},{type:`flag`,value:` \\ + --healthy-threshold-count`},{type:`value`,value:` ${f??5}`},{type:`flag`,value:` \\ + --unhealthy-threshold-count`},{type:`value`,value:` ${p??2}`},{type:`flag`,value:` \\ + --matcher`},{type:`value`,value:` HttpCode=${m}`}),[{label:`Create Target Group`,parts:h}]}var _=h;export{_ as component}; \ No newline at end of file diff --git a/spinifex/services/spinifexui/frontend/dist/assets/describe-images.js b/spinifex/services/spinifexui/frontend/dist/assets/describe-images.js index 1180af814..b186284d8 100644 --- a/spinifex/services/spinifexui/frontend/dist/assets/describe-images.js +++ b/spinifex/services/spinifexui/frontend/dist/assets/describe-images.js @@ -1 +1 @@ -import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{r}from"./ec22.js";import{t as i}from"./page-heading.js";import{t as a}from"./state-badge.js";import{r as o}from"./system-managed.js";import{t as s}from"./list-card.js";var c=t(),l=e();function u(){let e=(0,c.c)(3),{data:t}=n(r),a;if(e[0]!==t.Images){let n=(t.Images??[]).filter(f),r;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,l.jsx)(i,{title:`EC2 Images`}),e[2]=r):r=e[2],a=(0,l.jsxs)(l.Fragment,{children:[r,n.length>0?(0,l.jsx)(`div`,{className:`space-y-4`,children:n.map(d)}):(0,l.jsx)(`p`,{className:`text-muted-foreground`,children:`No images found.`})]}),e[0]=t.Images,e[1]=a}else a=e[1];return a}function d(e){return e.ImageId?(0,l.jsx)(s,{badge:(0,l.jsx)(a,{state:e.State}),params:{id:e.ImageId},subtitle:e.ImageId??``,title:e.Name??e.ImageId??``,to:`/ec2/describe-images/$id`},e.ImageId):null}function f(e){return!o(e)}export{u as component}; \ No newline at end of file +import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{r}from"./ec22.js";import{t as i}from"./page-heading.js";import{t as a}from"./state-badge.js";import{t as o}from"./system-managed.js";import{t as s}from"./list-card.js";var c=t(),l=e();function u(){let e=(0,c.c)(3),{data:t}=n(r),a;if(e[0]!==t.Images){let n=(t.Images??[]).filter(f),r;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,l.jsx)(i,{title:`EC2 Images`}),e[2]=r):r=e[2],a=(0,l.jsxs)(l.Fragment,{children:[r,n.length>0?(0,l.jsx)(`div`,{className:`space-y-4`,children:n.map(d)}):(0,l.jsx)(`p`,{className:`text-muted-foreground`,children:`No images found.`})]}),e[0]=t.Images,e[1]=a}else a=e[1];return a}function d(e){return e.ImageId?(0,l.jsx)(s,{badge:(0,l.jsx)(a,{state:e.State}),params:{id:e.ImageId},subtitle:e.ImageId??``,title:e.Name??e.ImageId??``,to:`/ec2/describe-images/$id`},e.ImageId):null}function f(e){return!o(e)}export{u as component}; \ No newline at end of file diff --git a/spinifex/services/spinifexui/frontend/dist/assets/describe-load-balancers.js b/spinifex/services/spinifexui/frontend/dist/assets/describe-load-balancers.js index c329b8485..198e2d8a3 100644 --- a/spinifex/services/spinifexui/frontend/dist/assets/describe-load-balancers.js +++ b/spinifex/services/spinifexui/frontend/dist/assets/describe-load-balancers.js @@ -1 +1 @@ -import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./link.js";import{t as i}from"./useNavigate.js";import{t as a}from"./button.js";import{r as o}from"./ec22.js";import{i as s}from"./elbv22.js";import{t as c}from"./page-heading.js";import{t as l}from"./state-badge.js";import{n as u}from"./system-managed.js";import{t as d}from"./lb-image-missing-banner.js";var f=t(),p=e();function m(e){return e?new Date(e).toLocaleString():``}function h(){let e=(0,f.c)(20),t=i(),{data:h}=n(s),{data:_}=n(o),v;e[0]===h.LoadBalancers?v=e[1]:(v=h.LoadBalancers??[],e[0]=h.LoadBalancers,e[1]=v);let y=v,b;e[2]===_.Images?b=e[3]:(b=_.Images??[],e[2]=_.Images,e[3]=b);let x;e[4]===b?x=e[5]:(x=u(b),e[4]=b,e[5]=x);let S=x,C=!S,w;e[6]===t?w=e[7]:(w=async()=>await t({to:`/ec2/create-load-balancer`}),e[6]=t,e[7]=w);let T;e[8]!==C||e[9]!==w?(T=(0,p.jsx)(c,{actions:(0,p.jsx)(a,{disabled:C,onClick:w,children:`Create Load Balancer`}),title:`Load Balancers`}),e[8]=C,e[9]=w,e[10]=T):T=e[10];let E;e[11]===S?E=e[12]:(E=!S&&(0,p.jsx)(d,{}),e[11]=S,e[12]=E);let D;e[13]!==y||e[14]!==t?(D=y.length>0?(0,p.jsx)(`div`,{className:`overflow-x-auto rounded-lg border bg-card`,children:(0,p.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,p.jsx)(`thead`,{children:(0,p.jsxs)(`tr`,{className:`border-b text-left text-muted-foreground`,children:[(0,p.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Name`}),(0,p.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`DNS Name`}),(0,p.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`State`}),(0,p.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Type`}),(0,p.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Scheme`}),(0,p.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`VPC`}),(0,p.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Created`})]})}),(0,p.jsx)(`tbody`,{children:y.map(e=>{if(!e.LoadBalancerArn)return null;let n=e.LoadBalancerArn;return(0,p.jsxs)(`tr`,{className:`cursor-pointer border-b transition-colors last:border-0 hover:bg-accent`,onClick:async()=>await t({to:`/ec2/describe-load-balancers/$id`,params:{id:encodeURIComponent(n)}}),children:[(0,p.jsx)(`td`,{className:`px-4 py-2 font-medium`,children:(0,p.jsx)(r,{className:`text-primary hover:underline`,onClick:g,params:{id:encodeURIComponent(n)},to:`/ec2/describe-load-balancers/$id`,children:e.LoadBalancerName??n})}),(0,p.jsx)(`td`,{className:`px-4 py-2 font-mono text-xs`,children:e.DNSName??``}),(0,p.jsx)(`td`,{className:`px-4 py-2`,children:(0,p.jsx)(l,{state:e.State?.Code})}),(0,p.jsx)(`td`,{className:`px-4 py-2`,children:e.Type??``}),(0,p.jsx)(`td`,{className:`px-4 py-2`,children:e.Scheme??``}),(0,p.jsx)(`td`,{className:`px-4 py-2 font-mono text-xs`,children:e.VpcId??``}),(0,p.jsx)(`td`,{className:`px-4 py-2 text-xs`,children:m(e.CreatedTime)})]},n)})})]})}):(0,p.jsx)(`p`,{className:`text-muted-foreground`,children:`No load balancers found.`}),e[13]=y,e[14]=t,e[15]=D):D=e[15];let O;return e[16]!==T||e[17]!==E||e[18]!==D?(O=(0,p.jsxs)(p.Fragment,{children:[T,E,D]}),e[16]=T,e[17]=E,e[18]=D,e[19]=O):O=e[19],O}function g(e){return e.stopPropagation()}var _=h;export{_ as component}; \ No newline at end of file +import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./link.js";import{t as i}from"./useNavigate.js";import{t as a}from"./button.js";import{i as o}from"./elbv22.js";import{t as s}from"./page-heading.js";import{t as c}from"./state-badge.js";var l=t(),u=e();function d(e){return e?new Date(e).toLocaleString():``}function f(){let e=(0,l.c)(10),t=i(),{data:f}=n(o),m;e[0]===f.LoadBalancers?m=e[1]:(m=f.LoadBalancers??[],e[0]=f.LoadBalancers,e[1]=m);let h=m,g;e[2]===t?g=e[3]:(g=(0,u.jsx)(s,{actions:(0,u.jsx)(a,{onClick:async()=>await t({to:`/ec2/create-load-balancer`}),children:`Create Load Balancer`}),title:`Load Balancers`}),e[2]=t,e[3]=g);let _;e[4]!==h||e[5]!==t?(_=h.length>0?(0,u.jsx)(`div`,{className:`overflow-x-auto rounded-lg border bg-card`,children:(0,u.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,u.jsx)(`thead`,{children:(0,u.jsxs)(`tr`,{className:`border-b text-left text-muted-foreground`,children:[(0,u.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Name`}),(0,u.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`DNS Name`}),(0,u.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`State`}),(0,u.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Type`}),(0,u.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Scheme`}),(0,u.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`VPC`}),(0,u.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Created`})]})}),(0,u.jsx)(`tbody`,{children:h.map(e=>{if(!e.LoadBalancerArn)return null;let n=e.LoadBalancerArn;return(0,u.jsxs)(`tr`,{className:`cursor-pointer border-b transition-colors last:border-0 hover:bg-accent`,onClick:async()=>await t({to:`/ec2/describe-load-balancers/$id`,params:{id:encodeURIComponent(n)}}),children:[(0,u.jsx)(`td`,{className:`px-4 py-2 font-medium`,children:(0,u.jsx)(r,{className:`text-primary hover:underline`,onClick:p,params:{id:encodeURIComponent(n)},to:`/ec2/describe-load-balancers/$id`,children:e.LoadBalancerName??n})}),(0,u.jsx)(`td`,{className:`px-4 py-2 font-mono text-xs`,children:e.DNSName??``}),(0,u.jsx)(`td`,{className:`px-4 py-2`,children:(0,u.jsx)(c,{state:e.State?.Code})}),(0,u.jsx)(`td`,{className:`px-4 py-2`,children:e.Type??``}),(0,u.jsx)(`td`,{className:`px-4 py-2`,children:e.Scheme??``}),(0,u.jsx)(`td`,{className:`px-4 py-2 font-mono text-xs`,children:e.VpcId??``}),(0,u.jsx)(`td`,{className:`px-4 py-2 text-xs`,children:d(e.CreatedTime)})]},n)})})]})}):(0,u.jsx)(`p`,{className:`text-muted-foreground`,children:`No load balancers found.`}),e[4]=h,e[5]=t,e[6]=_):_=e[6];let v;return e[7]!==g||e[8]!==_?(v=(0,u.jsxs)(u.Fragment,{children:[g,_]}),e[7]=g,e[8]=_,e[9]=v):v=e[9],v}function p(e){return e.stopPropagation()}var m=f;export{m as component}; \ No newline at end of file diff --git a/spinifex/services/spinifexui/frontend/dist/assets/ec23.js b/spinifex/services/spinifexui/frontend/dist/assets/ec23.js index 9995fd2aa..46172b893 100644 --- a/spinifex/services/spinifexui/frontend/dist/assets/ec23.js +++ b/spinifex/services/spinifexui/frontend/dist/assets/ec23.js @@ -1 +1 @@ -import{D as e,E as t,O as n,T as r,j as i,k as a,w as o}from"./SignatureV4.js";import{F as s,I as c,P as l}from"./ec2.js";var u=/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\d{1,2}$/,d=i().min(1,`Key name is required`).max(255,`Key name must be 255 characters or less`).regex(/^[\w\s._\-:/()#,@[\]+=&;{}!$*]+$/,`Key name contains invalid characters`),f=[`gp3`],p=a({imageId:i(`Please select an Image`),instanceType:i(`Please select an instance type`),keyName:i(`Please select a key pair`).min(1,`Key pair is required`),subnetId:i().optional(),placementGroupName:i().optional(),count:e(`Instance count must be a whole number`).min(1,`Instance count must be at least 1`),rootDeviceName:i().optional(),rootVolumeSize:n().int(`Volume size must be a whole number`).min(1,`Volume size must be at least 1 GiB`).max(16384,`Volume size must be at most 16384 GiB`).optional(),rootVolumeType:o(f).optional(),rootDeleteOnTermination:t().optional()}),m=a({keyName:d}),h=a({keyName:d,publicKeyMaterial:i().min(1,`Public key is required`).refine(e=>e.trim().length>0,`Public key cannot be empty`)}),g=a({size:n().int(`Size must be a whole number`).min(1,`Size must be at least 1 GiB`).max(16384,`Size must be at most 16384 GiB`),availabilityZone:i().min(1,`Availability zone is required`)}),_=a({size:n().int(`Size must be a whole number`).min(1,`Size must be at least 1 GiB`)}),v=a({volumeId:i().min(1,`Volume is required`),description:i().optional()});a({sourceSnapshotId:i().min(1,`Source snapshot is required`),sourceRegion:i().min(1,`Source region is required`),description:i().optional()}),a({volumeId:i().min(1,`Volume is required`),instanceId:i().min(1,`Instance is required`),device:i().optional()}),a({volumeId:i().min(1,`Volume is required`),instanceId:i().optional(),force:t().optional()}),a({instanceType:i().min(1,`Instance type is required`)}),a({name:i().min(1,`Name is required`),description:i().optional()});var y=a({vpcId:i().min(1,`VPC is required`),cidrBlock:i().min(1,`CIDR block is required`).regex(u,`Must be a valid CIDR block (e.g. 10.0.1.0/24)`),availabilityZone:i().optional()});a({cidrBlock:i().min(1,`CIDR block is required`).regex(u,`Must be a valid CIDR block (e.g. 10.0.0.0/16)`),name:i().optional()});var b=a({key:i().min(1,`Key is required`),value:i()}),x=a({mode:o([`vpc-only`,`vpc-and-more`]),namePrefix:i().optional(),autoGenerateNames:t(),cidrBlock:i().min(1,`CIDR block is required`).regex(u,`Must be a valid CIDR block (e.g. 10.0.0.0/16)`).refine(e=>c(e),`CIDR has invalid octets or prefix length (must be /16 to /28)`),tenancy:o([`default`,`dedicated`]),publicSubnetCount:n().int().min(0).max(1),privateSubnetCount:n().int().min(0).max(2),publicSubnetCidrs:r(i()),privateSubnetCidrs:r(i()),tags:r(b)}).superRefine((e,t)=>{if(e.mode!==`vpc-and-more`)return;let n=[];for(let[r,i]of e.publicSubnetCidrs.entries())c(i,16,28)?(l(e.cidrBlock,i)||t.addIssue({code:`custom`,message:`Subnet CIDR must be within the VPC CIDR range`,path:[`publicSubnetCidrs`,r]}),n.push({cidr:i,field:`publicSubnetCidrs`,index:r})):t.addIssue({code:`custom`,message:`Invalid subnet CIDR format or prefix length`,path:[`publicSubnetCidrs`,r]});for(let[r,i]of e.privateSubnetCidrs.entries())c(i,16,28)?(l(e.cidrBlock,i)||t.addIssue({code:`custom`,message:`Subnet CIDR must be within the VPC CIDR range`,path:[`privateSubnetCidrs`,r]}),n.push({cidr:i,field:`privateSubnetCidrs`,index:r})):t.addIssue({code:`custom`,message:`Invalid subnet CIDR format or prefix length`,path:[`privateSubnetCidrs`,r]});for(let e=0;ee.trim().length>0,`Public key cannot be empty`)}),g=a({size:n().int(`Size must be a whole number`).min(1,`Size must be at least 1 GiB`).max(16384,`Size must be at most 16384 GiB`),availabilityZone:i().min(1,`Availability zone is required`)}),_=a({size:n().int(`Size must be a whole number`).min(1,`Size must be at least 1 GiB`)}),v=a({volumeId:i().min(1,`Volume is required`),description:i().optional()});a({sourceSnapshotId:i().min(1,`Source snapshot is required`),sourceRegion:i().min(1,`Source region is required`),description:i().optional()}),a({volumeId:i().min(1,`Volume is required`),instanceId:i().min(1,`Instance is required`),device:i().optional()}),a({volumeId:i().min(1,`Volume is required`),instanceId:i().optional(),force:t().optional()}),a({instanceType:i().min(1,`Instance type is required`)}),a({name:i().min(1,`Name is required`),description:i().optional()});var y=a({vpcId:i().min(1,`VPC is required`),cidrBlock:i().min(1,`CIDR block is required`).regex(u,`Must be a valid CIDR block (e.g. 10.0.1.0/24)`),availabilityZone:i().optional()});a({cidrBlock:i().min(1,`CIDR block is required`).regex(u,`Must be a valid CIDR block (e.g. 10.0.0.0/16)`),name:i().optional()});var b=a({key:i().min(1,`Key is required`),value:i()}),x=a({mode:o([`vpc-only`,`vpc-and-more`]),namePrefix:i().optional(),autoGenerateNames:t(),cidrBlock:i().min(1,`CIDR block is required`).regex(u,`Must be a valid CIDR block (e.g. 10.0.0.0/16)`).refine(e=>c(e),`CIDR has invalid octets or prefix length (must be /16 to /28)`),tenancy:o([`default`,`dedicated`]),publicSubnetCount:n().int().min(0).max(1),privateSubnetCount:n().int().min(0).max(2),publicSubnetCidrs:r(i()),privateSubnetCidrs:r(i()),tags:r(b)}).superRefine((e,t)=>{if(e.mode!==`vpc-and-more`)return;let n=[];for(let[r,i]of e.publicSubnetCidrs.entries())c(i,16,28)?(l(e.cidrBlock,i)||t.addIssue({code:`custom`,message:`Subnet CIDR must be within the VPC CIDR range`,path:[`publicSubnetCidrs`,r]}),n.push({cidr:i,field:`publicSubnetCidrs`,index:r})):t.addIssue({code:`custom`,message:`Invalid subnet CIDR format or prefix length`,path:[`publicSubnetCidrs`,r]});for(let[r,i]of e.privateSubnetCidrs.entries())c(i,16,28)?(l(e.cidrBlock,i)||t.addIssue({code:`custom`,message:`Subnet CIDR must be within the VPC CIDR range`,path:[`privateSubnetCidrs`,r]}),n.push({cidr:i,field:`privateSubnetCidrs`,index:r})):t.addIssue({code:`custom`,message:`Invalid subnet CIDR format or prefix length`,path:[`privateSubnetCidrs`,r]});for(let e=0;e{try{return JSON.parse(e),!0}catch{return!1}},{message:`Policy document must be valid JSON`})});export{n,r as t}; \ No newline at end of file +import{j as e,k as t}from"./SignatureV4.js";var n=t({userName:e().min(1,`User name is required`).max(64,`User name must be 64 characters or less`).regex(/^[\w+=,.@-]+$/,`User name contains invalid characters`),path:e().optional()}),r=t({policyName:e().min(1,`Policy name is required`).max(128,`Policy name must be 128 characters or less`).regex(/^[\w+=,.@-]+$/,`Policy name contains invalid characters`),description:e().optional(),policyDocument:e().min(1,`Policy document is required`).refine(e=>{try{return JSON.parse(e),!0}catch{return!1}},{message:`Policy document must be valid JSON`})});export{n,r as t}; \ No newline at end of file diff --git a/spinifex/services/spinifexui/frontend/dist/assets/index.js b/spinifex/services/spinifexui/frontend/dist/assets/index.js index f02efb46d..3d73cd942 100644 --- a/spinifex/services/spinifexui/frontend/dist/assets/index.js +++ b/spinifex/services/spinifexui/frontend/dist/assets/index.js @@ -1,4 +1,4 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/login.js","assets/compiler-runtime.js","assets/awsClient.js","assets/SignatureV4.js","assets/fromUtf8.browser.js","assets/toUtf8.browser.js","assets/DescribeInstancesCommand.js","assets/collapsible.js","assets/button.js","assets/dist.js","assets/separator.js","assets/createBaseUIEventDetails.js","assets/addEventListener.js","assets/zod.js","assets/card.js","assets/field.js","assets/route.js","assets/_auth.js","assets/ec22.js","assets/queryOptions.js","assets/s32.js","assets/useQuery.js","assets/useBaseQuery.js","assets/QueryClientProvider.js","assets/link.js","assets/useStore.js","assets/createLucideIcon.js","assets/chevron-down.js","assets/chevron-right.js","assets/page-heading.js","assets/state-badge.js","assets/admin.js","assets/nodes.js","assets/redirect.js","assets/service-metrics.js","assets/ls.js","assets/useSuspenseQuery.js","assets/list-card.js","assets/create-bucket.js","assets/s3.js","assets/error-banner.js","assets/useNavigate.js","assets/back-link.js","assets/cli-command-panel.js","assets/check.js","assets/copy.js","assets/use-copy-to-clipboard.js","assets/form-actions.js","assets/create-user.js","assets/iam.js","assets/iam3.js","assets/create-policy.js","assets/textarea.js","assets/create-vpc.js","assets/ec2.js","assets/select.js","assets/useOpenInteractionType.js","assets/ec23.js","assets/create-volume.js","assets/create-target-group.js","assets/elbv2.js","assets/target-group-form.js","assets/plus.js","assets/trash-2.js","assets/elbv23.js","assets/create-subnet.js","assets/create-snapshot.js","assets/create-security-group.js","assets/create-placement-group.js","assets/create-load-balancer.js","assets/elbv22.js","assets/lb-image-missing-banner.js","assets/system-managed.js","assets/import-key-pair.js","assets/create-key-pair.js","assets/alert-dialog.js","assets/download.js","assets/triangle-alert.js","assets/run-instances.js","assets/route2.js","assets/_bucket.js","assets/upload-button.js","assets/delete-confirmation-dialog.js","assets/list-users.js","assets/iam2.js","assets/list-policies.js","assets/describe-vpcs.js","assets/describe-volumes.js","assets/describe-target-groups.js","assets/describe-subnets.js","assets/describe-snapshots.js","assets/describe-security-groups.js","assets/describe-placement-groups.js","assets/describe-load-balancers.js","assets/describe-key-pairs.js","assets/describe-instances.js","assets/describe-images.js","assets/_.js","assets/_userName.js","assets/detail-row.js","assets/_policyArn.js","assets/_id12.js","assets/_id11.js","assets/_id10.js","assets/_id9.js","assets/tabs.js","assets/_id8.js","assets/_id7.js","assets/_id6.js","assets/_id5.js","assets/_id4.js","assets/_id3.js","assets/_id2.js","assets/ami-details.js","assets/_id.js"])))=>i.map(i=>d[i]); +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/login.js","assets/compiler-runtime.js","assets/awsClient.js","assets/SignatureV4.js","assets/fromUtf8.browser.js","assets/toUtf8.browser.js","assets/DescribeInstancesCommand.js","assets/collapsible.js","assets/button.js","assets/dist.js","assets/separator.js","assets/createBaseUIEventDetails.js","assets/addEventListener.js","assets/zod.js","assets/card.js","assets/field.js","assets/route.js","assets/_auth.js","assets/ec22.js","assets/queryOptions.js","assets/s32.js","assets/useQuery.js","assets/useBaseQuery.js","assets/QueryClientProvider.js","assets/link.js","assets/useStore.js","assets/createLucideIcon.js","assets/chevron-down.js","assets/chevron-right.js","assets/page-heading.js","assets/state-badge.js","assets/admin.js","assets/nodes.js","assets/redirect.js","assets/service-metrics.js","assets/ls.js","assets/useSuspenseQuery.js","assets/list-card.js","assets/create-bucket.js","assets/s3.js","assets/error-banner.js","assets/useNavigate.js","assets/back-link.js","assets/cli-command-panel.js","assets/check.js","assets/copy.js","assets/use-copy-to-clipboard.js","assets/form-actions.js","assets/create-user.js","assets/iam.js","assets/iam3.js","assets/create-policy.js","assets/textarea.js","assets/create-vpc.js","assets/ec2.js","assets/select.js","assets/useOpenInteractionType.js","assets/ec23.js","assets/create-volume.js","assets/create-target-group.js","assets/elbv2.js","assets/target-group-form.js","assets/plus.js","assets/trash-2.js","assets/elbv23.js","assets/create-subnet.js","assets/create-snapshot.js","assets/create-security-group.js","assets/create-placement-group.js","assets/create-load-balancer.js","assets/elbv22.js","assets/import-key-pair.js","assets/create-key-pair.js","assets/alert-dialog.js","assets/download.js","assets/triangle-alert.js","assets/run-instances.js","assets/route2.js","assets/_bucket.js","assets/upload-button.js","assets/delete-confirmation-dialog.js","assets/list-users.js","assets/iam2.js","assets/list-policies.js","assets/describe-vpcs.js","assets/describe-volumes.js","assets/describe-target-groups.js","assets/describe-subnets.js","assets/describe-snapshots.js","assets/describe-security-groups.js","assets/describe-placement-groups.js","assets/describe-load-balancers.js","assets/describe-key-pairs.js","assets/describe-instances.js","assets/describe-images.js","assets/system-managed.js","assets/_.js","assets/_userName.js","assets/detail-row.js","assets/_policyArn.js","assets/_id12.js","assets/_id11.js","assets/_id10.js","assets/_id9.js","assets/tabs.js","assets/_id8.js","assets/_id7.js","assets/_id6.js","assets/_id5.js","assets/_id4.js","assets/_id3.js","assets/_id2.js","assets/ami-details.js","assets/_id.js"])))=>i.map(i=>d[i]); import{a as e,i as t,n,r,t as i}from"./compiler-runtime.js";import{C as a,M as o,O as s,S as c,T as l,_ as u,a as d,b as f,c as p,d as m,f as h,g,h as _,i as v,j as y,k as b,m as x,n as S,o as C,p as w,r as T,s as E,t as D,w as O,x as k,y as ee}from"./QueryClientProvider.js";import{A,B as j,C as te,D as M,E as N,F as ne,G as re,K as ie,L as ae,M as oe,N as P,O as se,P as ce,R as le,S as ue,T as de,V as fe,_ as pe,a as me,b as he,c as ge,d as _e,f as ve,h as ye,i as be,j as xe,k as Se,l as Ce,m as we,o as Te,s as Ee,t as F,v as De,w as Oe,x as ke,y as Ae,z as je}from"./useStore.js";import{i as Me,n as Ne,r as Pe}from"./matchContext.js";import{n as Fe,t as I}from"./redirect.js";import{t as Ie}from"./link.js";import{n as L,r as Le,t as R}from"./lazyRouteComponent.js";import{t as Re}from"./useNavigate.js";import{cn as z,hn as ze,t as Be}from"./awsClient.js";import{c as Ve,d as He,i as Ue,l as We,n as Ge,t as Ke}from"./dist.js";import{F as qe,I as B,L as Je,S as Ye,c as Xe,l as Ze,t as Qe,x as $e}from"./SignatureV4.js";import{t as et}from"./createLucideIcon.js";import{C as tt,D as nt,E as rt,T as it,_ as at,b as ot,c as st,d as ct,f as lt,g as ut,h as dt,l as ft,m as pt,n as mt,o as ht,p as gt,r as _t,t as vt,u as yt,v as bt,x as xt,y as V}from"./button.js";import{a as St,i as Ct,n as wt,o as Tt,r as Et,s as Dt,t as Ot}from"./separator.js";import{_ as kt,b as At,f as jt,g as Mt,i as Nt,p as Pt,r as Ft,s as It,t as Lt,u as Rt,v as zt,x as Bt,y as Vt}from"./createBaseUIEventDetails.js";import{A as H,At as Ht,Bt as Ut,C as Wt,Ct as Gt,Dt as Kt,Et as qt,F as Jt,Ft as Yt,G as Xt,Gt as Zt,I as Qt,It as $t,J as en,K as tn,Kt as nn,L as rn,Lt as an,M as on,N as sn,O as cn,Ot as ln,P as un,Pt as dn,Q as fn,S as pn,St as mn,T as hn,Tt as gn,V as _n,W as vn,X as yn,Z as bn,_t as xn,a as Sn,bt as Cn,dt as wn,ft as Tn,gt as En,ht as Dn,i as On,j as kn,k as An,lt as jn,mt as Mn,o as Nn,p as Pn,pt as Fn,q as In,r as Ln,t as Rn,ut as zn,vt as Bn,w as Vn,wt as Hn,xt as Un,yt as Wn,z as Gn,zt as Kn}from"./useOpenInteractionType.js";import{n as qn,o as Jn,r as Yn,t as Xn,u as Zn}from"./addEventListener.js";import{_ as Qn,a as $n,b as er,c as tr,d as nr,f as rr,g as ir,h as ar,i as or,l as sr,m as cr,n as lr,o as ur,p as dr,r as fr,s as pr,t as mr,u as hr,v as gr,x as _r,y as vr}from"./ec22.js";import{a as yr,c as br,i as xr,n as Sr,o as Cr,r as wr,s as Tr,t as Er}from"./elbv22.js";import{a as Dr,i as Or,n as kr,o as Ar,r as jr,s as Mr,t as Nr}from"./iam2.js";import{n as Pr,t as Fr}from"./s32.js";(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),e.crossOrigin===`use-credentials`?t.credentials=`include`:e.crossOrigin===`anonymous`?t.credentials=`omit`:t.credentials=`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();function Ir(e){return{onFetch:(t,n)=>{let r=t.options,i=t.fetchOptions?.meta?.fetchMore?.direction,a=t.state.data?.pages||[],o=t.state.data?.pageParams||[],s={pages:[],pageParams:[]},c=0,l=async()=>{let n=!1,l=e=>{m(e,()=>t.signal,()=>n=!0)},u=x(t.options,t.fetchOptions),d=async(e,r,i)=>{if(n)return Promise.reject(t.signal.reason);if(r==null&&e.pages.length)return Promise.resolve(e);let a=await u((()=>{let e={client:t.client,queryKey:t.queryKey,pageParam:r,direction:i?`backward`:`forward`,meta:t.options.meta};return l(e),e})()),{maxPages:o}=t.options,s=i?w:h;return{pages:s(e.pages,a,o),pageParams:s(e.pageParams,r,o)}};if(i&&a.length){let e=i===`backward`,t=e?Rr:Lr,n={pages:a,pageParams:o};s=await d(n,t(r,n),e)}else{let t=e??a.length;do{let e=c===0?o[0]??r.initialPageParam:Lr(r,s);if(c>0&&e==null)break;s=await d(s,e),c++}while(ct.options.persister?.(l,{client:t.client,queryKey:t.queryKey,meta:t.options.meta,signal:t.signal},n):t.fetchFn=l}}}function Lr(e,{pages:t,pageParams:n}){let r=t.length-1;return t.length>0?e.getNextPageParam(t[r],t,n[r],n):void 0}function Rr(e,{pages:t,pageParams:n}){return t.length>0?e.getPreviousPageParam?.(t[0],t,n[0],n):void 0}var zr=class extends T{#e;#t;#n;#r;#i;#a;#o;#s;constructor(e){super(),this.#s=!1,this.#o=e.defaultOptions,this.setOptions(e.options),this.observers=[],this.#i=e.client,this.#r=this.#i.getQueryCache(),this.queryKey=e.queryKey,this.queryHash=e.queryHash,this.#t=Hr(this.options),this.state=e.state??this.#t,this.scheduleGc()}get meta(){return this.options.meta}get queryType(){return this.#e}get promise(){return this.#a?.promise}setOptions(e){if(this.options={...this.#o,...e},e?._type&&(this.#e=e._type),this.updateGcTime(this.options.gcTime),this.state&&this.state.data===void 0){let e=Hr(this.options);e.data!==void 0&&(this.setState(Vr(e.data,e.dataUpdatedAt)),this.#t=e)}}optionalRemove(){!this.observers.length&&this.state.fetchStatus===`idle`&&this.#r.remove(this)}setData(e,t){let n=a(this.state.data,e,this.options);return this.#l({data:n,type:`success`,dataUpdatedAt:t?.updatedAt,manual:t?.manual}),n}setState(e){this.#l({type:`setState`,state:e})}cancel(e){let t=this.#a?.promise;return this.#a?.cancel(e),t?t.then(k).catch(k):Promise.resolve()}destroy(){super.destroy(),this.cancel({silent:!0})}get resetState(){return this.#t}reset(){this.destroy(),this.setState(this.resetState)}isActive(){return this.observers.some(e=>O(e.options.enabled,this)!==!1)}isDisabled(){return this.getObserversCount()>0?!this.isActive():this.options.queryFn===s||!this.isFetched()}isFetched(){return this.state.dataUpdateCount+this.state.errorUpdateCount>0}isStatic(){return this.getObserversCount()>0?this.observers.some(e=>l(e.options.staleTime,this)===`static`):!1}isStale(){return this.getObserversCount()>0?this.observers.some(e=>e.getCurrentResult().isStale):this.state.data===void 0||this.state.isInvalidated}isStaleByTime(e=0){return this.state.data===void 0?!0:e===`static`?!1:this.state.isInvalidated?!0:!b(this.state.dataUpdatedAt,e)}onFocus(){this.observers.find(e=>e.shouldFetchOnWindowFocus())?.refetch({cancelRefetch:!1}),this.#a?.continue()}onOnline(){this.observers.find(e=>e.shouldFetchOnReconnect())?.refetch({cancelRefetch:!1}),this.#a?.continue()}addObserver(e){this.observers.includes(e)||(this.observers.push(e),this.clearGcTimeout(),this.#r.notify({type:`observerAdded`,query:this,observer:e}))}removeObserver(e){this.observers.includes(e)&&(this.observers=this.observers.filter(t=>t!==e),this.observers.length||(this.#a&&(this.#s||this.#c()?this.#a.cancel({revert:!0}):this.#a.cancelRetry()),this.scheduleGc()),this.#r.notify({type:`observerRemoved`,query:this,observer:e}))}getObserversCount(){return this.observers.length}#c(){return this.state.fetchStatus===`paused`&&this.state.status===`pending`}invalidate(){this.state.isInvalidated||this.#l({type:`invalidate`})}async fetch(e,t){if(this.state.fetchStatus!==`idle`&&this.#a?.status()!==`rejected`){if(this.state.data!==void 0&&t?.cancelRefetch)this.cancel({silent:!0});else if(this.#a)return this.#a.continueRetry(),this.#a.promise}if(e&&this.setOptions(e),!this.options.queryFn){let e=this.observers.find(e=>e.options.queryFn);e&&this.setOptions(e.options)}let n=new AbortController,r=e=>{Object.defineProperty(e,`signal`,{enumerable:!0,get:()=>(this.#s=!0,n.signal)})},i=()=>{let e=x(this.options,t),n=(()=>{let e={client:this.#i,queryKey:this.queryKey,meta:this.meta};return r(e),e})();return this.#s=!1,this.options.persister?this.options.persister(e,n,this):e(n)},a=(()=>{let e={fetchOptions:t,options:this.options,queryKey:this.queryKey,client:this.#i,state:this.state,fetchFn:i};return r(e),e})();(this.#e===`infinite`?Ir(this.options.pages):this.options.behavior)?.onFetch(a,this),this.#n=this.state,(this.state.fetchStatus===`idle`||this.state.fetchMeta!==a.fetchOptions?.meta)&&this.#l({type:`fetch`,meta:a.fetchOptions?.meta}),this.#a=C({initialPromise:t?.initialPromise,fn:a.fetchFn,onCancel:e=>{e instanceof v&&e.revert&&this.setState({...this.#n,fetchStatus:`idle`}),n.abort()},onFail:(e,t)=>{this.#l({type:`failed`,failureCount:e,error:t})},onPause:()=>{this.#l({type:`pause`})},onContinue:()=>{this.#l({type:`continue`})},retry:a.options.retry,retryDelay:a.options.retryDelay,networkMode:a.options.networkMode,canRun:()=>!0});try{let e=await this.#a.start();if(e===void 0)throw Error(`${this.queryHash} data is undefined`);return this.setData(e),this.#r.config.onSuccess?.(e,this),this.#r.config.onSettled?.(e,this.state.error,this),e}catch(e){if(e instanceof v){if(e.silent)return this.#a.promise;if(e.revert){if(this.state.data===void 0)throw e;return this.state.data}}throw this.#l({type:`error`,error:e}),this.#r.config.onError?.(e,this),this.#r.config.onSettled?.(this.state.data,e,this),e}finally{this.scheduleGc()}}#l(e){let t=t=>{switch(e.type){case`failed`:return{...t,fetchFailureCount:e.failureCount,fetchFailureReason:e.error};case`pause`:return{...t,fetchStatus:`paused`};case`continue`:return{...t,fetchStatus:`fetching`};case`fetch`:return{...t,...Br(t.data,this.options),fetchMeta:e.meta??null};case`success`:let n={...t,...Vr(e.data,e.dataUpdatedAt),dataUpdateCount:t.dataUpdateCount+1,...!e.manual&&{fetchStatus:`idle`,fetchFailureCount:0,fetchFailureReason:null}};return this.#n=e.manual?n:void 0,n;case`error`:let r=e.error;return{...t,error:r,errorUpdateCount:t.errorUpdateCount+1,errorUpdatedAt:Date.now(),fetchFailureCount:t.fetchFailureCount+1,fetchFailureReason:r,fetchStatus:`idle`,status:`error`,isInvalidated:!0};case`invalidate`:return{...t,isInvalidated:!0};case`setState`:return{...t,...e.state}}};this.state=t(this.state),p.batch(()=>{this.observers.forEach(e=>{e.onQueryUpdate()}),this.#r.notify({query:this,type:`updated`,action:e})})}};function Br(e,t){return{fetchFailureCount:0,fetchFailureReason:null,fetchStatus:d(t.networkMode)?`fetching`:`paused`,...e===void 0&&{error:null,status:`pending`}}}function Vr(e,t){return{data:e,dataUpdatedAt:t??Date.now(),error:null,isInvalidated:!1,status:`success`}}function Hr(e){let t=typeof e.initialData==`function`?e.initialData():e.initialData,n=t!==void 0,r=n?typeof e.initialDataUpdatedAt==`function`?e.initialDataUpdatedAt():e.initialDataUpdatedAt:0;return{data:t,dataUpdateCount:0,dataUpdatedAt:n?r??Date.now():0,error:null,errorUpdateCount:0,errorUpdatedAt:0,fetchFailureCount:0,fetchFailureReason:null,fetchMeta:null,isInvalidated:!1,status:n?`success`:`pending`,fetchStatus:`idle`}}var Ur=class extends T{#e;#t;#n;#r;constructor(e){super(),this.#e=e.client,this.mutationId=e.mutationId,this.#n=e.mutationCache,this.#t=[],this.state=e.state||Wr(),this.setOptions(e.options),this.scheduleGc()}setOptions(e){this.options=e,this.updateGcTime(this.options.gcTime)}get meta(){return this.options.meta}addObserver(e){this.#t.includes(e)||(this.#t.push(e),this.clearGcTimeout(),this.#n.notify({type:`observerAdded`,mutation:this,observer:e}))}removeObserver(e){this.#t=this.#t.filter(t=>t!==e),this.scheduleGc(),this.#n.notify({type:`observerRemoved`,mutation:this,observer:e})}optionalRemove(){this.#t.length||(this.state.status===`pending`?this.scheduleGc():this.#n.remove(this))}continue(){return this.#r?.continue()??this.execute(this.state.variables)}async execute(e){let t=()=>{this.#i({type:`continue`})},n={client:this.#e,meta:this.options.meta,mutationKey:this.options.mutationKey};this.#r=C({fn:()=>this.options.mutationFn?this.options.mutationFn(e,n):Promise.reject(Error(`No mutationFn found`)),onFail:(e,t)=>{this.#i({type:`failed`,failureCount:e,error:t})},onPause:()=>{this.#i({type:`pause`})},onContinue:t,retry:this.options.retry??0,retryDelay:this.options.retryDelay,networkMode:this.options.networkMode,canRun:()=>this.#n.canRun(this)});let r=this.state.status===`pending`,i=!this.#r.canStart();try{if(r)t();else{this.#i({type:`pending`,variables:e,isPaused:i}),this.#n.config.onMutate&&await this.#n.config.onMutate(e,this,n);let t=await this.options.onMutate?.(e,n);t!==this.state.context&&this.#i({type:`pending`,context:t,variables:e,isPaused:i})}let a=await this.#r.start();return await this.#n.config.onSuccess?.(a,e,this.state.context,this,n),await this.options.onSuccess?.(a,e,this.state.context,n),await this.#n.config.onSettled?.(a,null,this.state.variables,this.state.context,this,n),await this.options.onSettled?.(a,null,e,this.state.context,n),this.#i({type:`success`,data:a}),a}catch(t){try{await this.#n.config.onError?.(t,e,this.state.context,this,n)}catch(e){Promise.reject(e)}try{await this.options.onError?.(t,e,this.state.context,n)}catch(e){Promise.reject(e)}try{await this.#n.config.onSettled?.(void 0,t,this.state.variables,this.state.context,this,n)}catch(e){Promise.reject(e)}try{await this.options.onSettled?.(void 0,t,e,this.state.context,n)}catch(e){Promise.reject(e)}throw this.#i({type:`error`,error:t}),t}finally{this.#n.runNext(this)}}#i(e){let t=t=>{switch(e.type){case`failed`:return{...t,failureCount:e.failureCount,failureReason:e.error};case`pause`:return{...t,isPaused:!0};case`continue`:return{...t,isPaused:!1};case`pending`:return{...t,context:e.context,data:void 0,failureCount:0,failureReason:null,error:null,isPaused:e.isPaused,status:`pending`,variables:e.variables,submittedAt:Date.now()};case`success`:return{...t,data:e.data,failureCount:0,failureReason:null,error:null,status:`success`,isPaused:!1};case`error`:return{...t,data:void 0,error:e.error,failureCount:t.failureCount+1,failureReason:e.error,isPaused:!1,status:`error`}}};this.state=t(this.state),p.batch(()=>{this.#t.forEach(t=>{t.onMutationUpdate(e)}),this.#n.notify({mutation:this,type:`updated`,action:e})})}};function Wr(){return{context:void 0,data:void 0,error:null,failureCount:0,failureReason:null,isPaused:!1,status:`idle`,variables:void 0,submittedAt:0}}var Gr=class extends o{constructor(e={}){super(),this.config=e,this.#e=new Set,this.#t=new Map,this.#n=0}#e;#t;#n;build(e,t,n){let r=new Ur({client:e,mutationCache:this,mutationId:++this.#n,options:e.defaultMutationOptions(t),state:n});return this.add(r),r}add(e){this.#e.add(e);let t=Kr(e);if(typeof t==`string`){let n=this.#t.get(t);n?n.push(e):this.#t.set(t,[e])}this.notify({type:`added`,mutation:e})}remove(e){if(this.#e.delete(e)){let t=Kr(e);if(typeof t==`string`){let n=this.#t.get(t);if(n)if(n.length>1){let t=n.indexOf(e);t!==-1&&n.splice(t,1)}else n[0]===e&&this.#t.delete(t)}}this.notify({type:`removed`,mutation:e})}canRun(e){let t=Kr(e);if(typeof t==`string`){let n=this.#t.get(t)?.find(e=>e.state.status===`pending`);return!n||n===e}else return!0}runNext(e){let t=Kr(e);return typeof t==`string`?(this.#t.get(t)?.find(t=>t!==e&&t.state.isPaused))?.continue()??Promise.resolve():Promise.resolve()}clear(){p.batch(()=>{this.#e.forEach(e=>{this.notify({type:`removed`,mutation:e})}),this.#e.clear(),this.#t.clear()})}getAll(){return Array.from(this.#e)}find(e){let t={exact:!0,...e};return this.getAll().find(e=>ee(t,e))}findAll(e={}){return this.getAll().filter(t=>ee(e,t))}notify(e){p.batch(()=>{this.listeners.forEach(t=>{t(e)})})}resumePausedMutations(){let e=this.getAll().filter(e=>e.state.isPaused);return p.batch(()=>Promise.all(e.map(e=>e.continue().catch(k))))}};function Kr(e){return e.options.scope?.id}var qr=class extends o{constructor(e={}){super(),this.config=e,this.#e=new Map}#e;build(e,t,n){let r=t.queryKey,i=t.queryHash??u(r,t),a=this.get(i);return a||(a=new zr({client:e,queryKey:r,queryHash:i,options:e.defaultQueryOptions(t),state:n,defaultOptions:e.getQueryDefaults(r)}),this.add(a)),a}add(e){this.#e.has(e.queryHash)||(this.#e.set(e.queryHash,e),this.notify({type:`added`,query:e}))}remove(e){let t=this.#e.get(e.queryHash);t&&(e.destroy(),t===e&&this.#e.delete(e.queryHash),this.notify({type:`removed`,query:e}))}clear(){p.batch(()=>{this.getAll().forEach(e=>{this.remove(e)})})}get(e){return this.#e.get(e)}getAll(){return[...this.#e.values()]}find(e){let t={exact:!0,...e};return this.getAll().find(e=>f(t,e))}findAll(e={}){let t=this.getAll();return Object.keys(e).length>0?t.filter(t=>f(e,t)):t}notify(e){p.batch(()=>{this.listeners.forEach(t=>{t(e)})})}onFocus(){p.batch(()=>{this.getAll().forEach(e=>{e.onFocus()})})}onOnline(){p.batch(()=>{this.getAll().forEach(e=>{e.onOnline()})})}},Jr=class{#e;#t;#n;#r;#i;#a;#o;#s;constructor(e={}){this.#e=e.queryCache||new qr,this.#t=e.mutationCache||new Gr,this.#n=e.defaultOptions||{},this.#r=new Map,this.#i=new Map,this.#a=0}mount(){this.#a++,this.#a===1&&(this.#o=y.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onFocus())}),this.#s=E.subscribe(async e=>{e&&(await this.resumePausedMutations(),this.#e.onOnline())}))}unmount(){this.#a--,this.#a===0&&(this.#o?.(),this.#o=void 0,this.#s?.(),this.#s=void 0)}isFetching(e){return this.#e.findAll({...e,fetchStatus:`fetching`}).length}isMutating(e){return this.#t.findAll({...e,status:`pending`}).length}getQueryData(e){let t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state.data}ensureQueryData(e){let t=this.defaultQueryOptions(e),n=this.#e.build(this,t),r=n.state.data;return r===void 0?this.fetchQuery(e):(e.revalidateIfStale&&n.isStaleByTime(l(t.staleTime,n))&&this.prefetchQuery(t),Promise.resolve(r))}getQueriesData(e){return this.#e.findAll(e).map(({queryKey:e,state:t})=>[e,t.data])}setQueryData(e,t,n){let r=this.defaultQueryOptions({queryKey:e}),i=this.#e.get(r.queryHash)?.state.data,a=_(t,i);if(a!==void 0)return this.#e.build(this,r).setData(a,{...n,manual:!0})}setQueriesData(e,t,n){return p.batch(()=>this.#e.findAll(e).map(({queryKey:e})=>[e,this.setQueryData(e,t,n)]))}getQueryState(e){let t=this.defaultQueryOptions({queryKey:e});return this.#e.get(t.queryHash)?.state}removeQueries(e){let t=this.#e;p.batch(()=>{t.findAll(e).forEach(e=>{t.remove(e)})})}resetQueries(e,t){let n=this.#e;return p.batch(()=>(n.findAll(e).forEach(e=>{e.reset()}),this.refetchQueries({type:`active`,...e},t)))}cancelQueries(e,t={}){let n={revert:!0,...t},r=p.batch(()=>this.#e.findAll(e).map(e=>e.cancel(n)));return Promise.all(r).then(k).catch(k)}invalidateQueries(e,t={}){return p.batch(()=>(this.#e.findAll(e).forEach(e=>{e.invalidate()}),e?.refetchType===`none`?Promise.resolve():this.refetchQueries({...e,type:e?.refetchType??e?.type??`active`},t)))}refetchQueries(e,t={}){let n={...t,cancelRefetch:t.cancelRefetch??!0},r=p.batch(()=>this.#e.findAll(e).filter(e=>!e.isDisabled()&&!e.isStatic()).map(e=>{let t=e.fetch(void 0,n);return n.throwOnError||(t=t.catch(k)),e.state.fetchStatus===`paused`?Promise.resolve():t}));return Promise.all(r).then(k)}fetchQuery(e){let t=this.defaultQueryOptions(e);t.retry===void 0&&(t.retry=!1);let n=this.#e.build(this,t);return n.isStaleByTime(l(t.staleTime,n))?n.fetch(t):Promise.resolve(n.state.data)}prefetchQuery(e){return this.fetchQuery(e).then(k).catch(k)}fetchInfiniteQuery(e){return e._type=`infinite`,this.fetchQuery(e)}prefetchInfiniteQuery(e){return this.fetchInfiniteQuery(e).then(k).catch(k)}ensureInfiniteQueryData(e){return e._type=`infinite`,this.ensureQueryData(e)}resumePausedMutations(){return E.isOnline()?this.#t.resumePausedMutations():Promise.resolve()}getQueryCache(){return this.#e}getMutationCache(){return this.#t}getDefaultOptions(){return this.#n}setDefaultOptions(e){this.#n=e}setQueryDefaults(e,t){this.#r.set(g(e),{queryKey:e,defaultOptions:t})}getQueryDefaults(e){let t=[...this.#r.values()],n={};return t.forEach(t=>{c(e,t.queryKey)&&Object.assign(n,t.defaultOptions)}),n}setMutationDefaults(e,t){this.#i.set(g(e),{mutationKey:e,defaultOptions:t})}getMutationDefaults(e){let t=[...this.#i.values()],n={};return t.forEach(t=>{c(e,t.mutationKey)&&Object.assign(n,t.defaultOptions)}),n}defaultQueryOptions(e){if(e._defaulted)return e;let t={...this.#n.queries,...this.getQueryDefaults(e.queryKey),...e,_defaulted:!0};return t.queryHash||=u(t.queryKey,t),t.refetchOnReconnect===void 0&&(t.refetchOnReconnect=t.networkMode!==`always`),t.throwOnError===void 0&&(t.throwOnError=!!t.suspense),!t.networkMode&&t.persister&&(t.networkMode=`offlineFirst`),t.queryFn===s&&(t.enabled=!1),t}defaultMutationOptions(e){return e?._defaulted?e:{...this.#n.mutations,...e?.mutationKey&&this.getMutationDefaults(e.mutationKey),...e,_defaulted:!0}}clear(){this.#e.clear(),this.#t.clear()}};function Yr(){try{return typeof window<`u`&&typeof window.sessionStorage==`object`?window.sessionStorage:void 0}catch{return}}var Xr=`tsr-scroll-restoration-v1_3`;function Zr(){let e=Yr();if(!e)return null;let t={};try{let n=JSON.parse(e.getItem(`tsr-scroll-restoration-v1_3`)||`{}`);ae(n)&&(t=n)}catch{}return{get state(){return t},set:e=>{t=P(e,t)||t},persist:()=>{try{e.setItem(Xr,JSON.stringify(t))}catch{}}}}var Qr=Zr(),$r=e=>e.state.__TSR_key||e.href;function ei(e){let t=[],n;for(;n=e.parentNode;)t.push(`${e.tagName}:nth-child(${Array.prototype.indexOf.call(n.children,e)+1})`),e=n;return`${t.reverse().join(` > `)}`.toLowerCase()}var ti=!1,ni=`window`,ri=`data-scroll-restoration-id`;function ii(e,t){if(!Qr)return;let n=Qr;if((t??e.options.scrollRestoration??!1)&&(e.isScrollRestoring=!0),e.isScrollRestorationSetup||!n)return;e.isScrollRestorationSetup=!0,ti=!1;let r=e.options.getScrollRestorationKey||$r,i=new Map;window.history.scrollRestoration=`manual`;let a=t=>{if(!(ti||!e.isScrollRestoring))if(t.target===document||t.target===window)i.set(ni,{scrollX:window.scrollX||0,scrollY:window.scrollY||0});else{let e=t.target;i.set(e,{scrollX:e.scrollLeft||0,scrollY:e.scrollTop||0})}},o=t=>{if(!e.isScrollRestoring||!t||i.size===0||!n)return;let r=n.state[t]||={};for(let[e,t]of i){let n;if(e===ni)n=ni;else if(e.isConnected){let t=e.getAttribute(ri);n=t?`[${ri}="${t}"]`:ei(e)}n&&(r[n]=t)}};document.addEventListener(`scroll`,a,!0),e.subscribe(`onBeforeLoad`,e=>{o(e.fromLocation?r(e.fromLocation):void 0),i.clear()}),window.addEventListener(`pagehide`,()=>{o(r(e.stores.resolvedLocation.get()??e.stores.location.get())),n.persist()}),e.subscribe(`onRendered`,t=>{let a=r(t.toLocation),o=e.options.scrollRestorationBehavior,s=e.options.scrollToTopSelectors;if(i.clear(),!e.resetNextScroll){e.resetNextScroll=!0;return}if(!(typeof e.options.scrollRestoration==`function`&&!e.options.scrollRestoration({location:e.latestLocation}))){ti=!0;try{let t=e.isScrollRestoring?n.state[a]:void 0,r=!1;if(t)for(let e in t){let n=t[e];if(!ae(n))continue;let{scrollX:i,scrollY:a}=n;if(!(!Number.isFinite(i)||!Number.isFinite(a))){if(e===ni)window.scrollTo({top:a,left:i,behavior:o}),r=!0;else if(e){let t;try{t=document.querySelector(e)}catch{continue}t&&(t.scrollLeft=i,t.scrollTop=a,r=!0)}}}if(!r){let t=e.history.location.hash.slice(1);if(t){let e=window.history.state?.__hashScrollIntoViewOptions??!0;if(e){let n=document.getElementById(t);n&&n.scrollIntoView(e)}}else{let e={top:0,left:0,behavior:o};if(window.scrollTo(e),s)for(let t of s){if(t===ni)continue;let n=typeof t==`function`?t():document.querySelector(t);n&&n.scrollTo(e)}}}}finally{ti=!1}e.isScrollRestoring&&n.set(e=>(e[a]||={},e))}})}function ai(e,t=String){let n=new URLSearchParams;for(let r in e){let i=e[r];i!==void 0&&n.set(r,t(i))}return n.toString()}function oi(e){return e?e===`false`?!1:e===`true`?!0:e*0==0&&+e+``===e?+e:e:``}function si(e){let t=new URLSearchParams(e),n=Object.create(null);for(let[e,r]of t.entries()){let t=n[e];t==null?n[e]=oi(r):Array.isArray(t)?t.push(oi(r)):n[e]=[t,oi(r)]}return n}var ci=ui(JSON.parse),li=di(JSON.stringify,JSON.parse);function ui(e){return t=>{t[0]===`?`&&(t=t.substring(1));let n=si(t);for(let t in n){let r=n[t];if(typeof r==`string`)try{n[t]=e(r)}catch{}}return n}}function di(e,t){let n=typeof t==`function`;function r(r){if(typeof r==`object`&&r)try{return e(r)}catch{}else if(n&&typeof r==`string`)try{return t(r),e(r)}catch{}return r}return e=>{let t=ai(e,r);return t?`?${t}`:``}}function fi(e){return{input:({url:t})=>{for(let n of e)t=mi(n,t);return t},output:({url:t})=>{for(let n=e.length-1;n>=0;n--)t=hi(e[n],t);return t}}}function pi(e){let t=ye(e.basepath),n=`/${t}`,r=`${n}/`,i=e.caseSensitive?n:n.toLowerCase(),a=e.caseSensitive?r:r.toLowerCase();return{input:({url:t})=>{let r=e.caseSensitive?t.pathname:t.pathname.toLowerCase();return r===i?t.pathname=`/`:r.startsWith(a)&&(t.pathname=t.pathname.slice(n.length)),t},output:({url:e})=>(e.pathname=ve([`/`,t,e.pathname]),e)}}function mi(e,t){let n=e?.input?.({url:t});if(n){if(typeof n==`string`)return new URL(n);if(n instanceof URL)return n}return t}function hi(e,t){let n=e?.output?.({url:t});if(n){if(typeof n==`string`)return new URL(n);if(n instanceof URL)return n}return t}function gi(e,t){let{createMutableStore:n,createReadonlyStore:r,batch:i,init:a}=t,o=new Map,s=new Map,c=new Map,l=n(e.status),u=n(e.loadedAt),d=n(e.isLoading),f=n(e.isTransitioning),p=n(e.location),m=n(e.resolvedLocation),h=n(e.statusCode),g=n(e.redirect),_=n([]),v=n([]),y=n([]),b=r(()=>_i(o,_.get())),x=r(()=>_i(s,v.get())),S=r(()=>_i(c,y.get())),C=r(()=>_.get()[0]),w=r(()=>_.get().some(e=>o.get(e)?.get().status===`pending`)),T=r(()=>({locationHref:p.get().href,resolvedLocationHref:m.get()?.href,status:l.get()})),E=r(()=>({status:l.get(),loadedAt:u.get(),isLoading:d.get(),isTransitioning:f.get(),matches:b.get(),location:p.get(),resolvedLocation:m.get(),statusCode:h.get(),redirect:g.get()})),D=Oe(64);function O(e){let t=D.get(e);return t||(t=r(()=>{let t=_.get();for(let n of t){let t=o.get(n);if(t&&t.routeId===e)return t.get()}}),D.set(e,t)),t}let k={status:l,loadedAt:u,isLoading:d,isTransitioning:f,location:p,resolvedLocation:m,statusCode:h,redirect:g,matchesId:_,pendingIds:v,cachedIds:y,matches:b,pendingMatches:x,cachedMatches:S,firstId:C,hasPending:w,matchRouteDeps:T,matchStores:o,pendingMatchStores:s,cachedMatchStores:c,__store:E,getRouteMatchStore:O,setMatches:ee,setPending:A,setCached:j};ee(e.matches),a?.(k);function ee(e){vi(e,o,_,n,i)}function A(e){vi(e,s,v,n,i)}function j(e){vi(e,c,y,n,i)}return k}function _i(e,t){let n=[];for(let r of t){let t=e.get(r);t&&n.push(t.get())}return n}function vi(e,t,n,r,i){let a=e.map(e=>e.id),o=new Set(a);i(()=>{for(let e of t.keys())o.has(e)||t.delete(e);for(let n of e){let e=t.get(n.id);if(!e){let e=r(n);e.routeId=n.routeId,t.set(n.id,e);continue}e.routeId=n.routeId,e.get()!==n&&e.set(n)}M(n.get(),a)||n.set(a)})}var yi=e=>{if(!e.rendered)return e.rendered=!0,e.onReady?.()},bi=e=>e.stores.matchesId.get().some(t=>e.stores.matchStores.get(t)?.get()._forcePending),xi=(e,t)=>!!(e.preload&&!e.router.stores.matchStores.has(t)),Si=(e,t,n=!0)=>{let r={...e.router.options.context??{}},i=n?t:t-1;for(let t=0;t<=i;t++){let n=e.matches[t];if(!n)continue;let i=e.router.getMatch(n.id);i&&Object.assign(r,i.__routeContext,i.__beforeLoadContext)}return r},Ci=(e,t)=>{if(!e.matches.length)return;let n=t.routeId,r=e.matches.findIndex(t=>t.routeId===e.router.routeTree.id),i=r>=0?r:0,a=n?e.matches.findIndex(e=>e.routeId===n):e.firstBadMatchIndex??e.matches.length-1;a<0&&(a=i);for(let t=a;t>=0;t--){let n=e.matches[t];if(e.router.looseRoutesById[n.routeId].options.notFoundComponent)return t}return n?a:i},wi=(e,t,n)=>{if(!(!I(n)&&!Me(n)))throw I(n)&&n.redirectHandled&&!n.options.reloadDocument?n:(t&&(t._nonReactive.beforeLoadPromise?.resolve(),t._nonReactive.loaderPromise?.resolve(),t._nonReactive.beforeLoadPromise=void 0,t._nonReactive.loaderPromise=void 0,t._nonReactive.error=n,e.updateMatch(t.id,r=>({...r,status:I(n)?`redirected`:Me(n)?`notFound`:r.status===`pending`?`success`:r.status,context:Si(e,t.index),isFetching:!1,error:n})),Me(n)&&!n.routeId&&(n.routeId=t.routeId),t._nonReactive.loadPromise?.resolve()),I(n)&&(e.rendered=!0,n.options._fromLocation=e.location,n.redirectHandled=!0,n=e.router.resolveRedirect(n)),n)},Ti=(e,t)=>{let n=e.router.getMatch(t);return!!(!n||n._nonReactive.dehydrated)},Ei=(e,t,n)=>{let r=Si(e,n);e.updateMatch(t,e=>({...e,context:r}))},Di=(e,t,n,r)=>{let{id:i,routeId:a}=e.matches[t],o=e.router.looseRoutesById[a];if(n instanceof Promise)throw n;n.routerCode=r,e.firstBadMatchIndex??=t,wi(e,e.router.getMatch(i),n);try{o.options.onError?.(n)}catch(t){n=t,wi(e,e.router.getMatch(i),n)}e.updateMatch(i,e=>(e._nonReactive.beforeLoadPromise?.resolve(),e._nonReactive.beforeLoadPromise=void 0,e._nonReactive.loadPromise?.resolve(),{...e,error:n,status:`error`,isFetching:!1,updatedAt:Date.now(),abortController:new AbortController})),!e.preload&&!I(n)&&!Me(n)&&(e.serialError??=n)},Oi=(e,t,n,r)=>{if(r._nonReactive.pendingTimeout!==void 0)return;let i=n.options.pendingMs??e.router.options.defaultPendingMs;if(e.onReady&&!xi(e,t)&&(n.options.loader||n.options.beforeLoad||Ri(n))&&typeof i==`number`&&i!==1/0&&(n.options.pendingComponent??e.router.options?.defaultPendingComponent)){let t=setTimeout(()=>{yi(e)},i);r._nonReactive.pendingTimeout=t}},ki=(e,t,n)=>{let r=e.router.getMatch(t);if(!r._nonReactive.beforeLoadPromise&&!r._nonReactive.loaderPromise)return;Oi(e,t,n,r);let i=()=>{let n=e.router.getMatch(t);n.preload&&(n.status===`redirected`||n.status===`notFound`)&&wi(e,n,n.error)};return r._nonReactive.beforeLoadPromise?r._nonReactive.beforeLoadPromise.then(i):i()},U=(e,t,n,r)=>{let i=e.router.getMatch(t),a=i._nonReactive.loadPromise;i._nonReactive.loadPromise=se(()=>{a?.resolve(),a=void 0});let{paramsError:o,searchError:s}=i;o&&Di(e,n,o,`PARSE_PARAMS`),s&&Di(e,n,s,`VALIDATE_SEARCH`),Oi(e,t,r,i);let c=new AbortController,l=!1,u=()=>{l||(l=!0,e.updateMatch(t,e=>({...e,isFetching:`beforeLoad`,fetchCount:e.fetchCount+1,abortController:c})))},d=()=>{i._nonReactive.beforeLoadPromise?.resolve(),i._nonReactive.beforeLoadPromise=void 0,e.updateMatch(t,e=>({...e,isFetching:!1}))};if(!r.options.beforeLoad){e.router.batch(()=>{u(),d()});return}i._nonReactive.beforeLoadPromise=se();let f={...Si(e,n,!1),...i.__routeContext},{search:p,params:m,cause:h}=i,g=xi(e,t),_={search:p,abortController:c,params:m,preload:g,context:f,location:e.location,navigate:t=>e.router.navigate({...t,_fromLocation:e.location}),buildLocation:e.router.buildLocation,cause:g?`preload`:h,matches:e.matches,routeId:r.id,...e.router.options.additionalContext},v=r=>{if(r===void 0){e.router.batch(()=>{u(),d()});return}(I(r)||Me(r))&&(u(),Di(e,n,r,`BEFORE_LOAD`)),e.router.batch(()=>{u(),e.updateMatch(t,e=>({...e,__beforeLoadContext:r})),d()})},y;try{if(y=r.options.beforeLoad(_),le(y))return u(),y.catch(t=>{Di(e,n,t,`BEFORE_LOAD`)}).then(v)}catch(t){u(),Di(e,n,t,`BEFORE_LOAD`)}v(y)},Ai=(e,t)=>{let{id:n,routeId:r}=e.matches[t],i=e.router.looseRoutesById[r],a=()=>s(),o=()=>U(e,n,t,i),s=()=>{if(Ti(e,n))return;let t=ki(e,n,i);return le(t)?t.then(o):o()};return a()},ji=(e,t,n)=>{let r=e.router.getMatch(t);if(!r||!n.options.head&&!n.options.scripts&&!n.options.headers)return;let i={ssr:e.router.options.ssr,matches:e.matches,match:r,params:r.params,loaderData:r.loaderData};return Promise.all([n.options.head?.(i),n.options.scripts?.(i),n.options.headers?.(i)]).then(([e,t,n])=>({meta:e?.meta,links:e?.links,headScripts:e?.scripts,headers:n,scripts:t,styles:e?.styles}))},Mi=(e,t,n,r,i)=>{let a=t[r-1],{params:o,loaderDeps:s,abortController:c,cause:l}=e.router.getMatch(n),u=Si(e,r),d=xi(e,n);return{params:o,deps:s,preload:!!d,parentMatchPromise:a,abortController:c,context:u,location:e.location,navigate:t=>e.router.navigate({...t,_fromLocation:e.location}),cause:d?`preload`:l,route:i,...e.router.options.additionalContext}},Ni=async(e,t,n,r,i)=>{try{let a=e.router.getMatch(n);try{Li(i);let o=i.options.loader,s=typeof o==`function`?o:o?.handler,c=s?.(Mi(e,t,n,r,i)),l=!!s&&le(c);if((l||i._lazyPromise||i._componentsPromise||i.options.head||i.options.scripts||i.options.headers||a._nonReactive.minPendingPromise)&&e.updateMatch(n,e=>({...e,isFetching:`loader`})),s){let t=l?await c:c;wi(e,e.router.getMatch(n),t),t!==void 0&&e.updateMatch(n,e=>({...e,loaderData:t}))}i._lazyPromise&&await i._lazyPromise;let u=a._nonReactive.minPendingPromise;u&&await u,i._componentsPromise&&await i._componentsPromise,e.updateMatch(n,t=>({...t,error:void 0,context:Si(e,r),status:`success`,isFetching:!1,updatedAt:Date.now()}))}catch(t){let o=t;if(o?.name===`AbortError`){if(a.abortController.signal.aborted){a._nonReactive.loaderPromise?.resolve(),a._nonReactive.loaderPromise=void 0;return}e.updateMatch(n,t=>({...t,status:t.status===`pending`?`success`:t.status,isFetching:!1,context:Si(e,r)}));return}let s=a._nonReactive.minPendingPromise;s&&await s,Me(t)&&await i.options.notFoundComponent?.preload?.(),wi(e,e.router.getMatch(n),t);try{i.options.onError?.(t)}catch(t){o=t,wi(e,e.router.getMatch(n),t)}!I(o)&&!Me(o)&&await Li(i,[`errorComponent`]),e.updateMatch(n,t=>({...t,error:o,context:Si(e,r),status:`error`,isFetching:!1}))}}catch(t){let r=e.router.getMatch(n);r&&(r._nonReactive.loaderPromise=void 0),wi(e,r,t)}},Pi=async(e,t,n)=>{async function r(r,a,c,l,d){let f=Date.now()-a.updatedAt,p=r?d.options.preloadStaleTime??e.router.options.defaultPreloadStaleTime??3e4:d.options.staleTime??e.router.options.defaultStaleTime??0,m=d.options.shouldReload,h=typeof m==`function`?m(Mi(e,t,i,n,d)):m,{status:g,invalid:_}=l,v=f>=p&&(!!e.forceStaleReload||l.cause===`enter`||c!==void 0&&c!==l.id);o=g===`success`&&(_||(h??v)),r&&d.options.preload===!1||(o&&!e.sync&&u?(s=!0,(async()=>{try{await Ni(e,t,i,n,d);let r=e.router.getMatch(i);r._nonReactive.loaderPromise?.resolve(),r._nonReactive.loadPromise?.resolve(),r._nonReactive.loaderPromise=void 0,r._nonReactive.loadPromise=void 0}catch(t){I(t)&&await e.router.navigate(t.options)}})()):g!==`success`||o?await Ni(e,t,i,n,d):Ei(e,i,n))}let{id:i,routeId:a}=e.matches[n],o=!1,s=!1,c=e.router.looseRoutesById[a],l=c.options.loader,u=((typeof l==`function`?void 0:l?.staleReloadMode)??e.router.options.defaultStaleReloadMode)!==`blocking`;if(Ti(e,i)){if(!e.router.getMatch(i))return e.matches[n];Ei(e,i,n)}else{let t=e.router.getMatch(i),o=e.router.stores.matchesId.get()[n],s=(o&&e.router.stores.matchStores.get(o)||null)?.routeId===a?o:e.router.stores.matches.get().find(e=>e.routeId===a)?.id,l=xi(e,i);if(t._nonReactive.loaderPromise){if(t.status===`success`&&!e.sync&&!t.preload&&u)return t;await t._nonReactive.loaderPromise;let n=e.router.getMatch(i),a=n._nonReactive.error||n.error;a&&wi(e,n,a),n.status===`pending`&&await r(l,t,s,n,c)}else{let n=l&&!e.router.stores.matchStores.has(i),a=e.router.getMatch(i);a._nonReactive.loaderPromise=se(),n!==a.preload&&e.updateMatch(i,e=>({...e,preload:n})),await r(l,t,s,a,c)}}let d=e.router.getMatch(i);s||(d._nonReactive.loaderPromise?.resolve(),d._nonReactive.loadPromise?.resolve(),d._nonReactive.loadPromise=void 0),clearTimeout(d._nonReactive.pendingTimeout),d._nonReactive.pendingTimeout=void 0,s||(d._nonReactive.loaderPromise=void 0),d._nonReactive.dehydrated=void 0;let f=s?d.isFetching:!1;return f!==d.isFetching||d.invalid!==!1?(e.updateMatch(i,e=>({...e,isFetching:f,invalid:!1})),e.router.getMatch(i)):d};async function Fi(e){let t=e,n=[];bi(t.router)&&yi(t);let r;for(let e=0;e({...e,...a?{status:`success`,globalNotFound:!0,error:void 0}:{status:`notFound`,error:l},isFetching:!1})),u=e,await Li(r,[`notFoundComponent`])}else if(!t.preload){let e=t.matches[0];e.globalNotFound||t.router.getMatch(e.id)?.globalNotFound&&t.updateMatch(e.id,e=>({...e,globalNotFound:!1,error:void 0}))}if(t.serialError&&t.firstBadMatchIndex!==void 0){let e=t.router.looseRoutesById[t.matches[t.firstBadMatchIndex].routeId];await Li(e,[`errorComponent`])}for(let e=0;e<=u;e++){let{id:n,routeId:r}=t.matches[e],i=t.router.looseRoutesById[r];try{let e=ji(t,n,i);if(e){let r=await e;t.updateMatch(n,e=>({...e,...r}))}}catch(e){console.error(`Error executing head for route ${r}:`,e)}}let d=yi(t);if(le(d)&&await d,l)throw l;if(t.serialError&&!t.preload&&!t.onReady)throw t.serialError;return t.matches}function Ii(e,t){let n=t.map(t=>e.options[t]?.preload?.()).filter(Boolean);if(n.length!==0)return Promise.all(n)}function Li(e,t=zi){!e._lazyLoaded&&e._lazyPromise===void 0&&(e.lazyFn?e._lazyPromise=e.lazyFn().then(t=>{let{id:n,...r}=t.options;Object.assign(e.options,r),e._lazyLoaded=!0,e._lazyPromise=void 0}):e._lazyLoaded=!0);let n=()=>e._componentsLoaded?void 0:t===zi?(()=>{if(e._componentsPromise===void 0){let t=Ii(e,zi);t?e._componentsPromise=t.then(()=>{e._componentsLoaded=!0,e._componentsPromise=void 0}):e._componentsLoaded=!0}return e._componentsPromise})():Ii(e,t);return e._lazyPromise?e._lazyPromise.then(n):n()}function Ri(e){for(let t of zi)if(e.options[t]?.preload)return!0;return!1}var zi=[`component`,`errorComponent`,`pendingComponent`,`notFoundComponent`],Bi=`__TSR_index`,Vi=`popstate`,Hi=`beforeunload`;function Ui(e){let t=e.getLocation(),n=new Set,r=r=>{t=e.getLocation(),n.forEach(e=>e({location:t,action:r}))},i=n=>{e.notifyOnIndexChange??!0?r(n):t=e.getLocation()},a=async({task:n,navigateOpts:r,...i})=>{if(r?.ignoreBlocker??!1){n();return}let a=e.getBlockers?.()??[],o=i.type===`PUSH`||i.type===`REPLACE`;if(typeof document<`u`&&a.length&&o)for(let n of a){let r=qi(i.path,i.state);if(await n.blockerFn({currentLocation:t,nextLocation:r,action:i.type})){e.onBlocked?.();return}}n()};return{get location(){return t},get length(){return e.getLength()},subscribers:n,subscribe:e=>(n.add(e),()=>{n.delete(e)}),push:(n,i,o)=>{let s=t.state[Bi];i=Wi(s+1,i),a({task:()=>{e.pushState(n,i),r({type:`PUSH`})},navigateOpts:o,type:`PUSH`,path:n,state:i})},replace:(n,i,o)=>{let s=t.state[Bi];i=Wi(s,i),a({task:()=>{e.replaceState(n,i),r({type:`REPLACE`})},navigateOpts:o,type:`REPLACE`,path:n,state:i})},go:(t,n)=>{a({task:()=>{e.go(t),i({type:`GO`,index:t})},navigateOpts:n,type:`GO`})},back:t=>{a({task:()=>{e.back(t?.ignoreBlocker??!1),i({type:`BACK`})},navigateOpts:t,type:`BACK`})},forward:t=>{a({task:()=>{e.forward(t?.ignoreBlocker??!1),i({type:`FORWARD`})},navigateOpts:t,type:`FORWARD`})},canGoBack:()=>t.state[Bi]!==0,createHref:t=>e.createHref(t),block:t=>{if(!e.setBlockers)return()=>{};let n=e.getBlockers?.()??[];return e.setBlockers([...n,t]),()=>{let n=e.getBlockers?.()??[];e.setBlockers?.(n.filter(e=>e!==t))}},flush:()=>e.flush?.(),destroy:()=>e.destroy?.(),notify:r}}function Wi(e,t){t||={};let n=Ji();return{...t,key:n,__TSR_key:n,[Bi]:e}}function Gi(e){let t=e?.window??(typeof document<`u`?window:void 0),n=t.history.pushState,r=t.history.replaceState,i=[],a=()=>i,o=e=>i=e,s=e?.createHref??(e=>e),c=e?.parseLocation??(()=>qi(`${t.location.pathname}${t.location.search}${t.location.hash}`,t.history.state));if(!t.history.state?.__TSR_key&&!t.history.state?.key){let e=Ji();t.history.replaceState({[Bi]:0,key:e,__TSR_key:e},``)}let l=c(),u,d=!1,f=!1,p=!1,m=!1,h=()=>l,g,_,v=()=>{g&&(C._ignoreSubscribers=!0,(g.isPush?t.history.pushState:t.history.replaceState)(g.state,``,g.href),C._ignoreSubscribers=!1,g=void 0,_=void 0,u=void 0)},y=(e,t,n)=>{let r=s(t);_||(u=l),l=qi(t,n),g={href:r,state:n,isPush:g?.isPush||e===`push`},_||=Promise.resolve().then(()=>v())},b=e=>{l=c(),C.notify({type:e})},x=async()=>{if(f){f=!1;return}let e=c(),n=e.state[Bi]-l.state[Bi],r=n===1,i=n===-1,o=!r&&!i||d;d=!1;let s=o?`GO`:i?`BACK`:`FORWARD`,u=o?{type:`GO`,index:n}:{type:i?`BACK`:`FORWARD`};if(p)p=!1;else{let n=a();if(typeof document<`u`&&n.length){for(let r of n)if(await r.blockerFn({currentLocation:l,nextLocation:e,action:s})){f=!0,t.history.go(1),C.notify(u);return}}}l=c(),C.notify(u)},S=e=>{if(m){m=!1;return}let t=!1,n=a();if(typeof document<`u`&&n.length)for(let e of n){let n=e.enableBeforeUnload??!0;if(n===!0){t=!0;break}if(typeof n==`function`&&n()===!0){t=!0;break}}if(t)return e.preventDefault(),e.returnValue=``},C=Ui({getLocation:h,getLength:()=>t.history.length,pushState:(e,t)=>y(`push`,e,t),replaceState:(e,t)=>y(`replace`,e,t),back:e=>(e&&(p=!0),m=!0,t.history.back()),forward:e=>{e&&(p=!0),m=!0,t.history.forward()},go:e=>{d=!0,t.history.go(e)},createHref:e=>s(e),flush:v,destroy:()=>{t.history.pushState=n,t.history.replaceState=r,t.removeEventListener(Hi,S,{capture:!0}),t.removeEventListener(Vi,x)},onBlocked:()=>{u&&l!==u&&(l=u)},getBlockers:a,setBlockers:o,notifyOnIndexChange:!1});return t.addEventListener(Hi,S,{capture:!0}),t.addEventListener(Vi,x),t.history.pushState=function(...e){let r=n.apply(t.history,e);return C._ignoreSubscribers||b(`PUSH`),r},t.history.replaceState=function(...e){let n=r.apply(t.history,e);return C._ignoreSubscribers||b(`REPLACE`),n},C}function Ki(e){let t=e.replace(/[\x00-\x1f\x7f]/g,``);return t.startsWith(`//`)&&(t=`/`+t.replace(/^\/+/,``)),t}function qi(e,t){let n=Ki(e),r=n.indexOf(`#`),i=n.indexOf(`?`),a=Ji();return{href:n,pathname:n.substring(0,r>0?i>0?Math.min(r,i):r:i>0?i:n.length),hash:r>-1?n.substring(r):``,search:i>-1?n.slice(i,r===-1?void 0:r):``,state:t||{[Bi]:0,key:a,__TSR_key:a}}}function Ji(){return(Math.random()+1).toString(36).substring(7)}function Yi(e,t){let n=t,r=e;return{fromLocation:n,toLocation:r,pathChanged:n?.pathname!==r.pathname,hrefChanged:n?.href!==r.href,hashChanged:n?.hash!==r.hash}}var Xi=class{constructor(e,t){this.tempLocationKey=`${Math.round(Math.random()*1e7)}`,this.resetNextScroll=!0,this.shouldViewTransition=void 0,this.isViewTransitionTypesSupported=void 0,this.subscribers=new Set,this.isScrollRestoring=!1,this.isScrollRestorationSetup=!1,this.routeBranchCache=new WeakMap,this.startTransition=e=>e(),this.update=e=>{let t=this.options,n=this.basepath??t?.basepath??`/`,r=this.basepath===void 0,i=t?.rewrite;if(this.options={...t,...e},this.isServer=this.options.isServer??typeof document>`u`,this.protocolAllowlist=new Set(this.options.protocolAllowlist),this.options.pathParamsAllowedCharacters&&(this.pathParamsDecoder=Ce(this.options.pathParamsAllowedCharacters)),(!this.history||this.options.history&&this.options.history!==this.history)&&(this.options.history?this.history=this.options.history:this.history=Gi()),this.origin=this.options.origin,this.origin||(window?.origin&&window.origin!==`null`?this.origin=window.origin:this.origin=`http://localhost`),this.history&&this.updateLatestLocation(),this.options.routeTree!==this.routeTree){this.routeTree=this.options.routeTree;let e;this.resolvePathCache=Oe(1e3),e=this.buildRouteTree(),this.setRoutes(e)}if(!this.stores&&this.latestLocation){let e=this.getStoreConfig(this);this.batch=e.batch,this.stores=gi($i(this.latestLocation),e),ii(this)}let a=!1,o=this.options.basepath??`/`,s=this.options.rewrite;if(r||n!==o||i!==s){this.basepath=o;let e=[],t=ye(o);t&&t!==`/`&&e.push(pi({basepath:o})),s&&e.push(s),this.rewrite=e.length===0?void 0:e.length===1?e[0]:fi(e),this.history&&this.updateLatestLocation(),a=!0}a&&this.stores&&this.stores.location.set(this.latestLocation),typeof window<`u`&&`CSS`in window&&typeof window.CSS?.supports==`function`&&(this.isViewTransitionTypesSupported=window.CSS.supports(`selector(:active-view-transition-type(a)`))},this.updateLatestLocation=()=>{this.latestLocation=this.parseLocation(this.history.location,this.latestLocation)},this.buildRouteTree=()=>{let e=te(this.routeTree,this.options.caseSensitive,(e,t)=>{e.init({originalIndex:t})});return this.options.routeMasks&&ue(this.options.routeMasks,e.processedTree),e},this.subscribe=(e,t)=>{let n={eventType:e,fn:t};return this.subscribers.add(n),()=>{this.subscribers.delete(n)}},this.emit=e=>{this.subscribers.forEach(t=>{t.eventType===e.type&&t.fn(e)})},this.parseLocation=(e,t)=>{let n=({pathname:e,search:n,hash:r,href:i,state:a})=>{if(!this.rewrite&&!/[ \x00-\x1f\x7f\u0080-\uffff]/.test(e)){let i=this.options.parseSearch(n),o=this.options.stringifySearch(i);return{href:e+o+r,publicHref:e+o+r,pathname:Se(e).path,external:!1,searchStr:o,search:j(t?.search,i),hash:Se(r.slice(1)).path,state:fe(t?.state,a)}}let o=new URL(i,this.origin),s=mi(this.rewrite,o),c=this.options.parseSearch(s.search),l=this.options.stringifySearch(c);return s.search=l,{href:s.href.replace(s.origin,``),publicHref:i,pathname:Se(s.pathname).path,external:!!this.rewrite&&s.origin!==this.origin,searchStr:l,search:j(t?.search,c),hash:Se(s.hash.slice(1)).path,state:fe(t?.state,a)}},r=n(e),{__tempLocation:i,__tempKey:a}=r.state;if(i&&(!a||a===this.tempLocationKey)){let e=n(i);return e.state.key=r.state.key,e.state.__TSR_key=r.state.__TSR_key,delete e.state.__tempLocation,{...e,maskedLocation:r}}return r},this.resolvePathWithBase=(e,t)=>we({base:e,to:t.includes(`//`)?ge(t):t,trailingSlash:this.options.trailingSlash,cache:this.resolvePathCache}),this.matchRoutes=(e,t,n)=>typeof e==`string`?this.matchRoutesInternal({pathname:e,search:t},n):this.matchRoutesInternal(e,t),this.getMatchedRoutes=e=>ta({pathname:e,routesById:this.routesById,processedTree:this.processedTree}),this.cancelMatch=e=>{let t=this.getMatch(e);t&&(t.abortController.abort(),clearTimeout(t._nonReactive.pendingTimeout),t._nonReactive.pendingTimeout=void 0)},this.cancelMatches=()=>{this.stores.pendingIds.get().forEach(e=>{this.cancelMatch(e)}),this.stores.matchesId.get().forEach(e=>{if(this.stores.pendingMatchStores.has(e))return;let t=this.stores.matchStores.get(e)?.get();t&&(t.status===`pending`||t.isFetching===`loader`)&&this.cancelMatch(e)})},this.buildLocation=e=>{let t=(t={})=>{let n=t._fromLocation||this.pendingBuiltLocation||this.latestLocation,r=this.matchRoutesLightweight(n);t.from;let i=t.unsafeRelative===`path`?n.pathname:t.from??r.fullPath,a=t.to?`${t.to}`:void 0,o=r.search,s=Object.assign(Object.create(null),r.params),c=a?.charCodeAt(0)===47?`/`:this.resolvePathWithBase(i,`.`),l=a?this.resolvePathWithBase(c,a):c,u=t.params===!1||t.params===null?Object.create(null):(t.params??!0)===!0?s:Object.assign(s,P(t.params,s)),d=this.routesByPath[pe(l)],f;if(d)f=this.getRouteBranch(d);else if(l.includes(`$`))f=[];else{let e=this.getMatchedRoutes(l);f=e.matchedRoutes,this.options.notFoundRoute&&(!e.foundRoute||e.foundRoute.path!==`/`&&e.routeParams[`**`])&&(f=[...f,this.options.notFoundRoute])}if(f.length&&ce(u))for(let e of f){let t=e.options.params?.stringify??e.options.stringifyParams;if(t)try{Object.assign(u,t(u))}catch{}}let p=e.leaveParams?l:Se(_e({path:l,params:u,decoder:this.pathParamsDecoder,server:this.isServer}).interpolatedPath).path,m=o;if(e._includeValidateSearch&&this.options.search?.strict){let e={};f.forEach(t=>{if(t.options.validateSearch)try{Object.assign(e,ea(t.options.validateSearch,{...e,...m}))}catch{}}),m=e}m=na({search:m,dest:t,destRoutes:f,_includeValidateSearch:e._includeValidateSearch}),m=j(o,m);let h=this.options.stringifySearch(m),g=t.hash===!0?n.hash:t.hash?P(t.hash,n.hash):void 0,_=g?`#${g}`:``,v=t.state===!0?n.state:t.state?P(t.state,n.state):{};v=fe(n.state,v);let y=`${p}${h}${_}`,b,x,S=!1;if(this.rewrite){let e=new URL(y,this.origin),t=hi(this.rewrite,e);b=e.href.replace(e.origin,``),t.origin===this.origin?x=t.pathname+t.search+t.hash:(x=t.href,S=!0)}else b=xe(y),x=b;return{publicHref:x,href:b,pathname:p,search:m,searchStr:h,state:v,hash:g??``,external:S,unmaskOnReload:t.unmaskOnReload}},n=(n={},r)=>{let i=t(n),a=r?t(r):void 0;if(!a){let n=Object.create(null);if(this.options.routeMasks){let o=Ae(i.pathname,this.processedTree);if(o){Object.assign(n,o.rawParams);let{from:i,params:s,...c}=o.route,l=s===!1||s===null?Object.create(null):(s??!0)===!0?n:Object.assign(n,P(s,n));r={from:e.from,...c,params:l},a=t(r)}}}return a&&(i.maskedLocation=a),i};return e.mask?n(e,{from:e.from,...e.mask}):n(e)},this.commitLocation=async({viewTransition:e,ignoreBlocker:t,...n})=>{let r=()=>{let e=[`key`,`__TSR_key`,`__TSR_index`,`__hashScrollIntoViewOptions`];e.forEach(e=>{n.state[e]=this.latestLocation.state[e]});let t=A(n.state,this.latestLocation.state);return e.forEach(e=>{delete n.state[e]}),t},i=pe(this.latestLocation.href)===pe(n.href),a=this.commitLocationPromise;if(this.commitLocationPromise=se(()=>{a?.resolve(),a=void 0}),i&&r())this.load();else{let{maskedLocation:r,hashScrollIntoView:i,...a}=n;r&&(a={...r,state:{...r.state,__tempKey:void 0,__tempLocation:{...a,search:a.searchStr,state:{...a.state,__tempKey:void 0,__tempLocation:void 0,__TSR_key:void 0,key:void 0}}}},(a.unmaskOnReload??this.options.unmaskOnReload??!1)&&(a.state.__tempKey=this.tempLocationKey)),a.state.__hashScrollIntoViewOptions=i??this.options.defaultHashScrollIntoView??!0,this.shouldViewTransition=e,this.history[n.replace?`replace`:`push`](a.publicHref,a.state,{ignoreBlocker:t})}return this.resetNextScroll=n.resetScroll??!0,this.history.subscribers.size||this.load(),this.commitLocationPromise},this.buildAndCommitLocation=({replace:e,resetScroll:t,hashScrollIntoView:n,viewTransition:r,ignoreBlocker:i,href:a,...o}={})=>{if(a){let t=this.history.location.state.__TSR_index,n=qi(a,{__TSR_index:e?t:t+1}),r=new URL(n.pathname,this.origin);o.to=mi(this.rewrite,r).pathname,o.search=this.options.parseSearch(n.search),o.hash=n.hash.slice(1)}let s=this.buildLocation({...o,_includeValidateSearch:!0});this.pendingBuiltLocation=s;let c=this.commitLocation({...s,viewTransition:r,replace:e,resetScroll:t,hashScrollIntoView:n,ignoreBlocker:i});return Promise.resolve().then(()=>{this.pendingBuiltLocation===s&&(this.pendingBuiltLocation=void 0)}),c},this.navigate=async({to:e,reloadDocument:t,href:n,publicHref:r,...i})=>{let a=!1;if(n)try{new URL(`${n}`),a=!0}catch{}if(a&&!t&&(t=!0),t){if(e!==void 0||!n){let t=this.buildLocation({to:e,...i});n??=t.publicHref,r??=t.publicHref}let t=!a&&r?r:n;if(ne(t,this.protocolAllowlist))return Promise.resolve();if(!i.ignoreBlocker){let e=this.history.getBlockers?.()??[];for(let t of e)if(t?.blockerFn&&await t.blockerFn({currentLocation:this.latestLocation,nextLocation:this.latestLocation,action:`PUSH`}))return Promise.resolve()}return i.replace?window.location.replace(t):window.location.href=t,Promise.resolve()}return this.buildAndCommitLocation({...i,href:n,to:e,_isNavigate:!0})},this.beforeLoad=()=>{this.cancelMatches(),this.updateLatestLocation();let e=this.matchRoutes(this.latestLocation),t=this.stores.cachedMatches.get().filter(t=>!e.some(e=>e.id===t.id));this.batch(()=>{this.stores.status.set(`pending`),this.stores.statusCode.set(200),this.stores.isLoading.set(!0),this.stores.location.set(this.latestLocation),this.stores.setPending(e),this.stores.setCached(t)})},this.load=async e=>{let t,n,r,i=this.stores.resolvedLocation.get()??this.stores.location.get();for(r=new Promise(a=>{this.startTransition(async()=>{try{this.beforeLoad();let t=this.latestLocation,n=Yi(t,this.stores.resolvedLocation.get());this.stores.redirect.get()||this.emit({type:`onBeforeNavigate`,...n}),this.emit({type:`onBeforeLoad`,...n}),await Fi({router:this,sync:e?.sync,forceStaleReload:i.href===t.href,matches:this.stores.pendingMatches.get(),location:t,updateMatch:this.updateMatch,onReady:async()=>{this.startTransition(()=>{this.startViewTransition(async()=>{let e=null,t=null,n=null,r=null;this.batch(()=>{let i=this.stores.pendingMatches.get(),a=i.length,o=this.stores.matches.get();e=a?o.filter(e=>!this.stores.pendingMatchStores.has(e.id)):null;let s=new Set;for(let e of this.stores.pendingMatchStores.values())e.routeId&&s.add(e.routeId);let c=new Set;for(let e of this.stores.matchStores.values())e.routeId&&c.add(e.routeId);t=a?o.filter(e=>!s.has(e.routeId)):null,n=a?i.filter(e=>!c.has(e.routeId)):null,r=a?i.filter(e=>c.has(e.routeId)):o,this.stores.isLoading.set(!1),this.stores.loadedAt.set(Date.now()),a&&(this.stores.setMatches(i),this.stores.setPending([]),this.stores.setCached([...this.stores.cachedMatches.get(),...e.filter(e=>e.status!==`error`&&e.status!==`notFound`&&e.status!==`redirected`)]),this.clearExpiredCache())});for(let[e,i]of[[t,`onLeave`],[n,`onEnter`],[r,`onStay`]])if(e)for(let t of e)this.looseRoutesById[t.routeId].options[i]?.(t)})})}})}catch(e){I(e)?(t=e,this.navigate({...t.options,replace:!0,ignoreBlocker:!0})):Me(e)&&(n=e);let r=t?t.status:n?404:this.stores.matches.get().some(e=>e.status===`error`)?500:200;this.batch(()=>{this.stores.statusCode.set(r),this.stores.redirect.set(t)})}this.latestLoadPromise===r&&(this.commitLocationPromise?.resolve(),this.latestLoadPromise=void 0,this.commitLocationPromise=void 0),a()})}),this.latestLoadPromise=r,await r;this.latestLoadPromise&&r!==this.latestLoadPromise;)await this.latestLoadPromise;let a;this.hasNotFoundMatch()?a=404:this.stores.matches.get().some(e=>e.status===`error`)&&(a=500),a!==void 0&&this.stores.statusCode.set(a)},this.startViewTransition=e=>{let t=this.shouldViewTransition??this.options.defaultViewTransition;if(this.shouldViewTransition=void 0,t&&typeof document<`u`&&`startViewTransition`in document&&typeof document.startViewTransition==`function`){let n;if(typeof t==`object`&&this.isViewTransitionTypesSupported){let r=this.latestLocation,i=this.stores.resolvedLocation.get(),a=typeof t.types==`function`?t.types(Yi(r,i)):t.types;if(a===!1){e();return}n={update:e,types:a}}else n=e;document.startViewTransition(n)}else e()},this.updateMatch=(e,t)=>{this.startTransition(()=>{let n=this.stores.pendingMatchStores.get(e);if(n){n.set(t);return}let r=this.stores.matchStores.get(e);if(r){r.set(t);return}let i=this.stores.cachedMatchStores.get(e);if(i){let n=t(i.get());n.status===`redirected`?this.stores.cachedMatchStores.delete(e)&&this.stores.cachedIds.set(t=>t.filter(t=>t!==e)):i.set(n)}})},this.getMatch=e=>this.stores.cachedMatchStores.get(e)?.get()??this.stores.pendingMatchStores.get(e)?.get()??this.stores.matchStores.get(e)?.get(),this.invalidate=e=>{let t=t=>e?.filter?.(t)??!0?{...t,invalid:!0,...e?.forcePending||t.status===`error`||t.status===`notFound`?{status:`pending`,error:void 0}:void 0}:t;return this.batch(()=>{this.stores.setMatches(this.stores.matches.get().map(t)),this.stores.setCached(this.stores.cachedMatches.get().map(t)),this.stores.setPending(this.stores.pendingMatches.get().map(t))}),this.shouldViewTransition=!1,this.load({sync:e?.sync})},this.getParsedLocationHref=e=>e.publicHref||`/`,this.resolveRedirect=e=>{let t=e.headers.get(`Location`);if(!e.options.href||e.options._builtLocation){let t=e.options._builtLocation??this.buildLocation(e.options),n=this.getParsedLocationHref(t);e.options.href=n,e.headers.set(`Location`,n)}else if(t)try{let n=new URL(t);if(this.origin&&n.origin===this.origin){let t=n.pathname+n.search+n.hash;e.options.href=t,e.headers.set(`Location`,t)}}catch{}if(e.options.href&&!e.options._builtLocation&&ne(e.options.href,this.protocolAllowlist))throw Error(`Redirect blocked: unsafe protocol`);return e.headers.get(`Location`)||e.headers.set(`Location`,e.options.href),e},this.clearCache=e=>{let t=e?.filter;t===void 0?this.stores.setCached([]):this.stores.setCached(this.stores.cachedMatches.get().filter(e=>!t(e)))},this.clearExpiredCache=()=>{let e=Date.now();this.clearCache({filter:t=>{let n=this.looseRoutesById[t.routeId];if(!n.options.loader)return!0;let r=(t.preload?n.options.preloadGcTime??this.options.defaultPreloadGcTime:n.options.gcTime??this.options.defaultGcTime)??300*1e3;return t.status===`error`?!0:e-t.updatedAt>=r}})},this.loadRouteChunk=Li,this.preloadRoute=async e=>{let t=e._builtLocation??this.buildLocation(e),n=this.matchRoutes(t,{throwOnError:!0,preload:!0,dest:e}),r=new Set([...this.stores.matchesId.get(),...this.stores.pendingIds.get()]),i=new Set([...r,...this.stores.cachedIds.get()]),a=n.filter(e=>!i.has(e.id));if(a.length){let e=this.stores.cachedMatches.get();this.stores.setCached([...e,...a])}try{return n=await Fi({router:this,matches:n,location:t,preload:!0,updateMatch:(e,t)=>{r.has(e)?n=n.map(n=>n.id===e?t(n):n):this.updateMatch(e,t)}}),n}catch(e){if(I(e))return e.options.reloadDocument?void 0:await this.preloadRoute({...e.options,_fromLocation:t});Me(e)||console.error(e);return}},this.matchRoute=(e,t)=>{let n={...e,to:e.to?this.resolvePathWithBase(e.from||``,e.to):void 0,params:e.params||{},leaveParams:!0},r=this.buildLocation(n);if(t?.pending&&this.stores.status.get()!==`pending`)return!1;let i=(t?.pending===void 0?!this.stores.isLoading.get():t.pending)?this.latestLocation:this.stores.resolvedLocation.get()||this.stores.location.get(),a=ke(r.pathname,t?.caseSensitive??!1,t?.fuzzy??!1,i.pathname,this.processedTree);return!a||e.params&&!A(a.rawParams,e.params,{partial:!0})?!1:t?.includeSearch??!0?A(i.search,r.search,{partial:!0})?a.rawParams:!1:a.rawParams},this.hasNotFoundMatch=()=>this.stores.matches.get().some(e=>e.status===`notFound`||e.globalNotFound),this.getStoreConfig=t,this.update({defaultPreloadDelay:50,defaultPendingMs:1e3,defaultPendingMinMs:500,context:void 0,...e,caseSensitive:e.caseSensitive??!1,notFoundMode:e.notFoundMode??`fuzzy`,stringifySearch:e.stringifySearch??li,parseSearch:e.parseSearch??ci,protocolAllowlist:e.protocolAllowlist??N}),typeof document<`u`&&(self.__TSR_ROUTER__=this)}isShell(){return!!this.options.isShell}isPrerendering(){return!!this.options.isPrerendering}get state(){return this.stores.__store.get()}setRoutes({routesById:e,routesByPath:t,processedTree:n}){this.routesById=e,this.routesByPath=t,this.processedTree=n;let r=this.options.notFoundRoute;r&&(r.init({originalIndex:99999999999}),this.routesById[r.id]=r)}getRouteBranch(e){let t=this.routeBranchCache.get(e);return t||(t=De(e),this.routeBranchCache.set(e,t)),t}get looseRoutesById(){return this.routesById}getParentContext(e){return e?.id?e.context??this.options.context??void 0:this.options.context??void 0}matchRoutesInternal(e,t){let n=this.getMatchedRoutes(e.pathname),{foundRoute:r,routeParams:i}=n,{matchedRoutes:a}=n,o=!1;(r?r.path!==`/`&&i[`**`]:pe(e.pathname))&&(this.options.notFoundRoute?a=[...a,this.options.notFoundRoute]:o=!0);let s=o?ia(this.options.notFoundMode,a):void 0,c=Array(a.length),l=new Map;for(let e of this.stores.matchStores.values())e.routeId&&l.set(e.routeId,e.get());for(let n=0;nthis.navigate({...t,_fromLocation:e}),buildLocation:this.buildLocation,cause:n.cause,abortController:n.abortController,preload:!!n.preload,matches:c,routeId:r.id};n.__routeContext=r.options.context(t)??void 0}n.context={...a,...n.__routeContext,...n.__beforeLoadContext}}}return c}matchRoutesLightweight(e){let{matchedRoutes:t,routeParams:n}=this.getMatchedRoutes(e.pathname),r=je(t),i={...e.search};for(let e of t)try{Object.assign(i,ea(e.options.validateSearch,i))}catch{}let a=je(this.stores.matchesId.get()),o=a&&this.stores.matchStores.get(a)?.get(),s=o&&o.routeId===r.id&&o.pathname===e.pathname,c;if(s)c=o.params;else{let e=Object.assign(Object.create(null),n);for(let n of t)try{aa(n,e)}catch{}c=e}return{matchedRoutes:t,fullPath:r.fullPath,search:i,params:c}}},Zi=class extends Error{},Qi=class extends Error{};function $i(e){return{loadedAt:0,isLoading:!1,isTransitioning:!1,status:`idle`,resolvedLocation:void 0,location:e,matches:[],statusCode:200}}function ea(e,t){if(e==null)return{};if(`~standard`in e){let n=e[`~standard`].validate(t);if(n instanceof Promise)throw new Zi(`Async validation not supported`);if(n.issues)throw new Zi(JSON.stringify(n.issues,void 0,2),{cause:n});return n.value}return`parse`in e?e.parse(t):typeof e==`function`?e(t):{}}function ta({pathname:e,routesById:t,processedTree:n}){let r=Object.create(null),i=pe(e),a,o=he(i,n,!0);return o&&(a=o.route,Object.assign(r,o.rawParams)),{matchedRoutes:o?.branch||[t.__root__],routeParams:r,foundRoute:a}}function na({search:e,dest:t,destRoutes:n,_includeValidateSearch:r}){return ra(n)(e,t,r??!1)}function ra(e){let t={dest:null,_includeValidateSearch:!1,middlewares:[]};for(let n of e)`search`in n.options?n.options.search?.middlewares&&t.middlewares.push(...n.options.search.middlewares):(n.options.preSearchFilters||n.options.postSearchFilters)&&t.middlewares.push(({search:e,next:t})=>{let r=e;`preSearchFilters`in n.options&&n.options.preSearchFilters&&(r=n.options.preSearchFilters.reduce((e,t)=>t(e),e));let i=t(r);return`postSearchFilters`in n.options&&n.options.postSearchFilters?n.options.postSearchFilters.reduce((e,t)=>t(e),i):i}),n.options.validateSearch&&t.middlewares.push(({search:e,next:r})=>{let i=r(e);if(!t._includeValidateSearch)return i;try{return{...i,...ea(n.options.validateSearch,i)??void 0}}catch{return i}});t.middlewares.push(({search:e})=>{let n=t.dest;return n.search?n.search===!0?e:P(n.search,e):{}});let n=(e,t,r)=>{if(e>=r.length)return t;let i=r[e];return i({search:t,next:t=>n(e+1,t,r)})};return function(e,r,i){return t.dest=r,t._includeValidateSearch=i,n(0,e,t.middlewares)}}function ia(e,t){if(e!==`root`)for(let e=t.length-1;e>=0;e--){let n=t[e];if(n.children)return n.id}return Pe}function aa(e,t){let n=e.options.params?.parse??e.options.parseParams;if(n){let e=n(t);if(e===!1)throw Error(`Route params.parse returned false for a matched route`);Object.assign(t,e)}}function oa(e,t){if(e)return typeof e==`string`?e:e[t]}function sa(e){return typeof e==`string`?{href:e,crossOrigin:void 0}:e}function ca(e){if(e.tag!==`link`)return;let t=e.attrs?.rel,n=e.attrs?.href;if(typeof n==`string`&&(typeof t==`string`?t.split(/\s+/):[]).includes(`stylesheet`))return n}function la(e,t){let n=ca(t);return!!n&&e?.inlineCss?.styles[n]!==void 0}function ua(e){if(typeof document<`u`&&document.querySelector){let t=e.stores.location.get(),n=t.state.__hashScrollIntoViewOptions??!0;if(n&&t.hash!==``){let e=document.getElementById(t.hash);e&&e.scrollIntoView(n)}}}var W=e(r(),1),G=n();function da(e){let t=e.errorComponent??pa;return(0,G.jsx)(fa,{getResetKey:e.getResetKey,onCatch:e.onCatch,children:({error:n,reset:r})=>n?W.createElement(t,{error:n,reset:r}):e.children})}var fa=class extends W.Component{constructor(...e){super(...e),this.state={error:null}}static getDerivedStateFromProps(e,t){let n=e.getResetKey();return t.error&&t.resetKey!==n?{resetKey:n,error:null}:{resetKey:n}}static getDerivedStateFromError(e){return{error:e}}reset(){this.setState({error:null})}componentDidCatch(e,t){this.props.onCatch&&this.props.onCatch(e,t)}render(){return this.props.children({error:this.state.error,reset:()=>{this.reset()}})}};function pa({error:e}){let[t,n]=W.useState(!1);return(0,G.jsxs)(`div`,{style:{padding:`.5rem`,maxWidth:`100%`},children:[(0,G.jsxs)(`div`,{style:{display:`flex`,alignItems:`center`,gap:`.5rem`},children:[(0,G.jsx)(`strong`,{style:{fontSize:`1rem`},children:`Something went wrong!`}),(0,G.jsx)(`button`,{style:{appearance:`none`,fontSize:`.6em`,border:`1px solid currentColor`,padding:`.1rem .2rem`,fontWeight:`bold`,borderRadius:`.25rem`},onClick:()=>n(e=>!e),children:t?`Hide Error`:`Show Error`})]}),(0,G.jsx)(`div`,{style:{height:`.25rem`}}),t?(0,G.jsx)(`div`,{children:(0,G.jsx)(`pre`,{style:{fontSize:`.7em`,border:`1px solid red`,borderRadius:`.25rem`,padding:`.3rem`,color:`red`,overflow:`auto`},children:e.message?(0,G.jsx)(`code`,{children:e.message}):null})}):null]})}var ma=(e=>(e[e.None=0]=`None`,e[e.Mutable=1]=`Mutable`,e[e.Watching=2]=`Watching`,e[e.RecursedCheck=4]=`RecursedCheck`,e[e.Recursed=8]=`Recursed`,e[e.Dirty=16]=`Dirty`,e[e.Pending=32]=`Pending`,e))(ma||{});function ha({update:e,notify:t,unwatched:n}){return{link:r,unlink:i,propagate:a,checkDirty:o,shallowPropagate:s};function r(e,t,n){let r=t.depsTail;if(r!==void 0&&r.dep===e)return;let i=r===void 0?t.deps:r.nextDep;if(i!==void 0&&i.dep===e){i.version=n,t.depsTail=i;return}let a=e.subsTail;if(a!==void 0&&a.version===n&&a.sub===t)return;let o=t.depsTail=e.subsTail={version:n,dep:e,sub:t,prevDep:r,nextDep:i,prevSub:a,nextSub:void 0};i!==void 0&&(i.prevDep=o),r===void 0?t.deps=o:r.nextDep=o,a===void 0?e.subs=o:a.nextSub=o}function i(e,t=e.sub){let r=e.dep,i=e.prevDep,a=e.nextDep,o=e.nextSub,s=e.prevSub;return a===void 0?t.depsTail=i:a.prevDep=i,i===void 0?t.deps=a:i.nextDep=a,o===void 0?r.subsTail=s:o.prevSub=s,s===void 0?(r.subs=o)===void 0&&n(r):s.nextSub=o,a}function a(e){let n=e.nextSub,r;top:do{let i=e.sub,a=i.flags;if(a&60?a&12?a&4?!(a&48)&&c(e,i)?(i.flags=a|40,a&=1):a=0:i.flags=a&-9|32:a=0:i.flags=a|32,a&2&&t(i),a&1){let t=i.subs;if(t!==void 0){let i=(e=t).nextSub;i!==void 0&&(r={value:n,prev:r},n=i);continue}}if((e=n)!==void 0){n=e.nextSub;continue}for(;r!==void 0;)if(e=r.value,r=r.prev,e!==void 0){n=e.nextSub;continue top}break}while(!0)}function o(t,n){let r,i=0,a=!1;top:do{let o=t.dep,c=o.flags;if(n.flags&16)a=!0;else if((c&17)==17){if(e(o)){let e=o.subs;e.nextSub!==void 0&&s(e),a=!0}}else if((c&33)==33){(t.nextSub!==void 0||t.prevSub!==void 0)&&(r={value:t,prev:r}),t=o.deps,n=o,++i;continue}if(!a){let e=t.nextDep;if(e!==void 0){t=e;continue}}for(;i--;){let i=n.subs,o=i.nextSub!==void 0;if(o?(t=r.value,r=r.prev):t=i,a){if(e(n)){o&&s(i),n=t.sub;continue}a=!1}else n.flags&=-33;n=t.sub;let c=t.nextDep;if(c!==void 0){t=c;continue top}}return a}while(!0)}function s(e){do{let n=e.sub,r=n.flags;(r&48)==32&&(n.flags=r|16,(r&6)==2&&t(n))}while((e=e.nextSub)!==void 0)}function c(e,t){let n=t.depsTail;for(;n!==void 0;){if(n===e)return!0;n=n.prevDep}return!1}}function ga(e,t,n){let r=typeof e==`object`,i=r?e:void 0;return{next:(r?e.next:e)?.bind(i),error:(r?e.error:t)?.bind(i),complete:(r?e.complete:n)?.bind(i)}}var _a=[],va=0,{link:ya,unlink:ba,propagate:xa,checkDirty:Sa,shallowPropagate:Ca}=ha({update(e){return e._update()},notify(e){_a[Ta++]=e,e.flags&=~ma.Watching},unwatched(e){e.depsTail!==void 0&&(e.depsTail=void 0,e.flags=ma.Mutable|ma.Dirty,ka(e))}}),wa=0,Ta=0,Ea,Da=0;function Oa(e){try{++Da,e()}finally{--Da||Aa()}}function ka(e){let t=e.depsTail,n=t===void 0?e.deps:t.nextDep;for(;n!==void 0;)n=ba(n,e)}function Aa(){if(!(Da>0)){for(;wa{i.get(),n.current?t.next?.(i._snapshot):n.current=!0});return{unsubscribe:()=>{r.stop()}}},_update(e){let a=Ea,o=t?.compare??Object.is;if(n)Ea=i,++va,i.depsTail=void 0;else if(e===void 0)return!1;n&&(i.flags=ma.Mutable|ma.RecursedCheck);try{let t=i._snapshot,a=typeof e==`function`?e(t):e===void 0&&n?r(t):e;return t===void 0||!o(t,a)?(i._snapshot=a,!0):!1}finally{Ea=a,n&&(i.flags&=~ma.RecursedCheck),ka(i)}}};return n?(i.flags=ma.Mutable|ma.Dirty,i.get=function(){let e=i.flags;if(e&ma.Dirty||e&ma.Pending&&Sa(i.deps,i)){if(i._update()){let e=i.subs;e!==void 0&&Ca(e)}}else e&ma.Pending&&(i.flags=e&~ma.Pending);return Ea!==void 0&&ya(i,Ea,va),i._snapshot}):i.set=function(e){if(i._update(e)){let e=i.subs;e!==void 0&&(xa(e),Ca(e),Aa())}},i}function Ma(e){let t=()=>{let t=Ea;Ea=n,++va,n.depsTail=void 0,n.flags=ma.Watching|ma.RecursedCheck;try{return e()}finally{Ea=t,n.flags&=~ma.RecursedCheck,ka(n)}},n={deps:void 0,depsTail:void 0,subs:void 0,subsTail:void 0,flags:ma.Watching|ma.RecursedCheck,notify(){let e=this.flags;e&ma.Dirty||e&ma.Pending&&Sa(this.deps,this)?t():this.flags=ma.Watching},stop(){this.flags=ma.None,this.depsTail=void 0,ka(this)}};return t(),n}function Na(e){let t=be(),n=`not-found-${F(t.stores.location,e=>e.pathname)}-${F(t.stores.status,e=>e)}`;return(0,G.jsx)(da,{getResetKey:()=>n,onCatch:(t,n)=>{if(Me(t))e.onCatch?.(t,n);else throw t},errorComponent:({error:t})=>{if(Me(t))return e.fallback?.(t);throw t},children:e.children})}function Pa(){return(0,G.jsx)(`p`,{children:`Not Found`})}function Fa(e){return(0,G.jsx)(G.Fragment,{children:e.children})}function Ia(e,t,n){return t.options.notFoundComponent?(0,G.jsx)(t.options.notFoundComponent,{...n}):e.options.defaultNotFoundComponent?(0,G.jsx)(e.options.defaultNotFoundComponent,{...n}):(0,G.jsx)(Pa,{})}var La=W.memo(function({matchId:e}){let t=be(),n=t.stores.matchStores.get(e);n||de();let r=F(t.stores.loadedAt,e=>e),i=F(n,e=>e);return(0,G.jsx)(Ra,{router:t,matchId:e,resetKey:r,matchState:W.useMemo(()=>{let e=i.routeId,n=t.routesById[e].parentRoute?.id;return{routeId:e,ssr:i.ssr,_displayPending:i._displayPending,parentRouteId:n}},[i._displayPending,i.routeId,i.ssr,t.routesById])})});function Ra({router:e,matchId:t,resetKey:n,matchState:r}){let i=e.routesById[r.routeId],a=i.options.pendingComponent??e.options.defaultPendingComponent,o=a?(0,G.jsx)(a,{}):null,s=i.options.errorComponent??e.options.defaultErrorComponent,c=i.options.onCatch??e.options.defaultOnCatch,l=i.isRoot?i.options.notFoundComponent??e.options.notFoundRoute?.options.component:i.options.notFoundComponent,u=r.ssr===!1||r.ssr===`data-only`,d=(!i.isRoot||i.options.wrapInSuspense||u)&&(i.options.wrapInSuspense??a??(i.options.errorComponent?.preload||u))?W.Suspense:Fa,f=s?da:Fa,p=l?Na:Fa;return(0,G.jsxs)(i.isRoot?i.options.shellComponent??Fa:Fa,{children:[(0,G.jsx)(Ne.Provider,{value:t,children:(0,G.jsx)(d,{fallback:o,children:(0,G.jsx)(f,{getResetKey:()=>n,errorComponent:s||pa,onCatch:(e,t)=>{if(Me(e))throw e.routeId??=r.routeId,e;c?.(e,t)},children:(0,G.jsx)(p,{fallback:e=>{if(e.routeId??=r.routeId,!l||e.routeId&&e.routeId!==r.routeId||!e.routeId&&!i.isRoot)throw e;return W.createElement(l,e)},children:u||r._displayPending?(0,G.jsx)(Te,{fallback:o,children:(0,G.jsx)(Ba,{matchId:t})}):(0,G.jsx)(Ba,{matchId:t})})})})}),r.parentRouteId===`__root__`?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(za,{resetKey:n}),(e.options.scrollRestoration,null)]}):null]})}function za({resetKey:e}){let t=be(),n=W.useRef(void 0);return re(()=>{let e=t.latestLocation.href;(n.current===void 0||n.current!==e)&&(t.emit({type:`onRendered`,...Yi(t.stores.location.get(),t.stores.resolvedLocation.get())}),n.current=e)},[t.latestLocation.state.__TSR_key,e,t]),null}var Ba=W.memo(function({matchId:e}){let t=be(),n=(e,n)=>t.getMatch(e.id)?._nonReactive[n]??e._nonReactive[n],r=t.stores.matchStores.get(e);r||de();let i=F(r,e=>e),a=i.routeId,o=t.routesById[a],s=W.useMemo(()=>{let e=(t.routesById[a].options.remountDeps??t.options.defaultRemountDeps)?.({routeId:a,loaderDeps:i.loaderDeps,params:i._strictParams,search:i._strictSearch});return e?JSON.stringify(e):void 0},[a,i.loaderDeps,i._strictParams,i._strictSearch,t.options.defaultRemountDeps,t.routesById]),c=W.useMemo(()=>{let e=o.options.component??t.options.defaultComponent;return e?(0,G.jsx)(e,{},s):(0,G.jsx)(Va,{})},[s,o.options.component,t.options.defaultComponent]);if(i._displayPending)throw n(i,`displayPendingPromise`);if(i._forcePending)throw n(i,`minPendingPromise`);if(i.status===`pending`){let e=o.options.pendingMinMs??t.options.defaultPendingMinMs;if(e){let n=t.getMatch(i.id);if(n&&!n._nonReactive.minPendingPromise){let t=se();n._nonReactive.minPendingPromise=t,setTimeout(()=>{t.resolve(),n._nonReactive.minPendingPromise=void 0},e)}}throw n(i,`loadPromise`)}if(i.status===`notFound`)return Me(i.error)||de(),Ia(t,o,i.error);if(i.status===`redirected`)throw I(i.error)||de(),n(i,`loadPromise`);if(i.status===`error`)throw i.error;return c}),Va=W.memo(function(){let e=be(),t=W.useContext(Ne),n,r=!1,i;{let a=t?e.stores.matchStores.get(t):void 0;[n,r]=F(a,e=>[e?.routeId,e?.globalNotFound??!1]),i=F(e.stores.matchesId,e=>e[e.findIndex(e=>e===t)+1])}let a=n?e.routesById[n]:void 0,o=e.options.defaultPendingComponent?(0,G.jsx)(e.options.defaultPendingComponent,{}):null;if(r)return a||de(),Ia(e,a,void 0);if(!i)return null;let s=(0,G.jsx)(La,{matchId:i});return n===`__root__`?(0,G.jsx)(W.Suspense,{fallback:o,children:s}):s});function Ha(){let e=be(),t=W.useRef({router:e,mounted:!1}),[n,r]=W.useState(!1),i=F(e.stores.isLoading,e=>e),a=F(e.stores.hasPending,e=>e),o=ie(i),s=i||n||a,c=ie(s),l=i||a,u=ie(l);return e.startTransition=e=>{r(!0),W.startTransition(()=>{e(),r(!1)})},W.useEffect(()=>{let t=e.history.subscribe(e.load),n=e.buildLocation({to:e.latestLocation.pathname,search:!0,params:!0,hash:!0,state:!0,_includeValidateSearch:!0});return pe(e.latestLocation.publicHref)!==pe(n.publicHref)&&e.commitLocation({...n,replace:!0}),()=>{t()}},[e,e.history]),re(()=>{typeof window<`u`&&e.ssr||t.current.router===e&&t.current.mounted||(t.current={router:e,mounted:!0},(async()=>{try{await e.load()}catch(e){console.error(e)}})())},[e]),re(()=>{o&&!i&&e.emit({type:`onLoad`,...Yi(e.stores.location.get(),e.stores.resolvedLocation.get())})},[o,e,i]),re(()=>{u&&!l&&e.emit({type:`onBeforeRouteMount`,...Yi(e.stores.location.get(),e.stores.resolvedLocation.get())})},[l,u,e]),re(()=>{if(c&&!s){let t=Yi(e.stores.location.get(),e.stores.resolvedLocation.get());e.emit({type:`onResolved`,...t}),Oa(()=>{e.stores.status.set(`idle`),e.stores.resolvedLocation.set(e.stores.location.get())}),t.hrefChanged&&ua(e)}},[s,c,e]),null}function Ua(){let e=be(),t=e.routesById.__root__.options.pendingComponent??e.options.defaultPendingComponent,n=t?(0,G.jsx)(t,{}):null,r=(0,G.jsxs)(typeof document<`u`&&e.ssr?Fa:W.Suspense,{fallback:n,children:[(0,G.jsx)(Ha,{}),(0,G.jsx)(Wa,{})]});return e.options.InnerWrap?(0,G.jsx)(e.options.InnerWrap,{children:r}):r}function Wa(){let e=be(),t=F(e.stores.firstId,e=>e),n=F(e.stores.loadedAt,e=>e),r=t?(0,G.jsx)(La,{matchId:t}):null;return(0,G.jsx)(Ne.Provider,{value:t,children:e.options.disableGlobalCatchBoundary?r:(0,G.jsx)(da,{getResetKey:()=>n,errorComponent:pa,onCatch:void 0,children:r})})}var Ga=e=>({createMutableStore:ja,createReadonlyStore:ja,batch:Oa}),Ka=e=>new qa(e),qa=class extends Xi{constructor(e){super(e,Ga)}};function Ja({router:e,children:t,...n}){ce(n)&&e.update({...e.options,...n,context:{...e.options.context,...n.context}});let r=(0,G.jsx)(me.Provider,{value:e,children:t});return e.options.Wrap?(0,G.jsx)(e.options.Wrap,{children:r}):r}function Ya({router:e,...t}){return(0,G.jsx)(Ja,{router:e,...t,children:(0,G.jsx)(Ua,{})})}function Xa(e){let t=be(),n=(0,W.useRef)(void 0);return F(t.stores.location,r=>{let i=e?.select?e.select(r):r;if(e?.structuralSharing??t.options.defaultStructuralSharing){let e=fe(n.current,i);return n.current=e,e}return i})}function Za(e){let{attrs:t,children:n,nonce:r}=e;switch(e.tag){case`title`:return(0,G.jsx)(`title`,{...t,suppressHydrationWarning:!0,children:n});case`meta`:return(0,G.jsx)(`meta`,{...t,suppressHydrationWarning:!0});case`link`:return(0,G.jsx)(`link`,{...t,precedence:t?.precedence??(t?.rel===`stylesheet`?`default`:void 0),nonce:r,suppressHydrationWarning:!0});case`style`:return e.inlineCss,(0,G.jsx)(`style`,{...t,dangerouslySetInnerHTML:{__html:n},nonce:r});case`script`:return(0,G.jsx)(Qa,{attrs:t,children:n});default:return null}}function Qa({attrs:e,children:t}){be();let n=Ee(),r=typeof e?.type==`string`&&e.type!==``&&e.type!==`text/javascript`&&e.type!==`module`;if(W.useEffect(()=>{if(!r){if(e?.src){let t=(()=>{try{let t=document.baseURI||window.location.href;return new URL(e.src,t).href}catch{return e.src}})();if(Array.from(document.querySelectorAll(`script[src]`)).find(e=>e.src===t))return;let n=document.createElement(`script`);for(let[t,r]of Object.entries(e))t!==`suppressHydrationWarning`&&r!==void 0&&r!==!1&&n.setAttribute(t,typeof r==`boolean`?``:String(r));return document.head.appendChild(n),()=>{n.parentNode&&n.parentNode.removeChild(n)}}if(typeof t==`string`){let n=typeof e?.type==`string`?e.type:`text/javascript`,r=typeof e?.nonce==`string`?e.nonce:void 0;if(Array.from(document.querySelectorAll(`script:not([src])`)).find(e=>{if(!(e instanceof HTMLScriptElement))return!1;let i=e.getAttribute(`type`)??`text/javascript`,a=e.getAttribute(`nonce`)??void 0;return e.textContent===t&&i===n&&a===r}))return;let i=document.createElement(`script`);if(i.textContent=t,e)for(let[t,n]of Object.entries(e))t!==`suppressHydrationWarning`&&n!==void 0&&n!==!1&&i.setAttribute(t,typeof n==`boolean`?``:String(n));return document.head.appendChild(i),()=>{i.parentNode&&i.parentNode.removeChild(i)}}}},[e,t,r]),r&&typeof t==`string`)return(0,G.jsx)(`script`,{...e,suppressHydrationWarning:!0,dangerouslySetInnerHTML:{__html:t}});if(!n){if(e?.src)return(0,G.jsx)(`script`,{...e,suppressHydrationWarning:!0});if(typeof t==`string`)return(0,G.jsx)(`script`,{...e,dangerouslySetInnerHTML:{__html:t},suppressHydrationWarning:!0})}return null}var $a=e=>{let t=be(),n=t.options.ssr?.nonce,r=F(t.stores.matches,e=>e.map(e=>e.meta).filter(Boolean),A),i=W.useMemo(()=>{let e=[],t={},i;for(let a=r.length-1;a>=0;a--){let o=r[a];for(let r=o.length-1;r>=0;r--){let a=o[r];if(a)if(a.title)i||={tag:`title`,children:a.title};else if(`script:ld+json`in a)try{let t=JSON.stringify(a[`script:ld+json`]);e.push({tag:`script`,attrs:{type:`application/ld+json`},children:oe(t)})}catch{}else{let r=a.name??a.property;if(r){if(t[r])continue;t[r]=!0}e.push({tag:`meta`,attrs:{...a,nonce:n}})}}}return i&&e.push(i),n&&e.push({tag:`meta`,attrs:{property:`csp-nonce`,content:n}}),e.reverse(),e},[r,n]),a=F(t.stores.matches,r=>{let i=r.map(e=>e.links).filter(Boolean).flat(1).map(e=>({tag:`link`,attrs:{...e,nonce:n}})),a=t.ssr?.manifest,o=r.map(e=>a?.routes[e.routeId]?.assets??[]).filter(Boolean).flat(1).flatMap(t=>t.tag===`link`?la(a,t)?[]:[{tag:`link`,attrs:{...t.attrs,crossOrigin:oa(e,`stylesheet`)??t.attrs?.crossOrigin,suppressHydrationWarning:!0,nonce:n}}]:t.tag===`style`?[{tag:`style`,attrs:{...t.attrs,nonce:n},children:t.children,...t.inlineCss?{inlineCss:!0}:{}}]:[]);return[...i,...o]},A),o=F(t.stores.matches,r=>{let i=[];return r.map(e=>t.looseRoutesById[e.routeId]).forEach(r=>t.ssr?.manifest?.routes[r.id]?.preloads?.filter(Boolean).forEach(t=>{let r=sa(t);i.push({tag:`link`,attrs:{rel:`modulepreload`,href:r.href,crossOrigin:oa(e,`modulepreload`)??r.crossOrigin,nonce:n}})})),i},A),s=F(t.stores.matches,e=>e.map(e=>e.styles).flat(1).filter(Boolean).map(({children:e,...t})=>({tag:`style`,attrs:{...t,nonce:n},children:e})),A),c=F(t.stores.matches,e=>e.map(e=>e.headScripts).flat(1).filter(Boolean).map(({children:e,...t})=>({tag:`script`,attrs:{...t,nonce:n},children:e})),A);return eo([...i,...o,...a,...s,...c],e=>JSON.stringify(e))};function eo(e,t){let n=new Set;return e.filter(e=>{let r=t(e);return n.has(r)?!1:(n.add(r),!0)})}function to(e){let t=$a(e.assetCrossOrigin),n=be().options.ssr?.nonce;return(0,G.jsx)(G.Fragment,{children:t.map(e=>(0,W.createElement)(Za,{...e,key:`tsr-meta-${JSON.stringify(e)}`,nonce:n}))})}var no=t((e=>{function t(e,t){var n=e.length;e.push(t);a:for(;0>>1,a=e[r];if(0>>1;ri(c,n))li(u,c)?(e[r]=u,e[l]=n,r=l):(e[r]=c,e[s]=n,r=s);else if(li(u,n))e[r]=u,e[l]=n,r=l;else break a}}return t}function i(e,t){var n=e.sortIndex-t.sortIndex;return n===0?e.id-t.id:n}if(e.unstable_now=void 0,typeof performance==`object`&&typeof performance.now==`function`){var a=performance;e.unstable_now=function(){return a.now()}}else{var o=Date,s=o.now();e.unstable_now=function(){return o.now()-s}}var c=[],l=[],u=1,d=null,f=3,p=!1,m=!1,h=!1,g=!1,_=typeof setTimeout==`function`?setTimeout:null,v=typeof clearTimeout==`function`?clearTimeout:null,y=typeof setImmediate<`u`?setImmediate:null;function b(e){for(var i=n(l);i!==null;){if(i.callback===null)r(l);else if(i.startTime<=e)r(l),i.sortIndex=i.expirationTime,t(c,i);else break;i=n(l)}}function x(e){if(h=!1,b(e),!m)if(n(c)!==null)m=!0,S||(S=!0,O());else{var t=n(l);t!==null&&A(x,t.startTime-e)}}var S=!1,C=-1,w=5,T=-1;function E(){return g?!0:!(e.unstable_now()-Tt&&E());){var o=d.callback;if(typeof o==`function`){d.callback=null,f=d.priorityLevel;var s=o(d.expirationTime<=t);if(t=e.unstable_now(),typeof s==`function`){d.callback=s,b(t),i=!0;break b}d===n(c)&&r(c),b(t)}else r(c);d=n(c)}if(d!==null)i=!0;else{var u=n(l);u!==null&&A(x,u.startTime-t),i=!1}}break a}finally{d=null,f=a,p=!1}i=void 0}}finally{i?O():S=!1}}}var O;if(typeof y==`function`)O=function(){y(D)};else if(typeof MessageChannel<`u`){var k=new MessageChannel,ee=k.port2;k.port1.onmessage=D,O=function(){ee.postMessage(null)}}else O=function(){_(D,0)};function A(t,n){C=_(function(){t(e.unstable_now())},n)}e.unstable_IdlePriority=5,e.unstable_ImmediatePriority=1,e.unstable_LowPriority=4,e.unstable_NormalPriority=3,e.unstable_Profiling=null,e.unstable_UserBlockingPriority=2,e.unstable_cancelCallback=function(e){e.callback=null},e.unstable_forceFrameRate=function(e){0>e||125o?(r.sortIndex=a,t(l,r),n(c)===null&&r===n(l)&&(h?(v(C),C=-1):h=!0,A(x,a-o))):(r.sortIndex=s,t(c,r),m||p||(m=!0,S||(S=!0,O()))),r},e.unstable_shouldYield=E,e.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}})),ro=t(((e,t)=>{t.exports=no()})),io=t((e=>{var t=ro(),n=r(),i=ze();function a(e){var t=`https://react.dev/errors/`+e;if(1ie||(e.current=re[ie],re[ie]=null,ie--)}function P(e,t){ie++,re[ie]=e.current,e.current=t}var se=ae(null),ce=ae(null),le=ae(null),ue=ae(null);function de(e,t){switch(P(le,t),P(ce,e),P(se,null),t.nodeType){case 9:case 11:e=(e=t.documentElement)&&(e=e.namespaceURI)?Vd(e):0;break;default:if(e=t.tagName,t=t.namespaceURI)t=Vd(t),e=Hd(t,e);else switch(e){case`svg`:e=1;break;case`math`:e=2;break;default:e=0}}oe(se),P(se,e)}function fe(){oe(se),oe(ce),oe(le)}function pe(e){e.memoizedState!==null&&P(ue,e);var t=se.current,n=Hd(t,e.type);t!==n&&(P(ce,e),P(se,n))}function me(e){ce.current===e&&(oe(se),oe(ce)),ue.current===e&&(oe(ue),Qf._currentValue=ne)}var he,ge;function _e(e){if(he===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);he=t&&t[1]||``,ge=-1)`:-1`)&&(u=u.replace(``,e.displayName)),u}while(1<=r&&0<=i);break}}}finally{ve=!1,Error.prepareStackTrace=n}return(n=e?e.displayName||e.name:``)?_e(n):``}function be(e,t){switch(e.tag){case 26:case 27:case 5:return _e(e.type);case 16:return _e(`Lazy`);case 13:return e.child!==t&&t!==null?_e(`Suspense Fallback`):_e(`Suspense`);case 19:return _e(`SuspenseList`);case 0:case 15:return ye(e.type,!1);case 11:return ye(e.type.render,!1);case 1:return ye(e.type,!0);case 31:return _e(`Activity`);default:return``}}function xe(e){try{var t=``,n=null;do t+=be(e,n),n=e,e=e.return;while(e);return t}catch(e){return` Error generating stack: `+e.message+` `+e.stack}}var Se=Object.prototype.hasOwnProperty,Ce=t.unstable_scheduleCallback,we=t.unstable_cancelCallback,Te=t.unstable_shouldYield,Ee=t.unstable_requestPaint,F=t.unstable_now,De=t.unstable_getCurrentPriorityLevel,Oe=t.unstable_ImmediatePriority,ke=t.unstable_UserBlockingPriority,Ae=t.unstable_NormalPriority,je=t.unstable_LowPriority,Me=t.unstable_IdlePriority,Ne=t.log,Pe=t.unstable_setDisableYieldValue,Fe=null,I=null;function Ie(e){if(typeof Ne==`function`&&Pe(e),I&&typeof I.setStrictMode==`function`)try{I.setStrictMode(Fe,e)}catch{}}var L=Math.clz32?Math.clz32:Re,Le=Math.log,R=Math.LN2;function Re(e){return e>>>=0,e===0?32:31-(Le(e)/R|0)|0}var z=256,Be=262144,Ve=4194304;function He(e){var t=e&42;if(t!==0)return t;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Ue(e,t,n){var r=e.pendingLanes;if(r===0)return 0;var i=0,a=e.suspendedLanes,o=e.pingedLanes;e=e.warmLanes;var s=r&134217727;return s===0?(s=r&~a,s===0?o===0?n||(n=r&~e,n!==0&&(i=He(n))):i=He(o):i=He(s)):(r=s&~a,r===0?(o&=s,o===0?n||(n=s&~e,n!==0&&(i=He(n))):i=He(o)):i=He(r)),i===0?0:t!==0&&t!==i&&(t&a)===0&&(a=i&-i,n=t&-t,a>=n||a===32&&n&4194048)?t:i}function We(e,t){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&t)===0}function Ge(e,t){switch(e){case 1:case 2:case 4:case 8:case 64:return t+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Ke(){var e=Ve;return Ve<<=1,!(Ve&62914560)&&(Ve=4194304),e}function qe(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function B(e,t){e.pendingLanes|=t,t!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function Je(e,t,n,r,i,a){var o=e.pendingLanes;e.pendingLanes=n,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=n,e.entangledLanes&=n,e.errorRecoveryDisabledLanes&=n,e.shellSuspendCounter=0;var s=e.entanglements,c=e.expirationTimes,l=e.hiddenUpdates;for(n=o&~n;0`u`||window.document===void 0||window.document.createElement===void 0),an=!1;if(rn)try{var on={};Object.defineProperty(on,`passive`,{get:function(){an=!0}}),window.addEventListener(`test`,on,on),window.removeEventListener(`test`,on,on)}catch{an=!1}var sn=null,cn=null,ln=null;function un(){if(ln)return ln;var e,t=cn,n=t.length,r,i=`value`in sn?sn.value:sn.textContent,a=i.length;for(e=0;e=Hn),Gn=` `,Kn=!1;function qn(e,t){switch(e){case`keyup`:return Bn.indexOf(t.keyCode)!==-1;case`keydown`:return t.keyCode!==229;case`keypress`:case`mousedown`:case`focusout`:return!0;default:return!1}}function Jn(e){return e=e.detail,typeof e==`object`&&`data`in e?e.data:null}var Yn=!1;function Xn(e,t){switch(e){case`compositionend`:return Jn(t);case`keypress`:return t.which===32?(Kn=!0,Gn):null;case`textInput`:return e=t.data,e===Gn&&Kn?null:e;default:return null}}function Zn(e,t){if(Yn)return e===`compositionend`||!Vn&&qn(e,t)?(e=un(),ln=cn=sn=null,Yn=!1,e):null;switch(e){case`paste`:return null;case`keypress`:if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=t)return{node:n,offset:t-e};e=r}a:{for(;n;){if(n.nextSibling){n=n.nextSibling;break a}n=n.parentNode}n=void 0}n=yr(n)}}function xr(e,t){return e&&t?e===t?!0:e&&e.nodeType===3?!1:t&&t.nodeType===3?xr(e,t.parentNode):`contains`in e?e.contains(t):e.compareDocumentPosition?!!(e.compareDocumentPosition(t)&16):!1:!1}function Sr(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var t=Mt(e.document);t instanceof e.HTMLIFrameElement;){try{var n=typeof t.contentWindow.location.href==`string`}catch{n=!1}if(n)e=t.contentWindow;else break;t=Mt(e.document)}return t}function Cr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&(t===`input`&&(e.type===`text`||e.type===`search`||e.type===`tel`||e.type===`url`||e.type===`password`)||t===`textarea`||e.contentEditable===`true`)}var wr=rn&&`documentMode`in document&&11>=document.documentMode,Tr=null,Er=null,Dr=null,Or=!1;function kr(e,t,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;Or||Tr==null||Tr!==Mt(r)||(r=Tr,`selectionStart`in r&&Cr(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Dr&&vr(Dr,r)||(Dr=r,r=Td(Er,`onSelect`),0>=o,i-=o,xi=1<<32-L(t)+i|n<h?(g=d,d=null):g=d.sibling;var _=p(i,d,s[h],c);if(_===null){d===null&&(d=g);break}e&&d&&_.alternate===null&&t(i,d),a=o(_,a,h),u===null?l=_:u.sibling=_,u=_,d=g}if(h===s.length)return n(i,d),U&&Ci(i,h),l;if(d===null){for(;hg?(_=h,h=null):_=h.sibling;var y=p(i,h,v.value,l);if(y===null){h===null&&(h=_);break}e&&h&&y.alternate===null&&t(i,h),s=o(y,s,g),d===null?u=y:d.sibling=y,d=y,h=_}if(v.done)return n(i,h),U&&Ci(i,g),u;if(h===null){for(;!v.done;g++,v=c.next())v=f(i,v.value,l),v!==null&&(s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return U&&Ci(i,g),u}for(h=r(h);!v.done;g++,v=c.next())v=m(h,i,g,v.value,l),v!==null&&(e&&v.alternate!==null&&h.delete(v.key===null?g:v.key),s=o(v,s,g),d===null?u=v:d.sibling=v,d=v);return e&&h.forEach(function(e){return t(i,e)}),U&&Ci(i,g),u}function b(e,r,o,c){if(typeof o==`object`&&o&&o.type===_&&o.key===null&&(o=o.props.children),typeof o==`object`&&o){switch(o.$$typeof){case h:a:{for(var l=o.key;r!==null;){if(r.key===l){if(l=o.type,l===_){if(r.tag===7){n(e,r.sibling),c=i(r,o.props.children),c.return=e,e=c;break a}}else if(r.elementType===l||typeof l==`object`&&l&&l.$$typeof===E&&xa(l)===r.type){n(e,r.sibling),c=i(r,o.props),Oa(c,o),c.return=e,e=c;break a}n(e,r);break}else t(e,r);r=r.sibling}o.type===_?(c=ci(o.props.children,e.mode,c,o.key),c.return=e,e=c):(c=si(o.type,o.key,o.props,null,e.mode,c),Oa(c,o),c.return=e,e=c)}return s(e);case g:a:{for(l=o.key;r!==null;){if(r.key===l)if(r.tag===4&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),c=i(r,o.children||[]),c.return=e,e=c;break a}else{n(e,r);break}else t(e,r);r=r.sibling}c=di(o,e.mode,c),c.return=e,e=c}return s(e);case E:return o=xa(o),b(e,r,o,c)}if(te(o))return v(e,r,o,c);if(ee(o)){if(l=ee(o),typeof l!=`function`)throw Error(a(150));return o=l.call(o),y(e,r,o,c)}if(typeof o.then==`function`)return b(e,r,Da(o),c);if(o.$$typeof===x)return b(e,r,Zi(e,o),c);ka(e,o)}return typeof o==`string`&&o!==``||typeof o==`number`||typeof o==`bigint`?(o=``+o,r!==null&&r.tag===6?(n(e,r.sibling),c=i(r,o),c.return=e,e=c):(n(e,r),c=li(o,e.mode,c),c.return=e,e=c),s(e)):n(e,r)}return function(e,t,n,r){try{Ea=0;var i=b(e,t,n,r);return Ta=null,i}catch(t){if(t===ha||t===_a)throw t;var a=ri(29,t,null,e.mode);return a.lanes=r,a.return=e,a}}}var ja=Aa(!0),Ma=Aa(!1),Na=!1;function Pa(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Fa(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function Ia(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function La(e,t,n){var r=e.updateQueue;if(r===null)return null;if(r=r.shared,J&2){var i=r.pending;return i===null?t.next=t:(t.next=i.next,i.next=t),r.pending=t,t=ei(e),$r(e,null,n),t}return Xr(e,r,t,n),ei(e)}function Ra(e,t,n){if(t=t.updateQueue,t!==null&&(t=t.shared,n&4194048)){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Xe(e,n)}}function za(e,t){var n=e.updateQueue,r=e.alternate;if(r!==null&&(r=r.updateQueue,n===r)){var i=null,a=null;if(n=n.firstBaseUpdate,n!==null){do{var o={lane:n.lane,tag:n.tag,payload:n.payload,callback:null,next:null};a===null?i=a=o:a=a.next=o,n=n.next}while(n!==null);a===null?i=a=t:a=a.next=t}else i=a=t;n={baseState:r.baseState,firstBaseUpdate:i,lastBaseUpdate:a,shared:r.shared,callbacks:r.callbacks},e.updateQueue=n;return}e=n.lastBaseUpdate,e===null?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}var Ba=!1;function Va(){if(Ba){var e=ca;if(e!==null)throw e}}function Ha(e,t,n,r){Ba=!1;var i=e.updateQueue;Na=!1;var a=i.firstBaseUpdate,o=i.lastBaseUpdate,s=i.shared.pending;if(s!==null){i.shared.pending=null;var c=s,l=c.next;c.next=null,o===null?a=l:o.next=l,o=c;var u=e.alternate;u!==null&&(u=u.updateQueue,s=u.lastBaseUpdate,s!==o&&(s===null?u.firstBaseUpdate=l:s.next=l,u.lastBaseUpdate=c))}if(a!==null){var d=i.baseState;o=0,u=l=c=null,s=a;do{var f=s.lane&-536870913,m=f!==s.lane;if(m?(X&f)===f:(r&f)===f){f!==0&&f===sa&&(Ba=!0),u!==null&&(u=u.next={lane:0,tag:s.tag,payload:s.payload,callback:null,next:null});a:{var h=e,g=s;f=t;var _=n;switch(g.tag){case 1:if(h=g.payload,typeof h==`function`){d=h.call(_,d,f);break a}d=h;break a;case 3:h.flags=h.flags&-65537|128;case 0:if(h=g.payload,f=typeof h==`function`?h.call(_,d,f):h,f==null)break a;d=p({},d,f);break a;case 2:Na=!0}}f=s.callback,f!==null&&(e.flags|=64,m&&(e.flags|=8192),m=i.callbacks,m===null?i.callbacks=[f]:m.push(f))}else m={lane:f,tag:s.tag,payload:s.payload,callback:s.callback,next:null},u===null?(l=u=m,c=d):u=u.next=m,o|=f;if(s=s.next,s===null){if(s=i.shared.pending,s===null)break;m=s,s=m.next,m.next=null,i.lastBaseUpdate=m,i.shared.pending=null}}while(1);u===null&&(c=d),i.baseState=c,i.firstBaseUpdate=l,i.lastBaseUpdate=u,a===null&&(i.shared.lanes=0),Gl|=o,e.lanes=o,e.memoizedState=d}}function Ua(e,t){if(typeof e!=`function`)throw Error(a(191,e));e.call(t)}function Wa(e,t){var n=e.callbacks;if(n!==null)for(e.callbacks=null,e=0;ea?a:8;var o=M.T,s={};M.T=s,As(e,!1,t,n);try{var c=i(),l=M.S;l!==null&&l(s,c),typeof c==`object`&&c&&typeof c.then==`function`?ks(e,t,W(c,r),pu(e)):ks(e,t,r,pu(e))}catch(n){ks(e,t,{then:function(){},status:`rejected`,reason:n},pu())}finally{N.p=a,o!==null&&s.types!==null&&(o.types=s.types),M.T=o}}function ys(){}function bs(e,t,n,r){if(e.tag!==5)throw Error(a(476));var i=xs(e).queue;vs(e,i,t,ne,n===null?ys:function(){return Ss(e),n(r)})}function xs(e){var t=e.memoizedState;if(t!==null)return t;t={memoizedState:ne,baseState:ne,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:jo,lastRenderedState:ne},next:null};var n={};return t.next={memoizedState:n,baseState:n,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:jo,lastRenderedState:n},next:null},e.memoizedState=t,e=e.alternate,e!==null&&(e.memoizedState=t),t}function Ss(e){var t=xs(e);t.next===null&&(t=e.alternate.memoizedState),ks(e,t.next.queue,{},pu())}function Cs(){return Xi(Qf)}function ws(){return Eo().memoizedState}function Ts(){return Eo().memoizedState}function Es(e){for(var t=e.return;t!==null;){switch(t.tag){case 24:case 3:var n=pu();e=Ia(n);var r=La(t,e,n);r!==null&&(hu(r,t,n),Ra(r,t,n)),t={cache:ra()},e.payload=t;return}t=t.return}}function Ds(e,t,n){var r=pu();n={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null},js(e)?Ms(t,n):(n=Zr(e,t,n,r),n!==null&&(hu(n,e,r),Ns(n,t,r)))}function Os(e,t,n){ks(e,t,n,pu())}function ks(e,t,n,r){var i={lane:r,revertLane:0,gesture:null,action:n,hasEagerState:!1,eagerState:null,next:null};if(js(e))Ms(t,i);else{var a=e.alternate;if(e.lanes===0&&(a===null||a.lanes===0)&&(a=t.lastRenderedReducer,a!==null))try{var o=t.lastRenderedState,s=a(o,n);if(i.hasEagerState=!0,i.eagerState=s,_r(s,o))return Xr(e,t,i,0),Ll===null&&Yr(),!1}catch{}if(n=Zr(e,t,i,r),n!==null)return hu(n,e,r),Ns(n,t,r),!0}return!1}function As(e,t,n,r){if(r={lane:2,revertLane:dd(),gesture:null,action:r,hasEagerState:!1,eagerState:null,next:null},js(e)){if(t)throw Error(a(479))}else t=Zr(e,n,r,2),t!==null&&hu(t,e,2)}function js(e){var t=e.alternate;return e===q||t!==null&&t===q}function Ms(e,t){lo=co=!0;var n=e.pending;n===null?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Ns(e,t,n){if(n&4194048){var r=t.lanes;r&=e.pendingLanes,n|=r,t.lanes=n,Xe(e,n)}}var Ps={readContext:Xi,use:ko,useCallback:go,useContext:go,useEffect:go,useImperativeHandle:go,useLayoutEffect:go,useInsertionEffect:go,useMemo:go,useReducer:go,useRef:go,useState:go,useDebugValue:go,useDeferredValue:go,useTransition:go,useSyncExternalStore:go,useId:go,useHostTransitionStatus:go,useFormState:go,useActionState:go,useOptimistic:go,useMemoCache:go,useCacheRefresh:go};Ps.useEffectEvent=go;var Fs={readContext:Xi,use:ko,useCallback:function(e,t){return To().memoizedState=[e,t===void 0?null:t],e},useContext:Xi,useEffect:as,useImperativeHandle:function(e,t,n){n=n==null?null:n.concat([e]),rs(4194308,4,ds.bind(null,t,e),n)},useLayoutEffect:function(e,t){return rs(4194308,4,e,t)},useInsertionEffect:function(e,t){rs(4,2,e,t)},useMemo:function(e,t){var n=To();t=t===void 0?null:t;var r=e();if(uo){Ie(!0);try{e()}finally{Ie(!1)}}return n.memoizedState=[r,t],r},useReducer:function(e,t,n){var r=To();if(n!==void 0){var i=n(t);if(uo){Ie(!0);try{n(t)}finally{Ie(!1)}}}else i=t;return r.memoizedState=r.baseState=i,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:i},r.queue=e,e=e.dispatch=Ds.bind(null,q,e),[r.memoizedState,e]},useRef:function(e){var t=To();return e={current:e},t.memoizedState=e},useState:function(e){e=Vo(e);var t=e.queue,n=Os.bind(null,q,t);return t.dispatch=n,[e.memoizedState,n]},useDebugValue:ps,useDeferredValue:function(e,t){return gs(To(),e,t)},useTransition:function(){var e=Vo(!1);return e=vs.bind(null,q,e.queue,!0,!1),To().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,t,n){var r=q,i=To();if(U){if(n===void 0)throw Error(a(407));n=n()}else{if(n=t(),Ll===null)throw Error(a(349));X&127||Io(r,t,n)}i.memoizedState=n;var o={value:n,getSnapshot:t};return i.queue=o,as(Ro.bind(null,r,o,e),[e]),r.flags|=2048,ts(9,{destroy:void 0},Lo.bind(null,r,o,n,t),null),n},useId:function(){var e=To(),t=Ll.identifierPrefix;if(U){var n=Si,r=xi;n=(r&~(1<<32-L(r)-1)).toString(32)+n,t=`_`+t+`R_`+n,n=fo++,0<\/script>`,o=o.removeChild(o.firstChild);break;case`select`:o=typeof r.is==`string`?s.createElement(`select`,{is:r.is}):s.createElement(`select`),r.multiple?o.multiple=!0:r.size&&(o.size=r.size);break;default:o=typeof r.is==`string`?s.createElement(i,{is:r.is}):s.createElement(i)}}o[rt]=t,o[it]=r;a:for(s=t.child;s!==null;){if(s.tag===5||s.tag===6)o.appendChild(s.stateNode);else if(s.tag!==4&&s.tag!==27&&s.child!==null){s.child.return=s,s=s.child;continue}if(s===t)break a;for(;s.sibling===null;){if(s.return===null||s.return===t)break a;s=s.return}s.sibling.return=s.return,s=s.sibling}t.stateNode=o;a:switch(Pd(o,i,r),i){case`button`:case`input`:case`select`:case`textarea`:r=!!r.autoFocus;break a;case`img`:r=!0;break a;default:r=!1}r&&kc(t)}}return Pc(t),Ac(t,t.type,e===null?null:e.memoizedProps,t.pendingProps,n),null;case 6:if(e&&t.stateNode!=null)e.memoizedProps!==r&&kc(t);else{if(typeof r!=`string`&&t.stateNode===null)throw Error(a(166));if(e=le.current,Ii(t)){if(e=t.stateNode,n=t.memoizedProps,r=null,i=Oi,i!==null)switch(i.tag){case 27:case 5:r=i.memoizedProps}e[rt]=t,e=!!(e.nodeValue===n||r!==null&&!0===r.suppressHydrationWarning||jd(e.nodeValue,n)),e||Ni(t,!0)}else e=Bd(e).createTextNode(r),e[rt]=t,t.stateNode=e}return Pc(t),null;case 31:if(n=t.memoizedState,e===null||e.memoizedState!==null){if(r=Ii(t),n!==null){if(e===null){if(!r)throw Error(a(318));if(e=t.memoizedState,e=e===null?null:e.dehydrated,!e)throw Error(a(557));e[rt]=t}else Li(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Pc(t),e=!1}else n=Ri(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=n),e=!0;if(!e)return t.flags&256?(no(t),t):(no(t),null);if(t.flags&128)throw Error(a(558))}return Pc(t),null;case 13:if(r=t.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(i=Ii(t),r!==null&&r.dehydrated!==null){if(e===null){if(!i)throw Error(a(318));if(i=t.memoizedState,i=i===null?null:i.dehydrated,!i)throw Error(a(317));i[rt]=t}else Li(),!(t.flags&128)&&(t.memoizedState=null),t.flags|=4;Pc(t),i=!1}else i=Ri(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=i),i=!0;if(!i)return t.flags&256?(no(t),t):(no(t),null)}return no(t),t.flags&128?(t.lanes=n,t):(n=r!==null,e=e!==null&&e.memoizedState!==null,n&&(r=t.child,i=null,r.alternate!==null&&r.alternate.memoizedState!==null&&r.alternate.memoizedState.cachePool!==null&&(i=r.alternate.memoizedState.cachePool.pool),o=null,r.memoizedState!==null&&r.memoizedState.cachePool!==null&&(o=r.memoizedState.cachePool.pool),o!==i&&(r.flags|=2048)),n!==e&&n&&(t.child.flags|=8192),Mc(t,t.updateQueue),Pc(t),null);case 4:return fe(),e===null&&Sd(t.stateNode.containerInfo),Pc(t),null;case 10:return Wi(t.type),Pc(t),null;case 19:if(oe(io),r=t.memoizedState,r===null)return Pc(t),null;if(i=(t.flags&128)!=0,o=r.rendering,o===null)if(i)Nc(r,!1);else{if(Wl!==0||e!==null&&e.flags&128)for(e=t.child;e!==null;){if(o=ao(e),o!==null){for(t.flags|=128,Nc(r,!1),e=o.updateQueue,t.updateQueue=e,Mc(t,e),t.subtreeFlags=0,e=n,n=t.child;n!==null;)oi(n,e),n=n.sibling;return P(io,io.current&1|2),U&&Ci(t,r.treeForkCount),t.child}e=e.sibling}r.tail!==null&&F()>tu&&(t.flags|=128,i=!0,Nc(r,!1),t.lanes=4194304)}else{if(!i)if(e=ao(o),e!==null){if(t.flags|=128,i=!0,e=e.updateQueue,t.updateQueue=e,Mc(t,e),Nc(r,!0),r.tail===null&&r.tailMode===`hidden`&&!o.alternate&&!U)return Pc(t),null}else 2*F()-r.renderingStartTime>tu&&n!==536870912&&(t.flags|=128,i=!0,Nc(r,!1),t.lanes=4194304);r.isBackwards?(o.sibling=t.child,t.child=o):(e=r.last,e===null?t.child=o:e.sibling=o,r.last=o)}return r.tail===null?(Pc(t),null):(e=r.tail,r.rendering=e,r.tail=e.sibling,r.renderingStartTime=F(),e.sibling=null,n=io.current,P(io,i?n&1|2:n&1),U&&Ci(t,r.treeForkCount),e);case 22:case 23:return no(t),Ya(),r=t.memoizedState!==null,e===null?r&&(t.flags|=8192):e.memoizedState!==null!==r&&(t.flags|=8192),r?n&536870912&&!(t.flags&128)&&(Pc(t),t.subtreeFlags&6&&(t.flags|=8192)):Pc(t),n=t.updateQueue,n!==null&&Mc(t,n.retryQueue),n=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),r=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(r=t.memoizedState.cachePool.pool),r!==n&&(t.flags|=2048),e!==null&&oe(da),null;case 24:return n=null,e!==null&&(n=e.memoizedState.cache),t.memoizedState.cache!==n&&(t.flags|=2048),Wi(na),Pc(t),null;case 25:return null;case 30:return null}throw Error(a(156,t.tag))}function Ic(e,t){switch(Ei(t),t.tag){case 1:return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 3:return Wi(na),fe(),e=t.flags,e&65536&&!(e&128)?(t.flags=e&-65537|128,t):null;case 26:case 27:case 5:return me(t),null;case 31:if(t.memoizedState!==null){if(no(t),t.alternate===null)throw Error(a(340));Li()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 13:if(no(t),e=t.memoizedState,e!==null&&e.dehydrated!==null){if(t.alternate===null)throw Error(a(340));Li()}return e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 19:return oe(io),null;case 4:return fe(),null;case 10:return Wi(t.type),null;case 22:case 23:return no(t),Ya(),e!==null&&oe(da),e=t.flags,e&65536?(t.flags=e&-65537|128,t):null;case 24:return Wi(na),null;case 25:return null;default:return null}}function Lc(e,t){switch(Ei(t),t.tag){case 3:Wi(na),fe();break;case 26:case 27:case 5:me(t);break;case 4:fe();break;case 31:t.memoizedState!==null&&no(t);break;case 13:no(t);break;case 19:oe(io);break;case 10:Wi(t.type);break;case 22:case 23:no(t),Ya(),e!==null&&oe(da);break;case 24:Wi(na)}}function Rc(e,t){try{var n=t.updateQueue,r=n===null?null:n.lastEffect;if(r!==null){var i=r.next;n=i;do{if((n.tag&e)===e){r=void 0;var a=n.create,o=n.inst;r=a(),o.destroy=r}n=n.next}while(n!==i)}}catch(e){Z(t,t.return,e)}}function zc(e,t,n){try{var r=t.updateQueue,i=r===null?null:r.lastEffect;if(i!==null){var a=i.next;r=a;do{if((r.tag&e)===e){var o=r.inst,s=o.destroy;if(s!==void 0){o.destroy=void 0,i=t;var c=n,l=s;try{l()}catch(e){Z(i,c,e)}}}r=r.next}while(r!==a)}}catch(e){Z(t,t.return,e)}}function Bc(e){var t=e.updateQueue;if(t!==null){var n=e.stateNode;try{Wa(t,n)}catch(t){Z(e,e.return,t)}}}function Vc(e,t,n){n.props=Hs(e.type,e.memoizedProps),n.state=e.memoizedState;try{n.componentWillUnmount()}catch(n){Z(e,t,n)}}function Hc(e,t){try{var n=e.ref;if(n!==null){switch(e.tag){case 26:case 27:case 5:var r=e.stateNode;break;case 30:r=e.stateNode;break;default:r=e.stateNode}typeof n==`function`?e.refCleanup=n(r):n.current=r}}catch(n){Z(e,t,n)}}function Uc(e,t){var n=e.ref,r=e.refCleanup;if(n!==null)if(typeof r==`function`)try{r()}catch(n){Z(e,t,n)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof n==`function`)try{n(null)}catch(n){Z(e,t,n)}else n.current=null}function Wc(e){var t=e.type,n=e.memoizedProps,r=e.stateNode;try{a:switch(t){case`button`:case`input`:case`select`:case`textarea`:n.autoFocus&&r.focus();break a;case`img`:n.src?r.src=n.src:n.srcSet&&(r.srcset=n.srcSet)}}catch(t){Z(e,e.return,t)}}function Gc(e,t,n){try{var r=e.stateNode;Fd(r,e.type,n,t),r[it]=t}catch(t){Z(e,e.return,t)}}function Kc(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&Zd(e.type)||e.tag===4}function qc(e){a:for(;;){for(;e.sibling===null;){if(e.return===null||Kc(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&Zd(e.type)||e.flags&2||e.child===null||e.tag===4)continue a;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Jc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?(n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n).insertBefore(e,t):(t=n.nodeType===9?n.body:n.nodeName===`HTML`?n.ownerDocument.body:n,t.appendChild(e),n=n._reactRootContainer,n!=null||t.onclick!==null||(t.onclick=Jt));else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode,t=null),e=e.child,e!==null))for(Jc(e,t,n),e=e.sibling;e!==null;)Jc(e,t,n),e=e.sibling}function Yc(e,t,n){var r=e.tag;if(r===5||r===6)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(r!==4&&(r===27&&Zd(e.type)&&(n=e.stateNode),e=e.child,e!==null))for(Yc(e,t,n),e=e.sibling;e!==null;)Yc(e,t,n),e=e.sibling}function Xc(e){var t=e.stateNode,n=e.memoizedProps;try{for(var r=e.type,i=t.attributes;i.length;)t.removeAttributeNode(i[0]);Pd(t,r,n),t[rt]=e,t[it]=n}catch(t){Z(e,e.return,t)}}var Zc=!1,Qc=!1,$c=!1,el=typeof WeakSet==`function`?WeakSet:Set,tl=null;function nl(e,t){if(e=e.containerInfo,Rd=sp,e=Sr(e),Cr(e)){if(`selectionStart`in e)var n={start:e.selectionStart,end:e.selectionEnd};else a:{n=(n=e.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var i=r.anchorOffset,o=r.focusNode;r=r.focusOffset;try{n.nodeType,o.nodeType}catch{n=null;break a}var s=0,c=-1,l=-1,u=0,d=0,f=e,p=null;b:for(;;){for(var m;f!==n||i!==0&&f.nodeType!==3||(c=s+i),f!==o||r!==0&&f.nodeType!==3||(l=s+r),f.nodeType===3&&(s+=f.nodeValue.length),(m=f.firstChild)!==null;)p=f,f=m;for(;;){if(f===e)break b;if(p===n&&++u===i&&(c=s),p===o&&++d===r&&(l=s),(m=f.nextSibling)!==null)break;f=p,p=f.parentNode}f=m}n=c===-1||l===-1?null:{start:c,end:l}}else n=null}n||={start:0,end:0}}else n=null;for(zd={focusedElem:e,selectionRange:n},sp=!1,tl=t;tl!==null;)if(t=tl,e=t.child,t.subtreeFlags&1028&&e!==null)e.return=t,tl=e;else for(;tl!==null;){switch(t=tl,o=t.alternate,e=t.flags,t.tag){case 0:if(e&4&&(e=t.updateQueue,e=e===null?null:e.events,e!==null))for(n=0;n title`))),Pd(o,r,n),o[rt]=e,gt(o),r=o;break a;case`link`:var s=Vf(`link`,`href`,i).get(r+(n.href||``));if(s){for(var c=0;cg&&(o=g,g=h,h=o);var _=br(s,h),v=br(s,g);if(_&&v&&(p.rangeCount!==1||p.anchorNode!==_.node||p.anchorOffset!==_.offset||p.focusNode!==v.node||p.focusOffset!==v.offset)){var y=d.createRange();y.setStart(_.node,_.offset),p.removeAllRanges(),h>g?(p.addRange(y),p.extend(v.node,v.offset)):(y.setEnd(v.node,v.offset),p.addRange(y))}}}}for(d=[],p=s;p=p.parentNode;)p.nodeType===1&&d.push({element:p,left:p.scrollLeft,top:p.scrollTop});for(typeof s.focus==`function`&&s.focus(),s=0;sn?32:n,M.T=null,n=lu,lu=null;var o=au,s=su;if(iu=0,ou=au=null,su=0,J&6)throw Error(a(331));var c=J;if(J|=4,Ml(o.current),wl(o,o.current,s,n),J=c,id(0,!1),I&&typeof I.onPostCommitFiberRoot==`function`)try{I.onPostCommitFiberRoot(Fe,o)}catch{}return!0}finally{N.p=i,M.T=r,Vu(e,t)}}function Wu(e,t,n){t=pi(n,t),t=Js(e.stateNode,t,2),e=La(e,t,2),e!==null&&(B(e,2),rd(e))}function Z(e,t,n){if(e.tag===3)Wu(e,e,n);else for(;t!==null;){if(t.tag===3){Wu(t,e,n);break}else if(t.tag===1){var r=t.stateNode;if(typeof t.type.getDerivedStateFromError==`function`||typeof r.componentDidCatch==`function`&&(ru===null||!ru.has(r))){e=pi(n,e),n=Ys(2),r=La(t,n,2),r!==null&&(Xs(n,r,t,e),B(r,2),rd(r));break}}t=t.return}}function Gu(e,t,n){var r=e.pingCache;if(r===null){r=e.pingCache=new Il;var i=new Set;r.set(t,i)}else i=r.get(t),i===void 0&&(i=new Set,r.set(t,i));i.has(n)||(Hl=!0,i.add(n),e=Ku.bind(null,e,t,n),t.then(e,e))}function Ku(e,t,n){var r=e.pingCache;r!==null&&r.delete(t),e.pingedLanes|=e.suspendedLanes&n,e.warmLanes&=~n,Ll===e&&(X&n)===n&&(Wl===4||Wl===3&&(X&62914560)===X&&300>F()-$l?!(J&2)&&Su(e,0):ql|=n,Yl===X&&(Yl=0)),rd(e)}function qu(e,t){t===0&&(t=Ke()),e=Qr(e,t),e!==null&&(B(e,t),rd(e))}function Ju(e){var t=e.memoizedState,n=0;t!==null&&(n=t.retryLane),qu(e,n)}function Yu(e,t){var n=0;switch(e.tag){case 31:case 13:var r=e.stateNode,i=e.memoizedState;i!==null&&(n=i.retryLane);break;case 19:r=e.stateNode;break;case 22:r=e.stateNode._retryCache;break;default:throw Error(a(314))}r!==null&&r.delete(t),qu(e,n)}function Xu(e,t){return Ce(e,t)}var Zu=null,Qu=null,$u=!1,ed=!1,td=!1,nd=0;function rd(e){e!==Qu&&e.next===null&&(Qu===null?Zu=Qu=e:Qu=Qu.next=e),ed=!0,$u||($u=!0,ud())}function id(e,t){if(!td&&ed){td=!0;do for(var n=!1,r=Zu;r!==null;){if(!t)if(e!==0){var i=r.pendingLanes;if(i===0)var a=0;else{var o=r.suspendedLanes,s=r.pingedLanes;a=(1<<31-L(42|e)+1)-1,a&=i&~(o&~s),a=a&201326741?a&201326741|1:a?a|2:0}a!==0&&(n=!0,ld(r,a))}else a=X,a=Ue(r,r===Ll?a:0,r.cancelPendingCommit!==null||r.timeoutHandle!==-1),!(a&3)||We(r,a)||(n=!0,ld(r,a));r=r.next}while(n);td=!1}}function ad(){od()}function od(){ed=$u=!1;var e=0;nd!==0&&Gd()&&(e=nd);for(var t=F(),n=null,r=Zu;r!==null;){var i=r.next,a=sd(r,t);a===0?(r.next=null,n===null?Zu=i:n.next=i,i===null&&(Qu=n)):(n=r,(e!==0||a&3)&&(ed=!0)),r=i}iu!==0&&iu!==5||id(e,!1),nd!==0&&(nd=0)}function sd(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,i=e.expirationTimes,a=e.pendingLanes&-62914561;0s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Pt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),gt(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Pt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Pt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Pt(n.imageSizes)+`"]`)):i+=`[href="`+Pt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=p({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),gt(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Pt(r)+`"][href="`+Pt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=p({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),gt(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=ht(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=p({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);gt(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=ht(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=p({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),gt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=ht(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=p({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),gt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var i=(i=le.current)?gf(i):null;if(!i)throw Error(a(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=ht(i).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=ht(i).hoistableStyles,s=o.get(e);if(s||(i=i.ownerDocument||i,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=i.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),o||Nf(i,e,n,s.state))),t&&r===null)throw Error(a(528,``));return s}if(t&&r!==null)throw Error(a(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=ht(i).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(a(444,e))}}function Af(e){return`href="`+Pt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return p({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),gt(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Pt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Pt(n.href)+`"]`);if(r)return t.instance=r,gt(r),r;var i=p({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),gt(r),Pd(r,`style`,i),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:i=Af(n.href);var o=e.querySelector(jf(i));if(o)return t.state.loading|=4,t.instance=o,gt(o),o;r=Mf(n),(i=mf.get(i))&&Rf(r,i),o=(e.ownerDocument||e).createElement(`link`),gt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Pd(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(i=e.querySelector(Ff(o)))?(t.instance=i,gt(i),i):(r=n,(i=mf.get(o))&&(r=p({},n),zf(r,i)),e=e.ownerDocument||e,i=e.createElement(`script`),gt(i),Pd(i,`link`,r),e.head.appendChild(i),t.instance=i);case`void`:return null;default:throw Error(a(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,gt(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),gt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=io()}))(),1),K=i(),q=(0,W.createContext)(void 0);function oo(e,t){try{let t=localStorage.getItem(e);if(t===`light`||t===`dark`||t===`system`)return t}catch{}return t}function so(e){let t=(0,K.c)(14),{children:n,defaultTheme:r,storageKey:i}=e,a=r===void 0?`dark`:r,o=i===void 0?`ui-theme`:i,s;t[0]!==a||t[1]!==o?(s=()=>oo(o,a),t[0]=a,t[1]=o,t[2]=s):s=t[2];let[c,l]=(0,W.useState)(s),u,d;t[3]===c?(u=t[4],d=t[5]):(u=()=>{let e=window.document.documentElement;if(e.classList.remove(`light`,`dark`),c===`system`){let t=window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`;e.classList.add(t);return}e.classList.add(c)},d=[c],t[3]=c,t[4]=u,t[5]=d),(0,W.useEffect)(u,d);let f;t[6]===o?f=t[7]:(f=e=>{try{localStorage.setItem(o,e)}catch{}l(e)},t[6]=o,t[7]=f);let p;t[8]!==f||t[9]!==c?(p={theme:c,setTheme:f},t[8]=f,t[9]=c,t[10]=p):p=t[10];let m=p,h;return t[11]!==n||t[12]!==m?(h=(0,G.jsx)(q.Provider,{value:m,children:n}),t[11]=n,t[12]=m,t[13]=h):h=t[13],h}function co(){let e=(0,W.useContext)(q);if(e===void 0)throw Error(`useTheme must be used within a ThemeProvider`);return e}function lo(e){return Ge(e.defaultTagName??`div`,e,e)}var uo=et(`activity`,[[`path`,{d:`M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2`,key:`169zse`}]]),fo=et(`book-open`,[[`path`,{d:`M12 7v14`,key:`1akyts`}],[`path`,{d:`M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z`,key:`ruj8y`}]]),po=et(`camera`,[[`path`,{d:`M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z`,key:`18u6gg`}],[`circle`,{cx:`12`,cy:`13`,r:`3`,key:`1vg3eu`}]]),mo=et(`circle-alert`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`12`,x2:`12`,y1:`8`,y2:`12`,key:`1pkeuh`}],[`line`,{x1:`12`,x2:`12.01`,y1:`16`,y2:`16`,key:`4dfq90`}]]),ho=et(`crosshair`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`22`,x2:`18`,y1:`12`,y2:`12`,key:`l9bcsi`}],[`line`,{x1:`6`,x2:`2`,y1:`12`,y2:`12`,key:`13hhkx`}],[`line`,{x1:`12`,x2:`12`,y1:`6`,y2:`2`,key:`10w3f3`}],[`line`,{x1:`12`,x2:`12`,y1:`22`,y2:`18`,key:`15g9kq`}]]),go=et(`hard-drive`,[[`path`,{d:`M10 16h.01`,key:`1bzywj`}],[`path`,{d:`M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`18tbho`}],[`path`,{d:`M21.946 12.013H2.054`,key:`zqlbp7`}],[`path`,{d:`M6 16h.01`,key:`1pmjb7`}]]),_o=et(`house`,[[`path`,{d:`M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8`,key:`5wwlr5`}],[`path`,{d:`M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z`,key:`r6nss1`}]]),vo=et(`image`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,ry:`2`,key:`1m3agn`}],[`circle`,{cx:`9`,cy:`9`,r:`2`,key:`af1f0g`}],[`path`,{d:`m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21`,key:`1xmnt7`}]]),yo=et(`key`,[[`path`,{d:`m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4`,key:`g0fldk`}],[`path`,{d:`m21 2-9.6 9.6`,key:`1j0ho8`}],[`circle`,{cx:`7.5`,cy:`15.5`,r:`5.5`,key:`yqb3hr`}]]),bo=et(`layers`,[[`path`,{d:`M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z`,key:`zw3jo`}],[`path`,{d:`M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12`,key:`1wduqc`}],[`path`,{d:`M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17`,key:`kqbvx6`}]]),xo=et(`layout-grid`,[[`rect`,{width:`7`,height:`7`,x:`3`,y:`3`,rx:`1`,key:`1g98yp`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`3`,rx:`1`,key:`6d4xhi`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`14`,rx:`1`,key:`nxv5o0`}],[`rect`,{width:`7`,height:`7`,x:`3`,y:`14`,rx:`1`,key:`1bb6yr`}]]),So=et(`log-out`,[[`path`,{d:`m16 17 5-5-5-5`,key:`1bji2h`}],[`path`,{d:`M21 12H9`,key:`dn1m92`}],[`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`,key:`1uf3rs`}]]),Co=et(`moon`,[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]),wo=et(`network`,[[`rect`,{x:`16`,y:`16`,width:`6`,height:`6`,rx:`1`,key:`4q2zg0`}],[`rect`,{x:`2`,y:`16`,width:`6`,height:`6`,rx:`1`,key:`8cvhb9`}],[`rect`,{x:`9`,y:`2`,width:`6`,height:`6`,rx:`1`,key:`1egb70`}],[`path`,{d:`M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3`,key:`1jsf9p`}],[`path`,{d:`M12 12V8`,key:`2874zd`}]]),To=et(`panel-left`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M9 3v18`,key:`fh3hqa`}]]),Eo=et(`server`,[[`rect`,{width:`20`,height:`8`,x:`2`,y:`2`,rx:`2`,ry:`2`,key:`ngkwjq`}],[`rect`,{width:`20`,height:`8`,x:`2`,y:`14`,rx:`2`,ry:`2`,key:`iecqi9`}],[`line`,{x1:`6`,x2:`6.01`,y1:`6`,y2:`6`,key:`16zg32`}],[`line`,{x1:`6`,x2:`6.01`,y1:`18`,y2:`18`,key:`nzw8ys`}]]),Do=et(`shield-check`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]]),Oo=et(`shield`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}]]),ko=et(`sun`,[[`circle`,{cx:`12`,cy:`12`,r:`4`,key:`4exip2`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`m4.93 4.93 1.41 1.41`,key:`149t6j`}],[`path`,{d:`m17.66 17.66 1.41 1.41`,key:`ptbguv`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`m6.34 17.66-1.41 1.41`,key:`1m8zz5`}],[`path`,{d:`m19.07 4.93-1.41 1.41`,key:`1shlcs`}]]),Ao=et(`users`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`path`,{d:`M16 3.128a4 4 0 0 1 0 7.744`,key:`16gr8j`}],[`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`,key:`kshegd`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}]]),jo=et(`waypoints`,[[`path`,{d:`m10.586 5.414-5.172 5.172`,key:`4mc350`}],[`path`,{d:`m18.586 13.414-5.172 5.172`,key:`8c96vv`}],[`path`,{d:`M6 12h12`,key:`8npq4p`}],[`circle`,{cx:`12`,cy:`20`,r:`2`,key:`144qzu`}],[`circle`,{cx:`12`,cy:`4`,r:`2`,key:`muu5ef`}],[`circle`,{cx:`20`,cy:`12`,r:`2`,key:`1xzzfp`}],[`circle`,{cx:`4`,cy:`12`,r:`2`,key:`1hvhnz`}]]),Mo=et(`x`,[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]),No=W.forwardRef(function(e,t){let{render:n,className:r,id:i,name:a,value:o,disabled:s=!1,onValueChange:c,defaultValue:l,autoFocus:u=!1,style:d,...f}=e,{state:p,name:m,disabled:h,setTouched:g,setDirty:_,validityData:v,setFocused:y,setFilled:b,validationMode:x,validation:S}=Tt(),C=h||s,w=m??a,T={...p,disabled:C},{labelId:E}=St(),D=Ct({id:i});ht(()=>{let e=o!=null;S.inputRef.current?.value||e&&o!==``?b(!0):e&&o===``&&b(!1)},[S.inputRef,b,o]);let O=W.useRef(null);ht(()=>{u&&O.current===Mt(Vt(O.current))&&y(!0)},[u,y]);let[k]=Et({controlled:o,default:l,name:`FieldControl`,state:`value`}),ee=o!==void 0,A=ee?k:void 0,j=st(()=>S.inputRef.current?.value);return wt(S.inputRef,{id:D,value:A,getValue:j}),Ge(`input`,e,{ref:[t,O],state:T,props:[{id:D,disabled:C,name:w,ref:S.inputRef,"aria-labelledby":E,autoFocus:u,...ee?{value:A}:{defaultValue:l},onChange(e){let t=e.currentTarget.value;c?.(t,Lt(Rt,e.nativeEvent)),_(t!==v.initialValue),b(t!==``)},onFocus(){y(!0)},onBlur(e){g(!0),y(!1),x===`onBlur`&&S.commit(e.currentTarget.value)},onKeyDown(e){e.currentTarget.tagName===`INPUT`&&e.key===`Enter`&&(g(!0),S.commit(e.currentTarget.value))}},S.getInputValidationProps(),f],stateAttributesMapping:Dt})}),Po=W.forwardRef(function(e,t){return(0,G.jsx)(No,{ref:t,...e})});function Fo(e){let t=(0,K.c)(10),n,r,i;t[0]===e?(n=t[1],r=t[2],i=t[3]):({className:n,type:i,...r}=e,t[0]=e,t[1]=n,t[2]=r,t[3]=i);let a;t[4]===n?a=t[5]:(a=B(`h-7 w-full min-w-0 rounded-md border border-input bg-input/20 px-2 py-0.5 text-sm transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-xs/relaxed file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/30 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 md:text-xs/relaxed dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40`,n),t[4]=n,t[5]=a);let o;return t[6]!==r||t[7]!==a||t[8]!==i?(o=(0,G.jsx)(Po,{className:a,"data-slot":`input`,type:i,...r}),t[6]=r,t[7]=a,t[8]=i,t[9]=o):o=t[9],o}var Io=W.createContext(void 0);function Lo(e){let t=W.useContext(Io);if(e===!1&&t===void 0)throw Error(We(27));return t}var Ro={...en,...Jn},zo=W.forwardRef(function(e,t){let{render:n,className:r,style:i,forceRender:a=!1,...o}=e,{store:s}=Lo(),c=s.useState(`open`),l=s.useState(`nested`),u=s.useState(`mounted`);return Ge(`div`,e,{state:{open:c,transitionStatus:s.useState(`transitionStatus`)},ref:[s.context.backdropRef,t],stateAttributesMapping:Ro,props:[{role:`presentation`,hidden:!u,style:{userSelect:`none`,WebkitUserSelect:`none`}},o],enabled:a||!l})}),Bo=W.forwardRef(function(e,t){let{render:n,className:r,disabled:i=!1,nativeButton:a=!0,style:o,...s}=e,{store:c}=Lo(),l=c.useState(`open`);function u(e){l&&c.setOpen(!1,Lt(Ft,e.nativeEvent))}let{getButtonProps:d,buttonRef:f}=_t({disabled:i,native:a});return Ge(`button`,e,{state:{disabled:i},ref:[t,f],props:[{onClick:u},s,d]})}),Vo=W.forwardRef(function(e,t){let{render:n,className:r,style:i,id:a,...o}=e,{store:s}=Lo(),c=At(a);return s.useSyncedValueWithCleanup(`descriptionElementId`,c),Ge(`p`,e,{ref:t,props:[{id:c},o]})});function Ho(e,t){return t!=null&&!Ht(t)?0:typeof e==`function`?e():e}function Uo(e,t,n){let r=Ho(e,n);return typeof r==`number`?r:r?.[t]}function Wo(e){return typeof e==`function`?e():e}function Go(e,t){return t||e===`click`||e===`mousedown`}var Ko=W.createContext({hasProvider:!1,timeoutMs:0,delayRef:{current:0},initialDelayRef:{current:0},timeout:new bn,currentIdRef:{current:null},currentContextRef:{current:null}});function qo(e){let{children:t,delay:n,timeoutMs:r=0}=e,i=W.useRef(n),a=W.useRef(n),o=W.useRef(null),s=W.useRef(null),c=fn();return(0,G.jsx)(Ko.Provider,{value:W.useMemo(()=>({hasProvider:!0,delayRef:i,initialDelayRef:a,currentIdRef:o,timeoutMs:r,currentContextRef:s,timeout:c}),[r,c]),children:t})}function Jo(e,t={open:!1}){let n=`rootStore`in e?e.rootStore:e,r=n.useState(`floatingId`),{open:i}=t,{currentIdRef:a,delayRef:o,timeoutMs:s,initialDelayRef:c,currentContextRef:l,hasProvider:u,timeout:d}=W.useContext(Ko),[f,p]=W.useState(!1);return ht(()=>{function e(){p(!1),l.current?.setIsInstantPhase(!1),a.current=null,l.current=null,o.current=c.current}if(a.current&&!i&&a.current===r){if(p(!1),s){let t=r;return d.start(s,()=>{n.select(`open`)||a.current&&a.current!==t||e()}),()=>{d.clear()}}e()}},[i,r,a,o,s,c,l,d,n]),ht(()=>{if(!i)return;let e=l.current,t=a.current;d.clear(),l.current={onOpenChange:n.setOpen,setIsInstantPhase:p},a.current=r,o.current={open:0,close:Uo(c.current,`close`)},t!==null&&t!==r?(p(!0),e?.setIsInstantPhase(!0),e?.onOpenChange(!1,Lt(Rt))):(p(!1),e?.setIsInstantPhase(!1))},[i,r,n,a,o,s,c,l,d]),ht(()=>()=>{l.current=null},[l]),W.useMemo(()=>({hasProvider:u,delayRef:o,isInstantPhase:f}),[u,o,f])}function Yo(e,t){let n=null,r=null,i=!1;return{contextElement:e||void 0,getBoundingClientRect(){let a=e?.getBoundingClientRect()||{width:0,height:0,x:0,y:0},o=t.axis===`x`||t.axis===`both`,s=t.axis===`y`||t.axis===`both`,c=[`mouseenter`,`mousemove`].includes(t.dataRef.current.openEvent?.type||``)&&t.pointerType!==`touch`,l=a.width,u=a.height,d=a.x,f=a.y;return n==null&&t.x&&o&&(n=a.x-t.x),r==null&&t.y&&s&&(r=a.y-t.y),d-=n||0,f-=r||0,l=0,u=0,!i||c?(l=t.axis===`y`?a.width:0,u=t.axis===`x`?a.height:0,d=o&&t.x!=null?t.x:d,f=s&&t.y!=null?t.y:f):i&&!c&&(u=t.axis===`x`?a.height:u,l=t.axis===`y`?a.width:l),i=!0,{width:l,height:u,x:d,y:f,top:f,right:d+l,bottom:f+u,left:d}}}}function Xo(e){return e!=null&&e.clientX!=null}function Zo(e,t={}){let n=`rootStore`in e?e.rootStore:e,r=n.useState(`open`),i=n.useState(`floatingElement`),a=n.useState(`domReferenceElement`),o=n.context.dataRef,{enabled:s=!0,axis:c=`both`}=t,l=W.useRef(!1),u=W.useRef(null),[d,f]=W.useState(),[p,m]=W.useState([]),h=st((e,t,r)=>{l.current||o.current.openEvent&&!Xo(o.current.openEvent)||n.set(`positionReference`,Yo(r??a,{x:e,y:t,axis:c,dataRef:o,pointerType:d}))}),g=st(e=>{r?u.current||m([]):h(e.clientX,e.clientY,e.currentTarget)}),_=Ht(d)?i:r,v=W.useCallback(()=>{if(!_||!s)return;let e=at(i);function t(e){kt(i,zt(e))?(u.current?.(),u.current=null):h(e.clientX,e.clientY)}if(!o.current.openEvent||Xo(o.current.openEvent))return u.current=Xn(e,`mousemove`,t),()=>{u.current?.(),u.current=null};n.set(`positionReference`,a)},[_,s,i,o,a,n,h]);W.useEffect(()=>v(),[v,p]),W.useEffect(()=>{s&&!i&&(l.current=!1)},[s,i]),W.useEffect(()=>{!s&&r&&(l.current=!0)},[s,r]);let y=W.useMemo(()=>{function e(e){f(e.pointerType)}return{onPointerDown:e,onPointerEnter:e,onMouseMove:g,onMouseEnter:g}},[g]);return W.useMemo(()=>s?{reference:y,trigger:y}:{},[s,y])}function Qo(e,t,n){let{reference:r,floating:i}=e,a=Gt(t),o=Mn(t),s=En(o),c=mn(t),l=a===`y`,u=r.x+r.width/2-i.width/2,d=r.y+r.height/2-i.height/2,f=r[s]/2-i[s]/2,p;switch(c){case`top`:p={x:u,y:r.y-i.height};break;case`bottom`:p={x:u,y:r.y+r.height};break;case`right`:p={x:r.x+r.width,y:d};break;case`left`:p={x:r.x-i.width,y:d};break;default:p={x:r.x,y:r.y}}switch(Fn(t)){case`start`:p[o]-=f*(n&&l?-1:1);break;case`end`:p[o]+=f*(n&&l?-1:1);break}return p}async function $o(e,t){t===void 0&&(t={});let{x:n,y:r,platform:i,rects:a,elements:o,strategy:s}=e,{boundary:c=`clippingAncestors`,rootBoundary:l=`viewport`,elementContext:u=`floating`,altBoundary:d=!1,padding:f=0}=wn(t,e),p=Un(f),m=o[d?u===`floating`?`reference`:`floating`:u],h=qt(await i.getClippingRect({element:await(i.isElement==null?void 0:i.isElement(m))??!0?m:m.contextElement||await(i.getDocumentElement==null?void 0:i.getDocumentElement(o.floating)),boundary:c,rootBoundary:l,strategy:s})),g=u===`floating`?{x:n,y:r,width:a.floating.width,height:a.floating.height}:a.reference,_=await(i.getOffsetParent==null?void 0:i.getOffsetParent(o.floating)),v=await(i.isElement==null?void 0:i.isElement(_))&&await(i.getScale==null?void 0:i.getScale(_))||{x:1,y:1},y=qt(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:o,rect:g,offsetParent:_,strategy:s}):g);return{top:(h.top-y.top+p.top)/v.y,bottom:(y.bottom-h.bottom+p.bottom)/v.y,left:(h.left-y.left+p.left)/v.x,right:(y.right-h.right+p.right)/v.x}}var es=50,ts=async(e,t,n)=>{let{placement:r=`bottom`,strategy:i=`absolute`,middleware:a=[],platform:o}=n,s=o.detectOverflow?o:{...o,detectOverflow:$o},c=await(o.isRTL==null?void 0:o.isRTL(t)),l=await o.getElementRects({reference:e,floating:t,strategy:i}),{x:u,y:d}=Qo(l,r,c),f=r,p=0,m={};for(let n=0;ne<=0)){let e=(i.flip?.index||0)+1,t=S[e];if(t&&(!(u===`alignment`&&_!==Gt(t))||T.every(e=>Gt(e.placement)===_?e.overflows[0]>0:!0)))return{data:{index:e,overflows:T},reset:{placement:t}};let n=T.filter(e=>e.overflows[0]<=0).sort((e,t)=>e.overflows[1]-t.overflows[1])[0]?.placement;if(!n)switch(f){case`bestFit`:{let e=T.filter(e=>{if(x){let t=Gt(e.placement);return t===_||t===`y`}return!0}).map(e=>[e.placement,e.overflows.filter(e=>e>0).reduce((e,t)=>e+t,0)]).sort((e,t)=>e[1]-t[1])[0]?.[0];e&&(n=e);break}case`initialPlacement`:n=o;break}if(r!==n)return{reset:{placement:n}}}return{}}}};function rs(e,t){return{top:e.top-t.height,right:e.right-t.width,bottom:e.bottom-t.height,left:e.left-t.width}}function is(e){return ln.some(t=>e[t]>=0)}var as=function(e){return e===void 0&&(e={}),{name:`hide`,options:e,async fn(t){let{rects:n,platform:r}=t,{strategy:i=`referenceHidden`,...a}=wn(e,t);switch(i){case`referenceHidden`:{let e=rs(await r.detectOverflow(t,{...a,elementContext:`reference`}),n.reference);return{data:{referenceHiddenOffsets:e,referenceHidden:is(e)}}}case`escaped`:{let e=rs(await r.detectOverflow(t,{...a,altBoundary:!0}),n.floating);return{data:{escapedOffsets:e,escaped:is(e)}}}default:return{}}}}},os=new Set([`left`,`top`]);async function ss(e,t){let{placement:n,platform:r,elements:i}=e,a=await(r.isRTL==null?void 0:r.isRTL(i.floating)),o=mn(n),s=Fn(n),c=Gt(n)===`y`,l=os.has(o)?-1:1,u=a&&c?-1:1,d=wn(t,e),{mainAxis:f,crossAxis:p,alignmentAxis:m}=typeof d==`number`?{mainAxis:d,crossAxis:0,alignmentAxis:null}:{mainAxis:d.mainAxis||0,crossAxis:d.crossAxis||0,alignmentAxis:d.alignmentAxis};return s&&typeof m==`number`&&(p=s===`end`?m*-1:m),c?{x:p*u,y:f*l}:{x:f*l,y:p*u}}var cs=function(e){return e===void 0&&(e=0),{name:`offset`,options:e,async fn(t){var n;let{x:r,y:i,placement:a,middlewareData:o}=t,s=await ss(t,e);return a===o.offset?.placement&&(n=o.arrow)!=null&&n.alignmentOffset?{}:{x:r+s.x,y:i+s.y,data:{...s,placement:a}}}}},ls=function(e){return e===void 0&&(e={}),{name:`shift`,options:e,async fn(t){let{x:n,y:r,placement:i,platform:a}=t,{mainAxis:o=!0,crossAxis:s=!1,limiter:c={fn:e=>{let{x:t,y:n}=e;return{x:t,y:n}}},...l}=wn(e,t),u={x:n,y:r},d=await a.detectOverflow(t,l),f=Gt(mn(i)),p=Bn(f),m=u[p],h=u[f];if(o){let e=p===`y`?`top`:`left`,t=p===`y`?`bottom`:`right`,n=m+d[e],r=m-d[t];m=jn(n,m,r)}if(s){let e=f===`y`?`top`:`left`,t=f===`y`?`bottom`:`right`,n=h+d[e],r=h-d[t];h=jn(n,h,r)}let g=c.fn({...t,[p]:m,[f]:h});return{...g,data:{x:g.x-n,y:g.y-r,enabled:{[p]:o,[f]:s}}}}}},us=function(e){return e===void 0&&(e={}),{options:e,fn(t){let{x:n,y:r,placement:i,rects:a,middlewareData:o}=t,{offset:s=0,mainAxis:c=!0,crossAxis:l=!0}=wn(e,t),u={x:n,y:r},d=Gt(i),f=Bn(d),p=u[f],m=u[d],h=wn(s,t),g=typeof h==`number`?{mainAxis:h,crossAxis:0}:{mainAxis:0,crossAxis:0,...h};if(c){let e=f===`y`?`height`:`width`,t=a.reference[f]-a.floating[e]+g.mainAxis,n=a.reference[f]+a.reference[e]-g.mainAxis;pn&&(p=n)}if(l){let e=f===`y`?`width`:`height`,t=os.has(mn(i)),n=a.reference[d]-a.floating[e]+(t&&o.offset?.[d]||0)+(t?0:g.crossAxis),r=a.reference[d]+a.reference[e]+(t?0:o.offset?.[d]||0)-(t?g.crossAxis:0);mr&&(m=r)}return{[f]:p,[d]:m}}}},ds=function(e){return e===void 0&&(e={}),{name:`size`,options:e,async fn(t){var n,r;let{placement:i,rects:a,platform:o,elements:s}=t,{apply:c=()=>{},...l}=wn(e,t),u=await o.detectOverflow(t,l),d=mn(i),f=Fn(i),p=Gt(i)===`y`,{width:m,height:h}=a.floating,g,_;d===`top`||d===`bottom`?(g=d,_=f===(await(o.isRTL==null?void 0:o.isRTL(s.floating))?`start`:`end`)?`left`:`right`):(_=d,g=f===`end`?`top`:`bottom`);let v=h-u.top-u.bottom,y=m-u.left-u.right,b=gn(h-u[g],v),x=gn(m-u[_],y),S=!t.middlewareData.shift,C=b,w=x;if((n=t.middlewareData.shift)!=null&&n.enabled.x&&(w=y),(r=t.middlewareData.shift)!=null&&r.enabled.y&&(C=v),S&&!f){let e=Hn(u.left,0),t=Hn(u.right,0),n=Hn(u.top,0),r=Hn(u.bottom,0);p?w=m-2*(e!==0||t!==0?e+t:Hn(u.left,u.right)):C=h-2*(n!==0||r!==0?n+r:Hn(u.top,u.bottom))}await c({...t,availableWidth:w,availableHeight:C});let T=await o.getDimensions(s.floating);return m!==T.width||h!==T.height?{reset:{rects:!0}}:{}}}};function fs(e){let t=ft(e),n=parseFloat(t.width)||0,r=parseFloat(t.height)||0,i=ot(e),a=i?e.offsetWidth:n,o=i?e.offsetHeight:r,s=Kt(n)!==a||Kt(r)!==o;return s&&(n=a,r=o),{width:n,height:r,$:s}}function ps(e){return V(e)?e:e.contextElement}function ms(e){let t=ps(e);if(!ot(t))return zn(1);let n=t.getBoundingClientRect(),{width:r,height:i,$:a}=fs(t),o=(a?Kt(n.width):n.width)/r,s=(a?Kt(n.height):n.height)/i;return(!o||!Number.isFinite(o))&&(o=1),(!s||!Number.isFinite(s))&&(s=1),{x:o,y:s}}var hs=zn(0);function gs(e){let t=at(e);return!nt()||!t.visualViewport?hs:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function _s(e,t,n){return t===void 0&&(t=!1),!n||t&&n!==at(e)?!1:t}function vs(e,t,n,r){t===void 0&&(t=!1),n===void 0&&(n=!1);let i=e.getBoundingClientRect(),a=ps(e),o=zn(1);t&&(r?V(r)&&(o=ms(r)):o=ms(e));let s=_s(a,n,r)?gs(a):zn(0),c=(i.left+s.x)/o.x,l=(i.top+s.y)/o.y,u=i.width/o.x,d=i.height/o.y;if(a){let e=at(a),t=r&&V(r)?at(r):r,n=e,i=lt(n);for(;i&&r&&t!==n;){let e=ms(i),t=i.getBoundingClientRect(),r=ft(i),a=t.left+(i.clientLeft+parseFloat(r.paddingLeft))*e.x,o=t.top+(i.clientTop+parseFloat(r.paddingTop))*e.y;c*=e.x,l*=e.y,u*=e.x,d*=e.y,c+=a,l+=o,n=at(i),i=lt(n)}}return qt({width:u,height:d,x:c,y:l})}function ys(e,t){let n=pt(e).scrollLeft;return t?t.left+n:vs(ct(e)).left+n}function bs(e,t){let n=e.getBoundingClientRect();return{x:n.left+t.scrollLeft-ys(e,n),y:n.top+t.scrollTop}}function xs(e){let{elements:t,rect:n,offsetParent:r,strategy:i}=e,a=i===`fixed`,o=ct(r),s=t?rt(t.floating):!1;if(r===o||s&&a)return n;let c={scrollLeft:0,scrollTop:0},l=zn(1),u=zn(0),d=ot(r);if((d||!d&&!a)&&((gt(r)!==`body`||tt(o))&&(c=pt(r)),d)){let e=vs(r);l=ms(r),u.x=e.x+r.clientLeft,u.y=e.y+r.clientTop}let f=o&&!d&&!a?bs(o,c):zn(0);return{width:n.width*l.x,height:n.height*l.y,x:n.x*l.x-c.scrollLeft*l.x+u.x+f.x,y:n.y*l.y-c.scrollTop*l.y+u.y+f.y}}function Ss(e){return Array.from(e.getClientRects())}function Cs(e){let t=ct(e),n=pt(e),r=e.ownerDocument.body,i=Hn(t.scrollWidth,t.clientWidth,r.scrollWidth,r.clientWidth),a=Hn(t.scrollHeight,t.clientHeight,r.scrollHeight,r.clientHeight),o=-n.scrollLeft+ys(e),s=-n.scrollTop;return ft(r).direction===`rtl`&&(o+=Hn(t.clientWidth,r.clientWidth)-i),{width:i,height:a,x:o,y:s}}var ws=25;function Ts(e,t){let n=at(e),r=ct(e),i=n.visualViewport,a=r.clientWidth,o=r.clientHeight,s=0,c=0;if(i){a=i.width,o=i.height;let e=nt();(!e||e&&t===`fixed`)&&(s=i.offsetLeft,c=i.offsetTop)}let l=ys(r);if(l<=0){let e=r.ownerDocument,t=e.body,n=getComputedStyle(t),i=e.compatMode===`CSS1Compat`&&parseFloat(n.marginLeft)+parseFloat(n.marginRight)||0,o=Math.abs(r.clientWidth-t.clientWidth-i);o<=ws&&(a-=o)}else l<=ws&&(a+=l);return{width:a,height:o,x:s,y:c}}function Es(e,t){let n=vs(e,!0,t===`fixed`),r=n.top+e.clientTop,i=n.left+e.clientLeft,a=ot(e)?ms(e):zn(1);return{width:e.clientWidth*a.x,height:e.clientHeight*a.y,x:i*a.x,y:r*a.y}}function Ds(e,t,n){let r;if(t===`viewport`)r=Ts(e,n);else if(t===`document`)r=Cs(ct(e));else if(V(t))r=Es(t,n);else{let n=gs(e);r={x:t.x-n.x,y:t.y-n.y,width:t.width,height:t.height}}return qt(r)}function Os(e,t){let n=ut(e);return n===t||!V(n)||xt(n)?!1:ft(n).position===`fixed`||Os(n,t)}function ks(e,t){let n=t.get(e);if(n)return n;let r=dt(e,[],!1).filter(e=>V(e)&>(e)!==`body`),i=null,a=ft(e).position===`fixed`,o=a?ut(e):e;for(;V(o)&&!xt(o);){let t=ft(o),n=bt(o);!n&&t.position===`fixed`&&(i=null),(a?!n&&!i:!n&&t.position===`static`&&i&&(i.position===`absolute`||i.position===`fixed`)||tt(o)&&!n&&Os(e,o))?r=r.filter(e=>e!==o):i=t,o=ut(o)}return t.set(e,r),r}function As(e){let{element:t,boundary:n,rootBoundary:r,strategy:i}=e,a=[...n===`clippingAncestors`?rt(t)?[]:ks(t,this._c):[].concat(n),r],o=Ds(t,a[0],i),s=o.top,c=o.right,l=o.bottom,u=o.left;for(let e=1;e{o(!1,1e-7)},1e3)}n===1&&!zs(l,e.getBoundingClientRect())&&o(),y=!1}try{n=new IntersectionObserver(b,{...v,root:i.ownerDocument})}catch{n=new IntersectionObserver(b,v)}n.observe(e)}return o(!0),a}function Vs(e,t,n,r){r===void 0&&(r={});let{ancestorScroll:i=!0,ancestorResize:a=!0,elementResize:o=typeof ResizeObserver==`function`,layoutShift:s=typeof IntersectionObserver==`function`,animationFrame:c=!1}=r,l=ps(e),u=i||a?[...l?dt(l):[],...t?dt(t):[]]:[];u.forEach(e=>{i&&e.addEventListener(`scroll`,n,{passive:!0}),a&&e.addEventListener(`resize`,n)});let d=l&&s?Bs(l,n):null,f=-1,p=null;o&&(p=new ResizeObserver(e=>{let[r]=e;r&&r.target===l&&p&&t&&(p.unobserve(t),cancelAnimationFrame(f),f=requestAnimationFrame(()=>{var e;(e=p)==null||e.observe(t)})),n()}),l&&!c&&p.observe(l),t&&p.observe(t));let m,h=c?vs(e):null;c&&g();function g(){let t=vs(e);h&&!zs(h,t)&&n(),h=t,m=requestAnimationFrame(g)}return n(),()=>{var e;u.forEach(e=>{i&&e.removeEventListener(`scroll`,n),a&&e.removeEventListener(`resize`,n)}),d?.(),(e=p)==null||e.disconnect(),p=null,c&&cancelAnimationFrame(m)}}var Hs=cs,Us=ls,Ws=ns,Gs=ds,Ks=as,qs=us,Js=(e,t,n)=>{let r=new Map,i={platform:Rs,...n},a={...i.platform,_c:r};return ts(e,t,{...i,platform:a})},Ys=e(ze(),1),Xs=typeof document<`u`?W.useLayoutEffect:function(){};function Zs(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e==`function`&&e.toString()===t.toString())return!0;let n,r,i;if(e&&t&&typeof e==`object`){if(Array.isArray(e)){if(n=e.length,n!==t.length)return!1;for(r=n;r--!==0;)if(!Zs(e[r],t[r]))return!1;return!0}if(i=Object.keys(e),n=i.length,n!==Object.keys(t).length)return!1;for(r=n;r--!==0;)if(!{}.hasOwnProperty.call(t,i[r]))return!1;for(r=n;r--!==0;){let n=i[r];if(!(n===`_owner`&&e.$$typeof)&&!Zs(e[n],t[n]))return!1}return!0}return e!==e&&t!==t}function Qs(e){return typeof window>`u`?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function $s(e,t){let n=Qs(e);return Math.round(t*n)/n}function ec(e){let t=W.useRef(e);return Xs(()=>{t.current=e}),t}function tc(e){e===void 0&&(e={});let{placement:t=`bottom`,strategy:n=`absolute`,middleware:r=[],platform:i,elements:{reference:a,floating:o}={},transform:s=!0,whileElementsMounted:c,open:l}=e,[u,d]=W.useState({x:0,y:0,strategy:n,placement:t,middlewareData:{},isPositioned:!1}),[f,p]=W.useState(r);Zs(f,r)||p(r);let[m,h]=W.useState(null),[g,_]=W.useState(null),v=W.useCallback(e=>{e!==S.current&&(S.current=e,h(e))},[]),y=W.useCallback(e=>{e!==C.current&&(C.current=e,_(e))},[]),b=a||m,x=o||g,S=W.useRef(null),C=W.useRef(null),w=W.useRef(u),T=c!=null,E=ec(c),D=ec(i),O=ec(l),k=W.useCallback(()=>{if(!S.current||!C.current)return;let e={placement:t,strategy:n,middleware:f};D.current&&(e.platform=D.current),Js(S.current,C.current,e).then(e=>{let t={...e,isPositioned:O.current!==!1};ee.current&&!Zs(w.current,t)&&(w.current=t,Ys.flushSync(()=>{d(t)}))})},[f,t,n,D,O]);Xs(()=>{l===!1&&w.current.isPositioned&&(w.current.isPositioned=!1,d(e=>({...e,isPositioned:!1})))},[l]);let ee=W.useRef(!1);Xs(()=>(ee.current=!0,()=>{ee.current=!1}),[]),Xs(()=>{if(b&&(S.current=b),x&&(C.current=x),b&&x){if(E.current)return E.current(b,x,k);k()}},[b,x,k,E,T]);let A=W.useMemo(()=>({reference:S,floating:C,setReference:v,setFloating:y}),[v,y]),j=W.useMemo(()=>({reference:b,floating:x}),[b,x]),te=W.useMemo(()=>{let e={position:n,left:0,top:0};if(!j.floating)return e;let t=$s(j.floating,u.x),r=$s(j.floating,u.y);return s?{...e,transform:`translate(`+t+`px, `+r+`px)`,...Qs(j.floating)>=1.5&&{willChange:`transform`}}:{position:n,left:t,top:r}},[n,s,j.floating,u.x,u.y]);return W.useMemo(()=>({...u,update:k,refs:A,elements:j,floatingStyles:te}),[u,k,A,j,te])}var nc=(e,t)=>{let n=Hs(e);return{name:n.name,fn:n.fn,options:[e,t]}},rc=(e,t)=>{let n=Us(e);return{name:n.name,fn:n.fn,options:[e,t]}},ic=(e,t)=>({fn:qs(e).fn,options:[e,t]}),ac=(e,t)=>{let n=Ws(e);return{name:n.name,fn:n.fn,options:[e,t]}},oc=(e,t)=>{let n=Gs(e);return{name:n.name,fn:n.fn,options:[e,t]}},sc=(e,t)=>{let n=Ks(e);return{name:n.name,fn:n.fn,options:[e,t]}};function cc(e,t){let n=W.useRef(null),r=W.useRef(null);return W.useCallback(i=>{if(e!==void 0){if(n.current!==null){let e=n.current,i=r.current,a=t.context.triggerElements.getById(e);i&&a===i&&t.context.triggerElements.delete(e),n.current=null,r.current=null}i!==null&&(n.current=e,r.current=i,t.context.triggerElements.add(e,i))}},[t,e])}function lc(e,t,n,r){let i=n.useState(`isMountedByTrigger`,e),a=cc(e,n),o=st(t=>{if(a(t),!t||!n.select(`open`))return;let i=n.select(`activeTriggerId`);if(i===e){n.update({activeTriggerElement:t,...r});return}i??n.update({activeTriggerId:e,activeTriggerElement:t,...r})});return ht(()=>{i&&n.update({activeTriggerElement:t.current,...r})},[i,n,t,...Object.values(r)]),{registerTrigger:o,isMountedByThisTrigger:i}}function uc(e){let t=e.useState(`open`);ht(()=>{if(t&&!e.select(`activeTriggerId`)&&e.context.triggerElements.size===1){let t=e.context.triggerElements.entries().next();if(!t.done){let[n,r]=t.value;e.update({activeTriggerId:n,activeTriggerElement:r})}}},[t,e])}function dc(e,t,n){let{mounted:r,setMounted:i,transitionStatus:a}=qn(e);t.useSyncedValues({mounted:r,transitionStatus:a});let o=st(()=>{i(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1}),n?.(),t.context.onOpenChangeComplete?.(!1)});return Yn({enabled:!t.useState(`preventUnmountingOnClose`),open:e,ref:t.context.popupRef,onComplete(){e||o()}}),{forceUnmount:o,transitionStatus:a}}function fc(){return new Vn({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:new Wt,floatingId:``,syncOnly:!1,nested:!1,onOpenChange:void 0})}function pc(){return{open:!1,openProp:void 0,mounted:!1,transitionStatus:void 0,floatingRootContext:fc(),preventUnmountingOnClose:!1,payload:void 0,activeTriggerId:null,activeTriggerElement:null,triggerIdProp:void 0,popupElement:null,positionerElement:null,activeTriggerProps:Ue,inactiveTriggerProps:Ue,popupProps:Ue}}var mc=H(e=>e.triggerIdProp??e.activeTriggerId),hc={open:H(e=>e.openProp??e.open),mounted:H(e=>e.mounted),transitionStatus:H(e=>e.transitionStatus),floatingRootContext:H(e=>e.floatingRootContext),preventUnmountingOnClose:H(e=>e.preventUnmountingOnClose),payload:H(e=>e.payload),activeTriggerId:mc,activeTriggerElement:H(e=>e.mounted?e.activeTriggerElement:null),isTriggerActive:H((e,t)=>t!==void 0&&mc(e)===t),isOpenedByTrigger:H((e,t)=>t!==void 0&&mc(e)===t&&e.open),isMountedByTrigger:H((e,t)=>t!==void 0&&mc(e)===t&&e.mounted),triggerProps:H((e,t)=>t?e.activeTriggerProps:e.inactiveTriggerProps),popupProps:H(e=>e.popupProps),popupElement:H(e=>e.popupElement),positionerElement:H(e=>e.positionerElement)};function gc(e){let{open:t=!1,onOpenChange:n,elements:r={}}=e,i=Bt(),a=sn()!=null,o=Ve(()=>new Vn({open:t,transitionStatus:void 0,onOpenChange:n,referenceElement:r.reference??null,floatingElement:r.floating??null,triggerElements:new Wt,floatingId:i,syncOnly:!1,nested:a})).current;return ht(()=>{let e={open:t,floatingId:i};r.reference!==void 0&&(e.referenceElement=r.reference,e.domReferenceElement=V(r.reference)?r.reference:null),r.floating!==void 0&&(e.floatingElement=r.floating),o.update(e)},[t,i,r.reference,r.floating,o]),o.context.onOpenChange=n,o.context.nested=a,o}function _c(e={}){let{nodeId:t,externalTree:n}=e,r=gc(e),i=e.rootContext||r,a={reference:i.useState(`referenceElement`),floating:i.useState(`floatingElement`),domReference:i.useState(`domReferenceElement`)},[o,s]=W.useState(null),c=W.useRef(null),l=un(n);ht(()=>{a.domReference&&(c.current=a.domReference)},[a.domReference]);let u=tc({...e,elements:{...a,...o&&{reference:o}}}),d=W.useCallback(e=>{let t=V(e)?{getBoundingClientRect:()=>e.getBoundingClientRect(),getClientRects:()=>e.getClientRects(),contextElement:e}:e;s(t),u.refs.setReference(t)},[u.refs]),[f,p]=W.useState(void 0),[m,h]=W.useState(null);i.useSyncedValue(`referenceElement`,f??null);let g=V(f)?f:null;i.useSyncedValue(`domReferenceElement`,f===void 0?a.domReference:g),i.useSyncedValue(`floatingElement`,m);let _=W.useCallback(e=>{(V(e)||e===null)&&(c.current=e,p(e)),(V(u.refs.reference.current)||u.refs.reference.current===null||e!==null&&!V(e))&&u.refs.setReference(e)},[u.refs,p]),v=W.useCallback(e=>{h(e),u.refs.setFloating(e)},[u.refs]),y=W.useMemo(()=>({...u.refs,setReference:_,setFloating:v,setPositionReference:d,domReference:c}),[u.refs,_,v,d]),b=W.useMemo(()=>({...u.elements,domReference:a.domReference}),[u.elements,a.domReference]),x=i.useState(`open`),S=i.useState(`floatingId`),C=W.useMemo(()=>({...u,dataRef:i.context.dataRef,open:x,onOpenChange:i.setOpen,events:i.context.events,floatingId:S,refs:y,elements:b,nodeId:t,rootStore:i}),[u,y,b,t,i,x,S]);return ht(()=>{i.context.dataRef.current.floatingContext=C;let e=l?.nodesRef.current.find(e=>e.id===t);e&&(e.context=C)}),W.useMemo(()=>({...u,context:C,refs:y,elements:b,rootStore:i}),[u,y,b,C,i])}function vc(e){let{popupStore:t,treatPopupAsFloatingElement:n=!1,onOpenChange:r}=e,i=Bt(),a=sn()!=null,o=t.useState(`open`),s=t.useState(`activeTriggerElement`),c=t.useState(n?`popupElement`:`positionerElement`),l=t.context.triggerElements,u=Ve(()=>new Vn({open:o,transitionStatus:void 0,referenceElement:s,floatingElement:c,triggerElements:l,onOpenChange:r,floatingId:i,syncOnly:!0,nested:a})).current;return ht(()=>{let e={open:o,floatingId:i,referenceElement:s,floatingElement:c};V(s)&&(e.domReferenceElement=s),u.state.positionReference===u.state.referenceElement&&(e.positionReference=s),u.update(e)},[o,i,s,c,u]),u.context.onOpenChange=r,u.context.nested=a,u}var yc=Zt&&nn;function bc(e,t={}){let n=`rootStore`in e?e.rootStore:e,{events:r,dataRef:i}=n.context,{enabled:a=!0,delay:o}=t,s=W.useRef(!1),c=W.useRef(null),l=fn(),u=W.useRef(!0);W.useEffect(()=>{let e=n.select(`domReferenceElement`);if(!a)return;let t=at(e);function r(){let e=n.select(`domReferenceElement`);!n.select(`open`)&&ot(e)&&e===Mt(Vt(e))&&(s.current=!0)}function i(){u.current=!0}function o(){u.current=!1}return Xt(Xn(t,`blur`,r),yc&&Xn(t,`keydown`,i,!0),yc&&Xn(t,`pointerdown`,o,!0))},[n,a]),W.useEffect(()=>{if(!a)return;function e(e){if(e.reason===`trigger-press`||e.reason===`escape-key`){let e=n.select(`domReferenceElement`);V(e)&&(c.current=e,s.current=!0)}}return r.on(`openchange`,e),()=>{r.off(`openchange`,e)}},[r,a,n]);let d=W.useMemo(()=>({onMouseLeave(){s.current=!1,c.current=null},onFocus(e){let t=e.currentTarget;if(s.current){if(c.current===t)return;s.current=!1,c.current=null}let r=zt(e.nativeEvent);if(V(r)){if(yc&&!e.relatedTarget){if(!u.current&&!Kn(r))return}else if(!Ut(r))return}let i=an(e.relatedTarget,n.context.triggerElements),{nativeEvent:a,currentTarget:d}=e,f=typeof o==`function`?o():o;if(n.select(`open`)&&i||f===0||f===void 0){n.setOpen(!0,Lt(jt,a,d));return}l.start(f,()=>{s.current||n.setOpen(!0,Lt(jt,a,d))})},onBlur(e){s.current=!1,c.current=null;let t=e.relatedTarget,r=e.nativeEvent,a=V(t)&&t.hasAttribute(_n(`focus-guard`))&&t.getAttribute(`data-type`)===`outside`;l.start(0,()=>{let e=n.select(`domReferenceElement`),o=Mt(Vt(e));!t&&o===e||kt(i.current.floatingContext?.refs.floating.current,o)||kt(e,o)||a||an(t??o,n.context.triggerElements)||n.setOpen(!1,Lt(jt,r))})}}),[i,n,l,o]);return W.useMemo(()=>a?{reference:d,trigger:d}:{},[a,d])}var xc=class e{constructor(){this.pointerType=void 0,this.interactedInside=!1,this.handler=void 0,this.blockMouseMove=!0,this.performedPointerEventsMutation=!1,this.pointerEventsScopeElement=null,this.pointerEventsReferenceElement=null,this.pointerEventsFloatingElement=null,this.restTimeoutPending=!1,this.openChangeTimeout=new bn,this.restTimeout=new bn,this.handleCloseOptions=void 0}static create(){return new e}dispose=()=>{this.openChangeTimeout.clear(),this.restTimeout.clear()};disposeEffect=()=>this.dispose},Sc=new WeakMap;function Cc(e){if(!e.performedPointerEventsMutation)return;let t=e.pointerEventsScopeElement;t&&Sc.get(t)===e&&(e.pointerEventsScopeElement?.style.removeProperty(`pointer-events`),e.pointerEventsReferenceElement?.style.removeProperty(`pointer-events`),e.pointerEventsFloatingElement?.style.removeProperty(`pointer-events`),Sc.delete(t)),e.performedPointerEventsMutation=!1,e.pointerEventsScopeElement=null,e.pointerEventsReferenceElement=null,e.pointerEventsFloatingElement=null}function wc(e,t){let{scopeElement:n,referenceElement:r,floatingElement:i}=t,a=Sc.get(n);a&&a!==e&&Cc(a),Cc(e),e.performedPointerEventsMutation=!0,e.pointerEventsScopeElement=n,e.pointerEventsReferenceElement=r,e.pointerEventsFloatingElement=i,Sc.set(n,e),n.style.pointerEvents=`none`,r.style.pointerEvents=`auto`,i.style.pointerEvents=`auto`}function Tc(e){let t=Ve(xc.create).current,n=e.context.dataRef.current;return n.hoverInteractionState||=t,Zn(n.hoverInteractionState.disposeEffect),n.hoverInteractionState}function Ec(e,t={}){let n=`rootStore`in e?e.rootStore:e,r=n.useState(`open`),i=n.useState(`floatingElement`),a=n.useState(`domReferenceElement`),{dataRef:o}=n.context,{enabled:s=!0,closeDelay:c=0,nodeId:l}=t,u=Tc(n),d=un(),f=sn(),p=st(()=>Go(o.current.openEvent?.type,u.interactedInside)),m=st(()=>{let e=o.current.openEvent?.type;return e?.includes(`mouse`)&&e!==`mousedown`}),h=st(e=>an(e,n.context.triggerElements)),g=W.useCallback(e=>{let t=Uo(c,`close`,u.pointerType),r=()=>{n.setOpen(!1,Lt(Pt,e)),d?.events.emit(`floating.closed`,e)};t?u.openChangeTimeout.start(t,r):(u.openChangeTimeout.clear(),r())},[c,n,u,d]),_=st(()=>{Cc(u)}),v=st(e=>{let t=zt(e);if(!$t(t)){u.interactedInside=!1;return}u.interactedInside=t?.closest(`[aria-haspopup]`)!=null});ht(()=>{r||(u.pointerType=void 0,u.restTimeoutPending=!1,u.interactedInside=!1,_())},[r,u,_]),W.useEffect(()=>_,[_]),ht(()=>{if(s&&r&&u.handleCloseOptions?.blockPointerEvents&&m()&&V(a)&&i){let e=a,t=i,n=Vt(i),r=d?.nodesRef.current.find(e=>e.id===f)?.context?.elements.floating;return r&&(r.style.pointerEvents=``),wc(u,{scopeElement:u.handleCloseOptions?.getScope?.()??u.pointerEventsScopeElement??r??e.closest(`[data-rootownerid]`)??n.body,referenceElement:e,floatingElement:t}),()=>{_()}}},[s,r,a,i,u,m,d,f,_]);let y=fn();W.useEffect(()=>{if(!s)return;function e(){u.openChangeTimeout.clear(),y.clear(),d?.events.off(`floating.closed`,r),_()}function t(e){if(d&&f&&dn(d.nodesRef.current,f).length>0){d.events.on(`floating.closed`,r);return}if(h(e.relatedTarget))return;let t=o.current.floatingContext?.nodeId??l,n=e.relatedTarget;if(!(d&&t&&V(n)&&dn(d.nodesRef.current,t,!1).some(e=>kt(e.context?.elements.floating,n)))){if(u.handler){u.handler(e);return}_(),p()||g(e)}}function r(e){!d||!f||dn(d.nodesRef.current,f).length>0||y.start(0,()=>{d.events.off(`floating.closed`,r),n.setOpen(!1,Lt(Pt,e)),d.events.emit(`floating.closed`,e)})}let a=i;return Xt(a&&Xn(a,`mouseenter`,e),a&&Xn(a,`mouseleave`,t),a&&Xn(a,`pointerdown`,v,!0),()=>{d?.events.off(`floating.closed`,r)})},[s,i,n,o,l,p,h,g,_,v,u,d,f,y])}var Dc={current:null};function Oc(e,t={}){let n=`rootStore`in e?e.rootStore:e,{dataRef:r,events:i}=n.context,{enabled:a=!0,delay:o=0,handleClose:s=null,mouseOnly:c=!1,restMs:l=0,move:u=!0,triggerElementRef:d=Dc,externalTree:f,isActiveTrigger:p=!0,getHandleCloseContext:m,isClosing:h}=t,g=un(f),_=Tc(n),v=W.useRef(!1),y=vn(s),b=vn(o),x=vn(l),S=vn(a),C=vn(h);p&&(_.handleCloseOptions=y.current?.__options);let w=st(()=>Go(r.current.openEvent?.type,_.interactedInside)),T=st(e=>an(e,n.context.triggerElements)),E=st((e,t,r)=>{let i=n.context.triggerElements;if(i.hasElement(t))return!e||!kt(e,t);if(!V(r))return!1;let a=r;return i.hasMatchingElement(e=>kt(e,a))&&(!e||!kt(e,a))}),D=st((e,t=!0)=>{let r=Uo(b.current,`close`,_.pointerType);r?_.openChangeTimeout.start(r,()=>{n.setOpen(!1,Lt(Pt,e)),g?.events.emit(`floating.closed`,e)}):t&&(_.openChangeTimeout.clear(),n.setOpen(!1,Lt(Pt,e)),g?.events.emit(`floating.closed`,e))}),O=st(()=>{_.handler&&=(Vt(n.select(`domReferenceElement`)).removeEventListener(`mousemove`,_.handler),void 0)}),k=st(()=>{Cc(_)});return W.useEffect(()=>O,[O]),W.useEffect(()=>{if(!a)return;function e(e){e.open?v.current=!1:(v.current=e.reason===Pt,O(),_.openChangeTimeout.clear(),_.restTimeout.clear(),_.blockMouseMove=!0,_.restTimeoutPending=!1)}return i.on(`openchange`,e),()=>{i.off(`openchange`,e)}},[a,i,_,O]),W.useEffect(()=>{if(!a)return;let e=d.current??(p?n.select(`domReferenceElement`):null);if(!V(e))return;function t(e){if(_.openChangeTimeout.clear(),_.blockMouseMove=!1,c&&!Ht(_.pointerType))return;let t=Wo(x.current),r=Uo(b.current,`open`,_.pointerType),i=zt(e),a=e.currentTarget??null,o=n.select(`domReferenceElement`),s=a;if(V(i)&&!n.context.triggerElements.hasElement(i)){for(let e of n.context.triggerElements.elements())if(kt(e,i)){s=e;break}}V(a)&&V(o)&&!n.context.triggerElements.hasElement(a)&&kt(a,o)&&(s=o);let l=s==null?!1:E(o,s,i),u=n.select(`open`),d=C.current?.()??n.select(`transitionStatus`)===`ending`,f=!u&&d&&v.current,p=!l&&V(s)&&V(o)&&kt(o,s)&&f,m=t>0&&!r,h=l&&(u||f)||p,g=!u||l;if(h){n.setOpen(!0,Lt(Pt,e,s));return}m||(r?_.openChangeTimeout.start(r,()=>{g&&n.setOpen(!0,Lt(Pt,e,s))}):g&&n.setOpen(!0,Lt(Pt,e,s)))}function i(e){if(w()){k();return}O();let t=Vt(n.select(`domReferenceElement`));_.restTimeout.clear(),_.restTimeoutPending=!1;let i=r.current.floatingContext??m?.();if(!T(e.relatedTarget)){if(y.current&&i){n.select(`open`)||_.openChangeTimeout.clear();let r=d.current;_.handler=y.current({...i,tree:g,x:e.clientX,y:e.clientY,onClose(){k(),O(),S.current&&!w()&&r===n.select(`domReferenceElement`)&&D(e,!0)}}),t.addEventListener(`mousemove`,_.handler),_.handler(e);return}(_.pointerType!==`touch`||!kt(n.select(`floatingElement`),e.relatedTarget))&&D(e)}}return u?Xt(Xn(e,`mousemove`,t,{once:!0}),Xn(e,`mouseenter`,t),Xn(e,`mouseleave`,i)):Xt(Xn(e,`mouseenter`,t),Xn(e,`mouseleave`,i))},[O,k,r,b,D,n,a,y,_,p,E,w,T,c,u,x,d,g,S,m,C]),W.useMemo(()=>{if(!a)return;function e(e){_.pointerType=e.pointerType}return{onPointerDown:e,onPointerEnter:e,onMouseMove(e){let{nativeEvent:t}=e,r=e.currentTarget,i=n.select(`domReferenceElement`),a=n.select(`open`),o=E(i,r,e.target);if(c&&!Ht(_.pointerType))return;if(a&&o&&_.handleCloseOptions?.blockPointerEvents){let e=n.select(`floatingElement`);e&&wc(_,{scopeElement:_.handleCloseOptions?.getScope?.()??r.ownerDocument.body,referenceElement:r,floatingElement:e})}let s=Wo(x.current);if(a&&!o||s===0||!o&&_.restTimeoutPending&&e.movementX**2+e.movementY**2<2)return;_.restTimeout.clear();function l(){if(_.restTimeoutPending=!1,w())return;let e=n.select(`open`);!_.blockMouseMove&&(!e||o)&&n.setOpen(!0,Lt(Pt,t,r))}_.pointerType===`touch`?Ys.flushSync(()=>{l()}):o&&a?l():(_.restTimeoutPending=!0,_.restTimeout.start(s,l))}}},[a,_,w,E,c,n,x])}var kc=new Map([[`select`,`listbox`],[`combobox`,`listbox`],[`label`,!1]]);function Ac(e,t={}){let n=`rootStore`in e?e.rootStore:e,r=n.useState(`open`),i=n.useState(`floatingId`),a=n.useState(`domReferenceElement`),o=n.useState(`floatingElement`),{role:s=`dialog`}=t,c=Bt(),l=a?.id||c,u=W.useMemo(()=>Yt(o)?.id||i,[o,i]),d=kc.get(s)??s,f=sn()!=null,p=W.useMemo(()=>d===`tooltip`||s===`label`?Ue:{"aria-haspopup":d===`alertdialog`?`dialog`:d,"aria-expanded":`false`,...d===`listbox`&&{role:`combobox`},...d===`menu`&&f&&{role:`menuitem`},...s===`select`&&{"aria-autocomplete":`none`},...s===`combobox`&&{"aria-autocomplete":`list`}},[d,f,s]),m=W.useMemo(()=>d===`tooltip`||s===`label`?{[`aria-${s===`label`?`labelledby`:`describedby`}`]:r?u:void 0}:{...p,"aria-expanded":r?`true`:`false`,"aria-controls":r?u:void 0,...d===`menu`&&{id:l}},[d,u,r,l,s,p]),h=W.useMemo(()=>{let e={id:u,...d&&{role:d}};return d===`tooltip`||s===`label`?e:{...e,...d===`menu`&&{"aria-labelledby":l}}},[d,u,l,s]),g=W.useCallback(({active:e,selected:t})=>{let n={role:`option`,...e&&{id:`${u}-fui-option`}};switch(s){case`select`:case`combobox`:return{...n,"aria-selected":t};default:}return{}},[u,s]);return W.useMemo(()=>({reference:m,floating:h,item:g,trigger:p}),[m,h,p,g])}var jc=.1,Mc=jc*jc,Nc=.5;function Pc(e,t,n,r,i,a){return r>=t!=a>=t&&e<=(i-n)*(t-r)/(a-r)+n}function Fc(e,t,n,r,i,a,o,s,c,l){let u=!1;return Pc(e,t,n,r,i,a)&&(u=!u),Pc(e,t,i,a,o,s)&&(u=!u),Pc(e,t,o,s,c,l)&&(u=!u),Pc(e,t,c,l,n,r)&&(u=!u),u}function Ic(e,t,n){return e>=n.x&&e<=n.x+n.width&&t>=n.y&&t<=n.y+n.height}function Lc(e,t,n,r,i,a){return e>=Math.min(n,i)&&e<=Math.max(n,i)&&t>=Math.min(r,a)&&t<=Math.max(r,a)}function Rc(e={}){let{blockPointerEvents:t=!1}=e,n=new bn,r=({x:e,y:t,placement:r,elements:i,onClose:a,nodeId:o,tree:s})=>{let c=r?.split(`-`)[0],l=!1,u=null,d=null,f=typeof performance<`u`?performance.now():0;function p(e,t){let n=performance.now(),r=n-f;if(u===null||d===null||r===0)return u=e,d=t,f=n,!1;let i=e-u,a=t-d,o=i*i+a*a,s=r*r*Mc;return u=e,d=t,f=n,o0)}function b(){y()||m()}if(y())return;let x=a.getBoundingClientRect(),S=u.getBoundingClientRect(),C=e>S.right-S.width/2,w=t>S.bottom-S.height/2,T=S.width>x.width,E=S.height>x.height,D=(T?x:S).left,O=(T?x:S).right,k=(E?x:S).top,ee=(E?x:S).bottom;if(c===`top`&&t>=x.bottom-1||c===`bottom`&&t<=x.top+1||c===`left`&&e>=x.right-1||c===`right`&&e<=x.left+1){b();return}let A=!1;switch(c){case`top`:A=Lc(d,f,D,x.top+1,O,S.bottom-1);break;case`bottom`:A=Lc(d,f,D,S.top+1,O,x.bottom-1);break;case`left`:A=Lc(d,f,S.right-1,ee,x.left+1,k);break;case`right`:A=Lc(d,f,x.right-1,ee,S.left+1,k);break;default:}if(A)return;if(l&&!Ic(d,f,x)){b();return}if(!g&&p(d,f)){b();return}let j=!1;switch(c){case`top`:{let n=T?Nc/2:Nc*4,r=T||C?e+n:e-n,i=T?e-n:C?e+n:e-n,a=t+Nc+1,o=C||T?S.bottom-Nc:S.top,s=C?T?S.bottom-Nc:S.top:S.bottom-Nc;j=Fc(d,f,r,a,i,a,S.left,o,S.right,s);break}case`bottom`:{let n=T?Nc/2:Nc*4,r=T||C?e+n:e-n,i=T?e-n:C?e+n:e-n,a=t-Nc,o=C||T?S.top+Nc:S.bottom,s=C?T?S.top+Nc:S.bottom:S.top+Nc;j=Fc(d,f,r,a,i,a,S.left,o,S.right,s);break}case`left`:{let n=E?Nc/2:Nc*4,r=E||w?t+n:t-n,i=E?t-n:w?t+n:t-n,a=e+Nc+1,o=w||E?S.right-Nc:S.left,s=w?E?S.right-Nc:S.left:S.right-Nc;j=Fc(d,f,o,S.top,s,S.bottom,a,r,a,i);break}case`right`:{let n=E?Nc/2:Nc*4,r=E||w?t+n:t-n,i=E?t-n:w?t+n:t-n,a=e-Nc,o=w||E?S.left+Nc:S.right,s=w?E?S.left+Nc:S.right:S.left+Nc;j=Fc(d,f,a,r,a,i,o,S.top,s,S.bottom);break}default:}j?l||n.start(40,b):b()}};return r.__options={...e,blockPointerEvents:t},r}var zc=function(e){return e.nestedDialogs=`--nested-dialogs`,e}({}),Bc=function(e){return e[e.open=tn.open]=`open`,e[e.closed=tn.closed]=`closed`,e[e.startingStyle=tn.startingStyle]=`startingStyle`,e[e.endingStyle=tn.endingStyle]=`endingStyle`,e.nested=`data-nested`,e.nestedDialogOpen=`data-nested-dialog-open`,e}({}),Vc=W.createContext(void 0);function Hc(){let e=W.useContext(Vc);if(e===void 0)throw Error(We(26));return e}var Uc={...en,...Jn,nestedDialogOpen(e){return e?{[Bc.nestedDialogOpen]:``}:null}},Wc=W.forwardRef(function(e,t){let{className:n,finalFocus:r,initialFocus:i,render:a,style:o,...s}=e,{store:c}=Lo(),l=c.useState(`descriptionElementId`),u=c.useState(`disablePointerDismissal`),d=c.useState(`floatingRootContext`),f=c.useState(`popupProps`),p=c.useState(`modal`),m=c.useState(`mounted`),h=c.useState(`nested`),g=c.useState(`nestedOpenDialogCount`),_=c.useState(`open`),v=c.useState(`openMethod`),y=c.useState(`titleElementId`),b=c.useState(`transitionStatus`),x=c.useState(`role`);Hc(),Yn({open:_,ref:c.context.popupRef,onComplete(){_&&c.context.onOpenChangeComplete?.(!0)}});function S(e){return e===`touch`?c.context.popupRef.current:!0}let C=i===void 0?S:i,w=Ge(`div`,e,{state:{open:_,nested:h,transitionStatus:b,nestedDialogOpen:g>0},props:[f,{"aria-labelledby":y??void 0,"aria-describedby":l??void 0,role:x,tabIndex:-1,hidden:!m,onKeyDown(e){Pn.has(e.key)&&e.stopPropagation()},style:{[zc.nestedDialogs]:g}},s],ref:[t,c.context.popupRef,c.useStateSetter(`popupElement`)],stateAttributesMapping:Uc});return(0,G.jsx)(on,{context:d,openInteractionType:v,disabled:!m,closeOnFocusOut:!u,initialFocus:C,returnFocus:r,modal:p!==!1,restoreFocus:`popup`,children:w})}),Gc=W.forwardRef(function(e,t){let{keepMounted:n=!1,...r}=e,{store:i}=Lo(),a=i.useState(`mounted`),o=i.useState(`modal`),s=i.useState(`open`);return a||n?(0,G.jsx)(Vc.Provider,{value:n,children:(0,G.jsxs)(Jt,{ref:t,...r,children:[a&&o===!0&&(0,G.jsx)(Sn,{ref:i.context.internalBackdropRef,inert:Nn(!s)}),e.children]})}):null});function Kc(e){let{store:t,parentContext:n,actionsRef:r,isDrawer:i}=e,a=t.useState(`open`),o=t.useState(`disablePointerDismissal`),s=t.useState(`modal`),c=t.useState(`popupElement`),{openMethod:l,triggerProps:u}=Rn(a);uc(t);let{forceUnmount:d}=dc(a,t),f=W.useCallback(()=>{t.setOpen(!1,Lt(It))},[t]);W.useImperativeHandle(r,()=>({unmount:d,close:f}),[d,f]);let p=vc({popupStore:t,onOpenChange:t.setOpen,treatPopupAsFloatingElement:!0}),[m,h]=W.useState(0),[g,_]=W.useState(0),v=m===0,y=Ac(p),b=kn(p,{outsidePressEvent(){return t.context.internalBackdropRef.current||t.context.backdropRef.current?`intentional`:{mouse:s===`trap-focus`?`sloppy`:`intentional`,touch:`sloppy`}},outsidePress(e){if(!t.context.outsidePressEnabledRef.current||`button`in e&&e.button!==0||`touches`in e&&e.touches.length!==1)return!1;let n=zt(e);if(v&&!o){let e=n;return s&&(t.context.internalBackdropRef.current||t.context.backdropRef.current)?t.context.internalBackdropRef.current===e||t.context.backdropRef.current===e||kt(e,c)&&!e?.hasAttribute(`data-base-ui-portal`):!0}return!1},escapeKey:v});Ln(a&&s===!0,c);let{getReferenceProps:x,getFloatingProps:S,getTriggerProps:C}=pn([y,b]);t.useContextCallback(`onNestedDialogOpen`,(e,t)=>{h(e),_(t)}),t.useContextCallback(`onNestedDialogClose`,()=>{h(0),_(0)}),W.useEffect(()=>(n?.onNestedDialogOpen&&a&&n.onNestedDialogOpen(m+1,g+ +!!i),n?.onNestedDialogClose&&!a&&n.onNestedDialogClose(),()=>{n?.onNestedDialogClose&&a&&n.onNestedDialogClose()}),[i,a,m,g,n]);let w=W.useMemo(()=>x(u),[x,u]),T=W.useMemo(()=>C(u),[C,u]),E=W.useMemo(()=>S(),[S]);t.useSyncedValues({openMethod:l,activeTriggerProps:w,inactiveTriggerProps:T,popupProps:E,floatingRootContext:p,nestedOpenDialogCount:m,nestedOpenDrawerCount:g})}var qc={...hc,modal:H(e=>e.modal),nested:H(e=>e.nested),nestedOpenDialogCount:H(e=>e.nestedOpenDialogCount),nestedOpenDrawerCount:H(e=>e.nestedOpenDrawerCount),disablePointerDismissal:H(e=>e.disablePointerDismissal),openMethod:H(e=>e.openMethod),descriptionElementId:H(e=>e.descriptionElementId),titleElementId:H(e=>e.titleElementId),viewportElement:H(e=>e.viewportElement),role:H(e=>e.role)},Jc=class e extends hn{constructor(e){super(Yc(e),{popupRef:W.createRef(),backdropRef:W.createRef(),internalBackdropRef:W.createRef(),outsidePressEnabledRef:{current:!0},triggerElements:new Wt,onOpenChange:void 0,onOpenChangeComplete:void 0},qc)}setOpen=(e,t)=>{if(t.preventUnmountOnClose=()=>{this.set(`preventUnmountingOnClose`,!0)},!e&&t.trigger==null&&this.state.activeTriggerId!=null&&(t.trigger=this.state.activeTriggerElement??void 0),this.context.onOpenChange?.(e,t),t.isCanceled)return;this.state.floatingRootContext.dispatchOpenChange(e,t);let n={open:e},r=t.trigger?.id??null;(r||e)&&(n.activeTriggerId=r,n.activeTriggerElement=t.trigger??null),this.update(n)};static useStore(t,n){let r=Ve(()=>new e(n)).current;return t??r}};function Yc(e={}){return{...pc(),modal:!0,disablePointerDismissal:!1,popupElement:null,viewportElement:null,descriptionElementId:void 0,titleElementId:void 0,openMethod:null,nested:!1,nestedOpenDialogCount:0,nestedOpenDrawerCount:0,role:`dialog`,...e}}var Xc=W.createContext(!1);function Zc(e){let{children:t,open:n,defaultOpen:r=!1,onOpenChange:i,onOpenChangeComplete:a,disablePointerDismissal:o=!1,modal:s=!0,actionsRef:c,handle:l,triggerId:u,defaultTriggerId:d=null}=e,f=Lo(!0),p=W.useContext(Xc),m=!!f,h=Jc.useStore(l?.store,{open:r,openProp:n,activeTriggerId:d,triggerIdProp:u,modal:s,disablePointerDismissal:o,nested:m});On(()=>{n===void 0&&h.state.open===!1&&r===!0&&h.update({open:!0,activeTriggerId:d})}),h.useControlledProp(`openProp`,n),h.useControlledProp(`triggerIdProp`,u),h.useSyncedValues({disablePointerDismissal:o,nested:m,modal:s}),h.useContextCallback(`onOpenChange`,i),h.useContextCallback(`onOpenChangeComplete`,a);let g=h.useState(`payload`);Kc({store:h,actionsRef:c,parentContext:f?.store.context,isDrawer:p,onOpenChange:i,triggerIdProp:u});let _=W.useMemo(()=>({store:h}),[h]);return(0,G.jsx)(Xc.Provider,{value:!1,children:(0,G.jsx)(Io.Provider,{value:_,children:typeof t==`function`?t({payload:g}):t})})}var Qc=W.forwardRef(function(e,t){let{render:n,className:r,style:i,id:a,...o}=e,{store:s}=Lo(),c=At(a);return s.useSyncedValueWithCleanup(`titleElementId`,c),Ge(`h2`,e,{ref:t,props:[{id:c},o]})});function $c(e){let t=(0,K.c)(4),n;t[0]===e?n=t[1]:({...n}=e,t[0]=e,t[1]=n);let r;return t[2]===n?r=t[3]:(r=(0,G.jsx)(Zc,{"data-slot":`sheet`,...n}),t[2]=n,t[3]=r),r}function el(e){let t=(0,K.c)(4),n;t[0]===e?n=t[1]:({...n}=e,t[0]=e,t[1]=n);let r;return t[2]===n?r=t[3]:(r=(0,G.jsx)(Gc,{"data-slot":`sheet-portal`,...n}),t[2]=n,t[3]=r),r}function tl(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`data-closed:fade-out-0 data-open:fade-in-0 data-closed:animate-out data-open:animate-in fixed inset-0 z-50 bg-black/80 duration-100 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(zo,{className:i,"data-slot":`sheet-overlay`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function nl(e){let t=(0,K.c)(17),n,r,i,a,o;t[0]===e?(n=t[1],r=t[2],i=t[3],a=t[4],o=t[5]):({className:r,children:n,side:a,showCloseButton:o,...i}=e,t[0]=e,t[1]=n,t[2]=r,t[3]=i,t[4]=a,t[5]=o);let s=a===void 0?`right`:a,c=o===void 0?!0:o,l;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,G.jsx)(tl,{}),t[6]=l):l=t[6];let u;t[7]===r?u=t[8]:(u=B(`data-[side=right]:data-closed:slide-out-to-right-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=top]:data-closed:slide-out-to-top-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:fade-out-0 data-open:fade-in-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-closed:animate-out data-open:animate-in fixed z-50 flex flex-col bg-background bg-clip-padding text-xs/relaxed shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm`,r),t[7]=r,t[8]=u);let d;t[9]===c?d=t[10]:(d=c&&(0,G.jsxs)(Bo,{"data-slot":`sheet-close`,render:(0,G.jsx)(vt,{className:`absolute top-4 right-4`,size:`icon-sm`,variant:`ghost`}),children:[(0,G.jsx)(Mo,{}),(0,G.jsx)(`span`,{className:`sr-only`,children:`Close`})]}),t[9]=c,t[10]=d);let f;return t[11]!==n||t[12]!==i||t[13]!==s||t[14]!==u||t[15]!==d?(f=(0,G.jsxs)(el,{children:[l,(0,G.jsxs)(Wc,{className:u,"data-side":s,"data-slot":`sheet-content`,...i,children:[n,d]})]}),t[11]=n,t[12]=i,t[13]=s,t[14]=u,t[15]=d,t[16]=f):f=t[16],f}function rl(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`flex flex-col gap-1.5 p-6`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`div`,{className:i,"data-slot":`sheet-header`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function il(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`text-sm font-medium text-foreground`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(Qc,{className:i,"data-slot":`sheet-title`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function al(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`text-xs/relaxed text-muted-foreground`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(Vo,{className:i,"data-slot":`sheet-description`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}var ol=W.createContext(void 0);function sl(e){let t=W.useContext(ol);if(t===void 0&&!e)throw Error(We(72));return t}var cl={...hc,disabled:H(e=>e.disabled),instantType:H(e=>e.instantType),isInstantPhase:H(e=>e.isInstantPhase),trackCursorAxis:H(e=>e.trackCursorAxis),disableHoverablePopup:H(e=>e.disableHoverablePopup),lastOpenChangeReason:H(e=>e.openChangeReason),closeOnClick:H(e=>e.closeOnClick),closeDelay:H(e=>e.closeDelay),hasViewport:H(e=>e.hasViewport)},ll=class e extends hn{constructor(e){super({...ul(),...e},{popupRef:W.createRef(),onOpenChange:void 0,onOpenChangeComplete:void 0,triggerElements:new Wt},cl)}setOpen=(e,t)=>{let n=t.reason,r=n===Pt,i=e&&n===`trigger-focus`,a=!e&&(n===`trigger-press`||n===`escape-key`);if(t.preventUnmountOnClose=()=>{this.set(`preventUnmountingOnClose`,!0)},this.context.onOpenChange?.(e,t),t.isCanceled)return;this.state.floatingRootContext.dispatchOpenChange(e,t);let o=()=>{let r={open:e,openChangeReason:n};i?r.instantType=`focus`:a?r.instantType=`dismiss`:n===`trigger-hover`&&(r.instantType=void 0);let o=t.trigger?.id??null;(o||e)&&(r.activeTriggerId=o,r.activeTriggerElement=t.trigger??null),this.update(r)};r?Ys.flushSync(o):o()};static useStore(t,n){let r=Ve(()=>new e(n)).current,i=t??r,a=vc({popupStore:i,onOpenChange:i.setOpen});return i.state.floatingRootContext=a,i}};function ul(){return{...pc(),disabled:!1,instantType:void 0,isInstantPhase:!1,trackCursorAxis:`none`,disableHoverablePopup:!1,openChangeReason:null,closeOnClick:!0,closeDelay:0,hasViewport:!1}}var dl=cn(function(e){let{disabled:t=!1,defaultOpen:n=!1,open:r,disableHoverablePopup:i=!1,trackCursorAxis:a=`none`,actionsRef:o,onOpenChange:s,onOpenChangeComplete:c,handle:l,triggerId:u,defaultTriggerId:d=null,children:f}=e,p=ll.useStore(l?.store,{open:n,openProp:r,activeTriggerId:d,triggerIdProp:u});On(()=>{r===void 0&&p.state.open===!1&&n===!0&&p.update({open:!0,activeTriggerId:d})}),p.useControlledProp(`openProp`,r),p.useControlledProp(`triggerIdProp`,u),p.useContextCallback(`onOpenChange`,s),p.useContextCallback(`onOpenChangeComplete`,c);let m=p.useState(`open`),h=!t&&m,g=p.useState(`activeTriggerId`),_=p.useState(`payload`);p.useSyncedValues({trackCursorAxis:a,disableHoverablePopup:i}),ht(()=>{m&&t&&p.setOpen(!1,Lt(Nt))},[m,t,p]),p.useSyncedValue(`disabled`,t),uc(p);let{forceUnmount:v,transitionStatus:y}=dc(h,p),b=p.select(`floatingRootContext`),x=p.useState(`isInstantPhase`),S=p.useState(`instantType`),C=p.useState(`lastOpenChangeReason`),w=W.useRef(null);ht(()=>{y===`ending`&&C===`none`||y!==`ending`&&x?(S!==`delay`&&(w.current=S),p.set(`instantType`,`delay`)):w.current!==null&&(p.set(`instantType`,w.current),w.current=null)},[y,x,C,S,p]),ht(()=>{h&&(g??p.set(`payload`,void 0))},[p,g,h]);let T=W.useCallback(()=>{p.setOpen(!1,Lt(It))},[p]);W.useImperativeHandle(o,()=>({unmount:v,close:T}),[v,T]);let{getReferenceProps:E,getFloatingProps:D,getTriggerProps:O}=pn([kn(b,{enabled:!t,referencePress:()=>p.select(`closeOnClick`)}),Zo(b,{enabled:!t&&a!==`none`,axis:a===`none`?void 0:a})]),k=W.useMemo(()=>E(),[E]),ee=W.useMemo(()=>O(),[O]),A=W.useMemo(()=>D(),[D]);return p.useSyncedValues({activeTriggerProps:k,inactiveTriggerProps:ee,popupProps:A}),(0,G.jsx)(ol.Provider,{value:p,children:typeof f==`function`?f({payload:_}):f})}),fl=W.createContext(void 0);function pl(){return W.useContext(fl)}var ml=function(e){return e[e.popupOpen=In.popupOpen]=`popupOpen`,e.triggerDisabled=`data-trigger-disabled`,e}({}),hl=An(function(e,t){let{className:n,render:r,handle:i,payload:a,disabled:o,delay:s,closeOnClick:c=!0,closeDelay:l,id:u,style:d,...f}=e,p=sl(!0),m=i?.store??p;if(!m)throw Error(We(82));let h=At(u),g=m.useState(`isTriggerActive`,h),_=m.useState(`isOpenedByTrigger`,h),v=m.useState(`floatingRootContext`),y=W.useRef(null),b=s??600,x=l??0,{registerTrigger:S,isMountedByThisTrigger:C}=lc(h,y,m,{payload:a,closeOnClick:c,closeDelay:x}),w=pl(),{delayRef:T,isInstantPhase:E,hasProvider:D}=Jo(v,{open:_});m.useSyncedValue(`isInstantPhase`,E);let O=m.useState(`disabled`),k=o??O,ee=m.useState(`trackCursorAxis`),A=m.useState(`disableHoverablePopup`),j=Oc(v,{enabled:!k,mouseOnly:!0,move:!1,handleClose:!A&&ee!==`both`?Rc():null,restMs(){let e=w?.delay,t=typeof T.current==`object`?T.current.open:void 0,n=b;return D&&(n=t===0?0:s??e??b),n},delay(){let e=typeof T.current==`object`?T.current.close:void 0,t=x;return l==null&&D&&(t=e),{close:t}},triggerElementRef:y,isActiveTrigger:g,isClosing:()=>m.select(`transitionStatus`)===`ending`}),te=bc(v,{enabled:!k}).reference,M={open:_},N=m.useState(`triggerProps`,C);return Ge(`button`,e,{state:M,ref:[t,S,y],props:[j,te,N,{onPointerDown(){m.set(`closeOnClick`,c)},id:h,[ml.triggerDisabled]:k?``:void 0},f],stateAttributesMapping:yn})}),gl=W.createContext(void 0);function _l(){let e=W.useContext(gl);if(e===void 0)throw Error(We(70));return e}var vl=W.forwardRef(function(e,t){let{children:n,container:r,className:i,render:a,style:o,...s}=e,{portalNode:c,portalSubtree:l}=Qt({container:r,ref:t,componentProps:e,elementProps:s});return!l&&!c?null:(0,G.jsxs)(W.Fragment,{children:[l,c&&Ys.createPortal(n,c)]})}),yl=W.forwardRef(function(e,t){let{keepMounted:n=!1,...r}=e;return sl().useState(`mounted`)||n?(0,G.jsx)(gl.Provider,{value:n,children:(0,G.jsx)(vl,{ref:t,...r})}):null}),bl=W.createContext(void 0);function xl(){let e=W.useContext(bl);if(e===void 0)throw Error(We(71));return e}var Sl=W.createContext(void 0);function Cl(){return W.useContext(Sl)?.direction??`ltr`}var wl=e=>({name:`arrow`,options:e,async fn(t){let{x:n,y:r,placement:i,rects:a,platform:o,elements:s,middlewareData:c}=t,{element:l,padding:u=0,offsetParent:d=`real`}=wn(e,t)||{};if(l==null)return{};let f=Un(u),p={x:n,y:r},m=Mn(i),h=En(m),g=await o.getDimensions(l),_=m===`y`,v=_?`top`:`left`,y=_?`bottom`:`right`,b=_?`clientHeight`:`clientWidth`,x=a.reference[h]+a.reference[m]-p[m]-a.floating[h],S=p[m]-a.reference[m],C=d===`real`?await o.getOffsetParent?.(l):s.floating,w=s.floating[b]||a.floating[h];(!w||!await o.isElement?.(C))&&(w=s.floating[b]||a.floating[h]);let T=x/2-S/2,E=w/2-g[h]/2-1,D=Math.min(f[v],E),O=Math.min(f[y],E),k=D,ee=w-g[h]-O,A=w/2-g[h]/2+T,j=jn(k,A,ee),te=!c.arrow&&Fn(i)!=null&&A!==j&&a.reference[h]/2-(A({...wl(e),options:[e,t]}),El={name:`hide`,async fn(e){let{width:t,height:n,x:r,y:i}=e.rects.reference,a=t===0&&n===0&&r===0&&i===0;return{data:{referenceHidden:(await sc().fn(e)).data?.referenceHidden||a}}}},Dl={sideX:`left`,sideY:`top`},Ol={name:`adaptiveOrigin`,async fn(e){let{x:t,y:n,rects:{floating:r},elements:{floating:i},platform:a,strategy:o,placement:s}=e,c=at(i),l=c.getComputedStyle(i);if(!(l.transitionDuration!==`0s`&&l.transitionDuration!==``))return{x:t,y:n,data:Dl};let u=await a.getOffsetParent?.(i),d={width:0,height:0};if(o===`fixed`&&c?.visualViewport)d={width:c.visualViewport.width,height:c.visualViewport.height};else if(u===c){let e=Vt(i);d={width:e.documentElement.clientWidth,height:e.documentElement.clientHeight}}else await a.isElement?.(u)&&(d=await a.getDimensions(u));let f=mn(s),p=t,m=n;f===`left`&&(p=d.width-(t+r.width)),f===`top`&&(m=d.height-(n+r.height));let h=f===`left`?`right`:Dl.sideX,g=f===`top`?`bottom`:Dl.sideY;return{x:p,y:m,data:{sideX:h,sideY:g}}}};function kl(e,t,n){let r=e===`inline-start`||e===`inline-end`;return{top:`top`,right:r?n?`inline-start`:`inline-end`:`right`,bottom:`bottom`,left:r?n?`inline-end`:`inline-start`:`left`}[t]}function Al(e,t,n){let{rects:r,placement:i}=e;return{side:kl(t,mn(i),n),align:Fn(i)||`center`,anchor:{width:r.reference.width,height:r.reference.height},positioner:{width:r.floating.width,height:r.floating.height}}}function jl(e){let{anchor:t,positionMethod:n=`absolute`,side:r=`bottom`,sideOffset:i=0,align:a=`center`,alignOffset:o=0,collisionBoundary:s,collisionPadding:c=5,sticky:l=!1,arrowPadding:u=5,disableAnchorTracking:d=!1,keepMounted:f=!1,floatingRootContext:p,mounted:m,collisionAvoidance:h,shiftCrossAxis:g=!1,nodeId:_,adaptiveOrigin:v,lazyFlip:y=!1,externalTree:b}=e,[x,S]=W.useState(null);!m&&x!==null&&S(null);let C=h.side||`flip`,w=h.align||`flip`,T=h.fallbackAxisSide||`end`,E=typeof t==`function`?t:void 0,D=st(E),O=E?D:t,k=vn(t),ee=vn(m),A=Cl()===`rtl`,j=x||{top:`top`,right:`right`,bottom:`bottom`,left:`left`,"inline-end":A?`left`:`right`,"inline-start":A?`right`:`left`}[r],te=a===`center`?j:`${j}-${a}`,M=c,N=+(r===`bottom`),ne=+(r===`top`),re=+(r===`right`),ie=+(r===`left`);typeof M==`number`?M={top:M+N,right:M+ie,bottom:M+ne,left:M+re}:M&&={top:(M.top||0)+N,right:(M.right||0)+ie,bottom:(M.bottom||0)+ne,left:(M.left||0)+re};let ae={boundary:s===`clipping-ancestors`?`clippingAncestors`:s,padding:M},oe=W.useRef(null),P=vn(i),se=vn(o),ce=[nc(e=>{let t=Al(e,r,A),n=typeof P.current==`function`?P.current(t):P.current,i=typeof se.current==`function`?se.current(t):se.current;return{mainAxis:n,crossAxis:i,alignmentAxis:i}},[typeof i==`function`?0:i,typeof o==`function`?0:o,A,r])],le=w===`none`&&C!==`shift`,ue=!le&&(l||g||C===`shift`),de=C===`none`?null:ac({...ae,padding:{top:M.top+1,right:M.right+1,bottom:M.bottom+1,left:M.left+1},mainAxis:!g&&C===`flip`,crossAxis:w===`flip`?`alignment`:!1,fallbackAxisSideDirection:T}),fe=le?null:rc(e=>{let t=Vt(e.elements.floating).documentElement;return{...ae,rootBoundary:g?{x:0,y:0,width:t.clientWidth,height:t.clientHeight}:void 0,mainAxis:w!==`none`,crossAxis:ue,limiter:l||g?void 0:ic(e=>{if(!oe.current)return{};let{width:t,height:n}=oe.current.getBoundingClientRect(),r=Gt(mn(e.placement)),i=r===`y`?t:n,a=r===`y`?M.left+M.right:M.top+M.bottom;return{offset:i/2+a/2}})}},[ae,l,g,M,w]);C===`shift`||w===`shift`||a===`center`?ce.push(fe,de):ce.push(de,fe),ce.push(oc({...ae,apply({elements:{floating:e},availableWidth:t,availableHeight:n,rects:r}){if(!ee.current)return;let i=e.style;i.setProperty(`--available-width`,`${t}px`),i.setProperty(`--available-height`,`${n}px`);let a=at(e).devicePixelRatio||1,{x:o,y:s,width:c,height:l}=r.reference,u=(Math.round((o+c)*a)-Math.round(o*a))/a,d=(Math.round((s+l)*a)-Math.round(s*a))/a;i.setProperty(`--anchor-width`,`${u}px`),i.setProperty(`--anchor-height`,`${d}px`)}}),Tl(()=>({element:oe.current||Vt(oe.current).createElement(`div`),padding:u,offsetParent:`floating`}),[u]),{name:`transformOrigin`,fn(e){let{elements:t,middlewareData:n,placement:a,rects:o,y:s}=e,c=mn(a),l=Gt(c),u=oe.current,d=n.arrow?.x||0,f=n.arrow?.y||0,p=u?.clientWidth||0,m=u?.clientHeight||0,h=d+p/2,g=f+m/2,_=Math.abs(n.shift?.y||0),v=o.reference.height/2,y=typeof i==`function`?i(Al(e,r,A)):i,b=_>y,x={top:`${h}px calc(100% + ${y}px)`,bottom:`${h}px ${-y}px`,left:`calc(100% + ${y}px) ${g}px`,right:`${-y}px ${g}px`}[c],S=`${h}px ${o.reference.y+v-s}px`;return t.floating.style.setProperty(`--transform-origin`,ue&&l===`y`&&b?S:x),{}}},El,v),ht(()=>{!m&&p&&p.update({referenceElement:null,floatingElement:null,domReferenceElement:null,positionReference:null})},[m,p]);let pe=W.useMemo(()=>({elementResize:!d&&typeof ResizeObserver<`u`,layoutShift:!d&&typeof IntersectionObserver<`u`}),[d]),{refs:me,elements:he,x:ge,y:_e,middlewareData:ve,update:ye,placement:be,context:xe,isPositioned:Se,floatingStyles:Ce}=_c({rootContext:p,open:f?m:void 0,placement:te,middleware:ce,strategy:n,whileElementsMounted:f?void 0:(...e)=>Vs(...e,pe),nodeId:_,externalTree:b}),{sideX:we,sideY:Te}=ve.adaptiveOrigin||Dl,Ee=Se?n:`fixed`,F=W.useMemo(()=>{let e=v?{position:Ee,[we]:ge,[Te]:_e}:{position:Ee,...Ce};return Se||(e.opacity=0),e},[v,Ee,we,ge,Te,_e,Ce,Se]),De=W.useRef(null);ht(()=>{if(!m)return;let e=k.current,t=typeof e==`function`?e():e,n=(Ml(t)?t.current:t)||null;n!==De.current&&(me.setPositionReference(n),De.current=n)},[m,me,O,k]),W.useEffect(()=>{if(!m)return;let e=k.current;typeof e!=`function`&&Ml(e)&&e.current!==De.current&&(me.setPositionReference(e.current),De.current=e.current)},[m,me,O,k]),W.useEffect(()=>{if(f&&m&&he.domReference&&he.floating)return Vs(he.domReference,he.floating,ye,pe)},[f,m,he,ye,pe]);let Oe=mn(be),ke=kl(r,Oe,A),Ae=Fn(be)||`center`,je=!!ve.hide?.referenceHidden;ht(()=>{y&&m&&Se&&S(Oe)},[y,m,Se,Oe]);let Me=W.useMemo(()=>({position:`absolute`,top:ve.arrow?.y,left:ve.arrow?.x}),[ve.arrow]),Ne=ve.arrow?.centerOffset!==0;return W.useMemo(()=>({positionerStyles:F,arrowStyles:Me,arrowRef:oe,arrowUncentered:Ne,side:ke,align:Ae,physicalSide:Oe,anchorHidden:je,refs:me,context:xe,isPositioned:Se,update:ye}),[F,Me,oe,Ne,ke,Ae,Oe,je,me,xe,Se,ye])}function Ml(e){return e!=null&&`current`in e}function Nl(e){return e===`starting`?rn:Ue}function Pl(e,t,{styles:n,transitionStatus:r,props:i,refs:a,hidden:o,inert:s=!1}){let c={...n};return s&&(c.pointerEvents=`none`),Ge(`div`,e,{state:t,ref:a,props:[{role:`presentation`,hidden:o,style:c},Nl(r),i],stateAttributesMapping:en})}var Fl=W.forwardRef(function(e,t){let{render:n,className:r,anchor:i,positionMethod:a=`absolute`,side:o=`top`,align:s=`center`,sideOffset:c=0,alignOffset:l=0,collisionBoundary:u=`clipping-ancestors`,collisionPadding:d=5,arrowPadding:f=5,sticky:p=!1,disableAnchorTracking:m=!1,collisionAvoidance:h=Gn,style:g,..._}=e,v=sl(),y=_l(),b=v.useState(`open`),x=v.useState(`mounted`),S=v.useState(`trackCursorAxis`),C=v.useState(`disableHoverablePopup`),w=v.useState(`floatingRootContext`),T=v.useState(`instantType`),E=v.useState(`transitionStatus`),D=jl({anchor:i,positionMethod:a,floatingRootContext:w,mounted:x,side:o,sideOffset:c,align:s,alignOffset:l,collisionBoundary:u,collisionPadding:d,sticky:p,arrowPadding:f,disableAnchorTracking:m,keepMounted:y,collisionAvoidance:h,adaptiveOrigin:v.useState(`hasViewport`)?Ol:void 0}),O=Pl(e,W.useMemo(()=>({open:b,side:D.side,align:D.align,anchorHidden:D.anchorHidden,instant:S===`none`?T:`tracking-cursor`}),[b,D.side,D.align,D.anchorHidden,S,T]),{styles:D.positionerStyles,transitionStatus:E,props:_,refs:[t,v.useStateSetter(`positionerElement`)],hidden:!x,inert:!b||S===`both`||C});return(0,G.jsx)(bl.Provider,{value:D,children:O})}),Il={...en,...Jn},J=W.forwardRef(function(e,t){let{className:n,render:r,style:i,...a}=e,o=sl(),{side:s,align:c}=xl(),l=o.useState(`open`),u=o.useState(`instantType`),d=o.useState(`transitionStatus`),f=o.useState(`popupProps`),p=o.useState(`floatingRootContext`);Yn({open:l,ref:o.context.popupRef,onComplete(){l&&o.context.onOpenChangeComplete?.(!0)}});let m=o.useState(`disabled`),h=o.useState(`closeDelay`);return Ec(p,{enabled:!m,closeDelay:h}),Ge(`div`,e,{state:{open:l,side:s,align:c,instant:u,transitionStatus:d},ref:[t,o.context.popupRef,o.useStateSetter(`popupElement`)],props:[f,Nl(d),a],stateAttributesMapping:Il})}),Ll=W.forwardRef(function(e,t){let{className:n,render:r,style:i,...a}=e,o=sl(),s=o.useState(`open`),c=o.useState(`instantType`),{arrowRef:l,side:u,align:d,arrowUncentered:f,arrowStyles:p}=xl();return Ge(`div`,e,{state:{open:s,side:u,align:d,uncentered:f,instant:c},ref:[t,l],props:[{style:p,"aria-hidden":!0},a],stateAttributesMapping:en})}),Y=function(e){let{delay:t,closeDelay:n,timeout:r=400}=e,i=W.useMemo(()=>({delay:t,closeDelay:n}),[t,n]),a=W.useMemo(()=>({open:t,close:n}),[t,n]);return(0,G.jsx)(fl.Provider,{value:i,children:(0,G.jsx)(qo,{delay:a,timeoutMs:r,children:e.children})})};function X(e){let t=(0,K.c)(6),n,r;t[0]===e?(n=t[1],r=t[2]):({delay:r,...n}=e,t[0]=e,t[1]=n,t[2]=r);let i=r===void 0?0:r,a;return t[3]!==i||t[4]!==n?(a=(0,G.jsx)(Y,{"data-slot":`tooltip-provider`,delay:i,...n}),t[3]=i,t[4]=n,t[5]=a):a=t[5],a}function Rl(e){let t=(0,K.c)(4),n;t[0]===e?n=t[1]:({...n}=e,t[0]=e,t[1]=n);let r;return t[2]===n?r=t[3]:(r=(0,G.jsx)(X,{children:(0,G.jsx)(dl,{"data-slot":`tooltip`,...n})}),t[2]=n,t[3]=r),r}function zl(e){let t=(0,K.c)(4),n;t[0]===e?n=t[1]:({...n}=e,t[0]=e,t[1]=n);let r;return t[2]===n?r=t[3]:(r=(0,G.jsx)(hl,{"data-slot":`tooltip-trigger`,...n}),t[2]=n,t[3]=r),r}function Bl(e){let t=(0,K.c)(21),n,r,i,a,o,s,c;t[0]===e?(n=t[1],r=t[2],i=t[3],a=t[4],o=t[5],s=t[6],c=t[7]):({className:r,side:a,sideOffset:o,align:s,alignOffset:c,children:n,...i}=e,t[0]=e,t[1]=n,t[2]=r,t[3]=i,t[4]=a,t[5]=o,t[6]=s,t[7]=c);let l=a===void 0?`top`:a,u=o===void 0?4:o,d=s===void 0?`center`:s,f=c===void 0?0:c,p;t[8]===r?p=t[9]:(p=B(`data-open:fade-in-0 data-open:zoom-in-95 data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-closed:fade-out-0 data-closed:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=delayed-open]:animate-in data-closed:animate-out data-open:animate-in z-50 w-fit max-w-xs origin-(--transform-origin) rounded-md bg-foreground px-3 py-1.5 text-xs text-background **:data-[slot=kbd]:rounded-md`,r),t[8]=r,t[9]=p);let m;t[10]===Symbol.for(`react.memo_cache_sentinel`)?(m=(0,G.jsx)(Ll,{className:`z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5`}),t[10]=m):m=t[10];let h;t[11]!==n||t[12]!==i||t[13]!==p?(h=(0,G.jsxs)(J,{className:p,"data-slot":`tooltip-content`,...i,children:[n,m]}),t[11]=n,t[12]=i,t[13]=p,t[14]=h):h=t[14];let g;return t[15]!==d||t[16]!==f||t[17]!==l||t[18]!==u||t[19]!==h?(g=(0,G.jsx)(yl,{children:(0,G.jsx)(Fl,{align:d,alignOffset:f,className:`isolate z-50`,side:l,sideOffset:u,children:h})}),t[15]=d,t[16]=f,t[17]=l,t[18]=u,t[19]=h,t[20]=g):g=t[20],g}var Vl=window.matchMedia(`(max-width: 767px)`);function Hl(e){return Vl.addEventListener(`change`,e),()=>Vl.removeEventListener(`change`,e)}function Ul(){return Vl.matches}function Wl(){return(0,W.useSyncExternalStore)(Hl,Ul)}var Gl=`sidebar_state`,Kl=3600*24*7,ql=`12rem`,Jl=`16rem`,Yl=`3rem`,Xl=`b`,Zl=W.createContext(null);function Ql(){let e=W.useContext(Zl);if(!e)throw Error(`useSidebar must be used within a SidebarProvider.`);return e}function $l(e){let t=(0,K.c)(36),n,r,i,a,o,s,c;t[0]===e?(n=t[1],r=t[2],i=t[3],a=t[4],o=t[5],s=t[6],c=t[7]):({defaultOpen:c,open:i,onOpenChange:o,className:r,style:s,children:n,...a}=e,t[0]=e,t[1]=n,t[2]=r,t[3]=i,t[4]=a,t[5]=o,t[6]=s,t[7]=c);let l=c===void 0?!0:c,u=Wl(),[d,f]=W.useState(!1),[p,m]=W.useState(l),h=i??p,g;t[8]!==h||t[9]!==o?(g=e=>{let t=typeof e==`function`?e(h):e;o?o(t):m(t),document.cookie=`${Gl}=${t}; path=/; max-age=${Kl}`},t[8]=h,t[9]=o,t[10]=g):g=t[10];let _=g,v;t[11]!==u||t[12]!==_?(v=()=>u?f(tu):_(eu),t[11]=u,t[12]=_,t[13]=v):v=t[13];let y=v,b,x;t[14]===y?(b=t[15],x=t[16]):(b=()=>{let e=e=>{e.key===Xl&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),y())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},x=[y],t[14]=y,t[15]=b,t[16]=x),W.useEffect(b,x);let S=h?`expanded`:`collapsed`,C;t[17]!==u||t[18]!==h||t[19]!==d||t[20]!==_||t[21]!==S||t[22]!==y?(C={state:S,open:h,setOpen:_,isMobile:u,openMobile:d,setOpenMobile:f,toggleSidebar:y},t[17]=u,t[18]=h,t[19]=d,t[20]=_,t[21]=S,t[22]=y,t[23]=C):C=t[23];let w=C,T;t[24]===r?T=t[25]:(T=B(`group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar`,r),t[24]=r,t[25]=T);let E;t[26]===s?E=t[27]:(E={"--sidebar-width":ql,"--sidebar-width-icon":Yl,...s},t[26]=s,t[27]=E);let D=E,O;t[28]!==n||t[29]!==a||t[30]!==T||t[31]!==D?(O=(0,G.jsx)(`div`,{className:T,"data-slot":`sidebar-wrapper`,style:D,...a,children:n}),t[28]=n,t[29]=a,t[30]=T,t[31]=D,t[32]=O):O=t[32];let k;return t[33]!==w||t[34]!==O?(k=(0,G.jsx)(Zl.Provider,{value:w,children:O}),t[33]=w,t[34]=O,t[35]=k):k=t[35],k}function eu(e){return!e}function tu(e){return!e}function nu(e){let t=(0,K.c)(46),n,r,i,a,o,s;t[0]===e?(n=t[1],r=t[2],i=t[3],a=t[4],o=t[5],s=t[6]):({side:a,variant:o,collapsible:s,className:r,children:n,...i}=e,t[0]=e,t[1]=n,t[2]=r,t[3]=i,t[4]=a,t[5]=o,t[6]=s);let c=a===void 0?`left`:a,l=o===void 0?`sidebar`:o,u=s===void 0?`offExamples`:s,{isMobile:d,state:f,openMobile:p,setOpenMobile:m}=Ql();if(u===`none`){let e;t[7]===r?e=t[8]:(e=B(`flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground`,r),t[7]=r,t[8]=e);let a;return t[9]!==n||t[10]!==i||t[11]!==e?(a=(0,G.jsx)(`div`,{className:e,"data-slot":`sidebar`,...i,children:n}),t[9]=n,t[10]=i,t[11]=e,t[12]=a):a=t[12],a}if(d){let e;t[13]===Symbol.for(`react.memo_cache_sentinel`)?(e={"--sidebar-width":Jl},t[13]=e):e=t[13];let r=e,a;t[14]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,G.jsxs)(rl,{className:`sr-only`,children:[(0,G.jsx)(il,{children:`Sidebar`}),(0,G.jsx)(al,{children:`Displays the mobile sidebar.`})]}),t[14]=a):a=t[14];let o;t[15]===n?o=t[16]:(o=(0,G.jsx)(`div`,{className:`flex h-full w-full flex-col`,children:n}),t[15]=n,t[16]=o);let s;t[17]!==c||t[18]!==o?(s=(0,G.jsxs)(nl,{className:`w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden`,"data-mobile":`true`,"data-sidebar":`sidebar`,"data-slot":`sidebar`,side:c,style:r,children:[a,o]}),t[17]=c,t[18]=o,t[19]=s):s=t[19];let l;return t[20]!==p||t[21]!==i||t[22]!==m||t[23]!==s?(l=(0,G.jsx)($c,{onOpenChange:m,open:p,...i,children:s}),t[20]=p,t[21]=i,t[22]=m,t[23]=s,t[24]=l):l=t[24],l}let h=f===`collapsed`?u:``,g=l===`floating`||l===`inset`?`group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]`:`group-data-[collapsible=icon]:w-(--sidebar-width-icon)`,_;t[25]===g?_=t[26]:(_=B(`relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear`,`group-data-[collapsible=offExamples]:w-0`,`group-data-[side=right]:rotate-180`,g),t[25]=g,t[26]=_);let v;t[27]===_?v=t[28]:(v=(0,G.jsx)(`div`,{className:_,"data-slot":`sidebar-gap`}),t[27]=_,t[28]=v);let y=c===`left`?`left-0 group-data-[collapsible=offExamples]:left-[calc(var(--sidebar-width)*-1)]`:`right-0 group-data-[collapsible=offExamples]:right-[calc(var(--sidebar-width)*-1)]`,b=l===`floating`||l===`inset`?`p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]`:`group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l`,x;t[29]!==r||t[30]!==y||t[31]!==b?(x=B(`fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex`,y,b,r),t[29]=r,t[30]=y,t[31]=b,t[32]=x):x=t[32];let S;t[33]===n?S=t[34]:(S=(0,G.jsx)(`div`,{className:`flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 group-data-[variant=floating]:ring-sidebar-border`,"data-sidebar":`sidebar`,"data-slot":`sidebar-inner`,children:n}),t[33]=n,t[34]=S);let C;t[35]!==i||t[36]!==x||t[37]!==S?(C=(0,G.jsx)(`div`,{className:x,"data-slot":`sidebar-container`,...i,children:S}),t[35]=i,t[36]=x,t[37]=S,t[38]=C):C=t[38];let w;return t[39]!==c||t[40]!==f||t[41]!==C||t[42]!==h||t[43]!==v||t[44]!==l?(w=(0,G.jsxs)(`div`,{className:`group peer hidden text-sidebar-foreground md:block`,"data-collapsible":h,"data-side":c,"data-slot":`sidebar`,"data-state":f,"data-variant":l,children:[v,C]}),t[39]=c,t[40]=f,t[41]=C,t[42]=h,t[43]=v,t[44]=l,t[45]=w):w=t[45],w}function ru(e){let t=(0,K.c)(15),n,r,i;t[0]===e?(n=t[1],r=t[2],i=t[3]):({className:n,onClick:r,...i}=e,t[0]=e,t[1]=n,t[2]=r,t[3]=i);let{toggleSidebar:a}=Ql(),o;t[4]===n?o=t[5]:(o=B(n),t[4]=n,t[5]=o);let s;t[6]!==r||t[7]!==a?(s=e=>{r?.(e),a()},t[6]=r,t[7]=a,t[8]=s):s=t[8];let c,l;t[9]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,G.jsx)(To,{}),l=(0,G.jsx)(`span`,{className:`sr-only`,children:`Toggle Sidebar`}),t[9]=c,t[10]=l):(c=t[9],l=t[10]);let u;return t[11]!==i||t[12]!==o||t[13]!==s?(u=(0,G.jsxs)(vt,{className:o,"data-sidebar":`trigger`,"data-slot":`sidebar-trigger`,onClick:s,size:`icon-lg`,variant:`ghost`,...i,children:[c,l]}),t[11]=i,t[12]=o,t[13]=s,t[14]=u):u=t[14],u}function iu(e){let t=(0,K.c)(9),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let{toggleSidebar:i}=Ql(),a;t[3]===n?a=t[4]:(a=B(`absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex`,`in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize`,`[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize`,`group-data-[collapsible=offExamples]:translate-x-0 group-data-[collapsible=offExamples]:after:left-full hover:group-data-[collapsible=offExamples]:bg-sidebar`,`[[data-side=left][data-collapsible=offExamples]_&]:-right-2`,`[[data-side=right][data-collapsible=offExamples]_&]:-left-2`,n),t[3]=n,t[4]=a);let o;return t[5]!==r||t[6]!==a||t[7]!==i?(o=(0,G.jsx)(`button`,{"aria-label":`Toggle Sidebar`,className:a,"data-sidebar":`rail`,"data-slot":`sidebar-rail`,onClick:i,tabIndex:-1,title:`Toggle Sidebar`,...r}),t[5]=r,t[6]=a,t[7]=i,t[8]=o):o=t[8],o}function au(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`flex flex-col gap-2 p-2`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`div`,{className:i,"data-sidebar":`header`,"data-slot":`sidebar-header`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function ou(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`flex flex-col gap-2 p-2`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`div`,{className:i,"data-sidebar":`footer`,"data-slot":`sidebar-footer`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function su(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`mx-2 w-auto bg-sidebar-border`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(Ot,{className:i,"data-sidebar":`separator`,"data-slot":`sidebar-separator`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function cu(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`no-scrollbar flex min-h-0 flex-1 flex-col gap-0 overflow-auto group-data-[collapsible=icon]:overflow-hidden`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`div`,{className:i,"data-sidebar":`content`,"data-slot":`sidebar-content`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function lu(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`relative flex w-full min-w-0 flex-col px-2 py-1`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`div`,{className:i,"data-sidebar":`group`,"data-slot":`sidebar-group`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function uu(e){let t=(0,K.c)(10),n,r,i,a;if(t[0]!==e){let{className:o,render:s,...c}=e;n=s,a=lo,r=`div`,i=He({className:B(`flex h-8 shrink-0 items-center rounded-md px-2 text-xs text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0`,o)},c),t[0]=e,t[1]=n,t[2]=r,t[3]=i,t[4]=a}else n=t[1],r=t[2],i=t[3],a=t[4];let o;t[5]===Symbol.for(`react.memo_cache_sentinel`)?(o={slot:`sidebar-group-label`,sidebar:`group-label`},t[5]=o):o=t[5];let s;return t[6]!==n||t[7]!==r||t[8]!==i?(s={defaultTagName:r,props:i,render:n,state:o},t[6]=n,t[7]=r,t[8]=i,t[9]=s):s=t[9],a(s)}function du(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`flex w-full min-w-0 flex-col gap-px`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`ul`,{className:i,"data-sidebar":`menu`,"data-slot":`sidebar-menu`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function fu(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`group/menu-item relative`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`li`,{className:i,"data-sidebar":`menu-item`,"data-slot":`sidebar-menu-item`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}var pu=Ke(`peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-[calc(var(--radius-sm)+2px)] p-2 text-left text-xs ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate`,{variants:{variant:{default:`hover:bg-sidebar-accent hover:text-sidebar-accent-foreground`,outline:`bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]`},size:{default:`h-8 text-xs`,sm:`h-7 text-xs`,lg:`h-12 text-xs group-data-[collapsible=icon]:p-0!`}},defaultVariants:{variant:`default`,size:`default`}});function mu(e){let t=(0,K.c)(15),{render:n,isActive:r,variant:i,size:a,tooltip:o,className:s,...c}=e,l=r===void 0?!1:r,u=i===void 0?`default`:i,d=a===void 0?`default`:a,{isMobile:f,state:p}=Ql(),m=He({className:B(pu({variant:u,size:d}),s)},c),h=o?zl:n,g;t[0]!==l||t[1]!==d?(g={slot:`sidebar-menu-button`,sidebar:`menu-button`,size:d,active:l},t[0]=l,t[1]=d,t[2]=g):g=t[2];let _;t[3]!==m||t[4]!==h||t[5]!==g?(_={defaultTagName:`button`,props:m,render:h,state:g},t[3]=m,t[4]=h,t[5]=g,t[6]=_):_=t[6];let v=lo(_);if(!o)return v;let y;t[7]===o?y=t[8]:(y=typeof o==`string`?{children:o}:o,t[7]=o,t[8]=y);let b=y,x=p!==`collapsed`||f,S;t[9]!==x||t[10]!==b?(S=(0,G.jsx)(Bl,{align:`center`,hidden:x,side:`right`,...b}),t[9]=x,t[10]=b,t[11]=S):S=t[11];let C;return t[12]!==v||t[13]!==S?(C=(0,G.jsxs)(Rl,{children:[v,S]}),t[12]=v,t[13]=S,t[14]=C):C=t[14],C}var hu=`ap-southeast-2`,gu=9999;async function _u({action:e,credentials:t,service:n=`spinifex`}){let r=window.location.protocol.replace(`:`,``),i=`Action=${e}`,a=new Xe({method:`POST`,protocol:r,hostname:`localhost`,port:gu,path:`/`,headers:{host:`localhost:${gu}`,"content-type":`application/x-www-form-urlencoded`},body:i}),o=await new Qe({credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey},region:hu,service:n,sha256:Ze}).sign(a),s={};for(let[e,t]of Object.entries(o.headers))typeof t==`string`&&(s[e]=t);let c=`${window.location.protocol}//${window.location.host}/proxy/awsgw/`,l=await fetch(c,{method:`POST`,headers:s,body:i});if(!l.ok){let t=await l.text().catch(()=>``);throw Error(`${e} failed: ${l.status}${t?` - ${t}`:``}`)}return await l.json()}var vu=`000000000001`,yu=(0,W.createContext)(void 0);function bu({children:e}){let[t,n]=(0,W.useState)({isAdmin:!1,accountId:null,userName:null,version:null,license:null,loading:!0});return(0,W.useEffect)(()=>{async function e(){let e=Ye();if(!e){n(e=>({...e,loading:!1}));return}try{let t=await _u({action:`GetCallerIdentity`,credentials:e}),r=t.account_id===vu,i=null;if(r)try{i=await _u({action:`GetVersion`,credentials:e})}catch{}n({isAdmin:r,accountId:t.account_id,userName:t.user_name,version:i,license:i?.license??null,loading:!1})}catch{n(e=>({...e,loading:!1}))}}e()},[]),(0,G.jsx)(yu,{value:t,children:e})}function xu(){let e=(0,W.useContext)(yu);if(e===void 0)throw Error(`useAdmin must be used within an AdminProvider`);return e}function Su(){let e=(0,K.c)(8),{theme:t,setTheme:n}=co(),r;e[0]!==n||e[1]!==t?(r=()=>{n(t===`light`?`dark`:t===`dark`?`light`:`dark`)},e[0]=n,e[1]=t,e[2]=r):r=e[2];let i=r,a,o,s;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,G.jsx)(ko,{className:`size-[1.2rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90`}),o=(0,G.jsx)(Co,{className:`absolute size-[1.2rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0`}),s=(0,G.jsx)(`span`,{className:`sr-only`,children:`Toggle theme`}),e[3]=a,e[4]=o,e[5]=s):(a=e[3],o=e[4],s=e[5]);let c;return e[6]===i?c=e[7]:(c=(0,G.jsxs)(vt,{className:`rounded-full`,onClick:i,size:`icon-sm`,variant:`ghost`,children:[a,o,s]}),e[6]=i,e[7]=c),c}function Cu(){let e=(0,K.c)(7),{isAdmin:t,license:n}=xu(),r=t&&n===`open-source`,i,a;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(i=B(`z-50 flex h-10 shrink-0 items-center gap-2 border-b border-sidebar-border bg-sidebar px-4 text-sidebar-foreground`,`sticky top-0`),a=(0,G.jsx)(ru,{className:`-ml-1`}),e[0]=i,e[1]=a):(i=e[0],a=e[1]);let o;e[2]===r?o=e[3]:(o=r&&(0,G.jsx)(`a`,{href:`https://mulgadc.com/purchase`,target:`_blank`,rel:`noopener noreferrer`,className:B(mt({variant:`outline`,size:`sm`})),children:`Upgrade`}),e[2]=r,e[3]=o);let s;e[4]===Symbol.for(`react.memo_cache_sentinel`)?(s=(0,G.jsx)(Su,{}),e[4]=s):s=e[4];let c;return e[5]===o?c=e[6]:(c=(0,G.jsxs)(`header`,{className:i,children:[a,(0,G.jsxs)(`div`,{className:`flex w-full items-center justify-end gap-2`,children:[o,s]})]}),e[5]=o,e[6]=c),c}function wu(){let e=(0,K.c)(3),t,n;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,G.jsx)(`h1`,{className:`text-4xl font-bold`,children:`404`}),n=(0,G.jsx)(`p`,{className:`text-muted-foreground`,children:`Page not found`}),e[0]=t,e[1]=n):(t=e[0],n=e[1]);let r;return e[2]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,G.jsxs)(`div`,{className:`flex flex-1 flex-col items-center justify-center gap-4`,children:[t,n,(0,G.jsx)(Ie,{to:`/`,children:(0,G.jsx)(vt,{variant:`outline`,children:`Go back home`})})]}),e[2]=r):r=e[2],r}function Tu(){let e=(0,K.c)(144),t;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={select:Eu},e[0]=t):t=e[0];let n=Xa(t),r=Re(),i=S(),{isAdmin:a}=xu(),o;e[1]!==r||e[2]!==i?(o=function(){$e(),Be(),i.clear(),r({to:`/login`})},e[1]=r,e[2]=i,e[3]=o):o=e[3];let s=o,c;e[4]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,G.jsxs)(au,{className:`flex flex-row items-center gap-2 px-4 py-3`,children:[(0,G.jsx)(`img`,{src:`/mulga-logo.svg`,alt:`Mulga`,className:`size-6 shrink-0 dark:invert`}),(0,G.jsx)(`span`,{className:`truncate text-sm font-semibold group-data-[collapsible=icon]:hidden`,children:`Spinifex`})]}),e[4]=c):c=e[4];let l;e[5]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,G.jsx)(uu,{children:`General`}),e[5]=l):l=e[5];let u=n===`/`,d,f;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,G.jsx)(_o,{className:`size-4`}),f=(0,G.jsx)(`span`,{children:`Dashboard`}),e[6]=d,e[7]=f):(d=e[6],f=e[7]);let p;e[8]===u?p=e[9]:(p=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/`,children:(0,G.jsxs)(mu,{isActive:u,tooltip:`Dashboard`,children:[d,f]})})}),e[8]=u,e[9]=p);let m;e[10]!==a||e[11]!==n?(m=a&&(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/nodes`,children:(0,G.jsxs)(mu,{isActive:n.startsWith(`/nodes`),tooltip:`Nodes`,children:[(0,G.jsx)(Eo,{className:`size-4`}),(0,G.jsx)(`span`,{children:`Nodes`})]})})}),e[10]=a,e[11]=n,e[12]=m):m=e[12];let h;e[13]!==p||e[14]!==m?(h=(0,G.jsxs)(lu,{children:[l,(0,G.jsxs)(du,{children:[p,m]})]}),e[13]=p,e[14]=m,e[15]=h):h=e[15];let g;e[16]===Symbol.for(`react.memo_cache_sentinel`)?(g=(0,G.jsx)(uu,{children:`EC2`}),e[16]=g):g=e[16];let _;e[17]===n?_=e[18]:(_=n.startsWith(`/ec2/describe-instances`)||n.startsWith(`/ec2/run-instances`),e[17]=n,e[18]=_);let v,y;e[19]===Symbol.for(`react.memo_cache_sentinel`)?(v=(0,G.jsx)(Eo,{className:`size-4`}),y=(0,G.jsx)(`span`,{children:`Instances`}),e[19]=v,e[20]=y):(v=e[19],y=e[20]);let b;e[21]===_?b=e[22]:(b=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-instances`,children:(0,G.jsxs)(mu,{isActive:_,tooltip:`EC2 Instances`,children:[v,y]})})}),e[21]=_,e[22]=b);let x;e[23]===n?x=e[24]:(x=n.startsWith(`/ec2/describe-images`),e[23]=n,e[24]=x);let C,w;e[25]===Symbol.for(`react.memo_cache_sentinel`)?(C=(0,G.jsx)(vo,{className:`size-4`}),w=(0,G.jsx)(`span`,{children:`Images`}),e[25]=C,e[26]=w):(C=e[25],w=e[26]);let T;e[27]===x?T=e[28]:(T=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-images`,children:(0,G.jsxs)(mu,{isActive:x,tooltip:`Images`,children:[C,w]})})}),e[27]=x,e[28]=T);let E;e[29]===n?E=e[30]:(E=n.startsWith(`/ec2/describe-key-pairs`),e[29]=n,e[30]=E);let D,O;e[31]===Symbol.for(`react.memo_cache_sentinel`)?(D=(0,G.jsx)(yo,{className:`size-4`}),O=(0,G.jsx)(`span`,{children:`Key Pairs`}),e[31]=D,e[32]=O):(D=e[31],O=e[32]);let k;e[33]===E?k=e[34]:(k=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-key-pairs`,children:(0,G.jsxs)(mu,{isActive:E,tooltip:`Key Pairs`,children:[D,O]})})}),e[33]=E,e[34]=k);let ee;e[35]===n?ee=e[36]:(ee=n.startsWith(`/ec2/describe-volumes`)||n.startsWith(`/ec2/create-volume`)||n.startsWith(`/ec2/modify-volume`),e[35]=n,e[36]=ee);let A,j;e[37]===Symbol.for(`react.memo_cache_sentinel`)?(A=(0,G.jsx)(go,{className:`size-4`}),j=(0,G.jsx)(`span`,{children:`Volumes`}),e[37]=A,e[38]=j):(A=e[37],j=e[38]);let te;e[39]===ee?te=e[40]:(te=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-volumes`,children:(0,G.jsxs)(mu,{isActive:ee,tooltip:`Volumes`,children:[A,j]})})}),e[39]=ee,e[40]=te);let M;e[41]===n?M=e[42]:(M=n.startsWith(`/ec2/describe-snapshots`)||n.startsWith(`/ec2/create-snapshot`),e[41]=n,e[42]=M);let N,ne;e[43]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,G.jsx)(po,{className:`size-4`}),ne=(0,G.jsx)(`span`,{children:`Snapshots`}),e[43]=N,e[44]=ne):(N=e[43],ne=e[44]);let re;e[45]===M?re=e[46]:(re=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-snapshots`,children:(0,G.jsxs)(mu,{isActive:M,tooltip:`Snapshots`,children:[N,ne]})})}),e[45]=M,e[46]=re);let ie;e[47]===n?ie=e[48]:(ie=n.startsWith(`/ec2/describe-placement-groups`)||n.startsWith(`/ec2/create-placement-group`),e[47]=n,e[48]=ie);let ae,oe;e[49]===Symbol.for(`react.memo_cache_sentinel`)?(ae=(0,G.jsx)(bo,{className:`size-4`}),oe=(0,G.jsx)(`span`,{children:`Placement Groups`}),e[49]=ae,e[50]=oe):(ae=e[49],oe=e[50]);let P;e[51]===ie?P=e[52]:(P=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-placement-groups`,children:(0,G.jsxs)(mu,{isActive:ie,tooltip:`Placement Groups`,children:[ae,oe]})})}),e[51]=ie,e[52]=P);let se;e[53]===n?se=e[54]:(se=n.startsWith(`/ec2/describe-load-balancers`)||n.startsWith(`/ec2/create-load-balancer`),e[53]=n,e[54]=se);let ce,le;e[55]===Symbol.for(`react.memo_cache_sentinel`)?(ce=(0,G.jsx)(jo,{className:`size-4`}),le=(0,G.jsx)(`span`,{children:`Load Balancers`}),e[55]=ce,e[56]=le):(ce=e[55],le=e[56]);let ue;e[57]===se?ue=e[58]:(ue=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-load-balancers`,children:(0,G.jsxs)(mu,{isActive:se,tooltip:`Load Balancers`,children:[ce,le]})})}),e[57]=se,e[58]=ue);let de;e[59]===n?de=e[60]:(de=n.startsWith(`/ec2/describe-target-groups`)||n.startsWith(`/ec2/create-target-group`),e[59]=n,e[60]=de);let fe,pe;e[61]===Symbol.for(`react.memo_cache_sentinel`)?(fe=(0,G.jsx)(ho,{className:`size-4`}),pe=(0,G.jsx)(`span`,{children:`Target Groups`}),e[61]=fe,e[62]=pe):(fe=e[61],pe=e[62]);let me;e[63]===de?me=e[64]:(me=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-target-groups`,children:(0,G.jsxs)(mu,{isActive:de,tooltip:`Target Groups`,children:[fe,pe]})})}),e[63]=de,e[64]=me);let he;e[65]!==b||e[66]!==T||e[67]!==k||e[68]!==te||e[69]!==re||e[70]!==P||e[71]!==ue||e[72]!==me?(he=(0,G.jsxs)(lu,{children:[g,(0,G.jsxs)(du,{children:[b,T,k,te,re,P,ue,me]})]}),e[65]=b,e[66]=T,e[67]=k,e[68]=te,e[69]=re,e[70]=P,e[71]=ue,e[72]=me,e[73]=he):he=e[73];let ge;e[74]===Symbol.for(`react.memo_cache_sentinel`)?(ge=(0,G.jsx)(uu,{children:`Networking`}),e[74]=ge):ge=e[74];let _e;e[75]===n?_e=e[76]:(_e=n.startsWith(`/ec2/describe-vpcs`)||n.startsWith(`/ec2/create-vpc`),e[75]=n,e[76]=_e);let ve,ye;e[77]===Symbol.for(`react.memo_cache_sentinel`)?(ve=(0,G.jsx)(wo,{className:`size-4`}),ye=(0,G.jsx)(`span`,{children:`VPCs`}),e[77]=ve,e[78]=ye):(ve=e[77],ye=e[78]);let be;e[79]===_e?be=e[80]:(be=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-vpcs`,children:(0,G.jsxs)(mu,{isActive:_e,tooltip:`VPCs`,children:[ve,ye]})})}),e[79]=_e,e[80]=be);let xe;e[81]===n?xe=e[82]:(xe=n.startsWith(`/ec2/describe-subnets`)||n.startsWith(`/ec2/create-subnet`),e[81]=n,e[82]=xe);let Se,Ce;e[83]===Symbol.for(`react.memo_cache_sentinel`)?(Se=(0,G.jsx)(xo,{className:`size-4`}),Ce=(0,G.jsx)(`span`,{children:`Subnets`}),e[83]=Se,e[84]=Ce):(Se=e[83],Ce=e[84]);let we;e[85]===xe?we=e[86]:(we=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-subnets`,children:(0,G.jsxs)(mu,{isActive:xe,tooltip:`Subnets`,children:[Se,Ce]})})}),e[85]=xe,e[86]=we);let Te;e[87]===n?Te=e[88]:(Te=n.startsWith(`/ec2/describe-security-groups`)||n.startsWith(`/ec2/create-security-group`),e[87]=n,e[88]=Te);let Ee,F;e[89]===Symbol.for(`react.memo_cache_sentinel`)?(Ee=(0,G.jsx)(Do,{className:`size-4`}),F=(0,G.jsx)(`span`,{children:`Security Groups`}),e[89]=Ee,e[90]=F):(Ee=e[89],F=e[90]);let De;e[91]===Te?De=e[92]:(De=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-security-groups`,children:(0,G.jsxs)(mu,{isActive:Te,tooltip:`Security Groups`,children:[Ee,F]})})}),e[91]=Te,e[92]=De);let Oe;e[93]!==be||e[94]!==we||e[95]!==De?(Oe=(0,G.jsxs)(lu,{children:[ge,(0,G.jsxs)(du,{children:[be,we,De]})]}),e[93]=be,e[94]=we,e[95]=De,e[96]=Oe):Oe=e[96];let ke;e[97]===Symbol.for(`react.memo_cache_sentinel`)?(ke=(0,G.jsx)(uu,{children:`IAM`}),e[97]=ke):ke=e[97];let Ae;e[98]===n?Ae=e[99]:(Ae=n.startsWith(`/iam/list-users`)||n.startsWith(`/iam/create-user`),e[98]=n,e[99]=Ae);let je,Me;e[100]===Symbol.for(`react.memo_cache_sentinel`)?(je=(0,G.jsx)(Ao,{className:`size-4`}),Me=(0,G.jsx)(`span`,{children:`Users`}),e[100]=je,e[101]=Me):(je=e[100],Me=e[101]);let Ne;e[102]===Ae?Ne=e[103]:(Ne=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/iam/list-users`,children:(0,G.jsxs)(mu,{isActive:Ae,tooltip:`Users`,children:[je,Me]})})}),e[102]=Ae,e[103]=Ne);let Pe;e[104]===n?Pe=e[105]:(Pe=n.startsWith(`/iam/list-policies`)||n.startsWith(`/iam/create-policy`),e[104]=n,e[105]=Pe);let Fe,I;e[106]===Symbol.for(`react.memo_cache_sentinel`)?(Fe=(0,G.jsx)(Oo,{className:`size-4`}),I=(0,G.jsx)(`span`,{children:`Policies`}),e[106]=Fe,e[107]=I):(Fe=e[106],I=e[107]);let L;e[108]===Pe?L=e[109]:(L=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/iam/list-policies`,children:(0,G.jsxs)(mu,{isActive:Pe,tooltip:`Policies`,children:[Fe,I]})})}),e[108]=Pe,e[109]=L);let Le;e[110]!==Ne||e[111]!==L?(Le=(0,G.jsxs)(lu,{children:[ke,(0,G.jsxs)(du,{children:[Ne,L]})]}),e[110]=Ne,e[111]=L,e[112]=Le):Le=e[112];let R;e[113]===Symbol.for(`react.memo_cache_sentinel`)?(R=(0,G.jsx)(uu,{children:`S3`}),e[113]=R):R=e[113];let z;e[114]===n?z=e[115]:(z=n.startsWith(`/s3/ls`),e[114]=n,e[115]=z);let ze,Ve;e[116]===Symbol.for(`react.memo_cache_sentinel`)?(ze=(0,G.jsx)(Eo,{className:`size-4`}),Ve=(0,G.jsx)(`span`,{children:`Buckets`}),e[116]=ze,e[117]=Ve):(ze=e[116],Ve=e[117]);let He;e[118]===z?He=e[119]:(He=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/s3/ls`,children:(0,G.jsxs)(mu,{isActive:z,tooltip:`Buckets`,children:[ze,Ve]})})}),e[118]=z,e[119]=He);let Ue;e[120]!==a||e[121]!==n?(Ue=a&&(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/s3/service-metrics`,children:(0,G.jsxs)(mu,{isActive:n.startsWith(`/s3/service-metrics`),tooltip:`Service Metrics`,children:[(0,G.jsx)(uo,{className:`size-4`}),(0,G.jsx)(`span`,{children:`Service Metrics`})]})})}),e[120]=a,e[121]=n,e[122]=Ue):Ue=e[122];let We;e[123]!==He||e[124]!==Ue?(We=(0,G.jsxs)(lu,{children:[R,(0,G.jsxs)(du,{children:[He,Ue]})]}),e[123]=He,e[124]=Ue,e[125]=We):We=e[125];let Ge;e[126]===a?Ge=e[127]:(Ge=a&&(0,G.jsxs)(lu,{children:[(0,G.jsx)(uu,{children:`Documentation`}),(0,G.jsx)(du,{children:(0,G.jsx)(fu,{children:(0,G.jsx)(`a`,{href:`https://docs.mulgadc.com`,target:`_blank`,rel:`noopener noreferrer`,children:(0,G.jsxs)(mu,{tooltip:`Documentation`,children:[(0,G.jsx)(fo,{className:`size-4`}),(0,G.jsx)(`span`,{children:`Docs`})]})})})})]}),e[126]=a,e[127]=Ge);let Ke;e[128]!==he||e[129]!==Oe||e[130]!==Le||e[131]!==We||e[132]!==Ge||e[133]!==h?(Ke=(0,G.jsxs)(cu,{children:[h,he,Oe,Le,We,Ge]}),e[128]=he,e[129]=Oe,e[130]=Le,e[131]=We,e[132]=Ge,e[133]=h,e[134]=Ke):Ke=e[134];let qe;e[135]===Symbol.for(`react.memo_cache_sentinel`)?(qe=(0,G.jsx)(su,{className:`mx-0 w-full`}),e[135]=qe):qe=e[135];let B,Je;e[136]===Symbol.for(`react.memo_cache_sentinel`)?(B=(0,G.jsx)(So,{className:`size-4`}),Je=(0,G.jsx)(`span`,{children:`Sign out`}),e[136]=B,e[137]=Je):(B=e[136],Je=e[137]);let Ye;e[138]===s?Ye=e[139]:(Ye=(0,G.jsxs)(ou,{children:[qe,(0,G.jsx)(du,{children:(0,G.jsx)(fu,{children:(0,G.jsxs)(mu,{onClick:s,tooltip:`Sign out`,children:[B,Je]})})})]}),e[138]=s,e[139]=Ye);let Xe;e[140]===Symbol.for(`react.memo_cache_sentinel`)?(Xe=(0,G.jsx)(iu,{}),e[140]=Xe):Xe=e[140];let Ze;return e[141]!==Ke||e[142]!==Ye?(Ze=(0,G.jsxs)(nu,{collapsible:`icon`,children:[c,Ke,Ye,Xe]}),e[141]=Ke,e[142]=Ye,e[143]=Ze):Ze=e[143],Ze}function Eu(e){return e.pathname}function Du(e){let t=(0,K.c)(18),{error:n,reset:r}=e,i=be(),a=S(),o;t[0]!==a||t[1]!==r||t[2]!==i?(o=function(){a.invalidateQueries(),r(),i.invalidate()},t[0]=a,t[1]=r,t[2]=i,t[3]=o):o=t[3];let s=o,c;t[4]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,G.jsx)(Tu,{}),t[4]=c):c=t[4];let l;t[5]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,G.jsx)(Cu,{}),t[5]=l):l=t[5];let u,d;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(u=(0,G.jsx)(`div`,{className:`flex justify-center`,children:(0,G.jsx)(mo,{className:`size-12 text-destructive`})}),d=(0,G.jsx)(`h1`,{className:`text-2xl font-semibold`,children:`Something went wrong`}),t[6]=u,t[7]=d):(u=t[6],d=t[7]);let f=n.message||`An unexpected error occurred`,p;t[8]===f?p=t[9]:(p=(0,G.jsx)(`p`,{className:`text-muted-foreground`,children:f}),t[8]=f,t[9]=p);let m;t[10]===s?m=t[11]:(m=(0,G.jsx)(vt,{onClick:s,variant:`default`,children:`Try Again`}),t[10]=s,t[11]=m);let h;t[12]===Symbol.for(`react.memo_cache_sentinel`)?(h=(0,G.jsx)(Ie,{to:`/`,children:(0,G.jsx)(vt,{variant:`outline`,children:`Go Home`})}),t[12]=h):h=t[12];let g;t[13]===m?g=t[14]:(g=(0,G.jsxs)(`div`,{className:`flex justify-center gap-2`,children:[m,h]}),t[13]=m,t[14]=g);let _;return t[15]!==g||t[16]!==p?(_=(0,G.jsxs)(G.Fragment,{children:[c,(0,G.jsxs)(`main`,{className:`flex flex-1 flex-col`,children:[l,(0,G.jsx)(`div`,{className:`flex flex-1 items-center justify-center p-6 pt-0`,children:(0,G.jsxs)(`div`,{className:`max-w-md space-y-4 text-center`,children:[u,d,p,g]})})]})]}),t[15]=g,t[16]=p,t[17]=_):_=t[17],_}var Ou=Le()({head:()=>({meta:[{title:`Mulga`}]}),component:()=>(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(to,{}),(0,G.jsx)(Tu,{}),(0,G.jsxs)(`main`,{className:`flex flex-1 flex-col`,children:[(0,G.jsx)(Cu,{}),(0,G.jsx)(`div`,{className:`flex flex-1 flex-col p-8`,children:(0,G.jsx)(Va,{})})]})]}),errorComponent:Du,notFoundComponent:wu}),ku=L(`/login`)({beforeLoad:()=>{if(Ye())throw Fe({to:`/`})},component:R(()=>z(()=>import(`./login.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])),`component`)}),Au=L(`/_auth`)({beforeLoad:()=>{if(!Ye())throw Fe({to:`/login`})},component:R(()=>z(()=>import(`./route.js`),__vite__mapDeps([16,1])),`component`)}),ju=L(`/_auth/`)({loader:async({context:e})=>{await Promise.all([e.queryClient.ensureQueryData(ur),e.queryClient.ensureQueryData(vr),e.queryClient.ensureQueryData(_r),e.queryClient.ensureQueryData(tr),e.queryClient.ensureQueryData(Pr),e.queryClient.ensureQueryData(dr)])},head:()=>({meta:[{title:`Dashboard | Mulga`}]}),component:R(()=>z(()=>import(`./_auth.js`),__vite__mapDeps([17,1,3,4,18,2,5,6,19,20,21,22,23,24,25,26,27,28,29,30,31,9,14])),`component`)}),Mu=L(`/_auth/nodes`)({head:()=>({meta:[{title:`Nodes | Mulga`}]}),component:R(()=>z(()=>import(`./nodes.js`),__vite__mapDeps([32,1,21,22,23,33,29,31,3,4,9,19,14])),`component`)}),Nu=L(`/_auth/s3/service-metrics`)({head:()=>({meta:[{title:`Service Metrics | Mulga`}]}),component:R(()=>z(()=>import(`./service-metrics.js`),__vite__mapDeps([34,1,21,22,23,33,29,31,3,4,9,19,14])),`component`)}),Pu=L(`/_auth/s3/ls/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(Pr)},head:()=>({meta:[{title:`Buckets | S3 | Mulga`}]}),component:R(()=>z(()=>import(`./ls.js`),__vite__mapDeps([35,1,3,4,20,2,5,19,8,9,36,22,23,24,25,37,29])),`component`)}),Fu=L(`/_auth/s3/(buckets)/create-bucket`)({head:()=>({meta:[{title:`Create Bucket | S3 | Mulga`}]}),component:R(()=>z(()=>import(`./create-bucket.js`),__vite__mapDeps([38,1,39,2,3,4,5,23,40,13,41,25,42,24,26,43,8,9,44,27,45,46,47,29,15,10,11])),`component`)}),Iu=L(`/_auth/iam/(users)/create-user`)({head:()=>({meta:[{title:`Create User | IAM | Mulga`}]}),component:R(()=>z(()=>import(`./create-user.js`),__vite__mapDeps([48,1,49,2,3,4,5,23,40,13,41,25,42,24,26,43,8,9,44,27,45,46,47,29,15,10,11,50])),`component`)}),Lu=L(`/_auth/iam/(policies)/create-policy`)({head:()=>({meta:[{title:`Create Policy | IAM | Mulga`}]}),component:R(()=>z(()=>import(`./create-policy.js`),__vite__mapDeps([51,1,49,2,3,4,5,23,40,13,41,25,42,24,26,43,8,9,44,27,45,46,47,29,15,10,11,52,50])),`component`)}),Ru=L(`/_auth/ec2/(vpc)/create-vpc`)({head:()=>({meta:[{title:`Create VPC | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-vpc.js`),__vite__mapDeps([53,1,54,2,3,4,5,18,6,19,23,40,8,9,55,10,11,56,12,25,26,44,27,13,41,42,24,28,43,45,46,47,29,15,57])),`component`)}),zu=L(`/_auth/ec2/(volumes)/create-volume`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(mr)},head:()=>({meta:[{title:`Create Volume | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-volume.js`),__vite__mapDeps([58,1,54,2,3,4,5,18,6,19,23,40,55,8,9,10,11,56,12,25,26,44,27,13,36,22,41,42,24,43,45,46,47,29,15,57])),`component`)}),Bu=L(`/_auth/ec2/(target-groups)/create-target-group`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(_r)},head:()=>({meta:[{title:`Create Target Group | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-target-group.js`),__vite__mapDeps([59,1,18,2,3,4,5,6,19,60,23,40,13,36,22,41,25,42,24,26,43,8,9,44,27,45,46,61,7,10,11,12,55,56,62,63,15,47,29,64])),`component`)}),Vu=L(`/_auth/ec2/(subnet)/create-subnet`)({loader:async({context:e})=>{await Promise.all([e.queryClient.ensureQueryData(_r),e.queryClient.ensureQueryData(mr)])},head:()=>({meta:[{title:`Create Subnet | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-subnet.js`),__vite__mapDeps([65,1,3,4,54,2,5,18,6,19,23,40,55,8,9,10,11,56,12,25,26,44,27,13,36,22,41,42,24,43,45,46,47,29,15,57])),`component`)}),Hu=L(`/_auth/ec2/(snapshots)/create-snapshot`)({validateSearch:e=>({volumeId:typeof e.volumeId==`string`?e.volumeId:void 0}),loader:async({context:e})=>{await e.queryClient.ensureQueryData(vr)},head:()=>({meta:[{title:`Create Snapshot | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-snapshot.js`),__vite__mapDeps([66,1,54,2,3,4,5,18,6,19,23,40,55,8,9,10,11,56,12,25,26,44,27,13,36,22,41,42,24,43,45,46,47,29,15,52,57])),`component`)}),Uu=L(`/_auth/ec2/(security-groups)/create-security-group`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(_r)},head:()=>({meta:[{title:`Create Security Group | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-security-group.js`),__vite__mapDeps([67,1,3,4,54,2,5,18,6,19,23,40,55,8,9,10,11,56,12,25,26,44,27,13,36,22,41,42,24,43,45,46,47,29,15,57])),`component`)}),Wu=L(`/_auth/ec2/(placement-groups)/create-placement-group`)({head:()=>({meta:[{title:`Create Placement Group | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-placement-group.js`),__vite__mapDeps([68,1,54,2,3,4,5,18,6,19,23,40,55,8,9,10,11,56,12,25,26,44,27,13,41,42,24,43,45,46,47,29,15,57])),`component`)}),Z=L(`/_auth/ec2/(load-balancers)/create-load-balancer`)({loader:async({context:e})=>{await Promise.all([e.queryClient.ensureQueryData(_r),e.queryClient.ensureQueryData(Qn),e.queryClient.ensureQueryData(dr),e.queryClient.ensureQueryData(br),e.queryClient.ensureQueryData(fr)])},head:()=>({meta:[{title:`Create Load Balancer | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-load-balancer.js`),__vite__mapDeps([69,1,3,4,18,2,5,6,19,60,23,40,70,8,9,55,10,11,56,12,25,26,44,27,13,36,22,41,42,24,62,43,45,46,63,71,72,61,7,15,47,29,64])),`component`)}),Gu=L(`/_auth/ec2/(key)/import-key-pair`)({head:()=>({meta:[{title:`Import Key Pair | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./import-key-pair.js`),__vite__mapDeps([73,1,54,2,3,4,5,18,6,19,23,40,13,41,25,42,24,26,43,8,9,44,27,45,46,47,29,15,10,11,52,57])),`component`)}),Ku=L(`/_auth/ec2/(key)/create-key-pair`)({head:()=>({meta:[{title:`Create Key Pair | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-key-pair.js`),__vite__mapDeps([74,1,54,2,3,4,5,18,6,19,23,40,75,8,9,13,41,25,42,24,26,44,76,43,27,45,46,77,47,29,15,10,11,57])),`component`)}),qu=L(`/_auth/ec2/(instances)/run-instances`)({loader:async({context:e})=>{await Promise.all([e.queryClient.ensureQueryData(fr),e.queryClient.ensureQueryData(tr),e.queryClient.ensureQueryData($n),e.queryClient.ensureQueryData(Qn),e.queryClient.ensureQueryData(hr)])},head:()=>({meta:[{title:`Run Instances | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./run-instances.js`),__vite__mapDeps([78,1,54,2,3,4,5,18,6,19,23,40,7,8,9,10,11,12,55,56,25,26,44,27,13,36,22,41,42,24,43,45,46,29,15,57])),`component`)}),Ju=L(`/_auth/s3/ls/$bucket`)({component:R(()=>z(()=>import(`./route2.js`),__vite__mapDeps([79,1])),`component`)}),Yu=L(`/_auth/s3/ls/$bucket/`)({loader:async({context:e,params:t})=>{await e.queryClient.ensureQueryData(Fr(t.bucket))},head:({params:e})=>({meta:[{title:`${e.bucket} | S3 | Mulga`}]}),component:R(()=>z(()=>import(`./_bucket.js`),__vite__mapDeps([80,1,39,2,3,4,5,23,40,81,8,9,24,25,26,76,63,82,75,20,19,36,22,42,29])),`component`)}),Xu=L(`/_auth/iam/(users)/list-users/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(Mr)},head:()=>({meta:[{title:`Users | IAM | Mulga`}]}),component:R(()=>z(()=>import(`./list-users.js`),__vite__mapDeps([83,1,84,2,3,4,5,19,8,9,36,22,23,24,25,37,29])),`component`)}),Zu=L(`/_auth/iam/(policies)/list-policies/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(jr)},head:()=>({meta:[{title:`Policies | IAM | Mulga`}]}),component:R(()=>z(()=>import(`./list-policies.js`),__vite__mapDeps([85,1,84,2,3,4,5,19,8,9,36,22,23,24,25,37,29])),`component`)}),Qu=L(`/_auth/ec2/(vpc)/describe-vpcs/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(_r)},head:()=>({meta:[{title:`VPCs | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-vpcs.js`),__vite__mapDeps([86,1,3,4,18,2,5,6,19,8,9,36,22,23,24,25,37,29,30])),`component`)}),$u=L(`/_auth/ec2/(volumes)/describe-volumes/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(vr)},head:()=>({meta:[{title:`Volumes | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-volumes.js`),__vite__mapDeps([87,1,18,2,3,4,5,6,19,8,9,36,22,23,24,25,37,29,30])),`component`)}),ed=L(`/_auth/ec2/(target-groups)/describe-target-groups/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(br)},head:()=>({meta:[{title:`Target Groups | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-target-groups.js`),__vite__mapDeps([88,1,70,2,3,4,5,19,8,9,21,22,23,36,24,25,41,29])),`component`)}),td=L(`/_auth/ec2/(subnet)/describe-subnets/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(Qn)},head:()=>({meta:[{title:`Subnets | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-subnets.js`),__vite__mapDeps([89,1,3,4,18,2,5,6,19,8,9,36,22,23,24,25,37,29,30])),`component`)}),nd=L(`/_auth/ec2/(snapshots)/describe-snapshots/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(ar)},head:()=>({meta:[{title:`Snapshots | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-snapshots.js`),__vite__mapDeps([90,1,18,2,3,4,5,6,19,8,9,36,22,23,24,25,37,29,30])),`component`)}),rd=L(`/_auth/ec2/(security-groups)/describe-security-groups/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(dr)},head:()=>({meta:[{title:`Security Groups | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-security-groups.js`),__vite__mapDeps([91,1,18,2,3,4,5,6,19,8,9,36,22,23,24,25,37,29])),`component`)}),id=L(`/_auth/ec2/(placement-groups)/describe-placement-groups/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(hr)},head:()=>({meta:[{title:`Placement Groups | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-placement-groups.js`),__vite__mapDeps([92,1,18,2,3,4,5,6,19,8,9,36,22,23,24,25,37,29,30])),`component`)}),ad=L(`/_auth/ec2/(load-balancers)/describe-load-balancers/`)({loader:async({context:e})=>{await Promise.all([e.queryClient.ensureQueryData(xr),e.queryClient.ensureQueryData(fr)])},head:()=>({meta:[{title:`Load Balancers | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-load-balancers.js`),__vite__mapDeps([93,1,18,2,3,4,5,6,19,70,8,9,36,22,23,24,25,41,71,72,29,30])),`component`)}),od=L(`/_auth/ec2/(key)/describe-key-pairs/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(tr)},head:()=>({meta:[{title:`Key Pairs | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-key-pairs.js`),__vite__mapDeps([94,1,18,2,3,4,5,6,19,8,9,36,22,23,24,25,37,29])),`component`)}),sd=L(`/_auth/ec2/(instances)/describe-instances/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(ur)},head:()=>({meta:[{title:`Instances | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-instances.js`),__vite__mapDeps([95,1,18,2,3,4,5,6,19,8,9,36,22,23,24,25,37,29,30])),`component`)}),cd=L(`/_auth/ec2/(images)/describe-images/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(fr)},head:()=>({meta:[{title:`Images | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-images.js`),__vite__mapDeps([96,1,18,2,3,4,5,6,19,36,22,23,37,24,25,29,30,72])),`component`)}),ld=L(`/_auth/s3/ls/$bucket/$`)({loader:async({context:e,params:t})=>{let n=Je(t._splat??``);await e.queryClient.ensureQueryData(Fr(t.bucket,n))},head:({params:e})=>({meta:[{title:`${qe(e._splat??``,`${e.bucket}/`)} | S3 | Mulga`}]}),component:R(()=>z(()=>import(`./_.js`),__vite__mapDeps([97,1,39,2,3,4,5,23,40,81,8,9,24,25,26,76,63,82,75,20,19,36,22,42])),`component`)}),ud=L(`/_auth/iam/(users)/list-users/$userName`)({loader:async({context:e,params:t})=>{await Promise.all([e.queryClient.ensureQueryData(Ar(t.userName)),e.queryClient.ensureQueryData(Nr(t.userName)),e.queryClient.ensureQueryData(kr(t.userName)),e.queryClient.ensureQueryData(jr)])},head:({params:e})=>({meta:[{title:`${e.userName} | IAM | Mulga`}]}),component:R(()=>z(()=>import(`./_userName.js`),__vite__mapDeps([98,1,3,4,49,2,5,23,40,84,19,75,8,9,36,22,41,25,42,24,26,44,63,77,82,99,29,30,46])),`component`)}),dd=L(`/_auth/iam/(policies)/list-policies/$policyArn`)({loader:async({context:e,params:t})=>{let n=decodeURIComponent(t.policyArn),r=await e.queryClient.ensureQueryData(Or(n)),i=r.Policy?.DefaultVersionId;return i&&await e.queryClient.ensureQueryData(Dr(n,i)),r},head:({loaderData:e})=>({meta:[{title:`${e?.Policy?.PolicyName??`Policy`} | IAM | Mulga`}]}),component:R(()=>z(()=>import(`./_policyArn.js`),__vite__mapDeps([100,1,3,4,49,2,5,23,40,84,19,8,9,36,22,41,25,42,24,26,63,82,75,99,29])),`component`)}),fd=L(`/_auth/ec2/(vpc)/describe-vpcs/$id`)({loader:async({context:e,params:t})=>{await Promise.all([e.queryClient.ensureQueryData(er(t.id)),e.queryClient.ensureQueryData(Qn)])},head:({params:e})=>({meta:[{title:`${e.id} | VPC | Mulga`}]}),component:R(()=>z(()=>import(`./_id12.js`),__vite__mapDeps([101,1,3,4,54,2,5,18,6,19,23,40,8,9,36,22,24,25,41,42,26,63,82,75,99,29,30])),`component`)}),pd=L(`/_auth/ec2/(volumes)/modify-volume/$id`)({loader:async({context:e,params:t})=>{await e.queryClient.ensureQueryData(gr(t.id))},head:({params:e})=>({meta:[{title:`Resize ${e.id} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id11.js`),__vite__mapDeps([102,1,54,2,3,4,5,18,6,19,23,40,13,36,22,41,25,42,24,26,47,8,9,29,15,10,11,57])),`component`)}),md=L(`/_auth/ec2/(volumes)/describe-volumes/$id`)({loader:async({context:e,params:t})=>{await Promise.all([e.queryClient.ensureQueryData(gr(t.id)),e.queryClient.ensureQueryData(ur)])},head:({params:e})=>({meta:[{title:`${e.id} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id10.js`),__vite__mapDeps([103,1,3,4,54,2,5,18,6,19,23,40,75,8,9,55,10,11,56,12,25,26,44,27,36,22,24,41,42,63,82,99,29,30,15])),`component`)}),hd=L(`/_auth/ec2/(target-groups)/describe-target-groups/$id`)({loader:async({context:e,params:t})=>{let n=decodeURIComponent(t.id);await Promise.all([e.queryClient.ensureQueryData(Tr(n)),e.queryClient.ensureQueryData(Cr(n)),e.queryClient.ensureQueryData(yr([n])),e.queryClient.ensureQueryData(ur)])},head:({params:e})=>({meta:[{title:`${decodeURIComponent(e.id)} | Target Group | Mulga`}]}),component:R(()=>z(()=>import(`./_id9.js`),__vite__mapDeps([104,1,3,4,18,2,5,6,19,60,23,40,70,75,8,9,105,55,10,11,56,12,25,26,44,27,15,21,22,36,41,42,24,63,82,99,29])),`component`)}),gd=L(`/_auth/ec2/(subnet)/describe-subnets/$id`)({loader:async({context:e,params:t})=>{await e.queryClient.ensureQueryData(ir(t.id))},head:({params:e})=>({meta:[{title:`${e.id} | Subnet | Mulga`}]}),component:R(()=>z(()=>import(`./_id8.js`),__vite__mapDeps([106,1,3,4,54,2,5,18,6,19,23,40,8,9,36,22,24,25,41,42,26,63,82,75,99,29,30])),`component`)}),_d=L(`/_auth/ec2/(snapshots)/describe-snapshots/$id`)({loader:async({context:e,params:t})=>{await Promise.all([e.queryClient.ensureQueryData(cr(t.id)),e.queryClient.ensureQueryData(nr)])},head:({params:e})=>({meta:[{title:`${e.id} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id7.js`),__vite__mapDeps([107,1,3,4,54,2,5,18,6,19,23,40,75,8,9,36,22,24,25,41,42,26,45,63,82,99,29,30,15,10,11])),`component`)}),vd=L(`/_auth/ec2/(security-groups)/describe-security-groups/$id`)({loader:async({context:e,params:t})=>{await e.queryClient.ensureQueryData(rr(t.id))},head:({params:e})=>({meta:[{title:`${e.id} | Security Group | Mulga`}]}),component:R(()=>z(()=>import(`./_id6.js`),__vite__mapDeps([108,1,54,2,3,4,5,18,6,19,23,40,75,8,9,55,10,11,56,12,25,26,44,27,13,36,22,24,41,42,62,63,82,99,29,15,57])),`component`)}),yd=L(`/_auth/ec2/(placement-groups)/describe-placement-groups/$id`)({loader:async({context:e,params:t})=>{await Promise.all([e.queryClient.ensureQueryData(sr(t.id)),e.queryClient.ensureQueryData(ur)])},head:({params:e})=>({meta:[{title:`${e.id} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id5.js`),__vite__mapDeps([109,1,54,2,3,4,5,18,6,19,23,40,8,9,36,22,24,25,41,42,26,63,82,75,99,29,30])),`component`)}),Q=L(`/_auth/ec2/(load-balancers)/describe-load-balancers/$id`)({loader:async({context:e,params:t})=>{let n=decodeURIComponent(t.id);await Promise.all([e.queryClient.ensureQueryData(wr(n)),e.queryClient.ensureQueryData(Er(n)),e.queryClient.ensureQueryData(Sr(n)),e.queryClient.ensureQueryData(yr([n])),e.queryClient.ensureQueryData(br),e.queryClient.ensureQueryData(Qn)])},head:({params:e})=>({meta:[{title:`${decodeURIComponent(e.id)} | Load Balancer | Mulga`}]}),component:R(()=>z(()=>import(`./_id4.js`),__vite__mapDeps([110,1,3,4,18,2,5,6,19,60,23,40,70,75,8,9,55,10,11,56,12,25,26,44,27,105,15,13,36,22,41,42,24,63,82,99,29,30,64])),`component`)}),bd=L(`/_auth/ec2/(key)/describe-key-pairs/$id`)({loader:async({context:e,params:t})=>await e.queryClient.ensureQueryData(pr(t.id)),head:({loaderData:e})=>({meta:[{title:`${e?.KeyPairs?.[0]?.KeyName??`Key Pair`} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id3.js`),__vite__mapDeps([111,1,3,4,54,2,5,18,6,19,23,40,8,9,36,22,41,25,42,24,26,63,82,75,99,29])),`component`)}),xd=L(`/_auth/ec2/(instances)/describe-instances/$id`)({loader:async({context:e,params:t})=>{let[n]=await Promise.all([e.queryClient.ensureQueryData(or(t.id)),e.queryClient.ensureQueryData($n)]),r=n.Reservations?.[0]?.Instances?.[0]?.ImageId;return await e.queryClient.ensureQueryData(lr(r)),n},head:({loaderData:e})=>({meta:[{title:`${e?.Reservations?.[0]?.Instances?.[0]?.InstanceId??`Instance`} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id2.js`),__vite__mapDeps([112,1,3,4,54,2,5,18,6,19,23,40,75,8,9,55,10,11,56,12,25,26,44,27,36,22,24,42,63,82,99,29,30,15,52,113])),`component`)}),Sd=L(`/_auth/ec2/(images)/describe-images/$id`)({loader:async({context:e,params:t})=>await e.queryClient.ensureQueryData(lr(t.id)),head:({loaderData:e})=>({meta:[{title:`${e?.Images?.[0]?.Name??`Image`} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id.js`),__vite__mapDeps([114,1,18,2,3,4,5,6,19,36,22,23,42,24,25,26,29,30,72,113,99])),`component`)}),Cd=ku.update({id:`/login`,path:`/login`,getParentRoute:()=>Ou}),$=Au.update({id:`/_auth`,getParentRoute:()=>Ou}),wd=ju.update({id:`/`,path:`/`,getParentRoute:()=>$}),Td=Mu.update({id:`/nodes`,path:`/nodes`,getParentRoute:()=>$}),Ed=Nu.update({id:`/s3/service-metrics`,path:`/s3/service-metrics`,getParentRoute:()=>$}),Dd=Pu.update({id:`/s3/ls/`,path:`/s3/ls/`,getParentRoute:()=>$}),Od=Fu.update({id:`/s3/(buckets)/create-bucket`,path:`/s3/create-bucket`,getParentRoute:()=>$}),kd=Iu.update({id:`/iam/(users)/create-user`,path:`/iam/create-user`,getParentRoute:()=>$}),Ad=Lu.update({id:`/iam/(policies)/create-policy`,path:`/iam/create-policy`,getParentRoute:()=>$}),jd=Ru.update({id:`/ec2/(vpc)/create-vpc`,path:`/ec2/create-vpc`,getParentRoute:()=>$}),Md=zu.update({id:`/ec2/(volumes)/create-volume`,path:`/ec2/create-volume`,getParentRoute:()=>$}),Nd=Bu.update({id:`/ec2/(target-groups)/create-target-group`,path:`/ec2/create-target-group`,getParentRoute:()=>$}),Pd=Vu.update({id:`/ec2/(subnet)/create-subnet`,path:`/ec2/create-subnet`,getParentRoute:()=>$}),Fd=Hu.update({id:`/ec2/(snapshots)/create-snapshot`,path:`/ec2/create-snapshot`,getParentRoute:()=>$}),Id=Uu.update({id:`/ec2/(security-groups)/create-security-group`,path:`/ec2/create-security-group`,getParentRoute:()=>$}),Ld=Wu.update({id:`/ec2/(placement-groups)/create-placement-group`,path:`/ec2/create-placement-group`,getParentRoute:()=>$}),Rd=Z.update({id:`/ec2/(load-balancers)/create-load-balancer`,path:`/ec2/create-load-balancer`,getParentRoute:()=>$}),zd=Gu.update({id:`/ec2/(key)/import-key-pair`,path:`/ec2/import-key-pair`,getParentRoute:()=>$}),Bd=Ku.update({id:`/ec2/(key)/create-key-pair`,path:`/ec2/create-key-pair`,getParentRoute:()=>$}),Vd=qu.update({id:`/ec2/(instances)/run-instances`,path:`/ec2/run-instances`,getParentRoute:()=>$}),Hd=Ju.update({id:`/s3/ls/$bucket`,path:`/s3/ls/$bucket`,getParentRoute:()=>$}),Ud=Yu.update({id:`/`,path:`/`,getParentRoute:()=>Hd}),Wd=Xu.update({id:`/iam/(users)/list-users/`,path:`/iam/list-users/`,getParentRoute:()=>$}),Gd=Zu.update({id:`/iam/(policies)/list-policies/`,path:`/iam/list-policies/`,getParentRoute:()=>$}),Kd=Qu.update({id:`/ec2/(vpc)/describe-vpcs/`,path:`/ec2/describe-vpcs/`,getParentRoute:()=>$}),qd=$u.update({id:`/ec2/(volumes)/describe-volumes/`,path:`/ec2/describe-volumes/`,getParentRoute:()=>$}),Jd=ed.update({id:`/ec2/(target-groups)/describe-target-groups/`,path:`/ec2/describe-target-groups/`,getParentRoute:()=>$}),Yd=td.update({id:`/ec2/(subnet)/describe-subnets/`,path:`/ec2/describe-subnets/`,getParentRoute:()=>$}),Xd=nd.update({id:`/ec2/(snapshots)/describe-snapshots/`,path:`/ec2/describe-snapshots/`,getParentRoute:()=>$}),Zd=rd.update({id:`/ec2/(security-groups)/describe-security-groups/`,path:`/ec2/describe-security-groups/`,getParentRoute:()=>$}),Qd=id.update({id:`/ec2/(placement-groups)/describe-placement-groups/`,path:`/ec2/describe-placement-groups/`,getParentRoute:()=>$}),$d=ad.update({id:`/ec2/(load-balancers)/describe-load-balancers/`,path:`/ec2/describe-load-balancers/`,getParentRoute:()=>$}),ef=od.update({id:`/ec2/(key)/describe-key-pairs/`,path:`/ec2/describe-key-pairs/`,getParentRoute:()=>$}),tf=sd.update({id:`/ec2/(instances)/describe-instances/`,path:`/ec2/describe-instances/`,getParentRoute:()=>$}),nf=cd.update({id:`/ec2/(images)/describe-images/`,path:`/ec2/describe-images/`,getParentRoute:()=>$}),rf=ld.update({id:`/$`,path:`/$`,getParentRoute:()=>Hd}),af=ud.update({id:`/iam/(users)/list-users/$userName`,path:`/iam/list-users/$userName`,getParentRoute:()=>$}),of=dd.update({id:`/iam/(policies)/list-policies/$policyArn`,path:`/iam/list-policies/$policyArn`,getParentRoute:()=>$}),sf=fd.update({id:`/ec2/(vpc)/describe-vpcs/$id`,path:`/ec2/describe-vpcs/$id`,getParentRoute:()=>$}),cf=pd.update({id:`/ec2/(volumes)/modify-volume/$id`,path:`/ec2/modify-volume/$id`,getParentRoute:()=>$}),lf=md.update({id:`/ec2/(volumes)/describe-volumes/$id`,path:`/ec2/describe-volumes/$id`,getParentRoute:()=>$}),uf=hd.update({id:`/ec2/(target-groups)/describe-target-groups/$id`,path:`/ec2/describe-target-groups/$id`,getParentRoute:()=>$}),df=gd.update({id:`/ec2/(subnet)/describe-subnets/$id`,path:`/ec2/describe-subnets/$id`,getParentRoute:()=>$}),ff=_d.update({id:`/ec2/(snapshots)/describe-snapshots/$id`,path:`/ec2/describe-snapshots/$id`,getParentRoute:()=>$}),pf=vd.update({id:`/ec2/(security-groups)/describe-security-groups/$id`,path:`/ec2/describe-security-groups/$id`,getParentRoute:()=>$}),mf=yd.update({id:`/ec2/(placement-groups)/describe-placement-groups/$id`,path:`/ec2/describe-placement-groups/$id`,getParentRoute:()=>$}),hf=Q.update({id:`/ec2/(load-balancers)/describe-load-balancers/$id`,path:`/ec2/describe-load-balancers/$id`,getParentRoute:()=>$}),gf=bd.update({id:`/ec2/(key)/describe-key-pairs/$id`,path:`/ec2/describe-key-pairs/$id`,getParentRoute:()=>$}),_f=xd.update({id:`/ec2/(instances)/describe-instances/$id`,path:`/ec2/describe-instances/$id`,getParentRoute:()=>$}),vf=Sd.update({id:`/ec2/(images)/describe-images/$id`,path:`/ec2/describe-images/$id`,getParentRoute:()=>$}),yf={AuthS3LsBucketSplatRoute:rf,AuthS3LsBucketIndexRoute:Ud},bf={AuthNodesRoute:Td,AuthIndexRoute:wd,AuthS3ServiceMetricsRoute:Ed,AuthS3LsBucketRouteRoute:Hd._addFileChildren(yf),AuthEc2instancesRunInstancesRoute:Vd,AuthEc2keyCreateKeyPairRoute:Bd,AuthEc2keyImportKeyPairRoute:zd,AuthEc2loadBalancersCreateLoadBalancerRoute:Rd,AuthEc2placementGroupsCreatePlacementGroupRoute:Ld,AuthEc2securityGroupsCreateSecurityGroupRoute:Id,AuthEc2snapshotsCreateSnapshotRoute:Fd,AuthEc2subnetCreateSubnetRoute:Pd,AuthEc2targetGroupsCreateTargetGroupRoute:Nd,AuthEc2volumesCreateVolumeRoute:Md,AuthEc2vpcCreateVpcRoute:jd,AuthIampoliciesCreatePolicyRoute:Ad,AuthIamusersCreateUserRoute:kd,AuthS3bucketsCreateBucketRoute:Od,AuthS3LsIndexRoute:Dd,AuthEc2imagesDescribeImagesIdRoute:vf,AuthEc2instancesDescribeInstancesIdRoute:_f,AuthEc2keyDescribeKeyPairsIdRoute:gf,AuthEc2loadBalancersDescribeLoadBalancersIdRoute:hf,AuthEc2placementGroupsDescribePlacementGroupsIdRoute:mf,AuthEc2securityGroupsDescribeSecurityGroupsIdRoute:pf,AuthEc2snapshotsDescribeSnapshotsIdRoute:ff,AuthEc2subnetDescribeSubnetsIdRoute:df,AuthEc2targetGroupsDescribeTargetGroupsIdRoute:uf,AuthEc2volumesDescribeVolumesIdRoute:lf,AuthEc2volumesModifyVolumeIdRoute:cf,AuthEc2vpcDescribeVpcsIdRoute:sf,AuthIampoliciesListPoliciesPolicyArnRoute:of,AuthIamusersListUsersUserNameRoute:af,AuthEc2imagesDescribeImagesIndexRoute:nf,AuthEc2instancesDescribeInstancesIndexRoute:tf,AuthEc2keyDescribeKeyPairsIndexRoute:ef,AuthEc2loadBalancersDescribeLoadBalancersIndexRoute:$d,AuthEc2placementGroupsDescribePlacementGroupsIndexRoute:Qd,AuthEc2securityGroupsDescribeSecurityGroupsIndexRoute:Zd,AuthEc2snapshotsDescribeSnapshotsIndexRoute:Xd,AuthEc2subnetDescribeSubnetsIndexRoute:Yd,AuthEc2targetGroupsDescribeTargetGroupsIndexRoute:Jd,AuthEc2volumesDescribeVolumesIndexRoute:qd,AuthEc2vpcDescribeVpcsIndexRoute:Kd,AuthIampoliciesListPoliciesIndexRoute:Gd,AuthIamusersListUsersIndexRoute:Wd},xf={AuthRouteRoute:$._addFileChildren(bf),LoginRoute:Cd},Sf=Ou._addFileChildren(xf)._addFileTypes(),Cf=new Jr({defaultOptions:{queries:{staleTime:5e3}}}),wf=Ka({routeTree:Sf,context:{queryClient:Cf},defaultPreload:`intent`,scrollRestoration:!0,defaultStructuralSharing:!0,defaultPreloadStaleTime:0}),Tf=document.querySelector(`#app`);Tf&&!Tf.innerHTML&&ao.createRoot(Tf).render((0,G.jsx)(W.StrictMode,{children:(0,G.jsx)(so,{defaultTheme:`dark`,storageKey:`spinifex-ui-theme`,children:(0,G.jsx)(D,{client:Cf,children:(0,G.jsx)(bu,{children:(0,G.jsx)($l,{children:(0,G.jsx)(Ya,{router:wf})})})})})}));export{gc as A,Eo as B,Cl as C,Kc as D,Jc as E,Io as F,lo as G,yo as H,Lo as I,Br as J,Va as K,Fo as L,Vo as M,Bo as N,Gc as O,zo as P,Mo as R,jl as S,Xc as T,go as U,wo as V,po as W,Hu as _,yd as a,Pl as b,gd as c,pd as d,fd as f,Yu as g,ld as h,Q as i,Rs as j,Wc as k,hd as l,ud as m,xd as n,vd as o,dd as p,Wr as q,bd as r,_d as s,Sd as t,md as u,xu as v,Qc as w,Nl as x,_u as y,Oo as z}; \ No newline at end of file +`).replace(kd,``)}function jd(e,t){return t=Ad(t),Ad(e)===t}function Md(e,t,n,r,i,o){switch(n){case`children`:typeof r==`string`?t===`body`||t===`textarea`&&r===``||Vt(e,r):(typeof r==`number`||typeof r==`bigint`)&&t!==`body`&&Vt(e,``+r);break;case`className`:Tt(e,`class`,r);break;case`tabIndex`:Tt(e,`tabindex`,r);break;case`dir`:case`role`:case`viewBox`:case`width`:case`height`:Tt(e,n,r);break;case`style`:Ut(e,r,o);break;case`data`:if(t!==`object`){Tt(e,`data`,r);break}case`src`:case`href`:if(r===``&&(t!==`a`||n!==`href`)){e.removeAttribute(n);break}if(r==null||typeof r==`function`||typeof r==`symbol`||typeof r==`boolean`){e.removeAttribute(n);break}r=qt(``+r),e.setAttribute(n,r);break;case`action`:case`formAction`:if(typeof r==`function`){e.setAttribute(n,`javascript:throw new Error('A React form was unexpectedly submitted. If you called form.submit() manually, consider using form.requestSubmit() instead. If you\\'re trying to use event.stopPropagation() in a submit event handler, consider also calling event.preventDefault().')`);break}else typeof o==`function`&&(n===`formAction`?(t!==`input`&&Md(e,t,`name`,i.name,i,null),Md(e,t,`formEncType`,i.formEncType,i,null),Md(e,t,`formMethod`,i.formMethod,i,null),Md(e,t,`formTarget`,i.formTarget,i,null)):(Md(e,t,`encType`,i.encType,i,null),Md(e,t,`method`,i.method,i,null),Md(e,t,`target`,i.target,i,null)));if(r==null||typeof r==`symbol`||typeof r==`boolean`){e.removeAttribute(n);break}r=qt(``+r),e.setAttribute(n,r);break;case`onClick`:r!=null&&(e.onclick=Jt);break;case`onScroll`:r!=null&&Q(`scroll`,e);break;case`onScrollEnd`:r!=null&&Q(`scrollend`,e);break;case`dangerouslySetInnerHTML`:if(r!=null){if(typeof r!=`object`||!(`__html`in r))throw Error(a(61));if(n=r.__html,n!=null){if(i.children!=null)throw Error(a(60));e.innerHTML=n}}break;case`multiple`:e.multiple=r&&typeof r!=`function`&&typeof r!=`symbol`;break;case`muted`:e.muted=r&&typeof r!=`function`&&typeof r!=`symbol`;break;case`suppressContentEditableWarning`:case`suppressHydrationWarning`:case`defaultValue`:case`defaultChecked`:case`innerHTML`:case`ref`:break;case`autoFocus`:break;case`xlinkHref`:if(r==null||typeof r==`function`||typeof r==`boolean`||typeof r==`symbol`){e.removeAttribute(`xlink:href`);break}n=qt(``+r),e.setAttributeNS(`http://www.w3.org/1999/xlink`,`xlink:href`,n);break;case`contentEditable`:case`spellCheck`:case`draggable`:case`value`:case`autoReverse`:case`externalResourcesRequired`:case`focusable`:case`preserveAlpha`:r!=null&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,``+r):e.removeAttribute(n);break;case`inert`:case`allowFullScreen`:case`async`:case`autoPlay`:case`controls`:case`default`:case`defer`:case`disabled`:case`disablePictureInPicture`:case`disableRemotePlayback`:case`formNoValidate`:case`hidden`:case`loop`:case`noModule`:case`noValidate`:case`open`:case`playsInline`:case`readOnly`:case`required`:case`reversed`:case`scoped`:case`seamless`:case`itemScope`:r&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,``):e.removeAttribute(n);break;case`capture`:case`download`:!0===r?e.setAttribute(n,``):!1!==r&&r!=null&&typeof r!=`function`&&typeof r!=`symbol`?e.setAttribute(n,r):e.removeAttribute(n);break;case`cols`:case`rows`:case`size`:case`span`:r!=null&&typeof r!=`function`&&typeof r!=`symbol`&&!isNaN(r)&&1<=r?e.setAttribute(n,r):e.removeAttribute(n);break;case`rowSpan`:case`start`:r==null||typeof r==`function`||typeof r==`symbol`||isNaN(r)?e.removeAttribute(n):e.setAttribute(n,r);break;case`popover`:Q(`beforetoggle`,e),Q(`toggle`,e),wt(e,`popover`,r);break;case`xlinkActuate`:Et(e,`http://www.w3.org/1999/xlink`,`xlink:actuate`,r);break;case`xlinkArcrole`:Et(e,`http://www.w3.org/1999/xlink`,`xlink:arcrole`,r);break;case`xlinkRole`:Et(e,`http://www.w3.org/1999/xlink`,`xlink:role`,r);break;case`xlinkShow`:Et(e,`http://www.w3.org/1999/xlink`,`xlink:show`,r);break;case`xlinkTitle`:Et(e,`http://www.w3.org/1999/xlink`,`xlink:title`,r);break;case`xlinkType`:Et(e,`http://www.w3.org/1999/xlink`,`xlink:type`,r);break;case`xmlBase`:Et(e,`http://www.w3.org/XML/1998/namespace`,`xml:base`,r);break;case`xmlLang`:Et(e,`http://www.w3.org/XML/1998/namespace`,`xml:lang`,r);break;case`xmlSpace`:Et(e,`http://www.w3.org/XML/1998/namespace`,`xml:space`,r);break;case`is`:wt(e,`is`,r);break;case`innerText`:case`textContent`:break;default:(!(2s)break;var u=c.transferSize,d=c.initiatorType;u&&Id(d)&&(c=c.responseEnd,o+=u*(c`u`?null:document;function xf(e,t,n){var r=bf;if(r&&typeof t==`string`&&t){var i=Pt(t);i=`link[rel="`+e+`"][href="`+i+`"]`,typeof n==`string`&&(i+=`[crossorigin="`+n+`"]`),hf.has(i)||(hf.add(i),e={rel:e,crossOrigin:n,href:t},r.querySelector(i)===null&&(t=r.createElement(`link`),Pd(t,`link`,e),gt(t),r.head.appendChild(t)))}}function Sf(e){_f.D(e),xf(`dns-prefetch`,e,null)}function Cf(e,t){_f.C(e,t),xf(`preconnect`,e,t)}function wf(e,t,n){_f.L(e,t,n);var r=bf;if(r&&e&&t){var i=`link[rel="preload"][as="`+Pt(t)+`"]`;t===`image`&&n&&n.imageSrcSet?(i+=`[imagesrcset="`+Pt(n.imageSrcSet)+`"]`,typeof n.imageSizes==`string`&&(i+=`[imagesizes="`+Pt(n.imageSizes)+`"]`)):i+=`[href="`+Pt(e)+`"]`;var a=i;switch(t){case`style`:a=Af(e);break;case`script`:a=Pf(e)}mf.has(a)||(e=p({rel:`preload`,href:t===`image`&&n&&n.imageSrcSet?void 0:e,as:t},n),mf.set(a,e),r.querySelector(i)!==null||t===`style`&&r.querySelector(jf(a))||t===`script`&&r.querySelector(Ff(a))||(t=r.createElement(`link`),Pd(t,`link`,e),gt(t),r.head.appendChild(t)))}}function Tf(e,t){_f.m(e,t);var n=bf;if(n&&e){var r=t&&typeof t.as==`string`?t.as:`script`,i=`link[rel="modulepreload"][as="`+Pt(r)+`"][href="`+Pt(e)+`"]`,a=i;switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:a=Pf(e)}if(!mf.has(a)&&(e=p({rel:`modulepreload`,href:e},t),mf.set(a,e),n.querySelector(i)===null)){switch(r){case`audioworklet`:case`paintworklet`:case`serviceworker`:case`sharedworker`:case`worker`:case`script`:if(n.querySelector(Ff(a)))return}r=n.createElement(`link`),Pd(r,`link`,e),gt(r),n.head.appendChild(r)}}}function Ef(e,t,n){_f.S(e,t,n);var r=bf;if(r&&e){var i=ht(r).hoistableStyles,a=Af(e);t||=`default`;var o=i.get(a);if(!o){var s={loading:0,preload:null};if(o=r.querySelector(jf(a)))s.loading=5;else{e=p({rel:`stylesheet`,href:e,"data-precedence":t},n),(n=mf.get(a))&&Rf(e,n);var c=o=r.createElement(`link`);gt(c),Pd(c,`link`,e),c._p=new Promise(function(e,t){c.onload=e,c.onerror=t}),c.addEventListener(`load`,function(){s.loading|=1}),c.addEventListener(`error`,function(){s.loading|=2}),s.loading|=4,Lf(o,t,r)}o={type:`stylesheet`,instance:o,count:1,state:s},i.set(a,o)}}}function Df(e,t){_f.X(e,t);var n=bf;if(n&&e){var r=ht(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=p({src:e,async:!0},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),gt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function Of(e,t){_f.M(e,t);var n=bf;if(n&&e){var r=ht(n).hoistableScripts,i=Pf(e),a=r.get(i);a||(a=n.querySelector(Ff(i)),a||(e=p({src:e,async:!0,type:`module`},t),(t=mf.get(i))&&zf(e,t),a=n.createElement(`script`),gt(a),Pd(a,`link`,e),n.head.appendChild(a)),a={type:`script`,instance:a,count:1,state:null},r.set(i,a))}}function kf(e,t,n,r){var i=(i=le.current)?gf(i):null;if(!i)throw Error(a(446));switch(e){case`meta`:case`title`:return null;case`style`:return typeof n.precedence==`string`&&typeof n.href==`string`?(t=Af(n.href),n=ht(i).hoistableStyles,r=n.get(t),r||(r={type:`style`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};case`link`:if(n.rel===`stylesheet`&&typeof n.href==`string`&&typeof n.precedence==`string`){e=Af(n.href);var o=ht(i).hoistableStyles,s=o.get(e);if(s||(i=i.ownerDocument||i,s={type:`stylesheet`,instance:null,count:0,state:{loading:0,preload:null}},o.set(e,s),(o=i.querySelector(jf(e)))&&!o._p&&(s.instance=o,s.state.loading=5),mf.has(e)||(n={rel:`preload`,as:`style`,href:n.href,crossOrigin:n.crossOrigin,integrity:n.integrity,media:n.media,hrefLang:n.hrefLang,referrerPolicy:n.referrerPolicy},mf.set(e,n),o||Nf(i,e,n,s.state))),t&&r===null)throw Error(a(528,``));return s}if(t&&r!==null)throw Error(a(529,``));return null;case`script`:return t=n.async,n=n.src,typeof n==`string`&&t&&typeof t!=`function`&&typeof t!=`symbol`?(t=Pf(n),n=ht(i).hoistableScripts,r=n.get(t),r||(r={type:`script`,instance:null,count:0,state:null},n.set(t,r)),r):{type:`void`,instance:null,count:0,state:null};default:throw Error(a(444,e))}}function Af(e){return`href="`+Pt(e)+`"`}function jf(e){return`link[rel="stylesheet"][`+e+`]`}function Mf(e){return p({},e,{"data-precedence":e.precedence,precedence:null})}function Nf(e,t,n,r){e.querySelector(`link[rel="preload"][as="style"][`+t+`]`)?r.loading=1:(t=e.createElement(`link`),r.preload=t,t.addEventListener(`load`,function(){return r.loading|=1}),t.addEventListener(`error`,function(){return r.loading|=2}),Pd(t,`link`,n),gt(t),e.head.appendChild(t))}function Pf(e){return`[src="`+Pt(e)+`"]`}function Ff(e){return`script[async]`+e}function If(e,t,n){if(t.count++,t.instance===null)switch(t.type){case`style`:var r=e.querySelector(`style[data-href~="`+Pt(n.href)+`"]`);if(r)return t.instance=r,gt(r),r;var i=p({},n,{"data-href":n.href,"data-precedence":n.precedence,href:null,precedence:null});return r=(e.ownerDocument||e).createElement(`style`),gt(r),Pd(r,`style`,i),Lf(r,n.precedence,e),t.instance=r;case`stylesheet`:i=Af(n.href);var o=e.querySelector(jf(i));if(o)return t.state.loading|=4,t.instance=o,gt(o),o;r=Mf(n),(i=mf.get(i))&&Rf(r,i),o=(e.ownerDocument||e).createElement(`link`),gt(o);var s=o;return s._p=new Promise(function(e,t){s.onload=e,s.onerror=t}),Pd(o,`link`,r),t.state.loading|=4,Lf(o,n.precedence,e),t.instance=o;case`script`:return o=Pf(n.src),(i=e.querySelector(Ff(o)))?(t.instance=i,gt(i),i):(r=n,(i=mf.get(o))&&(r=p({},n),zf(r,i)),e=e.ownerDocument||e,i=e.createElement(`script`),gt(i),Pd(i,`link`,r),e.head.appendChild(i),t.instance=i);case`void`:return null;default:throw Error(a(443,t.type))}else t.type===`stylesheet`&&!(t.state.loading&4)&&(r=t.instance,t.state.loading|=4,Lf(r,n.precedence,e));return t.instance}function Lf(e,t,n){for(var r=n.querySelectorAll(`link[rel="stylesheet"][data-precedence],style[data-precedence]`),i=r.length?r[r.length-1]:null,a=i,o=0;o title`):null)}function Uf(e,t,n){if(n===1||t.itemProp!=null)return!1;switch(e){case`meta`:case`title`:return!0;case`style`:if(typeof t.precedence!=`string`||typeof t.href!=`string`||t.href===``)break;return!0;case`link`:if(typeof t.rel!=`string`||typeof t.href!=`string`||t.href===``||t.onLoad||t.onError)break;switch(t.rel){case`stylesheet`:return e=t.disabled,typeof t.precedence==`string`&&e==null;default:return!0}case`script`:if(t.async&&typeof t.async!=`function`&&typeof t.async!=`symbol`&&!t.onLoad&&!t.onError&&t.src&&typeof t.src==`string`)return!0}return!1}function Wf(e){return!(e.type===`stylesheet`&&!(e.state.loading&3))}function Gf(e,t,n,r){if(n.type===`stylesheet`&&(typeof r.media!=`string`||!1!==matchMedia(r.media).matches)&&!(n.state.loading&4)){if(n.instance===null){var i=Af(r.href),a=t.querySelector(jf(i));if(a){t=a._p,typeof t==`object`&&t&&typeof t.then==`function`&&(e.count++,e=Jf.bind(e),t.then(e,e)),n.state.loading|=4,n.instance=a,gt(a);return}a=t.ownerDocument||t,r=Mf(r),(i=mf.get(i))&&Rf(r,i),a=a.createElement(`link`),gt(a);var o=a;o._p=new Promise(function(e,t){o.onload=e,o.onerror=t}),Pd(a,`link`,r),n.instance=a}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(n,t),(t=n.state.preload)&&!(n.state.loading&3)&&(e.count++,n=Jf.bind(e),t.addEventListener(`load`,n),t.addEventListener(`error`,n))}}var Kf=0;function qf(e,t){return e.stylesheets&&e.count===0&&Xf(e,e.stylesheets),0Kf?50:800)+t);return e.unsuspend=n,function(){e.unsuspend=null,clearTimeout(r),clearTimeout(i)}}:null}function Jf(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)Xf(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Yf=null;function Xf(e,t){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Yf=new Map,t.forEach(Zf,e),Yf=null,Jf.call(e))}function Zf(e,t){if(!(t.state.loading&4)){var n=Yf.get(e);if(n)var r=n.get(null);else{n=new Map,Yf.set(e,n);for(var i=e.querySelectorAll(`link[data-precedence],style[data-precedence]`),a=0;a{function n(){if(!(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>`u`||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=`function`))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(e){console.error(e)}}n(),t.exports=io()}))(),1),K=i(),q=(0,W.createContext)(void 0);function oo(e,t){try{let t=localStorage.getItem(e);if(t===`light`||t===`dark`||t===`system`)return t}catch{}return t}function so(e){let t=(0,K.c)(14),{children:n,defaultTheme:r,storageKey:i}=e,a=r===void 0?`dark`:r,o=i===void 0?`ui-theme`:i,s;t[0]!==a||t[1]!==o?(s=()=>oo(o,a),t[0]=a,t[1]=o,t[2]=s):s=t[2];let[c,l]=(0,W.useState)(s),u,d;t[3]===c?(u=t[4],d=t[5]):(u=()=>{let e=window.document.documentElement;if(e.classList.remove(`light`,`dark`),c===`system`){let t=window.matchMedia(`(prefers-color-scheme: dark)`).matches?`dark`:`light`;e.classList.add(t);return}e.classList.add(c)},d=[c],t[3]=c,t[4]=u,t[5]=d),(0,W.useEffect)(u,d);let f;t[6]===o?f=t[7]:(f=e=>{try{localStorage.setItem(o,e)}catch{}l(e)},t[6]=o,t[7]=f);let p;t[8]!==f||t[9]!==c?(p={theme:c,setTheme:f},t[8]=f,t[9]=c,t[10]=p):p=t[10];let m=p,h;return t[11]!==n||t[12]!==m?(h=(0,G.jsx)(q.Provider,{value:m,children:n}),t[11]=n,t[12]=m,t[13]=h):h=t[13],h}function co(){let e=(0,W.useContext)(q);if(e===void 0)throw Error(`useTheme must be used within a ThemeProvider`);return e}function lo(e){return Ge(e.defaultTagName??`div`,e,e)}var uo=et(`activity`,[[`path`,{d:`M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2`,key:`169zse`}]]),fo=et(`book-open`,[[`path`,{d:`M12 7v14`,key:`1akyts`}],[`path`,{d:`M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z`,key:`ruj8y`}]]),po=et(`camera`,[[`path`,{d:`M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z`,key:`18u6gg`}],[`circle`,{cx:`12`,cy:`13`,r:`3`,key:`1vg3eu`}]]),mo=et(`circle-alert`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`12`,x2:`12`,y1:`8`,y2:`12`,key:`1pkeuh`}],[`line`,{x1:`12`,x2:`12.01`,y1:`16`,y2:`16`,key:`4dfq90`}]]),ho=et(`crosshair`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`22`,x2:`18`,y1:`12`,y2:`12`,key:`l9bcsi`}],[`line`,{x1:`6`,x2:`2`,y1:`12`,y2:`12`,key:`13hhkx`}],[`line`,{x1:`12`,x2:`12`,y1:`6`,y2:`2`,key:`10w3f3`}],[`line`,{x1:`12`,x2:`12`,y1:`22`,y2:`18`,key:`15g9kq`}]]),go=et(`hard-drive`,[[`path`,{d:`M10 16h.01`,key:`1bzywj`}],[`path`,{d:`M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z`,key:`18tbho`}],[`path`,{d:`M21.946 12.013H2.054`,key:`zqlbp7`}],[`path`,{d:`M6 16h.01`,key:`1pmjb7`}]]),_o=et(`house`,[[`path`,{d:`M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8`,key:`5wwlr5`}],[`path`,{d:`M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z`,key:`r6nss1`}]]),vo=et(`image`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,ry:`2`,key:`1m3agn`}],[`circle`,{cx:`9`,cy:`9`,r:`2`,key:`af1f0g`}],[`path`,{d:`m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21`,key:`1xmnt7`}]]),yo=et(`key`,[[`path`,{d:`m15.5 7.5 2.3 2.3a1 1 0 0 0 1.4 0l2.1-2.1a1 1 0 0 0 0-1.4L19 4`,key:`g0fldk`}],[`path`,{d:`m21 2-9.6 9.6`,key:`1j0ho8`}],[`circle`,{cx:`7.5`,cy:`15.5`,r:`5.5`,key:`yqb3hr`}]]),bo=et(`layers`,[[`path`,{d:`M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z`,key:`zw3jo`}],[`path`,{d:`M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12`,key:`1wduqc`}],[`path`,{d:`M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17`,key:`kqbvx6`}]]),xo=et(`layout-grid`,[[`rect`,{width:`7`,height:`7`,x:`3`,y:`3`,rx:`1`,key:`1g98yp`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`3`,rx:`1`,key:`6d4xhi`}],[`rect`,{width:`7`,height:`7`,x:`14`,y:`14`,rx:`1`,key:`nxv5o0`}],[`rect`,{width:`7`,height:`7`,x:`3`,y:`14`,rx:`1`,key:`1bb6yr`}]]),So=et(`log-out`,[[`path`,{d:`m16 17 5-5-5-5`,key:`1bji2h`}],[`path`,{d:`M21 12H9`,key:`dn1m92`}],[`path`,{d:`M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4`,key:`1uf3rs`}]]),Co=et(`moon`,[[`path`,{d:`M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401`,key:`kfwtm`}]]),wo=et(`network`,[[`rect`,{x:`16`,y:`16`,width:`6`,height:`6`,rx:`1`,key:`4q2zg0`}],[`rect`,{x:`2`,y:`16`,width:`6`,height:`6`,rx:`1`,key:`8cvhb9`}],[`rect`,{x:`9`,y:`2`,width:`6`,height:`6`,rx:`1`,key:`1egb70`}],[`path`,{d:`M5 16v-3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v3`,key:`1jsf9p`}],[`path`,{d:`M12 12V8`,key:`2874zd`}]]),To=et(`panel-left`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M9 3v18`,key:`fh3hqa`}]]),Eo=et(`server`,[[`rect`,{width:`20`,height:`8`,x:`2`,y:`2`,rx:`2`,ry:`2`,key:`ngkwjq`}],[`rect`,{width:`20`,height:`8`,x:`2`,y:`14`,rx:`2`,ry:`2`,key:`iecqi9`}],[`line`,{x1:`6`,x2:`6.01`,y1:`6`,y2:`6`,key:`16zg32`}],[`line`,{x1:`6`,x2:`6.01`,y1:`18`,y2:`18`,key:`nzw8ys`}]]),Do=et(`shield-check`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}],[`path`,{d:`m9 12 2 2 4-4`,key:`dzmm74`}]]),Oo=et(`shield`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}]]),ko=et(`sun`,[[`circle`,{cx:`12`,cy:`12`,r:`4`,key:`4exip2`}],[`path`,{d:`M12 2v2`,key:`tus03m`}],[`path`,{d:`M12 20v2`,key:`1lh1kg`}],[`path`,{d:`m4.93 4.93 1.41 1.41`,key:`149t6j`}],[`path`,{d:`m17.66 17.66 1.41 1.41`,key:`ptbguv`}],[`path`,{d:`M2 12h2`,key:`1t8f8n`}],[`path`,{d:`M20 12h2`,key:`1q8mjw`}],[`path`,{d:`m6.34 17.66-1.41 1.41`,key:`1m8zz5`}],[`path`,{d:`m19.07 4.93-1.41 1.41`,key:`1shlcs`}]]),Ao=et(`users`,[[`path`,{d:`M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2`,key:`1yyitq`}],[`path`,{d:`M16 3.128a4 4 0 0 1 0 7.744`,key:`16gr8j`}],[`path`,{d:`M22 21v-2a4 4 0 0 0-3-3.87`,key:`kshegd`}],[`circle`,{cx:`9`,cy:`7`,r:`4`,key:`nufk8`}]]),jo=et(`waypoints`,[[`path`,{d:`m10.586 5.414-5.172 5.172`,key:`4mc350`}],[`path`,{d:`m18.586 13.414-5.172 5.172`,key:`8c96vv`}],[`path`,{d:`M6 12h12`,key:`8npq4p`}],[`circle`,{cx:`12`,cy:`20`,r:`2`,key:`144qzu`}],[`circle`,{cx:`12`,cy:`4`,r:`2`,key:`muu5ef`}],[`circle`,{cx:`20`,cy:`12`,r:`2`,key:`1xzzfp`}],[`circle`,{cx:`4`,cy:`12`,r:`2`,key:`1hvhnz`}]]),Mo=et(`x`,[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]),No=W.forwardRef(function(e,t){let{render:n,className:r,id:i,name:a,value:o,disabled:s=!1,onValueChange:c,defaultValue:l,autoFocus:u=!1,style:d,...f}=e,{state:p,name:m,disabled:h,setTouched:g,setDirty:_,validityData:v,setFocused:y,setFilled:b,validationMode:x,validation:S}=Tt(),C=h||s,w=m??a,T={...p,disabled:C},{labelId:E}=St(),D=Ct({id:i});ht(()=>{let e=o!=null;S.inputRef.current?.value||e&&o!==``?b(!0):e&&o===``&&b(!1)},[S.inputRef,b,o]);let O=W.useRef(null);ht(()=>{u&&O.current===Mt(Vt(O.current))&&y(!0)},[u,y]);let[k]=Et({controlled:o,default:l,name:`FieldControl`,state:`value`}),ee=o!==void 0,A=ee?k:void 0,j=st(()=>S.inputRef.current?.value);return wt(S.inputRef,{id:D,value:A,getValue:j}),Ge(`input`,e,{ref:[t,O],state:T,props:[{id:D,disabled:C,name:w,ref:S.inputRef,"aria-labelledby":E,autoFocus:u,...ee?{value:A}:{defaultValue:l},onChange(e){let t=e.currentTarget.value;c?.(t,Lt(Rt,e.nativeEvent)),_(t!==v.initialValue),b(t!==``)},onFocus(){y(!0)},onBlur(e){g(!0),y(!1),x===`onBlur`&&S.commit(e.currentTarget.value)},onKeyDown(e){e.currentTarget.tagName===`INPUT`&&e.key===`Enter`&&(g(!0),S.commit(e.currentTarget.value))}},S.getInputValidationProps(),f],stateAttributesMapping:Dt})}),Po=W.forwardRef(function(e,t){return(0,G.jsx)(No,{ref:t,...e})});function Fo(e){let t=(0,K.c)(10),n,r,i;t[0]===e?(n=t[1],r=t[2],i=t[3]):({className:n,type:i,...r}=e,t[0]=e,t[1]=n,t[2]=r,t[3]=i);let a;t[4]===n?a=t[5]:(a=B(`h-7 w-full min-w-0 rounded-md border border-input bg-input/20 px-2 py-0.5 text-sm transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-xs/relaxed file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/30 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-2 aria-invalid:ring-destructive/20 md:text-xs/relaxed dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40`,n),t[4]=n,t[5]=a);let o;return t[6]!==r||t[7]!==a||t[8]!==i?(o=(0,G.jsx)(Po,{className:a,"data-slot":`input`,type:i,...r}),t[6]=r,t[7]=a,t[8]=i,t[9]=o):o=t[9],o}var Io=W.createContext(void 0);function Lo(e){let t=W.useContext(Io);if(e===!1&&t===void 0)throw Error(We(27));return t}var Ro={...en,...Jn},zo=W.forwardRef(function(e,t){let{render:n,className:r,style:i,forceRender:a=!1,...o}=e,{store:s}=Lo(),c=s.useState(`open`),l=s.useState(`nested`),u=s.useState(`mounted`);return Ge(`div`,e,{state:{open:c,transitionStatus:s.useState(`transitionStatus`)},ref:[s.context.backdropRef,t],stateAttributesMapping:Ro,props:[{role:`presentation`,hidden:!u,style:{userSelect:`none`,WebkitUserSelect:`none`}},o],enabled:a||!l})}),Bo=W.forwardRef(function(e,t){let{render:n,className:r,disabled:i=!1,nativeButton:a=!0,style:o,...s}=e,{store:c}=Lo(),l=c.useState(`open`);function u(e){l&&c.setOpen(!1,Lt(Ft,e.nativeEvent))}let{getButtonProps:d,buttonRef:f}=_t({disabled:i,native:a});return Ge(`button`,e,{state:{disabled:i},ref:[t,f],props:[{onClick:u},s,d]})}),Vo=W.forwardRef(function(e,t){let{render:n,className:r,style:i,id:a,...o}=e,{store:s}=Lo(),c=At(a);return s.useSyncedValueWithCleanup(`descriptionElementId`,c),Ge(`p`,e,{ref:t,props:[{id:c},o]})});function Ho(e,t){return t!=null&&!Ht(t)?0:typeof e==`function`?e():e}function Uo(e,t,n){let r=Ho(e,n);return typeof r==`number`?r:r?.[t]}function Wo(e){return typeof e==`function`?e():e}function Go(e,t){return t||e===`click`||e===`mousedown`}var Ko=W.createContext({hasProvider:!1,timeoutMs:0,delayRef:{current:0},initialDelayRef:{current:0},timeout:new bn,currentIdRef:{current:null},currentContextRef:{current:null}});function qo(e){let{children:t,delay:n,timeoutMs:r=0}=e,i=W.useRef(n),a=W.useRef(n),o=W.useRef(null),s=W.useRef(null),c=fn();return(0,G.jsx)(Ko.Provider,{value:W.useMemo(()=>({hasProvider:!0,delayRef:i,initialDelayRef:a,currentIdRef:o,timeoutMs:r,currentContextRef:s,timeout:c}),[r,c]),children:t})}function Jo(e,t={open:!1}){let n=`rootStore`in e?e.rootStore:e,r=n.useState(`floatingId`),{open:i}=t,{currentIdRef:a,delayRef:o,timeoutMs:s,initialDelayRef:c,currentContextRef:l,hasProvider:u,timeout:d}=W.useContext(Ko),[f,p]=W.useState(!1);return ht(()=>{function e(){p(!1),l.current?.setIsInstantPhase(!1),a.current=null,l.current=null,o.current=c.current}if(a.current&&!i&&a.current===r){if(p(!1),s){let t=r;return d.start(s,()=>{n.select(`open`)||a.current&&a.current!==t||e()}),()=>{d.clear()}}e()}},[i,r,a,o,s,c,l,d,n]),ht(()=>{if(!i)return;let e=l.current,t=a.current;d.clear(),l.current={onOpenChange:n.setOpen,setIsInstantPhase:p},a.current=r,o.current={open:0,close:Uo(c.current,`close`)},t!==null&&t!==r?(p(!0),e?.setIsInstantPhase(!0),e?.onOpenChange(!1,Lt(Rt))):(p(!1),e?.setIsInstantPhase(!1))},[i,r,n,a,o,s,c,l,d]),ht(()=>()=>{l.current=null},[l]),W.useMemo(()=>({hasProvider:u,delayRef:o,isInstantPhase:f}),[u,o,f])}function Yo(e,t){let n=null,r=null,i=!1;return{contextElement:e||void 0,getBoundingClientRect(){let a=e?.getBoundingClientRect()||{width:0,height:0,x:0,y:0},o=t.axis===`x`||t.axis===`both`,s=t.axis===`y`||t.axis===`both`,c=[`mouseenter`,`mousemove`].includes(t.dataRef.current.openEvent?.type||``)&&t.pointerType!==`touch`,l=a.width,u=a.height,d=a.x,f=a.y;return n==null&&t.x&&o&&(n=a.x-t.x),r==null&&t.y&&s&&(r=a.y-t.y),d-=n||0,f-=r||0,l=0,u=0,!i||c?(l=t.axis===`y`?a.width:0,u=t.axis===`x`?a.height:0,d=o&&t.x!=null?t.x:d,f=s&&t.y!=null?t.y:f):i&&!c&&(u=t.axis===`x`?a.height:u,l=t.axis===`y`?a.width:l),i=!0,{width:l,height:u,x:d,y:f,top:f,right:d+l,bottom:f+u,left:d}}}}function Xo(e){return e!=null&&e.clientX!=null}function Zo(e,t={}){let n=`rootStore`in e?e.rootStore:e,r=n.useState(`open`),i=n.useState(`floatingElement`),a=n.useState(`domReferenceElement`),o=n.context.dataRef,{enabled:s=!0,axis:c=`both`}=t,l=W.useRef(!1),u=W.useRef(null),[d,f]=W.useState(),[p,m]=W.useState([]),h=st((e,t,r)=>{l.current||o.current.openEvent&&!Xo(o.current.openEvent)||n.set(`positionReference`,Yo(r??a,{x:e,y:t,axis:c,dataRef:o,pointerType:d}))}),g=st(e=>{r?u.current||m([]):h(e.clientX,e.clientY,e.currentTarget)}),_=Ht(d)?i:r,v=W.useCallback(()=>{if(!_||!s)return;let e=at(i);function t(e){kt(i,zt(e))?(u.current?.(),u.current=null):h(e.clientX,e.clientY)}if(!o.current.openEvent||Xo(o.current.openEvent))return u.current=Xn(e,`mousemove`,t),()=>{u.current?.(),u.current=null};n.set(`positionReference`,a)},[_,s,i,o,a,n,h]);W.useEffect(()=>v(),[v,p]),W.useEffect(()=>{s&&!i&&(l.current=!1)},[s,i]),W.useEffect(()=>{!s&&r&&(l.current=!0)},[s,r]);let y=W.useMemo(()=>{function e(e){f(e.pointerType)}return{onPointerDown:e,onPointerEnter:e,onMouseMove:g,onMouseEnter:g}},[g]);return W.useMemo(()=>s?{reference:y,trigger:y}:{},[s,y])}function Qo(e,t,n){let{reference:r,floating:i}=e,a=Gt(t),o=Mn(t),s=En(o),c=mn(t),l=a===`y`,u=r.x+r.width/2-i.width/2,d=r.y+r.height/2-i.height/2,f=r[s]/2-i[s]/2,p;switch(c){case`top`:p={x:u,y:r.y-i.height};break;case`bottom`:p={x:u,y:r.y+r.height};break;case`right`:p={x:r.x+r.width,y:d};break;case`left`:p={x:r.x-i.width,y:d};break;default:p={x:r.x,y:r.y}}switch(Fn(t)){case`start`:p[o]-=f*(n&&l?-1:1);break;case`end`:p[o]+=f*(n&&l?-1:1);break}return p}async function $o(e,t){t===void 0&&(t={});let{x:n,y:r,platform:i,rects:a,elements:o,strategy:s}=e,{boundary:c=`clippingAncestors`,rootBoundary:l=`viewport`,elementContext:u=`floating`,altBoundary:d=!1,padding:f=0}=wn(t,e),p=Un(f),m=o[d?u===`floating`?`reference`:`floating`:u],h=qt(await i.getClippingRect({element:await(i.isElement==null?void 0:i.isElement(m))??!0?m:m.contextElement||await(i.getDocumentElement==null?void 0:i.getDocumentElement(o.floating)),boundary:c,rootBoundary:l,strategy:s})),g=u===`floating`?{x:n,y:r,width:a.floating.width,height:a.floating.height}:a.reference,_=await(i.getOffsetParent==null?void 0:i.getOffsetParent(o.floating)),v=await(i.isElement==null?void 0:i.isElement(_))&&await(i.getScale==null?void 0:i.getScale(_))||{x:1,y:1},y=qt(i.convertOffsetParentRelativeRectToViewportRelativeRect?await i.convertOffsetParentRelativeRectToViewportRelativeRect({elements:o,rect:g,offsetParent:_,strategy:s}):g);return{top:(h.top-y.top+p.top)/v.y,bottom:(y.bottom-h.bottom+p.bottom)/v.y,left:(h.left-y.left+p.left)/v.x,right:(y.right-h.right+p.right)/v.x}}var es=50,ts=async(e,t,n)=>{let{placement:r=`bottom`,strategy:i=`absolute`,middleware:a=[],platform:o}=n,s=o.detectOverflow?o:{...o,detectOverflow:$o},c=await(o.isRTL==null?void 0:o.isRTL(t)),l=await o.getElementRects({reference:e,floating:t,strategy:i}),{x:u,y:d}=Qo(l,r,c),f=r,p=0,m={};for(let n=0;ne<=0)){let e=(i.flip?.index||0)+1,t=S[e];if(t&&(!(u===`alignment`&&_!==Gt(t))||T.every(e=>Gt(e.placement)===_?e.overflows[0]>0:!0)))return{data:{index:e,overflows:T},reset:{placement:t}};let n=T.filter(e=>e.overflows[0]<=0).sort((e,t)=>e.overflows[1]-t.overflows[1])[0]?.placement;if(!n)switch(f){case`bestFit`:{let e=T.filter(e=>{if(x){let t=Gt(e.placement);return t===_||t===`y`}return!0}).map(e=>[e.placement,e.overflows.filter(e=>e>0).reduce((e,t)=>e+t,0)]).sort((e,t)=>e[1]-t[1])[0]?.[0];e&&(n=e);break}case`initialPlacement`:n=o;break}if(r!==n)return{reset:{placement:n}}}return{}}}};function rs(e,t){return{top:e.top-t.height,right:e.right-t.width,bottom:e.bottom-t.height,left:e.left-t.width}}function is(e){return ln.some(t=>e[t]>=0)}var as=function(e){return e===void 0&&(e={}),{name:`hide`,options:e,async fn(t){let{rects:n,platform:r}=t,{strategy:i=`referenceHidden`,...a}=wn(e,t);switch(i){case`referenceHidden`:{let e=rs(await r.detectOverflow(t,{...a,elementContext:`reference`}),n.reference);return{data:{referenceHiddenOffsets:e,referenceHidden:is(e)}}}case`escaped`:{let e=rs(await r.detectOverflow(t,{...a,altBoundary:!0}),n.floating);return{data:{escapedOffsets:e,escaped:is(e)}}}default:return{}}}}},os=new Set([`left`,`top`]);async function ss(e,t){let{placement:n,platform:r,elements:i}=e,a=await(r.isRTL==null?void 0:r.isRTL(i.floating)),o=mn(n),s=Fn(n),c=Gt(n)===`y`,l=os.has(o)?-1:1,u=a&&c?-1:1,d=wn(t,e),{mainAxis:f,crossAxis:p,alignmentAxis:m}=typeof d==`number`?{mainAxis:d,crossAxis:0,alignmentAxis:null}:{mainAxis:d.mainAxis||0,crossAxis:d.crossAxis||0,alignmentAxis:d.alignmentAxis};return s&&typeof m==`number`&&(p=s===`end`?m*-1:m),c?{x:p*u,y:f*l}:{x:f*l,y:p*u}}var cs=function(e){return e===void 0&&(e=0),{name:`offset`,options:e,async fn(t){var n;let{x:r,y:i,placement:a,middlewareData:o}=t,s=await ss(t,e);return a===o.offset?.placement&&(n=o.arrow)!=null&&n.alignmentOffset?{}:{x:r+s.x,y:i+s.y,data:{...s,placement:a}}}}},ls=function(e){return e===void 0&&(e={}),{name:`shift`,options:e,async fn(t){let{x:n,y:r,placement:i,platform:a}=t,{mainAxis:o=!0,crossAxis:s=!1,limiter:c={fn:e=>{let{x:t,y:n}=e;return{x:t,y:n}}},...l}=wn(e,t),u={x:n,y:r},d=await a.detectOverflow(t,l),f=Gt(mn(i)),p=Bn(f),m=u[p],h=u[f];if(o){let e=p===`y`?`top`:`left`,t=p===`y`?`bottom`:`right`,n=m+d[e],r=m-d[t];m=jn(n,m,r)}if(s){let e=f===`y`?`top`:`left`,t=f===`y`?`bottom`:`right`,n=h+d[e],r=h-d[t];h=jn(n,h,r)}let g=c.fn({...t,[p]:m,[f]:h});return{...g,data:{x:g.x-n,y:g.y-r,enabled:{[p]:o,[f]:s}}}}}},us=function(e){return e===void 0&&(e={}),{options:e,fn(t){let{x:n,y:r,placement:i,rects:a,middlewareData:o}=t,{offset:s=0,mainAxis:c=!0,crossAxis:l=!0}=wn(e,t),u={x:n,y:r},d=Gt(i),f=Bn(d),p=u[f],m=u[d],h=wn(s,t),g=typeof h==`number`?{mainAxis:h,crossAxis:0}:{mainAxis:0,crossAxis:0,...h};if(c){let e=f===`y`?`height`:`width`,t=a.reference[f]-a.floating[e]+g.mainAxis,n=a.reference[f]+a.reference[e]-g.mainAxis;pn&&(p=n)}if(l){let e=f===`y`?`width`:`height`,t=os.has(mn(i)),n=a.reference[d]-a.floating[e]+(t&&o.offset?.[d]||0)+(t?0:g.crossAxis),r=a.reference[d]+a.reference[e]+(t?0:o.offset?.[d]||0)-(t?g.crossAxis:0);mr&&(m=r)}return{[f]:p,[d]:m}}}},ds=function(e){return e===void 0&&(e={}),{name:`size`,options:e,async fn(t){var n,r;let{placement:i,rects:a,platform:o,elements:s}=t,{apply:c=()=>{},...l}=wn(e,t),u=await o.detectOverflow(t,l),d=mn(i),f=Fn(i),p=Gt(i)===`y`,{width:m,height:h}=a.floating,g,_;d===`top`||d===`bottom`?(g=d,_=f===(await(o.isRTL==null?void 0:o.isRTL(s.floating))?`start`:`end`)?`left`:`right`):(_=d,g=f===`end`?`top`:`bottom`);let v=h-u.top-u.bottom,y=m-u.left-u.right,b=gn(h-u[g],v),x=gn(m-u[_],y),S=!t.middlewareData.shift,C=b,w=x;if((n=t.middlewareData.shift)!=null&&n.enabled.x&&(w=y),(r=t.middlewareData.shift)!=null&&r.enabled.y&&(C=v),S&&!f){let e=Hn(u.left,0),t=Hn(u.right,0),n=Hn(u.top,0),r=Hn(u.bottom,0);p?w=m-2*(e!==0||t!==0?e+t:Hn(u.left,u.right)):C=h-2*(n!==0||r!==0?n+r:Hn(u.top,u.bottom))}await c({...t,availableWidth:w,availableHeight:C});let T=await o.getDimensions(s.floating);return m!==T.width||h!==T.height?{reset:{rects:!0}}:{}}}};function fs(e){let t=ft(e),n=parseFloat(t.width)||0,r=parseFloat(t.height)||0,i=ot(e),a=i?e.offsetWidth:n,o=i?e.offsetHeight:r,s=Kt(n)!==a||Kt(r)!==o;return s&&(n=a,r=o),{width:n,height:r,$:s}}function ps(e){return V(e)?e:e.contextElement}function ms(e){let t=ps(e);if(!ot(t))return zn(1);let n=t.getBoundingClientRect(),{width:r,height:i,$:a}=fs(t),o=(a?Kt(n.width):n.width)/r,s=(a?Kt(n.height):n.height)/i;return(!o||!Number.isFinite(o))&&(o=1),(!s||!Number.isFinite(s))&&(s=1),{x:o,y:s}}var hs=zn(0);function gs(e){let t=at(e);return!nt()||!t.visualViewport?hs:{x:t.visualViewport.offsetLeft,y:t.visualViewport.offsetTop}}function _s(e,t,n){return t===void 0&&(t=!1),!n||t&&n!==at(e)?!1:t}function vs(e,t,n,r){t===void 0&&(t=!1),n===void 0&&(n=!1);let i=e.getBoundingClientRect(),a=ps(e),o=zn(1);t&&(r?V(r)&&(o=ms(r)):o=ms(e));let s=_s(a,n,r)?gs(a):zn(0),c=(i.left+s.x)/o.x,l=(i.top+s.y)/o.y,u=i.width/o.x,d=i.height/o.y;if(a){let e=at(a),t=r&&V(r)?at(r):r,n=e,i=lt(n);for(;i&&r&&t!==n;){let e=ms(i),t=i.getBoundingClientRect(),r=ft(i),a=t.left+(i.clientLeft+parseFloat(r.paddingLeft))*e.x,o=t.top+(i.clientTop+parseFloat(r.paddingTop))*e.y;c*=e.x,l*=e.y,u*=e.x,d*=e.y,c+=a,l+=o,n=at(i),i=lt(n)}}return qt({width:u,height:d,x:c,y:l})}function ys(e,t){let n=pt(e).scrollLeft;return t?t.left+n:vs(ct(e)).left+n}function bs(e,t){let n=e.getBoundingClientRect();return{x:n.left+t.scrollLeft-ys(e,n),y:n.top+t.scrollTop}}function xs(e){let{elements:t,rect:n,offsetParent:r,strategy:i}=e,a=i===`fixed`,o=ct(r),s=t?rt(t.floating):!1;if(r===o||s&&a)return n;let c={scrollLeft:0,scrollTop:0},l=zn(1),u=zn(0),d=ot(r);if((d||!d&&!a)&&((gt(r)!==`body`||tt(o))&&(c=pt(r)),d)){let e=vs(r);l=ms(r),u.x=e.x+r.clientLeft,u.y=e.y+r.clientTop}let f=o&&!d&&!a?bs(o,c):zn(0);return{width:n.width*l.x,height:n.height*l.y,x:n.x*l.x-c.scrollLeft*l.x+u.x+f.x,y:n.y*l.y-c.scrollTop*l.y+u.y+f.y}}function Ss(e){return Array.from(e.getClientRects())}function Cs(e){let t=ct(e),n=pt(e),r=e.ownerDocument.body,i=Hn(t.scrollWidth,t.clientWidth,r.scrollWidth,r.clientWidth),a=Hn(t.scrollHeight,t.clientHeight,r.scrollHeight,r.clientHeight),o=-n.scrollLeft+ys(e),s=-n.scrollTop;return ft(r).direction===`rtl`&&(o+=Hn(t.clientWidth,r.clientWidth)-i),{width:i,height:a,x:o,y:s}}var ws=25;function Ts(e,t){let n=at(e),r=ct(e),i=n.visualViewport,a=r.clientWidth,o=r.clientHeight,s=0,c=0;if(i){a=i.width,o=i.height;let e=nt();(!e||e&&t===`fixed`)&&(s=i.offsetLeft,c=i.offsetTop)}let l=ys(r);if(l<=0){let e=r.ownerDocument,t=e.body,n=getComputedStyle(t),i=e.compatMode===`CSS1Compat`&&parseFloat(n.marginLeft)+parseFloat(n.marginRight)||0,o=Math.abs(r.clientWidth-t.clientWidth-i);o<=ws&&(a-=o)}else l<=ws&&(a+=l);return{width:a,height:o,x:s,y:c}}function Es(e,t){let n=vs(e,!0,t===`fixed`),r=n.top+e.clientTop,i=n.left+e.clientLeft,a=ot(e)?ms(e):zn(1);return{width:e.clientWidth*a.x,height:e.clientHeight*a.y,x:i*a.x,y:r*a.y}}function Ds(e,t,n){let r;if(t===`viewport`)r=Ts(e,n);else if(t===`document`)r=Cs(ct(e));else if(V(t))r=Es(t,n);else{let n=gs(e);r={x:t.x-n.x,y:t.y-n.y,width:t.width,height:t.height}}return qt(r)}function Os(e,t){let n=ut(e);return n===t||!V(n)||xt(n)?!1:ft(n).position===`fixed`||Os(n,t)}function ks(e,t){let n=t.get(e);if(n)return n;let r=dt(e,[],!1).filter(e=>V(e)&>(e)!==`body`),i=null,a=ft(e).position===`fixed`,o=a?ut(e):e;for(;V(o)&&!xt(o);){let t=ft(o),n=bt(o);!n&&t.position===`fixed`&&(i=null),(a?!n&&!i:!n&&t.position===`static`&&i&&(i.position===`absolute`||i.position===`fixed`)||tt(o)&&!n&&Os(e,o))?r=r.filter(e=>e!==o):i=t,o=ut(o)}return t.set(e,r),r}function As(e){let{element:t,boundary:n,rootBoundary:r,strategy:i}=e,a=[...n===`clippingAncestors`?rt(t)?[]:ks(t,this._c):[].concat(n),r],o=Ds(t,a[0],i),s=o.top,c=o.right,l=o.bottom,u=o.left;for(let e=1;e{o(!1,1e-7)},1e3)}n===1&&!zs(l,e.getBoundingClientRect())&&o(),y=!1}try{n=new IntersectionObserver(b,{...v,root:i.ownerDocument})}catch{n=new IntersectionObserver(b,v)}n.observe(e)}return o(!0),a}function Vs(e,t,n,r){r===void 0&&(r={});let{ancestorScroll:i=!0,ancestorResize:a=!0,elementResize:o=typeof ResizeObserver==`function`,layoutShift:s=typeof IntersectionObserver==`function`,animationFrame:c=!1}=r,l=ps(e),u=i||a?[...l?dt(l):[],...t?dt(t):[]]:[];u.forEach(e=>{i&&e.addEventListener(`scroll`,n,{passive:!0}),a&&e.addEventListener(`resize`,n)});let d=l&&s?Bs(l,n):null,f=-1,p=null;o&&(p=new ResizeObserver(e=>{let[r]=e;r&&r.target===l&&p&&t&&(p.unobserve(t),cancelAnimationFrame(f),f=requestAnimationFrame(()=>{var e;(e=p)==null||e.observe(t)})),n()}),l&&!c&&p.observe(l),t&&p.observe(t));let m,h=c?vs(e):null;c&&g();function g(){let t=vs(e);h&&!zs(h,t)&&n(),h=t,m=requestAnimationFrame(g)}return n(),()=>{var e;u.forEach(e=>{i&&e.removeEventListener(`scroll`,n),a&&e.removeEventListener(`resize`,n)}),d?.(),(e=p)==null||e.disconnect(),p=null,c&&cancelAnimationFrame(m)}}var Hs=cs,Us=ls,Ws=ns,Gs=ds,Ks=as,qs=us,Js=(e,t,n)=>{let r=new Map,i={platform:Rs,...n},a={...i.platform,_c:r};return ts(e,t,{...i,platform:a})},Ys=e(ze(),1),Xs=typeof document<`u`?W.useLayoutEffect:function(){};function Zs(e,t){if(e===t)return!0;if(typeof e!=typeof t)return!1;if(typeof e==`function`&&e.toString()===t.toString())return!0;let n,r,i;if(e&&t&&typeof e==`object`){if(Array.isArray(e)){if(n=e.length,n!==t.length)return!1;for(r=n;r--!==0;)if(!Zs(e[r],t[r]))return!1;return!0}if(i=Object.keys(e),n=i.length,n!==Object.keys(t).length)return!1;for(r=n;r--!==0;)if(!{}.hasOwnProperty.call(t,i[r]))return!1;for(r=n;r--!==0;){let n=i[r];if(!(n===`_owner`&&e.$$typeof)&&!Zs(e[n],t[n]))return!1}return!0}return e!==e&&t!==t}function Qs(e){return typeof window>`u`?1:(e.ownerDocument.defaultView||window).devicePixelRatio||1}function $s(e,t){let n=Qs(e);return Math.round(t*n)/n}function ec(e){let t=W.useRef(e);return Xs(()=>{t.current=e}),t}function tc(e){e===void 0&&(e={});let{placement:t=`bottom`,strategy:n=`absolute`,middleware:r=[],platform:i,elements:{reference:a,floating:o}={},transform:s=!0,whileElementsMounted:c,open:l}=e,[u,d]=W.useState({x:0,y:0,strategy:n,placement:t,middlewareData:{},isPositioned:!1}),[f,p]=W.useState(r);Zs(f,r)||p(r);let[m,h]=W.useState(null),[g,_]=W.useState(null),v=W.useCallback(e=>{e!==S.current&&(S.current=e,h(e))},[]),y=W.useCallback(e=>{e!==C.current&&(C.current=e,_(e))},[]),b=a||m,x=o||g,S=W.useRef(null),C=W.useRef(null),w=W.useRef(u),T=c!=null,E=ec(c),D=ec(i),O=ec(l),k=W.useCallback(()=>{if(!S.current||!C.current)return;let e={placement:t,strategy:n,middleware:f};D.current&&(e.platform=D.current),Js(S.current,C.current,e).then(e=>{let t={...e,isPositioned:O.current!==!1};ee.current&&!Zs(w.current,t)&&(w.current=t,Ys.flushSync(()=>{d(t)}))})},[f,t,n,D,O]);Xs(()=>{l===!1&&w.current.isPositioned&&(w.current.isPositioned=!1,d(e=>({...e,isPositioned:!1})))},[l]);let ee=W.useRef(!1);Xs(()=>(ee.current=!0,()=>{ee.current=!1}),[]),Xs(()=>{if(b&&(S.current=b),x&&(C.current=x),b&&x){if(E.current)return E.current(b,x,k);k()}},[b,x,k,E,T]);let A=W.useMemo(()=>({reference:S,floating:C,setReference:v,setFloating:y}),[v,y]),j=W.useMemo(()=>({reference:b,floating:x}),[b,x]),te=W.useMemo(()=>{let e={position:n,left:0,top:0};if(!j.floating)return e;let t=$s(j.floating,u.x),r=$s(j.floating,u.y);return s?{...e,transform:`translate(`+t+`px, `+r+`px)`,...Qs(j.floating)>=1.5&&{willChange:`transform`}}:{position:n,left:t,top:r}},[n,s,j.floating,u.x,u.y]);return W.useMemo(()=>({...u,update:k,refs:A,elements:j,floatingStyles:te}),[u,k,A,j,te])}var nc=(e,t)=>{let n=Hs(e);return{name:n.name,fn:n.fn,options:[e,t]}},rc=(e,t)=>{let n=Us(e);return{name:n.name,fn:n.fn,options:[e,t]}},ic=(e,t)=>({fn:qs(e).fn,options:[e,t]}),ac=(e,t)=>{let n=Ws(e);return{name:n.name,fn:n.fn,options:[e,t]}},oc=(e,t)=>{let n=Gs(e);return{name:n.name,fn:n.fn,options:[e,t]}},sc=(e,t)=>{let n=Ks(e);return{name:n.name,fn:n.fn,options:[e,t]}};function cc(e,t){let n=W.useRef(null),r=W.useRef(null);return W.useCallback(i=>{if(e!==void 0){if(n.current!==null){let e=n.current,i=r.current,a=t.context.triggerElements.getById(e);i&&a===i&&t.context.triggerElements.delete(e),n.current=null,r.current=null}i!==null&&(n.current=e,r.current=i,t.context.triggerElements.add(e,i))}},[t,e])}function lc(e,t,n,r){let i=n.useState(`isMountedByTrigger`,e),a=cc(e,n),o=st(t=>{if(a(t),!t||!n.select(`open`))return;let i=n.select(`activeTriggerId`);if(i===e){n.update({activeTriggerElement:t,...r});return}i??n.update({activeTriggerId:e,activeTriggerElement:t,...r})});return ht(()=>{i&&n.update({activeTriggerElement:t.current,...r})},[i,n,t,...Object.values(r)]),{registerTrigger:o,isMountedByThisTrigger:i}}function uc(e){let t=e.useState(`open`);ht(()=>{if(t&&!e.select(`activeTriggerId`)&&e.context.triggerElements.size===1){let t=e.context.triggerElements.entries().next();if(!t.done){let[n,r]=t.value;e.update({activeTriggerId:n,activeTriggerElement:r})}}},[t,e])}function dc(e,t,n){let{mounted:r,setMounted:i,transitionStatus:a}=qn(e);t.useSyncedValues({mounted:r,transitionStatus:a});let o=st(()=>{i(!1),t.update({activeTriggerId:null,activeTriggerElement:null,mounted:!1}),n?.(),t.context.onOpenChangeComplete?.(!1)});return Yn({enabled:!t.useState(`preventUnmountingOnClose`),open:e,ref:t.context.popupRef,onComplete(){e||o()}}),{forceUnmount:o,transitionStatus:a}}function fc(){return new Vn({open:!1,transitionStatus:void 0,floatingElement:null,referenceElement:null,triggerElements:new Wt,floatingId:``,syncOnly:!1,nested:!1,onOpenChange:void 0})}function pc(){return{open:!1,openProp:void 0,mounted:!1,transitionStatus:void 0,floatingRootContext:fc(),preventUnmountingOnClose:!1,payload:void 0,activeTriggerId:null,activeTriggerElement:null,triggerIdProp:void 0,popupElement:null,positionerElement:null,activeTriggerProps:Ue,inactiveTriggerProps:Ue,popupProps:Ue}}var mc=H(e=>e.triggerIdProp??e.activeTriggerId),hc={open:H(e=>e.openProp??e.open),mounted:H(e=>e.mounted),transitionStatus:H(e=>e.transitionStatus),floatingRootContext:H(e=>e.floatingRootContext),preventUnmountingOnClose:H(e=>e.preventUnmountingOnClose),payload:H(e=>e.payload),activeTriggerId:mc,activeTriggerElement:H(e=>e.mounted?e.activeTriggerElement:null),isTriggerActive:H((e,t)=>t!==void 0&&mc(e)===t),isOpenedByTrigger:H((e,t)=>t!==void 0&&mc(e)===t&&e.open),isMountedByTrigger:H((e,t)=>t!==void 0&&mc(e)===t&&e.mounted),triggerProps:H((e,t)=>t?e.activeTriggerProps:e.inactiveTriggerProps),popupProps:H(e=>e.popupProps),popupElement:H(e=>e.popupElement),positionerElement:H(e=>e.positionerElement)};function gc(e){let{open:t=!1,onOpenChange:n,elements:r={}}=e,i=Bt(),a=sn()!=null,o=Ve(()=>new Vn({open:t,transitionStatus:void 0,onOpenChange:n,referenceElement:r.reference??null,floatingElement:r.floating??null,triggerElements:new Wt,floatingId:i,syncOnly:!1,nested:a})).current;return ht(()=>{let e={open:t,floatingId:i};r.reference!==void 0&&(e.referenceElement=r.reference,e.domReferenceElement=V(r.reference)?r.reference:null),r.floating!==void 0&&(e.floatingElement=r.floating),o.update(e)},[t,i,r.reference,r.floating,o]),o.context.onOpenChange=n,o.context.nested=a,o}function _c(e={}){let{nodeId:t,externalTree:n}=e,r=gc(e),i=e.rootContext||r,a={reference:i.useState(`referenceElement`),floating:i.useState(`floatingElement`),domReference:i.useState(`domReferenceElement`)},[o,s]=W.useState(null),c=W.useRef(null),l=un(n);ht(()=>{a.domReference&&(c.current=a.domReference)},[a.domReference]);let u=tc({...e,elements:{...a,...o&&{reference:o}}}),d=W.useCallback(e=>{let t=V(e)?{getBoundingClientRect:()=>e.getBoundingClientRect(),getClientRects:()=>e.getClientRects(),contextElement:e}:e;s(t),u.refs.setReference(t)},[u.refs]),[f,p]=W.useState(void 0),[m,h]=W.useState(null);i.useSyncedValue(`referenceElement`,f??null);let g=V(f)?f:null;i.useSyncedValue(`domReferenceElement`,f===void 0?a.domReference:g),i.useSyncedValue(`floatingElement`,m);let _=W.useCallback(e=>{(V(e)||e===null)&&(c.current=e,p(e)),(V(u.refs.reference.current)||u.refs.reference.current===null||e!==null&&!V(e))&&u.refs.setReference(e)},[u.refs,p]),v=W.useCallback(e=>{h(e),u.refs.setFloating(e)},[u.refs]),y=W.useMemo(()=>({...u.refs,setReference:_,setFloating:v,setPositionReference:d,domReference:c}),[u.refs,_,v,d]),b=W.useMemo(()=>({...u.elements,domReference:a.domReference}),[u.elements,a.domReference]),x=i.useState(`open`),S=i.useState(`floatingId`),C=W.useMemo(()=>({...u,dataRef:i.context.dataRef,open:x,onOpenChange:i.setOpen,events:i.context.events,floatingId:S,refs:y,elements:b,nodeId:t,rootStore:i}),[u,y,b,t,i,x,S]);return ht(()=>{i.context.dataRef.current.floatingContext=C;let e=l?.nodesRef.current.find(e=>e.id===t);e&&(e.context=C)}),W.useMemo(()=>({...u,context:C,refs:y,elements:b,rootStore:i}),[u,y,b,C,i])}function vc(e){let{popupStore:t,treatPopupAsFloatingElement:n=!1,onOpenChange:r}=e,i=Bt(),a=sn()!=null,o=t.useState(`open`),s=t.useState(`activeTriggerElement`),c=t.useState(n?`popupElement`:`positionerElement`),l=t.context.triggerElements,u=Ve(()=>new Vn({open:o,transitionStatus:void 0,referenceElement:s,floatingElement:c,triggerElements:l,onOpenChange:r,floatingId:i,syncOnly:!0,nested:a})).current;return ht(()=>{let e={open:o,floatingId:i,referenceElement:s,floatingElement:c};V(s)&&(e.domReferenceElement=s),u.state.positionReference===u.state.referenceElement&&(e.positionReference=s),u.update(e)},[o,i,s,c,u]),u.context.onOpenChange=r,u.context.nested=a,u}var yc=Zt&&nn;function bc(e,t={}){let n=`rootStore`in e?e.rootStore:e,{events:r,dataRef:i}=n.context,{enabled:a=!0,delay:o}=t,s=W.useRef(!1),c=W.useRef(null),l=fn(),u=W.useRef(!0);W.useEffect(()=>{let e=n.select(`domReferenceElement`);if(!a)return;let t=at(e);function r(){let e=n.select(`domReferenceElement`);!n.select(`open`)&&ot(e)&&e===Mt(Vt(e))&&(s.current=!0)}function i(){u.current=!0}function o(){u.current=!1}return Xt(Xn(t,`blur`,r),yc&&Xn(t,`keydown`,i,!0),yc&&Xn(t,`pointerdown`,o,!0))},[n,a]),W.useEffect(()=>{if(!a)return;function e(e){if(e.reason===`trigger-press`||e.reason===`escape-key`){let e=n.select(`domReferenceElement`);V(e)&&(c.current=e,s.current=!0)}}return r.on(`openchange`,e),()=>{r.off(`openchange`,e)}},[r,a,n]);let d=W.useMemo(()=>({onMouseLeave(){s.current=!1,c.current=null},onFocus(e){let t=e.currentTarget;if(s.current){if(c.current===t)return;s.current=!1,c.current=null}let r=zt(e.nativeEvent);if(V(r)){if(yc&&!e.relatedTarget){if(!u.current&&!Kn(r))return}else if(!Ut(r))return}let i=an(e.relatedTarget,n.context.triggerElements),{nativeEvent:a,currentTarget:d}=e,f=typeof o==`function`?o():o;if(n.select(`open`)&&i||f===0||f===void 0){n.setOpen(!0,Lt(jt,a,d));return}l.start(f,()=>{s.current||n.setOpen(!0,Lt(jt,a,d))})},onBlur(e){s.current=!1,c.current=null;let t=e.relatedTarget,r=e.nativeEvent,a=V(t)&&t.hasAttribute(_n(`focus-guard`))&&t.getAttribute(`data-type`)===`outside`;l.start(0,()=>{let e=n.select(`domReferenceElement`),o=Mt(Vt(e));!t&&o===e||kt(i.current.floatingContext?.refs.floating.current,o)||kt(e,o)||a||an(t??o,n.context.triggerElements)||n.setOpen(!1,Lt(jt,r))})}}),[i,n,l,o]);return W.useMemo(()=>a?{reference:d,trigger:d}:{},[a,d])}var xc=class e{constructor(){this.pointerType=void 0,this.interactedInside=!1,this.handler=void 0,this.blockMouseMove=!0,this.performedPointerEventsMutation=!1,this.pointerEventsScopeElement=null,this.pointerEventsReferenceElement=null,this.pointerEventsFloatingElement=null,this.restTimeoutPending=!1,this.openChangeTimeout=new bn,this.restTimeout=new bn,this.handleCloseOptions=void 0}static create(){return new e}dispose=()=>{this.openChangeTimeout.clear(),this.restTimeout.clear()};disposeEffect=()=>this.dispose},Sc=new WeakMap;function Cc(e){if(!e.performedPointerEventsMutation)return;let t=e.pointerEventsScopeElement;t&&Sc.get(t)===e&&(e.pointerEventsScopeElement?.style.removeProperty(`pointer-events`),e.pointerEventsReferenceElement?.style.removeProperty(`pointer-events`),e.pointerEventsFloatingElement?.style.removeProperty(`pointer-events`),Sc.delete(t)),e.performedPointerEventsMutation=!1,e.pointerEventsScopeElement=null,e.pointerEventsReferenceElement=null,e.pointerEventsFloatingElement=null}function wc(e,t){let{scopeElement:n,referenceElement:r,floatingElement:i}=t,a=Sc.get(n);a&&a!==e&&Cc(a),Cc(e),e.performedPointerEventsMutation=!0,e.pointerEventsScopeElement=n,e.pointerEventsReferenceElement=r,e.pointerEventsFloatingElement=i,Sc.set(n,e),n.style.pointerEvents=`none`,r.style.pointerEvents=`auto`,i.style.pointerEvents=`auto`}function Tc(e){let t=Ve(xc.create).current,n=e.context.dataRef.current;return n.hoverInteractionState||=t,Zn(n.hoverInteractionState.disposeEffect),n.hoverInteractionState}function Ec(e,t={}){let n=`rootStore`in e?e.rootStore:e,r=n.useState(`open`),i=n.useState(`floatingElement`),a=n.useState(`domReferenceElement`),{dataRef:o}=n.context,{enabled:s=!0,closeDelay:c=0,nodeId:l}=t,u=Tc(n),d=un(),f=sn(),p=st(()=>Go(o.current.openEvent?.type,u.interactedInside)),m=st(()=>{let e=o.current.openEvent?.type;return e?.includes(`mouse`)&&e!==`mousedown`}),h=st(e=>an(e,n.context.triggerElements)),g=W.useCallback(e=>{let t=Uo(c,`close`,u.pointerType),r=()=>{n.setOpen(!1,Lt(Pt,e)),d?.events.emit(`floating.closed`,e)};t?u.openChangeTimeout.start(t,r):(u.openChangeTimeout.clear(),r())},[c,n,u,d]),_=st(()=>{Cc(u)}),v=st(e=>{let t=zt(e);if(!$t(t)){u.interactedInside=!1;return}u.interactedInside=t?.closest(`[aria-haspopup]`)!=null});ht(()=>{r||(u.pointerType=void 0,u.restTimeoutPending=!1,u.interactedInside=!1,_())},[r,u,_]),W.useEffect(()=>_,[_]),ht(()=>{if(s&&r&&u.handleCloseOptions?.blockPointerEvents&&m()&&V(a)&&i){let e=a,t=i,n=Vt(i),r=d?.nodesRef.current.find(e=>e.id===f)?.context?.elements.floating;return r&&(r.style.pointerEvents=``),wc(u,{scopeElement:u.handleCloseOptions?.getScope?.()??u.pointerEventsScopeElement??r??e.closest(`[data-rootownerid]`)??n.body,referenceElement:e,floatingElement:t}),()=>{_()}}},[s,r,a,i,u,m,d,f,_]);let y=fn();W.useEffect(()=>{if(!s)return;function e(){u.openChangeTimeout.clear(),y.clear(),d?.events.off(`floating.closed`,r),_()}function t(e){if(d&&f&&dn(d.nodesRef.current,f).length>0){d.events.on(`floating.closed`,r);return}if(h(e.relatedTarget))return;let t=o.current.floatingContext?.nodeId??l,n=e.relatedTarget;if(!(d&&t&&V(n)&&dn(d.nodesRef.current,t,!1).some(e=>kt(e.context?.elements.floating,n)))){if(u.handler){u.handler(e);return}_(),p()||g(e)}}function r(e){!d||!f||dn(d.nodesRef.current,f).length>0||y.start(0,()=>{d.events.off(`floating.closed`,r),n.setOpen(!1,Lt(Pt,e)),d.events.emit(`floating.closed`,e)})}let a=i;return Xt(a&&Xn(a,`mouseenter`,e),a&&Xn(a,`mouseleave`,t),a&&Xn(a,`pointerdown`,v,!0),()=>{d?.events.off(`floating.closed`,r)})},[s,i,n,o,l,p,h,g,_,v,u,d,f,y])}var Dc={current:null};function Oc(e,t={}){let n=`rootStore`in e?e.rootStore:e,{dataRef:r,events:i}=n.context,{enabled:a=!0,delay:o=0,handleClose:s=null,mouseOnly:c=!1,restMs:l=0,move:u=!0,triggerElementRef:d=Dc,externalTree:f,isActiveTrigger:p=!0,getHandleCloseContext:m,isClosing:h}=t,g=un(f),_=Tc(n),v=W.useRef(!1),y=vn(s),b=vn(o),x=vn(l),S=vn(a),C=vn(h);p&&(_.handleCloseOptions=y.current?.__options);let w=st(()=>Go(r.current.openEvent?.type,_.interactedInside)),T=st(e=>an(e,n.context.triggerElements)),E=st((e,t,r)=>{let i=n.context.triggerElements;if(i.hasElement(t))return!e||!kt(e,t);if(!V(r))return!1;let a=r;return i.hasMatchingElement(e=>kt(e,a))&&(!e||!kt(e,a))}),D=st((e,t=!0)=>{let r=Uo(b.current,`close`,_.pointerType);r?_.openChangeTimeout.start(r,()=>{n.setOpen(!1,Lt(Pt,e)),g?.events.emit(`floating.closed`,e)}):t&&(_.openChangeTimeout.clear(),n.setOpen(!1,Lt(Pt,e)),g?.events.emit(`floating.closed`,e))}),O=st(()=>{_.handler&&=(Vt(n.select(`domReferenceElement`)).removeEventListener(`mousemove`,_.handler),void 0)}),k=st(()=>{Cc(_)});return W.useEffect(()=>O,[O]),W.useEffect(()=>{if(!a)return;function e(e){e.open?v.current=!1:(v.current=e.reason===Pt,O(),_.openChangeTimeout.clear(),_.restTimeout.clear(),_.blockMouseMove=!0,_.restTimeoutPending=!1)}return i.on(`openchange`,e),()=>{i.off(`openchange`,e)}},[a,i,_,O]),W.useEffect(()=>{if(!a)return;let e=d.current??(p?n.select(`domReferenceElement`):null);if(!V(e))return;function t(e){if(_.openChangeTimeout.clear(),_.blockMouseMove=!1,c&&!Ht(_.pointerType))return;let t=Wo(x.current),r=Uo(b.current,`open`,_.pointerType),i=zt(e),a=e.currentTarget??null,o=n.select(`domReferenceElement`),s=a;if(V(i)&&!n.context.triggerElements.hasElement(i)){for(let e of n.context.triggerElements.elements())if(kt(e,i)){s=e;break}}V(a)&&V(o)&&!n.context.triggerElements.hasElement(a)&&kt(a,o)&&(s=o);let l=s==null?!1:E(o,s,i),u=n.select(`open`),d=C.current?.()??n.select(`transitionStatus`)===`ending`,f=!u&&d&&v.current,p=!l&&V(s)&&V(o)&&kt(o,s)&&f,m=t>0&&!r,h=l&&(u||f)||p,g=!u||l;if(h){n.setOpen(!0,Lt(Pt,e,s));return}m||(r?_.openChangeTimeout.start(r,()=>{g&&n.setOpen(!0,Lt(Pt,e,s))}):g&&n.setOpen(!0,Lt(Pt,e,s)))}function i(e){if(w()){k();return}O();let t=Vt(n.select(`domReferenceElement`));_.restTimeout.clear(),_.restTimeoutPending=!1;let i=r.current.floatingContext??m?.();if(!T(e.relatedTarget)){if(y.current&&i){n.select(`open`)||_.openChangeTimeout.clear();let r=d.current;_.handler=y.current({...i,tree:g,x:e.clientX,y:e.clientY,onClose(){k(),O(),S.current&&!w()&&r===n.select(`domReferenceElement`)&&D(e,!0)}}),t.addEventListener(`mousemove`,_.handler),_.handler(e);return}(_.pointerType!==`touch`||!kt(n.select(`floatingElement`),e.relatedTarget))&&D(e)}}return u?Xt(Xn(e,`mousemove`,t,{once:!0}),Xn(e,`mouseenter`,t),Xn(e,`mouseleave`,i)):Xt(Xn(e,`mouseenter`,t),Xn(e,`mouseleave`,i))},[O,k,r,b,D,n,a,y,_,p,E,w,T,c,u,x,d,g,S,m,C]),W.useMemo(()=>{if(!a)return;function e(e){_.pointerType=e.pointerType}return{onPointerDown:e,onPointerEnter:e,onMouseMove(e){let{nativeEvent:t}=e,r=e.currentTarget,i=n.select(`domReferenceElement`),a=n.select(`open`),o=E(i,r,e.target);if(c&&!Ht(_.pointerType))return;if(a&&o&&_.handleCloseOptions?.blockPointerEvents){let e=n.select(`floatingElement`);e&&wc(_,{scopeElement:_.handleCloseOptions?.getScope?.()??r.ownerDocument.body,referenceElement:r,floatingElement:e})}let s=Wo(x.current);if(a&&!o||s===0||!o&&_.restTimeoutPending&&e.movementX**2+e.movementY**2<2)return;_.restTimeout.clear();function l(){if(_.restTimeoutPending=!1,w())return;let e=n.select(`open`);!_.blockMouseMove&&(!e||o)&&n.setOpen(!0,Lt(Pt,t,r))}_.pointerType===`touch`?Ys.flushSync(()=>{l()}):o&&a?l():(_.restTimeoutPending=!0,_.restTimeout.start(s,l))}}},[a,_,w,E,c,n,x])}var kc=new Map([[`select`,`listbox`],[`combobox`,`listbox`],[`label`,!1]]);function Ac(e,t={}){let n=`rootStore`in e?e.rootStore:e,r=n.useState(`open`),i=n.useState(`floatingId`),a=n.useState(`domReferenceElement`),o=n.useState(`floatingElement`),{role:s=`dialog`}=t,c=Bt(),l=a?.id||c,u=W.useMemo(()=>Yt(o)?.id||i,[o,i]),d=kc.get(s)??s,f=sn()!=null,p=W.useMemo(()=>d===`tooltip`||s===`label`?Ue:{"aria-haspopup":d===`alertdialog`?`dialog`:d,"aria-expanded":`false`,...d===`listbox`&&{role:`combobox`},...d===`menu`&&f&&{role:`menuitem`},...s===`select`&&{"aria-autocomplete":`none`},...s===`combobox`&&{"aria-autocomplete":`list`}},[d,f,s]),m=W.useMemo(()=>d===`tooltip`||s===`label`?{[`aria-${s===`label`?`labelledby`:`describedby`}`]:r?u:void 0}:{...p,"aria-expanded":r?`true`:`false`,"aria-controls":r?u:void 0,...d===`menu`&&{id:l}},[d,u,r,l,s,p]),h=W.useMemo(()=>{let e={id:u,...d&&{role:d}};return d===`tooltip`||s===`label`?e:{...e,...d===`menu`&&{"aria-labelledby":l}}},[d,u,l,s]),g=W.useCallback(({active:e,selected:t})=>{let n={role:`option`,...e&&{id:`${u}-fui-option`}};switch(s){case`select`:case`combobox`:return{...n,"aria-selected":t};default:}return{}},[u,s]);return W.useMemo(()=>({reference:m,floating:h,item:g,trigger:p}),[m,h,p,g])}var jc=.1,Mc=jc*jc,Nc=.5;function Pc(e,t,n,r,i,a){return r>=t!=a>=t&&e<=(i-n)*(t-r)/(a-r)+n}function Fc(e,t,n,r,i,a,o,s,c,l){let u=!1;return Pc(e,t,n,r,i,a)&&(u=!u),Pc(e,t,i,a,o,s)&&(u=!u),Pc(e,t,o,s,c,l)&&(u=!u),Pc(e,t,c,l,n,r)&&(u=!u),u}function Ic(e,t,n){return e>=n.x&&e<=n.x+n.width&&t>=n.y&&t<=n.y+n.height}function Lc(e,t,n,r,i,a){return e>=Math.min(n,i)&&e<=Math.max(n,i)&&t>=Math.min(r,a)&&t<=Math.max(r,a)}function Rc(e={}){let{blockPointerEvents:t=!1}=e,n=new bn,r=({x:e,y:t,placement:r,elements:i,onClose:a,nodeId:o,tree:s})=>{let c=r?.split(`-`)[0],l=!1,u=null,d=null,f=typeof performance<`u`?performance.now():0;function p(e,t){let n=performance.now(),r=n-f;if(u===null||d===null||r===0)return u=e,d=t,f=n,!1;let i=e-u,a=t-d,o=i*i+a*a,s=r*r*Mc;return u=e,d=t,f=n,o0)}function b(){y()||m()}if(y())return;let x=a.getBoundingClientRect(),S=u.getBoundingClientRect(),C=e>S.right-S.width/2,w=t>S.bottom-S.height/2,T=S.width>x.width,E=S.height>x.height,D=(T?x:S).left,O=(T?x:S).right,k=(E?x:S).top,ee=(E?x:S).bottom;if(c===`top`&&t>=x.bottom-1||c===`bottom`&&t<=x.top+1||c===`left`&&e>=x.right-1||c===`right`&&e<=x.left+1){b();return}let A=!1;switch(c){case`top`:A=Lc(d,f,D,x.top+1,O,S.bottom-1);break;case`bottom`:A=Lc(d,f,D,S.top+1,O,x.bottom-1);break;case`left`:A=Lc(d,f,S.right-1,ee,x.left+1,k);break;case`right`:A=Lc(d,f,x.right-1,ee,S.left+1,k);break;default:}if(A)return;if(l&&!Ic(d,f,x)){b();return}if(!g&&p(d,f)){b();return}let j=!1;switch(c){case`top`:{let n=T?Nc/2:Nc*4,r=T||C?e+n:e-n,i=T?e-n:C?e+n:e-n,a=t+Nc+1,o=C||T?S.bottom-Nc:S.top,s=C?T?S.bottom-Nc:S.top:S.bottom-Nc;j=Fc(d,f,r,a,i,a,S.left,o,S.right,s);break}case`bottom`:{let n=T?Nc/2:Nc*4,r=T||C?e+n:e-n,i=T?e-n:C?e+n:e-n,a=t-Nc,o=C||T?S.top+Nc:S.bottom,s=C?T?S.top+Nc:S.bottom:S.top+Nc;j=Fc(d,f,r,a,i,a,S.left,o,S.right,s);break}case`left`:{let n=E?Nc/2:Nc*4,r=E||w?t+n:t-n,i=E?t-n:w?t+n:t-n,a=e+Nc+1,o=w||E?S.right-Nc:S.left,s=w?E?S.right-Nc:S.left:S.right-Nc;j=Fc(d,f,o,S.top,s,S.bottom,a,r,a,i);break}case`right`:{let n=E?Nc/2:Nc*4,r=E||w?t+n:t-n,i=E?t-n:w?t+n:t-n,a=e-Nc,o=w||E?S.left+Nc:S.right,s=w?E?S.left+Nc:S.right:S.left+Nc;j=Fc(d,f,a,r,a,i,o,S.top,s,S.bottom);break}default:}j?l||n.start(40,b):b()}};return r.__options={...e,blockPointerEvents:t},r}var zc=function(e){return e.nestedDialogs=`--nested-dialogs`,e}({}),Bc=function(e){return e[e.open=tn.open]=`open`,e[e.closed=tn.closed]=`closed`,e[e.startingStyle=tn.startingStyle]=`startingStyle`,e[e.endingStyle=tn.endingStyle]=`endingStyle`,e.nested=`data-nested`,e.nestedDialogOpen=`data-nested-dialog-open`,e}({}),Vc=W.createContext(void 0);function Hc(){let e=W.useContext(Vc);if(e===void 0)throw Error(We(26));return e}var Uc={...en,...Jn,nestedDialogOpen(e){return e?{[Bc.nestedDialogOpen]:``}:null}},Wc=W.forwardRef(function(e,t){let{className:n,finalFocus:r,initialFocus:i,render:a,style:o,...s}=e,{store:c}=Lo(),l=c.useState(`descriptionElementId`),u=c.useState(`disablePointerDismissal`),d=c.useState(`floatingRootContext`),f=c.useState(`popupProps`),p=c.useState(`modal`),m=c.useState(`mounted`),h=c.useState(`nested`),g=c.useState(`nestedOpenDialogCount`),_=c.useState(`open`),v=c.useState(`openMethod`),y=c.useState(`titleElementId`),b=c.useState(`transitionStatus`),x=c.useState(`role`);Hc(),Yn({open:_,ref:c.context.popupRef,onComplete(){_&&c.context.onOpenChangeComplete?.(!0)}});function S(e){return e===`touch`?c.context.popupRef.current:!0}let C=i===void 0?S:i,w=Ge(`div`,e,{state:{open:_,nested:h,transitionStatus:b,nestedDialogOpen:g>0},props:[f,{"aria-labelledby":y??void 0,"aria-describedby":l??void 0,role:x,tabIndex:-1,hidden:!m,onKeyDown(e){Pn.has(e.key)&&e.stopPropagation()},style:{[zc.nestedDialogs]:g}},s],ref:[t,c.context.popupRef,c.useStateSetter(`popupElement`)],stateAttributesMapping:Uc});return(0,G.jsx)(on,{context:d,openInteractionType:v,disabled:!m,closeOnFocusOut:!u,initialFocus:C,returnFocus:r,modal:p!==!1,restoreFocus:`popup`,children:w})}),Gc=W.forwardRef(function(e,t){let{keepMounted:n=!1,...r}=e,{store:i}=Lo(),a=i.useState(`mounted`),o=i.useState(`modal`),s=i.useState(`open`);return a||n?(0,G.jsx)(Vc.Provider,{value:n,children:(0,G.jsxs)(Jt,{ref:t,...r,children:[a&&o===!0&&(0,G.jsx)(Sn,{ref:i.context.internalBackdropRef,inert:Nn(!s)}),e.children]})}):null});function Kc(e){let{store:t,parentContext:n,actionsRef:r,isDrawer:i}=e,a=t.useState(`open`),o=t.useState(`disablePointerDismissal`),s=t.useState(`modal`),c=t.useState(`popupElement`),{openMethod:l,triggerProps:u}=Rn(a);uc(t);let{forceUnmount:d}=dc(a,t),f=W.useCallback(()=>{t.setOpen(!1,Lt(It))},[t]);W.useImperativeHandle(r,()=>({unmount:d,close:f}),[d,f]);let p=vc({popupStore:t,onOpenChange:t.setOpen,treatPopupAsFloatingElement:!0}),[m,h]=W.useState(0),[g,_]=W.useState(0),v=m===0,y=Ac(p),b=kn(p,{outsidePressEvent(){return t.context.internalBackdropRef.current||t.context.backdropRef.current?`intentional`:{mouse:s===`trap-focus`?`sloppy`:`intentional`,touch:`sloppy`}},outsidePress(e){if(!t.context.outsidePressEnabledRef.current||`button`in e&&e.button!==0||`touches`in e&&e.touches.length!==1)return!1;let n=zt(e);if(v&&!o){let e=n;return s&&(t.context.internalBackdropRef.current||t.context.backdropRef.current)?t.context.internalBackdropRef.current===e||t.context.backdropRef.current===e||kt(e,c)&&!e?.hasAttribute(`data-base-ui-portal`):!0}return!1},escapeKey:v});Ln(a&&s===!0,c);let{getReferenceProps:x,getFloatingProps:S,getTriggerProps:C}=pn([y,b]);t.useContextCallback(`onNestedDialogOpen`,(e,t)=>{h(e),_(t)}),t.useContextCallback(`onNestedDialogClose`,()=>{h(0),_(0)}),W.useEffect(()=>(n?.onNestedDialogOpen&&a&&n.onNestedDialogOpen(m+1,g+ +!!i),n?.onNestedDialogClose&&!a&&n.onNestedDialogClose(),()=>{n?.onNestedDialogClose&&a&&n.onNestedDialogClose()}),[i,a,m,g,n]);let w=W.useMemo(()=>x(u),[x,u]),T=W.useMemo(()=>C(u),[C,u]),E=W.useMemo(()=>S(),[S]);t.useSyncedValues({openMethod:l,activeTriggerProps:w,inactiveTriggerProps:T,popupProps:E,floatingRootContext:p,nestedOpenDialogCount:m,nestedOpenDrawerCount:g})}var qc={...hc,modal:H(e=>e.modal),nested:H(e=>e.nested),nestedOpenDialogCount:H(e=>e.nestedOpenDialogCount),nestedOpenDrawerCount:H(e=>e.nestedOpenDrawerCount),disablePointerDismissal:H(e=>e.disablePointerDismissal),openMethod:H(e=>e.openMethod),descriptionElementId:H(e=>e.descriptionElementId),titleElementId:H(e=>e.titleElementId),viewportElement:H(e=>e.viewportElement),role:H(e=>e.role)},Jc=class e extends hn{constructor(e){super(Yc(e),{popupRef:W.createRef(),backdropRef:W.createRef(),internalBackdropRef:W.createRef(),outsidePressEnabledRef:{current:!0},triggerElements:new Wt,onOpenChange:void 0,onOpenChangeComplete:void 0},qc)}setOpen=(e,t)=>{if(t.preventUnmountOnClose=()=>{this.set(`preventUnmountingOnClose`,!0)},!e&&t.trigger==null&&this.state.activeTriggerId!=null&&(t.trigger=this.state.activeTriggerElement??void 0),this.context.onOpenChange?.(e,t),t.isCanceled)return;this.state.floatingRootContext.dispatchOpenChange(e,t);let n={open:e},r=t.trigger?.id??null;(r||e)&&(n.activeTriggerId=r,n.activeTriggerElement=t.trigger??null),this.update(n)};static useStore(t,n){let r=Ve(()=>new e(n)).current;return t??r}};function Yc(e={}){return{...pc(),modal:!0,disablePointerDismissal:!1,popupElement:null,viewportElement:null,descriptionElementId:void 0,titleElementId:void 0,openMethod:null,nested:!1,nestedOpenDialogCount:0,nestedOpenDrawerCount:0,role:`dialog`,...e}}var Xc=W.createContext(!1);function Zc(e){let{children:t,open:n,defaultOpen:r=!1,onOpenChange:i,onOpenChangeComplete:a,disablePointerDismissal:o=!1,modal:s=!0,actionsRef:c,handle:l,triggerId:u,defaultTriggerId:d=null}=e,f=Lo(!0),p=W.useContext(Xc),m=!!f,h=Jc.useStore(l?.store,{open:r,openProp:n,activeTriggerId:d,triggerIdProp:u,modal:s,disablePointerDismissal:o,nested:m});On(()=>{n===void 0&&h.state.open===!1&&r===!0&&h.update({open:!0,activeTriggerId:d})}),h.useControlledProp(`openProp`,n),h.useControlledProp(`triggerIdProp`,u),h.useSyncedValues({disablePointerDismissal:o,nested:m,modal:s}),h.useContextCallback(`onOpenChange`,i),h.useContextCallback(`onOpenChangeComplete`,a);let g=h.useState(`payload`);Kc({store:h,actionsRef:c,parentContext:f?.store.context,isDrawer:p,onOpenChange:i,triggerIdProp:u});let _=W.useMemo(()=>({store:h}),[h]);return(0,G.jsx)(Xc.Provider,{value:!1,children:(0,G.jsx)(Io.Provider,{value:_,children:typeof t==`function`?t({payload:g}):t})})}var Qc=W.forwardRef(function(e,t){let{render:n,className:r,style:i,id:a,...o}=e,{store:s}=Lo(),c=At(a);return s.useSyncedValueWithCleanup(`titleElementId`,c),Ge(`h2`,e,{ref:t,props:[{id:c},o]})});function $c(e){let t=(0,K.c)(4),n;t[0]===e?n=t[1]:({...n}=e,t[0]=e,t[1]=n);let r;return t[2]===n?r=t[3]:(r=(0,G.jsx)(Zc,{"data-slot":`sheet`,...n}),t[2]=n,t[3]=r),r}function el(e){let t=(0,K.c)(4),n;t[0]===e?n=t[1]:({...n}=e,t[0]=e,t[1]=n);let r;return t[2]===n?r=t[3]:(r=(0,G.jsx)(Gc,{"data-slot":`sheet-portal`,...n}),t[2]=n,t[3]=r),r}function tl(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`data-closed:fade-out-0 data-open:fade-in-0 data-closed:animate-out data-open:animate-in fixed inset-0 z-50 bg-black/80 duration-100 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(zo,{className:i,"data-slot":`sheet-overlay`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function nl(e){let t=(0,K.c)(17),n,r,i,a,o;t[0]===e?(n=t[1],r=t[2],i=t[3],a=t[4],o=t[5]):({className:r,children:n,side:a,showCloseButton:o,...i}=e,t[0]=e,t[1]=n,t[2]=r,t[3]=i,t[4]=a,t[5]=o);let s=a===void 0?`right`:a,c=o===void 0?!0:o,l;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,G.jsx)(tl,{}),t[6]=l):l=t[6];let u;t[7]===r?u=t[8]:(u=B(`data-[side=right]:data-closed:slide-out-to-right-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=top]:data-closed:slide-out-to-top-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:fade-out-0 data-open:fade-in-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-closed:animate-out data-open:animate-in fixed z-50 flex flex-col bg-background bg-clip-padding text-xs/relaxed shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm`,r),t[7]=r,t[8]=u);let d;t[9]===c?d=t[10]:(d=c&&(0,G.jsxs)(Bo,{"data-slot":`sheet-close`,render:(0,G.jsx)(vt,{className:`absolute top-4 right-4`,size:`icon-sm`,variant:`ghost`}),children:[(0,G.jsx)(Mo,{}),(0,G.jsx)(`span`,{className:`sr-only`,children:`Close`})]}),t[9]=c,t[10]=d);let f;return t[11]!==n||t[12]!==i||t[13]!==s||t[14]!==u||t[15]!==d?(f=(0,G.jsxs)(el,{children:[l,(0,G.jsxs)(Wc,{className:u,"data-side":s,"data-slot":`sheet-content`,...i,children:[n,d]})]}),t[11]=n,t[12]=i,t[13]=s,t[14]=u,t[15]=d,t[16]=f):f=t[16],f}function rl(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`flex flex-col gap-1.5 p-6`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`div`,{className:i,"data-slot":`sheet-header`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function il(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`text-sm font-medium text-foreground`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(Qc,{className:i,"data-slot":`sheet-title`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function al(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`text-xs/relaxed text-muted-foreground`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(Vo,{className:i,"data-slot":`sheet-description`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}var ol=W.createContext(void 0);function sl(e){let t=W.useContext(ol);if(t===void 0&&!e)throw Error(We(72));return t}var cl={...hc,disabled:H(e=>e.disabled),instantType:H(e=>e.instantType),isInstantPhase:H(e=>e.isInstantPhase),trackCursorAxis:H(e=>e.trackCursorAxis),disableHoverablePopup:H(e=>e.disableHoverablePopup),lastOpenChangeReason:H(e=>e.openChangeReason),closeOnClick:H(e=>e.closeOnClick),closeDelay:H(e=>e.closeDelay),hasViewport:H(e=>e.hasViewport)},ll=class e extends hn{constructor(e){super({...ul(),...e},{popupRef:W.createRef(),onOpenChange:void 0,onOpenChangeComplete:void 0,triggerElements:new Wt},cl)}setOpen=(e,t)=>{let n=t.reason,r=n===Pt,i=e&&n===`trigger-focus`,a=!e&&(n===`trigger-press`||n===`escape-key`);if(t.preventUnmountOnClose=()=>{this.set(`preventUnmountingOnClose`,!0)},this.context.onOpenChange?.(e,t),t.isCanceled)return;this.state.floatingRootContext.dispatchOpenChange(e,t);let o=()=>{let r={open:e,openChangeReason:n};i?r.instantType=`focus`:a?r.instantType=`dismiss`:n===`trigger-hover`&&(r.instantType=void 0);let o=t.trigger?.id??null;(o||e)&&(r.activeTriggerId=o,r.activeTriggerElement=t.trigger??null),this.update(r)};r?Ys.flushSync(o):o()};static useStore(t,n){let r=Ve(()=>new e(n)).current,i=t??r,a=vc({popupStore:i,onOpenChange:i.setOpen});return i.state.floatingRootContext=a,i}};function ul(){return{...pc(),disabled:!1,instantType:void 0,isInstantPhase:!1,trackCursorAxis:`none`,disableHoverablePopup:!1,openChangeReason:null,closeOnClick:!0,closeDelay:0,hasViewport:!1}}var dl=cn(function(e){let{disabled:t=!1,defaultOpen:n=!1,open:r,disableHoverablePopup:i=!1,trackCursorAxis:a=`none`,actionsRef:o,onOpenChange:s,onOpenChangeComplete:c,handle:l,triggerId:u,defaultTriggerId:d=null,children:f}=e,p=ll.useStore(l?.store,{open:n,openProp:r,activeTriggerId:d,triggerIdProp:u});On(()=>{r===void 0&&p.state.open===!1&&n===!0&&p.update({open:!0,activeTriggerId:d})}),p.useControlledProp(`openProp`,r),p.useControlledProp(`triggerIdProp`,u),p.useContextCallback(`onOpenChange`,s),p.useContextCallback(`onOpenChangeComplete`,c);let m=p.useState(`open`),h=!t&&m,g=p.useState(`activeTriggerId`),_=p.useState(`payload`);p.useSyncedValues({trackCursorAxis:a,disableHoverablePopup:i}),ht(()=>{m&&t&&p.setOpen(!1,Lt(Nt))},[m,t,p]),p.useSyncedValue(`disabled`,t),uc(p);let{forceUnmount:v,transitionStatus:y}=dc(h,p),b=p.select(`floatingRootContext`),x=p.useState(`isInstantPhase`),S=p.useState(`instantType`),C=p.useState(`lastOpenChangeReason`),w=W.useRef(null);ht(()=>{y===`ending`&&C===`none`||y!==`ending`&&x?(S!==`delay`&&(w.current=S),p.set(`instantType`,`delay`)):w.current!==null&&(p.set(`instantType`,w.current),w.current=null)},[y,x,C,S,p]),ht(()=>{h&&(g??p.set(`payload`,void 0))},[p,g,h]);let T=W.useCallback(()=>{p.setOpen(!1,Lt(It))},[p]);W.useImperativeHandle(o,()=>({unmount:v,close:T}),[v,T]);let{getReferenceProps:E,getFloatingProps:D,getTriggerProps:O}=pn([kn(b,{enabled:!t,referencePress:()=>p.select(`closeOnClick`)}),Zo(b,{enabled:!t&&a!==`none`,axis:a===`none`?void 0:a})]),k=W.useMemo(()=>E(),[E]),ee=W.useMemo(()=>O(),[O]),A=W.useMemo(()=>D(),[D]);return p.useSyncedValues({activeTriggerProps:k,inactiveTriggerProps:ee,popupProps:A}),(0,G.jsx)(ol.Provider,{value:p,children:typeof f==`function`?f({payload:_}):f})}),fl=W.createContext(void 0);function pl(){return W.useContext(fl)}var ml=function(e){return e[e.popupOpen=In.popupOpen]=`popupOpen`,e.triggerDisabled=`data-trigger-disabled`,e}({}),hl=An(function(e,t){let{className:n,render:r,handle:i,payload:a,disabled:o,delay:s,closeOnClick:c=!0,closeDelay:l,id:u,style:d,...f}=e,p=sl(!0),m=i?.store??p;if(!m)throw Error(We(82));let h=At(u),g=m.useState(`isTriggerActive`,h),_=m.useState(`isOpenedByTrigger`,h),v=m.useState(`floatingRootContext`),y=W.useRef(null),b=s??600,x=l??0,{registerTrigger:S,isMountedByThisTrigger:C}=lc(h,y,m,{payload:a,closeOnClick:c,closeDelay:x}),w=pl(),{delayRef:T,isInstantPhase:E,hasProvider:D}=Jo(v,{open:_});m.useSyncedValue(`isInstantPhase`,E);let O=m.useState(`disabled`),k=o??O,ee=m.useState(`trackCursorAxis`),A=m.useState(`disableHoverablePopup`),j=Oc(v,{enabled:!k,mouseOnly:!0,move:!1,handleClose:!A&&ee!==`both`?Rc():null,restMs(){let e=w?.delay,t=typeof T.current==`object`?T.current.open:void 0,n=b;return D&&(n=t===0?0:s??e??b),n},delay(){let e=typeof T.current==`object`?T.current.close:void 0,t=x;return l==null&&D&&(t=e),{close:t}},triggerElementRef:y,isActiveTrigger:g,isClosing:()=>m.select(`transitionStatus`)===`ending`}),te=bc(v,{enabled:!k}).reference,M={open:_},N=m.useState(`triggerProps`,C);return Ge(`button`,e,{state:M,ref:[t,S,y],props:[j,te,N,{onPointerDown(){m.set(`closeOnClick`,c)},id:h,[ml.triggerDisabled]:k?``:void 0},f],stateAttributesMapping:yn})}),gl=W.createContext(void 0);function _l(){let e=W.useContext(gl);if(e===void 0)throw Error(We(70));return e}var vl=W.forwardRef(function(e,t){let{children:n,container:r,className:i,render:a,style:o,...s}=e,{portalNode:c,portalSubtree:l}=Qt({container:r,ref:t,componentProps:e,elementProps:s});return!l&&!c?null:(0,G.jsxs)(W.Fragment,{children:[l,c&&Ys.createPortal(n,c)]})}),yl=W.forwardRef(function(e,t){let{keepMounted:n=!1,...r}=e;return sl().useState(`mounted`)||n?(0,G.jsx)(gl.Provider,{value:n,children:(0,G.jsx)(vl,{ref:t,...r})}):null}),bl=W.createContext(void 0);function xl(){let e=W.useContext(bl);if(e===void 0)throw Error(We(71));return e}var Sl=W.createContext(void 0);function Cl(){return W.useContext(Sl)?.direction??`ltr`}var wl=e=>({name:`arrow`,options:e,async fn(t){let{x:n,y:r,placement:i,rects:a,platform:o,elements:s,middlewareData:c}=t,{element:l,padding:u=0,offsetParent:d=`real`}=wn(e,t)||{};if(l==null)return{};let f=Un(u),p={x:n,y:r},m=Mn(i),h=En(m),g=await o.getDimensions(l),_=m===`y`,v=_?`top`:`left`,y=_?`bottom`:`right`,b=_?`clientHeight`:`clientWidth`,x=a.reference[h]+a.reference[m]-p[m]-a.floating[h],S=p[m]-a.reference[m],C=d===`real`?await o.getOffsetParent?.(l):s.floating,w=s.floating[b]||a.floating[h];(!w||!await o.isElement?.(C))&&(w=s.floating[b]||a.floating[h]);let T=x/2-S/2,E=w/2-g[h]/2-1,D=Math.min(f[v],E),O=Math.min(f[y],E),k=D,ee=w-g[h]-O,A=w/2-g[h]/2+T,j=jn(k,A,ee),te=!c.arrow&&Fn(i)!=null&&A!==j&&a.reference[h]/2-(A({...wl(e),options:[e,t]}),El={name:`hide`,async fn(e){let{width:t,height:n,x:r,y:i}=e.rects.reference,a=t===0&&n===0&&r===0&&i===0;return{data:{referenceHidden:(await sc().fn(e)).data?.referenceHidden||a}}}},Dl={sideX:`left`,sideY:`top`},Ol={name:`adaptiveOrigin`,async fn(e){let{x:t,y:n,rects:{floating:r},elements:{floating:i},platform:a,strategy:o,placement:s}=e,c=at(i),l=c.getComputedStyle(i);if(!(l.transitionDuration!==`0s`&&l.transitionDuration!==``))return{x:t,y:n,data:Dl};let u=await a.getOffsetParent?.(i),d={width:0,height:0};if(o===`fixed`&&c?.visualViewport)d={width:c.visualViewport.width,height:c.visualViewport.height};else if(u===c){let e=Vt(i);d={width:e.documentElement.clientWidth,height:e.documentElement.clientHeight}}else await a.isElement?.(u)&&(d=await a.getDimensions(u));let f=mn(s),p=t,m=n;f===`left`&&(p=d.width-(t+r.width)),f===`top`&&(m=d.height-(n+r.height));let h=f===`left`?`right`:Dl.sideX,g=f===`top`?`bottom`:Dl.sideY;return{x:p,y:m,data:{sideX:h,sideY:g}}}};function kl(e,t,n){let r=e===`inline-start`||e===`inline-end`;return{top:`top`,right:r?n?`inline-start`:`inline-end`:`right`,bottom:`bottom`,left:r?n?`inline-end`:`inline-start`:`left`}[t]}function Al(e,t,n){let{rects:r,placement:i}=e;return{side:kl(t,mn(i),n),align:Fn(i)||`center`,anchor:{width:r.reference.width,height:r.reference.height},positioner:{width:r.floating.width,height:r.floating.height}}}function jl(e){let{anchor:t,positionMethod:n=`absolute`,side:r=`bottom`,sideOffset:i=0,align:a=`center`,alignOffset:o=0,collisionBoundary:s,collisionPadding:c=5,sticky:l=!1,arrowPadding:u=5,disableAnchorTracking:d=!1,keepMounted:f=!1,floatingRootContext:p,mounted:m,collisionAvoidance:h,shiftCrossAxis:g=!1,nodeId:_,adaptiveOrigin:v,lazyFlip:y=!1,externalTree:b}=e,[x,S]=W.useState(null);!m&&x!==null&&S(null);let C=h.side||`flip`,w=h.align||`flip`,T=h.fallbackAxisSide||`end`,E=typeof t==`function`?t:void 0,D=st(E),O=E?D:t,k=vn(t),ee=vn(m),A=Cl()===`rtl`,j=x||{top:`top`,right:`right`,bottom:`bottom`,left:`left`,"inline-end":A?`left`:`right`,"inline-start":A?`right`:`left`}[r],te=a===`center`?j:`${j}-${a}`,M=c,N=+(r===`bottom`),ne=+(r===`top`),re=+(r===`right`),ie=+(r===`left`);typeof M==`number`?M={top:M+N,right:M+ie,bottom:M+ne,left:M+re}:M&&={top:(M.top||0)+N,right:(M.right||0)+ie,bottom:(M.bottom||0)+ne,left:(M.left||0)+re};let ae={boundary:s===`clipping-ancestors`?`clippingAncestors`:s,padding:M},oe=W.useRef(null),P=vn(i),se=vn(o),ce=[nc(e=>{let t=Al(e,r,A),n=typeof P.current==`function`?P.current(t):P.current,i=typeof se.current==`function`?se.current(t):se.current;return{mainAxis:n,crossAxis:i,alignmentAxis:i}},[typeof i==`function`?0:i,typeof o==`function`?0:o,A,r])],le=w===`none`&&C!==`shift`,ue=!le&&(l||g||C===`shift`),de=C===`none`?null:ac({...ae,padding:{top:M.top+1,right:M.right+1,bottom:M.bottom+1,left:M.left+1},mainAxis:!g&&C===`flip`,crossAxis:w===`flip`?`alignment`:!1,fallbackAxisSideDirection:T}),fe=le?null:rc(e=>{let t=Vt(e.elements.floating).documentElement;return{...ae,rootBoundary:g?{x:0,y:0,width:t.clientWidth,height:t.clientHeight}:void 0,mainAxis:w!==`none`,crossAxis:ue,limiter:l||g?void 0:ic(e=>{if(!oe.current)return{};let{width:t,height:n}=oe.current.getBoundingClientRect(),r=Gt(mn(e.placement)),i=r===`y`?t:n,a=r===`y`?M.left+M.right:M.top+M.bottom;return{offset:i/2+a/2}})}},[ae,l,g,M,w]);C===`shift`||w===`shift`||a===`center`?ce.push(fe,de):ce.push(de,fe),ce.push(oc({...ae,apply({elements:{floating:e},availableWidth:t,availableHeight:n,rects:r}){if(!ee.current)return;let i=e.style;i.setProperty(`--available-width`,`${t}px`),i.setProperty(`--available-height`,`${n}px`);let a=at(e).devicePixelRatio||1,{x:o,y:s,width:c,height:l}=r.reference,u=(Math.round((o+c)*a)-Math.round(o*a))/a,d=(Math.round((s+l)*a)-Math.round(s*a))/a;i.setProperty(`--anchor-width`,`${u}px`),i.setProperty(`--anchor-height`,`${d}px`)}}),Tl(()=>({element:oe.current||Vt(oe.current).createElement(`div`),padding:u,offsetParent:`floating`}),[u]),{name:`transformOrigin`,fn(e){let{elements:t,middlewareData:n,placement:a,rects:o,y:s}=e,c=mn(a),l=Gt(c),u=oe.current,d=n.arrow?.x||0,f=n.arrow?.y||0,p=u?.clientWidth||0,m=u?.clientHeight||0,h=d+p/2,g=f+m/2,_=Math.abs(n.shift?.y||0),v=o.reference.height/2,y=typeof i==`function`?i(Al(e,r,A)):i,b=_>y,x={top:`${h}px calc(100% + ${y}px)`,bottom:`${h}px ${-y}px`,left:`calc(100% + ${y}px) ${g}px`,right:`${-y}px ${g}px`}[c],S=`${h}px ${o.reference.y+v-s}px`;return t.floating.style.setProperty(`--transform-origin`,ue&&l===`y`&&b?S:x),{}}},El,v),ht(()=>{!m&&p&&p.update({referenceElement:null,floatingElement:null,domReferenceElement:null,positionReference:null})},[m,p]);let pe=W.useMemo(()=>({elementResize:!d&&typeof ResizeObserver<`u`,layoutShift:!d&&typeof IntersectionObserver<`u`}),[d]),{refs:me,elements:he,x:ge,y:_e,middlewareData:ve,update:ye,placement:be,context:xe,isPositioned:Se,floatingStyles:Ce}=_c({rootContext:p,open:f?m:void 0,placement:te,middleware:ce,strategy:n,whileElementsMounted:f?void 0:(...e)=>Vs(...e,pe),nodeId:_,externalTree:b}),{sideX:we,sideY:Te}=ve.adaptiveOrigin||Dl,Ee=Se?n:`fixed`,F=W.useMemo(()=>{let e=v?{position:Ee,[we]:ge,[Te]:_e}:{position:Ee,...Ce};return Se||(e.opacity=0),e},[v,Ee,we,ge,Te,_e,Ce,Se]),De=W.useRef(null);ht(()=>{if(!m)return;let e=k.current,t=typeof e==`function`?e():e,n=(Ml(t)?t.current:t)||null;n!==De.current&&(me.setPositionReference(n),De.current=n)},[m,me,O,k]),W.useEffect(()=>{if(!m)return;let e=k.current;typeof e!=`function`&&Ml(e)&&e.current!==De.current&&(me.setPositionReference(e.current),De.current=e.current)},[m,me,O,k]),W.useEffect(()=>{if(f&&m&&he.domReference&&he.floating)return Vs(he.domReference,he.floating,ye,pe)},[f,m,he,ye,pe]);let Oe=mn(be),ke=kl(r,Oe,A),Ae=Fn(be)||`center`,je=!!ve.hide?.referenceHidden;ht(()=>{y&&m&&Se&&S(Oe)},[y,m,Se,Oe]);let Me=W.useMemo(()=>({position:`absolute`,top:ve.arrow?.y,left:ve.arrow?.x}),[ve.arrow]),Ne=ve.arrow?.centerOffset!==0;return W.useMemo(()=>({positionerStyles:F,arrowStyles:Me,arrowRef:oe,arrowUncentered:Ne,side:ke,align:Ae,physicalSide:Oe,anchorHidden:je,refs:me,context:xe,isPositioned:Se,update:ye}),[F,Me,oe,Ne,ke,Ae,Oe,je,me,xe,Se,ye])}function Ml(e){return e!=null&&`current`in e}function Nl(e){return e===`starting`?rn:Ue}function Pl(e,t,{styles:n,transitionStatus:r,props:i,refs:a,hidden:o,inert:s=!1}){let c={...n};return s&&(c.pointerEvents=`none`),Ge(`div`,e,{state:t,ref:a,props:[{role:`presentation`,hidden:o,style:c},Nl(r),i],stateAttributesMapping:en})}var Fl=W.forwardRef(function(e,t){let{render:n,className:r,anchor:i,positionMethod:a=`absolute`,side:o=`top`,align:s=`center`,sideOffset:c=0,alignOffset:l=0,collisionBoundary:u=`clipping-ancestors`,collisionPadding:d=5,arrowPadding:f=5,sticky:p=!1,disableAnchorTracking:m=!1,collisionAvoidance:h=Gn,style:g,..._}=e,v=sl(),y=_l(),b=v.useState(`open`),x=v.useState(`mounted`),S=v.useState(`trackCursorAxis`),C=v.useState(`disableHoverablePopup`),w=v.useState(`floatingRootContext`),T=v.useState(`instantType`),E=v.useState(`transitionStatus`),D=jl({anchor:i,positionMethod:a,floatingRootContext:w,mounted:x,side:o,sideOffset:c,align:s,alignOffset:l,collisionBoundary:u,collisionPadding:d,sticky:p,arrowPadding:f,disableAnchorTracking:m,keepMounted:y,collisionAvoidance:h,adaptiveOrigin:v.useState(`hasViewport`)?Ol:void 0}),O=Pl(e,W.useMemo(()=>({open:b,side:D.side,align:D.align,anchorHidden:D.anchorHidden,instant:S===`none`?T:`tracking-cursor`}),[b,D.side,D.align,D.anchorHidden,S,T]),{styles:D.positionerStyles,transitionStatus:E,props:_,refs:[t,v.useStateSetter(`positionerElement`)],hidden:!x,inert:!b||S===`both`||C});return(0,G.jsx)(bl.Provider,{value:D,children:O})}),Il={...en,...Jn},J=W.forwardRef(function(e,t){let{className:n,render:r,style:i,...a}=e,o=sl(),{side:s,align:c}=xl(),l=o.useState(`open`),u=o.useState(`instantType`),d=o.useState(`transitionStatus`),f=o.useState(`popupProps`),p=o.useState(`floatingRootContext`);Yn({open:l,ref:o.context.popupRef,onComplete(){l&&o.context.onOpenChangeComplete?.(!0)}});let m=o.useState(`disabled`),h=o.useState(`closeDelay`);return Ec(p,{enabled:!m,closeDelay:h}),Ge(`div`,e,{state:{open:l,side:s,align:c,instant:u,transitionStatus:d},ref:[t,o.context.popupRef,o.useStateSetter(`popupElement`)],props:[f,Nl(d),a],stateAttributesMapping:Il})}),Ll=W.forwardRef(function(e,t){let{className:n,render:r,style:i,...a}=e,o=sl(),s=o.useState(`open`),c=o.useState(`instantType`),{arrowRef:l,side:u,align:d,arrowUncentered:f,arrowStyles:p}=xl();return Ge(`div`,e,{state:{open:s,side:u,align:d,uncentered:f,instant:c},ref:[t,l],props:[{style:p,"aria-hidden":!0},a],stateAttributesMapping:en})}),Y=function(e){let{delay:t,closeDelay:n,timeout:r=400}=e,i=W.useMemo(()=>({delay:t,closeDelay:n}),[t,n]),a=W.useMemo(()=>({open:t,close:n}),[t,n]);return(0,G.jsx)(fl.Provider,{value:i,children:(0,G.jsx)(qo,{delay:a,timeoutMs:r,children:e.children})})};function X(e){let t=(0,K.c)(6),n,r;t[0]===e?(n=t[1],r=t[2]):({delay:r,...n}=e,t[0]=e,t[1]=n,t[2]=r);let i=r===void 0?0:r,a;return t[3]!==i||t[4]!==n?(a=(0,G.jsx)(Y,{"data-slot":`tooltip-provider`,delay:i,...n}),t[3]=i,t[4]=n,t[5]=a):a=t[5],a}function Rl(e){let t=(0,K.c)(4),n;t[0]===e?n=t[1]:({...n}=e,t[0]=e,t[1]=n);let r;return t[2]===n?r=t[3]:(r=(0,G.jsx)(X,{children:(0,G.jsx)(dl,{"data-slot":`tooltip`,...n})}),t[2]=n,t[3]=r),r}function zl(e){let t=(0,K.c)(4),n;t[0]===e?n=t[1]:({...n}=e,t[0]=e,t[1]=n);let r;return t[2]===n?r=t[3]:(r=(0,G.jsx)(hl,{"data-slot":`tooltip-trigger`,...n}),t[2]=n,t[3]=r),r}function Bl(e){let t=(0,K.c)(21),n,r,i,a,o,s,c;t[0]===e?(n=t[1],r=t[2],i=t[3],a=t[4],o=t[5],s=t[6],c=t[7]):({className:r,side:a,sideOffset:o,align:s,alignOffset:c,children:n,...i}=e,t[0]=e,t[1]=n,t[2]=r,t[3]=i,t[4]=a,t[5]=o,t[6]=s,t[7]=c);let l=a===void 0?`top`:a,u=o===void 0?4:o,d=s===void 0?`center`:s,f=c===void 0?0:c,p;t[8]===r?p=t[9]:(p=B(`data-open:fade-in-0 data-open:zoom-in-95 data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-closed:fade-out-0 data-closed:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=delayed-open]:animate-in data-closed:animate-out data-open:animate-in z-50 w-fit max-w-xs origin-(--transform-origin) rounded-md bg-foreground px-3 py-1.5 text-xs text-background **:data-[slot=kbd]:rounded-md`,r),t[8]=r,t[9]=p);let m;t[10]===Symbol.for(`react.memo_cache_sentinel`)?(m=(0,G.jsx)(Ll,{className:`z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5`}),t[10]=m):m=t[10];let h;t[11]!==n||t[12]!==i||t[13]!==p?(h=(0,G.jsxs)(J,{className:p,"data-slot":`tooltip-content`,...i,children:[n,m]}),t[11]=n,t[12]=i,t[13]=p,t[14]=h):h=t[14];let g;return t[15]!==d||t[16]!==f||t[17]!==l||t[18]!==u||t[19]!==h?(g=(0,G.jsx)(yl,{children:(0,G.jsx)(Fl,{align:d,alignOffset:f,className:`isolate z-50`,side:l,sideOffset:u,children:h})}),t[15]=d,t[16]=f,t[17]=l,t[18]=u,t[19]=h,t[20]=g):g=t[20],g}var Vl=window.matchMedia(`(max-width: 767px)`);function Hl(e){return Vl.addEventListener(`change`,e),()=>Vl.removeEventListener(`change`,e)}function Ul(){return Vl.matches}function Wl(){return(0,W.useSyncExternalStore)(Hl,Ul)}var Gl=`sidebar_state`,Kl=3600*24*7,ql=`12rem`,Jl=`16rem`,Yl=`3rem`,Xl=`b`,Zl=W.createContext(null);function Ql(){let e=W.useContext(Zl);if(!e)throw Error(`useSidebar must be used within a SidebarProvider.`);return e}function $l(e){let t=(0,K.c)(36),n,r,i,a,o,s,c;t[0]===e?(n=t[1],r=t[2],i=t[3],a=t[4],o=t[5],s=t[6],c=t[7]):({defaultOpen:c,open:i,onOpenChange:o,className:r,style:s,children:n,...a}=e,t[0]=e,t[1]=n,t[2]=r,t[3]=i,t[4]=a,t[5]=o,t[6]=s,t[7]=c);let l=c===void 0?!0:c,u=Wl(),[d,f]=W.useState(!1),[p,m]=W.useState(l),h=i??p,g;t[8]!==h||t[9]!==o?(g=e=>{let t=typeof e==`function`?e(h):e;o?o(t):m(t),document.cookie=`${Gl}=${t}; path=/; max-age=${Kl}`},t[8]=h,t[9]=o,t[10]=g):g=t[10];let _=g,v;t[11]!==u||t[12]!==_?(v=()=>u?f(tu):_(eu),t[11]=u,t[12]=_,t[13]=v):v=t[13];let y=v,b,x;t[14]===y?(b=t[15],x=t[16]):(b=()=>{let e=e=>{e.key===Xl&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),y())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},x=[y],t[14]=y,t[15]=b,t[16]=x),W.useEffect(b,x);let S=h?`expanded`:`collapsed`,C;t[17]!==u||t[18]!==h||t[19]!==d||t[20]!==_||t[21]!==S||t[22]!==y?(C={state:S,open:h,setOpen:_,isMobile:u,openMobile:d,setOpenMobile:f,toggleSidebar:y},t[17]=u,t[18]=h,t[19]=d,t[20]=_,t[21]=S,t[22]=y,t[23]=C):C=t[23];let w=C,T;t[24]===r?T=t[25]:(T=B(`group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar`,r),t[24]=r,t[25]=T);let E;t[26]===s?E=t[27]:(E={"--sidebar-width":ql,"--sidebar-width-icon":Yl,...s},t[26]=s,t[27]=E);let D=E,O;t[28]!==n||t[29]!==a||t[30]!==T||t[31]!==D?(O=(0,G.jsx)(`div`,{className:T,"data-slot":`sidebar-wrapper`,style:D,...a,children:n}),t[28]=n,t[29]=a,t[30]=T,t[31]=D,t[32]=O):O=t[32];let k;return t[33]!==w||t[34]!==O?(k=(0,G.jsx)(Zl.Provider,{value:w,children:O}),t[33]=w,t[34]=O,t[35]=k):k=t[35],k}function eu(e){return!e}function tu(e){return!e}function nu(e){let t=(0,K.c)(46),n,r,i,a,o,s;t[0]===e?(n=t[1],r=t[2],i=t[3],a=t[4],o=t[5],s=t[6]):({side:a,variant:o,collapsible:s,className:r,children:n,...i}=e,t[0]=e,t[1]=n,t[2]=r,t[3]=i,t[4]=a,t[5]=o,t[6]=s);let c=a===void 0?`left`:a,l=o===void 0?`sidebar`:o,u=s===void 0?`offExamples`:s,{isMobile:d,state:f,openMobile:p,setOpenMobile:m}=Ql();if(u===`none`){let e;t[7]===r?e=t[8]:(e=B(`flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground`,r),t[7]=r,t[8]=e);let a;return t[9]!==n||t[10]!==i||t[11]!==e?(a=(0,G.jsx)(`div`,{className:e,"data-slot":`sidebar`,...i,children:n}),t[9]=n,t[10]=i,t[11]=e,t[12]=a):a=t[12],a}if(d){let e;t[13]===Symbol.for(`react.memo_cache_sentinel`)?(e={"--sidebar-width":Jl},t[13]=e):e=t[13];let r=e,a;t[14]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,G.jsxs)(rl,{className:`sr-only`,children:[(0,G.jsx)(il,{children:`Sidebar`}),(0,G.jsx)(al,{children:`Displays the mobile sidebar.`})]}),t[14]=a):a=t[14];let o;t[15]===n?o=t[16]:(o=(0,G.jsx)(`div`,{className:`flex h-full w-full flex-col`,children:n}),t[15]=n,t[16]=o);let s;t[17]!==c||t[18]!==o?(s=(0,G.jsxs)(nl,{className:`w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden`,"data-mobile":`true`,"data-sidebar":`sidebar`,"data-slot":`sidebar`,side:c,style:r,children:[a,o]}),t[17]=c,t[18]=o,t[19]=s):s=t[19];let l;return t[20]!==p||t[21]!==i||t[22]!==m||t[23]!==s?(l=(0,G.jsx)($c,{onOpenChange:m,open:p,...i,children:s}),t[20]=p,t[21]=i,t[22]=m,t[23]=s,t[24]=l):l=t[24],l}let h=f===`collapsed`?u:``,g=l===`floating`||l===`inset`?`group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]`:`group-data-[collapsible=icon]:w-(--sidebar-width-icon)`,_;t[25]===g?_=t[26]:(_=B(`relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear`,`group-data-[collapsible=offExamples]:w-0`,`group-data-[side=right]:rotate-180`,g),t[25]=g,t[26]=_);let v;t[27]===_?v=t[28]:(v=(0,G.jsx)(`div`,{className:_,"data-slot":`sidebar-gap`}),t[27]=_,t[28]=v);let y=c===`left`?`left-0 group-data-[collapsible=offExamples]:left-[calc(var(--sidebar-width)*-1)]`:`right-0 group-data-[collapsible=offExamples]:right-[calc(var(--sidebar-width)*-1)]`,b=l===`floating`||l===`inset`?`p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]`:`group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l`,x;t[29]!==r||t[30]!==y||t[31]!==b?(x=B(`fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex`,y,b,r),t[29]=r,t[30]=y,t[31]=b,t[32]=x):x=t[32];let S;t[33]===n?S=t[34]:(S=(0,G.jsx)(`div`,{className:`flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 group-data-[variant=floating]:ring-sidebar-border`,"data-sidebar":`sidebar`,"data-slot":`sidebar-inner`,children:n}),t[33]=n,t[34]=S);let C;t[35]!==i||t[36]!==x||t[37]!==S?(C=(0,G.jsx)(`div`,{className:x,"data-slot":`sidebar-container`,...i,children:S}),t[35]=i,t[36]=x,t[37]=S,t[38]=C):C=t[38];let w;return t[39]!==c||t[40]!==f||t[41]!==C||t[42]!==h||t[43]!==v||t[44]!==l?(w=(0,G.jsxs)(`div`,{className:`group peer hidden text-sidebar-foreground md:block`,"data-collapsible":h,"data-side":c,"data-slot":`sidebar`,"data-state":f,"data-variant":l,children:[v,C]}),t[39]=c,t[40]=f,t[41]=C,t[42]=h,t[43]=v,t[44]=l,t[45]=w):w=t[45],w}function ru(e){let t=(0,K.c)(15),n,r,i;t[0]===e?(n=t[1],r=t[2],i=t[3]):({className:n,onClick:r,...i}=e,t[0]=e,t[1]=n,t[2]=r,t[3]=i);let{toggleSidebar:a}=Ql(),o;t[4]===n?o=t[5]:(o=B(n),t[4]=n,t[5]=o);let s;t[6]!==r||t[7]!==a?(s=e=>{r?.(e),a()},t[6]=r,t[7]=a,t[8]=s):s=t[8];let c,l;t[9]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,G.jsx)(To,{}),l=(0,G.jsx)(`span`,{className:`sr-only`,children:`Toggle Sidebar`}),t[9]=c,t[10]=l):(c=t[9],l=t[10]);let u;return t[11]!==i||t[12]!==o||t[13]!==s?(u=(0,G.jsxs)(vt,{className:o,"data-sidebar":`trigger`,"data-slot":`sidebar-trigger`,onClick:s,size:`icon-lg`,variant:`ghost`,...i,children:[c,l]}),t[11]=i,t[12]=o,t[13]=s,t[14]=u):u=t[14],u}function iu(e){let t=(0,K.c)(9),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let{toggleSidebar:i}=Ql(),a;t[3]===n?a=t[4]:(a=B(`absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex`,`in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize`,`[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize`,`group-data-[collapsible=offExamples]:translate-x-0 group-data-[collapsible=offExamples]:after:left-full hover:group-data-[collapsible=offExamples]:bg-sidebar`,`[[data-side=left][data-collapsible=offExamples]_&]:-right-2`,`[[data-side=right][data-collapsible=offExamples]_&]:-left-2`,n),t[3]=n,t[4]=a);let o;return t[5]!==r||t[6]!==a||t[7]!==i?(o=(0,G.jsx)(`button`,{"aria-label":`Toggle Sidebar`,className:a,"data-sidebar":`rail`,"data-slot":`sidebar-rail`,onClick:i,tabIndex:-1,title:`Toggle Sidebar`,...r}),t[5]=r,t[6]=a,t[7]=i,t[8]=o):o=t[8],o}function au(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`flex flex-col gap-2 p-2`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`div`,{className:i,"data-sidebar":`header`,"data-slot":`sidebar-header`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function ou(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`flex flex-col gap-2 p-2`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`div`,{className:i,"data-sidebar":`footer`,"data-slot":`sidebar-footer`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function su(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`mx-2 w-auto bg-sidebar-border`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(Ot,{className:i,"data-sidebar":`separator`,"data-slot":`sidebar-separator`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function cu(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`no-scrollbar flex min-h-0 flex-1 flex-col gap-0 overflow-auto group-data-[collapsible=icon]:overflow-hidden`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`div`,{className:i,"data-sidebar":`content`,"data-slot":`sidebar-content`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function lu(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`relative flex w-full min-w-0 flex-col px-2 py-1`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`div`,{className:i,"data-sidebar":`group`,"data-slot":`sidebar-group`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function uu(e){let t=(0,K.c)(10),n,r,i,a;if(t[0]!==e){let{className:o,render:s,...c}=e;n=s,a=lo,r=`div`,i=He({className:B(`flex h-8 shrink-0 items-center rounded-md px-2 text-xs text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0`,o)},c),t[0]=e,t[1]=n,t[2]=r,t[3]=i,t[4]=a}else n=t[1],r=t[2],i=t[3],a=t[4];let o;t[5]===Symbol.for(`react.memo_cache_sentinel`)?(o={slot:`sidebar-group-label`,sidebar:`group-label`},t[5]=o):o=t[5];let s;return t[6]!==n||t[7]!==r||t[8]!==i?(s={defaultTagName:r,props:i,render:n,state:o},t[6]=n,t[7]=r,t[8]=i,t[9]=s):s=t[9],a(s)}function du(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`flex w-full min-w-0 flex-col gap-px`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`ul`,{className:i,"data-sidebar":`menu`,"data-slot":`sidebar-menu`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}function fu(e){let t=(0,K.c)(8),n,r;t[0]===e?(n=t[1],r=t[2]):({className:n,...r}=e,t[0]=e,t[1]=n,t[2]=r);let i;t[3]===n?i=t[4]:(i=B(`group/menu-item relative`,n),t[3]=n,t[4]=i);let a;return t[5]!==r||t[6]!==i?(a=(0,G.jsx)(`li`,{className:i,"data-sidebar":`menu-item`,"data-slot":`sidebar-menu-item`,...r}),t[5]=r,t[6]=i,t[7]=a):a=t[7],a}var pu=Ke(`peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-[calc(var(--radius-sm)+2px)] p-2 text-left text-xs ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate`,{variants:{variant:{default:`hover:bg-sidebar-accent hover:text-sidebar-accent-foreground`,outline:`bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]`},size:{default:`h-8 text-xs`,sm:`h-7 text-xs`,lg:`h-12 text-xs group-data-[collapsible=icon]:p-0!`}},defaultVariants:{variant:`default`,size:`default`}});function mu(e){let t=(0,K.c)(15),{render:n,isActive:r,variant:i,size:a,tooltip:o,className:s,...c}=e,l=r===void 0?!1:r,u=i===void 0?`default`:i,d=a===void 0?`default`:a,{isMobile:f,state:p}=Ql(),m=He({className:B(pu({variant:u,size:d}),s)},c),h=o?zl:n,g;t[0]!==l||t[1]!==d?(g={slot:`sidebar-menu-button`,sidebar:`menu-button`,size:d,active:l},t[0]=l,t[1]=d,t[2]=g):g=t[2];let _;t[3]!==m||t[4]!==h||t[5]!==g?(_={defaultTagName:`button`,props:m,render:h,state:g},t[3]=m,t[4]=h,t[5]=g,t[6]=_):_=t[6];let v=lo(_);if(!o)return v;let y;t[7]===o?y=t[8]:(y=typeof o==`string`?{children:o}:o,t[7]=o,t[8]=y);let b=y,x=p!==`collapsed`||f,S;t[9]!==x||t[10]!==b?(S=(0,G.jsx)(Bl,{align:`center`,hidden:x,side:`right`,...b}),t[9]=x,t[10]=b,t[11]=S):S=t[11];let C;return t[12]!==v||t[13]!==S?(C=(0,G.jsxs)(Rl,{children:[v,S]}),t[12]=v,t[13]=S,t[14]=C):C=t[14],C}var hu=`ap-southeast-2`,gu=9999;async function _u({action:e,credentials:t,service:n=`spinifex`}){let r=window.location.protocol.replace(`:`,``),i=`Action=${e}`,a=new Xe({method:`POST`,protocol:r,hostname:`localhost`,port:gu,path:`/`,headers:{host:`localhost:${gu}`,"content-type":`application/x-www-form-urlencoded`},body:i}),o=await new Qe({credentials:{accessKeyId:t.accessKeyId,secretAccessKey:t.secretAccessKey},region:hu,service:n,sha256:Ze}).sign(a),s={};for(let[e,t]of Object.entries(o.headers))typeof t==`string`&&(s[e]=t);let c=`${window.location.protocol}//${window.location.host}/proxy/awsgw/`,l=await fetch(c,{method:`POST`,headers:s,body:i});if(!l.ok){let t=await l.text().catch(()=>``);throw Error(`${e} failed: ${l.status}${t?` - ${t}`:``}`)}return await l.json()}var vu=`000000000001`,yu=(0,W.createContext)(void 0);function bu({children:e}){let[t,n]=(0,W.useState)({isAdmin:!1,accountId:null,userName:null,version:null,license:null,loading:!0});return(0,W.useEffect)(()=>{async function e(){let e=Ye();if(!e){n(e=>({...e,loading:!1}));return}try{let t=await _u({action:`GetCallerIdentity`,credentials:e}),r=t.account_id===vu,i=null;if(r)try{i=await _u({action:`GetVersion`,credentials:e})}catch{}n({isAdmin:r,accountId:t.account_id,userName:t.user_name,version:i,license:i?.license??null,loading:!1})}catch{n(e=>({...e,loading:!1}))}}e()},[]),(0,G.jsx)(yu,{value:t,children:e})}function xu(){let e=(0,W.useContext)(yu);if(e===void 0)throw Error(`useAdmin must be used within an AdminProvider`);return e}function Su(){let e=(0,K.c)(8),{theme:t,setTheme:n}=co(),r;e[0]!==n||e[1]!==t?(r=()=>{n(t===`light`?`dark`:t===`dark`?`light`:`dark`)},e[0]=n,e[1]=t,e[2]=r):r=e[2];let i=r,a,o,s;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,G.jsx)(ko,{className:`size-[1.2rem] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90`}),o=(0,G.jsx)(Co,{className:`absolute size-[1.2rem] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0`}),s=(0,G.jsx)(`span`,{className:`sr-only`,children:`Toggle theme`}),e[3]=a,e[4]=o,e[5]=s):(a=e[3],o=e[4],s=e[5]);let c;return e[6]===i?c=e[7]:(c=(0,G.jsxs)(vt,{className:`rounded-full`,onClick:i,size:`icon-sm`,variant:`ghost`,children:[a,o,s]}),e[6]=i,e[7]=c),c}function Cu(){let e=(0,K.c)(7),{isAdmin:t,license:n}=xu(),r=t&&n===`open-source`,i,a;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(i=B(`z-50 flex h-10 shrink-0 items-center gap-2 border-b border-sidebar-border bg-sidebar px-4 text-sidebar-foreground`,`sticky top-0`),a=(0,G.jsx)(ru,{className:`-ml-1`}),e[0]=i,e[1]=a):(i=e[0],a=e[1]);let o;e[2]===r?o=e[3]:(o=r&&(0,G.jsx)(`a`,{href:`https://mulgadc.com/purchase`,target:`_blank`,rel:`noopener noreferrer`,className:B(mt({variant:`outline`,size:`sm`})),children:`Upgrade`}),e[2]=r,e[3]=o);let s;e[4]===Symbol.for(`react.memo_cache_sentinel`)?(s=(0,G.jsx)(Su,{}),e[4]=s):s=e[4];let c;return e[5]===o?c=e[6]:(c=(0,G.jsxs)(`header`,{className:i,children:[a,(0,G.jsxs)(`div`,{className:`flex w-full items-center justify-end gap-2`,children:[o,s]})]}),e[5]=o,e[6]=c),c}function wu(){let e=(0,K.c)(3),t,n;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,G.jsx)(`h1`,{className:`text-4xl font-bold`,children:`404`}),n=(0,G.jsx)(`p`,{className:`text-muted-foreground`,children:`Page not found`}),e[0]=t,e[1]=n):(t=e[0],n=e[1]);let r;return e[2]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,G.jsxs)(`div`,{className:`flex flex-1 flex-col items-center justify-center gap-4`,children:[t,n,(0,G.jsx)(Ie,{to:`/`,children:(0,G.jsx)(vt,{variant:`outline`,children:`Go back home`})})]}),e[2]=r):r=e[2],r}function Tu(){let e=(0,K.c)(144),t;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={select:Eu},e[0]=t):t=e[0];let n=Xa(t),r=Re(),i=S(),{isAdmin:a}=xu(),o;e[1]!==r||e[2]!==i?(o=function(){$e(),Be(),i.clear(),r({to:`/login`})},e[1]=r,e[2]=i,e[3]=o):o=e[3];let s=o,c;e[4]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,G.jsxs)(au,{className:`flex flex-row items-center gap-2 px-4 py-3`,children:[(0,G.jsx)(`img`,{src:`/mulga-logo.svg`,alt:`Mulga`,className:`size-6 shrink-0 dark:invert`}),(0,G.jsx)(`span`,{className:`truncate text-sm font-semibold group-data-[collapsible=icon]:hidden`,children:`Spinifex`})]}),e[4]=c):c=e[4];let l;e[5]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,G.jsx)(uu,{children:`General`}),e[5]=l):l=e[5];let u=n===`/`,d,f;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,G.jsx)(_o,{className:`size-4`}),f=(0,G.jsx)(`span`,{children:`Dashboard`}),e[6]=d,e[7]=f):(d=e[6],f=e[7]);let p;e[8]===u?p=e[9]:(p=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/`,children:(0,G.jsxs)(mu,{isActive:u,tooltip:`Dashboard`,children:[d,f]})})}),e[8]=u,e[9]=p);let m;e[10]!==a||e[11]!==n?(m=a&&(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/nodes`,children:(0,G.jsxs)(mu,{isActive:n.startsWith(`/nodes`),tooltip:`Nodes`,children:[(0,G.jsx)(Eo,{className:`size-4`}),(0,G.jsx)(`span`,{children:`Nodes`})]})})}),e[10]=a,e[11]=n,e[12]=m):m=e[12];let h;e[13]!==p||e[14]!==m?(h=(0,G.jsxs)(lu,{children:[l,(0,G.jsxs)(du,{children:[p,m]})]}),e[13]=p,e[14]=m,e[15]=h):h=e[15];let g;e[16]===Symbol.for(`react.memo_cache_sentinel`)?(g=(0,G.jsx)(uu,{children:`EC2`}),e[16]=g):g=e[16];let _;e[17]===n?_=e[18]:(_=n.startsWith(`/ec2/describe-instances`)||n.startsWith(`/ec2/run-instances`),e[17]=n,e[18]=_);let v,y;e[19]===Symbol.for(`react.memo_cache_sentinel`)?(v=(0,G.jsx)(Eo,{className:`size-4`}),y=(0,G.jsx)(`span`,{children:`Instances`}),e[19]=v,e[20]=y):(v=e[19],y=e[20]);let b;e[21]===_?b=e[22]:(b=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-instances`,children:(0,G.jsxs)(mu,{isActive:_,tooltip:`EC2 Instances`,children:[v,y]})})}),e[21]=_,e[22]=b);let x;e[23]===n?x=e[24]:(x=n.startsWith(`/ec2/describe-images`),e[23]=n,e[24]=x);let C,w;e[25]===Symbol.for(`react.memo_cache_sentinel`)?(C=(0,G.jsx)(vo,{className:`size-4`}),w=(0,G.jsx)(`span`,{children:`Images`}),e[25]=C,e[26]=w):(C=e[25],w=e[26]);let T;e[27]===x?T=e[28]:(T=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-images`,children:(0,G.jsxs)(mu,{isActive:x,tooltip:`Images`,children:[C,w]})})}),e[27]=x,e[28]=T);let E;e[29]===n?E=e[30]:(E=n.startsWith(`/ec2/describe-key-pairs`),e[29]=n,e[30]=E);let D,O;e[31]===Symbol.for(`react.memo_cache_sentinel`)?(D=(0,G.jsx)(yo,{className:`size-4`}),O=(0,G.jsx)(`span`,{children:`Key Pairs`}),e[31]=D,e[32]=O):(D=e[31],O=e[32]);let k;e[33]===E?k=e[34]:(k=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-key-pairs`,children:(0,G.jsxs)(mu,{isActive:E,tooltip:`Key Pairs`,children:[D,O]})})}),e[33]=E,e[34]=k);let ee;e[35]===n?ee=e[36]:(ee=n.startsWith(`/ec2/describe-volumes`)||n.startsWith(`/ec2/create-volume`)||n.startsWith(`/ec2/modify-volume`),e[35]=n,e[36]=ee);let A,j;e[37]===Symbol.for(`react.memo_cache_sentinel`)?(A=(0,G.jsx)(go,{className:`size-4`}),j=(0,G.jsx)(`span`,{children:`Volumes`}),e[37]=A,e[38]=j):(A=e[37],j=e[38]);let te;e[39]===ee?te=e[40]:(te=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-volumes`,children:(0,G.jsxs)(mu,{isActive:ee,tooltip:`Volumes`,children:[A,j]})})}),e[39]=ee,e[40]=te);let M;e[41]===n?M=e[42]:(M=n.startsWith(`/ec2/describe-snapshots`)||n.startsWith(`/ec2/create-snapshot`),e[41]=n,e[42]=M);let N,ne;e[43]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,G.jsx)(po,{className:`size-4`}),ne=(0,G.jsx)(`span`,{children:`Snapshots`}),e[43]=N,e[44]=ne):(N=e[43],ne=e[44]);let re;e[45]===M?re=e[46]:(re=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-snapshots`,children:(0,G.jsxs)(mu,{isActive:M,tooltip:`Snapshots`,children:[N,ne]})})}),e[45]=M,e[46]=re);let ie;e[47]===n?ie=e[48]:(ie=n.startsWith(`/ec2/describe-placement-groups`)||n.startsWith(`/ec2/create-placement-group`),e[47]=n,e[48]=ie);let ae,oe;e[49]===Symbol.for(`react.memo_cache_sentinel`)?(ae=(0,G.jsx)(bo,{className:`size-4`}),oe=(0,G.jsx)(`span`,{children:`Placement Groups`}),e[49]=ae,e[50]=oe):(ae=e[49],oe=e[50]);let P;e[51]===ie?P=e[52]:(P=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-placement-groups`,children:(0,G.jsxs)(mu,{isActive:ie,tooltip:`Placement Groups`,children:[ae,oe]})})}),e[51]=ie,e[52]=P);let se;e[53]===n?se=e[54]:(se=n.startsWith(`/ec2/describe-load-balancers`)||n.startsWith(`/ec2/create-load-balancer`),e[53]=n,e[54]=se);let ce,le;e[55]===Symbol.for(`react.memo_cache_sentinel`)?(ce=(0,G.jsx)(jo,{className:`size-4`}),le=(0,G.jsx)(`span`,{children:`Load Balancers`}),e[55]=ce,e[56]=le):(ce=e[55],le=e[56]);let ue;e[57]===se?ue=e[58]:(ue=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-load-balancers`,children:(0,G.jsxs)(mu,{isActive:se,tooltip:`Load Balancers`,children:[ce,le]})})}),e[57]=se,e[58]=ue);let de;e[59]===n?de=e[60]:(de=n.startsWith(`/ec2/describe-target-groups`)||n.startsWith(`/ec2/create-target-group`),e[59]=n,e[60]=de);let fe,pe;e[61]===Symbol.for(`react.memo_cache_sentinel`)?(fe=(0,G.jsx)(ho,{className:`size-4`}),pe=(0,G.jsx)(`span`,{children:`Target Groups`}),e[61]=fe,e[62]=pe):(fe=e[61],pe=e[62]);let me;e[63]===de?me=e[64]:(me=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-target-groups`,children:(0,G.jsxs)(mu,{isActive:de,tooltip:`Target Groups`,children:[fe,pe]})})}),e[63]=de,e[64]=me);let he;e[65]!==b||e[66]!==T||e[67]!==k||e[68]!==te||e[69]!==re||e[70]!==P||e[71]!==ue||e[72]!==me?(he=(0,G.jsxs)(lu,{children:[g,(0,G.jsxs)(du,{children:[b,T,k,te,re,P,ue,me]})]}),e[65]=b,e[66]=T,e[67]=k,e[68]=te,e[69]=re,e[70]=P,e[71]=ue,e[72]=me,e[73]=he):he=e[73];let ge;e[74]===Symbol.for(`react.memo_cache_sentinel`)?(ge=(0,G.jsx)(uu,{children:`Networking`}),e[74]=ge):ge=e[74];let _e;e[75]===n?_e=e[76]:(_e=n.startsWith(`/ec2/describe-vpcs`)||n.startsWith(`/ec2/create-vpc`),e[75]=n,e[76]=_e);let ve,ye;e[77]===Symbol.for(`react.memo_cache_sentinel`)?(ve=(0,G.jsx)(wo,{className:`size-4`}),ye=(0,G.jsx)(`span`,{children:`VPCs`}),e[77]=ve,e[78]=ye):(ve=e[77],ye=e[78]);let be;e[79]===_e?be=e[80]:(be=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-vpcs`,children:(0,G.jsxs)(mu,{isActive:_e,tooltip:`VPCs`,children:[ve,ye]})})}),e[79]=_e,e[80]=be);let xe;e[81]===n?xe=e[82]:(xe=n.startsWith(`/ec2/describe-subnets`)||n.startsWith(`/ec2/create-subnet`),e[81]=n,e[82]=xe);let Se,Ce;e[83]===Symbol.for(`react.memo_cache_sentinel`)?(Se=(0,G.jsx)(xo,{className:`size-4`}),Ce=(0,G.jsx)(`span`,{children:`Subnets`}),e[83]=Se,e[84]=Ce):(Se=e[83],Ce=e[84]);let we;e[85]===xe?we=e[86]:(we=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-subnets`,children:(0,G.jsxs)(mu,{isActive:xe,tooltip:`Subnets`,children:[Se,Ce]})})}),e[85]=xe,e[86]=we);let Te;e[87]===n?Te=e[88]:(Te=n.startsWith(`/ec2/describe-security-groups`)||n.startsWith(`/ec2/create-security-group`),e[87]=n,e[88]=Te);let Ee,F;e[89]===Symbol.for(`react.memo_cache_sentinel`)?(Ee=(0,G.jsx)(Do,{className:`size-4`}),F=(0,G.jsx)(`span`,{children:`Security Groups`}),e[89]=Ee,e[90]=F):(Ee=e[89],F=e[90]);let De;e[91]===Te?De=e[92]:(De=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/ec2/describe-security-groups`,children:(0,G.jsxs)(mu,{isActive:Te,tooltip:`Security Groups`,children:[Ee,F]})})}),e[91]=Te,e[92]=De);let Oe;e[93]!==be||e[94]!==we||e[95]!==De?(Oe=(0,G.jsxs)(lu,{children:[ge,(0,G.jsxs)(du,{children:[be,we,De]})]}),e[93]=be,e[94]=we,e[95]=De,e[96]=Oe):Oe=e[96];let ke;e[97]===Symbol.for(`react.memo_cache_sentinel`)?(ke=(0,G.jsx)(uu,{children:`IAM`}),e[97]=ke):ke=e[97];let Ae;e[98]===n?Ae=e[99]:(Ae=n.startsWith(`/iam/list-users`)||n.startsWith(`/iam/create-user`),e[98]=n,e[99]=Ae);let je,Me;e[100]===Symbol.for(`react.memo_cache_sentinel`)?(je=(0,G.jsx)(Ao,{className:`size-4`}),Me=(0,G.jsx)(`span`,{children:`Users`}),e[100]=je,e[101]=Me):(je=e[100],Me=e[101]);let Ne;e[102]===Ae?Ne=e[103]:(Ne=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/iam/list-users`,children:(0,G.jsxs)(mu,{isActive:Ae,tooltip:`Users`,children:[je,Me]})})}),e[102]=Ae,e[103]=Ne);let Pe;e[104]===n?Pe=e[105]:(Pe=n.startsWith(`/iam/list-policies`)||n.startsWith(`/iam/create-policy`),e[104]=n,e[105]=Pe);let Fe,I;e[106]===Symbol.for(`react.memo_cache_sentinel`)?(Fe=(0,G.jsx)(Oo,{className:`size-4`}),I=(0,G.jsx)(`span`,{children:`Policies`}),e[106]=Fe,e[107]=I):(Fe=e[106],I=e[107]);let L;e[108]===Pe?L=e[109]:(L=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/iam/list-policies`,children:(0,G.jsxs)(mu,{isActive:Pe,tooltip:`Policies`,children:[Fe,I]})})}),e[108]=Pe,e[109]=L);let Le;e[110]!==Ne||e[111]!==L?(Le=(0,G.jsxs)(lu,{children:[ke,(0,G.jsxs)(du,{children:[Ne,L]})]}),e[110]=Ne,e[111]=L,e[112]=Le):Le=e[112];let R;e[113]===Symbol.for(`react.memo_cache_sentinel`)?(R=(0,G.jsx)(uu,{children:`S3`}),e[113]=R):R=e[113];let z;e[114]===n?z=e[115]:(z=n.startsWith(`/s3/ls`),e[114]=n,e[115]=z);let ze,Ve;e[116]===Symbol.for(`react.memo_cache_sentinel`)?(ze=(0,G.jsx)(Eo,{className:`size-4`}),Ve=(0,G.jsx)(`span`,{children:`Buckets`}),e[116]=ze,e[117]=Ve):(ze=e[116],Ve=e[117]);let He;e[118]===z?He=e[119]:(He=(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/s3/ls`,children:(0,G.jsxs)(mu,{isActive:z,tooltip:`Buckets`,children:[ze,Ve]})})}),e[118]=z,e[119]=He);let Ue;e[120]!==a||e[121]!==n?(Ue=a&&(0,G.jsx)(fu,{children:(0,G.jsx)(Ie,{to:`/s3/service-metrics`,children:(0,G.jsxs)(mu,{isActive:n.startsWith(`/s3/service-metrics`),tooltip:`Service Metrics`,children:[(0,G.jsx)(uo,{className:`size-4`}),(0,G.jsx)(`span`,{children:`Service Metrics`})]})})}),e[120]=a,e[121]=n,e[122]=Ue):Ue=e[122];let We;e[123]!==He||e[124]!==Ue?(We=(0,G.jsxs)(lu,{children:[R,(0,G.jsxs)(du,{children:[He,Ue]})]}),e[123]=He,e[124]=Ue,e[125]=We):We=e[125];let Ge;e[126]===a?Ge=e[127]:(Ge=a&&(0,G.jsxs)(lu,{children:[(0,G.jsx)(uu,{children:`Documentation`}),(0,G.jsx)(du,{children:(0,G.jsx)(fu,{children:(0,G.jsx)(`a`,{href:`https://docs.mulgadc.com`,target:`_blank`,rel:`noopener noreferrer`,children:(0,G.jsxs)(mu,{tooltip:`Documentation`,children:[(0,G.jsx)(fo,{className:`size-4`}),(0,G.jsx)(`span`,{children:`Docs`})]})})})})]}),e[126]=a,e[127]=Ge);let Ke;e[128]!==he||e[129]!==Oe||e[130]!==Le||e[131]!==We||e[132]!==Ge||e[133]!==h?(Ke=(0,G.jsxs)(cu,{children:[h,he,Oe,Le,We,Ge]}),e[128]=he,e[129]=Oe,e[130]=Le,e[131]=We,e[132]=Ge,e[133]=h,e[134]=Ke):Ke=e[134];let qe;e[135]===Symbol.for(`react.memo_cache_sentinel`)?(qe=(0,G.jsx)(su,{className:`mx-0 w-full`}),e[135]=qe):qe=e[135];let B,Je;e[136]===Symbol.for(`react.memo_cache_sentinel`)?(B=(0,G.jsx)(So,{className:`size-4`}),Je=(0,G.jsx)(`span`,{children:`Sign out`}),e[136]=B,e[137]=Je):(B=e[136],Je=e[137]);let Ye;e[138]===s?Ye=e[139]:(Ye=(0,G.jsxs)(ou,{children:[qe,(0,G.jsx)(du,{children:(0,G.jsx)(fu,{children:(0,G.jsxs)(mu,{onClick:s,tooltip:`Sign out`,children:[B,Je]})})})]}),e[138]=s,e[139]=Ye);let Xe;e[140]===Symbol.for(`react.memo_cache_sentinel`)?(Xe=(0,G.jsx)(iu,{}),e[140]=Xe):Xe=e[140];let Ze;return e[141]!==Ke||e[142]!==Ye?(Ze=(0,G.jsxs)(nu,{collapsible:`icon`,children:[c,Ke,Ye,Xe]}),e[141]=Ke,e[142]=Ye,e[143]=Ze):Ze=e[143],Ze}function Eu(e){return e.pathname}function Du(e){let t=(0,K.c)(18),{error:n,reset:r}=e,i=be(),a=S(),o;t[0]!==a||t[1]!==r||t[2]!==i?(o=function(){a.invalidateQueries(),r(),i.invalidate()},t[0]=a,t[1]=r,t[2]=i,t[3]=o):o=t[3];let s=o,c;t[4]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,G.jsx)(Tu,{}),t[4]=c):c=t[4];let l;t[5]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,G.jsx)(Cu,{}),t[5]=l):l=t[5];let u,d;t[6]===Symbol.for(`react.memo_cache_sentinel`)?(u=(0,G.jsx)(`div`,{className:`flex justify-center`,children:(0,G.jsx)(mo,{className:`size-12 text-destructive`})}),d=(0,G.jsx)(`h1`,{className:`text-2xl font-semibold`,children:`Something went wrong`}),t[6]=u,t[7]=d):(u=t[6],d=t[7]);let f=n.message||`An unexpected error occurred`,p;t[8]===f?p=t[9]:(p=(0,G.jsx)(`p`,{className:`text-muted-foreground`,children:f}),t[8]=f,t[9]=p);let m;t[10]===s?m=t[11]:(m=(0,G.jsx)(vt,{onClick:s,variant:`default`,children:`Try Again`}),t[10]=s,t[11]=m);let h;t[12]===Symbol.for(`react.memo_cache_sentinel`)?(h=(0,G.jsx)(Ie,{to:`/`,children:(0,G.jsx)(vt,{variant:`outline`,children:`Go Home`})}),t[12]=h):h=t[12];let g;t[13]===m?g=t[14]:(g=(0,G.jsxs)(`div`,{className:`flex justify-center gap-2`,children:[m,h]}),t[13]=m,t[14]=g);let _;return t[15]!==g||t[16]!==p?(_=(0,G.jsxs)(G.Fragment,{children:[c,(0,G.jsxs)(`main`,{className:`flex flex-1 flex-col`,children:[l,(0,G.jsx)(`div`,{className:`flex flex-1 items-center justify-center p-6 pt-0`,children:(0,G.jsxs)(`div`,{className:`max-w-md space-y-4 text-center`,children:[u,d,p,g]})})]})]}),t[15]=g,t[16]=p,t[17]=_):_=t[17],_}var Ou=Le()({head:()=>({meta:[{title:`Mulga`}]}),component:()=>(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(to,{}),(0,G.jsx)(Tu,{}),(0,G.jsxs)(`main`,{className:`flex flex-1 flex-col`,children:[(0,G.jsx)(Cu,{}),(0,G.jsx)(`div`,{className:`flex flex-1 flex-col p-8`,children:(0,G.jsx)(Va,{})})]})]}),errorComponent:Du,notFoundComponent:wu}),ku=L(`/login`)({beforeLoad:()=>{if(Ye())throw Fe({to:`/`})},component:R(()=>z(()=>import(`./login.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15])),`component`)}),Au=L(`/_auth`)({beforeLoad:()=>{if(!Ye())throw Fe({to:`/login`})},component:R(()=>z(()=>import(`./route.js`),__vite__mapDeps([16,1])),`component`)}),ju=L(`/_auth/`)({loader:async({context:e})=>{await Promise.all([e.queryClient.ensureQueryData(ur),e.queryClient.ensureQueryData(vr),e.queryClient.ensureQueryData(_r),e.queryClient.ensureQueryData(tr),e.queryClient.ensureQueryData(Pr),e.queryClient.ensureQueryData(dr)])},head:()=>({meta:[{title:`Dashboard | Mulga`}]}),component:R(()=>z(()=>import(`./_auth.js`),__vite__mapDeps([17,1,3,4,18,2,5,6,19,20,21,22,23,24,25,26,27,28,29,30,31,9,14])),`component`)}),Mu=L(`/_auth/nodes`)({head:()=>({meta:[{title:`Nodes | Mulga`}]}),component:R(()=>z(()=>import(`./nodes.js`),__vite__mapDeps([32,1,21,22,23,33,29,31,3,4,9,19,14])),`component`)}),Nu=L(`/_auth/s3/service-metrics`)({head:()=>({meta:[{title:`Service Metrics | Mulga`}]}),component:R(()=>z(()=>import(`./service-metrics.js`),__vite__mapDeps([34,1,21,22,23,33,29,31,3,4,9,19,14])),`component`)}),Pu=L(`/_auth/s3/ls/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(Pr)},head:()=>({meta:[{title:`Buckets | S3 | Mulga`}]}),component:R(()=>z(()=>import(`./ls.js`),__vite__mapDeps([35,1,3,4,20,2,5,19,8,9,36,22,23,24,25,37,29])),`component`)}),Fu=L(`/_auth/s3/(buckets)/create-bucket`)({head:()=>({meta:[{title:`Create Bucket | S3 | Mulga`}]}),component:R(()=>z(()=>import(`./create-bucket.js`),__vite__mapDeps([38,1,39,2,3,4,5,23,40,13,41,25,42,24,26,43,8,9,44,27,45,46,47,29,15,10,11])),`component`)}),Iu=L(`/_auth/iam/(users)/create-user`)({head:()=>({meta:[{title:`Create User | IAM | Mulga`}]}),component:R(()=>z(()=>import(`./create-user.js`),__vite__mapDeps([48,1,49,2,3,4,5,23,40,13,41,25,42,24,26,43,8,9,44,27,45,46,47,29,15,10,11,50])),`component`)}),Lu=L(`/_auth/iam/(policies)/create-policy`)({head:()=>({meta:[{title:`Create Policy | IAM | Mulga`}]}),component:R(()=>z(()=>import(`./create-policy.js`),__vite__mapDeps([51,1,49,2,3,4,5,23,40,13,41,25,42,24,26,43,8,9,44,27,45,46,47,29,15,10,11,52,50])),`component`)}),Ru=L(`/_auth/ec2/(vpc)/create-vpc`)({head:()=>({meta:[{title:`Create VPC | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-vpc.js`),__vite__mapDeps([53,1,54,2,3,4,5,18,6,19,23,40,8,9,55,10,11,56,12,25,26,44,27,13,41,42,24,28,43,45,46,47,29,15,57])),`component`)}),zu=L(`/_auth/ec2/(volumes)/create-volume`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(mr)},head:()=>({meta:[{title:`Create Volume | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-volume.js`),__vite__mapDeps([58,1,54,2,3,4,5,18,6,19,23,40,55,8,9,10,11,56,12,25,26,44,27,13,36,22,41,42,24,43,45,46,47,29,15,57])),`component`)}),Bu=L(`/_auth/ec2/(target-groups)/create-target-group`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(_r)},head:()=>({meta:[{title:`Create Target Group | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-target-group.js`),__vite__mapDeps([59,1,18,2,3,4,5,6,19,60,23,40,13,36,22,41,25,42,24,26,43,8,9,44,27,45,46,61,7,10,11,12,55,56,62,63,15,47,29,64])),`component`)}),Vu=L(`/_auth/ec2/(subnet)/create-subnet`)({loader:async({context:e})=>{await Promise.all([e.queryClient.ensureQueryData(_r),e.queryClient.ensureQueryData(mr)])},head:()=>({meta:[{title:`Create Subnet | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-subnet.js`),__vite__mapDeps([65,1,3,4,54,2,5,18,6,19,23,40,55,8,9,10,11,56,12,25,26,44,27,13,36,22,41,42,24,43,45,46,47,29,15,57])),`component`)}),Hu=L(`/_auth/ec2/(snapshots)/create-snapshot`)({validateSearch:e=>({volumeId:typeof e.volumeId==`string`?e.volumeId:void 0}),loader:async({context:e})=>{await e.queryClient.ensureQueryData(vr)},head:()=>({meta:[{title:`Create Snapshot | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-snapshot.js`),__vite__mapDeps([66,1,54,2,3,4,5,18,6,19,23,40,55,8,9,10,11,56,12,25,26,44,27,13,36,22,41,42,24,43,45,46,47,29,15,52,57])),`component`)}),Uu=L(`/_auth/ec2/(security-groups)/create-security-group`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(_r)},head:()=>({meta:[{title:`Create Security Group | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-security-group.js`),__vite__mapDeps([67,1,3,4,54,2,5,18,6,19,23,40,55,8,9,10,11,56,12,25,26,44,27,13,36,22,41,42,24,43,45,46,47,29,15,57])),`component`)}),Wu=L(`/_auth/ec2/(placement-groups)/create-placement-group`)({head:()=>({meta:[{title:`Create Placement Group | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-placement-group.js`),__vite__mapDeps([68,1,54,2,3,4,5,18,6,19,23,40,55,8,9,10,11,56,12,25,26,44,27,13,41,42,24,43,45,46,47,29,15,57])),`component`)}),Z=L(`/_auth/ec2/(load-balancers)/create-load-balancer`)({loader:async({context:e})=>{await Promise.all([e.queryClient.ensureQueryData(_r),e.queryClient.ensureQueryData(Qn),e.queryClient.ensureQueryData(dr),e.queryClient.ensureQueryData(br),e.queryClient.ensureQueryData(fr)])},head:()=>({meta:[{title:`Create Load Balancer | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-load-balancer.js`),__vite__mapDeps([69,1,3,4,18,2,5,6,19,60,23,40,70,8,9,55,10,11,56,12,25,26,44,27,13,36,22,41,42,24,62,43,45,46,63,61,7,15,47,29,64])),`component`)}),Gu=L(`/_auth/ec2/(key)/import-key-pair`)({head:()=>({meta:[{title:`Import Key Pair | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./import-key-pair.js`),__vite__mapDeps([71,1,54,2,3,4,5,18,6,19,23,40,13,41,25,42,24,26,43,8,9,44,27,45,46,47,29,15,10,11,52,57])),`component`)}),Ku=L(`/_auth/ec2/(key)/create-key-pair`)({head:()=>({meta:[{title:`Create Key Pair | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./create-key-pair.js`),__vite__mapDeps([72,1,54,2,3,4,5,18,6,19,23,40,73,8,9,13,41,25,42,24,26,44,74,43,27,45,46,75,47,29,15,10,11,57])),`component`)}),qu=L(`/_auth/ec2/(instances)/run-instances`)({loader:async({context:e})=>{await Promise.all([e.queryClient.ensureQueryData(fr),e.queryClient.ensureQueryData(tr),e.queryClient.ensureQueryData($n),e.queryClient.ensureQueryData(Qn),e.queryClient.ensureQueryData(hr)])},head:()=>({meta:[{title:`Run Instances | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./run-instances.js`),__vite__mapDeps([76,1,54,2,3,4,5,18,6,19,23,40,7,8,9,10,11,12,55,56,25,26,44,27,13,36,22,41,42,24,43,45,46,29,15,57])),`component`)}),Ju=L(`/_auth/s3/ls/$bucket`)({component:R(()=>z(()=>import(`./route2.js`),__vite__mapDeps([77,1])),`component`)}),Yu=L(`/_auth/s3/ls/$bucket/`)({loader:async({context:e,params:t})=>{await e.queryClient.ensureQueryData(Fr(t.bucket))},head:({params:e})=>({meta:[{title:`${e.bucket} | S3 | Mulga`}]}),component:R(()=>z(()=>import(`./_bucket.js`),__vite__mapDeps([78,1,39,2,3,4,5,23,40,79,8,9,24,25,26,74,63,80,73,20,19,36,22,42,29])),`component`)}),Xu=L(`/_auth/iam/(users)/list-users/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(Mr)},head:()=>({meta:[{title:`Users | IAM | Mulga`}]}),component:R(()=>z(()=>import(`./list-users.js`),__vite__mapDeps([81,1,82,2,3,4,5,19,8,9,36,22,23,24,25,37,29])),`component`)}),Zu=L(`/_auth/iam/(policies)/list-policies/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(jr)},head:()=>({meta:[{title:`Policies | IAM | Mulga`}]}),component:R(()=>z(()=>import(`./list-policies.js`),__vite__mapDeps([83,1,82,2,3,4,5,19,8,9,36,22,23,24,25,37,29])),`component`)}),Qu=L(`/_auth/ec2/(vpc)/describe-vpcs/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(_r)},head:()=>({meta:[{title:`VPCs | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-vpcs.js`),__vite__mapDeps([84,1,3,4,18,2,5,6,19,8,9,36,22,23,24,25,37,29,30])),`component`)}),$u=L(`/_auth/ec2/(volumes)/describe-volumes/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(vr)},head:()=>({meta:[{title:`Volumes | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-volumes.js`),__vite__mapDeps([85,1,18,2,3,4,5,6,19,8,9,36,22,23,24,25,37,29,30])),`component`)}),ed=L(`/_auth/ec2/(target-groups)/describe-target-groups/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(br)},head:()=>({meta:[{title:`Target Groups | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-target-groups.js`),__vite__mapDeps([86,1,70,2,3,4,5,19,8,9,21,22,23,36,24,25,41,29])),`component`)}),td=L(`/_auth/ec2/(subnet)/describe-subnets/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(Qn)},head:()=>({meta:[{title:`Subnets | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-subnets.js`),__vite__mapDeps([87,1,3,4,18,2,5,6,19,8,9,36,22,23,24,25,37,29,30])),`component`)}),nd=L(`/_auth/ec2/(snapshots)/describe-snapshots/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(ar)},head:()=>({meta:[{title:`Snapshots | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-snapshots.js`),__vite__mapDeps([88,1,18,2,3,4,5,6,19,8,9,36,22,23,24,25,37,29,30])),`component`)}),rd=L(`/_auth/ec2/(security-groups)/describe-security-groups/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(dr)},head:()=>({meta:[{title:`Security Groups | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-security-groups.js`),__vite__mapDeps([89,1,18,2,3,4,5,6,19,8,9,36,22,23,24,25,37,29])),`component`)}),id=L(`/_auth/ec2/(placement-groups)/describe-placement-groups/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(hr)},head:()=>({meta:[{title:`Placement Groups | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-placement-groups.js`),__vite__mapDeps([90,1,18,2,3,4,5,6,19,8,9,36,22,23,24,25,37,29,30])),`component`)}),ad=L(`/_auth/ec2/(load-balancers)/describe-load-balancers/`)({loader:async({context:e})=>{await Promise.all([e.queryClient.ensureQueryData(xr),e.queryClient.ensureQueryData(fr)])},head:()=>({meta:[{title:`Load Balancers | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-load-balancers.js`),__vite__mapDeps([91,1,70,2,3,4,5,19,8,9,36,22,23,24,25,41,29,30])),`component`)}),od=L(`/_auth/ec2/(key)/describe-key-pairs/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(tr)},head:()=>({meta:[{title:`Key Pairs | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-key-pairs.js`),__vite__mapDeps([92,1,18,2,3,4,5,6,19,8,9,36,22,23,24,25,37,29])),`component`)}),sd=L(`/_auth/ec2/(instances)/describe-instances/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(ur)},head:()=>({meta:[{title:`Instances | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-instances.js`),__vite__mapDeps([93,1,18,2,3,4,5,6,19,8,9,36,22,23,24,25,37,29,30])),`component`)}),cd=L(`/_auth/ec2/(images)/describe-images/`)({loader:async({context:e})=>{await e.queryClient.ensureQueryData(fr)},head:()=>({meta:[{title:`Images | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./describe-images.js`),__vite__mapDeps([94,1,18,2,3,4,5,6,19,36,22,23,37,24,25,29,30,95])),`component`)}),ld=L(`/_auth/s3/ls/$bucket/$`)({loader:async({context:e,params:t})=>{let n=Je(t._splat??``);await e.queryClient.ensureQueryData(Fr(t.bucket,n))},head:({params:e})=>({meta:[{title:`${qe(e._splat??``,`${e.bucket}/`)} | S3 | Mulga`}]}),component:R(()=>z(()=>import(`./_.js`),__vite__mapDeps([96,1,39,2,3,4,5,23,40,79,8,9,24,25,26,74,63,80,73,20,19,36,22,42])),`component`)}),ud=L(`/_auth/iam/(users)/list-users/$userName`)({loader:async({context:e,params:t})=>{await Promise.all([e.queryClient.ensureQueryData(Ar(t.userName)),e.queryClient.ensureQueryData(Nr(t.userName)),e.queryClient.ensureQueryData(kr(t.userName)),e.queryClient.ensureQueryData(jr)])},head:({params:e})=>({meta:[{title:`${e.userName} | IAM | Mulga`}]}),component:R(()=>z(()=>import(`./_userName.js`),__vite__mapDeps([97,1,3,4,49,2,5,23,40,82,19,73,8,9,36,22,41,25,42,24,26,44,63,75,80,98,29,30,46])),`component`)}),dd=L(`/_auth/iam/(policies)/list-policies/$policyArn`)({loader:async({context:e,params:t})=>{let n=decodeURIComponent(t.policyArn),r=await e.queryClient.ensureQueryData(Or(n)),i=r.Policy?.DefaultVersionId;return i&&await e.queryClient.ensureQueryData(Dr(n,i)),r},head:({loaderData:e})=>({meta:[{title:`${e?.Policy?.PolicyName??`Policy`} | IAM | Mulga`}]}),component:R(()=>z(()=>import(`./_policyArn.js`),__vite__mapDeps([99,1,3,4,49,2,5,23,40,82,19,8,9,36,22,41,25,42,24,26,63,80,73,98,29])),`component`)}),fd=L(`/_auth/ec2/(vpc)/describe-vpcs/$id`)({loader:async({context:e,params:t})=>{await Promise.all([e.queryClient.ensureQueryData(er(t.id)),e.queryClient.ensureQueryData(Qn)])},head:({params:e})=>({meta:[{title:`${e.id} | VPC | Mulga`}]}),component:R(()=>z(()=>import(`./_id12.js`),__vite__mapDeps([100,1,3,4,54,2,5,18,6,19,23,40,8,9,36,22,24,25,41,42,26,63,80,73,98,29,30])),`component`)}),pd=L(`/_auth/ec2/(volumes)/modify-volume/$id`)({loader:async({context:e,params:t})=>{await e.queryClient.ensureQueryData(gr(t.id))},head:({params:e})=>({meta:[{title:`Resize ${e.id} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id11.js`),__vite__mapDeps([101,1,54,2,3,4,5,18,6,19,23,40,13,36,22,41,25,42,24,26,47,8,9,29,15,10,11,57])),`component`)}),md=L(`/_auth/ec2/(volumes)/describe-volumes/$id`)({loader:async({context:e,params:t})=>{await Promise.all([e.queryClient.ensureQueryData(gr(t.id)),e.queryClient.ensureQueryData(ur)])},head:({params:e})=>({meta:[{title:`${e.id} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id10.js`),__vite__mapDeps([102,1,3,4,54,2,5,18,6,19,23,40,73,8,9,55,10,11,56,12,25,26,44,27,36,22,24,41,42,63,80,98,29,30,15])),`component`)}),hd=L(`/_auth/ec2/(target-groups)/describe-target-groups/$id`)({loader:async({context:e,params:t})=>{let n=decodeURIComponent(t.id);await Promise.all([e.queryClient.ensureQueryData(Tr(n)),e.queryClient.ensureQueryData(Cr(n)),e.queryClient.ensureQueryData(yr([n])),e.queryClient.ensureQueryData(ur)])},head:({params:e})=>({meta:[{title:`${decodeURIComponent(e.id)} | Target Group | Mulga`}]}),component:R(()=>z(()=>import(`./_id9.js`),__vite__mapDeps([103,1,3,4,18,2,5,6,19,60,23,40,70,73,8,9,104,55,10,11,56,12,25,26,44,27,15,21,22,36,41,42,24,63,80,98,29])),`component`)}),gd=L(`/_auth/ec2/(subnet)/describe-subnets/$id`)({loader:async({context:e,params:t})=>{await e.queryClient.ensureQueryData(ir(t.id))},head:({params:e})=>({meta:[{title:`${e.id} | Subnet | Mulga`}]}),component:R(()=>z(()=>import(`./_id8.js`),__vite__mapDeps([105,1,3,4,54,2,5,18,6,19,23,40,8,9,36,22,24,25,41,42,26,63,80,73,98,29,30])),`component`)}),_d=L(`/_auth/ec2/(snapshots)/describe-snapshots/$id`)({loader:async({context:e,params:t})=>{await Promise.all([e.queryClient.ensureQueryData(cr(t.id)),e.queryClient.ensureQueryData(nr)])},head:({params:e})=>({meta:[{title:`${e.id} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id7.js`),__vite__mapDeps([106,1,3,4,54,2,5,18,6,19,23,40,73,8,9,36,22,24,25,41,42,26,45,63,80,98,29,30,15,10,11])),`component`)}),vd=L(`/_auth/ec2/(security-groups)/describe-security-groups/$id`)({loader:async({context:e,params:t})=>{await e.queryClient.ensureQueryData(rr(t.id))},head:({params:e})=>({meta:[{title:`${e.id} | Security Group | Mulga`}]}),component:R(()=>z(()=>import(`./_id6.js`),__vite__mapDeps([107,1,54,2,3,4,5,18,6,19,23,40,73,8,9,55,10,11,56,12,25,26,44,27,13,36,22,24,41,42,62,63,80,98,29,15,57])),`component`)}),yd=L(`/_auth/ec2/(placement-groups)/describe-placement-groups/$id`)({loader:async({context:e,params:t})=>{await Promise.all([e.queryClient.ensureQueryData(sr(t.id)),e.queryClient.ensureQueryData(ur)])},head:({params:e})=>({meta:[{title:`${e.id} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id5.js`),__vite__mapDeps([108,1,54,2,3,4,5,18,6,19,23,40,8,9,36,22,24,25,41,42,26,63,80,73,98,29,30])),`component`)}),Q=L(`/_auth/ec2/(load-balancers)/describe-load-balancers/$id`)({loader:async({context:e,params:t})=>{let n=decodeURIComponent(t.id);await Promise.all([e.queryClient.ensureQueryData(wr(n)),e.queryClient.ensureQueryData(Er(n)),e.queryClient.ensureQueryData(Sr(n)),e.queryClient.ensureQueryData(yr([n])),e.queryClient.ensureQueryData(br),e.queryClient.ensureQueryData(Qn)])},head:({params:e})=>({meta:[{title:`${decodeURIComponent(e.id)} | Load Balancer | Mulga`}]}),component:R(()=>z(()=>import(`./_id4.js`),__vite__mapDeps([109,1,3,4,18,2,5,6,19,60,23,40,70,73,8,9,55,10,11,56,12,25,26,44,27,104,15,13,36,22,41,42,24,63,80,98,29,30,64])),`component`)}),bd=L(`/_auth/ec2/(key)/describe-key-pairs/$id`)({loader:async({context:e,params:t})=>await e.queryClient.ensureQueryData(pr(t.id)),head:({loaderData:e})=>({meta:[{title:`${e?.KeyPairs?.[0]?.KeyName??`Key Pair`} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id3.js`),__vite__mapDeps([110,1,3,4,54,2,5,18,6,19,23,40,8,9,36,22,41,25,42,24,26,63,80,73,98,29])),`component`)}),xd=L(`/_auth/ec2/(instances)/describe-instances/$id`)({loader:async({context:e,params:t})=>{let[n]=await Promise.all([e.queryClient.ensureQueryData(or(t.id)),e.queryClient.ensureQueryData($n)]),r=n.Reservations?.[0]?.Instances?.[0]?.ImageId;return await e.queryClient.ensureQueryData(lr(r)),n},head:({loaderData:e})=>({meta:[{title:`${e?.Reservations?.[0]?.Instances?.[0]?.InstanceId??`Instance`} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id2.js`),__vite__mapDeps([111,1,3,4,54,2,5,18,6,19,23,40,73,8,9,55,10,11,56,12,25,26,44,27,36,22,24,42,63,80,98,29,30,15,52,112])),`component`)}),Sd=L(`/_auth/ec2/(images)/describe-images/$id`)({loader:async({context:e,params:t})=>await e.queryClient.ensureQueryData(lr(t.id)),head:({loaderData:e})=>({meta:[{title:`${e?.Images?.[0]?.Name??`Image`} | EC2 | Mulga`}]}),component:R(()=>z(()=>import(`./_id.js`),__vite__mapDeps([113,1,18,2,3,4,5,6,19,36,22,23,42,24,25,26,29,30,95,112,98])),`component`)}),Cd=ku.update({id:`/login`,path:`/login`,getParentRoute:()=>Ou}),$=Au.update({id:`/_auth`,getParentRoute:()=>Ou}),wd=ju.update({id:`/`,path:`/`,getParentRoute:()=>$}),Td=Mu.update({id:`/nodes`,path:`/nodes`,getParentRoute:()=>$}),Ed=Nu.update({id:`/s3/service-metrics`,path:`/s3/service-metrics`,getParentRoute:()=>$}),Dd=Pu.update({id:`/s3/ls/`,path:`/s3/ls/`,getParentRoute:()=>$}),Od=Fu.update({id:`/s3/(buckets)/create-bucket`,path:`/s3/create-bucket`,getParentRoute:()=>$}),kd=Iu.update({id:`/iam/(users)/create-user`,path:`/iam/create-user`,getParentRoute:()=>$}),Ad=Lu.update({id:`/iam/(policies)/create-policy`,path:`/iam/create-policy`,getParentRoute:()=>$}),jd=Ru.update({id:`/ec2/(vpc)/create-vpc`,path:`/ec2/create-vpc`,getParentRoute:()=>$}),Md=zu.update({id:`/ec2/(volumes)/create-volume`,path:`/ec2/create-volume`,getParentRoute:()=>$}),Nd=Bu.update({id:`/ec2/(target-groups)/create-target-group`,path:`/ec2/create-target-group`,getParentRoute:()=>$}),Pd=Vu.update({id:`/ec2/(subnet)/create-subnet`,path:`/ec2/create-subnet`,getParentRoute:()=>$}),Fd=Hu.update({id:`/ec2/(snapshots)/create-snapshot`,path:`/ec2/create-snapshot`,getParentRoute:()=>$}),Id=Uu.update({id:`/ec2/(security-groups)/create-security-group`,path:`/ec2/create-security-group`,getParentRoute:()=>$}),Ld=Wu.update({id:`/ec2/(placement-groups)/create-placement-group`,path:`/ec2/create-placement-group`,getParentRoute:()=>$}),Rd=Z.update({id:`/ec2/(load-balancers)/create-load-balancer`,path:`/ec2/create-load-balancer`,getParentRoute:()=>$}),zd=Gu.update({id:`/ec2/(key)/import-key-pair`,path:`/ec2/import-key-pair`,getParentRoute:()=>$}),Bd=Ku.update({id:`/ec2/(key)/create-key-pair`,path:`/ec2/create-key-pair`,getParentRoute:()=>$}),Vd=qu.update({id:`/ec2/(instances)/run-instances`,path:`/ec2/run-instances`,getParentRoute:()=>$}),Hd=Ju.update({id:`/s3/ls/$bucket`,path:`/s3/ls/$bucket`,getParentRoute:()=>$}),Ud=Yu.update({id:`/`,path:`/`,getParentRoute:()=>Hd}),Wd=Xu.update({id:`/iam/(users)/list-users/`,path:`/iam/list-users/`,getParentRoute:()=>$}),Gd=Zu.update({id:`/iam/(policies)/list-policies/`,path:`/iam/list-policies/`,getParentRoute:()=>$}),Kd=Qu.update({id:`/ec2/(vpc)/describe-vpcs/`,path:`/ec2/describe-vpcs/`,getParentRoute:()=>$}),qd=$u.update({id:`/ec2/(volumes)/describe-volumes/`,path:`/ec2/describe-volumes/`,getParentRoute:()=>$}),Jd=ed.update({id:`/ec2/(target-groups)/describe-target-groups/`,path:`/ec2/describe-target-groups/`,getParentRoute:()=>$}),Yd=td.update({id:`/ec2/(subnet)/describe-subnets/`,path:`/ec2/describe-subnets/`,getParentRoute:()=>$}),Xd=nd.update({id:`/ec2/(snapshots)/describe-snapshots/`,path:`/ec2/describe-snapshots/`,getParentRoute:()=>$}),Zd=rd.update({id:`/ec2/(security-groups)/describe-security-groups/`,path:`/ec2/describe-security-groups/`,getParentRoute:()=>$}),Qd=id.update({id:`/ec2/(placement-groups)/describe-placement-groups/`,path:`/ec2/describe-placement-groups/`,getParentRoute:()=>$}),$d=ad.update({id:`/ec2/(load-balancers)/describe-load-balancers/`,path:`/ec2/describe-load-balancers/`,getParentRoute:()=>$}),ef=od.update({id:`/ec2/(key)/describe-key-pairs/`,path:`/ec2/describe-key-pairs/`,getParentRoute:()=>$}),tf=sd.update({id:`/ec2/(instances)/describe-instances/`,path:`/ec2/describe-instances/`,getParentRoute:()=>$}),nf=cd.update({id:`/ec2/(images)/describe-images/`,path:`/ec2/describe-images/`,getParentRoute:()=>$}),rf=ld.update({id:`/$`,path:`/$`,getParentRoute:()=>Hd}),af=ud.update({id:`/iam/(users)/list-users/$userName`,path:`/iam/list-users/$userName`,getParentRoute:()=>$}),of=dd.update({id:`/iam/(policies)/list-policies/$policyArn`,path:`/iam/list-policies/$policyArn`,getParentRoute:()=>$}),sf=fd.update({id:`/ec2/(vpc)/describe-vpcs/$id`,path:`/ec2/describe-vpcs/$id`,getParentRoute:()=>$}),cf=pd.update({id:`/ec2/(volumes)/modify-volume/$id`,path:`/ec2/modify-volume/$id`,getParentRoute:()=>$}),lf=md.update({id:`/ec2/(volumes)/describe-volumes/$id`,path:`/ec2/describe-volumes/$id`,getParentRoute:()=>$}),uf=hd.update({id:`/ec2/(target-groups)/describe-target-groups/$id`,path:`/ec2/describe-target-groups/$id`,getParentRoute:()=>$}),df=gd.update({id:`/ec2/(subnet)/describe-subnets/$id`,path:`/ec2/describe-subnets/$id`,getParentRoute:()=>$}),ff=_d.update({id:`/ec2/(snapshots)/describe-snapshots/$id`,path:`/ec2/describe-snapshots/$id`,getParentRoute:()=>$}),pf=vd.update({id:`/ec2/(security-groups)/describe-security-groups/$id`,path:`/ec2/describe-security-groups/$id`,getParentRoute:()=>$}),mf=yd.update({id:`/ec2/(placement-groups)/describe-placement-groups/$id`,path:`/ec2/describe-placement-groups/$id`,getParentRoute:()=>$}),hf=Q.update({id:`/ec2/(load-balancers)/describe-load-balancers/$id`,path:`/ec2/describe-load-balancers/$id`,getParentRoute:()=>$}),gf=bd.update({id:`/ec2/(key)/describe-key-pairs/$id`,path:`/ec2/describe-key-pairs/$id`,getParentRoute:()=>$}),_f=xd.update({id:`/ec2/(instances)/describe-instances/$id`,path:`/ec2/describe-instances/$id`,getParentRoute:()=>$}),vf=Sd.update({id:`/ec2/(images)/describe-images/$id`,path:`/ec2/describe-images/$id`,getParentRoute:()=>$}),yf={AuthS3LsBucketSplatRoute:rf,AuthS3LsBucketIndexRoute:Ud},bf={AuthNodesRoute:Td,AuthIndexRoute:wd,AuthS3ServiceMetricsRoute:Ed,AuthS3LsBucketRouteRoute:Hd._addFileChildren(yf),AuthEc2instancesRunInstancesRoute:Vd,AuthEc2keyCreateKeyPairRoute:Bd,AuthEc2keyImportKeyPairRoute:zd,AuthEc2loadBalancersCreateLoadBalancerRoute:Rd,AuthEc2placementGroupsCreatePlacementGroupRoute:Ld,AuthEc2securityGroupsCreateSecurityGroupRoute:Id,AuthEc2snapshotsCreateSnapshotRoute:Fd,AuthEc2subnetCreateSubnetRoute:Pd,AuthEc2targetGroupsCreateTargetGroupRoute:Nd,AuthEc2volumesCreateVolumeRoute:Md,AuthEc2vpcCreateVpcRoute:jd,AuthIampoliciesCreatePolicyRoute:Ad,AuthIamusersCreateUserRoute:kd,AuthS3bucketsCreateBucketRoute:Od,AuthS3LsIndexRoute:Dd,AuthEc2imagesDescribeImagesIdRoute:vf,AuthEc2instancesDescribeInstancesIdRoute:_f,AuthEc2keyDescribeKeyPairsIdRoute:gf,AuthEc2loadBalancersDescribeLoadBalancersIdRoute:hf,AuthEc2placementGroupsDescribePlacementGroupsIdRoute:mf,AuthEc2securityGroupsDescribeSecurityGroupsIdRoute:pf,AuthEc2snapshotsDescribeSnapshotsIdRoute:ff,AuthEc2subnetDescribeSubnetsIdRoute:df,AuthEc2targetGroupsDescribeTargetGroupsIdRoute:uf,AuthEc2volumesDescribeVolumesIdRoute:lf,AuthEc2volumesModifyVolumeIdRoute:cf,AuthEc2vpcDescribeVpcsIdRoute:sf,AuthIampoliciesListPoliciesPolicyArnRoute:of,AuthIamusersListUsersUserNameRoute:af,AuthEc2imagesDescribeImagesIndexRoute:nf,AuthEc2instancesDescribeInstancesIndexRoute:tf,AuthEc2keyDescribeKeyPairsIndexRoute:ef,AuthEc2loadBalancersDescribeLoadBalancersIndexRoute:$d,AuthEc2placementGroupsDescribePlacementGroupsIndexRoute:Qd,AuthEc2securityGroupsDescribeSecurityGroupsIndexRoute:Zd,AuthEc2snapshotsDescribeSnapshotsIndexRoute:Xd,AuthEc2subnetDescribeSubnetsIndexRoute:Yd,AuthEc2targetGroupsDescribeTargetGroupsIndexRoute:Jd,AuthEc2volumesDescribeVolumesIndexRoute:qd,AuthEc2vpcDescribeVpcsIndexRoute:Kd,AuthIampoliciesListPoliciesIndexRoute:Gd,AuthIamusersListUsersIndexRoute:Wd},xf={AuthRouteRoute:$._addFileChildren(bf),LoginRoute:Cd},Sf=Ou._addFileChildren(xf)._addFileTypes(),Cf=new Jr({defaultOptions:{queries:{staleTime:5e3}}}),wf=Ka({routeTree:Sf,context:{queryClient:Cf},defaultPreload:`intent`,scrollRestoration:!0,defaultStructuralSharing:!0,defaultPreloadStaleTime:0}),Tf=document.querySelector(`#app`);Tf&&!Tf.innerHTML&&ao.createRoot(Tf).render((0,G.jsx)(W.StrictMode,{children:(0,G.jsx)(so,{defaultTheme:`dark`,storageKey:`spinifex-ui-theme`,children:(0,G.jsx)(D,{client:Cf,children:(0,G.jsx)(bu,{children:(0,G.jsx)($l,{children:(0,G.jsx)(Ya,{router:wf})})})})})}));export{gc as A,Eo as B,Cl as C,Kc as D,Jc as E,Io as F,lo as G,yo as H,Lo as I,Br as J,Va as K,Fo as L,Vo as M,Bo as N,Gc as O,zo as P,Mo as R,jl as S,Xc as T,go as U,wo as V,po as W,Hu as _,yd as a,Pl as b,gd as c,pd as d,fd as f,Yu as g,ld as h,Q as i,Rs as j,Wc as k,hd as l,ud as m,xd as n,vd as o,dd as p,Wr as q,bd as r,_d as s,Sd as t,md as u,xu as v,Qc as w,Nl as x,_u as y,Oo as z}; \ No newline at end of file diff --git a/spinifex/services/spinifexui/frontend/dist/assets/lb-image-missing-banner.js b/spinifex/services/spinifexui/frontend/dist/assets/lb-image-missing-banner.js deleted file mode 100644 index b0a579dc5..000000000 --- a/spinifex/services/spinifexui/frontend/dist/assets/lb-image-missing-banner.js +++ /dev/null @@ -1 +0,0 @@ -import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./system-managed.js";var r=t(),i=e();function a(){let e=(0,r.c)(1),t;return e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,i.jsxs)(`div`,{className:`mb-6 max-w-4xl rounded-md border border-amber-500/50 bg-amber-500/10 p-4`,children:[(0,i.jsx)(`h2`,{className:`text-sm font-semibold`,children:`Load balancer image not imported`}),(0,i.jsx)(`p`,{className:`mt-1 text-sm text-muted-foreground`,children:`The load balancer system image has not been imported on this cluster. A cluster administrator must run the following command before load balancers can be created:`}),(0,i.jsxs)(`pre`,{className:`mt-2 overflow-x-auto rounded bg-muted px-3 py-2 font-mono text-xs`,children:[`spx admin images import --name `,n]})]}),e[0]=t):t=e[0],t}export{a as t}; \ No newline at end of file diff --git a/spinifex/services/spinifexui/frontend/dist/assets/system-managed.js b/spinifex/services/spinifexui/frontend/dist/assets/system-managed.js index 0b6b770d6..bff20f580 100644 --- a/spinifex/services/spinifexui/frontend/dist/assets/system-managed.js +++ b/spinifex/services/spinifexui/frontend/dist/assets/system-managed.js @@ -1 +1 @@ -var e=`lb-alpine-3.21.6-x86_64`;function t(e){return e.Tags?.some(e=>e.Key===`spinifex:managed-by`)??!1}function n(e){return e.Tags?.some(e=>e.Key===`spinifex:managed-by`&&e.Value===`elbv2`)??!1}function r(e){return e.some(n)}export{r as n,t as r,e as t}; \ No newline at end of file +function e(e){return e.Tags?.some(e=>e.Key===`spinifex:managed-by`)??!1}export{e as t}; \ No newline at end of file diff --git a/spinifex/services/spinifexui/frontend/dist/assets/upload-button.js b/spinifex/services/spinifexui/frontend/dist/assets/upload-button.js index 5a5f768ab..bd02905b1 100644 --- a/spinifex/services/spinifexui/frontend/dist/assets/upload-button.js +++ b/spinifex/services/spinifexui/frontend/dist/assets/upload-button.js @@ -1 +1 @@ -import{a as e,n as t,r as n,t as r}from"./compiler-runtime.js";import{t as i}from"./error-banner.js";import{t as a}from"./link.js";import{_ as o,a as s,d as c,in as l,ln as u,mn as d,rn as f}from"./awsClient.js";import{B as p,z as m}from"./SignatureV4.js";import{t as h}from"./createLucideIcon.js";import{t as g}from"./download.js";import{t as _}from"./trash-2.js";import{t as v}from"./button.js";import{a as y,i as b,n as x}from"./s3.js";import{t as S}from"./delete-confirmation-dialog.js";var C=h(`file`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}]]),w=h(`folder`,[[`path`,{d:`M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z`,key:`1kt360`}]]),T=h(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]),E=e=>(e,t)=>async n=>{let r=await e(n),{response:i}=r;if(d.isInstance(i)&&i.headers.expires){i.headers.expiresstring=i.headers.expires;try{u(i.headers.expires)}catch(e){t.logger?.warn(`AWS SDK Warning for ${t.clientName}::${t.commandName} response parsing (${i.headers.expires}): ${e}`),delete i.headers.expires}}return r},D={tags:[`S3`],name:`s3ExpiresMiddleware`,override:!0,relation:`after`,toMiddleware:`deserializerMiddleware`},O=e=>({applyToStack:t=>{t.addRelativeTo(E(e),D)}}),k=class extends f.classBuilder().ep({...o,Bucket:{type:`contextParams`,name:`Bucket`},Key:{type:`contextParams`,name:`Key`}}).m(function(e,t,n,r){return[l(n,e.getEndpointParameterInstructions()),y(n,{requestChecksumRequired:!1,requestValidationModeMember:`ChecksumMode`,responseAlgorithms:[`CRC64NVME`,`CRC32`,`CRC32C`,`SHA256`,`SHA1`,`SHA512`,`MD5`,`XXHASH64`,`XXHASH3`,`XXHASH128`]}),b(n),O(n)]}).s(`AmazonS3`,`GetObject`,{}).n(`S3Client`,`GetObjectCommand`).sc(c).build(){},A=r(),j=t();function M(e){let t=(0,A.c)(9),{folderName:n,fullPrefix:r,bucketName:i}=e,o;t[0]!==i||t[1]!==r?(o={bucket:i,_splat:r},t[0]=i,t[1]=r,t[2]=o):o=t[2];let s;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(s=(0,j.jsx)(w,{className:`size-5 text-muted-foreground`}),t[3]=s):s=t[3];let c;t[4]===n?c=t[5]:(c=(0,j.jsx)(`span`,{className:`font-medium`,children:n}),t[4]=n,t[5]=c);let l;return t[6]!==o||t[7]!==c?(l=(0,j.jsxs)(a,{className:`flex items-center gap-3 rounded-lg border bg-card p-4 transition-colors hover:bg-accent`,params:o,to:`/s3/ls/$bucket/$`,children:[s,c]}),t[6]=o,t[7]=c,t[8]=l):l=t[8],l}var N=e(n(),1);function P({object:e,bucketName:t,displayName:n,fullKey:r}){let[a,o]=(0,N.useState)(!1),c=x();async function l(){try{let e=new k({Bucket:t,Key:r}),i=await s().send(e);if(i.Body){let e=await i.Body.transformToByteArray(),t=URL.createObjectURL(new Blob([e])),r=document.createElement(`a`);r.href=t,r.download=n,document.body.append(r),r.click(),r.remove(),URL.revokeObjectURL(t)}}catch(e){throw Error(`Failed to download object`,{cause:e})}}async function u(){try{await c.mutateAsync({bucket:t,key:r})}finally{o(!1)}}return(0,j.jsxs)(`div`,{children:[c.error&&(0,j.jsx)(i,{error:c.error,msg:`Failed to delete object`}),(0,j.jsxs)(`div`,{className:`flex items-center justify-between rounded-lg border bg-card p-4`,children:[(0,j.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,j.jsx)(C,{className:`size-5 text-muted-foreground`}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`h3`,{className:`font-medium`,children:n}),e.LastModified&&(0,j.jsxs)(`p`,{className:`text-sm text-muted-foreground`,children:[`Last Modified: `,m(e.LastModified)]})]})]}),(0,j.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,j.jsx)(`div`,{className:`text-sm text-muted-foreground`,children:p(e.Size??0)}),(0,j.jsx)(`button`,{"aria-label":`Download ${n}`,className:`rounded-md p-2 transition-colors hover:bg-accent`,onClick:l,type:`button`,children:(0,j.jsx)(g,{className:`size-4`})}),(0,j.jsx)(`button`,{"aria-label":`Delete ${n}`,className:`rounded-md p-2 text-destructive transition-colors hover:bg-accent`,onClick:()=>o(!0),type:`button`,children:(0,j.jsx)(_,{className:`size-4`})})]}),(0,j.jsx)(S,{description:(0,j.jsxs)(j.Fragment,{children:[`Are you sure you want to delete `,(0,j.jsx)(`strong`,{children:n}),`? This action cannot be undone.`]}),isPending:c.isPending,onConfirm:u,onOpenChange:o,open:a,title:`Delete Object`})]})]},e.Key)}function F({bucket:e,prefix:t=``,isPending:n,onUpload:r}){let i=(0,N.useRef)(null);async function a(n){let a=n.target.files;if(!(!a||a.length===0))try{await Promise.all([...a].map(async n=>await r({bucket:e,key:`${t}${n.name}`,file:n})))}finally{i.current&&(i.current.value=``)}}return(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(`input`,{accept:`*/*`,"aria-label":`Choose files to upload`,className:`hidden`,multiple:!0,onChange:a,ref:i,type:`file`}),(0,j.jsxs)(v,{disabled:n,onClick:()=>i.current?.click(),size:`sm`,children:[(0,j.jsx)(T,{className:`mr-2 size-4`}),n?`Uploading…`:`Upload Files`]})]})}export{P as n,M as r,F as t}; \ No newline at end of file +import{a as e,n as t,r as n,t as r}from"./compiler-runtime.js";import{t as i}from"./error-banner.js";import{t as a}from"./link.js";import{_ as o,a as s,d as c,in as l,ln as u,mn as d,rn as f}from"./awsClient.js";import{B as p,z as m}from"./SignatureV4.js";import{t as h}from"./createLucideIcon.js";import{t as g}from"./download.js";import{t as _}from"./trash-2.js";import{t as v}from"./button.js";import{a as y,i as b,n as x}from"./s3.js";import{t as S}from"./delete-confirmation-dialog.js";var C=h(`file`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}]]),w=h(`folder`,[[`path`,{d:`M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z`,key:`1kt360`}]]),T=h(`upload`,[[`path`,{d:`M12 3v12`,key:`1x0j5s`}],[`path`,{d:`m17 8-5-5-5 5`,key:`7q97r8`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}]]),E=e=>(e,t)=>async n=>{let r=await e(n),{response:i}=r;if(d.isInstance(i)&&i.headers.expires){i.headers.expiresstring=i.headers.expires;try{u(i.headers.expires)}catch(e){t.logger?.warn(`AWS SDK Warning for ${t.clientName}::${t.commandName} response parsing (${i.headers.expires}): ${e}`),delete i.headers.expires}}return r},D={tags:[`S3`],name:`s3ExpiresMiddleware`,override:!0,relation:`after`,toMiddleware:`deserializerMiddleware`},O=e=>({applyToStack:t=>{t.addRelativeTo(E(e),D)}}),k=class extends f.classBuilder().ep({...o,Bucket:{type:`contextParams`,name:`Bucket`},Key:{type:`contextParams`,name:`Key`}}).m(function(e,t,n,r){return[l(n,e.getEndpointParameterInstructions()),y(n,{requestChecksumRequired:!1,requestValidationModeMember:`ChecksumMode`,responseAlgorithms:[`CRC64NVME`,`CRC32`,`CRC32C`,`SHA256`,`SHA1`,`SHA512`,`MD5`,`XXHASH64`,`XXHASH3`,`XXHASH128`]}),b(n),O(n)]}).s(`AmazonS3`,`GetObject`,{}).n(`S3Client`,`GetObjectCommand`).sc(c).build(){},A=r(),j=t();function M(e){let t=(0,A.c)(9),{folderName:n,fullPrefix:r,bucketName:i}=e,o;t[0]!==i||t[1]!==r?(o={bucket:i,_splat:r},t[0]=i,t[1]=r,t[2]=o):o=t[2];let s;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(s=(0,j.jsx)(w,{className:`size-5 text-muted-foreground`}),t[3]=s):s=t[3];let c;t[4]===n?c=t[5]:(c=(0,j.jsx)(`span`,{className:`font-medium`,children:n}),t[4]=n,t[5]=c);let l;return t[6]!==o||t[7]!==c?(l=(0,j.jsxs)(a,{className:`flex items-center gap-3 rounded-lg border bg-card p-4 transition-colors hover:bg-accent`,params:o,to:`/s3/ls/$bucket/$`,children:[s,c]}),t[6]=o,t[7]=c,t[8]=l):l=t[8],l}var N=e(n(),1);function P({object:e,bucketName:t,displayName:n,fullKey:r}){let[a,o]=(0,N.useState)(!1),[c,l]=(0,N.useState)(null),u=x();async function d(){l(null);try{let e=new k({Bucket:t,Key:r}),i=await s().send(e);if(i.Body){let e=await i.Body.transformToByteArray(),t=URL.createObjectURL(new Blob([e])),r=document.createElement(`a`);r.href=t,r.download=n,document.body.append(r),r.click(),r.remove(),URL.revokeObjectURL(t)}}catch(e){l(Error(`Failed to download object`,{cause:e}))}}async function f(){try{await u.mutateAsync({bucket:t,key:r})}finally{o(!1)}}return(0,j.jsxs)(`div`,{children:[u.error&&(0,j.jsx)(i,{error:u.error,msg:`Failed to delete object`}),c&&(0,j.jsx)(i,{error:c,msg:`Failed to download object`}),(0,j.jsxs)(`div`,{className:`flex items-center justify-between rounded-lg border bg-card p-4`,children:[(0,j.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,j.jsx)(C,{className:`size-5 text-muted-foreground`}),(0,j.jsxs)(`div`,{children:[(0,j.jsx)(`h3`,{className:`font-medium`,children:n}),e.LastModified&&(0,j.jsxs)(`p`,{className:`text-sm text-muted-foreground`,children:[`Last Modified: `,m(e.LastModified)]})]})]}),(0,j.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,j.jsx)(`div`,{className:`text-sm text-muted-foreground`,children:p(e.Size??0)}),(0,j.jsx)(`button`,{"aria-label":`Download ${n}`,className:`rounded-md p-2 transition-colors hover:bg-accent`,onClick:d,type:`button`,children:(0,j.jsx)(g,{className:`size-4`})}),(0,j.jsx)(`button`,{"aria-label":`Delete ${n}`,className:`rounded-md p-2 text-destructive transition-colors hover:bg-accent`,onClick:()=>o(!0),type:`button`,children:(0,j.jsx)(_,{className:`size-4`})})]}),(0,j.jsx)(S,{description:(0,j.jsxs)(j.Fragment,{children:[`Are you sure you want to delete `,(0,j.jsx)(`strong`,{children:n}),`? This action cannot be undone.`]}),isPending:u.isPending,onConfirm:f,onOpenChange:o,open:a,title:`Delete Object`})]})]},e.Key)}function F({bucket:e,prefix:t=``,isPending:n,onUpload:r}){let i=(0,N.useRef)(null);async function a(n){let a=n.target.files;if(!(!a||a.length===0))try{await Promise.all([...a].map(async n=>await r({bucket:e,key:`${t}${n.name}`,file:n})))}finally{i.current&&(i.current.value=``)}}return(0,j.jsxs)(j.Fragment,{children:[(0,j.jsx)(`input`,{accept:`*/*`,"aria-label":`Choose files to upload`,className:`hidden`,multiple:!0,onChange:a,ref:i,type:`file`}),(0,j.jsxs)(v,{disabled:n,onClick:()=>i.current?.click(),size:`sm`,children:[(0,j.jsx)(T,{className:`mr-2 size-4`}),n?`Uploading…`:`Upload Files`]})]})}export{P as n,M as r,F as t}; \ No newline at end of file diff --git a/spinifex/services/spinifexui/frontend/src/components/elbv2/lb-image-missing-banner.tsx b/spinifex/services/spinifexui/frontend/src/components/elbv2/lb-image-missing-banner.tsx deleted file mode 100644 index 475286bc5..000000000 --- a/spinifex/services/spinifexui/frontend/src/components/elbv2/lb-image-missing-banner.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { LB_IMAGE_NAME } from "@/lib/system-managed" - -export function LbImageMissingBanner() { - return ( -
-

- Load balancer image not imported -

-

- The load balancer system image has not been imported on this cluster. A - cluster administrator must run the following command before load - balancers can be created: -

-
-        spx admin images import --name {LB_IMAGE_NAME}
-      
-
- ) -} diff --git a/spinifex/services/spinifexui/frontend/src/lib/system-managed.test.ts b/spinifex/services/spinifexui/frontend/src/lib/system-managed.test.ts index 86fc7eb13..b4e53fe88 100644 --- a/spinifex/services/spinifexui/frontend/src/lib/system-managed.test.ts +++ b/spinifex/services/spinifexui/frontend/src/lib/system-managed.test.ts @@ -1,13 +1,7 @@ import type { Image } from "@aws-sdk/client-ec2" import { describe, expect, it } from "vitest" -import { - LB_MANAGED_BY_VALUE, - SYSTEM_MANAGED_TAG_KEY, - hasLbImage, - isLbImage, - isSystemManagedImage, -} from "./system-managed" +import { SYSTEM_MANAGED_TAG_KEY, isSystemManagedImage } from "./system-managed" describe("isSystemManagedImage", () => { it("returns true when image carries the managed-by tag", () => { @@ -30,49 +24,3 @@ describe("isSystemManagedImage", () => { expect(isSystemManagedImage({ ImageId: "ami-3" })).toBeFalsy() }) }) - -describe("isLbImage", () => { - it("returns true when tag value matches elbv2", () => { - const image: Image = { - ImageId: "ami-lb", - Tags: [{ Key: SYSTEM_MANAGED_TAG_KEY, Value: LB_MANAGED_BY_VALUE }], - } - expect(isLbImage(image)).toBeTruthy() - }) - - it("returns false for system-managed images owned by other components", () => { - const image: Image = { - ImageId: "ami-other", - Tags: [{ Key: SYSTEM_MANAGED_TAG_KEY, Value: "other-service" }], - } - expect(isLbImage(image)).toBeFalsy() - }) - - it("returns false for customer images", () => { - expect(isLbImage({ ImageId: "ami-cust" })).toBeFalsy() - }) -}) - -describe("hasLbImage", () => { - it("returns true when any image in the list is the LB AMI", () => { - const images: Image[] = [ - { ImageId: "ami-cust", Tags: [{ Key: "Name", Value: "ubuntu" }] }, - { - ImageId: "ami-lb", - Tags: [{ Key: SYSTEM_MANAGED_TAG_KEY, Value: LB_MANAGED_BY_VALUE }], - }, - ] - expect(hasLbImage(images)).toBeTruthy() - }) - - it("returns false for an empty list", () => { - expect(hasLbImage([])).toBeFalsy() - }) - - it("returns false when no image carries the elbv2 tag", () => { - const images: Image[] = [ - { ImageId: "ami-cust", Tags: [{ Key: "Name", Value: "ubuntu" }] }, - ] - expect(hasLbImage(images)).toBeFalsy() - }) -}) diff --git a/spinifex/services/spinifexui/frontend/src/lib/system-managed.ts b/spinifex/services/spinifexui/frontend/src/lib/system-managed.ts index 39873825d..b927fd665 100644 --- a/spinifex/services/spinifexui/frontend/src/lib/system-managed.ts +++ b/spinifex/services/spinifexui/frontend/src/lib/system-managed.ts @@ -1,30 +1,10 @@ import type { Image } from "@aws-sdk/client-ec2" // Tag key applied by Spinifex to platform-managed resources -// (HAProxy VMs, their ENIs, the LB AMI). The value identifies the -// owning component (e.g. "elbv2"). See spinifex/docs/TAG-CONVENTIONS.md. +// (HAProxy VMs, their ENIs). The value identifies the owning component +// (e.g. "elbv2"). See spinifex/docs/TAG-CONVENTIONS.md. export const SYSTEM_MANAGED_TAG_KEY = "spinifex:managed-by" -// Value of SYSTEM_MANAGED_TAG_KEY carried by the LB system AMI and its VMs. -export const LB_MANAGED_BY_VALUE = "elbv2" - -// Canonical name of the LB system image in utils.AvailableImages. -// Kept in sync with spinifex/utils/images.go. -export const LB_IMAGE_NAME = "lb-alpine-3.21.6-x86_64" - export function isSystemManagedImage(image: Image): boolean { return image.Tags?.some((tag) => tag.Key === SYSTEM_MANAGED_TAG_KEY) ?? false } - -export function isLbImage(image: Image): boolean { - return ( - image.Tags?.some( - (tag) => - tag.Key === SYSTEM_MANAGED_TAG_KEY && tag.Value === LB_MANAGED_BY_VALUE, - ) ?? false - ) -} - -export function hasLbImage(images: Image[]): boolean { - return images.some(isLbImage) -} diff --git a/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/-components/create-load-balancer-page.tsx b/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/-components/create-load-balancer-page.tsx index be9ee4176..1013500fd 100644 --- a/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/-components/create-load-balancer-page.tsx +++ b/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/-components/create-load-balancer-page.tsx @@ -12,7 +12,6 @@ import { type CliCommand, type CommandPart, } from "@/components/cli-command-panel" -import { LbImageMissingBanner } from "@/components/elbv2/lb-image-missing-banner" import { TargetGroupForm } from "@/components/elbv2/target-group-form" import { ErrorBanner } from "@/components/error-banner" import { FormActions } from "@/components/form-actions" @@ -27,14 +26,12 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select" -import { hasLbImage } from "@/lib/system-managed" import { getNameTag } from "@/lib/utils" import { type LbWizardResult, useCreateLoadBalancerWizard, } from "@/mutations/elbv2" import { - ec2ImagesQueryOptions, ec2SecurityGroupsQueryOptions, ec2SubnetsQueryOptions, ec2VpcsQueryOptions, @@ -85,10 +82,8 @@ export function CreateLoadBalancerPage() { const { data: subnetsData } = useSuspenseQuery(ec2SubnetsQueryOptions) const { data: sgsData } = useSuspenseQuery(ec2SecurityGroupsQueryOptions) const { data: tgsData } = useSuspenseQuery(elbv2TargetGroupsQueryOptions) - const { data: imagesData } = useSuspenseQuery(ec2ImagesQueryOptions) const wizardMutation = useCreateLoadBalancerWizard() - const lbImageImported = hasLbImage(imagesData.Images ?? []) const [wizardResult, setWizardResult] = useState(null) const vpcs = vpcsData.Vpcs ?? [] @@ -223,18 +218,6 @@ export function CreateLoadBalancerPage() { const groupedSubnets = groupSubnetsByAz(vpcSubnets) - if (!lbImageImported) { - return ( - <> - - Back to load balancers - - - - - ) - } - return ( <> diff --git a/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/-components/describe-load-balancers-page.tsx b/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/-components/describe-load-balancers-page.tsx index 54af19f1b..87b99159d 100644 --- a/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/-components/describe-load-balancers-page.tsx +++ b/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/-components/describe-load-balancers-page.tsx @@ -2,12 +2,9 @@ import type { LoadBalancer } from "@aws-sdk/client-elastic-load-balancing-v2" import { useSuspenseQuery } from "@tanstack/react-query" import { Link, useNavigate } from "@tanstack/react-router" -import { LbImageMissingBanner } from "@/components/elbv2/lb-image-missing-banner" import { PageHeading } from "@/components/page-heading" import { StateBadge } from "@/components/state-badge" import { Button } from "@/components/ui/button" -import { hasLbImage } from "@/lib/system-managed" -import { ec2ImagesQueryOptions } from "@/queries/ec2" import { elbv2LoadBalancersQueryOptions } from "@/queries/elbv2" function formatCreatedAt(createdAt: Date | undefined): string { @@ -20,17 +17,14 @@ function formatCreatedAt(createdAt: Date | undefined): string { export function DescribeLoadBalancersPage() { const navigate = useNavigate() const { data } = useSuspenseQuery(elbv2LoadBalancersQueryOptions) - const { data: imagesData } = useSuspenseQuery(ec2ImagesQueryOptions) const loadBalancers = data.LoadBalancers ?? [] - const lbImageImported = hasLbImage(imagesData.Images ?? []) return ( <> await navigate({ to: "/ec2/create-load-balancer" }) } @@ -41,8 +35,6 @@ export function DescribeLoadBalancersPage() { title="Load Balancers" /> - {!lbImageImported && } - {loadBalancers.length > 0 ? (
diff --git a/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/create-load-balancer.test.tsx b/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/create-load-balancer.test.tsx index 42e7d3651..54a90ebd1 100644 --- a/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/create-load-balancer.test.tsx +++ b/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/create-load-balancer.test.tsx @@ -1,4 +1,4 @@ -import type { Image, SecurityGroup, Subnet, Vpc } from "@aws-sdk/client-ec2" +import type { SecurityGroup, Subnet, Vpc } from "@aws-sdk/client-ec2" import type { TargetGroup } from "@aws-sdk/client-elastic-load-balancing-v2" import { screen, waitFor } from "@testing-library/react" import userEvent from "@testing-library/user-event" @@ -90,22 +90,12 @@ const EXISTING_TG: TargetGroup = { Port: 80, VpcId: VPC_ID, } -const LB_IMAGE: Image = { - ImageId: "ami-lb", - Name: "lb-alpine-3.21.6-x86_64", - Tags: [{ Key: "spinifex:managed-by", Value: "elbv2" }], -} - -function seedClient(options: { lbImageImported?: boolean } = {}) { - const { lbImageImported = true } = options +function seedClient() { const qc = createTestQueryClient() qc.setQueryData(["ec2", "vpcs"], { Vpcs: VPCS }) qc.setQueryData(["ec2", "subnets"], { Subnets: SUBNETS }) qc.setQueryData(["ec2", "securityGroups"], { SecurityGroups: SGS }) qc.setQueryData(["elbv2", "targetGroups"], { TargetGroups: [EXISTING_TG] }) - qc.setQueryData(["ec2", "images"], { - Images: lbImageImported ? [LB_IMAGE] : [], - }) return qc } @@ -268,22 +258,4 @@ describe("create-load-balancer route", () => { expect(screen.getByText(/arn:tg:new/)).toBeInTheDocument() expect(routerState.navigate).not.toHaveBeenCalled() }) - - it("blocks form render with import banner when LB AMI missing", () => { - renderWithClient( - , - seedClient({ lbImageImported: false }), - ) - - expect( - screen.getByText("Load balancer image not imported"), - ).toBeInTheDocument() - expect( - screen.getByText(/spx admin images import --name lb-alpine/), - ).toBeInTheDocument() - // Form inputs must not render - expect( - screen.queryByLabelText("Name", { selector: "#lb-name" }), - ).not.toBeInTheDocument() - }) }) diff --git a/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/describe-load-balancers/index.test.tsx b/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/describe-load-balancers/index.test.tsx index 511a84795..477808570 100644 --- a/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/describe-load-balancers/index.test.tsx +++ b/spinifex/services/spinifexui/frontend/src/routes/_auth/ec2/(load-balancers)/describe-load-balancers/index.test.tsx @@ -1,4 +1,3 @@ -import type { Image } from "@aws-sdk/client-ec2" import type { LoadBalancer } from "@aws-sdk/client-elastic-load-balancing-v2" import { screen } from "@testing-library/react" import { afterEach, beforeEach, describe, expect, it, vi } from "vitest" @@ -79,12 +78,6 @@ const LBS: LoadBalancer[] = [ }, ] -const LB_IMAGE: Image = { - ImageId: "ami-lb", - Name: "lb-alpine-3.21.6-x86_64", - Tags: [{ Key: "spinifex:managed-by", Value: "elbv2" }], -} - describe("describe-load-balancers list route", () => { beforeEach(() => sdk.reset()) afterEach(() => vi.clearAllMocks()) @@ -92,7 +85,6 @@ describe("describe-load-balancers list route", () => { it("renders load-balancer rows with resolved fields", () => { const qc = createTestQueryClient() qc.setQueryData(["elbv2", "loadBalancers"], { LoadBalancers: LBS }) - qc.setQueryData(["ec2", "images"], { Images: [LB_IMAGE] }) renderWithClient(, qc) @@ -100,9 +92,6 @@ describe("describe-load-balancers list route", () => { expect(screen.getByText("lb-one.example")).toBeInTheDocument() expect(screen.getByText("application")).toBeInTheDocument() expect(screen.getByText("internet-facing")).toBeInTheDocument() - expect( - screen.queryByText("Load balancer image not imported"), - ).not.toBeInTheDocument() expect( screen.getByRole("button", { name: "Create Load Balancer" }), ).not.toBeDisabled() @@ -111,47 +100,9 @@ describe("describe-load-balancers list route", () => { it("shows empty state when no load balancers", () => { const qc = createTestQueryClient() qc.setQueryData(["elbv2", "loadBalancers"], { LoadBalancers: [] }) - qc.setQueryData(["ec2", "images"], { Images: [LB_IMAGE] }) renderWithClient(, qc) expect(screen.getByText("No load balancers found.")).toBeInTheDocument() }) - - it("shows import banner and disables Create button when LB AMI missing", () => { - const qc = createTestQueryClient() - qc.setQueryData(["elbv2", "loadBalancers"], { LoadBalancers: [] }) - qc.setQueryData(["ec2", "images"], { Images: [] }) - - renderWithClient(, qc) - - expect( - screen.getByText("Load balancer image not imported"), - ).toBeInTheDocument() - expect( - screen.getByText(/spx admin images import --name lb-alpine/), - ).toBeInTheDocument() - expect( - screen.getByRole("button", { name: "Create Load Balancer" }), - ).toBeDisabled() - }) - - it("treats non-LB system images as missing", () => { - const qc = createTestQueryClient() - qc.setQueryData(["elbv2", "loadBalancers"], { LoadBalancers: [] }) - qc.setQueryData(["ec2", "images"], { - Images: [ - { - ImageId: "ami-customer", - Tags: [{ Key: "Name", Value: "ubuntu" }], - }, - ], - }) - - renderWithClient(, qc) - - expect( - screen.getByText("Load balancer image not imported"), - ).toBeInTheDocument() - }) }) diff --git a/spinifex/vm/devices.go b/spinifex/vm/devices.go new file mode 100644 index 000000000..f0fe5a473 --- /dev/null +++ b/spinifex/vm/devices.go @@ -0,0 +1,60 @@ +package vm + +import ( + "fmt" + "strings" +) + +// IsMMIO reports whether machineType is a memory-mapped I/O bus machine (e.g. +// microvm). MMIO machines use virtio-*-device transports instead of +// virtio-*-pci, because they have no PCI bus. +func IsMMIO(machineType string) bool { + return strings.HasPrefix(machineType, "microvm") +} + +// NetDevice returns the appropriate QEMU virtio-net device string for +// machineType, wiring netdev and mac. mac is omitted when empty. +func NetDevice(machineType, netdev, mac string) Device { + var transport string + if IsMMIO(machineType) { + transport = "virtio-net-device" + } else { + transport = "virtio-net-pci" + } + if mac != "" { + return Device{Value: fmt.Sprintf("%s,netdev=%s,mac=%s", transport, netdev, mac)} + } + return Device{Value: fmt.Sprintf("%s,netdev=%s", transport, netdev)} +} + +// BlkDevice returns the appropriate QEMU virtio-blk device string for +// machineType. iothread and queues are omitted when empty/zero. bootIdx is +// only emitted for PCI machines (MMIO has no bootindex concept). +func BlkDevice(machineType, drive, iothread string, queues int, bootIdx int) Device { + var b strings.Builder + if IsMMIO(machineType) { + b.WriteString("virtio-blk-device") + } else { + b.WriteString("virtio-blk-pci") + } + fmt.Fprintf(&b, ",drive=%s", drive) + if iothread != "" { + fmt.Fprintf(&b, ",iothread=%s", iothread) + } + if queues > 0 { + fmt.Fprintf(&b, ",num-queues=%d", queues) + } + if !IsMMIO(machineType) && bootIdx > 0 { + fmt.Fprintf(&b, ",bootindex=%d", bootIdx) + } + return Device{Value: b.String()} +} + +// RngDevice returns the appropriate QEMU virtio-rng device string for +// machineType. +func RngDevice(machineType string) Device { + if IsMMIO(machineType) { + return Device{Value: "virtio-rng-device"} + } + return Device{Value: "virtio-rng-pci"} +} diff --git a/spinifex/vm/devices_test.go b/spinifex/vm/devices_test.go new file mode 100644 index 000000000..5c2619182 --- /dev/null +++ b/spinifex/vm/devices_test.go @@ -0,0 +1,86 @@ +package vm + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestIsMMIO(t *testing.T) { + tests := []struct { + machineType string + want bool + }{ + {"microvm", true}, + {"microvm,x-option-roms=off", true}, + {"q35", false}, + {"virt", false}, + {"", false}, + } + for _, tt := range tests { + t.Run(tt.machineType, func(t *testing.T) { + assert.Equal(t, tt.want, IsMMIO(tt.machineType)) + }) + } +} + +func TestNetDevice_PCI(t *testing.T) { + d := NetDevice("q35", "net0", "02:00:00:aa:bb:cc") + assert.Equal(t, "virtio-net-pci,netdev=net0,mac=02:00:00:aa:bb:cc", d.Value) +} + +func TestNetDevice_PCI_NoMAC(t *testing.T) { + d := NetDevice("q35", "net0", "") + assert.Equal(t, "virtio-net-pci,netdev=net0", d.Value) +} + +func TestNetDevice_MMIO(t *testing.T) { + d := NetDevice("microvm", "net0", "02:00:00:aa:bb:cc") + assert.Equal(t, "virtio-net-device,netdev=net0,mac=02:00:00:aa:bb:cc", d.Value) +} + +func TestNetDevice_MMIO_NoMAC(t *testing.T) { + d := NetDevice("microvm,x-option-roms=off", "net0", "") + assert.Equal(t, "virtio-net-device,netdev=net0", d.Value) +} + +func TestBlkDevice_PCI(t *testing.T) { + d := BlkDevice("q35", "os", "ioth-os", 4, 1) + assert.Equal(t, "virtio-blk-pci,drive=os,iothread=ioth-os,num-queues=4,bootindex=1", d.Value) +} + +func TestBlkDevice_PCI_NoBootIdx(t *testing.T) { + d := BlkDevice("q35", "data", "ioth-data", 2, 0) + assert.Equal(t, "virtio-blk-pci,drive=data,iothread=ioth-data,num-queues=2", d.Value) +} + +func TestBlkDevice_PCI_NoIOThread(t *testing.T) { + d := BlkDevice("q35", "data", "", 0, 0) + assert.Equal(t, "virtio-blk-pci,drive=data", d.Value) +} + +func TestBlkDevice_MMIO(t *testing.T) { + d := BlkDevice("microvm", "os", "ioth-os", 4, 1) + // MMIO has no bootindex + assert.Equal(t, "virtio-blk-device,drive=os,iothread=ioth-os,num-queues=4", d.Value) +} + +func TestBlkDevice_MMIO_NoIOThread(t *testing.T) { + d := BlkDevice("microvm,x-option-roms=off", "data", "", 0, 0) + assert.Equal(t, "virtio-blk-device,drive=data", d.Value) +} + +func TestRngDevice_PCI(t *testing.T) { + d := RngDevice("q35") + assert.Equal(t, "virtio-rng-pci", d.Value) +} + +func TestRngDevice_MMIO(t *testing.T) { + d := RngDevice("microvm") + assert.Equal(t, "virtio-rng-device", d.Value) +} + +func TestRngDevice_MMIO_WithOptions(t *testing.T) { + d := RngDevice("microvm,x-option-roms=off,pic=off") + assert.Equal(t, "virtio-rng-device", d.Value) +} diff --git a/spinifex/vm/lifecycle.go b/spinifex/vm/lifecycle.go index 9b8f811ed..e5936c447 100644 --- a/spinifex/vm/lifecycle.go +++ b/spinifex/vm/lifecycle.go @@ -10,6 +10,7 @@ import ( "os" "path/filepath" "strconv" + "strings" "syscall" "time" @@ -170,6 +171,28 @@ func (m *Manager) launch(instance *VM) error { return nil } +// nbdkitPreExecWait returns how long startQEMU sleeps before exec'ing QEMU to +// give nbdkit time to bind its sockets. Direct-boot instances have no drives +// and no nbdkit, so the wait collapses to zero and the boot-time budget is +// preserved. +func nbdkitPreExecWait(directBoot bool) time.Duration { + if directBoot { + return 0 + } + return 2 * time.Second +} + +// qemuStartSettleWait returns the post-fork sleep that lets QEMU surface an +// immediate-start crash (bad cmdline, missing kernel) before we attempt QMP. +// Direct-boot binds the QMP socket within a few ms because there is no +// firmware, ROM, or block layer setup, so a full second is unnecessary. +func qemuStartSettleWait(directBoot bool) time.Duration { + if directBoot { + return 50 * time.Millisecond + } + return time.Second +} + // startQEMU launches the QEMU process for instance and waits for startup to // confirm. func (m *Manager) startQEMU(instance *VM) error { @@ -191,78 +214,111 @@ func (m *Manager) startQEMU(instance *VM) error { consoleLogPath := filepath.Join(runtimeDir, fmt.Sprintf("console-%s.log", instance.ID)) serialSocket := filepath.Join(runtimeDir, fmt.Sprintf("serial-%s.sock", instance.ID)) - instance.Config = buildBaseVMConfig(instance.ID, pidFile, consoleLogPath, serialSocket, spec.Architecture, spec.VCPUs, spec.MemoryMiB) + if instance.DirectBoot { + // Direct-boot (microvm) path: vm.Config was pre-built by the launcher. + // Only fill in the runtime-generated paths that are not known until now. + // SerialSocket is intentionally omitted: microvm uses a file chardev + // so kernel output is captured without a socket client. + instance.Config.PIDFile = pidFile + instance.Config.ConsoleLogPath = consoleLogPath + } else { + instance.Config = buildBaseVMConfig(instance.ID, pidFile, consoleLogPath, serialSocket, spec.Architecture, spec.VCPUs, spec.MemoryMiB) - instance.EBSRequests.Mu.Lock() - drives, iothreads, devices, err := buildDrives(instance.EBSRequests.Requests, spec.VCPUs) - instance.EBSRequests.Mu.Unlock() - if err != nil { - return err - } - instance.Config.Drives = append(instance.Config.Drives, drives...) - instance.Config.IOThreads = append(instance.Config.IOThreads, iothreads...) - instance.Config.Devices = append(instance.Config.Devices, devices...) - - if instance.ENIId != "" && m.deps.NetworkPlumber != nil { - spec := VPCTapSpec(instance.ENIId, instance.ENIMac) - if err := m.deps.NetworkPlumber.SetupTap(spec); err != nil { - slog.Error("Failed to set up tap device", "eni", instance.ENIId, "err", err) - return fmt.Errorf("setup tap device: %w", err) - } - tapName := spec.Name - - instance.Config.NetDevs = append(instance.Config.NetDevs, NetDev{ - Value: fmt.Sprintf("tap,id=net0,ifname=%s,script=no,downscript=no", tapName), - }) - instance.Config.Devices = append(instance.Config.Devices, Device{ - Value: fmt.Sprintf("virtio-net-pci,netdev=net0,mac=%s", instance.ENIMac), - }) - slog.Info("VPC networking configured", "tap", tapName, "eni", instance.ENIId, "mac", instance.ENIMac) - - if err := m.setupExtraENINICs(instance); err != nil { + instance.EBSRequests.Mu.Lock() + drives, iothreads, devices, err := buildDrives(instance.EBSRequests.Requests, spec.VCPUs, instance.Config.MachineType) + instance.EBSRequests.Mu.Unlock() + if err != nil { return err } + instance.Config.Drives = append(instance.Config.Drives, drives...) + instance.Config.IOThreads = append(instance.Config.IOThreads, iothreads...) + instance.Config.Devices = append(instance.Config.Devices, devices...) + } - if m.deps.DevNetworking { - m.appendDevHostfwdNIC(instance) + if instance.DirectBoot { + // Direct-boot (microvm) path: NetDevs and Devices are already set in + // the pre-built Config. Only create host-side tap devices for VPC ENIs + // so the kernel tap interfaces exist before QEMU opens them. + if instance.ENIId != "" && m.deps.NetworkPlumber != nil { + tapSpec := VPCTapSpec(instance.ENIId, instance.ENIMac) + if err := m.deps.NetworkPlumber.SetupTap(tapSpec); err != nil { + slog.Error("Failed to set up tap device (direct-boot)", "eni", instance.ENIId, "err", err) + return fmt.Errorf("setup tap device: %w", err) + } + slog.Info("VPC tap configured (direct-boot)", "tap", tapSpec.Name, "eni", instance.ENIId, "mac", instance.ENIMac) + for _, extra := range instance.ExtraENIs { + extraSpec := VPCTapSpec(extra.ENIID, extra.ENIMac) + if err := m.deps.NetworkPlumber.SetupTap(extraSpec); err != nil { + slog.Error("Failed to set up extra ENI tap (direct-boot)", "eni", extra.ENIID, "err", err) + return fmt.Errorf("setup tap device for extra ENI %s: %w", extra.ENIID, err) + } + } + } + if instance.MgmtMAC != "" && m.deps.NetworkPlumber != nil { + mgmtTap := MgmtTapName(instance.ID) + mgmtBridge := "br-mgmt" + if err := m.deps.NetworkPlumber.SetupTap(TapSpec{Name: mgmtTap, Bridge: mgmtBridge}); err != nil { + slog.Error("Failed to set up mgmt tap (direct-boot)", "tap", mgmtTap, "err", err) + return fmt.Errorf("setup mgmt tap: %w", err) + } + slog.Info("Mgmt tap configured (direct-boot)", "tap", mgmtTap, "mac", instance.MgmtMAC, "ip", instance.MgmtIP, "instanceId", instance.ID) } } else { - sshDebugAddr, err := viperblock.FindFreePort() - if err != nil { - slog.Error("Failed to find free port", "err", err) - return err - } - _, sshDebugPort, err := net.SplitHostPort(sshDebugAddr) - if err != nil { - slog.Error("Failed to parse port from address", "addr", sshDebugAddr, "err", err) - return fmt.Errorf("parse port from %s: %w", sshDebugAddr, err) + if instance.ENIId != "" && m.deps.NetworkPlumber != nil { + spec := VPCTapSpec(instance.ENIId, instance.ENIMac) + if err := m.deps.NetworkPlumber.SetupTap(spec); err != nil { + slog.Error("Failed to set up tap device", "eni", instance.ENIId, "err", err) + return fmt.Errorf("setup tap device: %w", err) + } + tapName := spec.Name + + instance.Config.NetDevs = append(instance.Config.NetDevs, NetDev{ + Value: fmt.Sprintf("tap,id=net0,ifname=%s,script=no,downscript=no", tapName), + }) + instance.Config.Devices = append(instance.Config.Devices, NetDevice(instance.Config.MachineType, "net0", instance.ENIMac)) + slog.Info("VPC networking configured", "tap", tapName, "eni", instance.ENIId, "mac", instance.ENIMac) + + if err := m.setupExtraENINICs(instance); err != nil { + return err + } + + if m.deps.DevNetworking { + m.appendDevHostfwdNIC(instance) + } + } else { + sshDebugAddr, err := viperblock.FindFreePort() + if err != nil { + slog.Error("Failed to find free port", "err", err) + return err + } + _, sshDebugPort, err := net.SplitHostPort(sshDebugAddr) + if err != nil { + slog.Error("Failed to parse port from address", "addr", sshDebugAddr, "err", err) + return fmt.Errorf("parse port from %s: %w", sshDebugAddr, err) + } + + bindIP := m.deps.BindHost + if bindIP == "" || bindIP == "0.0.0.0" { + bindIP = "127.0.0.1" + } + instance.Config.NetDevs = append(instance.Config.NetDevs, NetDev{ + Value: fmt.Sprintf("user,id=net0,hostfwd=tcp:%s:%s-:22", bindIP, sshDebugPort), + }) + instance.Config.Devices = append(instance.Config.Devices, NetDevice(instance.Config.MachineType, "net0", "")) } - bindIP := m.deps.BindHost - if bindIP == "" || bindIP == "0.0.0.0" { - bindIP = "127.0.0.1" + if instance.MgmtMAC != "" { + mgmtTap := MgmtTapName(instance.ID) + instance.Config.NetDevs = append(instance.Config.NetDevs, NetDev{ + Value: fmt.Sprintf("tap,id=mgmt0,ifname=%s,script=no,downscript=no", mgmtTap), + }) + instance.Config.Devices = append(instance.Config.Devices, NetDevice(instance.Config.MachineType, "mgmt0", instance.MgmtMAC)) + slog.Info("Management NIC configured", "tap", mgmtTap, "mac", instance.MgmtMAC, "ip", instance.MgmtIP, "instanceId", instance.ID) } - instance.Config.NetDevs = append(instance.Config.NetDevs, NetDev{ - Value: fmt.Sprintf("user,id=net0,hostfwd=tcp:%s:%s-:22", bindIP, sshDebugPort), - }) - instance.Config.Devices = append(instance.Config.Devices, Device{ - Value: "virtio-net-pci,netdev=net0", - }) + + instance.Config.Devices = append(instance.Config.Devices, RngDevice(instance.Config.MachineType)) } - if instance.MgmtMAC != "" { - mgmtTap := MgmtTapName(instance.ID) - instance.Config.NetDevs = append(instance.Config.NetDevs, NetDev{ - Value: fmt.Sprintf("tap,id=mgmt0,ifname=%s,script=no,downscript=no", mgmtTap), - }) - instance.Config.Devices = append(instance.Config.Devices, Device{ - Value: fmt.Sprintf("virtio-net-pci,netdev=mgmt0,mac=%s", instance.MgmtMAC), - }) - slog.Info("Management NIC configured", "tap", mgmtTap, "mac", instance.MgmtMAC, "ip", instance.MgmtIP, "instanceId", instance.ID) - } - - instance.Config.Devices = append(instance.Config.Devices, Device{Value: "virtio-rng-pci"}) - for i, addr := range instance.GPUPCIAddresses { xvga := "off" if instance.GPUXVGAEnabled { @@ -284,7 +340,7 @@ func (m *Manager) startQEMU(instance *VM) error { // Wait briefly for nbdkit to start. // TODO: Improve, confirm nbdkit started for each volume. - time.Sleep(2 * time.Second) + time.Sleep(nbdkitPreExecWait(instance.DirectBoot)) processChan := make(chan int, 1) exitChan := make(chan int, 1) @@ -368,7 +424,9 @@ func (m *Manager) startQEMU(instance *VM) error { return fmt.Errorf("failed to start qemu") } - time.Sleep(1 * time.Second) + // Catch immediate-start crashes (bad cmdline, missing kernel, etc.) before + // attempting QMP. + time.Sleep(qemuStartSettleWait(instance.DirectBoot)) select { case exitErr := <-exitChan: @@ -416,7 +474,8 @@ func (m *Manager) appendDevHostfwdNIC(instance *VM) { if bindIP == "" || bindIP == "0.0.0.0" { bindIP = "127.0.0.1" } - netdevVal := fmt.Sprintf("user,id=dev0,hostfwd=tcp:%s:%s-:22", bindIP, sshDebugPort) + var nb strings.Builder + fmt.Fprintf(&nb, "user,id=dev0,hostfwd=tcp:%s:%s-:22", bindIP, sshDebugPort) if instance.ExtraHostfwd != nil { for guestPort := range instance.ExtraHostfwd { @@ -435,17 +494,15 @@ func (m *Manager) appendDevHostfwdNIC(instance *VM) { slog.Warn("DEV_NETWORKING: failed to convert extra hostfwd port", "hostPort", hostPort, "err", convErr) continue } - netdevVal += fmt.Sprintf(",hostfwd=tcp:%s:%s-:%d", bindIP, hostPort, guestPort) + fmt.Fprintf(&nb, ",hostfwd=tcp:%s:%s-:%d", bindIP, hostPort, guestPort) instance.ExtraHostfwd[guestPort] = hostPortInt slog.Info("DEV_NETWORKING: extra hostfwd", "guestPort", guestPort, "hostPort", hostPort, "instanceId", instance.ID) } } - instance.Config.NetDevs = append(instance.Config.NetDevs, NetDev{Value: netdevVal}) + instance.Config.NetDevs = append(instance.Config.NetDevs, NetDev{Value: nb.String()}) devMac := GenerateDevMAC(instance.ID) - instance.Config.Devices = append(instance.Config.Devices, Device{ - Value: fmt.Sprintf("virtio-net-pci,netdev=dev0,mac=%s", devMac), - }) + instance.Config.Devices = append(instance.Config.Devices, NetDevice(instance.Config.MachineType, "dev0", devMac)) slog.Info("DEV_NETWORKING: added dev NIC with SSH hostfwd", "bindIP", bindIP, "port", sshDebugPort, "mac", devMac, "instanceId", instance.ID) } @@ -586,7 +643,7 @@ func buildBaseVMConfig(instanceID, pidFile, consoleLogPath, serialSocket, archit // buildDrives converts EBS volume requests into QEMU drive, iothread, and // device configurations. Returns an error if any non-EFI volume is missing // its NBDURI. -func buildDrives(requests []types.EBSRequest, cpuCount int) ([]Drive, []IOThread, []Device, error) { +func buildDrives(requests []types.EBSRequest, cpuCount int, machineType string) ([]Drive, []IOThread, []Device, error) { var drives []Drive var iothreads []IOThread var devices []Device @@ -611,10 +668,7 @@ func buildDrives(requests []types.EBSRequest, cpuCount int) ([]Drive, []IOThread iothreadID := "ioth-os" iothreads = append(iothreads, IOThread{ID: iothreadID}) - devices = append(devices, Device{ - Value: fmt.Sprintf("virtio-blk-pci,drive=%s,iothread=%s,num-queues=%d,bootindex=1", - drive.ID, iothreadID, cpuCount), - }) + devices = append(devices, BlkDevice(machineType, drive.ID, iothreadID, cpuCount, 1)) } if v.CloudInit { diff --git a/spinifex/vm/lifecycle_test.go b/spinifex/vm/lifecycle_test.go index bfa1de22d..47c285363 100644 --- a/spinifex/vm/lifecycle_test.go +++ b/spinifex/vm/lifecycle_test.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "testing" + "time" "github.com/mulgadc/spinifex/spinifex/types" "github.com/stretchr/testify/assert" @@ -42,6 +43,7 @@ func TestBuildDrives(t *testing.T) { name string requests []types.EBSRequest cpuCount int + machineType string wantDrives []Drive wantIOThreads []IOThread wantDevices []Device @@ -112,7 +114,11 @@ func TestBuildDrives(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - drives, iothreads, devices, err := buildDrives(tt.requests, tt.cpuCount) + machineType := tt.machineType + if machineType == "" { + machineType = "q35" + } + drives, iothreads, devices, err := buildDrives(tt.requests, tt.cpuCount, machineType) if tt.wantErr != "" { require.Error(t, err) @@ -605,3 +611,170 @@ func TestAppendDevHostfwdNIC_ExtraHostfwd_HappyPath(t *testing.T) { require.Len(t, instance.Config.Devices, 1) assert.Equal(t, fmt.Sprintf("virtio-net-pci,netdev=dev0,mac=%s", GenerateDevMAC("i-extra-ok")), instance.Config.Devices[0].Value) } + +// --------------------------------------------------------------------------- +// startQEMU — DirectBoot branch +// +// We call startQEMU directly (same package) and force early returns via tap +// errors so we cover the DirectBoot config-assignment lines and the tap setup +// paths without spawning a real QEMU process or sleeping 2 s. +// --------------------------------------------------------------------------- + +// directBootManager wires the minimum Deps for startQEMU to reach the +// DirectBoot tap-setup block: InstanceTypes resolver + NetworkPlumber. +func directBootManager(t *testing.T, plumber NetworkPlumber) *Manager { + t.Helper() + t.Setenv("XDG_RUNTIME_DIR", t.TempDir()) + resolver := fakeInstanceTypeResolver{ + "t3.nano": {Architecture: "x86_64", VCPUs: 1, MemoryMiB: 512}, + } + return NewManagerWithDeps(Deps{ + InstanceTypes: resolver, + NetworkPlumber: plumber, + }) +} + +// TestStartQEMU_DirectBoot_PrimaryTapError verifies that when the +// NetworkPlumber fails to set up the primary ENI tap, startQEMU returns a +// wrapped error. This also drives the DirectBoot config-assignment block +// (PIDFile / ConsoleLogPath / SerialSocket) before the early return. +func TestStartQEMU_DirectBoot_PrimaryTapError(t *testing.T) { + tapErr := errors.New("tap setup failed") + plumber := &fakeNetworkPlumber{setupErr: tapErr} + m := directBootManager(t, plumber) + + instance := &VM{ + ID: "i-db-tap-err", + InstanceType: "t3.nano", + DirectBoot: true, + ENIId: "eni-000000000000aaaa", + ENIMac: "02:aa:bb:cc:dd:01", + } + + err := m.startQEMU(instance) + + require.Error(t, err) + assert.Contains(t, err.Error(), "setup tap device") + // PIDFile and ConsoleLogPath are set before the tap call. + // SerialSocket is intentionally empty for direct-boot (file chardev used instead). + assert.NotEmpty(t, instance.Config.PIDFile) + assert.NotEmpty(t, instance.Config.ConsoleLogPath) + assert.Empty(t, instance.Config.SerialSocket) + // Exactly one SetupTap call (the primary ENI tap). + require.Len(t, plumber.setupCalls, 1) +} + +// TestStartQEMU_DirectBoot_ExtraENITapError verifies that a tap failure on a +// secondary ENI returns an error without starting QEMU. +func TestStartQEMU_DirectBoot_ExtraENITapError(t *testing.T) { + callCount := 0 + plumber := &fakeNetworkPlumber{} + // Override SetupTap to fail only on the second call (extra ENI). + realSetupCalls := &plumber.setupCalls + _ = realSetupCalls + + // Use a scripted plumber: success for primary, error for extra. + scriptedPlumber := &scriptedNetworkPlumber{ + errs: []error{nil, errors.New("extra tap failed")}, + } + m := directBootManager(t, scriptedPlumber) + _ = callCount + + instance := &VM{ + ID: "i-db-extra-tap-err", + InstanceType: "t3.nano", + DirectBoot: true, + ENIId: "eni-000000000000bbbb", + ENIMac: "02:aa:bb:cc:dd:02", + ExtraENIs: []ExtraENI{ + {ENIID: "eni-000000000000cccc", ENIMac: "02:aa:bb:cc:dd:03"}, + }, + } + + err := m.startQEMU(instance) + + require.Error(t, err) + assert.Contains(t, err.Error(), "extra ENI") + assert.Len(t, scriptedPlumber.calls, 2) +} + +// TestStartQEMU_DirectBoot_MgmtTapError verifies that a tap failure on the +// management NIC returns a wrapped error. +func TestStartQEMU_DirectBoot_MgmtTapError(t *testing.T) { + // No primary ENI → skips the ENI tap block; MgmtMAC set → enters mgmt block. + plumber := &fakeNetworkPlumber{setupErr: errors.New("mgmt tap failed")} + m := directBootManager(t, plumber) + + instance := &VM{ + ID: "i-db-mgmt-err", + InstanceType: "t3.nano", + DirectBoot: true, + MgmtMAC: "02:aa:bb:cc:dd:ff", + } + + err := m.startQEMU(instance) + + require.Error(t, err) + assert.Contains(t, err.Error(), "mgmt tap") + require.Len(t, plumber.setupCalls, 1) + assert.Equal(t, MgmtTapName("i-db-mgmt-err"), plumber.setupCalls[0].Name) + assert.Equal(t, "br-mgmt", plumber.setupCalls[0].Bridge) +} + +// TestStartQEMU_DirectBoot_NoENI_NoMgmt_InstanceTypeNotFound verifies that +// startQEMU returns an error when the instance type is absent from the resolver, +// exercising the early-return before any DirectBoot config is written. +func TestStartQEMU_DirectBoot_InstanceTypeNotFound(t *testing.T) { + plumber := &fakeNetworkPlumber{} + m := directBootManager(t, plumber) + + instance := &VM{ + ID: "i-db-unknown-type", + InstanceType: "x9.enormous", + DirectBoot: true, + } + + err := m.startQEMU(instance) + + require.Error(t, err) + assert.Contains(t, err.Error(), "x9.enormous") + assert.Empty(t, plumber.setupCalls) +} + +// scriptedNetworkPlumber returns errors from a pre-loaded slice, one per call. +type scriptedNetworkPlumber struct { + calls []TapSpec + errs []error + idx int +} + +func (p *scriptedNetworkPlumber) SetupTap(spec TapSpec) error { + p.calls = append(p.calls, spec) + if p.idx < len(p.errs) { + err := p.errs[p.idx] + p.idx++ + return err + } + return nil +} + +func (p *scriptedNetworkPlumber) CleanupTap(_ string) error { return nil } + +var _ NetworkPlumber = (*scriptedNetworkPlumber)(nil) + +// TestNbdkitPreExecWait locks in the per-mode pre-exec sleep budget: direct-boot +// is zero (no drives, no nbdkit) and the PC-machine path keeps the 2 s wait that +// the rest of the launch flow depends on. +func TestNbdkitPreExecWait(t *testing.T) { + assert.Equal(t, time.Duration(0), nbdkitPreExecWait(true)) + assert.Equal(t, 2*time.Second, nbdkitPreExecWait(false)) +} + +// TestQemuStartSettleWait locks in the per-mode post-fork settle: direct-boot +// trims to 50 ms (QMP socket binds within a few ms when there is no firmware, +// ROM, or block layer setup) and the PC-machine path retains the historical +// 1 s buffer that catches bad-cmdline crashes before the QMP dial. +func TestQemuStartSettleWait(t *testing.T) { + assert.Equal(t, 50*time.Millisecond, qemuStartSettleWait(true)) + assert.Equal(t, time.Second, qemuStartSettleWait(false)) +} diff --git a/spinifex/vm/microvm_test.go b/spinifex/vm/microvm_test.go new file mode 100644 index 000000000..966fa7704 --- /dev/null +++ b/spinifex/vm/microvm_test.go @@ -0,0 +1,47 @@ +package vm + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// TestMicroVMDirectBoot asserts that a microvm Config with direct-boot fields +// set produces the expected QEMU args and does not include PCI-specific flags +// such as -bios or pcie-root-port. +func TestMicroVMDirectBoot(t *testing.T) { + cfg := Config{ + CPUCount: 2, + Memory: 512, + Architecture: "x86_64", + MachineType: "microvm,x-option-roms=off,pic=off,pit=off,rtc=on,acpi=on,isa-serial=on", + KernelImage: "/path/vmlinuz", + Initrd: "/path/initramfs.cpio.gz", + KernelCmdline: "console=ttyS0 panic=1", + FwCfg: []FwCfgEntry{ + {Name: "opt/spinifex/netcfg", File: "/tmp/nc.tmp"}, + }, + } + + cmd, err := cfg.Execute() + require.NoError(t, err) + require.NotNil(t, cmd) + + args := cmd.Args[1:] + + // Machine type must be set + assert.Equal(t, "microvm,x-option-roms=off,pic=off,pit=off,rtc=on,acpi=on,isa-serial=on", argValue(args, "-M")) + + // Direct-boot flags must be present + assert.Equal(t, "/path/vmlinuz", argValue(args, "-kernel")) + assert.Equal(t, "/path/initramfs.cpio.gz", argValue(args, "-initrd")) + assert.Equal(t, "console=ttyS0 panic=1", argValue(args, "-append")) + assert.Equal(t, "name=opt/spinifex/netcfg,file=/tmp/nc.tmp", argValue(args, "-fw_cfg")) + + // PCI-specific flags must NOT appear + assert.False(t, argExists(args, "-bios"), "-bios must not appear for microvm direct-boot") + for _, a := range args { + assert.NotContains(t, a, "pcie-root-port", "pcie-root-port must not appear for microvm") + } +} diff --git a/spinifex/vm/network_helpers.go b/spinifex/vm/network_helpers.go index 5a4102a57..a669ba892 100644 --- a/spinifex/vm/network_helpers.go +++ b/spinifex/vm/network_helpers.go @@ -86,9 +86,7 @@ func (m *Manager) setupExtraENINICs(instance *VM) error { instance.Config.NetDevs = append(instance.Config.NetDevs, NetDev{ Value: fmt.Sprintf("tap,id=%s,ifname=%s,script=no,downscript=no", netID, extraTapName), }) - instance.Config.Devices = append(instance.Config.Devices, Device{ - Value: fmt.Sprintf("virtio-net-pci,netdev=%s,mac=%s", netID, extra.ENIMac), - }) + instance.Config.Devices = append(instance.Config.Devices, NetDevice(instance.Config.MachineType, netID, extra.ENIMac)) slog.Info("Extra VPC NIC configured", "tap", extraTapName, "eni", extra.ENIID, "mac", extra.ENIMac, "subnet", extra.SubnetID) } diff --git a/spinifex/vm/shutdown.go b/spinifex/vm/shutdown.go index 97b0f98e3..069925fd3 100644 --- a/spinifex/vm/shutdown.go +++ b/spinifex/vm/shutdown.go @@ -3,6 +3,7 @@ package vm import ( "fmt" "log/slog" + "os" "sync" "time" @@ -333,6 +334,12 @@ func (m *Manager) shutdownAndUnmount(instance *VM) { slog.Error("Volume unmount failed", "id", instance.ID, "err", err) } } + + for _, fw := range instance.Config.FwCfg { + if err := os.Remove(fw.File); err != nil && !os.IsNotExist(err) { + slog.Warn("Failed to remove fw_cfg temp file", "file", fw.File, "id", instance.ID, "err", err) + } + } } // cleanupTapDevices removes the primary VPC tap, every extra ENI tap, and diff --git a/spinifex/vm/vm.go b/spinifex/vm/vm.go index b518a2f9d..aeb0f6dc6 100644 --- a/spinifex/vm/vm.go +++ b/spinifex/vm/vm.go @@ -119,6 +119,12 @@ type VM struct { // filters out tagged VMs from customer-facing listings. ManagedBy string `json:"managed_by,omitempty"` + // DirectBoot signals that this VM was configured with a pre-built + // vm.Config by the launcher (microvm direct-boot path). When true, + // startQEMU skips buildBaseVMConfig and uses the existing Config + // instead. False for all PC-machine VMs. + DirectBoot bool `json:"direct_boot,omitempty"` + // GPUPCIAddresses holds the PCI addresses of all GPUs bound to this instance via // VFIO (e.g. ["0000:03:00.0"]). Empty for non-GPU instances. Single-GPU instances // have one entry; multi-GPU instances have one per assigned GPU. @@ -195,6 +201,17 @@ type Config struct { // UseUEFI requests OVMF firmware instead of the default SeaBIOS for x86_64 VMs. // Falls back silently to SeaBIOS if OVMF is not installed on the host. UseUEFI bool `json:"use_uefi,omitempty"` + + KernelImage string `json:"kernel_image,omitempty"` // path to vmlinuz; emits -kernel when set + Initrd string `json:"initrd,omitempty"` // path to initramfs; emits -initrd when set + KernelCmdline string `json:"kernel_cmdline,omitempty"` // emits -append when set + FwCfg []FwCfgEntry `json:"fw_cfg,omitempty"` // each emits -fw_cfg name=,file= +} + +// FwCfgEntry describes a single QEMU firmware configuration file entry. +type FwCfgEntry struct { + Name string `json:"name"` + File string `json:"file"` } func (cfg *Config) Execute() (*exec.Cmd, error) { @@ -230,10 +247,19 @@ func (cfg *Config) Execute() (*exec.Cmd, error) { args = append(args, "-display", "none") } - if cfg.SerialSocket != "" && cfg.ConsoleLogPath != "" { + if IsMMIO(cfg.MachineType) && cfg.ConsoleLogPath != "" { + // microvm with isa-serial=on: the machine creates the ISA serial device. + // Use -chardev file so output is captured without a socket client, then + // -serial chardev:console0 wires it to the existing device (not a new one). + // Do NOT use -device isa-serial here — that adds a second device (ttyS1) + // while the kernel talks to ttyS0. + args = append(args, "-chardev", fmt.Sprintf("file,id=console0,path=%s", cfg.ConsoleLogPath)) + args = append(args, "-serial", "chardev:console0") + } else if cfg.SerialSocket != "" && cfg.ConsoleLogPath != "" { chardevOpts := fmt.Sprintf("socket,id=console0,path=%s,server=on,wait=off,logfile=%s", cfg.SerialSocket, cfg.ConsoleLogPath) - args = append(args, "-chardev", chardevOpts, "-serial", "chardev:console0") + args = append(args, "-chardev", chardevOpts) + args = append(args, "-serial", "chardev:console0") } if cfg.CPUCount > 0 { @@ -252,8 +278,8 @@ func (cfg *Config) Execute() (*exec.Cmd, error) { args = append(args, "-object", fmt.Sprintf("iothread,id=%s", iot.ID)) } - if len(cfg.Drives) == 0 { - return nil, fmt.Errorf("at least one drive is required") + if len(cfg.Drives) == 0 && cfg.KernelImage == "" { + return nil, fmt.Errorf("at least one drive or a kernel image is required") } for _, drive := range cfg.Drives { @@ -296,6 +322,22 @@ func (cfg *Config) Execute() (*exec.Cmd, error) { args = append(args, "-netdev", netdev.Value) } + if cfg.KernelImage != "" { + args = append(args, "-kernel", cfg.KernelImage) + } + + if cfg.Initrd != "" { + args = append(args, "-initrd", cfg.Initrd) + } + + if cfg.KernelCmdline != "" { + args = append(args, "-append", cfg.KernelCmdline) + } + + for _, fw := range cfg.FwCfg { + args = append(args, "-fw_cfg", fmt.Sprintf("name=%s,file=%s", fw.Name, fw.File)) + } + var qemuArchitecture string switch cfg.Architecture { diff --git a/spinifex/vm/vm_test.go b/spinifex/vm/vm_test.go index 7e286586c..8fb2eefc2 100644 --- a/spinifex/vm/vm_test.go +++ b/spinifex/vm/vm_test.go @@ -3,6 +3,7 @@ package vm import ( "os" "slices" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -34,9 +35,9 @@ func TestExecute(t *testing.T) { cmd, err = cfg.Execute() - // Expect error, at least one drive required + // Expect error, at least one drive or kernel image required assert.Error(t, err) - assert.ErrorContains(t, err, "at least one drive is required") + assert.ErrorContains(t, err, "at least one drive or a kernel image is required") assert.Nil(t, cmd) cfg.Drives = []Drive{ @@ -231,6 +232,49 @@ func argExists(args []string, flag string) bool { return slices.Contains(args, flag) } +// allArgValues returns all values following flag (every occurrence). +func allArgValues(args []string, flag string) []string { + var out []string + for i, a := range args { + if a == flag && i+1 < len(args) { + out = append(out, args[i+1]) + } + } + return out +} + +func TestExecute_DriveAndKernelInvariant(t *testing.T) { + base := Config{ + CPUCount: 2, + Memory: 1024, + Architecture: "x86_64", + } + + t.Run("drives-only is OK", func(t *testing.T) { + cfg := base + cfg.Drives = []Drive{{File: "disk.img", Format: "raw"}} + cmd, err := cfg.Execute() + assert.NoError(t, err) + assert.NotNil(t, cmd) + }) + + t.Run("kernel-only is OK", func(t *testing.T) { + cfg := base + cfg.KernelImage = "/boot/vmlinuz" + cmd, err := cfg.Execute() + assert.NoError(t, err) + assert.NotNil(t, cmd) + }) + + t.Run("both-empty returns error", func(t *testing.T) { + cfg := base + cmd, err := cfg.Execute() + assert.Error(t, err) + assert.ErrorContains(t, err, "at least one drive or a kernel image") + assert.Nil(t, cmd) + }) +} + func TestResetNodeLocalState(t *testing.T) { v := &VM{ ID: "i-abc123", @@ -306,6 +350,30 @@ func TestExecute_SerialSocketAndConsoleLog(t *testing.T) { }) } +func TestExecute_MicrovmFileChardev(t *testing.T) { + cfg := Config{ + CPUCount: 1, + Memory: 512, + Architecture: "x86_64", + MachineType: "microvm,x-option-roms=off", + ConsoleLogPath: "/var/log/console.log", + KernelImage: "/boot/vmlinuz", + } + + cmd, err := cfg.Execute() + assert.NoError(t, err) + require.NotNil(t, cmd) + + args := cmd.Args[1:] + chardev := argValue(args, "-chardev") + assert.Equal(t, "file,id=console0,path=/var/log/console.log", chardev) + // -serial chardev:console0 attaches to the isa-serial=on device (ttyS0). + assert.Equal(t, "chardev:console0", argValue(args, "-serial")) + // No explicit isa-serial device addition (would create ttyS1, not ttyS0). + devs := strings.Join(allArgValues(args, "-device"), " ") + assert.NotContains(t, devs, "isa-serial") +} + func TestExecute_ARM64_Q35(t *testing.T) { const uefiPath = "/usr/share/qemu-efi-aarch64/QEMU_EFI.fd" if _, err := os.Stat(uefiPath); err != nil { diff --git a/tests/e2e/run-lb-e2e.sh b/tests/e2e/run-lb-e2e.sh index 8a6e58344..8e39744a0 100755 --- a/tests/e2e/run-lb-e2e.sh +++ b/tests/e2e/run-lb-e2e.sh @@ -12,6 +12,21 @@ set -e # ./tests/e2e/run-lb-e2e.sh # internal-only (single-node) # ./tests/e2e/run-lb-e2e.sh --peer # all 4 variants (multi-node, legacy) # ./tests/e2e/run-lb-e2e.sh --nodes ... # all 4 variants (multi-node, preferred) +# ./tests/e2e/run-lb-e2e.sh --microvm # same as above but with microvm.elbv2_enabled=true +# +# CI dual-path: this script is run twice in CI for microvm validation: +# 1. Default (microvm.elbv2_enabled=false) — baseline PC-machine path +# 2. With --microvm flag — direct-boot microvm path +# Both runs must pass identical assertions. +# +# Density test (manual, not CI-automated): +# LB_COUNT=50 ./tests/e2e/run-lb-e2e.sh --microvm +# Launches 50 LBs; asserts all reach Active; total QEMU fleet RSS logged. +# +# Customer-VM regression: run-e2e.sh (RunInstances + SSH) is run separately +# with microvm.elbv2_enabled=true to confirm customer VMs are unaffected. +# LaunchSystemInstance with DirectBoot=true is only reached by the ELBv2 +# service; RunInstances takes the PC-machine path unconditionally. cd "$(dirname "$0")/../.." @@ -31,13 +46,20 @@ fi # ========================================================================== PEER_NODE_IP="" ALL_NODE_IPS=() +MICROVM_MODE=false while [ $# -gt 0 ]; do case "$1" in - --peer) PEER_NODE_IP="$2"; shift 2 ;; - --nodes) shift; while [ $# -gt 0 ] && [[ "$1" != --* ]]; do ALL_NODE_IPS+=("$1"); shift; done ;; - *) echo "Unknown arg: $1"; exit 1 ;; + --peer) PEER_NODE_IP="$2"; shift 2 ;; + --nodes) shift; while [ $# -gt 0 ] && [[ "$1" != --* ]]; do ALL_NODE_IPS+=("$1"); shift; done ;; + --microvm) MICROVM_MODE=true; shift ;; + *) echo "Unknown arg: $1"; exit 1 ;; esac done + +if [ "$MICROVM_MODE" = true ]; then + export SPINIFEX_MICROVM_ELBV2_ENABLED=true + echo "[run-lb-e2e] microvm mode: SPINIFEX_MICROVM_ELBV2_ENABLED=true" +fi # --nodes supersedes --peer; fall back to --peer for backwards compat if [ ${#ALL_NODE_IPS[@]} -gt 0 ] && [ -z "$PEER_NODE_IP" ]; then PEER_NODE_IP="${ALL_NODE_IPS[1]:-}" @@ -776,7 +798,7 @@ if [ "$PEER_AVAILABLE" = true ]; then # test_http_from