diff --git a/.gitignore b/.gitignore index 1170717..51363f6 100644 --- a/.gitignore +++ b/.gitignore @@ -107,6 +107,10 @@ dist # vitepress build output **/.vitepress/dist +# wrangler local state +.wrangler/ +.dev.vars + # vitepress cache directory **/.vitepress/cache diff --git a/.vitepress/config.mts b/.vitepress/config.mts index d2e200c..37e81b5 100644 --- a/.vitepress/config.mts +++ b/.vitepress/config.mts @@ -7,7 +7,7 @@ const withBase = (path: string) => `${base}${path.replace(/^\//, "")}`; export default defineConfig({ lang: "en-US", title: "Optimum Docs", - description: "The world's first high-performance memory infrastructure for any blockchain.", + description: "Run an Optimum gateway, connect your validators, and read Signal and Accelerate in Console.", lastUpdated: true, cleanUrls: true, ignoreDeadLinks: true, @@ -49,7 +49,7 @@ export default defineConfig({ "meta", { property: "description", - content: "The world's first high-performance memory infrastructure for any blockchain.", + content: "Run an Optimum gateway, connect your validators, and read Signal and Accelerate in Console.", }, ], ["meta", { httpEquiv: "Content-Language", content: "en" }], @@ -111,91 +111,95 @@ export default defineConfig({ socialLinks: [ { icon: "github", link: "https://github.com/getoptimum/docs" }, { icon: "x", link: "https://x.com/get_optimum" }, - { icon: "discord", link: "https://discord.gg/7EwFpu79cZ" }, + { icon: "discord", link: "https://discord.gg/getoptimum" }, // { icon: "youtube", link: "" }, // { icon: { svg: telegramSVG }, link: "" }, ], } }) +const gateway = "https://getoptimum.github.io/optimum-gateway/versions/latest" + function nav() { return [ - { - text: "Optimum Gateway", - link: "https://getoptimum.github.io/optimum-gateway/versions/latest/", - }, - { - text: "Menu", - items: [ - { text: "Learn", link: "/docs/learn/overview/intro" }, - { - text: "Resources", - items: [ - // { - // text: "Optimum Improvement Proposals (OIPs)", - // link: "https://docs.getoptimum.xyz/", // TODO: Update link once live. - // }, - { - text: "Optimum ADRs", - link: "https://github.com/getoptimum/optimum/tree/main/docs/architecture#adr-table-of-contents", - }, - // { - // text: "Flexnode API Docs", - // link: "https://docs.getoptimum.xyz/", // TODO: Update link once live. - // }, - ], - }, - ], - }, + { text: "Start", link: "/start/what-optimum-does" }, + { text: "Console", link: "https://console.getoptimum.io/" }, + { text: "Gateway", link: `${gateway}/` }, ]; } function sidebarHome() { return [ { - text: "Overview of Optimum", + text: "Start here", + collapsed: false, + items: [ + { text: "Introduction", link: "/" }, + { text: "What Optimum does", link: "/start/what-optimum-does" }, + { text: "Choose a path", link: "/start/choose-a-path" }, + { text: "Before you begin", link: "/start/before-you-begin" }, + ], + }, + { + text: "Getting in", collapsed: false, items: [ - { - text: "Introduction", - link: "/docs/learn/overview/intro", - }, - { - text: "mump2p Protocol", - link: "/docs/learn/overview/p2p.md", - }, + { text: "Create an account", link: "/getting-in/create-an-account" }, + { text: "Account type", link: "/getting-in/account-type" }, + { text: "Register", link: "/getting-in/register" }, ], }, { - text: "Optimum Gateway", + text: "Signal", collapsed: false, items: [ - { - text: "Documentation", - link: "https://getoptimum.github.io/optimum-gateway/versions/latest/", - }, - { - text: "Quick start (HOP)", - link: "https://getoptimum.github.io/optimum-hop/", - }, + { text: "What Signal does", link: "/signal/what-signal-does" }, + { text: "Network", link: "/signal/network" }, + { text: "Connect your gateway", link: "/signal/connect-your-gateway" }, + { text: "When the check fails", link: "/signal/when-the-check-fails" }, + { text: "Register keys", link: "/signal/register-keys" }, + { text: "Onboard in bulk", link: "/signal/onboard-in-bulk" }, + { text: "Your first report", link: "/signal/your-first-report" }, ], }, { - text: "Research", + text: "Accelerate", collapsed: false, items: [ - { - text: "Gossip", - link: "/docs/research/gossip/gossip", - }, - { - text: "Transport", - link: "/docs/research/gossip/transport", - }, - { - text: "Decentralized Access", - link: "/docs/research/gossip/decentralized-access", - }, + { text: "What Accelerate does", link: "/accelerate/what-accelerate-does" }, + { text: "Readiness", link: "/accelerate/readiness" }, + { text: "Recommendation", link: "/accelerate/recommendation" }, + { text: "Adjust MEV-Boost", link: "/accelerate/adjust-mev-boost" }, + { text: "Where results show", link: "/accelerate/where-results-show" }, + ], + }, + { + text: "Operate", + collapsed: true, + items: [ + { text: "Run the gateway", link: "/operate/run-the-gateway" }, + { text: "Kubernetes", link: "/operate/kubernetes" }, + { text: "Block stream", link: "/operate/block-stream" }, + { text: "Telemetry", link: "/operate/telemetry" }, + ], + }, + { + text: "Help", + collapsed: true, + items: [ + { text: "Troubleshoot", link: "/help/troubleshoot" }, + { text: "Support", link: "/help/support" }, + { text: "FAQ", link: "/help/faq" }, + ], + }, + { + text: "Learn", + collapsed: true, + items: [ + { text: "mump2p protocol", link: "/docs/learn/overview/p2p" }, + { text: "Gossip", link: "/docs/research/gossip/gossip" }, + { text: "Transport", link: "/docs/research/gossip/transport" }, + { text: "Decentralized access", link: "/docs/research/gossip/decentralized-access" }, ], }, ] diff --git a/.vitepress/theme/style.css b/.vitepress/theme/style.css index 45ff480..6bde2eb 100644 --- a/.vitepress/theme/style.css +++ b/.vitepress/theme/style.css @@ -165,3 +165,16 @@ html.dark .light-mode-only { html.dark .dark-mode-only { display: block !important; } + +/* The data-path diagram uses currentColor, so it follows the theme. */ +.data-path { + overflow-x: auto; + margin: 1.5rem 0; + color: var(--vp-c-text-1); +} + +.data-path svg { + width: 100%; + height: auto; + display: block; +} diff --git a/accelerate/adjust-mev-boost.md b/accelerate/adjust-mev-boost.md new file mode 100644 index 0000000..dcae0cf --- /dev/null +++ b/accelerate/adjust-mev-boost.md @@ -0,0 +1,22 @@ +--- +title: Adjust MEV-Boost +description: Download the config and deploy it yourself. Console does not push it. +--- + +# Adjust MEV-Boost + +Upload first. The editor reads the file you are running. + +**Bid cutoff** is `timeout_get_header_ms`: the last moment a getHeader bid is accepted, in milliseconds into the slot. A later cutoff can take a higher bid. Set late enough, the proposal misses the slot. + +The late-in-slot deadline is `late_in_slot_time_ms`. The cutoff cannot sit on or past it; Console keeps the cutoff at least 1 ms earlier. + +Move the cutoff, then **DOWNLOAD CONFIG**. The file is `mev-boost-config.yaml`. + +![Accelerate, Adjust. The cutoff in milliseconds and Download config are marked.](/console/09-accelerate-adjust.png) + +The screen says **Export the new config and deploy it — nothing here reaches your infrastructure.** Deploy that file on your MEV-Boost the way you already deploy config. Optimum has no write access to it. + +**Configuration matches the file you uploaded** means you have not moved the cutoff since the upload. **Unsaved changes to the cutoff** means the editor and the file you uploaded differ; download before you deploy, or the node is still on the old value. + +After a config is stored, **Results** on the Accelerate screen says the terms are accepted and a configuration is on file. **View the proposal report** opens the measurement. What changed after you deployed is on that report, not on the upload panel. See [Where results show](/accelerate/where-results-show). diff --git a/accelerate/readiness.md b/accelerate/readiness.md new file mode 100644 index 0000000..a8fdf5d --- /dev/null +++ b/accelerate/readiness.md @@ -0,0 +1,33 @@ +--- +title: Readiness +description: The 200-proposal floor Console uses before it will recommend a cutoff. +--- + +# Readiness + +Before you accept anything, Console states what the current window can support. + +A cutoff recommendation needs **200 proposals that carry a failure measurement**, across all your validators, not per key. The panel is **Not enough proposals yet** until that count reaches 200. You can still start Accelerate and upload a configuration. Measurement runs from the moment that configuration takes effect. The recommendation appears once the window holds enough. + +When the window is large enough and a later bid was actually available, the panel is **What your proposals show**. The number is **ETH per MEV block**, left on the table in this window, measured against bids that arrived after the one your current cutoff took. The line under it is **Already proposed — not a projection.** + +Two other answers, when there is nothing to recommend: + +* Proposals were measured, but none of them took a relay bid, so there is no bid curve to read a cutoff from yet. +* Proposals were measured, and no better bid arrived after the one your current cutoff took. + +Under **Before you start**, the row **Validator keys registered** has three states. Indices are required to know which slots you propose. The button tells you what is missing rather than failing silently. + +![Accelerate, Before you start. Validator keys registered is marked, and its state is Needed.](/console/08-accelerate-before-you-start.png) + +| State | On the screen | What to do | +| --- | --- | --- | +| **Needed** | Needed to know which slots you propose. | [Register keys](/signal/register-keys). | +| **Activating** | Indices on record, none active on chain yet. | Wait for the activation queue. Pending validators are not assigned proposal slots, so nothing is measured until they activate. | +| **Done** | `N` of `M` registered indices active on chain. | Nothing. Proposals count as they happen. | + +While Console is still looking, the row reads **Checking which of your indices are active on chain…**. + +If indices are on record and the panel says **Not enough proposals yet**, check this row first. **Activating** means you are waiting on activation, not on proposal luck. + +The report’s own charts use the same measurement: accepted ETH on the bid that was taken, unrealised ETH on bids that arrived later, per MEV block. A per-proposal average is a different number and is labelled that way on the report. Do not read the headline ETH-per-MEV-block figure as ETH per proposal. diff --git a/accelerate/recommendation.md b/accelerate/recommendation.md new file mode 100644 index 0000000..2f3049a --- /dev/null +++ b/accelerate/recommendation.md @@ -0,0 +1,22 @@ +--- +title: Recommendation +description: What you accept before a cutoff is shown, and what the number means. +--- + +# Recommendation + +**Start Accelerate** opens **Acknowledge the disclaimer**. You can close it. Staff cannot accept it for you. + +The notice says the configuration information is a simulation from current network data, for information only. Optimum does not guarantee a performance outcome. Changes you make on your own infrastructure are your decision, and Optimum is not liable for the outcomes of using that information. + +Read the text in the dialog. The copy on this page is a summary so you know what the step is. The dialog is the agreement. + +After you accept, **Bid cutoff** asks you to upload the MEV-Boost configuration you actually run. Console compares it with what your proposals show. It still does not change anything on your side. + +If you have no file yet, **Download a starter file**. The download is `mev-boost-config.yaml`, with the known mainnet relays and MEV-Boost’s default cutoff. It is a starting point, not a config Console has applied. + +Until a file is on record, the report has no cutoff to judge proposals by. The screen says **No configuration uploaded yet**. + +The recommendation itself is withheld below 200 measured proposals. The callout is **Not enough proposals yet for a recommendation**. See [Readiness](/accelerate/readiness). + +On the report, **Recommended cutoff** is the offset where a later bid was available. The note is ETH per MEV block across the MEV blocks in the window. The callout beside it is **This does not price the risk of waiting**: the figure is uplift that was available at that offset, on blocks already proposed. **No cutoff change indicated** means the window does not support moving it. diff --git a/accelerate/what-accelerate-does.md b/accelerate/what-accelerate-does.md new file mode 100644 index 0000000..ca5a2d7 --- /dev/null +++ b/accelerate/what-accelerate-does.md @@ -0,0 +1,37 @@ +--- +title: What Accelerate does +description: Bid cutoff recommendations from slots you already proposed, for entity accounts. Console does not apply them. +--- + +# What Accelerate does + +Accelerate recommends a MEV-Boost bid cutoff from slots your validators already proposed. Console never writes to your infrastructure. You upload the MEV-Boost configuration you run, read a recommendation, and download a config to deploy yourself. Nothing on this screen changes validator behaviour until you deploy that file. + +## Who can use it + +Accelerate is for **entity** accounts. An **individual** account has Signal only. See [Account type](/getting-in/account-type). + +A recommendation needs 200 measured proposals ([Readiness](/accelerate/readiness)). An individual operator rarely proposes that many in a window short enough to act on, so the flow is offered to entities. + +If you registered as an entity and **Accelerate** is not in the sidebar, it is not enabled for your account yet. Ask [support](/help/support). There is no other URL to use. + +## The steps + +1. **Start Accelerate** — prerequisites, including the disclaimer. +2. **Recommendation** — your config. +3. **Adjust** — you record the cutoff you will deploy. + +Where you land on a return visit follows what is already stored. No acceptance sends you to step 1. Acceptance without a saved config sends you to the recommendation. A saved config sends you to adjust. If the terms change, the previous acceptance no longer counts and you start again. + +## What it measures + +Every figure is measured on slots you already proposed. Console does not forecast an annual gain. + +## Older names on some screens + +Accelerate is the product. A few Console labels still use older names for the same thing: + +* **MumBoost** — the report entry under **Performance**, and the terms messages. +* **MEV Cutoff Optimisation** — the title of the proposal report. + +This site says Accelerate, and quotes those labels where you need to find them on screen. diff --git a/accelerate/where-results-show.md b/accelerate/where-results-show.md new file mode 100644 index 0000000..d1709b2 --- /dev/null +++ b/accelerate/where-results-show.md @@ -0,0 +1,27 @@ +--- +title: Where results show +description: The Accelerate proposal report Console opens after a cutoff is on file. +--- + +# Where results show + +Open **View the proposal report** on Accelerate, or **Performance** → **MumBoost** in the sidebar. Both open the same Accelerate report. Its title on screen is still **MEV Cutoff Optimisation**. The subtitle says the window measures either performance since your last cutoff adjustment or a window you selected. The window end date is not included. + +![The proposal report. MumBoost in the sidebar and the title MEV Cutoff Optimisation are marked.](/console/10-proposal-report.png) + +**Optimum · mump2p · Mainnet** above the title names the network. It is not a separate product. + +Once the window has proposals, the report shows: + +* Proposal count, in slots. +* Accepted ETH and unrealised ETH per MEV block. Offsets count from the bid you took, not from the start of the slot. +* A cutoff curve showing the extra value per MEV block if the cutoff had been later, compared with the bid that was accepted. +* Head votes and failure types by slot. + +**No proposals in this window** means none of your validators was assigned a block proposal in that range. Widen the window. + +**No report for this window** means the report failed to load. It does not mean you have no proposals. Refresh. If it persists, use [Support](/help/support). + +Console stores a configuration only after it confirms you accepted the terms. **Could not check the MumBoost terms** means that check failed. Wait and refresh. **This operator has not accepted the MumBoost terms** means you need to accept them on Accelerate first. Both labels use MumBoost, the older name for Accelerate. See [Older names on some screens](/accelerate/what-accelerate-does#older-names-on-some-screens). + +The **MumBoost** entry appears only when it is enabled for your account. diff --git a/docs/how-to-guides/overview.md b/docs/how-to-guides/overview.md deleted file mode 100644 index f4562e5..0000000 --- a/docs/how-to-guides/overview.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -description: Learn how to get started with the Optimum protocol. ---- - -# Quick-start Overview - -## Under Construction 🚧 diff --git a/docs/learn/how-to-stake-mum.md b/docs/learn/how-to-stake-mum.md deleted file mode 100644 index e1cc786..0000000 --- a/docs/learn/how-to-stake-mum.md +++ /dev/null @@ -1,3 +0,0 @@ -# How to stake MUM - -## Under Construction 🚧 diff --git a/docs/learn/opt.md b/docs/learn/opt.md deleted file mode 100644 index c6c3328..0000000 --- a/docs/learn/opt.md +++ /dev/null @@ -1,3 +0,0 @@ -# Overview of the MUM Token - -## Under Construction 🚧 diff --git a/docs/learn/overview/intro.md b/docs/learn/overview/intro.md deleted file mode 100644 index f52414d..0000000 --- a/docs/learn/overview/intro.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -description: Get a quick primer on the constituent components of the Optimum protocol. ---- - -# Introduction to Optimum - -**Optimum** is the fastest decentralized internet protocol for web3. It accelerates **low-latency gossip** across geographically distributed nodes to scale data access and reduce network congestion for latency-sensitive dApps. - -Powered by [Random Linear Network Coding (RLNC)](./p2p.md#random-linear-network-coding-rlnc-fundamentals) — a cutting-edge data encoding technique developed under the supervision of **Professor Muriel Medard, EECS, MIT**. By applying RLNC to gossip, Optimum reduces redundancy and improves loss tolerance; under standard RLNC models, the dissemination strategy is **provably optimal** for throughput/latency under loss and contention. - -**Network & roles.** Optimum runs as a permissionless network of **[flexnodes](#flexnodes)** that anyone can operate alongside existing clients and P2P stacks. - -## Products - -Builders and operators can adopt **mump2p** now for measurable latency gains via the **Optimum Gateway**. - -### mump2p - -RLNC-accelerated, libp2p/gossipsub-compatible pub/sub for fast, resilient propagation of blocks, blobs, and transactions. -**Get started:** [Overview](../../learn/overview/p2p.md) · [Optimum Gateway](https://getoptimum.github.io/optimum-gateway/versions/latest/) - -## Flexnodes - -A **flexnode** is an operator-run node that participates in Optimum's coded gossip and serves memory requests. Flexnodes: - -* encode, decode, and forward RLNC-coded gossip frames; -* maintain bounded coded buffers to recover loss and smooth tail latency; -* interoperate with existing clients and libp2p/gossipsub where applicable. - -## Start here - -* **Run the Optimum Gateway:** [Gateway docs](https://getoptimum.github.io/optimum-gateway/versions/latest/) - -### Intended users - -L1/L2 teams (faster block/blob propagation); validators (lower missed-slot risk → APY/MEV uplift); node operators & builders (lower tail latency); dApp developers (faster inclusion); end users (snappier UX). - diff --git a/getting-in/account-type.md b/getting-in/account-type.md new file mode 100644 index 0000000..73ff64c --- /dev/null +++ b/getting-in/account-type.md @@ -0,0 +1,20 @@ +--- +title: Account type +description: Individual or Entity. Staking is not a precondition. +--- + +# Account type + +The question is **How do you take part?** + +| | Individual | Entity | +| --- | --- | --- | +| Who | You take part under your own name. | A company, fund, or staking provider. | +| Next screen | **Your details**. Contact fields. | **Your organisation**. Entity fields, then the same contact fields. | +| What you can use | Signal. | Signal and Accelerate. | + +Pick **Entity** if you want Accelerate. It is not offered to individual accounts: a cutoff recommendation needs 200 measured proposals, which an individual operator rarely reaches in a useful window. See [What Accelerate does](/accelerate/what-accelerate-does). + +The stored account type for an individual is an internal id. The label on the screen is **Individual**. + +Running validators is the next question, on the registration screen, not this one. Answering no is a supported account. It selects the stream-only gateway. It does not block registration. diff --git a/getting-in/create-an-account.md b/getting-in/create-an-account.md new file mode 100644 index 0000000..63f9a3c --- /dev/null +++ b/getting-in/create-an-account.md @@ -0,0 +1,33 @@ +--- +title: Create an account +description: Sign up to Console with Google or Microsoft, or sign in to an account Optimum already created. +--- + +# Create an account + +Open [Console](https://console.getoptimum.io/). The sign-in card has two tabs. + +| Tab | Heading | Buttons | +| --- | --- | --- | +| **Create account** | **Create your account** | **Sign up with Google**, **Sign up with Microsoft** | +| **Sign in** | **Sign in to Console** | **Continue with Google**, **Continue with Microsoft** | + +**Create account** takes a new account into registration. **Sign in** takes you back to the console, or to the page you were opening. If you sign in with an account that has no organisation yet, finish registration from the button on the console home page (see below). + +**Trouble signing in?** at the bottom of the card opens support. + +![Sign-in card. The Sign in and Create account tabs are marked, and Trouble signing in? is marked.](/console/01-sign-in.png) + +![Create account tab. Sign up with Google and Sign up with Microsoft are marked.](/console/02-create-account.png) + +The rail, once registration starts, is **Register org**, then **Connect**, then **Register keys** if you run validators. You can leave Connect with **I’ll do this later** and finish on **Signal**. You can leave validator indices with **Skip for now** and come back from the signup link. + +The last screen is **Your account is ready**. It shows whether a gateway enrolled, how many indices you submitted (**Awaiting confirmation**), and **Go to the console**. + +## When signup is closed + +If the card has no **Create account** tab, or [signup](https://console.getoptimum.io/signup) shows a 404, self-serve signup is closed. Optimum creates the account for you, and you sign in with the Google or Microsoft account you gave them. Where Signal and Accelerate are enabled for your organisation, you use the same screens. + +## No organisation linked + +**No operator account linked to your user.** means you signed in but registration never finished. While signup is open, the same screen shows **Finish setting up your account**, which returns you to registration. Without that button, ask [support](/help/support) to link the account. diff --git a/getting-in/register.md b/getting-in/register.md new file mode 100644 index 0000000..7d4755b --- /dev/null +++ b/getting-in/register.md @@ -0,0 +1,35 @@ +--- +title: Register +description: The fields Console asks for, and the terms checkbox on the same screen. +--- + +# Register + +The heading is **Your details** or **Your organisation**, depending on the account type. + +## Entity + +All of these are required. + +* **Entity name** +* **Display name** — your Console org name +* **Registered address** — named as the Partner's address in the agreement +* **State or country of incorporation** +* **Your title** — recorded in the agreement's signature block + +## Everyone + +* **Do you run validators?** — Yes or No. Asked even when you have no beacon node. +* **Full name** — required. The person accepting, named in the signature block. +* **Username** — required. For an individual, this is your Console org name. An entity already set that as Display name. +* **Telegram handle** — optional +* **Contact email** — required. For notifications. + +If you answer yes, Console also asks: + +* **Total stake (ETH)** +* **Stake to connect to Optimum (ETH)** + +There is no separate terms screen. On this screen, tick **I have read and agree to the terms**. The checkbox opens the agreement. **Accept the terms to continue** if you submit without it. + +Submitting this screen is what creates the organisation. Connect is next when enrolment is available for the account. Otherwise you go to validator indices, if you run validators, or straight to a ready account. diff --git a/help/faq.md b/help/faq.md new file mode 100644 index 0000000..ab853d0 --- /dev/null +++ b/help/faq.md @@ -0,0 +1,46 @@ +--- +title: FAQ +description: Short answers that point back at the page with the steps. +--- + +# FAQ + +## `/health` returns 503 right after the container starts + +Expected if you run validators and the client is not peered yet. `cl_peers`, `cl_health`, and `subscribed_topics` fail until then. For whether the gateway reached Optimum, trust **Verify** on Signal rather than this status. [Connect your gateway](/signal/connect-your-gateway). + +## `curl` to port 48123 from my laptop is refused + +The port is published on `127.0.0.1` of the gateway host. Run it there. [Network](/signal/network). + +## The peer id changed after a restart + +The identity directories were not mounted. [When the check fails](/signal/when-the-check-fails). + +## The second gateway was refused + +`OPT_GATEWAY_ID` is the hostname, and it is unique per organisation. [Before you begin](/start/before-you-begin). + +## I lost the enrollment key + +It cannot be shown again. On Signal, create a one-day key into the command, or mint one on **Keys** → **Enrollment keys** (**Manage gateways** on an invited account). Gateways that already enrolled are not affected. [Why enrollment keys](/signal/what-signal-does#why-enrollment-keys). + +## Which enrollment key should I use? + +The one from signup lasts 14 days. The one from Signal lasts a day. For a fleet rolled out over weeks, mint one on **Enrollment keys** and set **Valid for (days)**. [Why enrollment keys](/signal/what-signal-does#why-enrollment-keys). + +## I do not see Accelerate + +Accelerate is for entity accounts. An individual account has Signal only. If you registered as an entity and the entry is missing, it is not enabled for your account yet: ask [support](/help/support). [What Accelerate does](/accelerate/what-accelerate-does). + +## I do not see a performance report + +Each report waits on something different: a running gateway, confirmed indices, or proposed slots. Each entry appears only when it is enabled for your account. [Your first report](/signal/your-first-report). + +## Which region do I pick? + +None. Console does not ask for a region. Run the gateway on a host that can reach your beacon node and can open the ports in [Network](/signal/network). + +## Can Optimum run the gateway for me? + +No. Optimum does not host gateways. You run the container. [Choose a path](/start/choose-a-path). diff --git a/help/support.md b/help/support.md new file mode 100644 index 0000000..b2aec40 --- /dev/null +++ b/help/support.md @@ -0,0 +1,23 @@ +--- +title: Support +description: Where to ask when the docs and the gateway troubleshooting page do not cover it. +--- + +# Support + +Ask in the validator support channel on [Discord](https://discord.gg/getoptimum). Console's **Support** link and **Trouble signing in?** point to the same server. Support and announcements both run there. + +Partners Optimum onboards directly also have a dedicated Telegram group. Use it if you were given one. + +Use support when an index is already claimed, a lookup limit stopped a submit, a gateway credential needs revoking on a self-serve account, or a report failed to load after a refresh. Include: + +* the gateway id (`OPT_GATEWAY_ID`, which is the host name) +* the consensus client and its version +* the `failing` list from `curl http://localhost:48123/health`, if you have it +* what **Verify** on Signal shows + +Do not paste the enrollment key or any other secret. + +Invited operator accounts may also have **Help** → **Support** in the Console sidebar. Self-serve accounts do not get that group; use the Discord link above. + +The [security audit](https://cdn.probelab.io/media/documents/2026-08-ProbeLab-Security_Audit_Report_Optimum_Gateway.pdf) is a published PDF, not a support channel. diff --git a/help/troubleshoot.md b/help/troubleshoot.md new file mode 100644 index 0000000..8440578 --- /dev/null +++ b/help/troubleshoot.md @@ -0,0 +1,68 @@ +--- +title: Troubleshoot +description: The failures operators hit, what each one means, and the fix. +--- + +# Troubleshoot + +Start with the failure you can see. For the four failures Console names under Verify, see [When the check fails](/signal/when-the-check-fails). + +## Signing in and signup + +**Signup shows a 404, or there is no Create account tab.** Self-serve signup is closed. [Create an account](/getting-in/create-an-account#when-signup-is-closed). + +**No operator account linked to your user.** Registration did not finish. Use **Finish setting up your account** if it is there, or ask [support](/help/support). [No organisation linked](/getting-in/create-an-account#no-organisation-linked). + +## Starting the container + +**`Conflict. The container name "/optimum-gateway" is already in use`.** An earlier container still holds the name, running or stopped. Remove it and run the command again: + +```bash +docker rm -f optimum-gateway +``` + +This is safe. The peer id and the enrollment credential live in `$HOME/optimum-gateway` on the host, not in the container. The same applies whenever you change an `-e` value: a restart keeps the old environment. + +**The container exits on `write identity data: permission denied`.** SELinux is enforcing on the host. Turn on **Add an SELinux relabel to the identity mounts** and run the new command. [When the check fails](/signal/when-the-check-fails#the-container-exits-on-a-permission-error). + +**The container exits on `unable to load config`.** `-config ""` is missing from the end of the command. Copy the whole command again. + +## Enrollment + +**Enrollment fails with `401`.** The key is unknown, expired, used up, or revoked. Optimum returns the same `401` for all four on purpose, so it reads like a typo. Check the key on **Enrollment keys**: the card shows the expiry date and **enrollments used**, and a revoked key is no longer listed. A key from Signal lasts one day. During signup, the same case shows **This key can no longer be used**. Mint a new key and run the command again. [Which key lifetime](/signal/what-signal-does#which-key-lifetime). + +**A second host is refused with `409`.** Another gateway in your organisation already enrolled under that hostname. Give the host a unique hostname. [Onboard in bulk](/signal/onboard-in-bulk). + +**A rebuilt host is refused with `409`.** The host lost `$HOME/optimum-gateway`, so it generated a new identity, and the old credential under its hostname is still live. Restore the directory if you have it. Otherwise revoke the old gateway key under **Manage gateways** → **Gateway** (self-serve accounts: ask [support](/help/support)), then start it again. + +**Signup says Still waiting.** Nothing has enrolled with the key yet, and the page stopped checking. The key stays valid. Run the command, and Console picks the gateway up when it connects. + +## Health and Verify + +**`/health` says `degraded` right after start.** For a validator gateway, expected until your consensus client is peered: `cl_peers`, `cl_health`, and `subscribed_topics` fail until then. For a stream-only gateway, it clears once the first block arrives. Use **Verify** on Signal to confirm the gateway reached Optimum. [Connect your gateway](/signal/connect-your-gateway#check-it-is-healthy). + +**A stream-only gateway stays `degraded` with `cl_peers` failing.** It was started with the beacon-node command from Signal. Replace it with the [stream-only command](/signal/connect-your-gateway#stream-only). + +**`curl` to port `48123` is refused from another machine.** Telemetry is published on the gateway host's loopback only. Run it on that host. + +**Verify passes, and you are not sure it is the new gateway.** Verify checks every gateway in your organisation together. It shows counts, such as **Yes, 3** enrolled, not names. If another gateway is already healthy, the rows can pass before the new one reports. Confirm the new host with `curl http://localhost:48123/health` on that host. [When the check fails](/signal/when-the-check-fails#verify). + +**The peer id changed after a restart.** The identity directories were not mounted. [The peer id changed](/signal/when-the-check-fails#the-peer-id-changed). + +## Validators and reports + +**Indices rejected or skipped.** [Register keys](/signal/register-keys). + +**A report is empty.** Each one waits for something different: a running gateway, confirmed indices, or proposed slots. [Your first report](/signal/your-first-report). + +## Accelerate + +**No Accelerate entry.** Accelerate is for entity accounts. An individual account has Signal only. An entity account without the entry: ask [support](/help/support). [Who can use it](/accelerate/what-accelerate-does#who-can-use-it). + +**Validator keys registered says Activating.** Your indices are on record and none is active on chain yet. Pending validators are not assigned proposals, so nothing is measured until they activate. [Readiness](/accelerate/readiness). + +**Not enough proposals yet.** The recommendation needs 200 measured proposals across your validators. [Readiness](/accelerate/readiness). + +## Past the Console command + +Config keys, log lines, and metric names are in [Troubleshooting](https://getoptimum.github.io/optimum-gateway/versions/latest/troubleshoot) for gateway `v1.3.2`. diff --git a/index.md b/index.md index b5ad336..4142f56 100644 --- a/index.md +++ b/index.md @@ -1,13 +1,76 @@ --- -layout: page -title: "Introduction" +title: Introduction to Optimum +description: Optimum delivers Ethereum blocks to your beacon node sooner, and measures your MEV-Boost bid cutoff against your own proposals. --- - +# Introduction to Optimum -# Introduction +Your validators can only attest to a block after it reaches your beacon node. When the block arrives late, attestations miss or vote on the wrong head. When you propose, the MEV-Boost bid cutoff sets how long you wait for a better bid. If you wait too long, your block is late. If you cut off too early, you leave value behind. -If you are not redirected automatically, [click here to go to the Introduction page](/docs/learn/overview/intro). +Optimum works on both. + +## What Optimum is + +**mump2p** is Optimum's peer-to-peer mesh. It propagates blocks using network coding: peers send coded pieces of a block and rebuild it from whichever pieces arrive first, instead of waiting for a full copy. See [mump2p protocol](/docs/learn/overview/p2p) for the details. + +You join the mesh by running the **Optimum gateway**, one container on a host beside your beacon node. + +
+ + + + + + + + + + + + NETWORK + Optimum mesh + Interconnected + mump2p nodes + + GATEWAY + Your gateway + (you run it) + + CONSENSUS + Your beacon node + (unchanged) + + VALIDATOR + Your validator client + (unchanged) + + +
+ +The gateway is a peer of your consensus client. It passes blocks to the client and never receives validator keys. Your validator client, keys, and signing setup stay exactly as they are. + +## What you get + +| | What it does | Where you see it | +| --- | --- | --- | +| **Signal** | The gateway hands your beacon node blocks from the mesh, so your validators receive blocks sooner. That improves attestation performance. | Signal in Console, then the **Network** report | +| **Accelerate** | Reads the slots your validators already proposed and recommends a MEV-Boost bid cutoff. You download the config and deploy it yourself. For entity accounts. | Accelerate in Console, then its proposal report | + +Console never changes your infrastructure. Optimum does not host gateways. You run the gateway and apply any configuration yourself. + +## Who it is for + +* **Staking providers and other entities.** Run a gateway beside each beacon node, register your validator indices so Console can measure the result, then use Accelerate on your proposals. +* **Individuals who run validators.** Signal works the same way for you. Accelerate is offered to entity accounts only. [Account type](/getting-in/account-type). +* **Participants without validators.** Run a stream-only gateway to receive blocks from the mesh and serve them to your own consumers. This is a supported account. + +## The path + +1. **[Start here](/start/what-optimum-does).** How the pieces fit, which path is yours, and what the host needs. +2. **[Getting in](/getting-in/create-an-account).** Create a Console account and register your organisation. +3. **[Signal](/signal/what-signal-does).** Start the gateway, peer your consensus client, verify it, and register your validator indices. +4. **[Accelerate](/accelerate/what-accelerate-does).** For entity accounts. Once enough of your proposals are measured, read the cutoff recommendation and adjust MEV-Boost. + +[Open Console](https://console.getoptimum.io/) + +Already running a gateway? The versioned manual (every setting, metric, and log line) is the [gateway reference](https://getoptimum.github.io/optimum-gateway/versions/latest/). diff --git a/operate/block-stream.md b/operate/block-stream.md new file mode 100644 index 0000000..a2c129d --- /dev/null +++ b/operate/block-stream.md @@ -0,0 +1,14 @@ +--- +title: Block stream +description: The consumer feed, and where its reference lives. +--- + +# Block stream + +A stream-only gateway serves blocks to your consumers. It is the path for an account that does not run validators. See [Choose a path](/start/choose-a-path). + +On the gateway host the feed is `ws://127.0.0.1:9600` and gRPC `127.0.0.1:9601`. Mint a consumer token under **Keys** → **Stream consumers**. + +Protocol, authentication, and client usage: [Consumer block stream](https://getoptimum.github.io/optimum-gateway/versions/latest/block-stream). + +“Block stream” is the name of that gateway feature. It is not a separate Optimum product. diff --git a/operate/kubernetes.md b/operate/kubernetes.md new file mode 100644 index 0000000..f581955 --- /dev/null +++ b/operate/kubernetes.md @@ -0,0 +1,10 @@ +--- +title: Kubernetes +description: Pointer to the gateway Helm guide. +--- + +# Kubernetes + +Console’s connect step is a `docker run`. The same gateway runs under Helm. Ports, the enrollment key, telemetry on loopback, and the identity volumes still apply: a pod that does not persist the libp2p and mump2p data gets a new peer id on restart. + +The chart and values are in [Kubernetes (Helm)](https://getoptimum.github.io/optimum-gateway/versions/latest/kubernetes). diff --git a/operate/run-the-gateway.md b/operate/run-the-gateway.md new file mode 100644 index 0000000..9435530 --- /dev/null +++ b/operate/run-the-gateway.md @@ -0,0 +1,18 @@ +--- +title: Run the gateway +description: Where the install, enrolment, and configuration references live. +--- + +# Run the gateway + +The command operators paste is the one in [Connect your gateway](/signal/connect-your-gateway). It matches what Console renders for production (`v1.3.2`). + +Use the versioned gateway docs when you need the rest: + +* [Quick start](https://getoptimum.github.io/optimum-gateway/versions/latest/quick-start) — install and consensus-client notes, including Lighthouse v8 PeerDAS flags. +* [Network requirements](https://getoptimum.github.io/optimum-gateway/versions/latest/network-requirements) +* [Configuration](https://getoptimum.github.io/optimum-gateway/versions/latest/configuration) +* [Gateway self-enrollment](https://getoptimum.github.io/optimum-gateway/versions/latest/gateway-self-enrollment) +* [Release notes](https://getoptimum.github.io/optimum-gateway/versions/latest/release-notes) + +`latest` tracks the current release. A command copied from an older version page will not match the image Console asks you to run. diff --git a/operate/telemetry.md b/operate/telemetry.md new file mode 100644 index 0000000..14cb904 --- /dev/null +++ b/operate/telemetry.md @@ -0,0 +1,23 @@ +--- +title: Telemetry +description: The loopback health port, and where metrics are documented. +--- + +# Telemetry + +Console enables telemetry and remote push in the start command. Both variables are required. See [Connect your gateway](/signal/connect-your-gateway). + +On the gateway host: + +```bash +curl http://localhost:48123/health +curl -s http://localhost:48123/api/v1/self_info +``` + +`/metrics` is on the same port and is not served until telemetry is enabled. Do not publish `48123` beyond loopback. + +What each series means, and how the panels are calculated: + +* [Metrics and Grafana](https://getoptimum.github.io/optimum-gateway/versions/latest/telemetry) +* [Metrics reference](https://getoptimum.github.io/optimum-gateway/versions/latest/metrics) +* [Metrics methodology](https://getoptimum.github.io/optimum-gateway/versions/latest/metrics-methodology) diff --git a/package.json b/package.json index 114a09c..c505c71 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,7 @@ { "scripts": { "docs:dev": "vitepress dev", + "build": "vitepress build", "docs:build": "vitepress build", "docs:preview": "vitepress preview", "lint": "eslint --fix", @@ -23,7 +24,8 @@ "typescript": "^5.2.2", "typescript-eslint": "^8.26.1", "vitepress": "^1.6.3", - "vue-eslint-parser": "^10.1.1" + "vue-eslint-parser": "^10.1.1", + "wrangler": "^4.144.0" }, "dependencies": { "@fontsource-variable/geist": "^5.2.9", diff --git a/public/_redirects b/public/_redirects new file mode 100644 index 0000000..580ab50 --- /dev/null +++ b/public/_redirects @@ -0,0 +1,18 @@ +/docs/learn/overview/intro / 301 +/docs/learn/overview/deram /start/what-optimum-does 301 +/docs/learn/p2p/intro /docs/learn/overview/p2p 301 +/docs/learn/opt /start/what-optimum-does 301 +/docs/learn/how-to-stake-mum /start/what-optimum-does 301 +/docs/aws_deploy_devnet /start/what-optimum-does 301 +/docs/aws_devnet /start/what-optimum-does 301 +/docs/linode_devnet /start/what-optimum-does 301 +/docs/resources/news /start/what-optimum-does 301 +/docs/resources/optimum /start/what-optimum-does 301 +/docs/index / 301 +/docs/guides /start/what-optimum-does 301 +/docs/guides/* /start/what-optimum-does 301 +/docs/how-to-guides /start/what-optimum-does 301 +/docs/how-to-guides/* /start/what-optimum-does 301 +/reference https://getoptimum.github.io/optimum-gateway/versions/latest/ 301 +/reference/ https://getoptimum.github.io/optimum-gateway/versions/latest/ 301 +/getting-in/region /help/faq 301 diff --git a/public/console/01-sign-in.png b/public/console/01-sign-in.png new file mode 100644 index 0000000..3d0140c Binary files /dev/null and b/public/console/01-sign-in.png differ diff --git a/public/console/02-create-account.png b/public/console/02-create-account.png new file mode 100644 index 0000000..14eb861 Binary files /dev/null and b/public/console/02-create-account.png differ diff --git a/public/console/03-signal-run-gateway.png b/public/console/03-signal-run-gateway.png new file mode 100644 index 0000000..2287928 Binary files /dev/null and b/public/console/03-signal-run-gateway.png differ diff --git a/public/console/04-signal-peer-client.png b/public/console/04-signal-peer-client.png new file mode 100644 index 0000000..90683ff Binary files /dev/null and b/public/console/04-signal-peer-client.png differ diff --git a/public/console/05-signal-verify.png b/public/console/05-signal-verify.png new file mode 100644 index 0000000..64524cb Binary files /dev/null and b/public/console/05-signal-verify.png differ diff --git a/public/console/06-enrollment-keys.png b/public/console/06-enrollment-keys.png new file mode 100644 index 0000000..8b89ebf Binary files /dev/null and b/public/console/06-enrollment-keys.png differ diff --git a/public/console/07-manage-validators.png b/public/console/07-manage-validators.png new file mode 100644 index 0000000..2b3061d Binary files /dev/null and b/public/console/07-manage-validators.png differ diff --git a/public/console/08-accelerate-before-you-start.png b/public/console/08-accelerate-before-you-start.png new file mode 100644 index 0000000..2e76822 Binary files /dev/null and b/public/console/08-accelerate-before-you-start.png differ diff --git a/public/console/09-accelerate-adjust.png b/public/console/09-accelerate-adjust.png new file mode 100644 index 0000000..b24d3bd Binary files /dev/null and b/public/console/09-accelerate-adjust.png differ diff --git a/public/console/10-proposal-report.png b/public/console/10-proposal-report.png new file mode 100644 index 0000000..3f812d9 Binary files /dev/null and b/public/console/10-proposal-report.png differ diff --git a/signal/connect-your-gateway.md b/signal/connect-your-gateway.md new file mode 100644 index 0000000..4e91d35 --- /dev/null +++ b/signal/connect-your-gateway.md @@ -0,0 +1,157 @@ +--- +title: Connect your gateway +description: The production command Console shows, and how each consensus client is wired. +--- + +# Connect your gateway + +This page covers **Run a gateway** and **Peer your client** on Signal, and the same commands in the signup step **Connect your first gateway**. + +Copy the command from Console. If you just created the key, it is already in the command. Otherwise the command reads `$OPT_JOIN_KEY`, so export the key first. The command also carries the cluster id the key was minted for. The block below is the production shape, so you can read it. If Console shows a different `OPT_GATEWAY_CLUSTER_ID`, use that one. A mismatch authenticates and then fails every mesh handshake. + +The image Console hands out for production is `v1.3.2`. `-config ""` is required. The flag defaults to `config/app_conf.yml`, which is not in the image, and the process exits before it reads any environment variable. + +Do not add `OPT_CHAIN_ID`. This release does not read it. The chain comes from the enrollment key. + +Set `OPT_REMOTE_BOOTSTRAP_URL` whenever you set `OPT_REMOTE_AUTH_URL`. The bootstrap URL otherwise defaults to production, so an auth URL pointed at another environment enrols in one place and peers in another. + +Both telemetry variables are required. `OPT_ENABLE_TELEMETRY` without `OPT_REMOTE_PUSH_ENABLE` builds a local registry and does not push. `OPT_REMOTE_PUSH_ENABLE` without telemetry is refused at startup. `/health` answers either way, but two of its checks stay empty until telemetry is enabled. + +## Validator gateway + +```bash +mkdir -p "$HOME/optimum-gateway/libp2p" "$HOME/optimum-gateway/mump2p" && \ +docker run -d --name optimum-gateway \ + -p 33212:33212/tcp \ + -p 33213:33213/tcp \ + -p 127.0.0.1:48123:48123/tcp \ + -e OPT_JOIN_KEY="$OPT_JOIN_KEY" \ + -e OPT_REMOTE_AUTH_URL=https://auth.getoptimum.io \ + -e OPT_REMOTE_BOOTSTRAP_URL=https://bootstrap.getoptimum.io \ + -e OPT_GATEWAY_CLUSTER_ID=optimum_ethereum_mainnet_v0_1 \ + -e OPT_GATEWAY_ID=$(hostname) \ + -e OPT_ENABLE_TELEMETRY=true \ + -e OPT_REMOTE_PUSH_ENABLE=true \ + -v "$HOME/optimum-gateway/libp2p":/tmp/libp2p \ + -v "$HOME/optimum-gateway/mump2p":/tmp/mump2p \ + docker.io/getoptimum/gateway:v1.3.2 -config "" +``` + +On an SELinux host, add `:z` after each container path. That is what Console’s SELinux option does. `:z` is shared, so a second gateway on the same host can use its own subdirectory under the same parent. + +```bash +-v "$HOME/optimum-gateway/libp2p":/tmp/libp2p:z \ +-v "$HOME/optimum-gateway/mump2p":/tmp/mump2p:z \ +``` + +## Stream-only + +No beacon node, so `33212` is not published. `OPT_STREAM_ONLY` requires `OPT_STREAM_ENABLE`; the gateway will not start with only one of them. + +```bash +mkdir -p "$HOME/optimum-gateway/libp2p" "$HOME/optimum-gateway/mump2p" && \ +docker run -d --name optimum-gateway \ + -p 33213:33213/tcp \ + -p 127.0.0.1:48123:48123/tcp \ + -p 127.0.0.1:9600:9600/tcp \ + -p 127.0.0.1:9601:9601/tcp \ + -e OPT_JOIN_KEY="$OPT_JOIN_KEY" \ + -e OPT_REMOTE_AUTH_URL=https://auth.getoptimum.io \ + -e OPT_REMOTE_BOOTSTRAP_URL=https://bootstrap.getoptimum.io \ + -e OPT_GATEWAY_CLUSTER_ID=optimum_ethereum_mainnet_v0_1 \ + -e OPT_GATEWAY_ID=$(hostname) \ + -e OPT_ENABLE_TELEMETRY=true \ + -e OPT_REMOTE_PUSH_ENABLE=true \ + -e OPT_STREAM_ENABLE=true \ + -e OPT_STREAM_ONLY=true \ + -e OPT_STREAM_ADDR=0.0.0.0:9600 \ + -e OPT_STREAM_GRPC_ADDR=0.0.0.0:9601 \ + -v "$HOME/optimum-gateway/libp2p":/tmp/libp2p \ + -v "$HOME/optimum-gateway/mump2p":/tmp/mump2p \ + docker.io/getoptimum/gateway:v1.3.2 -config "" +``` + +Changing any `-e` means replacing the container, not restarting it. A restart keeps the old environment. Re-running without removing it fails because the name is taken. + +```bash +docker rm -f optimum-gateway +``` + +Then run the command again. The identity volumes are what keep the peer id. + +## Check it is healthy + +On the gateway host: + +```bash +curl http://localhost:48123/health +``` + +A healthy gateway answers `200` with `"status": "healthy"`. Anything else answers `503`, with `"status": "degraded"` and a `failing` list. + +For a stream-only gateway, give it a moment: the mesh checks do not pass until the first block arrives. `cl_peers`, `cl_health`, and `subscribed_topics` are skipped, not failed, so having no consensus client does not by itself make this degraded. + +If you run validators, expect `503` until the client is peered. The mesh checks clear once the first block arrives. `cl_peers`, `cl_health`, and `subscribed_topics` stay failing until the client step below is done. That `503` is the check working. + +## Connect your validators + +Pick the client in Console. Four clients dial the gateway. Lighthouse is wired the other way: the gateway dials the node. + +![Signal, Peer your client. Prysm, Lighthouse, Teku, Nimbus, and Lodestar are marked.](/console/04-signal-peer-client.png) + +### Prysm, Teku, Nimbus, Lodestar + +On the gateway host: + +```bash +curl -s http://localhost:48123/api/v1/self_info +``` + +Take `peer_id` from the reply. Build the address yourself: + +```text +/ip4//tcp/33212/p2p/ +``` + +`` is an address your consensus client can reach this machine on. Do not take the first entry of `libp2p.multiaddrs`. That list mixes the container’s private addresses, which change when the container is recreated, with the host’s public address. The first entry is often a container address your client cannot use. + +Add this on the beacon node. `` is that reachable host, and `` is `peer_id`. + +| Client | Flag | Also | +| --- | --- | --- | +| Prysm | `--peer=/ip4//tcp/33212/p2p/` | Prysm v7.1.8 or later. Do not set `OPT_DIRECT_CL_PEERS`. Prysm re-dials on its own. There is no `--p2p-static-peers`. | +| Teku | `--p2p-direct-peers=/ip4//tcp/33212/p2p/` | Set `--p2p-static-peers` to the same address. Static alone gets pruned. Teku v26.6.0 or later (minimum v26.4.0). | +| Nimbus | `--direct-peer=/ip4//tcp/33212/p2p/` | Use a stable `--netkey-file`, not a random key. Nimbus requires one for a direct peer. | +| Lodestar | `--directPeers=/ip4//tcp/33212/p2p/` | Not `--bootnodes`. That is discovery. `--directPeers` is the mesh peer that is kept. | + +Teku, Nimbus, and Lodestar also need the gateway to be told about the node, or the link does not come back after the gateway restarts. The peering itself forms without that variable: the gateway marks a client that connects as a direct peer. It does not remember that peer across its own restart, and these clients may not re-dial. Add this to the start command, then replace the container: + +```bash +-e OPT_DIRECT_CL_PEERS=/ip4//tcp//p2p/ +``` + +Use an address the gateway can reach. `127.0.0.1` from inside the container is the container. + +::: warning +Once `OPT_DIRECT_CL_PEERS` is set, port `33212` is an allowlist. Any consensus client that is not named is disconnected. Name every client that should reach this gateway. +::: + +### Lighthouse + +Lighthouse has no single flag for this. Wire it on the gateway. The lookup runs on the Lighthouse host, and Lighthouse does not enable HTTP unless you pass `--http`: + +```bash +curl -s http://localhost:5052/eth/v1/node/identity +``` + +Read `data.p2p_addresses`. Pick an address the gateway can reach, not the first entry. The first is often `127.0.0.1`. + +```bash +-e OPT_DIRECT_CL_PEERS=/ip4//tcp//p2p/ +``` + +Add that to the start command and replace the container. For Lighthouse this variable is the connection, not only the restart case: nothing on the node points at the gateway, so the gateway is the side that dials. The allowlist warning above applies. + +Lighthouse v8 needs extra PeerDAS flags. Those are in the [gateway quick start](https://getoptimum.github.io/optimum-gateway/versions/latest/quick-start), not on this page. + +`--libp2p-addresses` is deprecated in favour of `--boot-nodes`, and `--trusted-peers` takes a peer id. Console does not use that pair. Use `OPT_DIRECT_CL_PEERS` as above. diff --git a/signal/network.md b/signal/network.md new file mode 100644 index 0000000..749d27b --- /dev/null +++ b/signal/network.md @@ -0,0 +1,24 @@ +--- +title: Network +description: The ports Console publishes, and where the rest of the requirements live. +--- + +# Network + +Console publishes three ports. The full host requirements, including outbound access, are in the [gateway network requirements](https://getoptimum.github.io/optimum-gateway/versions/latest/network-requirements). + +| Port | Published | What it is | +| --- | --- | --- | +| `33212/tcp` | All interfaces, validator gateways only | What the consensus client dials. Not published for a stream-only gateway: that process does not listen on it. | +| `33213/tcp` | All interfaces | The mesh. | +| `48123/tcp` | `127.0.0.1` only | `/health`, `/metrics`, and `/api/v1/self_info`. | + +`/health` from any machine other than the gateway host is refused. That is the bind, not a failed gateway. + +Stream-only also publishes the consumer feed to loopback on the gateway host: WebSocket `9600` and gRPC `9601`. Inside the container those listeners bind `0.0.0.0` so the published ports can reach them. They are not published on the host’s other interfaces. A consumer token is required; `stream_require_auth` defaults on. + +Outbound, the gateway needs to reach Console’s auth and bootstrap endpoints (`auth.getoptimum.io` and `bootstrap.getoptimum.io` on the production command) and the mesh peers. Use the gateway network page for the firewall list rather than opening ports this page does not name. + +::: warning +Leave `48123` on loopback. It answers with this gateway’s peer id and multiaddrs. +::: diff --git a/signal/onboard-in-bulk.md b/signal/onboard-in-bulk.md new file mode 100644 index 0000000..05b70d3 --- /dev/null +++ b/signal/onboard-in-bulk.md @@ -0,0 +1,38 @@ +--- +title: Onboard in bulk +description: Many gateways from one enrollment key, and many validators at once. +--- + +# Onboard in bulk + +## Many gateways + +You do not need one key per host. One enrollment key enrols the whole fleet. See [Why enrollment keys](/signal/what-signal-does#why-enrollment-keys). + +1. Mint a key that outlasts the rollout: **Keys** → **Enrollment keys** (**Manage gateways** on an invited account) → **Generate enrollment key**. Set **Valid for (days)** to cover the time until the last host is started. The secret is shown once. Store it where your deployment tooling reads secrets. +2. Copy the start command from Signal. It reads the key from `$OPT_JOIN_KEY` unless you had Console put a key in it. +3. On each host, export `OPT_JOIN_KEY` and run that same command. +4. Peer each gateway with the beacon node beside it. Every gateway has its own peer id. [Connect your gateway](/signal/connect-your-gateway). +5. Open Signal and **Run check**. Verify covers every gateway in your organisation together: **Gateway enrolled** shows how many, such as **Yes, 3**. It does not name them, so check each new host with `curl http://localhost:48123/health` on that host. + +Hostnames must differ. The command sets `OPT_GATEWAY_ID=$(hostname)`, and a second gateway under a hostname that is already enrolled is refused with HTTP 409. Hosts built from one image often share a hostname, so set it per host first. + +Keep each host's `$HOME/optimum-gateway` directories. A gateway that keeps them re-uses its credential and spends nothing on restart. One that loses them enrols again, spends another of the key's enrollments, and is refused under the same hostname until the old credential is revoked. + +On Kubernetes, store the key in a Secret, inject it as `OPT_JOIN_KEY`, and give each pod a unique `OPT_GATEWAY_ID`, such as the pod name. Keep the identity PVC: an `emptyDir` is lost whenever the pod is replaced, and every replacement enrols again. The chart's own values still describe the older API key path. See [Fleet enrollment (join key)](https://getoptimum.github.io/optimum-gateway/versions/latest/kubernetes#fleet-enrollment-join-key) in the gateway Helm guide. + +## Many validators + +Validator indices are how Console knows which slots you propose. Three ways to submit them in bulk: + +| Where | How | Who has it | +| --- | --- | --- | +| Signup, **Register keys** | **Paste indices** or **Upload CSV**: decimal indices, one per line or comma separated. Optimum confirms them before they count. | Every account that answered yes to **Do you run validators?** | +| **Activate validators** → **Manage validators** | **Add**, **Remove**, or **Replace** your set. **Paste** or **Upload CSV**. A line is an index, an index and its BLS key, or a BLS key. **Replace** shows the net change before it applies. | Invited operator accounts, when the screen is enabled. | +| **Keep your validators in sync automatically**, on **Activate validators** | Generate an operator API key under **Manage API keys**, then run [optimum-keysync](https://github.com/getoptimum/optimum-keysync) on a schedule. It reconciles your set against `POST /api/v1/validator-keys/batch` every run. | Invited operator accounts. | + +![Manage validators. Add, Remove, Replace, Paste, and Upload CSV are marked.](/console/07-manage-validators.png) + +Console never lists your indices back to you. **Activate validators** shows counts and a history of changes only. + +Self-serve accounts add indices after signup by returning from the signup link or asking [support](/help/support). See [Register keys](/signal/register-keys). diff --git a/signal/register-keys.md b/signal/register-keys.md new file mode 100644 index 0000000..d58fd76 --- /dev/null +++ b/signal/register-keys.md @@ -0,0 +1,30 @@ +--- +title: Register keys +description: How validator indices are submitted, and what Console does with them before they count. +--- + +# Register keys + +The screen is **Validator indices to connect**. The signup rail calls the step **Register keys**. + +Indices are how Console knows which slots you proposed. They are confirmed by Optimum before they appear in a report. Submitting them does not make them active. + +Paste decimal validator indices, or upload a CSV (one per line, or comma separated). + +| Result | What it means | +| --- | --- | +| Indices submitted | Accepted into the queue. | +| Stake once confirmed | `submitted × 32` ETH. That is the protocol’s stake per index, not a balance Console looked up. | +| Could not be read as an index | BLS public keys and anything that is not a decimal index were skipped. Contact support if you only have keys. | +| Already claimed | Not submitted. Contact support if they are yours. | +| Not found on the beacon node | Check the indices and submit again. | +| Were not submitted | This account has reached its limit for validator lookups. Contact support to register the rest. A retry does not raise the limit. | +| Could not be checked just now | The beacon node did not answer. Nothing is wrong with those indices. Submit them again in a few minutes. | + +**Skip for now** writes nothing. You can return from the signup link. + +After a successful submit, the note on the screen is: submitted, and confirmed before they appear in any report. + +To add more later, come back from the signup link or ask support. Invited operator accounts can also use **Activate validators** when it is enabled, including an importer that keeps the set in sync. See [Onboard in bulk](/signal/onboard-in-bulk). **Keys** and **Manage gateways** hold gateway keys, not validator indices. + +Accelerate counts only indices that are active on chain. An index still in the activation queue is on record and proposes nothing yet. See [Readiness](/accelerate/readiness). diff --git a/signal/what-signal-does.md b/signal/what-signal-does.md new file mode 100644 index 0000000..b3306a7 --- /dev/null +++ b/signal/what-signal-does.md @@ -0,0 +1,58 @@ +--- +title: What Signal does +description: Signal puts a gateway beside your beacon node so your validators receive blocks sooner. +--- + +# What Signal does + +Signal is the gateway beside your beacon node. It receives blocks from the Optimum mesh and hands them to your consensus client, so your validators receive blocks sooner. That is what improves attestation performance. + +You set it up in one of two places. + +* **During signup.** The step is **Connect your first gateway**. It creates an enrollment key, shows the start command, the health check, and, if you run validators, the client flag. If you answered no to **Do you run validators?**, the command is the stream-only one. Console watches for the gateway and shows **Gateway connected** once it enrols. You can leave it with **I’ll do this later**. +* **Signal in the Console sidebar.** Use this after signup, and for every gateway after the first. It has three steps. + +| Step | On the screen | What you do | +| --- | --- | --- | +| Run a gateway | One command | Start the container beside your beacon node. | +| Peer your client | One setting | Point your consensus client at the gateway, or, for Lighthouse, the gateway at the client. | +| Verify | Check it took | Console confirms the gateway enrolled, reported in, and is sending blocks to the mesh. | + +![Signal, Run a gateway. The one-day enrollment key and the SELinux switch are marked.](/console/03-signal-run-gateway.png) + +Copy the command from this screen. It already carries the hosts for the environment you are signed into. Turn on the SELinux switch before you copy it when the host enforces SELinux. + +An account that does not run validators skips **Peer your client**. The command on Signal is still the beacon-node one, so for another stream-only gateway use the [stream-only command](/signal/connect-your-gateway#stream-only). + +**Verify** is the check to trust. It reads what Optimum sees from outside your host. The `curl /health` command beside the start command answers one thing Verify cannot: whether your consensus client is peered. Its first word is often `degraded` until that is done. See [When the check fails](/signal/when-the-check-fails). + +The pill beside the **Signal** title shows the last check: **Not checked**, **Checking**, **Connected**, **Not connected**, **Unknown**, or **Check failed**. + +## Why enrollment keys + +A gateway does not need a secret of its own handed to it. You give every host the same enrollment key (`OPT_JOIN_KEY`, `ojk_…`). On first start, each gateway creates its own keypair, enrols with Optimum, and keeps the credential it gets back in `$HOME/optimum-gateway/mump2p`. From then on it uses that credential, not the enrollment key. + +That is what makes a fleet manageable: + +* **One key for many hosts.** Run the same command on every host. Each enrolls under its own hostname (`OPT_GATEWAY_ID`), so hostnames must differ. A repeat is refused with HTTP 409. +* **Nothing to rotate on the hosts.** The key only lets new gateways in. When it expires or you revoke it, gateways that already enrolled keep running. +* **A short window if it leaks.** The key's lifetime is how long a copied command can still add gateways to your organisation. +* **The network and cluster come from the key.** A gateway cannot pick its own. + +Each key admits up to 1,000 gateways, and your organisation is capped at 1,000 live gateway credentials. A gateway that keeps its credential across restarts spends nothing. Losing the identity directory spends another enrollment. + +## Which key lifetime + +| Where you get it | Lasts | Use it for | +| --- | --- | --- | +| Signup, **Connect your first gateway** | 14 days | The first gateway, when the person signing up is not the person on the host. | +| Signal, **Create an enrollment key that lasts a day** | 1 day | A command you are about to paste. It goes straight into the command. | +| **Keys** → **Enrollment keys** (**Manage gateways** on an invited account), **Generate enrollment key** | You choose in **Valid for (days)**, up to 365 | A rollout across many hosts or over several weeks. | + +![Manage gateways, Enrollment keys. Generate enrollment key is marked.](/console/06-enrollment-keys.png) + +Every key is shown once. Export it as `OPT_JOIN_KEY` before running the command, unless Console already put it in. The key list shows **enrollments used** and the expiry date. + +Revoking an enrollment key stops new gateways only. To cut off one gateway that already enrolled, revoke that gateway's own key under **Manage gateways** → **Gateway**. Self-serve accounts do not have that tab; ask [support](/help/support). + +Next: [Network](/signal/network), then [Connect your gateway](/signal/connect-your-gateway). diff --git a/signal/when-the-check-fails.md b/signal/when-the-check-fails.md new file mode 100644 index 0000000..f3b6736 --- /dev/null +++ b/signal/when-the-check-fails.md @@ -0,0 +1,69 @@ +--- +title: When the check fails +description: What Verify reports, what it cannot see, and the four failures Console names. +--- + +# When the check fails + +## Verify + +**Verify the connection** on Signal runs by itself when you open the screen. It keeps checking while a gateway is enrolled but has not reported in. **Run check** runs it again. + +It reads three things from outside your host, across every gateway in your organisation. A row passes if any of them passes it. **Gateway enrolled** reads **Yes**, or **Yes, 3** for three gateways. **Blocks arriving** reads, for example, **4 of 5 slots**. + +![Verify the connection. Run check is marked, and the three rows read Yes, 9, Not seen, and Nothing to check.](/console/05-signal-verify.png) + +Verify is the check to trust for whether a gateway reached Optimum. Use `/health` on the host for the one thing Verify cannot see. + +| Row | Passes when | If it fails | +| --- | --- | --- | +| Gateway enrolled | A gateway has connected to Optimum for this account. | No gateway has connected yet. Mint an enrollment key, then run the command from **Run a gateway**. | +| Seen by Optimum | The gateway reported in within the last ten minutes. | It has a credential but has not reported in. Check that the container is running and outbound `443` is open. | +| Blocks arriving | Its blocks reached the mesh in recent slots. | It reports in, but its blocks are not reaching the mesh. Check that inbound `33212` and `33213` are open to it. | + +**Could not check** means a lookup did not answer. That does not mean the gateway is down. Run the check again. If a gateway is not recorded against a cluster and stays that way, contact support. + +::: info Whether your client is peered, only you can see +Optimum cannot see whether your consensus client peered with the gateway. On the gateway host, run `curl http://localhost:48123/health` and read `cl_peers`. +::: + +A `503` from `/health` right after start, with `cl_peers` failing, is expected until the client is peered. Read [Connect your gateway](/signal/connect-your-gateway) before treating that as a fault. The four cases below stay broken until you fix them. Console lists them under **What the check will tell you**. + +## Gateway not reachable + +Nothing is listening on `33212` (your client) or `33213` (the mesh). + +```bash +docker ps +curl http://localhost:48123/health +``` + +Run the curl on the gateway host. From anywhere else, `48123` is refused even when the gateway is fine. + +A stream-only gateway does not listen on `33212`. That is not this failure. + +## Your client is not peering + +The gateway is up and has mesh peers, and `cl_peers` is `0` in `/health`. + +The client flag is missing or points somewhere else. Check it against the address you built from `/api/v1/self_info`. If it peered once and then stopped, the gateway restarted without `OPT_DIRECT_CL_PEERS`, so it has nothing to re-dial from. Prysm is the client that re-dials without that variable. The others need it. Lighthouse needs it to connect at all. + +## The container exits on a permission error + +The log ends on `write identity data: permission denied` after loading JWKS. That reads like a rejected key. It is the identity mounts. + +Where SELinux is enforcing (Fedora, RHEL, Rocky, Alma, and derivatives), the container cannot write those directories until they are relabeled. Turn on **Add an SELinux relabel to the identity mounts** beside the start command in Console, and run the new command. The mounts gain a `:z` suffix. + +## The peer id changed + +The gateway generated a new identity because `$HOME/optimum-gateway/libp2p` and `mump2p` were not mounted. The address you gave the client no longer exists. + +Read `/api/v1/self_info` again, update the client, and keep the two volume mounts in the command so the next restart keeps the same peer id. + +## Replacing the container + +```bash +docker rm -f optimum-gateway +``` + +Then run the Console command again. Restarting reuses the old environment. Running a second `docker run` with the same name fails before it replaces anything. diff --git a/signal/your-first-report.md b/signal/your-first-report.md new file mode 100644 index 0000000..bd1377c --- /dev/null +++ b/signal/your-first-report.md @@ -0,0 +1,21 @@ +--- +title: Your first report +description: What each report waits for, and where it appears. +--- + +# Your first report + +Reports appear under **Performance** in the Console sidebar. Each entry appears only when it is enabled for your account. + +| Entry | What it shows | What it waits for | +| --- | --- | --- | +| Gateways | Your gateways as Optimum measures them. | A running gateway. No validator indices needed. | +| Network | Propagation against libp2p for your validators. | 500 or more confirmed validator indices. Per-operator figures show `n/a` until at least 30 paired slots are in the window. | +| Attestations | Attestation outcomes. | Confirmed validator indices. Self-serve accounts do not have this entry. | +| MumBoost | The Accelerate proposal report: proposal performance and MEV capture. MumBoost is the older name still on this entry. See [Where results show](/accelerate/where-results-show). | Proposed slots from active validators. | + +**Gateways** is in the main sidebar group, not under **Performance**. + +Submitted indices are not confirmed indices. Optimum confirms them first. Until then, **Network** and **Attestations** are empty on purpose. A newly onboarded partner sees the same. + +Accelerate waits on proposed slots, not on the 500-index line. See [Readiness](/accelerate/readiness). diff --git a/start/before-you-begin.md b/start/before-you-begin.md new file mode 100644 index 0000000..88f6c3c --- /dev/null +++ b/start/before-you-begin.md @@ -0,0 +1,21 @@ +--- +title: Before you begin +description: What has to be true on the host before you paste the Console command. +--- + +# Before you begin + +Have these before you create the enrollment key. The secret is shown once. + +* A host with Docker, beside the beacon node. Stream-only can be any host you control. +* The ports in [Network](/signal/network) open as listed. Telemetry stays on loopback. +* A Console account. [Create one](/getting-in/create-an-account), or sign in if Optimum invited you. +* Persistent directories for the gateway identity: `$HOME/optimum-gateway/libp2p` and `$HOME/optimum-gateway/mump2p`. The container defaults are `/tmp/libp2p` and `/tmp/mump2p`, which do not survive a restart. A new identity means the peer id your client was given no longer exists. + +::: warning +Do not start the container with `--network host`. That publishes telemetry, including the peer id and multiaddrs, on every interface. Console publishes `48123` to `127.0.0.1` only. +::: + +On Fedora, RHEL, Rocky, and Alma, SELinux is enforcing by default. The identity mounts then fail with `write identity data: permission denied` after the log has already loaded JWKS, which looks like a rejected key. Console has **Add an SELinux relabel to the identity mounts** above the start command. Turn it on before you copy the command. See [When the check fails](/signal/when-the-check-fails). + +One enrollment key covers every gateway you run. Each host enrols under its hostname (`OPT_GATEWAY_ID`). Two hosts that share a hostname: the second enrolment is refused with HTTP 409. For many hosts, see [Onboard in bulk](/signal/onboard-in-bulk). diff --git a/start/choose-a-path.md b/start/choose-a-path.md new file mode 100644 index 0000000..71cdfc0 --- /dev/null +++ b/start/choose-a-path.md @@ -0,0 +1,34 @@ +--- +title: Choose a path +description: Validators or stream-only, individual or entity, and distributed validators. +--- + +# Choose a path + +Two answers during registration decide what you see. **How do you take part?** is Individual or Entity. **Do you run validators?** is Yes or No. + +Optimum does not host gateways. Every path below is a container you run on your own host. + +## You run validators + +The gateway runs beside the beacon node. You peer the consensus client, then register validator indices. Signal is the sidebar entry for that. + +Accelerate is a later step, for entity accounts only. It needs active validators and enough proposed slots to measure. It is not part of connecting the gateway. See [Account type](/getting-in/account-type). + +## You do not run validators + +This is a supported account. The gateway takes blocks from the mesh and serves them to your own consumers. It does not peer a beacon node, and Console does not ask for validator indices. + +The signup step gives you the stream-only command. The command on **Signal** is the one for a gateway beside a beacon node. If you start a second stream-only gateway from Signal, use the [stream-only command](/signal/connect-your-gateway#stream-only) instead. Otherwise `/health` reports the consensus-client checks as failing. + +The container is started with `OPT_STREAM_ENABLE` and `OPT_STREAM_ONLY`. The libp2p port is not published. The feed, once healthy, is on the gateway host at `ws://127.0.0.1:9600` and gRPC `127.0.0.1:9601`. Both want a consumer token, minted under **Keys** → **Stream consumers** (invited operator accounts see that screen as **Manage gateways**). + +## Obol and other distributed validator setups + +The gateway still sits beside the beacon node those validators use. Charon and the validator client do not change. + +For an Obol Charon Distributed Validator Node (CDVN), use the [Optimum Gateway overlay for Obol CDVN](https://getoptimum.github.io/optimum-hop/integration/obol/). It adds the gateway as an opt-in Docker Compose overlay on the `dvnode` network, dials the beacon node from the gateway side, and turns off by removing the overlay from `COMPOSE_FILE`. + +::: warning +The overlay was written before Console enrolment. It uses an API key (`OPT_API_KEY=ogw_live_...`), pins `GATEWAY_VERSION=v1.1.1`, writes a mounted `app_conf.yml`, and its sample targets Hoodi. Console hands out an enrollment key (`OPT_JOIN_KEY`) and `v1.3.2`, run with `-config ""`. Ask [support](/help/support) which credential and version to use in the overlay before you mix the two. +::: diff --git a/start/what-optimum-does.md b/start/what-optimum-does.md new file mode 100644 index 0000000..36efcdf --- /dev/null +++ b/start/what-optimum-does.md @@ -0,0 +1,16 @@ +--- +title: What Optimum does +description: The gateway, Signal, and Accelerate, in the words Console uses. +--- + +# What Optimum does + +You run one container, the Optimum gateway, on a host that can reach your beacon node. The gateway enrols with an enrollment key from Console, joins the mesh, and your consensus client peers it. That peering is **Signal**. + +**Accelerate** is separate. It reads slots your validators already proposed and recommends a MEV-Boost bid cutoff. Console does not change your infrastructure. You download a config and apply it yourself. + +Both live in [Console](https://console.getoptimum.io/). This site is the runbook. Versioned gateway reference (install details, every setting, metrics) stays at [getoptimum.github.io/optimum-gateway](https://getoptimum.github.io/optimum-gateway/versions/latest/). + +::: info +There is no Optimum-hosted multiaddr to point a client at. The client peers the gateway you started beside it. The peer id comes from that gateway. +::: diff --git a/vercel.json b/vercel.json index 5c52a86..bb0949d 100644 --- a/vercel.json +++ b/vercel.json @@ -1,5 +1,25 @@ { + "ignoreCommand": "[ \"$VERCEL_ENV\" != production ]", "cleanUrls": true, + "redirects": [ + { "source": "/docs/guides", "destination": "/start/what-optimum-does", "permanent": true }, + { "source": "/docs/guides/:path*", "destination": "/start/what-optimum-does", "permanent": true }, + { "source": "/docs/how-to-guides", "destination": "/start/what-optimum-does", "permanent": true }, + { "source": "/docs/how-to-guides/:path*", "destination": "/start/what-optimum-does", "permanent": true }, + { "source": "/docs/learn/opt", "destination": "/start/what-optimum-does", "permanent": true }, + { "source": "/docs/learn/how-to-stake-mum", "destination": "/start/what-optimum-does", "permanent": true }, + { "source": "/docs/learn/overview/intro", "destination": "/", "permanent": true }, + { "source": "/docs/learn/overview/deram", "destination": "/start/what-optimum-does", "permanent": true }, + { "source": "/docs/learn/p2p/intro", "destination": "/docs/learn/overview/p2p", "permanent": true }, + { "source": "/docs/aws_deploy_devnet", "destination": "/start/what-optimum-does", "permanent": true }, + { "source": "/docs/aws_devnet", "destination": "/start/what-optimum-does", "permanent": true }, + { "source": "/docs/linode_devnet", "destination": "/start/what-optimum-does", "permanent": true }, + { "source": "/docs/resources/news", "destination": "/start/what-optimum-does", "permanent": true }, + { "source": "/docs/resources/optimum", "destination": "/start/what-optimum-does", "permanent": true }, + { "source": "/docs/index", "destination": "/", "permanent": true }, + { "source": "/reference", "destination": "https://getoptimum.github.io/optimum-gateway/versions/latest/", "permanent": true }, + { "source": "/getting-in/region", "destination": "/help/faq", "permanent": true } + ], "builds": [ { "src": "package.json", diff --git a/wrangler.jsonc b/wrangler.jsonc new file mode 100644 index 0000000..62da614 --- /dev/null +++ b/wrangler.jsonc @@ -0,0 +1,13 @@ +{ + "$schema": "node_modules/wrangler/config-schema.json", + // Must match the Worker connected to this repo. Workers Builds rejects a mismatch. + "name": "docs", + "compatibility_date": "2026-09-30", + // Version URLs are public. Vercel previews sit behind team login, so this is the link to share. + "preview_urls": true, + "assets": { + "directory": "./.vitepress/dist", + "html_handling": "auto-trailing-slash", + "not_found_handling": "404-page" + } +} diff --git a/yarn.lock b/yarn.lock index 129ba11..3c4870a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -177,6 +177,48 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.27.1" +"@cloudflare/kv-asset-handler@0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.5.0.tgz#d448d971aca78c04c39432a862298fb77f295527" + integrity sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg== + +"@cloudflare/unenv-preset@2.16.2": + version "2.16.2" + resolved "https://registry.yarnpkg.com/@cloudflare/unenv-preset/-/unenv-preset-2.16.2.tgz#73444ac5a3e6c78cd498477d8b013dd026b6ecea" + integrity sha512-JBP1+Z7ZSNG/d4mRP+y8VC5dka3tZVMLEZRvS+rzQ4DGV1EoxRFQckcJTTkXbHSQiTj0DtNI01Zwb/V2fX0mvQ== + +"@cloudflare/workerd-darwin-64@1.20260926.1": + version "1.20260926.1" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260926.1.tgz#652cd32ba3186b8136bb5ddeca2546358525efca" + integrity sha512-VCIpwgJu5Dm1o+VHLclNOKIdpttEqss7oDHS5DYxgVoonM9Dxxxr1xCQvJbh6IXFuQ1DDrbm5krjte5NsTgX3Q== + +"@cloudflare/workerd-darwin-arm64@1.20260926.1": + version "1.20260926.1" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260926.1.tgz#c816d663e330b4270a4e1fb11160072bd942171b" + integrity sha512-oVuLXfCnr1Xu9sBMNYrEPcFZQNMcviNcacz9l+oqQiLHc5UrVp++lpKbsuWstCfh+/c39Pp37TVeaNBLA8+ReA== + +"@cloudflare/workerd-linux-64@1.20260926.1": + version "1.20260926.1" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260926.1.tgz#31435880b95995a01cab79ad8f8557c5244310b2" + integrity sha512-BjmiDvYBVBG5248gCHSZS3yONbcm3/3qKTu9RaQA8o7jQHJfXx9JnWbhkld2KsbXnRGEGHFwpLLidIpIGtQYUA== + +"@cloudflare/workerd-linux-arm64@1.20260926.1": + version "1.20260926.1" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260926.1.tgz#a58cb1a44c50906482d02392451b627ec4e9c639" + integrity sha512-28bdfQDIFcpaKXMPisADy8BchpIsX+tEAhD+bhfEBXukFGFr8F3ouyiG3HzN3CqAh/OYvifJizzFZtptUPCy7w== + +"@cloudflare/workerd-windows-64@1.20260926.1": + version "1.20260926.1" + resolved "https://registry.yarnpkg.com/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260926.1.tgz#2b1c060c072ec93c84ba9d3fe39d42b89a336bf5" + integrity sha512-ehdL3ataKdEmlnW9oom6OZUR8n3XsTL/zl8+KGREpLi5sMSW0mek0PrF4wK9SX51f3Alnlu8tF8eKBg+mc3xFw== + +"@cspotcode/source-map-support@0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + "@docsearch/css@3.8.2": version "3.8.2" resolved "https://registry.npmjs.org/@docsearch/css/-/css-3.8.2.tgz" @@ -200,121 +242,258 @@ "@docsearch/css" "3.8.2" algoliasearch "^5.14.2" +"@emnapi/runtime@^1.11.3": + version "1.11.3" + resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.11.3.tgz#84257ae3b0531eb2aec1ffa23d70700da007ba95" + integrity sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA== + dependencies: + tslib "^2.4.0" + "@esbuild/aix-ppc64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz" integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== +"@esbuild/aix-ppc64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz#7a01a8d2ec2fbb2dac78adad09b0fa781e4082be" + integrity sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ== + "@esbuild/android-arm64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz" integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== +"@esbuild/android-arm64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz#b540a27d14e4afd058496a4dbec4d3f414db110a" + integrity sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg== + "@esbuild/android-arm@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz" integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== +"@esbuild/android-arm@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.28.1.tgz#704bd297de6d762de54eabbeafbf55f6756abe2f" + integrity sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ== + "@esbuild/android-x64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz" integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== +"@esbuild/android-x64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.28.1.tgz#d1cb166d34b0fbf0fe8ab460a5594f24a378701e" + integrity sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng== + "@esbuild/darwin-arm64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz" integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== +"@esbuild/darwin-arm64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz#1034b26457fc886368fe61bbd09f653f6afa8e54" + integrity sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q== + "@esbuild/darwin-x64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz" integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== +"@esbuild/darwin-x64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz#65556a432a1e4d72032d8218c1932fcca1a49772" + integrity sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ== + "@esbuild/freebsd-arm64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz" integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== +"@esbuild/freebsd-arm64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz#2e61e0592f9030d7e3dae18ee25ebc535918aef6" + integrity sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw== + "@esbuild/freebsd-x64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz" integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== +"@esbuild/freebsd-x64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz#c95ec289959ef8079c4dca817a1e2c4be66b9bd3" + integrity sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ== + "@esbuild/linux-arm64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz" integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== +"@esbuild/linux-arm64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz#40b22175dda06182f3ee8141186c5ff304c4a717" + integrity sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g== + "@esbuild/linux-arm@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz" integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== +"@esbuild/linux-arm@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz#c09a0f67917592ac0de892a9be4d3814debd2a6c" + integrity sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ== + "@esbuild/linux-ia32@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz" integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== +"@esbuild/linux-ia32@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz#a580f9c676797833891e519fc7a1337c8afd8db3" + integrity sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w== + "@esbuild/linux-loong64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz" integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== +"@esbuild/linux-loong64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz#46452cf321dc7f9e91c2fa780a56bb56e79cd68b" + integrity sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg== + "@esbuild/linux-mips64el@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz" integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== +"@esbuild/linux-mips64el@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz#4211b3184dd6608f53dcb22e39f5d34ee08852c8" + integrity sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ== + "@esbuild/linux-ppc64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz" integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== +"@esbuild/linux-ppc64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz#697857c2a61cb9b0b6bb6652e40c1dc5e1ca8e5d" + integrity sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ== + "@esbuild/linux-riscv64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz" integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== +"@esbuild/linux-riscv64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz#d192943eb146a40ac4c6497d0cf7be35b986bf08" + integrity sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ== + "@esbuild/linux-s390x@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz" integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== +"@esbuild/linux-s390x@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz#acea0356da0e0ebc08f97cf7b9c2e401e1e648dc" + integrity sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag== + "@esbuild/linux-x64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz" integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== +"@esbuild/linux-x64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz#6f0c3ce0cb64c534b70c4c45ecb2c16d34e35dfd" + integrity sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA== + +"@esbuild/netbsd-arm64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz#8bcd77077a0dce3378b574fedb26d2a253b73d36" + integrity sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw== + "@esbuild/netbsd-x64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz" integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== +"@esbuild/netbsd-x64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz#e7fb2a01e99c830c94e6623cd9fefb4c8fb58347" + integrity sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg== + +"@esbuild/openbsd-arm64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz#c52909372db8b86e2c55e05a8940033b5660a3b2" + integrity sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q== + "@esbuild/openbsd-x64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz" integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== +"@esbuild/openbsd-x64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz#c427b9be5a64c262ff9a7eb70b5fbbaadf446c6c" + integrity sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw== + +"@esbuild/openharmony-arm64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz#dc9b147baca2e6c4b3c85571741ef4860a489097" + integrity sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg== + "@esbuild/sunos-x64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz" integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== +"@esbuild/sunos-x64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz#ce866d12df13c15e4c99f073a3d466f6e0649b3a" + integrity sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ== + "@esbuild/win32-arm64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz" integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== +"@esbuild/win32-arm64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz#7468e3692d01d629d5941e5d83817bb80f9e39b4" + integrity sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA== + "@esbuild/win32-ia32@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz" integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== +"@esbuild/win32-ia32@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz#a5bc0063fb2bcab6d0ed63f2a1537958bc269ec6" + integrity sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg== + "@esbuild/win32-x64@0.21.5": version "0.21.5" resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz" integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== +"@esbuild/win32-x64@0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz#10064ee44f4347b90c9a02b446bbf80a91632b12" + integrity sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A== + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.1" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz" @@ -426,6 +605,167 @@ resolved "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz" integrity sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg== +"@img/colour@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@img/colour/-/colour-1.1.0.tgz#b0c2c2fa661adf75effd6b4964497cd80010bb9d" + integrity sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ== + +"@img/sharp-darwin-arm64@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz#bc10b262de2fc80088013f5f998298d1c8909fbf" + integrity sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA== + optionalDependencies: + "@img/sharp-libvips-darwin-arm64" "1.3.3" + +"@img/sharp-darwin-x64@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz#76c49ff04fb3f9d846b0d0575841b7ee59beec68" + integrity sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw== + optionalDependencies: + "@img/sharp-libvips-darwin-x64" "1.3.3" + +"@img/sharp-freebsd-wasm32@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz#ba55fd603c5d1d01a1cb14ffb4d970bc6ced80e1" + integrity sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA== + dependencies: + "@img/sharp-wasm32" "0.35.4" + +"@img/sharp-libvips-darwin-arm64@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz#08a6cf4fb4ee8d45f99404a569dcaa6b29391d97" + integrity sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg== + +"@img/sharp-libvips-darwin-x64@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz#1461e6fb310a869b3c13504589b8dd5c06624da8" + integrity sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw== + +"@img/sharp-libvips-linux-arm64@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz#cb938a3971b9a36329bc99427f1e5b72e266ba2e" + integrity sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A== + +"@img/sharp-libvips-linux-arm@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz#71032941b9fcbf8ebc3c1b62949927b844cbad62" + integrity sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA== + +"@img/sharp-libvips-linux-ppc64@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz#8246d2dec15234fd1cc54cc55dcba1aebc26c414" + integrity sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w== + +"@img/sharp-libvips-linux-riscv64@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz#59ff663c2aa6b418857357cd77ca4ccaece95876" + integrity sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ== + +"@img/sharp-libvips-linux-s390x@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz#bc17451f80d9f31663b3e906149f159a0ecb1ca8" + integrity sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q== + +"@img/sharp-libvips-linux-x64@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz#c7d1f83bc1cfe222cd9dc927f3c5137aa9791e76" + integrity sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA== + +"@img/sharp-libvips-linuxmusl-arm64@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz#303dfe2a8e6d1fd279ead559f4d2ccff2545e2a2" + integrity sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw== + +"@img/sharp-libvips-linuxmusl-x64@1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz#3750f70ad46ad87e4a08ee8d372ab9a7e17e2b6c" + integrity sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw== + +"@img/sharp-linux-arm64@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz#c2f53bf913fa1b46762b192c527a2b3647a211a8" + integrity sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ== + optionalDependencies: + "@img/sharp-libvips-linux-arm64" "1.3.3" + +"@img/sharp-linux-arm@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz#de8da0da2ee552267cae771597332a863378e43b" + integrity sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A== + optionalDependencies: + "@img/sharp-libvips-linux-arm" "1.3.3" + +"@img/sharp-linux-ppc64@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz#c40d7c5f8ce216c35224c58edcef8e6445935256" + integrity sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ== + optionalDependencies: + "@img/sharp-libvips-linux-ppc64" "1.3.3" + +"@img/sharp-linux-riscv64@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz#032ca206e713b1179efe0e18d525188c67277730" + integrity sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA== + optionalDependencies: + "@img/sharp-libvips-linux-riscv64" "1.3.3" + +"@img/sharp-linux-s390x@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz#19dac7501a15c8748bc7a11219fca391e424b6d7" + integrity sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ== + optionalDependencies: + "@img/sharp-libvips-linux-s390x" "1.3.3" + +"@img/sharp-linux-x64@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz#7d1d414d4a538e0704ba6b76ce6547e60f6211ce" + integrity sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA== + optionalDependencies: + "@img/sharp-libvips-linux-x64" "1.3.3" + +"@img/sharp-linuxmusl-arm64@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz#9534c93807822f4282d079a322facc6db53d50f6" + integrity sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-arm64" "1.3.3" + +"@img/sharp-linuxmusl-x64@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz#f488e7a0291991bff643cef82b5afd3cfd70fcf2" + integrity sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-x64" "1.3.3" + +"@img/sharp-wasm32@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz#81f71f3fc0d8447dc3af6cb378e24e758ff54225" + integrity sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA== + dependencies: + "@emnapi/runtime" "^1.11.3" + +"@img/sharp-webcontainers-wasm32@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz#77d2e8892d3a3825f0dc95ab02ceb613cb213286" + integrity sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA== + dependencies: + "@img/sharp-wasm32" "0.35.4" + +"@img/sharp-win32-arm64@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz#4101b44e3fb97d6f1a73c2a9c6142d491d1aa831" + integrity sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw== + +"@img/sharp-win32-ia32@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz#8d4755bd26d5ff34fb89c7907bd89c080a5dc9f5" + integrity sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw== + +"@img/sharp-win32-x64@0.35.4": + version "0.35.4" + resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz#0b67bd0b1f01123a982afcc6ba0dc00b877b8a0a" + integrity sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" @@ -438,11 +778,29 @@ wrap-ansi "^8.1.0" wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.6.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz#f4c663e862f06dc98ca4d453862c46902789a18d" + integrity sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw== + "@jridgewell/sourcemap-codec@^1.5.0": version "1.5.0" resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -469,6 +827,27 @@ resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@poppinss/colors@^4.1.5": + version "4.1.6" + resolved "https://registry.yarnpkg.com/@poppinss/colors/-/colors-4.1.6.tgz#bf8546e30cfc5ee8dfe68988ce58eb0ad9d7c21b" + integrity sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg== + dependencies: + kleur "^4.1.5" + +"@poppinss/dumper@^0.6.4": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@poppinss/dumper/-/dumper-0.6.5.tgz#8992703338d80d2218fdc37245c8cfc67f0f6ac9" + integrity sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw== + dependencies: + "@poppinss/colors" "^4.1.5" + "@sindresorhus/is" "^7.0.2" + supports-color "^10.0.0" + +"@poppinss/exception@^1.2.2": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@poppinss/exception/-/exception-1.2.3.tgz#b713855e6c9fe2110fea0949455c50828145e64a" + integrity sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw== + "@rollup/rollup-android-arm-eabi@4.35.0": version "4.35.0" resolved "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz" @@ -628,6 +1007,16 @@ resolved "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz" integrity sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg== +"@sindresorhus/is@^7.0.2": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-7.2.0.tgz#7c594e1a64336d2008d99d814056d459421504d4" + integrity sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw== + +"@speed-highlight/core@^1.2.7": + version "1.2.24" + resolved "https://registry.yarnpkg.com/@speed-highlight/core/-/core-1.2.24.tgz#e70acdec4f12420f6ec642ce987150622529bd67" + integrity sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw== + "@types/debug@^4.0.0": version "4.1.12" resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz" @@ -1026,6 +1415,11 @@ birpc@^0.2.19: resolved "https://registry.npmjs.org/birpc/-/birpc-0.2.19.tgz" integrity sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ== +blake3-wasm@2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/blake3-wasm/-/blake3-wasm-2.1.5.tgz#b22dbb84bc9419ed0159caa76af4b1b132e6ba52" + integrity sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g== + boolbase@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" @@ -1191,6 +1585,11 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +cookie@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-1.1.1.tgz#3bb9bdfc82369db9c2f69c93c9c3ceb310c88b3c" + integrity sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ== + copy-anything@^3.0.2: version "3.0.5" resolved "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz" @@ -1267,6 +1666,11 @@ dequal@^2.0.0: resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== +detect-libc@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad" + integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ== + devlop@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz" @@ -1351,6 +1755,43 @@ environment@^1.0.0: resolved "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz" integrity sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q== +error-stack-parser-es@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz#e6a1655dd12f39bb3a85bf4c7088187d78740327" + integrity sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA== + +esbuild@0.28.1: + version "0.28.1" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.28.1.tgz#ef45b4634c9c9d97a296aea4114a5f9840f95578" + integrity sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw== + optionalDependencies: + "@esbuild/aix-ppc64" "0.28.1" + "@esbuild/android-arm" "0.28.1" + "@esbuild/android-arm64" "0.28.1" + "@esbuild/android-x64" "0.28.1" + "@esbuild/darwin-arm64" "0.28.1" + "@esbuild/darwin-x64" "0.28.1" + "@esbuild/freebsd-arm64" "0.28.1" + "@esbuild/freebsd-x64" "0.28.1" + "@esbuild/linux-arm" "0.28.1" + "@esbuild/linux-arm64" "0.28.1" + "@esbuild/linux-ia32" "0.28.1" + "@esbuild/linux-loong64" "0.28.1" + "@esbuild/linux-mips64el" "0.28.1" + "@esbuild/linux-ppc64" "0.28.1" + "@esbuild/linux-riscv64" "0.28.1" + "@esbuild/linux-s390x" "0.28.1" + "@esbuild/linux-x64" "0.28.1" + "@esbuild/netbsd-arm64" "0.28.1" + "@esbuild/netbsd-x64" "0.28.1" + "@esbuild/openbsd-arm64" "0.28.1" + "@esbuild/openbsd-x64" "0.28.1" + "@esbuild/openharmony-arm64" "0.28.1" + "@esbuild/sunos-x64" "0.28.1" + "@esbuild/win32-arm64" "0.28.1" + "@esbuild/win32-ia32" "0.28.1" + "@esbuild/win32-x64" "0.28.1" + esbuild@^0.21.3: version "0.21.5" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz" @@ -1607,7 +2048,7 @@ foreground-child@^3.1.0: cross-spawn "^7.0.6" signal-exit "^4.0.1" -fsevents@~2.3.2, fsevents@~2.3.3: +fsevents@2.3.3, fsevents@~2.3.2, fsevents@~2.3.3: version "2.3.3" resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== @@ -1900,6 +2341,11 @@ keyv@^4.5.4: dependencies: json-buffer "3.0.1" +kleur@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" + integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== + levn@^0.4.1: version "0.4.1" resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" @@ -2362,6 +2808,18 @@ mimic-function@^5.0.0: resolved "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz" integrity sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA== +miniflare@5.20260926.1-alpha: + version "5.20260926.1-alpha" + resolved "https://registry.yarnpkg.com/miniflare/-/miniflare-5.20260926.1-alpha.tgz#cb07b002c01e96fd31410b86779d3aad14e1f85d" + integrity sha512-vc4lgl8YVxR2aundPnVPTIcL46UQKK+ebW7yinXNE1Y9joFS0JoakMazr7r3M8DXRvaemKS8EEmszkv/b05qUw== + dependencies: + "@cspotcode/source-map-support" "0.8.1" + sharp "0.35.4" + undici "7.29.1" + workerd "1.20260926.1" + ws "8.21.0" + youch "4.1.0-beta.10" + minimatch@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" @@ -2546,6 +3004,16 @@ path-scurry@^1.11.1: lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" +path-to-regexp@6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.3.0.tgz#2b6a26a337737a8e1416f9272ed0766b1c0389f4" + integrity sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ== + +pathe@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-2.0.3.tgz#3ecbec55421685b70a9da872b2cff3e1cbed1716" + integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w== + perfect-debounce@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz" @@ -2725,6 +3193,46 @@ semver@^7.6.0, semver@^7.6.3: resolved "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz" integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== +semver@^7.8.5: + version "7.8.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.8.5.tgz#39b646037dd50c14fb451e7e4cac58ed8b863f69" + integrity sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA== + +sharp@0.35.4: + version "0.35.4" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.35.4.tgz#361df3b2959daeb380541289960456c6be0f92de" + integrity sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA== + dependencies: + "@img/colour" "^1.1.0" + detect-libc "^2.1.2" + semver "^7.8.5" + optionalDependencies: + "@img/sharp-darwin-arm64" "0.35.4" + "@img/sharp-darwin-x64" "0.35.4" + "@img/sharp-freebsd-wasm32" "0.35.4" + "@img/sharp-libvips-darwin-arm64" "1.3.3" + "@img/sharp-libvips-darwin-x64" "1.3.3" + "@img/sharp-libvips-linux-arm" "1.3.3" + "@img/sharp-libvips-linux-arm64" "1.3.3" + "@img/sharp-libvips-linux-ppc64" "1.3.3" + "@img/sharp-libvips-linux-riscv64" "1.3.3" + "@img/sharp-libvips-linux-s390x" "1.3.3" + "@img/sharp-libvips-linux-x64" "1.3.3" + "@img/sharp-libvips-linuxmusl-arm64" "1.3.3" + "@img/sharp-libvips-linuxmusl-x64" "1.3.3" + "@img/sharp-linux-arm" "0.35.4" + "@img/sharp-linux-arm64" "0.35.4" + "@img/sharp-linux-ppc64" "0.35.4" + "@img/sharp-linux-riscv64" "0.35.4" + "@img/sharp-linux-s390x" "0.35.4" + "@img/sharp-linux-x64" "0.35.4" + "@img/sharp-linuxmusl-arm64" "0.35.4" + "@img/sharp-linuxmusl-x64" "0.35.4" + "@img/sharp-webcontainers-wasm32" "0.35.4" + "@img/sharp-win32-arm64" "0.35.4" + "@img/sharp-win32-ia32" "0.35.4" + "@img/sharp-win32-x64" "0.35.4" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" @@ -2893,6 +3401,11 @@ superjson@^2.2.1: dependencies: copy-anything "^3.0.2" +supports-color@^10.0.0: + version "10.2.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-10.2.2.tgz#466c2978cc5cd0052d542a0b576461c2b802ebb4" + integrity sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g== + supports-color@^7.1.0: version "7.2.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" @@ -2932,7 +3445,7 @@ ts-api-utils@^2.0.1: resolved "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz" integrity sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w== -tslib@^2.2.0: +tslib@^2.2.0, tslib@^2.4.0: version "2.8.1" resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== @@ -2968,6 +3481,18 @@ undici-types@~7.10.0: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.10.0.tgz#4ac2e058ce56b462b056e629cc6a02393d3ff350" integrity sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag== +undici@7.29.1: + version "7.29.1" + resolved "https://registry.yarnpkg.com/undici/-/undici-7.29.1.tgz#7741c6fc8b3e1a48e30323833642bfbe841443ad" + integrity sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q== + +unenv@2.0.0-rc.24: + version "2.0.0-rc.24" + resolved "https://registry.yarnpkg.com/unenv/-/unenv-2.0.0-rc.24.tgz#dd0035c3e93fedfa12c8454e34b7f17fe83efa2e" + integrity sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw== + dependencies: + pathe "^2.0.3" + unist-util-is@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz" @@ -3164,6 +3689,33 @@ word-wrap@^1.2.5: resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== +workerd@1.20260926.1: + version "1.20260926.1" + resolved "https://registry.yarnpkg.com/workerd/-/workerd-1.20260926.1.tgz#3635aa9497d24aee5104c51c8e3dc0a1a1d3d0b6" + integrity sha512-YojhsWBuZwk3Jk9OC0QfTgVbLeQOD1tK1olC9ZXAUcmeip8z4NE/xtttpxCsuTvQBRqppvy7Tkac0kxPYMjIXA== + optionalDependencies: + "@cloudflare/workerd-darwin-64" "1.20260926.1" + "@cloudflare/workerd-darwin-arm64" "1.20260926.1" + "@cloudflare/workerd-linux-64" "1.20260926.1" + "@cloudflare/workerd-linux-arm64" "1.20260926.1" + "@cloudflare/workerd-windows-64" "1.20260926.1" + +wrangler@^4.144.0: + version "4.144.0" + resolved "https://registry.yarnpkg.com/wrangler/-/wrangler-4.144.0.tgz#a61b647dc04fae603d416059adb07d7a257add82" + integrity sha512-4xIASysrsGBLkTuyoYUTJuhqjlnhwX90Ui8HVLElLJ9Unfqn0Hq51YuMP6GMmijbKFK/7Jmlgk6WkMZDCAklLQ== + dependencies: + "@cloudflare/kv-asset-handler" "0.5.0" + "@cloudflare/unenv-preset" "2.16.2" + blake3-wasm "2.1.5" + esbuild "0.28.1" + miniflare "5.20260926.1-alpha" + path-to-regexp "6.3.0" + unenv "2.0.0-rc.24" + workerd "1.20260926.1" + optionalDependencies: + fsevents "2.3.3" + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" @@ -3191,6 +3743,11 @@ wrap-ansi@^9.0.0: string-width "^7.0.0" strip-ansi "^7.1.0" +ws@8.21.0: + version "8.21.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.21.0.tgz#012e413fc07429945121b0c153158c4343086951" + integrity sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g== + xml-name-validator@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz" @@ -3211,6 +3768,25 @@ yocto-queue@^0.1.0: resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +youch-core@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/youch-core/-/youch-core-0.3.3.tgz#c5d3d85aeea0d8bc7b36e9764ed3f14b7ceddc7d" + integrity sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA== + dependencies: + "@poppinss/exception" "^1.2.2" + error-stack-parser-es "^1.0.5" + +youch@4.1.0-beta.10: + version "4.1.0-beta.10" + resolved "https://registry.yarnpkg.com/youch/-/youch-4.1.0-beta.10.tgz#94702059e0ba7668025f5cd1b5e5c0f3eb0e83c2" + integrity sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ== + dependencies: + "@poppinss/colors" "^4.1.5" + "@poppinss/dumper" "^0.6.4" + "@speed-highlight/core" "^1.2.7" + cookie "^1.0.2" + youch-core "^0.3.3" + zwitch@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz"